How to interrupt workflow transition in Plone

I am working on complex validation in the agility content type, which should check the dependencies between several fields during the transition of the workflow - I want it to work in SimplePublicationWorkflow, which runs when the content is sent from "private" to "pending".

I registered an event listener for IBeforeEvent and connected to it, but nothing that could be done before the exception was thrown could stop the transition. (and if you throw an exception there, it will be inactive and the user will see a page with an error instead of a special message).

So what is the recommended transition verification method in modern Plone? I came across documentation suggesting to add external methods that will be called in the Guard expression of the transition, but I would not want to use external methods, and if possible, I would like to support the default workflow. Creating a custom option is an option that provides a clean way of checking.

+4
source share
2 answers

The recommended method is to install protection.

A balanced expression should be able to look for a view to facilitate a more complex security code, but when the protector returns False , the transition does not even appear as available.

+3
source

For recording only; Today I found another use case and I monkey paid Products.DCWorkflow as proof of concept:

configure.zcml

 <configure xmlns="http://namespaces.zope.org/zope" xmlns:monkey="http://namespaces.plone.org/monkey"> <monkey:patch description="Allow aborting workflow transitions" class="Products.DCWorkflow.DCWorkflow.DCWorkflowDefinition" original="doActionFor" replacement=".patches.doActionFor" /> <subscriber for="Products.DCWorkflow.interfaces.IBeforeTransitionEvent" handler=".subscribers.validate_workflow_transition" /> </configure> 

subscribers.py

 def validate_workflow_transition(event): if not check_something(): raise MyException 

patches.py

 def doActionFor(self, ob, action, comment='', **kw): ... # XXX: above this everything is included without any changes # monkey patch replaces only the last line try: self._changeStateOf(ob, tdef, kw) except MyException: # do something pass 

The proof of concept worked as expected, but I was not happy with the final user interface, so I decided to follow Martijn's advice and re-execute everything as a guard; he will need additional code to establish protection in all related transitions of the workflow (and delete them when deleted), as well as view and view the browser to display a message explaining why the transition is not available, but in the end it will be cleaner.

0
source

Source: https://habr.com/ru/post/1494810/


All Articles