Skip to content

Instantly share code, notes, and snippets.

@victorjonsson
Last active November 11, 2016 15:22
Show Gist options
  • Select an option

  • Save victorjonsson/c9a89574d0d6bcad1ea5d1b093d16d4b to your computer and use it in GitHub Desktop.

Select an option

Save victorjonsson/c9a89574d0d6bcad1ea5d1b093d16d4b to your computer and use it in GitHub Desktop.

Revisions

  1. victorjonsson revised this gist Nov 11, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion fsm.php
    Original file line number Diff line number Diff line change
    @@ -135,7 +135,7 @@ function proccess(SomeEntity $data)
    break;
    default:
    throw new UnexpectedValueException(
    'Can not process when in state "'.$data->getState().'"'
    'Can not process data when in state "'.$data->getState().'"'
    );
    }
    }
  2. victorjonsson revised this gist Nov 11, 2016. 1 changed file with 6 additions and 5 deletions.
    11 changes: 6 additions & 5 deletions fsm.php
    Original file line number Diff line number Diff line change
    @@ -48,6 +48,7 @@ private function enterNewState($newState)
    }

    /**
    * Use this to execute a function before the new state is set
    * @param string $newState
    * @return callable|null
    */
    @@ -67,8 +68,8 @@ class SomeEntityHavingStateTransitions extends StateAbstract
    const STATE_C = '';

    protected static $stateTransitions = [
    ['to' => self::STATE_B, 'from'=>[self::STATE_A]],
    ['to' => self::STATE_C, 'from'=>[self::STATE_B]],
    ['to' => self::STATE_B, 'from' => [self::STATE_A]],
    ['to' => self::STATE_C, 'from' => [self::STATE_B]],
    ];

    protected function getStateTransitionCallback($newState) {
    @@ -94,9 +95,9 @@ class SomeEntity extends StateAbstract {
    const STATE_FAILED = 'FAILED';

    protected static $stateTransitions = [
    ['to' => self::STATE_IN_PROGRESS, 'from'=> [self::STATE_FAILED, self::STATE_INIT]],
    ['to' => self::STATE_FAILED, 'from'=> [self::STATE_IN_PROGRESS]]
    ['to' => self::STATE_SUCCESSFUL, 'from'=> [self::STATE_IN_PROGRESS]],
    ['to' => self::STATE_IN_PROGRESS, 'from' => [self::STATE_FAILED, self::STATE_INIT]],
    ['to' => self::STATE_FAILED, 'from' => [self::STATE_IN_PROGRESS]]
    ['to' => self::STATE_SUCCESSFUL, 'from' => [self::STATE_IN_PROGRESS]],
    ];

    public function transitionToInProgressState(DateTime $date, $data)
  3. victorjonsson revised this gist Nov 11, 2016. No changes.
  4. victorjonsson revised this gist Nov 11, 2016. 1 changed file with 5 additions and 5 deletions.
    10 changes: 5 additions & 5 deletions fsm.php
    Original file line number Diff line number Diff line change
    @@ -60,7 +60,7 @@ protected function getStateTransitionCallback($newState)
    trait StateTrait extends AbstractState {}


    class SomeEntityHavingState extends StateAbstract
    class SomeEntityHavingStateTransitions extends StateAbstract
    {
    const STATE_A = '';
    const STATE_B = '';
    @@ -87,7 +87,7 @@ public function setState($newState) {
    }
    }

    class DataWithState extends StateAbstract {
    class SomeEntity extends StateAbstract {

    const STATE_IN_PROGRESS = 'IN_PROGRESS';
    const STATE_SUCCESSFUL = 'SUCCESS';
    @@ -121,14 +121,14 @@ public function transitionToSuccessfulState(DateTime $date, $data)

    class DataProcessor {

    function proccess(DataWithState $data)
    function proccess(SomeEntity $data)
    {
    switch ($data->getState()) {
    case DataWithState::INIT_STATE:
    case SomeEntity::INIT_STATE:
    $data->transitionToInProgressState(new DateTime(), $this->fetchData());
    $this->doProcess($data);
    break;
    case DataWithState::STATE_FAILED:
    case SomeEntity::STATE_FAILED:
    $data->transitionToInProgressState(new DateTime(), $data->getData());
    $this->doProcess($data);
    break;
  5. victorjonsson revised this gist Nov 11, 2016. No changes.
  6. victorjonsson revised this gist Nov 11, 2016. 1 changed file with 15 additions and 3 deletions.
    18 changes: 15 additions & 3 deletions fsm.php
    Original file line number Diff line number Diff line change
    @@ -121,9 +121,21 @@ public function transitionToSuccessfulState(DateTime $date, $data)

    class DataProcessor {

    function proccess(DataWithState $data) {
    if ($data->getState() == DataWithState::INIT_STATE) {
    $fetchDat
    function proccess(DataWithState $data)
    {
    switch ($data->getState()) {
    case DataWithState::INIT_STATE:
    $data->transitionToInProgressState(new DateTime(), $this->fetchData());
    $this->doProcess($data);
    break;
    case DataWithState::STATE_FAILED:
    $data->transitionToInProgressState(new DateTime(), $data->getData());
    $this->doProcess($data);
    break;
    default:
    throw new UnexpectedValueException(
    'Can not process when in state "'.$data->getState().'"'
    );
    }
    }

  7. victorjonsson revised this gist Nov 11, 2016. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions fsm.php
    Original file line number Diff line number Diff line change
    @@ -49,7 +49,7 @@ private function enterNewState($newState)

    /**
    * @param string $newState
    * @return callable
    * @return callable|null
    */
    protected function getStateTransitionCallback($newState)
    {
    @@ -94,9 +94,9 @@ class DataWithState extends StateAbstract {
    const STATE_FAILED = 'FAILED';

    protected static $stateTransitions = [
    ['to' => self::STATE_IN_PROGRESS, 'from'=>[self::STATE_FAILED, self::STATE_INIT]],
    ['to' => self::STATE_FAILED, 'from' => ]
    ['to' => self::STATE_SUCCESSFUL, 'from'=>[self::STATE_IN_PROGRESS]],
    ['to' => self::STATE_IN_PROGRESS, 'from'=> [self::STATE_FAILED, self::STATE_INIT]],
    ['to' => self::STATE_FAILED, 'from'=> [self::STATE_IN_PROGRESS]]
    ['to' => self::STATE_SUCCESSFUL, 'from'=> [self::STATE_IN_PROGRESS]],
    ];

    public function transitionToInProgressState(DateTime $date, $data)
  8. victorjonsson revised this gist Nov 11, 2016. 1 changed file with 4 additions and 2 deletions.
    6 changes: 4 additions & 2 deletions fsm.php
    Original file line number Diff line number Diff line change
    @@ -51,8 +51,10 @@ private function enterNewState($newState)
    * @param string $newState
    * @return callable
    */
    abstract protected function getStateTransitionCallback($newState);

    protected function getStateTransitionCallback($newState)
    {
    return null;
    }
    }

    trait StateTrait extends AbstractState {}
  9. victorjonsson revised this gist Nov 11, 2016. 1 changed file with 4 additions and 5 deletions.
    9 changes: 4 additions & 5 deletions fsm.php
    Original file line number Diff line number Diff line change
    @@ -40,12 +40,11 @@ private function guardAgainstInvalidStateTransition()

    private function enterNewState($newState)
    {
    $callback = $this->getStateTransitionCallback();
    if (!is_callable($callback)) {
    throw new InvalidArgumentException();
    $callback = $this->getStateTransitionCallback($newState);
    if (is_callable($callback)) {
    call_user_func_array($callback, func_get_args());
    $this->currentState = $newState;
    }
    call_user_func_array($callback, func_get_args());
    $this->currentState = $newState;
    }

    /**
  10. victorjonsson revised this gist Nov 5, 2016. 1 changed file with 11 additions and 2 deletions.
    13 changes: 11 additions & 2 deletions fsm.php
    Original file line number Diff line number Diff line change
    @@ -86,7 +86,7 @@ public function setState($newState) {
    }
    }

    class OtherExampleOfEntityWithState extends StateAbstract {
    class DataWithState extends StateAbstract {

    const STATE_IN_PROGRESS = 'IN_PROGRESS';
    const STATE_SUCCESSFUL = 'SUCCESS';
    @@ -116,5 +116,14 @@ public function transitionToSuccessfulState(DateTime $date, $data)
    $this->transitionToNewState(self::STATE_SUCCESSFUL);
    $this->sucessfullDate = $date;
    }
    }

    class DataProcessor {

    function proccess(DataWithState $data) {
    if ($data->getState() == DataWithState::INIT_STATE) {
    $fetchDat
    }
    }

    }
    }
  11. victorjonsson revised this gist Nov 5, 2016. 1 changed file with 13 additions and 1 deletion.
    14 changes: 13 additions & 1 deletion fsm.php
    Original file line number Diff line number Diff line change
    @@ -1,11 +1,20 @@
    <?php

    abstract class StateAbstract {
    interface State {
    public function getState();
    }

    abstract class StateAbstract implements State {

    const STATE_INIT = 'STATE_INIT';

    protected $currentState = self::STATE_INIT;

    public function getState()
    {
    return $this->currentState;
    }

    protected function transitionToNewState($newState)
    {
    $this->guardAgainsInvalidStateTransition($newState);
    @@ -47,6 +56,9 @@ abstract protected function getStateTransitionCallback($newState);

    }

    trait StateTrait extends AbstractState {}


    class SomeEntityHavingState extends StateAbstract
    {
    const STATE_A = '';
  12. victorjonsson revised this gist Nov 5, 2016. 1 changed file with 19 additions and 1 deletion.
    20 changes: 19 additions & 1 deletion fsm.php
    Original file line number Diff line number Diff line change
    @@ -86,5 +86,23 @@ class OtherExampleOfEntityWithState extends StateAbstract {
    ['to' => self::STATE_SUCCESSFUL, 'from'=>[self::STATE_IN_PROGRESS]],
    ];


    public function transitionToInProgressState(DateTime $date, $data)
    {
    $this->transitionToNewState(self::STATE_IN_PROGRESS);
    $this->startedDate = $date;
    $this->data = $data;
    }

    public function transitionToFailedState(DateTime $date)
    {
    $this->transitionToNewState(self::STATE_FAILED);
    $this->failedDate = $date;
    }

    public function transitionToSuccessfulState(DateTime $date, $data)
    {
    $this->transitionToNewState(self::STATE_SUCCESSFUL);
    $this->sucessfullDate = $date;
    }

    }
  13. victorjonsson revised this gist Nov 5, 2016. 1 changed file with 21 additions and 1 deletion.
    22 changes: 21 additions & 1 deletion fsm.php
    Original file line number Diff line number Diff line change
    @@ -47,12 +47,17 @@ abstract protected function getStateTransitionCallback($newState);

    }

    class SomeStateable extends StateAbstract
    class SomeEntityHavingState extends StateAbstract
    {
    const STATE_A = '';
    const STATE_B = '';
    const STATE_C = '';

    protected static $stateTransitions = [
    ['to' => self::STATE_B, 'from'=>[self::STATE_A]],
    ['to' => self::STATE_C, 'from'=>[self::STATE_B]],
    ];

    protected function getStateTransitionCallback($newState) {
    switch ($newState) {
    case self::STATE_A:
    @@ -67,4 +72,19 @@ protected function getStateTransitionCallback($newState) {
    public function setState($newState) {
    $this->transitionToNewState($newState);
    }
    }

    class OtherExampleOfEntityWithState extends StateAbstract {

    const STATE_IN_PROGRESS = 'IN_PROGRESS';
    const STATE_SUCCESSFUL = 'SUCCESS';
    const STATE_FAILED = 'FAILED';

    protected static $stateTransitions = [
    ['to' => self::STATE_IN_PROGRESS, 'from'=>[self::STATE_FAILED, self::STATE_INIT]],
    ['to' => self::STATE_FAILED, 'from' => ]
    ['to' => self::STATE_SUCCESSFUL, 'from'=>[self::STATE_IN_PROGRESS]],
    ];


    }
  14. victorjonsson revised this gist Nov 5, 2016. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions fsm.php
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,5 @@
    <?php

    abstract class StateAbstract {

    const STATE_INIT = 'STATE_INIT';
  15. victorjonsson revised this gist Nov 5, 2016. 1 changed file with 25 additions and 6 deletions.
    31 changes: 25 additions & 6 deletions fsm.php
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,13 @@ abstract class StateAbstract {

    protected $currentState = self::STATE_INIT;

    protected function transitionToState($newState)
    protected function transitionToNewState($newState)
    {
    $this->guardAgainsInvalidStateTransition($newState);
    call_user_func_array([$this, 'enterNewState'], func_get_args());
    }

    private function guardAgainstInvalidStateTransition()
    {
    $validTransition = null;
    foreach (static::$stateTransitions as $transition) {
    @@ -19,12 +25,23 @@ protected function transitionToState($newState)
    } elseif (!$validTransition) {
    throw new InvalidStateTransationException(static::class, $this->currentState, $newState);
    }
    }

    call_user_func_array([$this, 'enterNewState'], func_get_args());
    $this->currentState = $newState;
    private function enterNewState($newState)
    {
    $callback = $this->getStateTransitionCallback();
    if (!is_callable($callback)) {
    throw new InvalidArgumentException();
    }
    call_user_func_array($callback, func_get_args());
    $this->currentState = $newState;
    }

    abstract protected function enterNewState($newState);
    /**
    * @param string $newState
    * @return callable
    */
    abstract protected function getStateTransitionCallback($newState);

    }

    @@ -34,10 +51,12 @@ class SomeStateable extends StateAbstract
    const STATE_B = '';
    const STATE_C = '';

    protected function enterNewState($newState) {
    protected function getStateTransitionCallback($newState) {
    switch ($newState) {
    case self::STATE_A:
    // do stuff...
    return function () {

    };
    break;
    // and so on...
    }
  16. victorjonsson revised this gist Nov 5, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion fsm.php
    Original file line number Diff line number Diff line change
    @@ -20,7 +20,7 @@ protected function transitionToState($newState)
    throw new InvalidStateTransationException(static::class, $this->currentState, $newState);
    }

    $this->enterNewState($newState);
    call_user_func_array([$this, 'enterNewState'], func_get_args());
    $this->currentState = $newState;
    }

  17. victorjonsson revised this gist Nov 5, 2016. 1 changed file with 16 additions and 17 deletions.
    33 changes: 16 additions & 17 deletions fsm.php
    Original file line number Diff line number Diff line change
    @@ -15,13 +15,16 @@ protected function transitionToState($newState)
    }

    if ($validTransition === null) {
    throw new DomainException('Unknown state');
    throw new UnknownStateException('Unknown state');
    } elseif (!$validTransition) {

    throw new InvalidStateTransationException(static::class, $this->currentState, $newState);
    }

    $this->enterNewState($newState);
    $this->currentState = $newState;
    }

    abstract protected function newStateCallback($newState);
    abstract protected function enterNewState($newState);

    }

    @@ -31,20 +34,16 @@ class SomeStateable extends StateAbstract
    const STATE_B = '';
    const STATE_C = '';

    protected static $stateTransitions = [
    ['to' => self::STATE_B, 'from' => [self::STATE_A]],
    ['to' => self::STATE_C, 'from' => [self::STATE_A, self::STATE_B]],
    ];
    protected function enterNewState($newState) {
    switch ($newState) {
    case self::STATE_A:
    // do stuff...
    break;
    // and so on...
    }
    }

    protected function getStateTransitions()
    {
    return [
    ['to'=>self::STATE_B, 'from'=>[self::STATE_A], 'callback' => function () {

    }],
    ['to'=>self::STATE_C, 'from'=>[self::STATE_B], 'callback' => function () {

    }],
    ];
    public function setState($newState) {
    $this->transitionToNewState($newState);
    }
    }
  18. victorjonsson revised this gist Nov 5, 2016. No changes.
  19. victorjonsson revised this gist Nov 5, 2016. 1 changed file with 15 additions and 3 deletions.
    18 changes: 15 additions & 3 deletions fsm.php
    Original file line number Diff line number Diff line change
    @@ -1,15 +1,27 @@
    abstract class StateAbstract {

    protected $state;
    const STATE_INIT = 'STATE_INIT';

    protected $currentState = self::STATE_INIT;

    protected function transitionToState($newState)
    {
    $validTransition = null;
    foreach (static::$stateTransitions as $transition) {
    if ($transition['to'] == $newState)
    if ($transition['to'] == $newState) {
    $validTransition = in_array($this->currentState, $transition['from']);
    break;
    }
    }

    if ($validTransition === null) {
    throw new DomainException('Unknown state');
    } elseif (!$validTransition) {

    }
    }

    protected function setState($newState);
    abstract protected function newStateCallback($newState);

    }

  20. victorjonsson revised this gist Nov 5, 2016. 1 changed file with 29 additions and 11 deletions.
    40 changes: 29 additions & 11 deletions fsm.php
    Original file line number Diff line number Diff line change
    @@ -1,20 +1,38 @@
    class StateAbstract {

    protected function isInState($state) {
    abstract class StateAbstract {

    protected $state;

    protected function transitionToState($newState)
    {
    foreach (static::$stateTransitions as $transition) {
    if ($transition['to'] == $newState)
    }
    }

    protected function transitionToState($newState) {
    protected function setState($newState);

    }
    }

    abstract function declareStates();
    class SomeStateable extends StateAbstract
    {
    const STATE_A = '';
    const STATE_B = '';
    const STATE_C = '';

    private function getStateTransitions()
    protected static $stateTransitions = [
    ['to' => self::STATE_B, 'from' => [self::STATE_A]],
    ['to' => self::STATE_C, 'from' => [self::STATE_A, self::STATE_B]],
    ];

    protected function getStateTransitions()
    {
    if ($this->stateTransitions === null) {
    $this->stateTransitions = $this->declareStates();
    }
    }
    return [
    ['to'=>self::STATE_B, 'from'=>[self::STATE_A], 'callback' => function () {

    }],
    ['to'=>self::STATE_C, 'from'=>[self::STATE_B], 'callback' => function () {

    }],
    ];
    }
    }
  21. victorjonsson revised this gist Nov 5, 2016. 1 changed file with 10 additions and 1 deletion.
    11 changes: 10 additions & 1 deletion fsm.php
    Original file line number Diff line number Diff line change
    @@ -4,8 +4,17 @@ protected function isInState($state) {

    }

    protected function transitionState($newState) {
    protected function transitionToState($newState) {

    }

    abstract function declareStates();

    private function getStateTransitions()
    {
    if ($this->stateTransitions === null) {
    $this->stateTransitions = $this->declareStates();
    }
    }

    }
  22. victorjonsson revised this gist Nov 4, 2016. No changes.
  23. victorjonsson created this gist Nov 4, 2016.
    11 changes: 11 additions & 0 deletions fsm.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,11 @@
    class StateAbstract {

    protected function isInState($state) {

    }

    protected function transitionState($newState) {

    }

    }