sdupton
sdupton

Reputation: 1879

Prevent deletion of folder (type) in Plone unless parent is being deleted

I want to prevent deletion of instance of a folderish type in Plone, excepting when a parent folder is being deleted. I have a hunch that an event handler can prevent deletion (raise an exception in an IObjectRemovedEvent handler bound to a marker interface), but implementing the exception to this rule seems harder to pin down: I want to allow deletion of the item when its parent folder is being deleted.

My initial hunch was that I could traverse __parent__ pointers and check if an attribute was set on the parent (or some distant indirect container) that it was being deleted, but I am not sure how I would set this attribute on deletion of the parent prior to an attempt to delete the contained child (otherwise not allowing deletion). So now, I'm questioning whether I am approaching this the right way? Am I misunderstanding the problem constraints for deleting objects in Plone? Should I look to plone.app.linkintegrity source to borrow tricks?

My use case: a "settings folder" inside a "project" folder -- intrinsically, the settings folder should never be allowed to be deleted unless the project folder itself is being deleted. I guess I'm asking for referential integrity for a very-specific containment relationship.

How would you prevent deletion of an object except in the case it was being deleted as a direct result of its parent being deleted?

Upvotes: 3

Views: 224

Answers (1)

sdupton
sdupton

Reputation: 1879

After a fair bit of time, I have finally found a solution to this general problem (but in a different context):

  1. Create a subscriber on the parent for the parent's interface and OFS.interfaces.IObjectWillBeMovedEvent.
  2. That handler should use zope.globalrequest.getRequest() to get the request object, and adapt that to IAnnotations to get an annotations object on the request (a global for the duration of the request, in practical terms).
  3. The IObjectWillBeMovedEvent handler will save a tuple form of the physical path tuple(context.getPhysicalPath()) on the annotation object.
  4. The event handler for IObjectRemovedEvent attempting to block deletion of the child item will pass if its path shares a base path of the parent (see example).

By consequence, an exception is only raised if an attempt is made to delete the object itself, but not when its parent is deleted.

See example: http://bazaar.launchpad.net/~upiq-dev/upiq/dev-uu.formlibrary/revision/113

Upvotes: 1

Related Questions