Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

User state workflow engine in PHP

I'm looking to implement user state / workflow handling in a PHP application.

Currently have:

  • a user based system with around 10 different states any user can be in (enabled, disabled, pre-registered, de-registered, deleted etc.)
  • defined rules regarding from which state to which a user can go based on different system events
  • a rather messy (but mostly working) system full of IFs and SWITCHes scattered all across the place

Want to:

  • replace the current IFfy user state handling with a "clever" state machine that would allow to define those user transition rules
  • allow to visualise those defined rules
  • make the system more secure and bullet proof by making sure the user can only be in legal states

My research:

I checked both SO and other places for a PHP implementation of workflow and state machines and promising candidates seem to be

  • The PEAR FSM http://www.indelible.org/php/FSM/guide.html
  • or the eZ componenet Workflow http://ezcomponents.org/docs/api/trunk/introduction_Workflow.html

I'd be grateful for any comments regarding any experience with working with either of the libraries above and / or opinion regarding suitability for what I need or for hints to other places where to look to.

like image 888
poisson Avatar asked Nov 14 '22 16:11

poisson


1 Answers

Depending on how your states are setup, sounds like you could just setup a class system with a factory to handle all of this elegantly?

You could also setup your classes with state checking, which you could throw exceptions and basically make it impossible to instantiate the class (and therefore impossible to enter that state).

I'm thinking something like this might work for you:

class StateFactory {
    $currentState;

    function __construct(){
        if(!isset($_SESSION['currentState'])){
            $this->currentState = 'StateOne';
        }
        else{
            $this->currentState = $_SESSION['currentState'];
        }

        $this->currentState = new {$this->currentState}->processState(); // I think something like this will work
    }

    function __deconstruct(){
        $_SESSION['currentState'] = $this->currentState;
    }
}

abstract class State{
    abstract function processState();
}

class StateOne extends State{
    function processState(){
        if(<check what is needed for this state>){
            <do what you need to do for this state>
            return 'StateTwo';
        }
        else
        {
            return 'StateWhatever';
        }
    }
}    

class StateTwo extends State{
    function processState(){
        if(<check what is needed for this state>){
            <do what you need to do for this state>
            return 'StateThree';
        }
        else
        {
            return 'StateWhatever';
        }
    }
}    

class StateThree extends State{
    ...
}

Obviously a lot is missing from this and a lot needs to be done to make this into something you can actually work with, but if you split things up like this, it will not be as messy and you'll be able to know where each state is being checked and what is being checked for.

like image 102
afuzzyllama Avatar answered Dec 16 '22 02:12

afuzzyllama