diff --git a/config/rector/sets/cakephp60.php b/config/rector/sets/cakephp60.php index c0ecf71..7a1cd44 100644 --- a/config/rector/sets/cakephp60.php +++ b/config/rector/sets/cakephp60.php @@ -6,6 +6,7 @@ use Cake\Upgrade\Rector\Cake6\RemoveAssignmentFromVoidMethodRector; use Cake\Upgrade\Rector\Cake6\ReplaceCommandArgsIoWithPropertiesRector; use Cake\Upgrade\Rector\Cake6\RouteBuilderToCallbackFirstRector; +use Cake\Upgrade\Rector\Cake6\TranslationToGetOrCreateTranslationRector; use Cake\Upgrade\Rector\Cake6\VoidMethod; use PHPStan\Type\ObjectType; use Rector\Config\RectorConfig; @@ -30,6 +31,10 @@ // RouteBuilder argument reordering $rectorConfig->rule(RouteBuilderToCallbackFirstRector::class); + // TranslateTrait::translation() became a pure getter, use getOrCreateTranslation() for create-on-access + // @see https://github.com/cakephp/cakephp/pull/19251 + $rectorConfig->rule(TranslationToGetOrCreateTranslationRector::class); + // Changes related to the accessible => patchable rename $rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [ new MethodCallRename('Cake\ORM\Entity', 'setAccess', 'setPatchable'), diff --git a/src/Rector/Cake6/TranslationToGetOrCreateTranslationRector.php b/src/Rector/Cake6/TranslationToGetOrCreateTranslationRector.php new file mode 100644 index 0000000..e76c0c5 --- /dev/null +++ b/src/Rector/Cake6/TranslationToGetOrCreateTranslationRector.php @@ -0,0 +1,71 @@ +translation() to $entity->getOrCreateTranslation() to preserve create-on-access behavior', + [ + new CodeSample( + <<<'CODE_SAMPLE' +$article->translation('fra'); +CODE_SAMPLE + , + <<<'CODE_SAMPLE' +$article->getOrCreateTranslation('fra'); +CODE_SAMPLE, + ), + ], + ); + } + + /** + * @return array> + */ + public function getNodeTypes(): array + { + return [MethodCall::class]; + } + + /** + * @param \PhpParser\Node\Expr\MethodCall $node + */ + public function refactor(Node $node): ?Node + { + if (!$node->name instanceof Identifier) { + return null; + } + + if ($node->name->toString() !== 'translation') { + return null; + } + + if (!$this->isObjectType($node->var, new ObjectType('Cake\ORM\Entity'))) { + return null; + } + + $node->name = new Identifier('getOrCreateTranslation'); + + return $node; + } +} diff --git a/tests/TestCase/Rector/MethodCall/TranslationToGetOrCreateTranslationRector/Fixture/fixture.php.inc b/tests/TestCase/Rector/MethodCall/TranslationToGetOrCreateTranslationRector/Fixture/fixture.php.inc new file mode 100644 index 0000000..e50239b --- /dev/null +++ b/tests/TestCase/Rector/MethodCall/TranslationToGetOrCreateTranslationRector/Fixture/fixture.php.inc @@ -0,0 +1,49 @@ +translation() + $translation = $article->translation('fra'); + + return $article; + } +} + +?> +----- +translation() + $translation = $article->getOrCreateTranslation('fra'); + + return $article; + } +} + +?> diff --git a/tests/TestCase/Rector/MethodCall/TranslationToGetOrCreateTranslationRector/Fixture/skip_non_entity.php.inc b/tests/TestCase/Rector/MethodCall/TranslationToGetOrCreateTranslationRector/Fixture/skip_non_entity.php.inc new file mode 100644 index 0000000..3946029 --- /dev/null +++ b/tests/TestCase/Rector/MethodCall/TranslationToGetOrCreateTranslationRector/Fixture/skip_non_entity.php.inc @@ -0,0 +1,26 @@ +translation('fra'); + + return $result; + } +} + +?> diff --git a/tests/TestCase/Rector/MethodCall/TranslationToGetOrCreateTranslationRector/TranslationToGetOrCreateTranslationRectorTest.php b/tests/TestCase/Rector/MethodCall/TranslationToGetOrCreateTranslationRector/TranslationToGetOrCreateTranslationRectorTest.php new file mode 100644 index 0000000..2b9834d --- /dev/null +++ b/tests/TestCase/Rector/MethodCall/TranslationToGetOrCreateTranslationRector/TranslationToGetOrCreateTranslationRectorTest.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/TranslationToGetOrCreateTranslationRector/config/configured_rule.php b/tests/TestCase/Rector/MethodCall/TranslationToGetOrCreateTranslationRector/config/configured_rule.php new file mode 100644 index 0000000..5765008 --- /dev/null +++ b/tests/TestCase/Rector/MethodCall/TranslationToGetOrCreateTranslationRector/config/configured_rule.php @@ -0,0 +1,9 @@ +rule(TranslationToGetOrCreateTranslationRector::class); +};