Workflow hints/actions
In trying to build this kind of workflow:

I was wondering if there's any way to push the workflow to the appropriate state, depending on which button the user pushes.
At first, I thought I could use allocateWorkItem, startWorkItem and completeWorkItem, as they accept an ActivityInterface parameter, but they also throw an exception when the passed activity is not the current flow object (why even have the parameter if it can only ever be one thing?)
The only possible solution I can think of is to set the condition on each connecting object to just be the action, and use the processData to set the "next" step. This seems horrifically messy though, especially when actual conditions come into place (which I would use the ExclusiveGateway for)
I'm not really certain how I would change workflow direction based on user input in a way that adheres to the BPMN standard either.
Thanks again.
Workflow branching can be done by conditional expressions using process data. Let's explain using the workflow LoanRequestProcess included in the Workflower package.

let's say the current activity of a process instance of the workflow is Check Applicant Information.
Somebody, that is the user that has the role Branch, does their work such as verifying the applicant's information, and tells the result to the BPM application.
Unfortunately the result was "rejected", the user clicks the "Reject" button to inform the BPM application of the result.
Then the BPM application updates the state of some object to reflect the result, and the activity Check Applicant Information is completed.
When the activity Check Applicant Information is completed, the token moves ahead to the exclusive gateway Result of Verification and the conditional expression rejected === true of the sequence flow Rejected is evaluated. rejected is the variable extracted from ProcessContextInterface::getProcessData() as the following:
<?php
// ...
// A database entity class that persists an instance of the workflow "LoanRequestProcess".
class LoanRequestProcess implements ProcessContextInterface
{
// ...
/**
* The data class for loan requests
*
* @var LoanRequest
*/
private $loanRequest;
public function getProcessData()
{
return [
'rejected' => $this->loanRequest->rejected,
];
}
This time the expression rejected === true is evaluated as true the token moves ahead to the end event through the sequence flow Rejected, and the process instance ends.
Thanks for the comprehensive reply!
That's very similar to the solution I mentioned briefly, but I ended up going a different direction. Main reason being that the workflow design process for me is user-facing, so I want to reduce complexity where possible, and having part of the input form be generated based on the diagram itself without requiring conditionals seems like it would make things simpler.
You can see my solution on my fork of the workflower bundle, where I've added a parameter to the completeWorkItem function in Workflow.php that allows the caller to sepcify the next flow target, if there are many. This is different to the Exclusive Gateway where user-defined conditions can be met.
I can see how this line of thought is incompatible with the bundle, so I won't be pushing this feature upstream.