Repository: symfony/symfony
File: src/Symfony/Component/Workflow/Workflow.php (PHP)

Code before:
                return new TransitionBlockerList([
                    TransitionBlocker::createBlockedByMarking($marking),
                ]);
            }
        }

        if (null === $this->dispatcher) {
            return new TransitionBlockerList();
        }

        $event = $this->guardTransition($subject, $marking, $transition, $context);

        if ($event->isBlocked()) {
            return $event->getTransitionBlockerList();
        }

        return new TransitionBlockerList();
    }

    private function guardTransition(object $subject, Marking $marking, Transition $transition, array $context = []): ?GuardEvent
    {
        if (null === $this->dispatcher) {
            return null;
        }

        $event = new GuardEvent($subject, $marking, $transition, $this, $context);

        $this->dispatcher->dispatch($event, WorkflowEvents::GUARD);
        $this->dispatcher->dispatch($event, sprintf('workflow.%s.guard', $this->name));
        $this->dispatcher->dispatch($event, sprintf('workflow.%s.guard.%s', $this->name, $transition->getName()));

        return $event;
    }

    private function leave(object $subject, Transition $transition, Marking $marking, array $context = []): void
    {
        $places = $transition->getFroms();

        if (null !== $this->dispatcher) {
            $event = new LeaveEvent($subject, $marking, $transition, $this, $context);

            $this->dispatcher->dispatch($event, WorkflowEvents::LEAVE);
            $this->dispatcher->dispatch($event, sprintf('workflow.%s.leave', $this->name));

            foreach ($places as $place) {
                $this->dispatcher->dispatch($event, sprintf('workflow.%s.leave.%s', $this->name, $place));
            }
        }

        foreach ($places as $place) {
            $marking->unmark($place);

Review comment (bug):
For the guard event, I always refused to pass the workflow. Because people will use it to determine if the transition is enabled or not and this is wrong

Code after:
                return new TransitionBlockerList([
                    TransitionBlocker::createBlockedByMarking($marking),
                ]);
            }
        }

        if (null === $this->dispatcher) {
            return new TransitionBlockerList();
        }

        $event = $this->guardTransition($subject, $marking, $transition);

        if ($event->isBlocked()) {
            return $event->getTransitionBlockerList();
        }

        return new TransitionBlockerList();
    }

    private function guardTransition(object $subject, Marking $marking, Transition $transition): ?GuardEvent
    {
        if (null === $this->dispatcher) {
            return null;
        }

        $event = new GuardEvent($subject, $marking, $transition, $this);

        $this->dispatcher->dispatch($event, WorkflowEvents::GUARD);
        $this->dispatcher->dispatch($event, sprintf('workflow.%s.guard', $this->name));
        $this->dispatcher->dispatch($event, sprintf('workflow.%s.guard.%s', $this->name, $transition->getName()));

        return $event;
    }

    private function leave(object $subject, Transition $transition, Marking $marking, array $context = []): void
    {
        $places = $transition->getFroms();

        if (null !== $this->dispatcher) {
            $event = new LeaveEvent($subject, $marking, $transition, $this, $context);

            $this->dispatcher->dispatch($event, WorkflowEvents::LEAVE);
            $this->dispatcher->dispatch($event, sprintf('workflow.%s.leave', $this->name));

            foreach ($places as $place) {
                $this->dispatcher->dispatch($event, sprintf('workflow.%s.leave.%s', $this->name, $place));
            }
        }

        foreach ($places as $place) {
            $marking->unmark($place);