On s'apprête à customiser le comportement aux requêtes PUT. Copie telle quelle du...
[Plinn.git] / Folder.py
index 9cd4d8b..9808810 100644 (file)
--- a/Folder.py
+++ b/Folder.py
 #######################################################################################
 """ Plinn portal folder implementation
 
 #######################################################################################
 """ Plinn portal folder implementation
 
-$Id: Folder.py 1459 2009-02-02 00:57:24Z pin $
-$URL: http://svn.cri.ensmp.fr/svn/Plinn/branches/CMF-2.1/Folder.py $
+
+
 """
 
 from OFS.CopySupport import CopyError, eNoData, _cb_decode, eInvalid, eNotFound,\
                                                        eNotSupported, sanity_check, cookie_path
 from App.Dialogs import MessageDialog
 """
 
 from OFS.CopySupport import CopyError, eNoData, _cb_decode, eInvalid, eNotFound,\
                                                        eNotSupported, sanity_check, cookie_path
 from App.Dialogs import MessageDialog
+from zExceptions import BadRequest
 import sys
 import warnings
 from cgi import escape
 from OFS import Moniker
 from ZODB.POSException import ConflictError
 import OFS.subscribers
 import sys
 import warnings
 from cgi import escape
 from OFS import Moniker
 from ZODB.POSException import ConflictError
 import OFS.subscribers
+from webdav.NullResource import NullResource
 from zope.event import notify
 from zope.lifecycleevent import ObjectCopiedEvent
 from zope.event import notify
 from zope.lifecycleevent import ObjectCopiedEvent
-from zope.app.container.contained import ObjectMovedEvent
-from zope.app.container.contained import notifyContainerModified
+try :
+       from zope.app.container.contained import notifyContainerModified
+       from zope.app.container.contained import ObjectMovedEvent
+except ImportError :
+       ## Zope-2.13 compat
+       from zope.container.contained import notifyContainerModified
+       from zope.container.contained import ObjectMovedEvent
 from OFS.event import ObjectClonedEvent
 from OFS.event import ObjectWillBeMovedEvent
 from zope.component.factory import Factory
 from Acquisition import aq_base, aq_inner, aq_parent
 
 from types import StringType
 from OFS.event import ObjectClonedEvent
 from OFS.event import ObjectWillBeMovedEvent
 from zope.component.factory import Factory
 from Acquisition import aq_base, aq_inner, aq_parent
 
 from types import StringType
-from Products.CMFCore.permissions import ListFolderContents, View, ManageProperties, AddPortalFolders, AddPortalContent, ManagePortal
+from Products.CMFCore.permissions import ListFolderContents, View, ViewManagementScreens,\
+                                                                                ManageProperties, AddPortalFolders, AddPortalContent,\
+                                                                                ManagePortal, ModifyPortalContent
 from permissions import DeletePortalContents, DeleteObjects, DeleteOwnedObjects, SetLocalRoles, CheckMemberPermission
 from Products.CMFCore.utils import _checkPermission, getToolByName
 from Products.CMFCore.CMFCatalogAware import CMFCatalogAware
 from permissions import DeletePortalContents, DeleteObjects, DeleteOwnedObjects, SetLocalRoles, CheckMemberPermission
 from Products.CMFCore.utils import _checkPermission, getToolByName
 from Products.CMFCore.CMFCatalogAware import CMFCatalogAware
@@ -53,6 +62,7 @@ from zope.interface import implements
 from Products.CMFCore.interfaces import IContentish
 
 from utils import _checkMemberPermission
 from Products.CMFCore.interfaces import IContentish
 
 from utils import _checkMemberPermission
+from utils import Message as _
 from Globals import InitializeClass
 from AccessControl import ClassSecurityInfo
 
 from Globals import InitializeClass
 from AccessControl import ClassSecurityInfo
 
