PHP code example of coff / state-machine-framework

1. Go to this page and download the library: Download coff/state-machine-framework library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

coff / state-machine-framework example snippets


    
    /**
     * @method static DRAFT()
     * @method static SENT()
     * ... // this should make your IDE believe these methods exist
     *
     */
    class PetitionEnum extends StateEnum {
        const __default     = self::DRAFT,
              DRAFT         = 'draft',
              SENT          = 'sent',
              VOTED         = 'voted',
              ACCEPTED      = 'accepted',
              REJECTED      = 'rejected',
              CANCELED      = 'canceled';
              
              // States names should be defined lowercase without spaces and special characters due to 
              // automatically determined assertion method names when in use with DefaultCallbackAssertion
              // @todo replace DefaultCallbackAssertion behavior in this matter 
              
    }

    class Petition extends Machine {
        
        protected $votesYes, $votesNo;
    
        public function init() {
            $this->setInitState(PetitionEnum::DRAFT());
            
            // defines machine's allowed behavior
            $this
                // prevents changing state upon assertion when AlwaysFalseAssertion is given
                ->allowTransition(PetitionEnum::DRAFT(), PetitionEnum::SENT(), new AlwaysFalseAssertion())
                ->allowTransition(PetitionEnum::DRAFT(), PetitionEnum::CANCELED(), new AlwaysFalseAssertion())
                
                // when no Assertion is given uses DefaultCallbackAssertion which calls assertXToY methods
                ->allowTransition(PetitionEnum::SENT(), PetitionEnum::VOTED())
                ->allowTransition(PetitionEnum::VOTED(), PetitionEnum::ACCEPTED())
                ->allowTransition(PetitionEnum::VOTED(), PetitionEnum::REJECTED())
                ;
            
        }
        
        public function send() 
        {
            // shall throw an exception if current state is not DRAFT because it wasn't allowed transition
            $this->setMachineState(PetitionEnum::SENT());
        }
        
        public function cancel() 
        {
            // shall throw an exception if current state is not DRAFT because it wasn't allowed transition
            $this->setMachineState(PetitionEnum::CANCELED());
        }

        
        public function setVotes($ya, $nay) 
        {
            $this->votesYes = $ya;
            $this->votesNo = $nay;
        }
        
        public function assertSentToVoted() 
        {
            // Method name used here is based upon DefaultCallbackAssertion. This can be changed though.
            return (null !== $this->votesYes && null !== $this->votesNo) ? true : false;
        }
        
        
        public function assertVotedToAccepted()
        {
            // condition for transition from state VOTED to ACCEPTED
            return $this->votesYes > $this->votesNo ? true : false;
        }
        
        public function assertVotedToRejected() 
        {
            // condition for transition from state VOTED to REJECTED
            return $this->votesYes <= $this->votesNo ? true : false;
        }
        
        public function onTransition(Transition $transition) 
        {
            // for purpose of this example we only echo this transition but you can easily dispatch an event from here 
            echo 'State changed from ' . $transition->getFromState() . ' to ' . $transition->getToState() . PHP_EOL;
        }
    }


    $p = new Petition();
    $p->init();
    
    $p->run();
    // <nothing happens>
    
    $p->send();
    // State changed from draft to sent
    
    $p->run();
    // <nothing happens>
    
    $p->setVotes(5,1);
    
    $p->run();
    // State changed from sent to voted
    // State changed from voted to accepted
    

    $machine
        ->allowTransition(MachineEnum::ONE(), MachineEnum::TWO(), new AlwaysTrueAssertion)
        ->allowTransition(MachineEnum::TWO(), MachineEnum::ONE(), new AlwaysTrueAssertion)
        
    $machine->run();
    // this will result in endless loop of state changes