/** * @param StateMachineInterface $sm * @param string $event * @param callable $callback * @param array $specs * * @return $this */ protected function add(StateMachineInterface $sm, $event, $callback, array $specs) { $specs = $this->processSpecs($specs); $listener = function (TransitionEvent $e) use($sm, $callback, $specs) { if ($sm !== $e->getStateMachine()) { return; } if (!(in_array(CallbackHandler::ALL, $specs['to']) || in_array($e->getTransition()->getState(), $specs['to']))) { return; } if (!(in_array(CallbackHandler::ALL, $specs['from']) || in_array($e->getInitialState()->getName(), $specs['from']))) { return; } if (in_array($e->getTransition()->getState(), $specs['exclude_to'])) { return; } if (in_array($e->getInitialState()->getName(), $specs['exclude_from'])) { return; } call_user_func($callback, $sm->getObject(), $e); }; $events = array($event); if (count($specs['on']) > 0 && !in_array(self::ALL, $specs['on'])) { $events = array_map(function ($v) use($event) { return $event . '.' . $v; }, $specs['on']); } foreach ($events as $event) { $this->dispatcher->addListener($event, $listener); } return $this; }