@@ -72,6 +82,18 @@ class PlinnFolder(CMFCatalogAware, PortalFolder, DefaultDublinCoreImpl) :
        def __init__( self, id, title='' ) :
                PortalFolder.__init__(self, id)
                DefaultDublinCoreImpl.__init__(self, title = title)
        def __init__( self, id, title='' ) :
                PortalFolder.__init__(self, id)
                DefaultDublinCoreImpl.__init__(self, title = title)
+       
+    def __getitem__(self, key):
+        if key in self:
+            return self._getOb(key, None)
+        request = getattr(self, 'REQUEST', None)
+        if not isinstance(request, (str, NoneType)):
+            method=request.get('REQUEST_METHOD', 'GET')
+            if (request.maybe_webdav_client and
+                method not in ('GET', 'POST')):
+                return NullResource(self, key, request).__of__(self)
+        raise KeyError, key
+    
                
        security.declarePublic('allowedContentTypes')
        def allowedContentTypes(self):
                
        security.declarePublic('allowedContentTypes')
        def allowedContentTypes(self):
@@ -105,7 +127,7 @@ class PlinnFolder(CMFCatalogAware, PortalFolder, DefaultDublinCoreImpl) :
 
        security.declareProtected(DeletePortalContents, 'manage_delObjects')
        def manage_delObjects(self, ids=[], REQUEST=None):
 
        security.declareProtected(DeletePortalContents, 'manage_delObjects')
        def manage_delObjects(self, ids=[], REQUEST=None):
-               """Delete a subordinate object.
+               """Delete subordinate objects.
                   A member can delete his owned contents (if he has the 'Delete Portal Contents' permission)
                   without 'Delete objects' permission in this folder.
                   Return skipped object ids.
                   A member can delete his owned contents (if he has the 'Delete Portal Contents' permission)
                   without 'Delete objects' permission in this folder.
                   Return skipped object ids.
@@ -133,7 +155,38 @@ class PlinnFolder(CMFCatalogAware, PortalFolder, DefaultDublinCoreImpl) :
                                manage_tabs_message='Object(s) deleted.',
                                update_menu=1)
                return notOwned
                                manage_tabs_message='Object(s) deleted.',
                                update_menu=1)
                return notOwned
-                               
+
+
+       security.declareProtected(AddPortalContent, 'manage_renameObjects')
+       def manage_renameObjects(self, ids=[], new_ids=[], REQUEST=None) :
+               """ Rename subordinate objects
+                       A member can rename his owned contents if he has the 'Modify Portal Content' permission.
+                       Returns skippend object ids.
+               """
+               if len(ids) != len(new_ids):
+                       raise BadRequest(_('Please rename each listed object.'))
+               
+               if _checkPermission(ViewManagementScreens, self) : # std zope perm
+                       return super(PlinnFolder, self).manage_renameObjects(ids, new_ids, REQUEST)
+                       
+               mtool = getToolByName(self, 'portal_membership')
+               authMember = mtool.getAuthenticatedMember()
+               skiped = []
+               for id, new_id in zip(ids, new_ids) :
+                       if id == new_id : continue
+                       
+                       ob = self._getOb(id)
+                       if authMember.allowed(ob, object_roles=['Owner'] ) and \
+                          _checkPermission(ModifyPortalContent, ob) :
+                               self.manage_renameObject(id, new_id)
+                       else :
+                               skiped.append(id)
+               
+               if REQUEST is not None :
+                       return self.manage_main(self, REQUEST, update_menu=1)
+
+               return skiped
+
 
        security.declareProtected(ListFolderContents, 'listFolderContents')
        def listFolderContents( self, contentFilter=None ):
 
        security.declareProtected(ListFolderContents, 'listFolderContents')
        def listFolderContents( self, contentFilter=None ):
@@ -242,164 +295,164 @@ class PlinnFolder(CMFCatalogAware, PortalFolder, DefaultDublinCoreImpl) :
                                self, REQUEST, portal_status_message="Folder added")
 
        
                                self, REQUEST, portal_status_message="Folder added")
 
        
