Overview

Namespaces

  • Mothership
    • Exception
      • StateMachine
    • StateMachine

Classes

  • Mothership\StateMachine\StateMachineAbstract
  • Mothership\StateMachine\Status
  • Mothership\StateMachine\Transition
  • Mothership\StateMachine\WorkflowAbstract

Interfaces

  • Mothership\StateMachine\StateMachineInterface
  • Mothership\StateMachine\StatusInterface
  • Mothership\StateMachine\TransitionInterface
  • Mothership\StateMachine\WorkflowInterface

Exceptions

  • Mothership\Exception\ExceptionAbstract
  • Mothership\Exception\StateMachine\StateMachineAdapterException
  • Mothership\Exception\StateMachine\StateMachineException
  • Mothership\Exception\StateMachine\StatusException
  • Mothership\Exception\StateMachine\TransitionException
  • Mothership\Exception\StateMachine\WorkflowException
  • Overview
  • Namespace
  • Class
  1: <?php
  2: /**
  3:  * Magento
  4:  *
  5:  * NOTICE OF LICENSE
  6:  *
  7:  * This source file is subject to the Open Software License (OSL 3.0)
  8:  * that is bundled with this package in the file LICENSE.txt.
  9:  * It is also available through the world-wide-web at this URL:
 10:  * http://opensource.org/licenses/osl-3.0.php
 11:  * If you did not receive a copy of the license and are unable to
 12:  * obtain it through the world-wide-web, please send an email
 13:  * to license@magentocommerce.com so we can send you a copy immediately.
 14:  *
 15:  * DISCLAIMER
 16:  *
 17:  * Do not edit or add to this file if you wish to upgrade Magento to newer
 18:  * versions in the future. If you wish to customize Magento for your
 19:  * needs please refer to http://www.magentocommerce.com for more information.
 20:  *
 21:  * @category  Mothership
 22:  * @package   Mothership_StateMachine
 23:  * @author    Maurizio Brioschi <brioschi@mothership.de>
 24:  * @copyright Copyright (c) 2015 Mothership GmbH
 25:  * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 26:  * @link      http://www.mothership.de/
 27:  */
 28: 
 29: namespace Mothership\StateMachine;
 30: 
 31: 
 32: use Mothership\StateMachine\StatusInterface;
 33: use Mothership\Exception\StateMachine\StatusException;
 34: use Mothership\StateMachine\TransitionInterface;
 35: use Mothership\StateMachine\WorkflowInterface;
 36: use Mothership\StateMachine\Transition;
 37: 
 38: class Status implements StatusInterface
 39: {
 40: 
 41:     /**
 42:      * @var array
 43:      */
 44:     protected $properties;
 45:     protected $types = ['initial', 'normal', 'final'];
 46:     private $workflow;
 47:     protected $internalState;
 48: 
 49:     protected $transitions = array();
 50: 
 51: 
 52:     public function __construct(WorkflowInterface $workflow, array $properties = [])
 53:     {
 54:         $this->workflow = $workflow;
 55:         $this->properties = $properties;
 56:         $this->transitions = $this->getTransitions();
 57:     }
 58: 
 59:     /**
 60:      * @return mixed
 61:      * @throws StatusException
 62:      */
 63:     public function getName()
 64:     {
 65:         if (!$this->has('name')) {
 66:             throw new StatusException("Status without a name", 100, null,
 67:                 $this->getWorkflow()->getOutput());
 68:         }
 69:         return $this->properties['name'];
 70:     }
 71: 
 72:     /**
 73:      * @return mixed
 74:      * @throws StatusException
 75:      */
 76:     public function getType()
 77:     {
 78:         if (!$this->has('type')) {
 79:             throw new StatusException("Status without a type", 100, null,
 80:                 $this->getWorkflow()->getOutput());
 81:         }
 82:         if (!in_array($this->properties['type'], $this->types)) {
 83:             throw new StatusException("The type specified is invalid", 100, null,
 84:                 $this->getWorkflow()->getOutput());
 85:         }
 86:         return $this->properties['type'];
 87:     }
 88: 
 89:     /**
 90:      * Get if is an initial state
 91:      * @return bool
 92:      * @throws StatusException
 93:      */
 94:     protected function isInitialType()
 95:     {
 96:         return $this->getType() == 'initial';
 97:     }
 98: 
 99:     /**
100:      * @return mixed
101:      * @throws Exception
102:      * @throws StatusException
103:      */
104:     public function getTransitions()
105:     {
106:         if (count($this->transitions) == 0 && !$this->isInitialType()) {
107:             if (!$this->has('transitions_to')) {
108:                 throw new StatusException("Status " . $this->getName() . " without transitions_to property", 80, null,
109:                     $this->getWorkflow()->getOutput());
110:             }
111:             if (!$this->has('transitions_from')) {
112:                 throw new StatusException("Status " . $this->getName() . " without transitions_from property", 81, null,
113:                     $this->getWorkflow()->getOutput());
114:             }
115: 
116:             foreach ($this->properties['transitions_from'] as $transition) {
117:                 array_push($this->transitions, new Transition($this, $transition));
118:             }
119: 
120:             if (count($this->transitions) == 0) {
121:                 throw new StatusException("Status " . $this->getName() . " has transition_from property not maching the name",
122:                     85, null,
123:                     $this->getWorkflow()->getOutput());
124:             }
125:         } else if ($this->isInitialType()) {
126:             $this->transitions = [];
127:         }
128:         return $this->transitions;
129:     }
130: 
131:     /**
132:      * @param $transition_name
133:      * @param \Mothership\StateMachine\StatusInterface $current_status
134:      * @return bool
135:      * @throws StatusException
136:      * @internal param \Mothership\StateMachine\TransictionInterface $transition
137:      */
138:     public function execute($transition_name, StatusInterface $current_status)
139:     {
140:         foreach ($this->transitions as $t) {
141:             if ($t->hasCondition()) {
142:                 if ($t->getTransitionFrom() == $current_status->getName() && $t->getName() == $transition_name &&
143:                     $this->workflow->getStatus($current_status->getName())->getInternalStatus() == $t->getCondition()
144:                 ) {
145:                     return $t->process();
146:                 } else if ($this->workflow->getStatus($current_status->getName())->getInternalStatus() != $t->getCondition()) {
147:                     throw new StatusException("STATUS: [" . $transition_name . "] cant't run from [" . $current_status->getName()
148:                         . "] for a different internalState of [" . $current_status->getName() . " => current internal
149:                         State: "
150:                         . $this->workflow->getStatus($current_status->getName())->getInternalStatus() . ", Status
151:                         need: " . $t->getCondition() . " ]",
152:                         10,
153:                         null,
154:                         $this->getWorkflow()->getOutput());
155:                 }
156:             } else {
157:                 if ($t->getTransitionFrom() == $current_status->getName() && $t->getName() == $transition_name) {
158:                     return $t->process();
159:                 }
160:             }
161:         }
162:         throw new StatusException("STATUS: [" . $transition_name . "] can't run from [" . $current_status->getName() . "]", 30,
163:             null,
164:             $this->getWorkflow()->getOutput());
165:     }
166: 
167:     /**
168:      * @param string $property
169:      *
170:      * @return boolean
171:      */
172:     public function has($property)
173:     {
174:         return array_key_exists($property, $this->properties);
175:     }
176: 
177:     /**
178:      * @param $property
179:      * @return mixed
180:      * @throws StatusException
181:      */
182:     public function get($property)
183:     {
184:         if (!$this->has($property)) {
185:             throw new StatusException("Status without a property: " . $property, 90, null,
186:                 $this->getWorkflow()->getOutput());
187:         }
188:         return $this->properties[$property];
189:     }
190: 
191:     /**
192:      * Returns optional state properties
193:      *
194:      * @return mixed
195:      */
196:     public function getProperties()
197:     {
198:         return $this->getProperties();
199:     }
200: 
201:     /**
202:      * @return WorkflowInterface
203:      */
204:     public function getWorkflow()
205:     {
206:         return $this->workflow;
207:     }
208: 
209:     /**
210:      * Set the internal status, useful if the next step need a condition to be executed
211:      * @param $state
212:      * @return mixed
213:      */
214:     public function setInternalStatus($state)
215:     {
216:         $this->internalState = $state;
217:     }
218: 
219:     /**
220:      * Get the internal status
221:      * @return mixed
222:      */
223:     public function getInternalStatus()
224:     {
225:         return $this->internalState;
226:     }
227: 
228:     public function hasInternalState()
229:     {
230:         if (!isset($this->internalState) || !isnull($this->internalState)) {
231:             return true;
232:         }
233:         return false;
234:     }
235: }
236: 
API documentation generated by ApiGen