collective.multiworkflow.api#

Workflow-aware equivalents of the plone.api workflow helpers.

Every signature is a pure superset of what plone.api.content offers today: called without workflow_id these behave exactly as their upstream counterparts, reading and driving review_state. Passing workflow_id addresses one specific workflow in the object's chain.

collective.multiworkflow.api.conflicting_permissions(obj: DexterityContent) dict[str, list[str]][source]#

Find permissions claimed by more than one workflow in the chain.

Concurrent workflows compose safely as long as the permission sets they manage are disjoint: DCWorkflowDefinition.updateRoleMappingsFor only rewrites the permissions listed in that workflow's own permissions, and executing a transition re-applies the mappings of the transitioning workflow alone.

A permission claimed by two workflows is therefore left as whichever of them transitioned last wrote it, and stays that way until the other one transitions or portal_workflow.updateRoleMappings() runs. Use this to audit a site — from an upgrade step, a test, or a debugging session — before trusting a chain's role mappings.

Parameters:

obj -- object whose chain is inspected.

Returns:

mapping of permission to the ids of the workflows managing it, in chain order. Permissions with a single claimant are omitted, so an empty mapping means the chain is conflict-free.

collective.multiworkflow.api.get_state(obj: DexterityContent, default: Any = <object object>, workflow_id: str | None = None) str[source]#

Get the object's current state, optionally in a specific workflow.

With no workflow_id this is plone.api.content.get_state: it returns review_state. workflow_id selects one workflow from the chain and returns the value of that workflow's state variable.

Parameters:
  • obj -- object to read the state of.

  • default -- returned if the object has no workflow at all.

  • workflow_id -- id of the workflow to read; None means the effective review_state.

Returns:

the current state id.

Raises:
  • InvalidParameterError -- if workflow_id is not registered.

  • WorkflowException -- if the state cannot be determined.

collective.multiworkflow.api.get_states(obj: DexterityContent) dict[str, str][source]#

Get the object's state in every workflow of its chain.

Parameters:

obj -- object to read the states of.

Returns:

mapping of workflow id to the current state id, in chain order.

collective.multiworkflow.api.owning_workflow(obj: DexterityContent) dict[str, str][source]#

Map every transition id in the object's chain to its owning workflow.

A transition id defined by more than one workflow is attributed to the first one in chain order, which is exactly how doActionFor resolves the collision.

Parameters:

obj -- object whose chain is inspected.

Returns:

mapping of transition id to workflow id.

collective.multiworkflow.api.transition(obj: DexterityContent, transition: str | None = None, to_state: str | None = None, workflow_id: str | None = None, **kwargs: Any) None[source]#

Perform a workflow transition, optionally on a specific workflow.

With no workflow_id the transition is routed exactly as plone.api.content.transition routes it — the first workflow in the chain that supports the id wins. Pass workflow_id to address a workflow whose transition id is shadowed by an earlier one in the chain.

Parameters:
  • obj -- object to transition.

  • transition -- id of the transition to perform.

  • to_state -- target state, as an alternative to transition. Only meaningful for the publication workflow, so it may not be combined with workflow_id.

  • workflow_id -- id of the workflow owning the transition.

  • kwargs -- passed through to the workflow, e.g. comment.

Raises:

InvalidParameterError -- if the transition or workflow is invalid, or if to_state and workflow_id are combined.

collective.multiworkflow.api.transitions(obj: DexterityContent) dict[str, list[str]][source]#

Get the transitions available to the current user, by workflow.

Parameters:

obj -- object to inspect.

Returns:

mapping of workflow id to the ids of its available transitions. Workflows with nothing available are omitted.