-       ## overload to maintain ownership if authenticated user has 'Manage portal' permission
-       def manage_pasteObjects(self, cb_copy_data=None, REQUEST=None):
-               """Paste previously copied objects into the current object.
-
-               If calling manage_pasteObjects from python code, pass the result of a
-               previous call to manage_cutObjects or manage_copyObjects as the first
-               argument.
-
-               Also sends IObjectCopiedEvent and IObjectClonedEvent
-               or IObjectWillBeMovedEvent and IObjectMovedEvent.
-               """
-               if cb_copy_data is not None:
-                       cp = cb_copy_data
-               elif REQUEST is not None and REQUEST.has_key('__cp'):
-                       cp = REQUEST['__cp']
-               else:
-                       cp = None
-               if cp is None:
-                       raise CopyError, eNoData
-
-               try:
-                       op, mdatas = _cb_decode(cp)
-               except:
-                       raise CopyError, eInvalid
-
-               oblist = []
-               app = self.getPhysicalRoot()
-               for mdata in mdatas:
-                       m = Moniker.loadMoniker(mdata)
-                       try:
-                               ob = m.bind(app)
-                       except ConflictError:
-                               raise
-                       except:
-                               raise CopyError, eNotFound
-                       self._verifyObjectPaste(ob, validate_src=op+1)
-                       oblist.append(ob)
-
-               result = []
-               if op == 0:
-                       # Copy operation
-                       mtool = getToolByName(self, 'portal_membership')
-                       utool = getToolByName(self, 'portal_url')
-                       portal = utool.getPortalObject()
-                       userIsPortalManager = mtool.checkPermission(ManagePortal, portal)
-
-                       for ob in oblist:
-                               orig_id = ob.getId()
-                               if not ob.cb_isCopyable():
-                                       raise CopyError, eNotSupported % escape(orig_id)
-
-                               try:
-                                       ob._notifyOfCopyTo(self, op=0)
-                               except ConflictError:
-                                       raise
-                               except:
-                                       raise CopyError, MessageDialog(
-                                               title="Copy Error",
-                                               message=sys.exc_info()[1],
-                                               action='manage_main')
-
-                               id = self._get_id(orig_id)
-                               result.append({'id': orig_id, 'new_id': id})
-
-                               orig_ob = ob
-                               ob = ob._getCopy(self)
-                               ob._setId(id)
-                               notify(ObjectCopiedEvent(ob, orig_ob))
-                               
-                               if not userIsPortalManager :
-                                       self._setObject(id, ob, suppress_events=True)
-                               else :
-                                       self._setObject(id, ob, suppress_events=True, set_owner=0)
-                               ob = self._getOb(id)
-                               ob.wl_clearLocks()
-
-                               ob._postCopy(self, op=0)
-
-                               OFS.subscribers.compatibilityCall('manage_afterClone', ob, ob)
-
-                               notify(ObjectClonedEvent(ob))
-
-                       if REQUEST is not None:
-                               return self.manage_main(self, REQUEST, update_menu=1,
-                                                                               cb_dataValid=1)
-
-               elif op == 1:
-                       # Move operation
-                       for ob in oblist:
-                               orig_id = ob.getId()
-                               if not ob.cb_isMoveable():
-                                       raise CopyError, eNotSupported % escape(orig_id)
-
-                               try:
-                                       ob._notifyOfCopyTo(self, op=1)
-                               except ConflictError:
-                                       raise
-                               except:
-                                       raise CopyError, MessageDialog(
-                                               title="Move Error",
-                                               message=sys.exc_info()[1],
-                                               action='manage_main')
-
-                               if not sanity_check(self, ob):
-                                       raise CopyError, "This object cannot be pasted into itself"
-
-                               orig_container = aq_parent(aq_inner(ob))
-                               if aq_base(orig_container) is aq_base(self):
-                                       id = orig_id
-                               else:
-                                       id = self._get_id(orig_id)
-                               result.append({'id': orig_id, 'new_id': id})
-
-                               notify(ObjectWillBeMovedEvent(ob, orig_container, orig_id,
-                                                                                         self, id))
-
-                               # try to make ownership explicit so that it gets carried
-                               # along to the new location if needed.
-                               ob.manage_changeOwnershipType(explicit=1)
-
-                               try:
-                                       orig_container._delObject(orig_id, suppress_events=True)
-                               except TypeError:
-                                       orig_container._delObject(orig_id)
-                                       warnings.warn(
-                                               "%s._delObject without suppress_events is discouraged."
-                                               % orig_container.__class__.__name__,
-                                               DeprecationWarning)
-                               ob = aq_base(ob)
-                               ob._setId(id)
-
-                               try:
-                                       self._setObject(id, ob, set_owner=0, suppress_events=True)
-                               except TypeError:
-                                       self._setObject(id, ob, set_owner=0)
-                                       warnings.warn(
-                                               "%s._setObject without suppress_events is discouraged."
-                                               % self.__class__.__name__, DeprecationWarning)
-                               ob = self._getOb(id)
-
-                               notify(ObjectMovedEvent(ob, orig_container, orig_id, self, id))
-                               notifyContainerModified(orig_container)
-                               if aq_base(orig_container) is not aq_base(self):
-                                       notifyContainerModified(self)
-
-                               ob._postCopy(self, op=1)
-                               # try to make ownership implicit if possible
-                               ob.manage_changeOwnershipType(explicit=0)
-
-                       if REQUEST is not None:
-                               REQUEST['RESPONSE'].setCookie('__cp', 'deleted',
-                                                                       path='%s' % cookie_path(REQUEST),
-                                                                       expires='Wed, 31-Dec-97 23:59:59 GMT')
-                               REQUEST['__cp'] = None
-                               return self.manage_main(self, REQUEST, update_menu=1,
-                                                                               cb_dataValid=0)
-
-               return result
+#   ## overload to maintain ownership if authenticated user has 'Manage portal' permission
+#   def manage_pasteObjects(self, cb_copy_data=None, REQUEST=None):
+#      """Paste previously copied objects into the current object.
+#
+#      If calling manage_pasteObjects from python code, pass the result of a
+#      previous call to manage_cutObjects or manage_copyObjects as the first
+#      argument.
+#
+#      Also sends IObjectCopiedEvent and IObjectClonedEvent
+#      or IObjectWillBeMovedEvent and IObjectMovedEvent.
+#      """
+#      if cb_copy_data is not None:
+#              cp = cb_copy_data
+#      elif REQUEST is not None and REQUEST.has_key('__cp'):
+#              cp = REQUEST['__cp']
+#      else:
+#              cp = None
+#      if cp is None:
+#              raise CopyError, eNoData
+#
+#      try:
+#              op, mdatas = _cb_decode(cp)
+#      except:
+#              raise CopyError, eInvalid
+#
+#      oblist = []
+#      app = self.getPhysicalRoot()
+#      for mdata in mdatas:
+#              m = Moniker.loadMoniker(mdata)
+#              try:
+#                      ob = m.bind(app)
+#              except ConflictError:
+#                      raise
+#              except:
+#                      raise CopyError, eNotFound
+#              self._verifyObjectPaste(ob, validate_src=op+1)
+#              oblist.append(ob)
+#
+#      result = []
+#      if op == 0:
+#              # Copy operation
+#              mtool = getToolByName(self, 'portal_membership')
+#              utool = getToolByName(self, 'portal_url')
+#              portal = utool.getPortalObject()
+#              userIsPortalManager = mtool.checkPermission(ManagePortal, portal)
+#
+#              for ob in oblist:
+#                      orig_id = ob.getId()
+#                      if not ob.cb_isCopyable():
+#                              raise CopyError, eNotSupported % escape(orig_id)
+#
+#                      try:
+#                              ob._notifyOfCopyTo(self, op=0)
+#                      except ConflictError:
+#                              raise
+#                      except:
+#                              raise CopyError, MessageDialog(
+#                                      title="Copy Error",
+#                                      message=sys.exc_info()[1],
+#                                      action='manage_main')
+#
+#                      id = self._get_id(orig_id)
+#                      result.append({'id': orig_id, 'new_id': id})
+#
+#                      orig_ob = ob
+#                      ob = ob._getCopy(self)
+#                      ob._setId(id)
+#                      notify(ObjectCopiedEvent(ob, orig_ob))
+#                      
+#                      if not userIsPortalManager :
+#                              self._setObject(id, ob, suppress_events=True)
+#                      else :
+#                              self._setObject(id, ob, suppress_events=True, set_owner=0)
+#                      ob = self._getOb(id)
+#                      ob.wl_clearLocks()
+#
+#                      ob._postCopy(self, op=0)
+#
+#                      OFS.subscribers.compatibilityCall('manage_afterClone', ob, ob)
+#
+#                      notify(ObjectClonedEvent(ob))
+#
+#              if REQUEST is not None:
+#                      return self.manage_main(self, REQUEST, update_menu=1,
+#                                                                      cb_dataValid=1)
+#
+#      elif op == 1:
+#              # Move operation
+#              for ob in oblist:
+#                      orig_id = ob.getId()
+#                      if not ob.cb_isMoveable():
+#                              raise CopyError, eNotSupported % escape(orig_id)
+#
+#                      try:
+#                              ob._notifyOfCopyTo(self, op=1)
+#                      except ConflictError:
+#                              raise
+#                      except:
+#                              raise CopyError, MessageDialog(
+#                                      title="Move Error",
+#                                      message=sys.exc_info()[1],
+#                                      action='manage_main')
+#
+#                      if not sanity_check(self, ob):
+#                              raise CopyError, "This object cannot be pasted into itself"
+#
+#                      orig_container = aq_parent(aq_inner(ob))
+#                      if aq_base(orig_container) is aq_base(self):
+#                              id = orig_id
+#                      else:
+#                              id = self._get_id(orig_id)
+#                      result.append({'id': orig_id, 'new_id': id})
+#
+#                      notify(ObjectWillBeMovedEvent(ob, orig_container, orig_id,
+#                                                                                self, id))
+#
+#                      # try to make ownership explicit so that it gets carried
+#                      # along to the new location if needed.
+#                      ob.manage_changeOwnershipType(explicit=1)
+#
+#                      try:
+#                              orig_container._delObject(orig_id, suppress_events=True)
+#                      except TypeError:
+#                              orig_container._delObject(orig_id)
+#                              warnings.warn(
+#                                      "%s._delObject without suppress_events is discouraged."
+#                                      % orig_container.__class__.__name__,
+#                                      DeprecationWarning)
+#                      ob = aq_base(ob)
+#                      ob._setId(id)
+#
+#                      try:
+#                              self._setObject(id, ob, set_owner=0, suppress_events=True)
+#                      except TypeError:
+#                              self._setObject(id, ob, set_owner=0)
+#                              warnings.warn(
+#                                      "%s._setObject without suppress_events is discouraged."
+#                                      % self.__class__.__name__, DeprecationWarning)
+#                      ob = self._getOb(id)
+#
+#                      notify(ObjectMovedEvent(ob, orig_container, orig_id, self, id))
+#                      notifyContainerModified(orig_container)
+#                      if aq_base(orig_container) is not aq_base(self):
+#                              notifyContainerModified(self)
+#
+#                      ob._postCopy(self, op=1)
+#                      # try to make ownership implicit if possible
+#                      ob.manage_changeOwnershipType(explicit=0)
+#
+#              if REQUEST is not None:
+#                      REQUEST['RESPONSE'].setCookie('__cp', 'deleted',
+#                                                              path='%s' % cookie_path(REQUEST),
+#                                                              expires='Wed, 31-Dec-97 23:59:59 GMT')
+#                      REQUEST['__cp'] = None
+#                      return self.manage_main(self, REQUEST, update_menu=1,
+#                                                                      cb_dataValid=0)
+#
+#      return result
 
                
 InitializeClass(PlinnFolder)
 
                
 InitializeClass(PlinnFolder)