From f4a088202f683c1c5a93f89f7be81509d2e3c2e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 1 Aug 2024 00:15:47 +0200 Subject: [PATCH] Refactor the OrderByKeyToClassConstRector to use the new enum only in Criteria::orderBy method call, and remove usage of Criteria::ASC and Criteria::DESC where not recommended Relates to: - https://github.com/doctrine/collections/pull/389; - https://github.com/doctrine/orm/issues/11313#issuecomment-2214570323 --- config/sets/doctrine-code-quality.php | 3 - config/sets/doctrine-collection-22.php | 17 +- ...r_by_asc_lower_with_class_constant.php.inc | 25 -- ...e_order_by_asc_with_class_constant.php.inc | 25 -- ..._order_by_desc_with_class_constant.php.inc | 25 -- .../Fixture/skip_already_using_const.php.inc | 13 -- .../config/configured_set.php | 10 - ...iteriaOrderingConstantDeprecationTest.php} | 4 +- ...ria_aliased_to_order_mixed_content.php.inc | 17 ++ ...ia_to_order_from_constant_criteria.php.inc | 17 ++ ...riteria_to_order_from_string_lower.php.inc | 17 ++ ...riteria_to_order_from_string_upper.php.inc | 17 ++ .../criteria_to_order_mixed_content.php.inc | 17 ++ ...ing_where_not_in_criteria_order_by.php.inc | 15 ++ ...r_by_asc_lower_with_class_constant.php.inc | 12 + ...e_order_by_asc_with_class_constant.php.inc | 12 + ..._order_by_desc_with_class_constant.php.inc | 12 + .../Fixture/skip_already_using_const.php.inc | 8 + ..._ASC_where_not_related_to_criteria.php.inc | 7 + .../skip_order_by_not_on_criteria.php.inc | 6 + .../config/configured_set.php | 10 + .../Property/OrderByKeyToClassConstRector.php | 111 --------- ...eriaOrderingConstantsDeprecationRector.php | 215 ++++++++++++++++++ ...sc_desc_in_attributes_not_replaced.php.inc | 27 +++ 24 files changed, 412 insertions(+), 230 deletions(-) delete mode 100644 rules-tests/CodeQuality/Rector/Property/OrderByKeyToClassConstRector/Fixture/replace_order_by_asc_lower_with_class_constant.php.inc delete mode 100644 rules-tests/CodeQuality/Rector/Property/OrderByKeyToClassConstRector/Fixture/replace_order_by_asc_with_class_constant.php.inc delete mode 100644 rules-tests/CodeQuality/Rector/Property/OrderByKeyToClassConstRector/Fixture/replace_order_by_desc_with_class_constant.php.inc delete mode 100644 rules-tests/CodeQuality/Rector/Property/OrderByKeyToClassConstRector/Fixture/skip_already_using_const.php.inc delete mode 100644 rules-tests/CodeQuality/Rector/Property/OrderByKeyToClassConstRector/config/configured_set.php rename rules-tests/{CodeQuality/Rector/Property/OrderByKeyToClassConstRector/OrderByKeyToClassConstRectorTest.php => Collection22/Rector/CriteriaOrderingConstantsDeprecations/CriteriaOrderingConstantDeprecationTest.php} (75%) create mode 100644 rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/criteria_aliased_to_order_mixed_content.php.inc create mode 100644 rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/criteria_to_order_from_constant_criteria.php.inc create mode 100644 rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/criteria_to_order_from_string_lower.php.inc create mode 100644 rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/criteria_to_order_from_string_upper.php.inc create mode 100644 rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/criteria_to_order_mixed_content.php.inc create mode 100644 rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/replace_class_constant_by_string_where_not_in_criteria_order_by.php.inc create mode 100644 rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/replace_order_by_asc_lower_with_class_constant.php.inc create mode 100644 rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/replace_order_by_asc_with_class_constant.php.inc create mode 100644 rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/replace_order_by_desc_with_class_constant.php.inc create mode 100644 rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/skip_already_using_const.php.inc create mode 100644 rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/skip_class_constant_ASC_where_not_related_to_criteria.php.inc create mode 100644 rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/skip_order_by_not_on_criteria.php.inc create mode 100644 rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/config/configured_set.php delete mode 100644 rules/CodeQuality/Rector/Property/OrderByKeyToClassConstRector.php create mode 100644 rules/Collection22/Rector/CriteriaOrderingConstantsDeprecationRector.php create mode 100644 tests/Set/DoctrineCOLLECTION22Set/Fixture/asc_desc_in_attributes_not_replaced.php.inc diff --git a/config/sets/doctrine-code-quality.php b/config/sets/doctrine-code-quality.php index 2c5aab98..c7ea6b59 100644 --- a/config/sets/doctrine-code-quality.php +++ b/config/sets/doctrine-code-quality.php @@ -9,7 +9,6 @@ use Rector\Doctrine\CodeQuality\Rector\Property\CorrectDefaultTypesOnEntityPropertyRector; use Rector\Doctrine\CodeQuality\Rector\Property\ImproveDoctrineCollectionDocTypeInEntityRector; use Rector\Doctrine\CodeQuality\Rector\Property\MakeEntityDateTimePropertyDateTimeInterfaceRector; -use Rector\Doctrine\CodeQuality\Rector\Property\OrderByKeyToClassConstRector; use Rector\Doctrine\CodeQuality\Rector\Property\TypedPropertyFromColumnTypeRector; use Rector\Doctrine\CodeQuality\Rector\Property\TypedPropertyFromToManyRelationTypeRector; use Rector\Doctrine\CodeQuality\Rector\Property\TypedPropertyFromToOneRelationTypeRector; @@ -31,8 +30,6 @@ TypedPropertyFromColumnTypeRector::class, TypedPropertyFromToOneRelationTypeRector::class, TypedPropertyFromToManyRelationTypeRector::class, - - OrderByKeyToClassConstRector::class, ]); $rectorConfig->ruleWithConfiguration(AttributeKeyToClassConstFetchRector::class, [ diff --git a/config/sets/doctrine-collection-22.php b/config/sets/doctrine-collection-22.php index d8da66b8..8a73387c 100644 --- a/config/sets/doctrine-collection-22.php +++ b/config/sets/doctrine-collection-22.php @@ -3,22 +3,7 @@ declare(strict_types=1); use Rector\Config\RectorConfig; -use Rector\Renaming\Rector\ClassConstFetch\RenameClassConstFetchRector; -use Rector\Renaming\ValueObject\RenameClassAndConstFetch; return static function (RectorConfig $rectorConfig): void { - $rectorConfig->ruleWithConfiguration(RenameClassConstFetchRector::class, [ - new RenameClassAndConstFetch( - 'Doctrine\\Common\\Collections\\Criteria', - 'ASC', - 'Doctrine\\Common\\Collections\\Order', - 'Ascending' - ), - new RenameClassAndConstFetch( - 'Doctrine\\Common\\Collections\\Criteria', - 'DESC', - 'Doctrine\\Common\\Collections\\Order', - 'Descending' - ), - ]); + $rectorConfig->rules([\Rector\Doctrine\Collection22\Rector\CriteriaOrderingConstantsDeprecationRector::class]); }; diff --git a/rules-tests/CodeQuality/Rector/Property/OrderByKeyToClassConstRector/Fixture/replace_order_by_asc_lower_with_class_constant.php.inc b/rules-tests/CodeQuality/Rector/Property/OrderByKeyToClassConstRector/Fixture/replace_order_by_asc_lower_with_class_constant.php.inc deleted file mode 100644 index e30c15fa..00000000 --- a/rules-tests/CodeQuality/Rector/Property/OrderByKeyToClassConstRector/Fixture/replace_order_by_asc_lower_with_class_constant.php.inc +++ /dev/null @@ -1,25 +0,0 @@ - 'asc'])] - protected \DateTimeInterface $messages; -} -?> ------ - \Doctrine\Common\Collections\Criteria::ASC])] - protected \DateTimeInterface $messages; -} -?> diff --git a/rules-tests/CodeQuality/Rector/Property/OrderByKeyToClassConstRector/Fixture/replace_order_by_asc_with_class_constant.php.inc b/rules-tests/CodeQuality/Rector/Property/OrderByKeyToClassConstRector/Fixture/replace_order_by_asc_with_class_constant.php.inc deleted file mode 100644 index 04858ad3..00000000 --- a/rules-tests/CodeQuality/Rector/Property/OrderByKeyToClassConstRector/Fixture/replace_order_by_asc_with_class_constant.php.inc +++ /dev/null @@ -1,25 +0,0 @@ - 'ASC'])] - protected \DateTimeInterface $messages; -} -?> ------ - \Doctrine\Common\Collections\Criteria::ASC])] - protected \DateTimeInterface $messages; -} -?> diff --git a/rules-tests/CodeQuality/Rector/Property/OrderByKeyToClassConstRector/Fixture/replace_order_by_desc_with_class_constant.php.inc b/rules-tests/CodeQuality/Rector/Property/OrderByKeyToClassConstRector/Fixture/replace_order_by_desc_with_class_constant.php.inc deleted file mode 100644 index 7bd5bfde..00000000 --- a/rules-tests/CodeQuality/Rector/Property/OrderByKeyToClassConstRector/Fixture/replace_order_by_desc_with_class_constant.php.inc +++ /dev/null @@ -1,25 +0,0 @@ - 'desc'])] - protected \DateTimeInterface $messages; -} -?> ------ - \Doctrine\Common\Collections\Criteria::DESC])] - protected \DateTimeInterface $messages; -} -?> diff --git a/rules-tests/CodeQuality/Rector/Property/OrderByKeyToClassConstRector/Fixture/skip_already_using_const.php.inc b/rules-tests/CodeQuality/Rector/Property/OrderByKeyToClassConstRector/Fixture/skip_already_using_const.php.inc deleted file mode 100644 index 018827ec..00000000 --- a/rules-tests/CodeQuality/Rector/Property/OrderByKeyToClassConstRector/Fixture/skip_already_using_const.php.inc +++ /dev/null @@ -1,13 +0,0 @@ - Criteria::ASC])] - protected \DateTimeInterface $messages; -} -?> diff --git a/rules-tests/CodeQuality/Rector/Property/OrderByKeyToClassConstRector/config/configured_set.php b/rules-tests/CodeQuality/Rector/Property/OrderByKeyToClassConstRector/config/configured_set.php deleted file mode 100644 index 92609e0f..00000000 --- a/rules-tests/CodeQuality/Rector/Property/OrderByKeyToClassConstRector/config/configured_set.php +++ /dev/null @@ -1,10 +0,0 @@ -rule(OrderByKeyToClassConstRector::class); -}; diff --git a/rules-tests/CodeQuality/Rector/Property/OrderByKeyToClassConstRector/OrderByKeyToClassConstRectorTest.php b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/CriteriaOrderingConstantDeprecationTest.php similarity index 75% rename from rules-tests/CodeQuality/Rector/Property/OrderByKeyToClassConstRector/OrderByKeyToClassConstRectorTest.php rename to rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/CriteriaOrderingConstantDeprecationTest.php index e2c5ff96..9b66a099 100644 --- a/rules-tests/CodeQuality/Rector/Property/OrderByKeyToClassConstRector/OrderByKeyToClassConstRectorTest.php +++ b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/CriteriaOrderingConstantDeprecationTest.php @@ -2,13 +2,13 @@ declare(strict_types=1); -namespace Rector\Doctrine\Tests\CodeQuality\Rector\Property\OrderByKeyToClassConstRector; +namespace Rector\Doctrine\Tests\Collection22\Rector\CriteriaOrderingConstantsDeprecations; use Iterator; use PHPUnit\Framework\Attributes\DataProvider; use Rector\Testing\PHPUnit\AbstractRectorTestCase; -final class OrderByKeyToClassConstRectorTest extends AbstractRectorTestCase +final class CriteriaOrderingConstantDeprecationTest extends AbstractRectorTestCase { #[DataProvider('provideData')] public function test(string $filePath): void diff --git a/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/criteria_aliased_to_order_mixed_content.php.inc b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/criteria_aliased_to_order_mixed_content.php.inc new file mode 100644 index 00000000..6a8703c1 --- /dev/null +++ b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/criteria_aliased_to_order_mixed_content.php.inc @@ -0,0 +1,17 @@ +orderBy(['param1' => \Doctrine\Common\Collections\Order::Ascending, 'param2' => SomeAliasedCriteria::DESC, 'param3' => 'asc']); + +?> +----- +orderBy(['param1' => \Doctrine\Common\Collections\Order::Ascending, 'param2' => \Doctrine\Common\Collections\Order::Descending, 'param3' => \Doctrine\Common\Collections\Order::Ascending]); + +?> diff --git a/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/criteria_to_order_from_constant_criteria.php.inc b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/criteria_to_order_from_constant_criteria.php.inc new file mode 100644 index 00000000..c41792fd --- /dev/null +++ b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/criteria_to_order_from_constant_criteria.php.inc @@ -0,0 +1,17 @@ +orderBy(['asc' => Criteria::ASC, 'desc' => Criteria::DESC]); + +?> +----- +orderBy(['asc' => \Doctrine\Common\Collections\Order::Ascending, 'desc' => \Doctrine\Common\Collections\Order::Descending]); + +?> diff --git a/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/criteria_to_order_from_string_lower.php.inc b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/criteria_to_order_from_string_lower.php.inc new file mode 100644 index 00000000..097dc58e --- /dev/null +++ b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/criteria_to_order_from_string_lower.php.inc @@ -0,0 +1,17 @@ +orderBy(['asc' => 'asc', 'desc' => 'desc']); + +?> +----- +orderBy(['asc' => \Doctrine\Common\Collections\Order::Ascending, 'desc' => \Doctrine\Common\Collections\Order::Descending]); + +?> diff --git a/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/criteria_to_order_from_string_upper.php.inc b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/criteria_to_order_from_string_upper.php.inc new file mode 100644 index 00000000..7645787e --- /dev/null +++ b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/criteria_to_order_from_string_upper.php.inc @@ -0,0 +1,17 @@ +orderBy(['asc' => 'ASC', 'desc' => 'DESC']); + +?> +----- +orderBy(['asc' => \Doctrine\Common\Collections\Order::Ascending, 'desc' => \Doctrine\Common\Collections\Order::Descending]); + +?> diff --git a/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/criteria_to_order_mixed_content.php.inc b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/criteria_to_order_mixed_content.php.inc new file mode 100644 index 00000000..8ced41a0 --- /dev/null +++ b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/criteria_to_order_mixed_content.php.inc @@ -0,0 +1,17 @@ +orderBy(['param1' => \Doctrine\Common\Collections\Order::Ascending, 'param2' => Criteria::DESC, 'param3' => 'asc']); + +?> +----- +orderBy(['param1' => \Doctrine\Common\Collections\Order::Ascending, 'param2' => \Doctrine\Common\Collections\Order::Descending, 'param3' => \Doctrine\Common\Collections\Order::Ascending]); + +?> diff --git a/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/replace_class_constant_by_string_where_not_in_criteria_order_by.php.inc b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/replace_class_constant_by_string_where_not_in_criteria_order_by.php.inc new file mode 100644 index 00000000..e8cbc5b4 --- /dev/null +++ b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/replace_class_constant_by_string_where_not_in_criteria_order_by.php.inc @@ -0,0 +1,15 @@ +addOrderBy('someParameter', Criteria::ASC); + +?> +----- +addOrderBy('someParameter', 'ASC'); + +?> diff --git a/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/replace_order_by_asc_lower_with_class_constant.php.inc b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/replace_order_by_asc_lower_with_class_constant.php.inc new file mode 100644 index 00000000..43762a2b --- /dev/null +++ b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/replace_order_by_asc_lower_with_class_constant.php.inc @@ -0,0 +1,12 @@ + 'asc'])] + protected \DateTimeInterface $messages; +} +?> diff --git a/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/replace_order_by_asc_with_class_constant.php.inc b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/replace_order_by_asc_with_class_constant.php.inc new file mode 100644 index 00000000..c6281694 --- /dev/null +++ b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/replace_order_by_asc_with_class_constant.php.inc @@ -0,0 +1,12 @@ + 'ASC'])] + protected \DateTimeInterface $messages; +} +?> diff --git a/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/replace_order_by_desc_with_class_constant.php.inc b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/replace_order_by_desc_with_class_constant.php.inc new file mode 100644 index 00000000..f9c6c180 --- /dev/null +++ b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/replace_order_by_desc_with_class_constant.php.inc @@ -0,0 +1,12 @@ + 'desc'])] + protected \DateTimeInterface $messages; +} +?> diff --git a/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/skip_already_using_const.php.inc b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/skip_already_using_const.php.inc new file mode 100644 index 00000000..8c70fe73 --- /dev/null +++ b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/skip_already_using_const.php.inc @@ -0,0 +1,8 @@ +orderBy(['asc' => \Doctrine\Common\Collections\Order::Ascending, 'desc' => \Doctrine\Common\Collections\Order::Descending]); + +?> diff --git a/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/skip_class_constant_ASC_where_not_related_to_criteria.php.inc b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/skip_class_constant_ASC_where_not_related_to_criteria.php.inc new file mode 100644 index 00000000..03d92128 --- /dev/null +++ b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/skip_class_constant_ASC_where_not_related_to_criteria.php.inc @@ -0,0 +1,7 @@ +addOrderBy('someParameter', SomeClass::ASC); + +?> diff --git a/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/skip_order_by_not_on_criteria.php.inc b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/skip_order_by_not_on_criteria.php.inc new file mode 100644 index 00000000..ffa4066f --- /dev/null +++ b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/Fixture/skip_order_by_not_on_criteria.php.inc @@ -0,0 +1,6 @@ +orderBy(['someType' => 'ASC']); + +?> diff --git a/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/config/configured_set.php b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/config/configured_set.php new file mode 100644 index 00000000..eb3ffabc --- /dev/null +++ b/rules-tests/Collection22/Rector/CriteriaOrderingConstantsDeprecations/config/configured_set.php @@ -0,0 +1,10 @@ +rule(CriteriaOrderingConstantsDeprecationRector::class); +}; diff --git a/rules/CodeQuality/Rector/Property/OrderByKeyToClassConstRector.php b/rules/CodeQuality/Rector/Property/OrderByKeyToClassConstRector.php deleted file mode 100644 index a1636953..00000000 --- a/rules/CodeQuality/Rector/Property/OrderByKeyToClassConstRector.php +++ /dev/null @@ -1,111 +0,0 @@ - 'ASC'])] - protected \DateTimeInterface $messages; -} -?> -CODE_SAMPLE - - , - <<<'CODE_SAMPLE' -use Doctrine\ORM\Mapping as ORM; - -class ReplaceOrderByAscWithClassConstant -{ - #[ORM\OrderBy(['createdAt' => \Doctrine\Common\Collections\Criteria::ASC])] - protected \DateTimeInterface $messages; -} -?> -CODE_SAMPLE - ), - ] - ); - } - - /** - * @return array> - */ - public function getNodeTypes(): array - { - return [Property::class]; - } - - /** - * @param Property $node - */ - public function refactor(Node $node): ?Node - { - $nodeAttribute = null; - foreach ($node->attrGroups as $attrGroup) { - foreach ($attrGroup->attrs as $attr) { - if ($attr->name->toString() === 'Doctrine\ORM\Mapping\OrderBy') { - $nodeAttribute = $attr; - break 2; - } - } - } - - // If Attribute is not OrderBy, return null - if (! $nodeAttribute instanceof Attribute) { - return null; - } - - if (! isset($nodeAttribute->args[0])) { - return null; - } - - if (! $nodeAttribute->args[0]->value instanceof Array_) { - return null; - } - - if (! isset($nodeAttribute->args[0]->value->items[0])) { - return null; - } - - if (! $nodeAttribute->args[0]->value->items[0]->value instanceof String_) { - return null; - } - - // If Attribute value from key is not `ASC` or `DESC`, return null - if (! in_array($nodeAttribute->args[0]->value->items[0]->value->value, ['ASC', 'asc', 'DESC', 'desc'], true)) { - return null; - } - - $upper = strtoupper($nodeAttribute->args[0]->value->items[0]->value->value); - $nodeAttribute->args[0]->value->items[0]->value = $this->nodeFactory->createClassConstFetch( - 'Doctrine\Common\Collections\Criteria', - $upper - ); - - return $node; - } -} diff --git a/rules/Collection22/Rector/CriteriaOrderingConstantsDeprecationRector.php b/rules/Collection22/Rector/CriteriaOrderingConstantsDeprecationRector.php new file mode 100644 index 00000000..12abdbb9 --- /dev/null +++ b/rules/Collection22/Rector/CriteriaOrderingConstantsDeprecationRector.php @@ -0,0 +1,215 @@ +criteriaObjectType = new ObjectType('Doctrine\Common\Collections\Criteria'); + } + + public function getRuleDefinition(): RuleDefinition + { + return new RuleDefinition( + 'Replace ASC/DESC with enum Ordering in Criteria::orderBy method call, and remove usage of Criteria::ASC and Criteria::DESC constants elsewhere', + [ + new CodeSample( + <<<'CODE_SAMPLE' + orderBy(['someProperty' => 'ASC', 'anotherProperty' => 'DESC']); + + ?> + CODE_SAMPLE + , + <<<'CODE_SAMPLE' + orderBy(['someProperty' => \Doctrine\Common\Collections\Order::Ascending, 'anotherProperty' => \Doctrine\Common\Collections\Order::Descending]); + + ?> + CODE_SAMPLE + ), + new CodeSample( + <<<'PHP' + addOrderBy('something', Criteria::ASC); + + ?> + PHP + , + <<<'PHP' + addOrderBy('something', 'ASC'); + + ?> + PHP + , + ), + ] + ); + } + + /** + * @return array> + */ + public function getNodeTypes(): array + { + return [Node\Expr\MethodCall::class, Node\Expr\ClassConstFetch::class]; + } + + /** + * @param Node\Expr\MethodCall|Node\Expr\ClassConstFetch $node + */ + public function refactor(Node $node): ?Node + { + if ($node instanceof Node\Expr\ClassConstFetch) { + return $this->refactorClassConstFetch($node); + } + return $this->refactorMethodCall($node); + + } + + private function refactorClassConstFetch(Node\Expr\ClassConstFetch $classConstFetch): ?Node + { + if (! $classConstFetch->name instanceof Node\Identifier) { + return null; + } + + if (! in_array($classConstFetch->name->name, ['ASC', 'DESC'])) { + return null; + } + + if (! $classConstFetch->class instanceof Node\Name) { + return null; + } + + if (! $this->criteriaObjectType->isSuperTypeOf( + new ObjectType($classConstFetch->class->toCodeString()) + )->yes()) { + return null; + } + + return match ($classConstFetch->name->name) { + 'ASC' => new String_('ASC'), + 'DESC' => new String_('DESC'), + }; + } + + private function refactorMethodCall(Node\Expr\MethodCall $node): ?Node + { + if (! $this->isName($node->name, 'orderBy')) { + return null; + } + + $isSuperTypeOfCriteria = $this->criteriaObjectType->isSuperTypeOf($this->nodeTypeResolver->getType($node->var)); + + if ($isSuperTypeOfCriteria->no() || $isSuperTypeOfCriteria->maybe()) { + return null; + } + + $args = $node->getArgs(); + + if (count($args) < 1) { + return null; + } + + $arg = $args[0]; + if (! $arg instanceof Node\Arg) { + return null; + } + + if (! $arg->value instanceof Array_) { + return null; + } + + $nodeHasChange = false; + $newItems = []; + + // we parse the array of the first argument + foreach ($arg->value->items as $item) { + + if ($item === null) { + $newItems[] = $item; + continue; + } + + if ($item->value instanceof String_ && in_array( + $v = strtoupper($item->value->value), + ['ASC', 'DESC'], + true + )) { + $newItems[] = $this->buildArrayItem($v, $item->key); + $nodeHasChange = true; + } elseif ( + $item->value instanceof Node\Expr\ClassConstFetch + && $item->value->class instanceof Node\Name + /* @phpstan-ignore-next-line */ + && $this->criteriaObjectType->isSuperTypeOf(new ObjectType($item->value->class->toCodeString())) + && $item->value->name instanceof Node\Identifier + && in_array($v = strtoupper((string) $item->value->name), ['ASC', 'DESC'], true) + ) { + $newItems[] = $this->buildArrayItem($v, $item->key); + $nodeHasChange = true; + } else { + $newItems[] = $item; + } + } + + if ($nodeHasChange) { + return $this->nodeFactory->createMethodCall( + $node->var, + 'orderBy', + $this->nodeFactory->createArgs([$this->nodeFactory->createArg(new Array_($newItems))]) + ); + } + + return null; + } + + /** + * @param 'ASC'|'DESC' $direction + * @return ArrayItem + */ + private function buildArrayItem(string $direction, Node\Expr|null $key): Node\Expr\ArrayItem + { + $value = $this->nodeFactory->createClassConstFetch( + 'Doctrine\Common\Collections\Order', + match ($direction) { + 'ASC' => 'Ascending', + 'DESC' => 'Descending', + } + ); + + return new Node\Expr\ArrayItem($value, $key); + } +} diff --git a/tests/Set/DoctrineCOLLECTION22Set/Fixture/asc_desc_in_attributes_not_replaced.php.inc b/tests/Set/DoctrineCOLLECTION22Set/Fixture/asc_desc_in_attributes_not_replaced.php.inc new file mode 100644 index 00000000..65d88f72 --- /dev/null +++ b/tests/Set/DoctrineCOLLECTION22Set/Fixture/asc_desc_in_attributes_not_replaced.php.inc @@ -0,0 +1,27 @@ + \Doctrine\Common\Collections\Criteria::ASC])] + public \Doctrine\Common\Collections\Collection $properties; + + #[ORM\OneToMany(targetEntity: YetAnotherEntity::class, mappedBy: 'dummy')] + #[ORM\OrderBy(["id" => \Doctrine\Common\Collections\Criteria::DESC])] + public \Doctrine\Common\Collections\Collection $otherProperties; +} +?> +----- + 'ASC'])] + public \Doctrine\Common\Collections\Collection $properties; + + #[ORM\OneToMany(targetEntity: YetAnotherEntity::class, mappedBy: 'dummy')] + #[ORM\OrderBy(["id" => 'DESC'])] + public \Doctrine\Common\Collections\Collection $otherProperties; +} +?>