/** * @param StateMachineContext $context * @param StateMachineEvent|null $event - this is null when an item enters the SM for the first time * @return static */ public static function nu(StateMachineContext $context, $event) { $j = new static(); $m = $context->getModel(); $j->role = $context->getRole(); $user = $context->getUser(); if ($user) { $j->created_by = $user->getId(); } $j->model = $m::className(); $j->sm_name = $context->getSm()->name; $j->attr = $context->getAttr(); $j->model_pk = $context->getModelPk(); if ($event) { $j->from_state = $event->getState()->getValue(); $j->to_state = $event->getTargetState()->getValue(); } else { $j->from_state = null; $j->to_state = $context->getSm()->getInitialStateValue(); } $j->save(); return $j; }
/** * Call this when a model is entering the state machine for the first time. * @param StateMachineContext $context * @return bool * @throws Exception * @throws \yii\db\Exception */ public function initStateMachineAttribute(StateMachineContext $context) { /** @var yii\db\Transaction|false $txn */ $txn = $this->useTransactions ? $context->getModel()->getDb()->beginTransaction() : false; try { // Entering state... $context->getModel()->{$context->getAttr()} = $this->getInitialStateValue(); $state = $this->getState($this->getInitialStateValue()); foreach ($state->getEnterCommands() as $command) { if (!$command->execute($context)) { $txn && $txn->rollBack(); return false; } } // Register the new timeouts foreach ($state->getTimeOuts() as $timeout) { $timeout->register($context); } // Persist the context's model data $context->getModel()->save(); // Update Journal - if applicable if ($this->modelJournal) { $journal = $this->modelJournal; /** @var StateMachineJournal $journal */ $journal::nu($context, null); } $txn && $txn->commit(); // transition completed successfully return true; } catch (Exception $e) { $txn && $txn->rollBack(); $context->attachException($e); throw $e; } }