symfony Laravel WorkflowSubscriber类根据调用不正确方法的当前转换有条件地调用保护方法

qoefvg9y  于 2022-11-16  发布在  其他
关注(0)|答案(2)|浏览(149)

这里我遇到了一个不必要的复杂情况。我只是试图在这个WorkflowSubscriber中创建一个方法,该方法检查事件的转换,创建一个类似guardToSomePlace$guardMethod变量,然后如果该方法存在,就调用它。下面是该概念的代码:

<?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之外的任何/所有方法都是false,因为这是在我创建$guardMethod变量之后唯一存在的方法。如果我在if语句之前dd method_exists($this, $guardMethod),则是false。但是在if语句中使用相同的事件/转换将其添加到if语句和dd的true中。这是使用Brexis/Laravel Symfony工作流包的Laravel 5.7。事件的转换总是我所期望的。$event->getTransition()总是返回一个具有正确名称的转换对象,即froms和tos。

d4so4syb

d4so4syb1#

这实际上与我在过去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);

在这里添加这个,这样它可能会帮助别人在未来。

q1qsirdb

q1qsirdb2#

答案总是在文档中。当你订阅workflow.bug.guard时,它将被调用用于所有的转换。你应该用workflow.bug.guard.transition订阅特定的转换。

相关问题