3

I would like to abort the deletion of an object (A custom Content-Type), and redirect to a page (a view) that sets the workflow to a custom state named Unavailable, shows a message to the user "You succesfully deleted the object!". The object will still be on ZODB, but for some groups it'll simply not be seen, as if it was really deleted.

I can do a raise in a subscriber using IObjectWillBeRemovedEvent, but trying to use raise zExceptions.Redirect("url") doesn't work. The raise call avoids the deletion, but a message "The object could not be deleted" is shown instead of the redirection.

Anyone has a solution to this scenario?

Lennart Regebro
  • 167,292
  • 41
  • 224
  • 251

3 Answers3

3

As you can see Plone / Zope 2 object management is messy (yes, I am willing to burn karma just to say this). You need to override delete action in the user interface level, not on the object level.

Try to figure out how to customize delete actions in Plone user interface.

  • Make sure the default Delete actions is no longer visible and available (e.g. set higher needed permission for it e.g. cmf.ManagePortal)

  • Create another Delete action which goes according to your specialized workflow

I believe Delete can be configured from portal_actions, but there might be separate cases for deleting one object (Actions menu) and deleting multiple objects (folder_contents).

Mikko Ohtamaa
  • 82,057
  • 50
  • 264
  • 435
  • Hum, this could be an approach I haven't thought about as well: override the delete action. So, I would create a new delete action, that has a new logic (if the content-type is going to be deleted do something, else just delete), and use it instead the default one (that is going to be hidden). – Somebody still uses you MS-DOS Aug 18 '11 at 16:45
  • Couldn't I just override `folder_delete` and `delete_confirmation` (that are used on the delete actions now available at the portal) inside my package? Or am I going to regret doing this in the future? Any *really* bad caveats going through this approach? – Somebody still uses you MS-DOS Aug 18 '11 at 17:22
  • 1
    Probably plenty of pitfalls, but because no one has not done it before you'll be the only one of suffering of those pitfalls :) – Mikko Ohtamaa Aug 19 '11 at 07:58
2

You need REQUEST.response.redirect("url"). I'm pretty sure that zExceptions.Redirect is the way that Zope internally handles response.redirect() calls. Be sure you still raise another exception after calling redirect() so that the transaction is aborte.

That said, this sure seems like the wrong way to accomplish this. For one thing, you'll do at least double indexing, which is done before the transaction aborts. Catalog indexing is the most expensive part of processing a request that modifies content so this creates wasteful load on your server.

Events are for doing additional stuff which is only tangentially related to the event. What you want is to fundamentally change what happens when someone deletes. Maybe you should patch/override the underlying deletion method on the container objects (folders?) to do your worklfow transition.

Ross Patterson
  • 5,702
  • 20
  • 38
1

You could raise a OFS.ObjectManager.BeforeDeleteException in the event handler to stop the deletion. If you raise a LinkIntegrityNotificationException you get redirected to Plones nice Link intergrity page.

from OFS.interfaces import IObjectWillBeRemovedEvent
from plone.app.linkintegrity.exceptions import LinkIntegrityNotificationException
import grok

@grok.subscribe(ICSRDocument, IObjectWillBeRemovedEvent)
def document_willbemoved(doc, event):
    raise LinkIntegrityNotificationException(doc)
Lennart Regebro
  • 167,292
  • 41
  • 224
  • 251