/** * @param string $name * @param mixed $value * @throws CannotGuessEventException * @throws EventNotFoundException * @throws InvalidSchemaException * @throws TransitionException * @throws \yii\base\UnknownPropertyException * @throws exceptions\StateNotFoundException * @throws null */ public function __set($name, $value) { if ($name === $this->virtAttr) { $m = $this->owner; // Value did not change - ignore if ($m->{$this->attr} === $value) { return; } // First time? Initialize SM for $value state if ($m->{$this->attr} === null && $m->getIsNewRecord()) { if ($value !== $this->sm->getInitialStateValue()) { throw new InvalidValueException("This attribute is just entering the State Machine and must be set to {$this->sm->getInitialStateValue()}"); } $context = $this->initStateMachine(); } else { // Not first time, try to trigger for $value $state = $this->sm->getState($m->{$this->attr}); if (!$state) { throw new InvalidSchemaException("Cannot load current state {$m->{$this->attr}}"); } $event = $state->guessEvent($value, $this->internalGetUserRole(Yii::$app->user->identity)); $context = $this->trigger($event); } // Migrate the context errors to the virtual attribute foreach ($context->errors as $attr => $error) { $m->addError($this->virtAttr, $error); } } else { parent::__set($name, $value); } }
/** * @return State * @throws exceptions\InvalidSchemaException * @throws exceptions\StateNotFoundException */ public function getTargetState() { return $this->sm->getState($this->target); }
/** * @return interfaces\StateMachineEvent[] */ public function getPossibleEvents() { return $this->sm->getState($this->model->{$this->attr})->getEvents($this->role, $this); }