У меня здесь излишне запутанная ситуация. Я просто пытаюсь создать внутри этого WorkflowSubscriber метод, который проверяет переход события, создает переменную $guardMethod
, которая будет выглядеть примерно как guardToSomePlace
, а затем, если этот метод существует, вызовите ее. Вот код этой концепции:
<?php
namespace App\Listeners;
use App\Models\BugTypes\Bug;
use Symfony\Component\Workflow\Event\GuardEvent;
class BugWorkflowSubscriber
{
/**
* Handle workflow guard events.
*
* @param \Symfony\Component\Workflow\Event\GuardEvent $event
*/
public function onGuard(GuardEvent $event)
{
$transition = $event->getTransition();
$guardMethod = 'guard' . studly_case($transition->getName());
// this can be something like guardToAccepted and it
// calls guardToOnHold below
if (method_exists($this, $guardMethod)) { // should fail
$this->$guardMethod($event);
}
}
/**
* Guards the to_on_hold transition
*
* @param \Symfony\Workflow\Event\GuardEvent $event
*
* @return void
*/
private function guardToOnHold(GuardEvent $event)
{
dd('why is it getting here for other transitions?');
}
/**
* Register the listeners for the subscriber.
*
* @param \Illuminate\Events\Dispatcher $events
*/
public function subscribe($events)
{
$events->listen(
'workflow.bug.guard',
'App\Listeners\BugWorkflowSubscriber@onGuard'
);
$events->listen(
'workflow.bug.entered.*',
'App\Listeners\Workflow\Bug\OnEntered'
);
}
}
Он вызывает метод guardToOnHold
для нескольких переходов, несмотря на то, что я могу dd $event->getTransition()
, и это именно тот переход, который я ожидаю, и если я dd method_exists($this, $guardMethod)
, он будет ложным для любых / всех методов, кроме guardToOnHold
, поскольку это единственный, который будет существовать после Создаю переменную $guardMethod
. Если я поставлю method_exists($this, $guardMethod)
перед оператором if, он будет ложным, но если я вставлю его внутри оператора if с тем же событием / переходом, он попадет в оператор if и true
dd. Это Laravel 5.7 с использованием пакета Brexis / Laravel Symfony Workflow. Переход к событию всегда такой, каким я его ожидал. $event->getTransition()
всегда возвращает один объект перехода с правильным именем, от и до.
Я пробовал это. Он генерирует исключение для вызова неопределенного метода, как и следовало ожидать для любых переходов, у которых нет защиты.
Возможно несколько событий. Если я передаю строку, идентичную результату $transition->getName()
, она ведет себя правильно.
Если я поставил само событие, оно выглядит точным (с правильным местом и переходом). Это не учитывает возможность выпуска большего количества событий ...
Но вы dd
, а как насчет только dump
?
Я попробовал dump и print_r, чтобы он продолжал двигаться. Он просто выгружает / печатает одно событие.
На самом деле это связано с тем, что я исследую последние 3 дня. Что происходит в рабочем процессе symfony, когда вы применяете переход, он вызывает функцию getEnabledTransitions, которая, в свою очередь, вызывает метод doCan и вызывает guardTransition, теперь guardTransition отправляет событие workflow.guard, и поскольку у вас есть слушатель (onGuard), ваша функция получает называется.
Это то, что, я думаю, происходит. Я все еще не уверен на 100%, прав ли я и что нужно делать в таких случаях, возможно, мне нужно дополнительное расследование.
Соответствующий код:
// all taken from Symfony/Component/Workflow/Workflow.php
public function apply($subject, $transitionName)
{
$transitions = $this->getEnabledTransitions($subject);
public function getEnabledTransitions($subject)
{
$enabled = array();
$marking = $this->getMarking($subject);
foreach ($this->definition->getTransitions() as $transition) {
if ($this->doCan($subject, $marking, $transition)) {
$enabled[] = $transition;
}
}
return $enabled;
}
private function doCan($subject, Marking $marking, Transition $transition)
{
foreach ($transition->getFroms() as $place) {
if (!$marking->has($place)) {
return false;
}
}
if (true === $this->guardTransition($subject, $marking, $transition)) {
return false;
}
private function guardTransition($subject, Marking $marking, Transition $transition)
{
if (null === $this->dispatcher) {
return;
}
$event = new GuardEvent($subject, $marking, $transition, $this->name);
$this->dispatcher->dispatch('workflow.guard', $event);
Добавьте это здесь, чтобы это могло помочь кому-то в будущем.
Вы уверены, что он не выпускает одно событие за другим? Что произойдет, если вы позвоните в
$this->$guardMethod($event)
без проверкиif
?