Braindump

Php Workflow Classes

PHP Workflow Classes

This is a very simple approach to a general workflow framework in PHP. It may not even work, but it should be worth a try.

class SimpleWorkflow {
    private $transitions = array();
    private $initialStep = '';

    public function addStep($name) {
        if (array_key_exists($name, $this->transitions))
            throw new Exception("Step '$name' already present.");
        $this->transitions[$name] = array();
    }

    public function addTransition($from, $to) {
        if (!array_key_exists($from, $this->transitions))
            throw new Exception("Step '$from' does not exist.");
        if (!array_key_exists($to, $this->transitions))
            throw new Exception("Step '$to' does not exist.");
        $this->transitions[$from][] = $to;
    }

    public function transitionExists($from, $to) {
        if (!array_key_exists($from, $this->transitions)) return false;
        if (!array_key_exists($to, $this->transitions)) return false;
        return (in_array($to, $this->transitions[$from]));
    }

    public function getInitialStep() {
        return $this->initialStep;
    }

    public function setInitialStep($name) {
        if (!array_key_exists($name, $this->transitions))
            throw new Exception("Step '$name' does not exist.");
        $this->initialStep = $name;
    }
}

class SimpleWorkflowExecutor {
    private $workflow;
    private $currentStep = '';
    private $nextStep = '';
    private $valid = false;

    public function __construct(SimpleWorkflow $workflow, $currentStep, $nextStep) {
        $this->workflow = $workflow;
        $this->currentStep = $currentStep;
        $this->nextStep = $nextStep;
        $this->checkNextStep();
    }

    private function checkNextStep() {
        $this->valid = $this->workflow->transitionExists($this->currentStep, $this->nextStep);
    }

    public function getNextStep() {
        if (!$this->valid)
            return $this->workflow->getInitialStep();
        return $this->nextStep;
    }
}

Usage

function initShoppingCart() {
    $wf = new SimpleWorkflow();
    $wf->addStep('Select product');
    $wf->addStep('Show cart');
    $wf->addStep('Enter billing address');
    $wf->addStep('Select shipping');
    $wf->addStep('Confirm order');
    $wf->addStep('Process order');

    $wf->addTransition('Select product', 'Show cart');
    $wf->addTransition('Show cart', 'Select product');
    $wf->addTransition('Show cart', 'Enter billing address');
    $wf->addTransition('Enter billing address', 'Show cart');
    $wf->addTransition('Enter billing address', 'Select shipping');
    $wf->addTransition('Select shipping', 'Enter billing address');
    $wf->addTransition('Select shipping', 'Confirm order');
    $wf->addTransition('Confirm order', 'Select shipping');
    $wf->addTransition('Confirm order', 'Process order');

    $wf->setInitialStep('Select product');

    return $wf;
}

$shoppingCart = initShoppingcart();
$executor = new SimpleWorkflowExecutor($shoppingCart, $_POST['STEP'], $_POST['NEXT_STEP']);
$stepToExecute = $executor->getNextStep();