Skip to content

Commit 3a4828e

Browse files
authored
Merge pull request #377 from cakephp/fix-event-manager-rector-idempotency
Fix EventManagerOnRector idempotency issue
2 parents a92c66d + b79503a commit 3a4828e

3 files changed

Lines changed: 56 additions & 0 deletions

File tree

src/Rector/Cake6/EventManagerOnRector.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
namespace Cake\Upgrade\Rector\Cake6;
55

66
use PhpParser\Node;
7+
use PhpParser\Node\Expr\Array_;
8+
use PhpParser\Node\Expr\ArrowFunction;
9+
use PhpParser\Node\Expr\Closure;
710
use PhpParser\Node\Expr\MethodCall;
811
use PHPStan\Type\ObjectType;
912
use Rector\Rector\AbstractRector;
@@ -63,6 +66,19 @@ public function refactor(Node $node): ?Node
6366
return null;
6467
}
6568

69+
$secondArgValue = $node->args[1]->value;
70+
$thirdArgValue = $node->args[2]->value;
71+
72+
// Skip if already transformed - 2nd arg is a callable expression (new format)
73+
if ($this->isCallableExpression($secondArgValue)) {
74+
return null;
75+
}
76+
77+
// Skip if already transformed - 3rd arg is array literal (new format)
78+
if ($thirdArgValue instanceof Array_) {
79+
return null;
80+
}
81+
6682
// Swap the 2nd and 3rd arguments
6783
$secondArg = $node->args[1];
6884
$thirdArg = $node->args[2];
@@ -72,4 +88,12 @@ public function refactor(Node $node): ?Node
7288

7389
return $node;
7490
}
91+
92+
/**
93+
* Check if the expression is a callable (Closure or ArrowFunction).
94+
*/
95+
private function isCallableExpression(Node\Expr $expr): bool
96+
{
97+
return $expr instanceof Closure || $expr instanceof ArrowFunction;
98+
}
7599
}

tests/TestCase/Rector/MethodCall/EventManagerOnRector/Fixture/fixture.php.inc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ class Fixture
2727
// Should be transformed - 3 arguments with variable
2828
$options = ['priority' => 100];
2929
$eventManager->on('Model.beforeFind', $options, $handler);
30+
31+
// Should be transformed - 3 arguments with arrow function as 3rd arg
32+
$eventManager->on('Model.beforeValidate', ['priority' => 50], fn($event) => true);
3033
}
3134
}
3235

@@ -61,6 +64,9 @@ class Fixture
6164
// Should be transformed - 3 arguments with variable
6265
$options = ['priority' => 100];
6366
$eventManager->on('Model.beforeFind', $handler, $options);
67+
68+
// Should be transformed - 3 arguments with arrow function as 3rd arg
69+
$eventManager->on('Model.beforeValidate', fn($event) => true, ['priority' => 50]);
6470
}
6571
}
6672

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Cake\Upgrade\Test\TestCase\Rector\MethodCall\EventManagerOnRector\Fixture;
4+
5+
use Cake\Event\EventManager;
6+
7+
class SkipAlreadyTransformed
8+
{
9+
public function run()
10+
{
11+
$eventManager = EventManager::instance();
12+
13+
// Should NOT be transformed - already in new format with closure as 2nd arg
14+
$eventManager->on('Model.beforeSave', function ($event) {
15+
return true;
16+
}, ['priority' => 90]);
17+
18+
// Should NOT be transformed - already in new format with arrow function as 2nd arg
19+
$eventManager->on('Controller.initialize', fn($event) => true, ['priority' => 10]);
20+
21+
// Should NOT be transformed - already in new format with variable callable
22+
$eventManager->on('Model.beforeFind', $callable, ['priority' => 100]);
23+
}
24+
}
25+
26+
?>

0 commit comments

Comments
 (0)