diff --git a/config/rector/sets/cakephp60.php b/config/rector/sets/cakephp60.php index 0aff07bd..6410f218 100644 --- a/config/rector/sets/cakephp60.php +++ b/config/rector/sets/cakephp60.php @@ -1,6 +1,7 @@ rule(EventManagerOnRector::class); // Changes related to the accessible => patchable rename $rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [ diff --git a/src/Rector/Rector/MethodCall/EventManagerOnRector.php b/src/Rector/Rector/MethodCall/EventManagerOnRector.php new file mode 100644 index 00000000..18ced45e --- /dev/null +++ b/src/Rector/Rector/MethodCall/EventManagerOnRector.php @@ -0,0 +1,75 @@ +on('Model.beforeSave', ['priority' => 90], $callable); +CODE_SAMPLE + , + <<<'CODE_SAMPLE' +$eventManager->on('Model.beforeSave', $callable, ['priority' => 90]); +CODE_SAMPLE, + ), + ], + ); + } + + /** + * @return array> + */ + public function getNodeTypes(): array + { + return [MethodCall::class]; + } + + /** + * @param \PhpParser\Node\Expr\MethodCall $node + */ + public function refactor(Node $node): ?Node + { + // Check if this is a call to the 'on' method + if (!$this->isName($node->name, 'on')) { + return null; + } + + // Check if the object implements EventManagerInterface + if (!$this->isObjectType($node->var, new ObjectType('Cake\Event\EventManagerInterface'))) { + return null; + } + + // Only process if there are exactly 3 arguments + if (count($node->args) !== 3) { + return null; + } + + // Swap the 2nd and 3rd arguments + $secondArg = $node->args[1]; + $thirdArg = $node->args[2]; + + $node->args[1] = $thirdArg; + $node->args[2] = $secondArg; + + return $node; + } +} diff --git a/tests/TestCase/Rector/MethodCall/EventManagerOnRector/EventManagerOnRectorTest.php b/tests/TestCase/Rector/MethodCall/EventManagerOnRector/EventManagerOnRectorTest.php new file mode 100644 index 00000000..074c8dcf --- /dev/null +++ b/tests/TestCase/Rector/MethodCall/EventManagerOnRector/EventManagerOnRectorTest.php @@ -0,0 +1,28 @@ +doTestFile($filePath); + } + + public static function provideData(): Iterator + { + return self::yieldFilesFromDirectory(__DIR__ . '/Fixture'); + } + + public function provideConfigFilePath(): string + { + return __DIR__ . '/config/configured_rule.php'; + } +} diff --git a/tests/TestCase/Rector/MethodCall/EventManagerOnRector/Fixture/fixture.php.inc b/tests/TestCase/Rector/MethodCall/EventManagerOnRector/Fixture/fixture.php.inc new file mode 100644 index 00000000..71ef3bd2 --- /dev/null +++ b/tests/TestCase/Rector/MethodCall/EventManagerOnRector/Fixture/fixture.php.inc @@ -0,0 +1,67 @@ +on('Model.beforeSave', ['priority' => 90], $callable); + + // Should be transformed - 3 arguments with different options + $eventManager->on('Controller.initialize', ['priority' => 10], function () { + return true; + }); + + // Should NOT be transformed - 2 arguments + $eventManager->on('Model.afterSave', $callable); + + // Should NOT be transformed - 1 argument + $eventManager->on('Model.afterDelete'); + + // Should be transformed - 3 arguments with variable + $options = ['priority' => 100]; + $eventManager->on('Model.beforeFind', $options, $handler); + } +} + +?> +----- +on('Model.beforeSave', $callable, ['priority' => 90]); + + // Should be transformed - 3 arguments with different options + $eventManager->on('Controller.initialize', function () { + return true; + }, ['priority' => 10]); + + // Should NOT be transformed - 2 arguments + $eventManager->on('Model.afterSave', $callable); + + // Should NOT be transformed - 1 argument + $eventManager->on('Model.afterDelete'); + + // Should be transformed - 3 arguments with variable + $options = ['priority' => 100]; + $eventManager->on('Model.beforeFind', $handler, $options); + } +} + +?> diff --git a/tests/TestCase/Rector/MethodCall/EventManagerOnRector/config/configured_rule.php b/tests/TestCase/Rector/MethodCall/EventManagerOnRector/config/configured_rule.php new file mode 100644 index 00000000..84e5dd29 --- /dev/null +++ b/tests/TestCase/Rector/MethodCall/EventManagerOnRector/config/configured_rule.php @@ -0,0 +1,9 @@ +rule(EventManagerOnRector::class); +};