from AccessControl import getSecurityManager from zope.interface import implements from five import grok from zope import component from zope import schema from zope.interface import Interface from zc.relation.interfaces import ICatalog from zope.app.intid.interfaces import IIntIds from plone.dexterity.content import Container from plone.uuid.interfaces import IUUID from Acquisition import aq_parent from plone.supermodel import model from plone.app.layout.viewlets.interfaces import IBelowContentBody import plone.app.contenttypes.interfaces from plone.dexterity.interfaces import IDexterityContainer from plone.app.contentlisting.interfaces import IContentListingObject from plone import api from plone.dexterity.browser.view import DefaultView from collective.z3cform.rolefield.field import LocalRolesToPrincipals from collective.dms.basecontent.widget import AjaxChosenMultiFieldWidget from plone.autoform import directives as form from zope.app.intid.interfaces import IIntIds from z3c.relationfield import RelationValue from zope.lifecycleevent.interfaces import IObjectAddedEvent import z3c.table.column from pfwbged.collection.searchview import ResultsTable from collective.dms.thesaurus.keywordsfield import ThesaurusKeywords from collective.dms.basecontent.dmsdocument import IDmsDocument from .link import ILink from . import _ class IFolder(model.Schema): """ """ treating_groups = LocalRolesToPrincipals( title=_(u"Treating groups"), required=False, roles_to_assign=('Editor',), value_type=schema.Choice(vocabulary=u'collective.dms.basecontent.treating_groups',) ) form.widget(treating_groups=AjaxChosenMultiFieldWidget) recipient_groups = LocalRolesToPrincipals( title=_(u"Recipient groups"), required=False, roles_to_assign=('Reader',), value_type=schema.Choice(vocabulary=u'collective.dms.basecontent.recipient_groups') ) form.widget(recipient_groups=AjaxChosenMultiFieldWidget) keywords = ThesaurusKeywords(title=_(u'Keywords'), required=False) class Folder(Container): """ """ implements(IFolder) def parent_folders(self): parents = [] for id, item in self.contentItems(): if not ILink.providedBy(item): continue parents.append(item.folder.to_object) return parents def child_folders(self): intids = component.getUtility(IIntIds) intid_catalog = component.getUtility(ICatalog) try: intid = intids.getId(self) except KeyError: return [] children = [] uuids = [] sm = getSecurityManager() for item in intid_catalog.findRelations({ 'to_id': intid, 'from_interfaces_flattened': ILink}): if item.isBroken(): continue link = item.from_object if not sm.checkPermission('View', link): continue document = aq_parent(link) if IFolder.providedBy(document): uuids.append(IUUID(document)) portal_catalog = api.portal.get_tool('portal_catalog') children = portal_catalog.searchResults({'UID': uuids}) return [IContentListingObject(x) for x in children] def intid(self): intids = component.getUtility(IIntIds) try: return intids.getId(self) except KeyError: return None grok.templatedir('templates') grok.context(IDexterityContainer) class ItemsTable(ResultsTable): def setUpColumns(self): columns = super(ItemsTable, self).setUpColumns() # do not include the delete column, from classifying folders we only # provide an icon for unlink columns = [x for x in columns if x.__name__ != 'dms.delete'] return columns from collective.dms.basecontent.browser import column class UnfileColumn(column.IconColumn, column.LinkColumn): grok.name('pfwbged.folder.unfile') grok.adapts(Interface, Interface, ItemsTable) header = u'' iconName = "++resource++unlink_icon.png" linkContent = _('Unfile') def getLinkURL(self, item): for id, child in item.getObject().contentItems(): if not ILink.providedBy(child): continue if child.folder.to_object == self.context: return item.getURL() + '/' + id + '/delete_confirmation' return '#' class ClassifiedItems: @property def table(self): table = ItemsTable(self.context, self.request) table.values = self.documents() table.update() return table def documents(self): if self.context.id == 'documents' and aq_parent(self.context).portal_type == 'Plone Site': # never return anything in the main documents folder return [] intids = component.getUtility(IIntIds) intid_catalog = component.getUtility(ICatalog) try: intid = intids.getId(self.context) except KeyError: return [] uuids = [] sm = getSecurityManager() for item in intid_catalog.findRelations({ 'to_id': intid, 'from_interfaces_flattened': ILink}): if item.isBroken(): continue link = item.from_object if not sm.checkPermission('View', link): continue document = aq_parent(link) uuids.append(IUUID(document)) portal_catalog = api.portal.get_tool('portal_catalog') children = portal_catalog.searchResults({'UID': uuids}) return [IContentListingObject(x) for x in children] class FolderViewlet(grok.Viewlet, ClassifiedItems): grok.context(plone.app.contenttypes.interfaces.IFolder) grok.template('foldersviewlet') grok.viewletmanager(IBelowContentBody) grok.order(15) class FolderView(DefaultView, ClassifiedItems): pass @grok.subscribe(IFolder, IObjectAddedEvent) @grok.subscribe(IDmsDocument, IObjectAddedEvent) def move_to_proper_location(context, event): folder = context.getParentNode() if folder.id == 'documents' and aq_parent(folder).portal_type == 'Plone Site': # the document is already in the right place, good return # add a link to classifying folder intids = component.getUtility(IIntIds) link = context.invokeFactory('pfwbgedlink', 'pfwbgedlink-0', folder=RelationValue(intids.getId(folder))) # then move the document to the general documents folder clipboard = folder.manage_cutObjects([context.id]) documents_folder = api.portal.get().documents result = documents_folder.manage_pasteObjects(clipboard) # makes sure original object is deleted try: folder.manage_delObjects([context.id]) except AttributeError: pass