[CMF-checkins] CVS: CMF/CMFCore - CMFCatalogAware.py:1.10 MembershipTool.py:1.24 PortalContent.py:1.36 PortalFolder.py:1.38
Florent Guillaume
fg@nuxeo.com
Sat, 20 Jul 2002 22:58:41 -0400
Update of /cvs-repository/CMF/CMFCore
In directory cvs.zope.org:/tmp/cvs-serv27923/CMFCore
Modified Files:
CMFCatalogAware.py MembershipTool.py PortalContent.py
PortalFolder.py
Log Message:
Allowed Portal Folders to be discussable.
(CMFCatalogAware has grown over time. It would be nice to split it into
separate mixins, unfortunately without a super() it would be hard to get
everything right for derived classes.)
=== CMF/CMFCore/CMFCatalogAware.py 1.9 => 1.10 ===
from Acquisition import aq_base
from AccessControl import ClassSecurityInfo
-from CMFCorePermissions import ModifyPortalContent
+from CMFCorePermissions import ModifyPortalContent, AccessContentsInformation
from utils import getToolByName
@@ -30,18 +30,31 @@
security.declareProtected(ModifyPortalContent, 'indexObject')
def indexObject(self):
+ """
+ Index the object in the portal catalog.
+ """
catalog = getToolByName(self, 'portal_catalog', None)
if catalog is not None:
catalog.indexObject(self)
security.declareProtected(ModifyPortalContent, 'unindexObject')
def unindexObject(self):
+ """
+ Unindex the object from the portal catalog.
+ """
catalog = getToolByName(self, 'portal_catalog', None)
if catalog is not None:
catalog.unindexObject(self)
security.declareProtected(ModifyPortalContent, 'reindexObject')
def reindexObject(self, idxs=[]):
+ """
+ Reindex the object in the portal catalog.
+ If idxs is present, only those indexes are reindexed.
+ The metadata is always updated.
+
+ Also update the modification date of the object.
+ """
if hasattr(aq_base(self), 'notifyModified'):
# Update modification date.
self.notifyModified()
@@ -49,56 +62,112 @@
if catalog is not None:
catalog.reindexObject(self, idxs=idxs)
+ security.declareProtected(ModifyPortalContent, 'reindexObjectSecurity')
+ def reindexObjectSecurity(self):
+ """
+ Reindex security-related indexes on the object
+ (and its descendants).
+ """
+ catalog = getToolByName(self, 'portal_catalog', None)
+ if catalog is not None:
+ path = '/'.join(self.getPhysicalPath())
+ for brain in catalog.searchResults(path=path):
+ ob = brain.getObject()
+ try: s = ob._p_changed
+ except: s = 0
+ catalog.reindexObject(ob, idxs=['allowedRolesAndUsers'])
+ if s is None: ob._p_deactivate()
+ # Reindex the object itself, as the PathIndex only gave us
+ # the descendants.
+ self.reindexObject(idxs=['allowedRolesAndUsers'])
+
+ # Workflow methods
+ # ----------------
+
+ security.declarePrivate('notifyWorkflowCreated')
+ def notifyWorkflowCreated(self):
+ """
+ Notify the workflow that self was just created.
+ """
+ wftool = getToolByName(self, 'portal_workflow', None)
+ if wftool is not None:
+ wftool.notifyCreated(self)
+
+ # Opaque subitems
+ # ---------------
+
+ security.declareProtected(AccessContentsInformation, 'opaqueItems')
+ def opaqueItems(self):
+ """
+ Return opaque items (subelements that are contained
+ using something that is not an ObjectManager).
+ """
+ # Since 'talkback' is the only opaque item on content
+ # right now, I will return that. Should be replaced with
+ # a list of tuples for every opaque item!
+ if hasattr(aq_base(self), 'talkback'):
+ talkback = self.talkback
+ if talkback is not None:
+ return ((talkback.id, talkback),)
+ return ()
+
+ security.declareProtected(AccessContentsInformation, 'opaqueIds')
+ def opaqueIds(self):
+ """
+ Return opaque ids (subelements that are contained
+ using something that is not an ObjectManager).
+ """
+ return [t[0] for t in self.opaqueItems()]
+
+ security.declareProtected(AccessContentsInformation, 'opaqueValues')
+ def opaqueValues(self):
+ """
+ Return opaque values (subelements that are contained
+ using something that is not an ObjectManager).
+ """
+ return [t[1] for t in self.opaqueItems()]
+
+ # Hooks
+ # -----
+
def manage_afterAdd(self, item, container):
"""
Add self to the catalog.
+ (Called when the object is created or moved.)
"""
- #
- # Are we being added (or moved)?
- #
if aq_base(container) is not aq_base(self):
self.indexObject()
- # Recurse in opaque subitems (talkbacks for instance).
- if hasattr(aq_base(self), 'opaqueValues'):
- for subitem in self.opaqueValues():
- if hasattr(aq_base(subitem), 'manage_afterAdd'):
- subitem.manage_afterAdd(item, container)
+ self.__recurse('manage_afterAdd', item, container)
def manage_afterClone(self, item):
"""
- Add self to workflow, as we have just been cloned.
+ Add self to the workflow.
+ (Called when the object is cloned.)
"""
self.notifyWorkflowCreated()
- # Recurse in opaque subitems.
- if hasattr(aq_base(self), 'opaqueValues'):
- for subitem in self.opaqueValues():
- if hasattr(aq_base(subitem), 'manage_afterClone'):
- subitem.manage_afterClone(item)
+ self.__recurse('manage_afterClone', item)
def manage_beforeDelete(self, item, container):
"""
Remove self from the catalog.
+ (Called when the object is deleted or moved.)
"""
- #
- # Are we going away?
- #
if aq_base(container) is not aq_base(self):
+ self.__recurse('manage_beforeDelete', item, container)
self.unindexObject()
- # Recurse in opaque subitems.
- if hasattr(aq_base(self), 'opaqueValues'):
- for subitem in self.opaqueValues():
- if hasattr(aq_base(subitem), 'manage_beforeDelete'):
- subitem.manage_beforeDelete(item, container)
- security.declarePrivate('notifyWorkflowCreated')
- def notifyWorkflowCreated(self):
+ def __recurse(self, name, *args):
"""
- Notify the workflow that self was just created.
+ Recurse in both normal and opaque subobjects.
"""
- wftool = getToolByName(self, 'portal_workflow', None)
- if wftool is not None:
- wftool.notifyCreated(self)
-
+ values = self.objectValues()
+ opaque_values = self.opaqueValues()
+ for subobjects in values, opaque_values:
+ for ob in subobjects:
+ try: s = ob._p_changed
+ except: s = 0
+ if hasattr(aq_base(ob), name):
+ getattr(ob, name)(*args)
+ if s is None: ob._p_deactivate()
Globals.InitializeClass(CMFCatalogAware)
-
=== CMF/CMFCore/MembershipTool.py 1.23 => 1.24 ===
obj.manage_setLocalRoles( member_id, roles )
if reindex:
- self.reindexObjectSecurity(obj)
+ # It is assumed that all objects have the method
+ # reindexObjectSecurity, which is in CMFCatalogAware and
+ # thus PortalContent and PortalFolder.
+ obj.reindexObjectSecurity()
security.declareProtected(CMFCorePermissions.View, 'deleteLocalRoles')
def deleteLocalRoles( self, obj, member_ids, reindex=1 ):
@@ -383,32 +386,7 @@
obj.manage_delLocalRoles( userids=member_ids )
if reindex:
- self.reindexObjectSecurity(obj)
-
- # This is not in CMFCatalogAware because all catalogged objects
- # are not necessarily CatalogAware, especially folders.
- security.declareProtected(CMFCorePermissions.ModifyPortalContent,
- 'reindexObjectSecurity')
- def reindexObjectSecurity(self, obj):
- """
- Reindex security-related indexes on the object
- (and its descendants).
- """
- catalog = getToolByName(self, 'portal_catalog', None)
- if catalog is not None:
- path = '/'.join(obj.getPhysicalPath())
- for brain in catalog.searchResults(path=path):
- ob = brain.getObject()
- catalog.reindexObject(ob, idxs=['allowedRolesAndUsers'])
-
- # We must also reindex the object itself, as the PathIndex
- # only gave us the descendants. We have no way to do it
- # reliably, and we don't want to reindex objects that
- # weren't indexed in the first place. As a heuristic, check
- # if the object has a reindexObject method, and use it.
-
- if hasattr(aq_base(obj), 'reindexObject'):
- obj.reindexObject(idxs=['allowedRolesAndUsers'])
+ obj.reindexObjectSecurity()
security.declarePrivate('addMember')
def addMember(self, id, password, roles, domains, properties=None):
=== CMF/CMFCore/PortalContent.py 1.35 => 1.36 ===
'''
return self()
- # Methods to support items that might be stored in attributes
- # unknown to the content object, such as the DiscussionItemContainer
- # "talkback".
-
- security.declareProtected(AccessContentsInformation, 'opaqueItems')
- def opaqueItems(self):
- """
- Returns opaque items (subelements that are contained
- using something that is not an ObjectManager).
- """
- # Since 'talkback' is the only opaque item on content
- # right now, I will return that. Should be replaced with
- # a list of tuples for every opaque item!
- if hasattr(aq_base(self), 'talkback'):
- talkback = self.talkback
- if talkback is not None:
- return ((talkback.id, talkback),)
- return ()
-
- security.declareProtected(AccessContentsInformation, 'opaqueIds')
- def opaqueIds(self):
- """
- Returns opaque ids (subelements that are contained
- using something that is not an ObjectManager).
- """
- return [t[0] for t in self.opaqueItems()]
-
- security.declareProtected(AccessContentsInformation, 'opaqueValues')
- def opaqueValues(self):
- """
- Returns opaque values (subelements that are contained
- using something that is not an ObjectManager).
- """
- return [t[1] for t in self.opaqueItems()]
-
InitializeClass(PortalContent)
=== CMF/CMFCore/PortalFolder.py 1.37 => 1.38 ===
from CMFCorePermissions import View, ManageProperties, ListFolderContents
from CMFCorePermissions import AddPortalFolders, AddPortalContent
+from CMFCatalogAware import CMFCatalogAware
from OFS.Folder import Folder
from OFS.ObjectManager import REPLACEABLE
from Globals import DTMLFile
@@ -67,7 +68,7 @@
)
-class PortalFolder( Folder, DynamicType ):
+class PortalFolder(DynamicType, CMFCatalogAware, Folder):
"""
Implements portal content management, but not UI details.
"""
@@ -270,10 +271,10 @@
"""
Implement dublin core type
"""
- portal_types = getToolByName(self, 'portal_types')
- ti = portal_types.getTypeInfo(self)
- if ti is not None:
- return ti.Title()
+ if hasattr(aq_base(self), 'getTypeInfo'):
+ ti = self.getTypeInfo()
+ if ti is not None:
+ return ti.Title()
return self.meta_type
security.declarePublic('encodeFolderFilter')
@@ -305,10 +306,16 @@
"""
return None
- def reindexObject( self, idxs=[] ):
- """
- Make content-assuming factory mechanism happy.
- """
+ # Ensure pure PortalFolders don't get cataloged.
+ # XXX We may want to revisit this.
+
+ def indexObject(self):
+ pass
+
+ def unindexObject(self):
+ pass
+
+ def reindexObject(self, idxs=[]):
pass
def PUT_factory( self, name, typ, body ):