But it is triggered many times, even before I confirm the deletion.
The docs suggest to read an old thread where Martin Aspelli explain that this event is triggered many times, and the first one is to check if the file can be deleted, and that transaction is rolled back after.
He also suggested to try an untested code:
from plone.app.linkintegrity.interfaces import ILinkIntegrityInfo
def myhandler(obj, event):
request = getattr(obj, 'REQUEST', None)
realDelete = False
if request is None:
realDelete = True
else:
info = ILinkIntegrityInfo(request)
if not info.integrityCheckingEnabled():
realDelete = True
elif not info.getIntegrityBreaches():
realDelete = True
elif info.isConfirmedItem(obj):
realDelete = True
if realDelete:
# do your thing
The problem is that this code never works.. In my case the method integrityCheckingEnabled always return True, the method getIntegrityBreaches always return {} and the method isConfirmedItem always return False.
I think the problem is the way link integrity was implemented in Plone 4; that was cleaned in Plone 5, so probably that doesn't happen anymore.
instead of creating a new event you should check if there's a way to identify if the event was fired as part of the link integrity feature or not; I think that was Martin's idea.
@hvelarde like I said before.. he code Martin wrote don't work.. looking at the thread mentioned above, I presume it worked before, but now it is broken.
what I meant is that you should have looked for a solution in that direction: trying to find out which one was the right event to process.
here you are:
def deletion_confirmed():
"""Check if we are in the context of a delete confirmation event.
We need to be sure we're in the righ event to process it, as
`IObjectRemovedEvent` is raised up to three times: the first one
when the delete confirmation window is shown; the second when we
select the 'Delete' button; and the last, as part of the
redirection request to the parent container. Why? I have absolutely
no idea. If we select 'Cancel' after the first event, then no more
events are fired.
"""
request = getRequest()
is_delete_confirmation = 'delete_confirmation' in request.URL
is_post = request.REQUEST_METHOD == 'POST'
form_being_submitted = 'form.submitted' in request.form
return is_delete_confirmation and is_post and form_being_submitted
now just add the following to your event subscriber:
if not deletion_confirmed():
return
tested and working; now, if you want to find out why 3 IObjectRemovedEvent events are fired, go ahead…
Lot of time ago I reached a similar needs by inspecting the request's content.
Don't remember details (and it was Archetype based) but it was something like this: check if the confirm button is in the request. IIRC you'll find the button only once so you can execute your code one time only (or skip it when the button is here... depends on what you need to do).