Redirecting in event handler after preventing object deletion

Hi,

We have to prevent a folder deletion in an event subscriber, because we have a fixed structure of parent folders which are all of the same content type.

Because all of the folders in the hierarchical structure have the same type, we have to allow “Delete objects” on them, because it should be possible to delete documents inside the lowest folders in the tree.

But it should not be possible to delete any folders in the structure itself.

The structure of parent folders itself grows dynamically, so giving all the last folders in the tree a special type is not possible. When a new subfolder has to be created, its now new parent type had to be to change - a migration nightmare and a no go.

So we try to allow deletion of objects inside folders in general (grant “Delete objects” permission on the folders, which is always needed to delete a document inside), and then prevent deletion in an event subscriber if it is from the type of the folders which build up the structure.

Preventing deletion in the subscriber works, when raising an exception the deletion process is aborted and an undefined error message appears. In the logs the exception shows up as expected.

Is there a way to catch this exception an display a portal message instead of the error page ?

So to say, what do i have to do in an event subscriber to cancel an IObjectRemovedEvent in a user friendly way, and say, redirect or display a portal message ?

from plone import api
from zExceptions import Redirect

api.portal.show_message("Custom message", type="error")
raise Redirect(obj.absolute_url())

Raising the Redirect exception should abort the current transaction.

1 Like

Maybe too late in your scenario, but is this not what workflows are meant for?

Many thanks. This is exactly what i was looking for.

Although the request parameter is missing in the api-call to show_message. It should be:

from zope.globalrequest import getRequest
api.portal.show_message("Löschen nicht möglich.", getRequest(), type="error")

Our workflow-definitions are several megabytes in size, and contain dynamically generated states and transitions for a strong hierarchical site layout.

What is hard to maneuver around is the fact that in the standard UI (of Plone 5.2 which we are using) some actions take the parent object into account when displaying the available actions for the content item.

Then, it is actually not clear in which part of Zope/Plone the permission “Delete objects” is taken into account. Does it only protect the content item, or do i need the permission “Delete objects” on the parent container, which in turn makes the parent container deleteable, if this is not otherwise restricted?

In the end, in a strong hierarchical site layout the folders giving the structure (and which in no way should be manipulateable) cannot have all the same state, as every folder facing the documents needs this “Delete objects” permission to make documents in it deleteable, which the parent folder must not have, or this last fixed folder in the branch is deleteable itself.

Actually we are in the process of figuring out how this all works together and where the mentioned permission is checked in the Zope/Plone core.

At the current knowledge, it demands a quite huge effort when extending or altering the fixed folder structure. Although this is an effort already because of the generated workflows anyway.

Regards.