mirror of
https://github.com/rectorphp/rector.git
synced 2025-04-21 16:02:23 +02:00
[SymfonyCodeQuality] From listener to subscriber (#1759)
[SymfonyCodeQuality] From listener to subscriber
This commit is contained in:
commit
bba9d1570e
@ -78,7 +78,8 @@
|
||||
"Rector\\ElasticSearchDSL\\": "packages/ElasticSearchDSL/src",
|
||||
"Rector\\SymfonyPHPUnit\\": "packages/SymfonyPHPUnit/src",
|
||||
"Rector\\Architecture\\": "packages/Architecture/src",
|
||||
"Rector\\PHPUnitSymfony\\": "packages/PHPUnitSymfony/src"
|
||||
"Rector\\PHPUnitSymfony\\": "packages/PHPUnitSymfony/src",
|
||||
"Rector\\SymfonyCodeQuality\\": "packages/SymfonyCodeQuality/src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
@ -118,7 +119,8 @@
|
||||
"Rector\\ElasticSearchDSL\\Tests\\": "packages/ElasticSearchDSL/tests",
|
||||
"Rector\\SymfonyPHPUnit\\Tests\\": "packages/SymfonyPHPUnit/tests",
|
||||
"Rector\\Architecture\\Tests\\": "packages/Architecture/tests",
|
||||
"Rector\\PHPUnitSymfony\\Tests\\": "packages/PHPUnitSymfony/tests"
|
||||
"Rector\\PHPUnitSymfony\\Tests\\": "packages/PHPUnitSymfony/tests",
|
||||
"Rector\\SymfonyCodeQuality\\Tests\\": "packages/SymfonyCodeQuality/tests"
|
||||
},
|
||||
"classmap": [
|
||||
"packages/Symfony/tests/Rector/FrameworkBundle/AbstractToConstructorInjectionRectorSource",
|
||||
@ -167,4 +169,4 @@
|
||||
"dev-master": "0.5-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
services:
|
||||
Rector\Symfony\Rector\BinaryOp\ResponseStatusCodeRector: ~
|
||||
Rector\Symfony\Rector\Class_\MakeCommandLazyRector: ~
|
||||
Rector\SymfonyCodeQuality\Rector\Class_\EventListenerToEventSubscriberRector: ~
|
||||
|
@ -0,0 +1,352 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\SymfonyCodeQuality\Rector\Class_;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\Array_;
|
||||
use PhpParser\Node\Expr\ArrayItem;
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use Rector\Bridge\Contract\AnalyzedApplicationContainerInterface;
|
||||
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
|
||||
use Rector\Rector\AbstractRector;
|
||||
use Rector\RectorDefinition\CodeSample;
|
||||
use Rector\RectorDefinition\RectorDefinition;
|
||||
use Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher;
|
||||
|
||||
/**
|
||||
* @see \Rector\SymfonyCodeQuality\Tests\Rector\Class_\EventListenerToEventSubscriberRector\EventListenerToEventSubscriberRectorTest
|
||||
*/
|
||||
final class EventListenerToEventSubscriberRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const EVENT_SUBSCRIBER_INTERFACE = 'Symfony\Component\EventDispatcher\EventSubscriberInterface';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const KERNEL_EVENTS_CLASS = 'Symfony\Component\HttpKernel\KernelEvents';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const CONSOLE_EVENTS_CLASS = 'Symfony\Component\Console\ConsoleEvents';
|
||||
|
||||
/**
|
||||
* @var string[][]
|
||||
*/
|
||||
private $eventNamesToClassConstants = [
|
||||
// kernel events
|
||||
'kernel.request' => [self::KERNEL_EVENTS_CLASS, 'REQUEST'],
|
||||
'kernel.exception' => [self::KERNEL_EVENTS_CLASS, 'EXCEPTION'],
|
||||
'kernel.view' => [self::KERNEL_EVENTS_CLASS, 'VIEW'],
|
||||
'kernel.controller' => [self::KERNEL_EVENTS_CLASS, 'CONTROLLER'],
|
||||
'kernel.controller_arguments' => [self::KERNEL_EVENTS_CLASS, 'CONTROLLER_ARGUMENTS'],
|
||||
'kernel.response' => [self::KERNEL_EVENTS_CLASS, 'RESPONSE'],
|
||||
'kernel.terminate' => [self::KERNEL_EVENTS_CLASS, 'TERMINATE'],
|
||||
'kernel.finish_request' => [self::KERNEL_EVENTS_CLASS, 'FINISH_REQUEST'],
|
||||
// console events
|
||||
'console.command' => [self::CONSOLE_EVENTS_CLASS, 'COMMAND'],
|
||||
'console.terminate' => [self::CONSOLE_EVENTS_CLASS, 'TERMINATE'],
|
||||
'console.error' => [self::CONSOLE_EVENTS_CLASS, 'ERROR'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @var AnalyzedApplicationContainerInterface
|
||||
*/
|
||||
private $analyzedApplicationContainer;
|
||||
|
||||
/**
|
||||
* @var mixed[][]
|
||||
*/
|
||||
private $listenerClassesToEvents = [];
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $areListenerClassesLoaded = false;
|
||||
|
||||
/**
|
||||
* @var DocBlockManipulator
|
||||
*/
|
||||
private $docBlockManipulator;
|
||||
|
||||
public function __construct(
|
||||
AnalyzedApplicationContainerInterface $analyzedApplicationContainer,
|
||||
DocBlockManipulator $docBlockManipulator
|
||||
) {
|
||||
$this->analyzedApplicationContainer = $analyzedApplicationContainer;
|
||||
$this->docBlockManipulator = $docBlockManipulator;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition(
|
||||
'Change Symfony Event listener class to Event Subscriber based on configuration in service.yaml file',
|
||||
[
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
<?php
|
||||
|
||||
class SomeListener
|
||||
{
|
||||
public function methodToBeCalled()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// in config.yaml
|
||||
services:
|
||||
SomeListener:
|
||||
tags:
|
||||
- { name: kernel.event_listener, event: 'some_event', method: 'methodToBeCalled' }
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
<?php
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
class SomeEventSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return ['some_event' => 'methodToBeCalled'];
|
||||
}
|
||||
|
||||
public function methodToBeCalled()
|
||||
{
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [Class_::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Class_ $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
// anonymous class
|
||||
if ($node->name === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// is already a subscriber
|
||||
if ($this->isAlreadyEventSubscriber($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// there must be event dispatcher in the application
|
||||
$listenerClassToEvents = $this->getListenerClassesToEventsToMethods();
|
||||
if ($listenerClassToEvents === []) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$className = $this->getName($node);
|
||||
if (! isset($listenerClassToEvents[$className])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->changeListenerToSubscriberWithMethods($node, $listenerClassToEvents[$className]);
|
||||
}
|
||||
|
||||
private function isAlreadyEventSubscriber(Class_ $class): bool
|
||||
{
|
||||
foreach ((array) $class->implements as $implement) {
|
||||
if ($this->isName($implement, 'Symfony\Component\EventDispatcher\EventSubscriberInterface')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[][]
|
||||
*/
|
||||
private function getListenerClassesToEventsToMethods(): array
|
||||
{
|
||||
if ($this->areListenerClassesLoaded) {
|
||||
return $this->listenerClassesToEvents;
|
||||
}
|
||||
|
||||
if (! $this->analyzedApplicationContainer->hasService('event_dispatcher')) {
|
||||
$this->areListenerClassesLoaded = true;
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/** @var TraceableEventDispatcher $applicationEventDispatcher */
|
||||
$applicationEventDispatcher = $this->analyzedApplicationContainer->getService('event_dispatcher');
|
||||
|
||||
foreach ($applicationEventDispatcher->getListeners() as $eventName => $listenersInEvent) {
|
||||
foreach ($listenersInEvent as $listener) {
|
||||
// must be array → class and method
|
||||
if (! is_array($listener)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$listenerClass = get_class($listener[0]);
|
||||
|
||||
// skip Symfony core listeners
|
||||
if (Strings::match($listenerClass, '#^(Symfony|Sensio|Doctrine)\\\\#')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$listenerPriority = $applicationEventDispatcher->getListenerPriority($eventName, $listener);
|
||||
|
||||
// group event name - method - class :)
|
||||
$this->listenerClassesToEvents[$listenerClass][$eventName][] = [$listener[1], $listenerPriority];
|
||||
}
|
||||
}
|
||||
|
||||
$this->areListenerClassesLoaded = true;
|
||||
|
||||
return $this->listenerClassesToEvents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $eventsToMethods
|
||||
*/
|
||||
private function changeListenerToSubscriberWithMethods(Class_ $class, array $eventsToMethods): Class_
|
||||
{
|
||||
$class->implements[] = new FullyQualified(self::EVENT_SUBSCRIBER_INTERFACE);
|
||||
|
||||
$classShortName = (string) $class->name;
|
||||
// remove suffix
|
||||
$classShortName = Strings::replace($classShortName, '#^(.*?)(Listener)?$#', '$1');
|
||||
$class->name = new Identifier($classShortName . 'EventSubscriber');
|
||||
|
||||
$clasMethod = $this->createGetSubscribedEventsClassMethod($eventsToMethods);
|
||||
$class->stmts[] = $clasMethod;
|
||||
|
||||
return $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return String_|ClassConstFetch
|
||||
*/
|
||||
private function createEventName(string $eventName): Node
|
||||
{
|
||||
if (class_exists($eventName)) {
|
||||
return $this->createClassConstantReference($eventName);
|
||||
}
|
||||
|
||||
// is string a that could be caught in constant, e.g. KernelEvents?
|
||||
if (isset($this->eventNamesToClassConstants[$eventName])) {
|
||||
[$class, $constant] = $this->eventNamesToClassConstants[$eventName];
|
||||
|
||||
return $this->createClassConstant($class, $constant);
|
||||
}
|
||||
|
||||
return new String_($eventName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[][] $eventsToMethods
|
||||
*/
|
||||
private function createGetSubscribedEventsClassMethod(array $eventsToMethods): ClassMethod
|
||||
{
|
||||
$getSubscribedEventsMethod = $this->nodeFactory->createPublicMethod('getSubscribedEvents');
|
||||
|
||||
$eventsToMethodsArray = new Array_();
|
||||
|
||||
$this->makeStatic($getSubscribedEventsMethod);
|
||||
|
||||
foreach ($eventsToMethods as $eventName => $methodNamesWithPriorities) {
|
||||
$eventName = $this->createEventName($eventName);
|
||||
|
||||
if (count($methodNamesWithPriorities) === 1) {
|
||||
$this->createSingleMethod($methodNamesWithPriorities, $eventName, $eventsToMethodsArray);
|
||||
} else {
|
||||
$this->createMultipleMethods($methodNamesWithPriorities, $eventName, $eventsToMethodsArray);
|
||||
}
|
||||
}
|
||||
|
||||
$getSubscribedEventsMethod->stmts[] = new Return_($eventsToMethodsArray);
|
||||
$this->decorateClassMethodWithReturnType($getSubscribedEventsMethod);
|
||||
|
||||
return $getSubscribedEventsMethod;
|
||||
}
|
||||
|
||||
private function decorateClassMethodWithReturnType(ClassMethod $classMethod): void
|
||||
{
|
||||
if ($this->isAtLeastPhpVersion('7.0')) {
|
||||
$classMethod->returnType = new Identifier('array');
|
||||
}
|
||||
|
||||
$this->docBlockManipulator->addReturnTag($classMethod, 'mixed[]');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassConstFetch|String_ $expr
|
||||
* @param mixed[] $methodNamesWithPriorities
|
||||
*/
|
||||
private function createSingleMethod(
|
||||
array $methodNamesWithPriorities,
|
||||
Node\Expr $expr,
|
||||
Array_ $eventsToMethodsArray
|
||||
): void {
|
||||
[$methodName, $priority] = $methodNamesWithPriorities[0];
|
||||
|
||||
if ($priority) {
|
||||
$methodNameWithPriorityArray = new Array_();
|
||||
$methodNameWithPriorityArray->items[] = new ArrayItem(new String_($methodName));
|
||||
$methodNameWithPriorityArray->items[] = new ArrayItem(new Node\Scalar\LNumber((int) $priority));
|
||||
|
||||
$eventsToMethodsArray->items[] = new ArrayItem($methodNameWithPriorityArray, $expr);
|
||||
} else {
|
||||
$eventsToMethodsArray->items[] = new ArrayItem(new String_($methodName), $expr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassConstFetch|String_ $expr
|
||||
* @param mixed[] $methodNamesWithPriorities
|
||||
*/
|
||||
private function createMultipleMethods(
|
||||
array $methodNamesWithPriorities,
|
||||
Node\Expr $expr,
|
||||
Array_ $eventsToMethodsArray
|
||||
): void {
|
||||
$multipleMethodsArray = new Array_();
|
||||
|
||||
foreach ($methodNamesWithPriorities as $methodNamesWithPriority) {
|
||||
[$methodName, $priority] = $methodNamesWithPriority;
|
||||
|
||||
if ($priority) {
|
||||
$methodNameWithPriorityArray = new Array_();
|
||||
$methodNameWithPriorityArray->items[] = new ArrayItem(new String_($methodName));
|
||||
$methodNameWithPriorityArray->items[] = new ArrayItem(new Node\Scalar\LNumber((int) $priority));
|
||||
|
||||
$multipleMethodsArray->items[] = new ArrayItem($methodNameWithPriorityArray);
|
||||
} else {
|
||||
$multipleMethodsArray->items[] = new ArrayItem(new String_($methodName));
|
||||
}
|
||||
}
|
||||
|
||||
$eventsToMethodsArray->items[] = new ArrayItem($multipleMethodsArray, $expr);
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\SymfonyCodeQuality\Tests\Rector\Class_\EventListenerToEventSubscriberRector;
|
||||
|
||||
use Rector\Configuration\Option;
|
||||
use Rector\SymfonyCodeQuality\Rector\Class_\EventListenerToEventSubscriberRector;
|
||||
use Rector\SymfonyCodeQuality\Tests\Rector\Class_\EventListenerToEventSubscriberRector\Source\ListenersKernel;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\PackageBuilder\Parameter\ParameterProvider;
|
||||
|
||||
final class EventListenerToEventSubscriberRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$parameterProvider = self::$container->get(ParameterProvider::class);
|
||||
$parameterProvider->changeParameter(Option::KERNEL_CLASS_PARAMETER, ListenersKernel::class);
|
||||
}
|
||||
|
||||
public function test(): void
|
||||
{
|
||||
// wtf: all test have to be in single file due to autoloading race-condigition and container creating issue of fixture
|
||||
$this->doTestFile(__DIR__ . '/Fixture/fixture.php.inc');
|
||||
}
|
||||
|
||||
protected function getRectorClass(): string
|
||||
{
|
||||
return EventListenerToEventSubscriberRector::class;
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\SymfonyCodeQuality\Tests\Rector\Class_\EventListenerToEventSubscriberRector\Fixture;
|
||||
|
||||
class SomeListener
|
||||
{
|
||||
public function methodToBeCalled()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class WithPriorityListener
|
||||
{
|
||||
public function callMe()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class MultipleMethods
|
||||
{
|
||||
public function callMe()
|
||||
{
|
||||
}
|
||||
|
||||
public function singles()
|
||||
{
|
||||
}
|
||||
|
||||
public function meToo()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\SymfonyCodeQuality\Tests\Rector\Class_\EventListenerToEventSubscriberRector\Fixture;
|
||||
|
||||
class SomeEventSubscriber implements \Symfony\Component\EventDispatcher\EventSubscriberInterface
|
||||
{
|
||||
public function methodToBeCalled()
|
||||
{
|
||||
}
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return ['some_event' => 'methodToBeCalled'];
|
||||
}
|
||||
}
|
||||
|
||||
class WithPriorityEventSubscriber implements \Symfony\Component\EventDispatcher\EventSubscriberInterface
|
||||
{
|
||||
public function callMe()
|
||||
{
|
||||
}
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return ['some_event' => ['callMe', 1540]];
|
||||
}
|
||||
}
|
||||
|
||||
class MultipleMethodsEventSubscriber implements \Symfony\Component\EventDispatcher\EventSubscriberInterface
|
||||
{
|
||||
public function callMe()
|
||||
{
|
||||
}
|
||||
|
||||
public function singles()
|
||||
{
|
||||
}
|
||||
|
||||
public function meToo()
|
||||
{
|
||||
}
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return ['single_event' => 'singles', 'multi_event' => ['callMe', 'meToo']];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,88 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\SymfonyCodeQuality\Tests\Rector\Class_\EventListenerToEventSubscriberRector\Source;
|
||||
|
||||
use Rector\SymfonyCodeQuality\Tests\Rector\Class_\EventListenerToEventSubscriberRector\Fixture\MultipleCallsListener;
|
||||
use Rector\SymfonyCodeQuality\Tests\Rector\Class_\EventListenerToEventSubscriberRector\Fixture\MultipleMethods;
|
||||
use Rector\SymfonyCodeQuality\Tests\Rector\Class_\EventListenerToEventSubscriberRector\Fixture\SomeListener;
|
||||
use Rector\SymfonyCodeQuality\Tests\Rector\Class_\EventListenerToEventSubscriberRector\Fixture\WithPriorityListener;
|
||||
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use Symfony\Component\HttpKernel\Kernel;
|
||||
|
||||
final class ListenersKernel extends Kernel
|
||||
{
|
||||
public function registerBundles(): iterable
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function registerContainerConfiguration(LoaderInterface $loader): void
|
||||
{
|
||||
}
|
||||
|
||||
protected function build(ContainerBuilder $containerBuilder): void
|
||||
{
|
||||
$eventDispatcherDefinition = $containerBuilder->register('event_dispatcher', EventDispatcher::class);
|
||||
|
||||
$this->registerSimpleListener($containerBuilder, $eventDispatcherDefinition);
|
||||
$this->registerWithPriority($containerBuilder, $eventDispatcherDefinition);
|
||||
$this->registerMultiple($containerBuilder, $eventDispatcherDefinition);
|
||||
}
|
||||
|
||||
public function getCacheDir()
|
||||
{
|
||||
return sys_get_temp_dir() . '/_tmp';
|
||||
}
|
||||
|
||||
public function getLogDir()
|
||||
{
|
||||
return sys_get_temp_dir() . '/_tmp';
|
||||
}
|
||||
|
||||
private function registerSimpleListener(ContainerBuilder $containerBuilder, Definition $eventDispatcherDefinition): void
|
||||
{
|
||||
$containerBuilder->register(SomeListener::class);
|
||||
|
||||
/* @see \Symfony\Component\EventDispatcher\EventDispatcher::addListener() */
|
||||
$eventDispatcherDefinition->addMethodCall(
|
||||
'addListener',
|
||||
['some_event', [new Reference(SomeListener::class), 'methodToBeCalled']]
|
||||
);
|
||||
}
|
||||
|
||||
private function registerWithPriority(ContainerBuilder $containerBuilder, Definition $eventDispatcherDefinition): void
|
||||
{
|
||||
$containerBuilder->register(WithPriorityListener::class);
|
||||
|
||||
/* @see \Symfony\Component\EventDispatcher\EventDispatcher::addListener() */
|
||||
$eventDispatcherDefinition->addMethodCall(
|
||||
'addListener',
|
||||
['some_event', [new Reference(WithPriorityListener::class), 'callMe'], 1540]
|
||||
);
|
||||
}
|
||||
|
||||
private function registerMultiple(ContainerBuilder $containerBuilder, Definition $eventDispatcherDefinition): void
|
||||
{
|
||||
$containerBuilder->register(MultipleMethods::class);
|
||||
|
||||
/* @see \Symfony\Component\EventDispatcher\EventDispatcher::addListener() */
|
||||
$eventDispatcherDefinition->addMethodCall(
|
||||
'addListener',
|
||||
['single_event', [new Reference(MultipleMethods::class), 'singles']]
|
||||
);
|
||||
|
||||
$eventDispatcherDefinition->addMethodCall(
|
||||
'addListener',
|
||||
['multi_event', [new Reference(MultipleMethods::class), 'callMe']]
|
||||
);
|
||||
|
||||
$eventDispatcherDefinition->addMethodCall(
|
||||
'addListener',
|
||||
['multi_event', [new Reference(MultipleMethods::class), 'meToo']]
|
||||
);
|
||||
}
|
||||
}
|
@ -177,3 +177,6 @@ parameters:
|
||||
- '#Parameter \#1 \$error_handler of function set_error_handler expects \(callable\)\|null, Closure\(mixed, mixed, mixed, mixed\)\: void given#'
|
||||
- '#Parameter \#1 \$error_handler of function set_error_handler expects \(callable\)\|null, callable given#'
|
||||
- '#Method Rector\\NodeTypeResolver\\PerNodeTypeResolver\\NameTypeResolver\:\:resolveFullyQualifiedName\(\) should return string\|null but returns PhpParser\\Node\\Name\|null#'
|
||||
|
||||
# array is callable
|
||||
- '#Parameter \#2 \$listener of method Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcher\:\:getListenerPriority\(\) expects callable\(\)\: mixed, array given#'
|
||||
|
Loading…
x
Reference in New Issue
Block a user