From f99fbbdd64ef31c22bbb211dae64b357869a2229 Mon Sep 17 00:00:00 2001 From: Arshid Date: Sat, 30 Aug 2025 10:39:20 +0530 Subject: [PATCH 01/48] [php 8.3] Add json_validate rule --- .../Fixture/Json_validate.php.inc | 15 ++++++++++ .../Fixture/Json_validate_named.php.inc | 15 ++++++++++ .../JsonValidate/Fixture/elseif.php.inc | 17 +++++++++++ .../Fixture/inline_string.php.inc | 13 +++++++++ .../JsonValidate/JsonValidateTest.php | 28 +++++++++++++++++++ .../JsonValidate/config/configured_rule.php | 13 +++++++++ .../Fixture/Json_validate.php.inc | 15 ++++++++++ .../Fixture/Json_validate_named.php.inc | 15 ++++++++++ .../JsonValidate/Fixture/elseif.php.inc | 17 +++++++++++ .../Fixture/inline_string.php.inc | 13 +++++++++ .../JsonValidate/JsonValidateTest.php | 28 +++++++++++++++++++ .../JsonValidate/config/configured_rule.php | 13 +++++++++ 12 files changed, 202 insertions(+) create mode 100644 rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate.php.inc create mode 100644 rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate_named.php.inc create mode 100644 rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/elseif.php.inc create mode 100644 rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/inline_string.php.inc create mode 100644 rules-tests/Php80/Rector/BooleanAnd/JsonValidate/JsonValidateTest.php create mode 100644 rules-tests/Php80/Rector/BooleanAnd/JsonValidate/config/configured_rule.php create mode 100644 rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate.php.inc create mode 100644 rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate_named.php.inc create mode 100644 rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/elseif.php.inc create mode 100644 rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/inline_string.php.inc create mode 100644 rules-tests/Php83/Rector/BooleanAnd/JsonValidate/JsonValidateTest.php create mode 100644 rules-tests/Php83/Rector/BooleanAnd/JsonValidate/config/configured_rule.php diff --git a/rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate.php.inc b/rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate.php.inc new file mode 100644 index 00000000000..df4c7b9c854 --- /dev/null +++ b/rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate.php.inc @@ -0,0 +1,15 @@ + +----- + \ No newline at end of file diff --git a/rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate_named.php.inc b/rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate_named.php.inc new file mode 100644 index 00000000000..820bc02b87f --- /dev/null +++ b/rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate_named.php.inc @@ -0,0 +1,15 @@ + +----- + diff --git a/rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/elseif.php.inc b/rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/elseif.php.inc new file mode 100644 index 00000000000..fd9ded72f99 --- /dev/null +++ b/rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/elseif.php.inc @@ -0,0 +1,17 @@ +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/rules-tests/Php80/Rector/BooleanAnd/JsonValidate/config/configured_rule.php b/rules-tests/Php80/Rector/BooleanAnd/JsonValidate/config/configured_rule.php new file mode 100644 index 00000000000..7ec6656c632 --- /dev/null +++ b/rules-tests/Php80/Rector/BooleanAnd/JsonValidate/config/configured_rule.php @@ -0,0 +1,13 @@ +phpVersion(PhpVersion::PHP_80); + + $rectorConfig->rule(JsonValidate::class); +}; diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate.php.inc new file mode 100644 index 00000000000..b6b3a77b883 --- /dev/null +++ b/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate.php.inc @@ -0,0 +1,15 @@ + +----- + \ No newline at end of file diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate_named.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate_named.php.inc new file mode 100644 index 00000000000..e83d15e1a97 --- /dev/null +++ b/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate_named.php.inc @@ -0,0 +1,15 @@ + +----- + diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/elseif.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/elseif.php.inc new file mode 100644 index 00000000000..31029c71be0 --- /dev/null +++ b/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/elseif.php.inc @@ -0,0 +1,17 @@ +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/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/config/configured_rule.php b/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/config/configured_rule.php new file mode 100644 index 00000000000..d46fd199fee --- /dev/null +++ b/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/config/configured_rule.php @@ -0,0 +1,13 @@ +phpVersion(PhpVersion::PHP_80); + + $rectorConfig->rule(JsonValidate::class); +}; From bfd6894a269740beb901b628cf98ddd74ba00c3d Mon Sep 17 00:00:00 2001 From: Arshid Date: Sat, 30 Aug 2025 10:42:30 +0530 Subject: [PATCH 02/48] [php 8.3] Add json_validate rule --- .../Php83/Rector/BooleanAnd/JsonValidate.php | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 rules/Php83/Rector/BooleanAnd/JsonValidate.php diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidate.php b/rules/Php83/Rector/BooleanAnd/JsonValidate.php new file mode 100644 index 00000000000..2fd882fb5d9 --- /dev/null +++ b/rules/Php83/Rector/BooleanAnd/JsonValidate.php @@ -0,0 +1,124 @@ +> + */ + public function getNodeTypes(): array + { + return [BooleanAnd::class]; + } + + /** + * @param BooleanAnd $node + */ + public function refactor(Node $node): ?Node + { + $funcCall = $this->matchJsonValidateArg($node); + + if (! $funcCall instanceof FuncCall) { + return null; + } + + if ($funcCall->isFirstClassCallable()) { + return null; + } + + if (isset($funcCall->getArgs()[1])) { + unset($funcCall->args[1]); + } + + $funcCall->name = new Name('json_validate'); + + return $funcCall; + } + + public function providePolyfillPackage(): string + { + return PolyfillPackage::PHP_80; + } + + public function matchJsonValidateArg(BooleanAnd $booleanAnd): ?FuncCall + { + if ($booleanAnd->left instanceof NotIdentical) { + $notIdentical = $booleanAnd->left; + + if ($notIdentical->left instanceof FuncCall + && $this->isName($notIdentical->left->name, 'json_decode') + && $notIdentical->right instanceof ConstFetch + && $this->isName($notIdentical->right->name, 'null')) { + + // right side: json_last_error() === JSON_ERROR_NONE + if (! $booleanAnd->right instanceof Identical) { + return null; + } + + $identical = $booleanAnd->right; + + if ($identical->left instanceof FuncCall + && $this->isName($identical->left->name, 'json_last_error') + && $identical->right instanceof ConstFetch + && $this->isName($identical->right->name, 'JSON_ERROR_NONE')) { + + return $notIdentical->left; // return json_decode(...) call + } + } + + } + + return null; + } +} From ebb70d1f5eecf212d9f2de571bdefd8be148a02b Mon Sep 17 00:00:00 2001 From: Arshid Date: Sat, 30 Aug 2025 10:47:33 +0530 Subject: [PATCH 03/48] [php 8.3] Add json_validate rule --- .../Fixture/Json_validate.php.inc | 15 ---------- .../Fixture/Json_validate_named.php.inc | 15 ---------- .../JsonValidate/Fixture/elseif.php.inc | 17 ----------- .../Fixture/inline_string.php.inc | 13 --------- .../JsonValidate/JsonValidateTest.php | 28 ------------------- .../JsonValidate/config/configured_rule.php | 13 --------- 6 files changed, 101 deletions(-) delete mode 100644 rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate.php.inc delete mode 100644 rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate_named.php.inc delete mode 100644 rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/elseif.php.inc delete mode 100644 rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/inline_string.php.inc delete mode 100644 rules-tests/Php80/Rector/BooleanAnd/JsonValidate/JsonValidateTest.php delete mode 100644 rules-tests/Php80/Rector/BooleanAnd/JsonValidate/config/configured_rule.php diff --git a/rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate.php.inc b/rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate.php.inc deleted file mode 100644 index df4c7b9c854..00000000000 --- a/rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate.php.inc +++ /dev/null @@ -1,15 +0,0 @@ - ------ - \ No newline at end of file diff --git a/rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate_named.php.inc b/rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate_named.php.inc deleted file mode 100644 index 820bc02b87f..00000000000 --- a/rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate_named.php.inc +++ /dev/null @@ -1,15 +0,0 @@ - ------ - diff --git a/rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/elseif.php.inc b/rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/elseif.php.inc deleted file mode 100644 index fd9ded72f99..00000000000 --- a/rules-tests/Php80/Rector/BooleanAnd/JsonValidate/Fixture/elseif.php.inc +++ /dev/null @@ -1,17 +0,0 @@ -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/rules-tests/Php80/Rector/BooleanAnd/JsonValidate/config/configured_rule.php b/rules-tests/Php80/Rector/BooleanAnd/JsonValidate/config/configured_rule.php deleted file mode 100644 index 7ec6656c632..00000000000 --- a/rules-tests/Php80/Rector/BooleanAnd/JsonValidate/config/configured_rule.php +++ /dev/null @@ -1,13 +0,0 @@ -phpVersion(PhpVersion::PHP_80); - - $rectorConfig->rule(JsonValidate::class); -}; From 634fb9d747741cdcd1fa8969d725f74d38040a5e Mon Sep 17 00:00:00 2001 From: Arshid Date: Sat, 30 Aug 2025 10:54:40 +0530 Subject: [PATCH 04/48] [php 8.3] Add json_validate rule --- config/set/php83.php | 2 ++ .../BooleanAnd/JsonValidate/Fixture/Json_validate.php.inc | 4 ++-- .../JsonValidate/Fixture/Json_validate_named.php.inc | 4 ++-- .../Rector/BooleanAnd/JsonValidate/Fixture/elseif.php.inc | 4 ++-- .../BooleanAnd/JsonValidate/Fixture/inline_string.php.inc | 4 ++-- .../{JsonValidateTest.php => JsonValidateRectorTest.php} | 4 ++-- .../BooleanAnd/JsonValidate/config/configured_rule.php | 4 ++-- .../BooleanAnd/{JsonValidate.php => JsonValidateRector.php} | 5 +---- 8 files changed, 15 insertions(+), 16 deletions(-) rename rules-tests/Php83/Rector/BooleanAnd/JsonValidate/{JsonValidateTest.php => JsonValidateRectorTest.php} (80%) rename rules/Php83/Rector/BooleanAnd/{JsonValidate.php => JsonValidateRector.php} (95%) diff --git a/config/set/php83.php b/config/set/php83.php index 8e0522228fb..e29e3f2323b 100644 --- a/config/set/php83.php +++ b/config/set/php83.php @@ -3,6 +3,7 @@ declare(strict_types=1); use Rector\Config\RectorConfig; +use Rector\Php83\Rector\BooleanAnd\JsonValidateRector; use Rector\Php83\Rector\Class_\ReadOnlyAnonymousClassRector; use Rector\Php83\Rector\ClassConst\AddTypeToConstRector; use Rector\Php83\Rector\ClassMethod\AddOverrideAttributeToOverriddenMethodsRector; @@ -18,5 +19,6 @@ RemoveGetClassGetParentClassNoArgsRector::class, ReadOnlyAnonymousClassRector::class, DynamicClassConstFetchRector::class, + JsonValidateRector::class ]); }; diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate.php.inc index b6b3a77b883..5e1e7cc695b 100644 --- a/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate.php.inc +++ b/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate.php.inc @@ -1,5 +1,5 @@ ----- ----- phpVersion(PhpVersion::PHP_80); - $rectorConfig->rule(JsonValidate::class); + $rectorConfig->rule(JsonValidateRector::class); }; diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidate.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php similarity index 95% rename from rules/Php83/Rector/BooleanAnd/JsonValidate.php rename to rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index 2fd882fb5d9..c1360894088 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidate.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -22,11 +22,8 @@ /** * @see \Rector\Tests\Php80\Rector\BooleanAnd\JsonValidate\JsonValidateTest */ -final class JsonValidate extends AbstractRector implements MinPhpVersionInterface, RelatedPolyfillInterface +final class JsonValidateRector extends AbstractRector implements MinPhpVersionInterface, RelatedPolyfillInterface { - public function __construct() - { - } public function provideMinPhpVersion(): int { From c640e56e211fc9cc1a8d9e96a50802ba0d9f8aff Mon Sep 17 00:00:00 2001 From: Arshid Date: Sat, 30 Aug 2025 10:56:02 +0530 Subject: [PATCH 05/48] [php 8.3] Add json_validate rule --- rules/Php83/Rector/BooleanAnd/JsonValidateRector.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index c1360894088..ee4b9335b4d 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -20,7 +20,7 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; /** - * @see \Rector\Tests\Php80\Rector\BooleanAnd\JsonValidate\JsonValidateTest + * @see \Rector\Tests\Php83\Rector\BooleanAnd\JsonValidate\JsonValidateTest */ final class JsonValidateRector extends AbstractRector implements MinPhpVersionInterface, RelatedPolyfillInterface { From d73f7bb548bea3ec829cae631fc570b4824d1608 Mon Sep 17 00:00:00 2001 From: Arshid Date: Sat, 30 Aug 2025 10:58:34 +0530 Subject: [PATCH 06/48] [php 8.3] Add json_validate rule --- rules/Php83/Rector/BooleanAnd/JsonValidateRector.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index ee4b9335b4d..09ce9b71161 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -20,7 +20,7 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; /** - * @see \Rector\Tests\Php83\Rector\BooleanAnd\JsonValidate\JsonValidateTest + * @see \Rector\Tests\Php83\Rector\BooleanAnd\JsonValidateRector\JsonValidateRectorTest */ final class JsonValidateRector extends AbstractRector implements MinPhpVersionInterface, RelatedPolyfillInterface { From 57ff8c06814c7eaeade52fc28b532fef0258c553 Mon Sep 17 00:00:00 2001 From: Arshid Date: Sat, 30 Aug 2025 11:03:39 +0530 Subject: [PATCH 07/48] [php 8.3] Add json_validate rule --- config/set/php83.php | 2 +- rules/Php83/Rector/BooleanAnd/JsonValidateRector.php | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/config/set/php83.php b/config/set/php83.php index e29e3f2323b..1a056a87c05 100644 --- a/config/set/php83.php +++ b/config/set/php83.php @@ -19,6 +19,6 @@ RemoveGetClassGetParentClassNoArgsRector::class, ReadOnlyAnonymousClassRector::class, DynamicClassConstFetchRector::class, - JsonValidateRector::class + JsonValidateRector::class, ]); }; diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index 09ce9b71161..503d35aa891 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -24,7 +24,6 @@ */ final class JsonValidateRector extends AbstractRector implements MinPhpVersionInterface, RelatedPolyfillInterface { - public function provideMinPhpVersion(): int { return PhpVersionFeature::STR_CONTAINS; From 4d2be54fa02b4e431713914bd46d4691fe91fb13 Mon Sep 17 00:00:00 2001 From: Arshid Date: Sat, 30 Aug 2025 11:09:41 +0530 Subject: [PATCH 08/48] [php 8.3] Add json_validate rule --- rules/Php83/Rector/BooleanAnd/JsonValidateRector.php | 2 +- src/ValueObject/PhpVersionFeature.php | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index 503d35aa891..866d2ff94e8 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -26,7 +26,7 @@ final class JsonValidateRector extends AbstractRector implements MinPhpVersionIn { public function provideMinPhpVersion(): int { - return PhpVersionFeature::STR_CONTAINS; + return PhpVersionFeature::JSON_VALIDATE; } public function getRuleDefinition(): RuleDefinition diff --git a/src/ValueObject/PhpVersionFeature.php b/src/ValueObject/PhpVersionFeature.php index 1c72c63d39b..e073214ca3e 100644 --- a/src/ValueObject/PhpVersionFeature.php +++ b/src/ValueObject/PhpVersionFeature.php @@ -522,6 +522,11 @@ final class PhpVersionFeature */ public const STR_CONTAINS = PhpVersion::PHP_80; + /** + * @var int + */ + public const JSON_VALIDATE = PhpVersion::PHP_80; + /** * @var int */ @@ -798,4 +803,10 @@ final class PhpVersionFeature * @var int */ public const DEPRECATE_NULL_ARG_IN_ARRAY_KEY_EXISTS_FUNCTION = PhpVersion::PHP_85; + + /** + * @see https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_passing_string_which_are_not_one_byte_long_to_ord + * @var int + */ + public const DEPRECATE_ORD_WITH_MULTIBYTE_STRING = PhpVersion::PHP_85; } From 5763420ba43e1f7c7584205de965f5b16b7776e6 Mon Sep 17 00:00:00 2001 From: Arshid Date: Sat, 30 Aug 2025 11:17:06 +0530 Subject: [PATCH 09/48] [php 8.3] Add json_validate rule --- .../Fixture/Json_validate.php.inc | 0 .../Fixture/Json_validate_named.php.inc | 0 .../{JsonValidate => JsonValidateTest}/Fixture/elseif.php.inc | 0 .../Fixture/inline_string.php.inc | 0 .../{JsonValidate => JsonValidateTest}/JsonValidateRectorTest.php | 0 .../{JsonValidate => JsonValidateTest}/config/configured_rule.php | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename rules-tests/Php83/Rector/BooleanAnd/{JsonValidate => JsonValidateTest}/Fixture/Json_validate.php.inc (100%) rename rules-tests/Php83/Rector/BooleanAnd/{JsonValidate => JsonValidateTest}/Fixture/Json_validate_named.php.inc (100%) rename rules-tests/Php83/Rector/BooleanAnd/{JsonValidate => JsonValidateTest}/Fixture/elseif.php.inc (100%) rename rules-tests/Php83/Rector/BooleanAnd/{JsonValidate => JsonValidateTest}/Fixture/inline_string.php.inc (100%) rename rules-tests/Php83/Rector/BooleanAnd/{JsonValidate => JsonValidateTest}/JsonValidateRectorTest.php (100%) rename rules-tests/Php83/Rector/BooleanAnd/{JsonValidate => JsonValidateTest}/config/configured_rule.php (100%) diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateTest/Fixture/Json_validate.php.inc similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate.php.inc rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidateTest/Fixture/Json_validate.php.inc diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate_named.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateTest/Fixture/Json_validate_named.php.inc similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate_named.php.inc rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidateTest/Fixture/Json_validate_named.php.inc diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/elseif.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateTest/Fixture/elseif.php.inc similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/elseif.php.inc rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidateTest/Fixture/elseif.php.inc diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/inline_string.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateTest/Fixture/inline_string.php.inc similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/inline_string.php.inc rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidateTest/Fixture/inline_string.php.inc diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/JsonValidateRectorTest.php b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateTest/JsonValidateRectorTest.php similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidate/JsonValidateRectorTest.php rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidateTest/JsonValidateRectorTest.php diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/config/configured_rule.php b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateTest/config/configured_rule.php similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidate/config/configured_rule.php rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidateTest/config/configured_rule.php From 70794c6e7c51de9bc9ddfdc513a822c3ea7deb0a Mon Sep 17 00:00:00 2001 From: Arshid Date: Sat, 30 Aug 2025 11:19:19 +0530 Subject: [PATCH 10/48] [php 8.3] Add json_validate rule --- .../Fixture/Json_validate.php.inc | 0 .../Fixture/Json_validate_named.php.inc | 0 .../{JsonValidateTest => JsonValidate}/Fixture/elseif.php.inc | 0 .../Fixture/inline_string.php.inc | 0 .../{JsonValidateTest => JsonValidate}/JsonValidateRectorTest.php | 0 .../{JsonValidateTest => JsonValidate}/config/configured_rule.php | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename rules-tests/Php83/Rector/BooleanAnd/{JsonValidateTest => JsonValidate}/Fixture/Json_validate.php.inc (100%) rename rules-tests/Php83/Rector/BooleanAnd/{JsonValidateTest => JsonValidate}/Fixture/Json_validate_named.php.inc (100%) rename rules-tests/Php83/Rector/BooleanAnd/{JsonValidateTest => JsonValidate}/Fixture/elseif.php.inc (100%) rename rules-tests/Php83/Rector/BooleanAnd/{JsonValidateTest => JsonValidate}/Fixture/inline_string.php.inc (100%) rename rules-tests/Php83/Rector/BooleanAnd/{JsonValidateTest => JsonValidate}/JsonValidateRectorTest.php (100%) rename rules-tests/Php83/Rector/BooleanAnd/{JsonValidateTest => JsonValidate}/config/configured_rule.php (100%) diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateTest/Fixture/Json_validate.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate.php.inc similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidateTest/Fixture/Json_validate.php.inc rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate.php.inc diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateTest/Fixture/Json_validate_named.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate_named.php.inc similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidateTest/Fixture/Json_validate_named.php.inc rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate_named.php.inc diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateTest/Fixture/elseif.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/elseif.php.inc similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidateTest/Fixture/elseif.php.inc rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/elseif.php.inc diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateTest/Fixture/inline_string.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/inline_string.php.inc similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidateTest/Fixture/inline_string.php.inc rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/inline_string.php.inc diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateTest/JsonValidateRectorTest.php b/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/JsonValidateRectorTest.php similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidateTest/JsonValidateRectorTest.php rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidate/JsonValidateRectorTest.php diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateTest/config/configured_rule.php b/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/config/configured_rule.php similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidateTest/config/configured_rule.php rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidate/config/configured_rule.php From e62a32c31066bedd4dcbc4881b47953255ac8c19 Mon Sep 17 00:00:00 2001 From: Arshid Date: Sat, 30 Aug 2025 11:36:48 +0530 Subject: [PATCH 11/48] [php 8.3] Add json_validate rule --- .../Fixture/Json_validate.php.inc | 0 .../Fixture/Json_validate_named.php.inc | 0 .../{JsonValidate => JsonValidateRector}/Fixture/elseif.php.inc | 0 .../Fixture/inline_string.php.inc | 0 .../JsonValidateRectorTest.php | 0 .../config/configured_rule.php | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename rules-tests/Php83/Rector/BooleanAnd/{JsonValidate => JsonValidateRector}/Fixture/Json_validate.php.inc (100%) rename rules-tests/Php83/Rector/BooleanAnd/{JsonValidate => JsonValidateRector}/Fixture/Json_validate_named.php.inc (100%) rename rules-tests/Php83/Rector/BooleanAnd/{JsonValidate => JsonValidateRector}/Fixture/elseif.php.inc (100%) rename rules-tests/Php83/Rector/BooleanAnd/{JsonValidate => JsonValidateRector}/Fixture/inline_string.php.inc (100%) rename rules-tests/Php83/Rector/BooleanAnd/{JsonValidate => JsonValidateRector}/JsonValidateRectorTest.php (100%) rename rules-tests/Php83/Rector/BooleanAnd/{JsonValidate => JsonValidateRector}/config/configured_rule.php (100%) diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate.php.inc similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate.php.inc rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate.php.inc diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate_named.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate_named.php.inc similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/Json_validate_named.php.inc rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate_named.php.inc diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/elseif.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/elseif.php.inc similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/elseif.php.inc rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/elseif.php.inc diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/inline_string.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/inline_string.php.inc similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidate/Fixture/inline_string.php.inc rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/inline_string.php.inc diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/JsonValidateRectorTest.php b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/JsonValidateRectorTest.php similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidate/JsonValidateRectorTest.php rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/JsonValidateRectorTest.php diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidate/config/configured_rule.php b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/config/configured_rule.php similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidate/config/configured_rule.php rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/config/configured_rule.php From 996ff1a6fc1ef69b6dc41bcab6b4b44495512a16 Mon Sep 17 00:00:00 2001 From: Arshid Date: Sat, 30 Aug 2025 12:46:15 +0530 Subject: [PATCH 12/48] [php 8.3] Add json_validate rule --- src/ValueObject/PhpVersionFeature.php | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/ValueObject/PhpVersionFeature.php b/src/ValueObject/PhpVersionFeature.php index e073214ca3e..c8acf525023 100644 --- a/src/ValueObject/PhpVersionFeature.php +++ b/src/ValueObject/PhpVersionFeature.php @@ -522,11 +522,6 @@ final class PhpVersionFeature */ public const STR_CONTAINS = PhpVersion::PHP_80; - /** - * @var int - */ - public const JSON_VALIDATE = PhpVersion::PHP_80; - /** * @var int */ @@ -803,10 +798,4 @@ final class PhpVersionFeature * @var int */ public const DEPRECATE_NULL_ARG_IN_ARRAY_KEY_EXISTS_FUNCTION = PhpVersion::PHP_85; - - /** - * @see https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_passing_string_which_are_not_one_byte_long_to_ord - * @var int - */ - public const DEPRECATE_ORD_WITH_MULTIBYTE_STRING = PhpVersion::PHP_85; -} +} \ No newline at end of file From ebc267279520bca6cebaa53d0a224639379884ab Mon Sep 17 00:00:00 2001 From: Arshid Date: Sat, 30 Aug 2025 12:50:02 +0530 Subject: [PATCH 13/48] [php 8.3] Add json_validate rule --- src/ValueObject/PhpVersionFeature.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ValueObject/PhpVersionFeature.php b/src/ValueObject/PhpVersionFeature.php index c8acf525023..f903c5a7fc2 100644 --- a/src/ValueObject/PhpVersionFeature.php +++ b/src/ValueObject/PhpVersionFeature.php @@ -522,6 +522,11 @@ final class PhpVersionFeature */ public const STR_CONTAINS = PhpVersion::PHP_80; + /** + * @var int + */ + public const JSON_VALIDATE = PhpVersion::PHP_80; + /** * @var int */ @@ -798,4 +803,4 @@ final class PhpVersionFeature * @var int */ public const DEPRECATE_NULL_ARG_IN_ARRAY_KEY_EXISTS_FUNCTION = PhpVersion::PHP_85; -} \ No newline at end of file +} From cd85f76bbce34b6c94273afea018df0b758c2a8e Mon Sep 17 00:00:00 2001 From: Arshid Date: Sat, 30 Aug 2025 16:15:55 +0530 Subject: [PATCH 14/48] [php 8.3] Add json_validate rule --- src/ValueObject/PolyfillPackage.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ValueObject/PolyfillPackage.php b/src/ValueObject/PolyfillPackage.php index 06ca9334736..a3772b256ab 100644 --- a/src/ValueObject/PolyfillPackage.php +++ b/src/ValueObject/PolyfillPackage.php @@ -9,6 +9,11 @@ */ final class PolyfillPackage { + /** + * @var string + */ + public const PHP_83 = 'symfony/polyfill-php83'; + /** * @var string */ From 6c975d852dfc812cdbb15e0b12dc2d4aed310721 Mon Sep 17 00:00:00 2001 From: Arshid Date: Sat, 30 Aug 2025 16:23:50 +0530 Subject: [PATCH 15/48] [php 8.3] Add json_validate rule --- .../BooleanAnd/JsonValidateRector/config/configured_rule.php | 2 +- rules/Php83/Rector/BooleanAnd/JsonValidateRector.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/config/configured_rule.php b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/config/configured_rule.php index 3007d10b9fc..dd7fc250a5d 100644 --- a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/config/configured_rule.php +++ b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/config/configured_rule.php @@ -7,7 +7,7 @@ use Rector\ValueObject\PhpVersion; return static function (RectorConfig $rectorConfig): void { - $rectorConfig->phpVersion(PhpVersion::PHP_80); + $rectorConfig->phpVersion(PhpVersion::PHP_83); $rectorConfig->rule(JsonValidateRector::class); }; diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index 866d2ff94e8..1d8f63e301f 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -84,7 +84,7 @@ public function refactor(Node $node): ?Node public function providePolyfillPackage(): string { - return PolyfillPackage::PHP_80; + return PolyfillPackage::PHP_83; } public function matchJsonValidateArg(BooleanAnd $booleanAnd): ?FuncCall From e23d2c73d5a375cdc0c3e95f5f5a0d5b3b4539f4 Mon Sep 17 00:00:00 2001 From: Arshid Date: Sat, 30 Aug 2025 16:26:45 +0530 Subject: [PATCH 16/48] [php 8.3] Add json_validate rule --- src/ValueObject/PhpVersionFeature.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ValueObject/PhpVersionFeature.php b/src/ValueObject/PhpVersionFeature.php index f903c5a7fc2..ea4720424de 100644 --- a/src/ValueObject/PhpVersionFeature.php +++ b/src/ValueObject/PhpVersionFeature.php @@ -522,11 +522,6 @@ final class PhpVersionFeature */ public const STR_CONTAINS = PhpVersion::PHP_80; - /** - * @var int - */ - public const JSON_VALIDATE = PhpVersion::PHP_80; - /** * @var int */ @@ -706,6 +701,11 @@ final class PhpVersionFeature * @var int */ public const DYNAMIC_CLASS_CONST_FETCH = PhpVersion::PHP_83; + + /** + * @var int + */ + public const JSON_VALIDATE = PhpVersion::PHP_80; /** * @see https://wiki.php.net/rfc/deprecate-implicitly-nullable-types From 3377025469b3bfeaae366acd6a2eb8d7ffcb2333 Mon Sep 17 00:00:00 2001 From: Arshid Date: Sat, 30 Aug 2025 16:27:39 +0530 Subject: [PATCH 17/48] [php 8.3] Add json_validate rule --- src/ValueObject/PhpVersionFeature.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ValueObject/PhpVersionFeature.php b/src/ValueObject/PhpVersionFeature.php index ea4720424de..e292c50a21d 100644 --- a/src/ValueObject/PhpVersionFeature.php +++ b/src/ValueObject/PhpVersionFeature.php @@ -705,7 +705,7 @@ final class PhpVersionFeature /** * @var int */ - public const JSON_VALIDATE = PhpVersion::PHP_80; + public const JSON_VALIDATE = PhpVersion::PHP_83; /** * @see https://wiki.php.net/rfc/deprecate-implicitly-nullable-types From be1813a0d3c34d45869ff777a5d6dad75981dc2a Mon Sep 17 00:00:00 2001 From: Arshid Date: Sat, 30 Aug 2025 16:40:21 +0530 Subject: [PATCH 18/48] [php 8.3] Add json_validate rule --- .../JsonValidateRector/Fixture/Json_validate.php.inc | 2 ++ .../JsonValidateRector/Fixture/Json_validate_named.php.inc | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate.php.inc index 5e1e7cc695b..87748e3d6f4 100644 --- a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate.php.inc +++ b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate.php.inc @@ -1,4 +1,5 @@ ----- @@ -9,7 +9,7 @@ if (json_decode($json, true) !== null && json_last_error() === JSON_ERROR_NONE){ From cfceaab37b6b1386f3d0727d07b3b16442362eac Mon Sep 17 00:00:00 2001 From: Arshid Date: Sat, 30 Aug 2025 17:10:33 +0530 Subject: [PATCH 19/48] [php 8.3] Add json_validate rule --- .../Fixture/Json_validate.php.inc | 2 +- .../Fixture/Json_validate_named.php.inc | 4 +- .../JsonValidateRector/Fixture/elseif.php.inc | 2 +- .../Fixture/inline_string.php.inc | 2 +- .../Fixture/json_flag.php.inc | 17 ++++++++ .../Fixture/json_validate_base.php.inc | 17 ++++++++ .../Rector/BooleanAnd/JsonValidateRector.php | 40 +++++++++++++++++-- 7 files changed, 75 insertions(+), 9 deletions(-) create mode 100644 rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_flag.php.inc create mode 100644 rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_base.php.inc diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate.php.inc index 87748e3d6f4..c5a679544a1 100644 --- a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate.php.inc +++ b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate.php.inc @@ -11,7 +11,7 @@ if (json_decode($json, true) !== null && json_last_error() === JSON_ERROR_NONE){ namespace Rector\Tests\Php83\Rector\BooleanAnd\JsonValidateRector\Fixture; -if (json_validate($json)){ +if (json_validate($json, true)){ echo 1; } ?> \ No newline at end of file diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate_named.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate_named.php.inc index 316bed9f16e..7d9e3cda76e 100644 --- a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate_named.php.inc +++ b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate_named.php.inc @@ -1,7 +1,7 @@ @@ -9,7 +9,7 @@ if (json_decode(json: $json, true) !== null && json_last_error() === JSON_ERROR_ diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/elseif.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/elseif.php.inc index 94733abea8a..cad374eaeb0 100644 --- a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/elseif.php.inc +++ b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/elseif.php.inc @@ -12,6 +12,6 @@ namespace Rector\Tests\Php83\Rector\BooleanAnd\JsonValidateRector\Fixture; if ($flag) { echo "skip"; -} elseif (json_validate($config)) { +} elseif (json_validate($config, true)) { echo "valid config"; } diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/inline_string.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/inline_string.php.inc index a87faa97959..20cb92fc231 100644 --- a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/inline_string.php.inc +++ b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/inline_string.php.inc @@ -8,6 +8,6 @@ if (json_decode('{"a":1}', true) !== null && json_last_error() === JSON_ERROR_NO +----- + \ No newline at end of file diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_base.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_base.php.inc new file mode 100644 index 00000000000..002e3c80f8e --- /dev/null +++ b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_base.php.inc @@ -0,0 +1,17 @@ + +----- + \ No newline at end of file diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index 1d8f63e301f..7fcbeed9a29 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -10,6 +10,7 @@ use PhpParser\Node\Expr\BinaryOp\NotIdentical; use PhpParser\Node\Expr\ConstFetch; use PhpParser\Node\Expr\FuncCall; +use PhpParser\Node\Identifier; use PhpParser\Node\Name; use Rector\Rector\AbstractRector; use Rector\ValueObject\PhpVersionFeature; @@ -73,11 +74,18 @@ public function refactor(Node $node): ?Node return null; } - if (isset($funcCall->getArgs()[1])) { - unset($funcCall->args[1]); - } - + $args = $funcCall->getArgs(); + $argPositions = $this->resolveArgPositions($args); + $funcCall->name = new Name('json_validate'); + $funcCall->args = []; + + foreach($argPositions as $position){ + if(! isset($args[$position])){ + continue; + } + $funcCall->args[$position] = $args[$position]; + } return $funcCall; } @@ -87,6 +95,30 @@ public function providePolyfillPackage(): string return PolyfillPackage::PHP_83; } + /** + * @param Arg[] $args + */ + private function resolveArgPositions(array $args): array + { + $positions = []; + $expectedNames = ['json', 'associative', 'depth', 'flags']; + foreach ($args as $position => $arg) { + if ($arg->name instanceof Identifier) { + $name = $arg->name->toString(); + if (in_array($name, $expectedNames, true)) { + $positions[$name] = $position; + } + } + } + + return [ + 'json' => 0, + 'associative' => 1, + 'depth' => 2, + 'flags' => 3 + ]; + } + public function matchJsonValidateArg(BooleanAnd $booleanAnd): ?FuncCall { if ($booleanAnd->left instanceof NotIdentical) { From 73f0f228ef685aa63ba945449a099dd06e16bcd0 Mon Sep 17 00:00:00 2001 From: Arshid Date: Sat, 30 Aug 2025 17:16:43 +0530 Subject: [PATCH 20/48] [php 8.3] Add json_validate rule --- .../Rector/BooleanAnd/JsonValidateRector.php | 57 ++++++++++--------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index 7fcbeed9a29..5c7964f852d 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -76,15 +76,16 @@ public function refactor(Node $node): ?Node $args = $funcCall->getArgs(); $argPositions = $this->resolveArgPositions($args); - + $funcCall->name = new Name('json_validate'); $funcCall->args = []; - foreach($argPositions as $position){ - if(! isset($args[$position])){ + foreach ($argPositions as $argPosition) { + if (! isset($args[$argPosition])) { continue; } - $funcCall->args[$position] = $args[$position]; + + $funcCall->args[$argPosition] = $args[$argPosition]; } return $funcCall; @@ -95,30 +96,6 @@ public function providePolyfillPackage(): string return PolyfillPackage::PHP_83; } - /** - * @param Arg[] $args - */ - private function resolveArgPositions(array $args): array - { - $positions = []; - $expectedNames = ['json', 'associative', 'depth', 'flags']; - foreach ($args as $position => $arg) { - if ($arg->name instanceof Identifier) { - $name = $arg->name->toString(); - if (in_array($name, $expectedNames, true)) { - $positions[$name] = $position; - } - } - } - - return [ - 'json' => 0, - 'associative' => 1, - 'depth' => 2, - 'flags' => 3 - ]; - } - public function matchJsonValidateArg(BooleanAnd $booleanAnd): ?FuncCall { if ($booleanAnd->left instanceof NotIdentical) { @@ -149,4 +126,28 @@ public function matchJsonValidateArg(BooleanAnd $booleanAnd): ?FuncCall return null; } + + /** + * @param PhpParser\Node\Arg[] $args + */ + private function resolveArgPositions(array $args): array + { + $positions = []; + $expectedNames = ['json', 'associative', 'depth', 'flags']; + foreach ($args as $position => $arg) { + if ($arg->name instanceof Identifier) { + $name = $arg->name->toString(); + if (in_array($name, $expectedNames, true)) { + $positions[$name] = $position; + } + } + } + + return [ + 'json' => 0, + 'associative' => 1, + 'depth' => 2, + 'flags' => 3, + ]; + } } From 097388d8dd0b27a4c0741221bc25f08592eebc43 Mon Sep 17 00:00:00 2001 From: Arshid Date: Sat, 30 Aug 2025 17:18:55 +0530 Subject: [PATCH 21/48] [php 8.3] Add json_validate rule --- rules/Php83/Rector/BooleanAnd/JsonValidateRector.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index 5c7964f852d..d61213d4620 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -5,6 +5,7 @@ namespace Rector\Php83\Rector\BooleanAnd; use PhpParser\Node; +use PhpParser\Node\Arg; use PhpParser\Node\Expr\BinaryOp\BooleanAnd; use PhpParser\Node\Expr\BinaryOp\Identical; use PhpParser\Node\Expr\BinaryOp\NotIdentical; @@ -128,7 +129,8 @@ public function matchJsonValidateArg(BooleanAnd $booleanAnd): ?FuncCall } /** - * @param PhpParser\Node\Arg[] $args + * @param Arg[] $args + * @return array Maps argument name to its position */ private function resolveArgPositions(array $args): array { From 4a94748a791ec733000f6469ebb8b87a7c3fce26 Mon Sep 17 00:00:00 2001 From: Arshid Date: Sat, 30 Aug 2025 19:48:00 +0530 Subject: [PATCH 22/48] [php 8.3] Add json_validate rule --- .../Rector/BooleanAnd/JsonValidateRector.php | 34 ++++--------------- 1 file changed, 6 insertions(+), 28 deletions(-) diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index d61213d4620..a7bc675dacf 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -5,13 +5,11 @@ namespace Rector\Php83\Rector\BooleanAnd; use PhpParser\Node; -use PhpParser\Node\Arg; use PhpParser\Node\Expr\BinaryOp\BooleanAnd; use PhpParser\Node\Expr\BinaryOp\Identical; use PhpParser\Node\Expr\BinaryOp\NotIdentical; use PhpParser\Node\Expr\ConstFetch; use PhpParser\Node\Expr\FuncCall; -use PhpParser\Node\Identifier; use PhpParser\Node\Name; use Rector\Rector\AbstractRector; use Rector\ValueObject\PhpVersionFeature; @@ -76,7 +74,12 @@ public function refactor(Node $node): ?Node } $args = $funcCall->getArgs(); - $argPositions = $this->resolveArgPositions($args); + $argPositions = [ + 'json' => 0, + 'associative' => 1, + 'depth' => 2, + 'flags' => 3, + ]; $funcCall->name = new Name('json_validate'); $funcCall->args = []; @@ -127,29 +130,4 @@ public function matchJsonValidateArg(BooleanAnd $booleanAnd): ?FuncCall return null; } - - /** - * @param Arg[] $args - * @return array Maps argument name to its position - */ - private function resolveArgPositions(array $args): array - { - $positions = []; - $expectedNames = ['json', 'associative', 'depth', 'flags']; - foreach ($args as $position => $arg) { - if ($arg->name instanceof Identifier) { - $name = $arg->name->toString(); - if (in_array($name, $expectedNames, true)) { - $positions[$name] = $position; - } - } - } - - return [ - 'json' => 0, - 'associative' => 1, - 'depth' => 2, - 'flags' => 3, - ]; - } } From 3f78b411c3a89cdc48e988a14b182b9ca471aa77 Mon Sep 17 00:00:00 2001 From: Arshid Date: Sat, 30 Aug 2025 20:01:45 +0530 Subject: [PATCH 23/48] [php 8.3] Add json_validate rule --- .../Fixture/Json_validate_named_base.php.inc | 15 +++++++++++++++ .../Rector/BooleanAnd/JsonValidateRector.php | 14 +++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate_named_base.php.inc diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate_named_base.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate_named_base.php.inc new file mode 100644 index 00000000000..dd40a1364a7 --- /dev/null +++ b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate_named_base.php.inc @@ -0,0 +1,15 @@ + +----- + diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index a7bc675dacf..71516cdb545 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -75,21 +75,21 @@ public function refactor(Node $node): ?Node $args = $funcCall->getArgs(); $argPositions = [ - 'json' => 0, - 'associative' => 1, - 'depth' => 2, - 'flags' => 3, + 'json', + 'associative', + 'depth', + 'flags', ]; $funcCall->name = new Name('json_validate'); $funcCall->args = []; - foreach ($argPositions as $argPosition) { - if (! isset($args[$argPosition])) { + foreach ($argPositions as $position => $argKey) { + if (! isset($args[$position])) { continue; } - $funcCall->args[$argPosition] = $args[$argPosition]; + $funcCall->args[$position] = $args[$position]; } return $funcCall; From 70d193c25d20399684841f94cfdade5c33e8543f Mon Sep 17 00:00:00 2001 From: Arshid Date: Sat, 30 Aug 2025 20:03:31 +0530 Subject: [PATCH 24/48] [php 8.3] Add json_validate rule --- .../Rector/BooleanAnd/JsonValidateRector.php | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index 71516cdb545..07ebc0a793e 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -74,23 +74,9 @@ public function refactor(Node $node): ?Node } $args = $funcCall->getArgs(); - $argPositions = [ - 'json', - 'associative', - 'depth', - 'flags', - ]; - $funcCall->name = new Name('json_validate'); $funcCall->args = []; - - foreach ($argPositions as $position => $argKey) { - if (! isset($args[$position])) { - continue; - } - - $funcCall->args[$position] = $args[$position]; - } + $funcCall->args = $args; return $funcCall; } From 162a30e8c504c0b7ebbdee40567a4b67b3b28330 Mon Sep 17 00:00:00 2001 From: Arshid Date: Mon, 1 Sep 2025 15:16:21 +0530 Subject: [PATCH 25/48] [php 8.3] Add json_validate rule --- .../Fixture/json_validate_yoda.php.inc | 17 +++++++ .../Fixture/json_validate_yoda_base.php.inc | 17 +++++++ .../Rector/BooleanAnd/JsonValidateRector.php | 50 +++++++++++++------ 3 files changed, 69 insertions(+), 15 deletions(-) create mode 100644 rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda.php.inc create mode 100644 rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda_base.php.inc diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda.php.inc new file mode 100644 index 00000000000..da31c299838 --- /dev/null +++ b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda.php.inc @@ -0,0 +1,17 @@ + +----- + \ No newline at end of file diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda_base.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda_base.php.inc new file mode 100644 index 00000000000..60629369fbc --- /dev/null +++ b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda_base.php.inc @@ -0,0 +1,17 @@ + +----- + \ No newline at end of file diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index 07ebc0a793e..a9e5e3c2a40 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -91,28 +91,48 @@ public function matchJsonValidateArg(BooleanAnd $booleanAnd): ?FuncCall if ($booleanAnd->left instanceof NotIdentical) { $notIdentical = $booleanAnd->left; - if ($notIdentical->left instanceof FuncCall - && $this->isName($notIdentical->left->name, 'json_decode') - && $notIdentical->right instanceof ConstFetch - && $this->isName($notIdentical->right->name, 'null')) { + $jsonDecodeCall = $this->getJsonNode($notIdentical); - // right side: json_last_error() === JSON_ERROR_NONE - if (! $booleanAnd->right instanceof Identical) { - return null; - } + if (! $booleanAnd->right instanceof Identical) { + return null; + } - $identical = $booleanAnd->right; + $identical = $booleanAnd->right; - if ($identical->left instanceof FuncCall - && $this->isName($identical->left->name, 'json_last_error') - && $identical->right instanceof ConstFetch - && $this->isName($identical->right->name, 'JSON_ERROR_NONE')) { + if ($identical->left instanceof \PhpParser\Node\Expr\FuncCall + && $this->isName($identical->left->name, 'json_last_error') + && $identical->right instanceof ConstFetch + && $this->isName($identical->right->name, 'JSON_ERROR_NONE')) { + return $jsonDecodeCall; // return json_decode(...) call + } - return $notIdentical->left; // return json_decode(...) call - } + if ( + $identical->left instanceof ConstFetch + && $this->isName($identical->left->name, 'JSON_ERROR_NONE') + && $identical->right instanceof \PhpParser\Node\Expr\FuncCall + && $this->isName($identical->right->name, 'json_last_error') + ) { + return $jsonDecodeCall; // return json_decode(...) call } } + return null; + } + + protected function getJsonNode(NotIdentical $notIdentical): ?FuncCall + { + + if ($notIdentical->left instanceof FuncCall + && $this->isName($notIdentical->left->name, 'json_decode') + ) { + return $notIdentical->left; + } + + if ($notIdentical->right instanceof FuncCall + && $this->isName($notIdentical->right->name, 'json_decode') + ) { + return $notIdentical->right; + } return null; } From 337c8c2af1d6cb2e36e319f08041ecfdfe8a375a Mon Sep 17 00:00:00 2001 From: Arshid Date: Mon, 1 Sep 2025 15:19:40 +0530 Subject: [PATCH 26/48] [php 8.3] Add json_validate rule --- rules/Php83/Rector/BooleanAnd/JsonValidateRector.php | 1 - 1 file changed, 1 deletion(-) diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index a9e5e3c2a40..fdbb0017a20 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -75,7 +75,6 @@ public function refactor(Node $node): ?Node $args = $funcCall->getArgs(); $funcCall->name = new Name('json_validate'); - $funcCall->args = []; $funcCall->args = $args; return $funcCall; From e24127887623bd1e4dcc703afb7a653cc6777e7a Mon Sep 17 00:00:00 2001 From: Arshid Date: Mon, 1 Sep 2025 15:51:31 +0530 Subject: [PATCH 27/48] [php 8.3] Add json_validate rule --- .../Rector/BooleanAnd/JsonValidateRector.php | 56 +++++++++++-------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index fdbb0017a20..af4057cf567 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -11,6 +11,8 @@ use PhpParser\Node\Expr\ConstFetch; use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Name; +use Rector\NodeManipulator\BinaryOpManipulator; +use Rector\Php71\ValueObject\TwoNodeMatch; use Rector\Rector\AbstractRector; use Rector\ValueObject\PhpVersionFeature; use Rector\ValueObject\PolyfillPackage; @@ -24,6 +26,11 @@ */ final class JsonValidateRector extends AbstractRector implements MinPhpVersionInterface, RelatedPolyfillInterface { + public function __construct( + private readonly BinaryOpManipulator $binaryOpManipulator + ) { + } + public function provideMinPhpVersion(): int { return PhpVersionFeature::JSON_VALIDATE; @@ -87,35 +94,38 @@ public function providePolyfillPackage(): string public function matchJsonValidateArg(BooleanAnd $booleanAnd): ?FuncCall { - if ($booleanAnd->left instanceof NotIdentical) { - $notIdentical = $booleanAnd->left; - - $jsonDecodeCall = $this->getJsonNode($notIdentical); + // match: json_decode(...) !== null OR null !== json_decode(...) + if (!($booleanAnd->left instanceof NotIdentical)) { + return null; + } - if (! $booleanAnd->right instanceof Identical) { - return null; - } + $decodeMatch = $this->binaryOpManipulator->matchFirstAndSecondConditionNode( + $booleanAnd->left, + fn($node) => $node instanceof FuncCall && $this->isName($node->name, 'json_decode'), + fn($node) => $node instanceof ConstFetch && $this->isName($node->name, 'null') + ); - $identical = $booleanAnd->right; + if (! $decodeMatch instanceof TwoNodeMatch) { + return null; + } - if ($identical->left instanceof \PhpParser\Node\Expr\FuncCall - && $this->isName($identical->left->name, 'json_last_error') - && $identical->right instanceof ConstFetch - && $this->isName($identical->right->name, 'JSON_ERROR_NONE')) { - return $jsonDecodeCall; // return json_decode(...) call - } + // match: json_last_error() === JSON_ERROR_NONE OR JSON_ERROR_NONE === json_last_error() + if (!($booleanAnd->right instanceof Identical)) { + return null; + } - if ( - $identical->left instanceof ConstFetch - && $this->isName($identical->left->name, 'JSON_ERROR_NONE') - && $identical->right instanceof \PhpParser\Node\Expr\FuncCall - && $this->isName($identical->right->name, 'json_last_error') - ) { - return $jsonDecodeCall; // return json_decode(...) call - } + $errorMatch = $this->binaryOpManipulator->matchFirstAndSecondConditionNode( + $booleanAnd->right, + fn($node) => $node instanceof FuncCall && $this->isName($node->name, 'json_last_error'), + fn($node) => $node instanceof ConstFetch && $this->isName($node->name, 'JSON_ERROR_NONE') + ); + if (! $errorMatch instanceof TwoNodeMatch) { + return null; } - return null; + + // always return the json_decode(...) call + return $decodeMatch->getFirstExpr(); } protected function getJsonNode(NotIdentical $notIdentical): ?FuncCall From 8a47321e2744aab874782c151632f0a3bba60172 Mon Sep 17 00:00:00 2001 From: Arshid Date: Mon, 1 Sep 2025 15:56:44 +0530 Subject: [PATCH 28/48] [php 8.3] Add json_validate rule --- .../Rector/BooleanAnd/JsonValidateRector.php | 21 ++++--------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index af4057cf567..23bcdf687b8 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -125,24 +125,11 @@ public function matchJsonValidateArg(BooleanAnd $booleanAnd): ?FuncCall } // always return the json_decode(...) call - return $decodeMatch->getFirstExpr(); - } - - protected function getJsonNode(NotIdentical $notIdentical): ?FuncCall - { - - if ($notIdentical->left instanceof FuncCall - && $this->isName($notIdentical->left->name, 'json_decode') - ) { - return $notIdentical->left; - } - - if ($notIdentical->right instanceof FuncCall - && $this->isName($notIdentical->right->name, 'json_decode') - ) { - return $notIdentical->right; + $funcCall = $decodeMatch->getFirstExpr(); + if(!$funcCall instanceof FuncCall){ + return null; } - return null; + return $funcCall; } } From e9b25127d50c2f2fe2ff5fe61856a8d273ea588c Mon Sep 17 00:00:00 2001 From: Arshid Date: Mon, 1 Sep 2025 16:01:49 +0530 Subject: [PATCH 29/48] [php 8.3] Add json_validate rule --- .../Rector/BooleanAnd/JsonValidateRector.php | 71 ++++++++++--------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index 23bcdf687b8..fdbb0017a20 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -11,8 +11,6 @@ use PhpParser\Node\Expr\ConstFetch; use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Name; -use Rector\NodeManipulator\BinaryOpManipulator; -use Rector\Php71\ValueObject\TwoNodeMatch; use Rector\Rector\AbstractRector; use Rector\ValueObject\PhpVersionFeature; use Rector\ValueObject\PolyfillPackage; @@ -26,11 +24,6 @@ */ final class JsonValidateRector extends AbstractRector implements MinPhpVersionInterface, RelatedPolyfillInterface { - public function __construct( - private readonly BinaryOpManipulator $binaryOpManipulator - ) { - } - public function provideMinPhpVersion(): int { return PhpVersionFeature::JSON_VALIDATE; @@ -94,42 +87,52 @@ public function providePolyfillPackage(): string public function matchJsonValidateArg(BooleanAnd $booleanAnd): ?FuncCall { - // match: json_decode(...) !== null OR null !== json_decode(...) - if (!($booleanAnd->left instanceof NotIdentical)) { - return null; - } + if ($booleanAnd->left instanceof NotIdentical) { + $notIdentical = $booleanAnd->left; - $decodeMatch = $this->binaryOpManipulator->matchFirstAndSecondConditionNode( - $booleanAnd->left, - fn($node) => $node instanceof FuncCall && $this->isName($node->name, 'json_decode'), - fn($node) => $node instanceof ConstFetch && $this->isName($node->name, 'null') - ); + $jsonDecodeCall = $this->getJsonNode($notIdentical); - if (! $decodeMatch instanceof TwoNodeMatch) { - return null; - } + if (! $booleanAnd->right instanceof Identical) { + return null; + } + + $identical = $booleanAnd->right; + + if ($identical->left instanceof \PhpParser\Node\Expr\FuncCall + && $this->isName($identical->left->name, 'json_last_error') + && $identical->right instanceof ConstFetch + && $this->isName($identical->right->name, 'JSON_ERROR_NONE')) { + return $jsonDecodeCall; // return json_decode(...) call + } + + if ( + $identical->left instanceof ConstFetch + && $this->isName($identical->left->name, 'JSON_ERROR_NONE') + && $identical->right instanceof \PhpParser\Node\Expr\FuncCall + && $this->isName($identical->right->name, 'json_last_error') + ) { + return $jsonDecodeCall; // return json_decode(...) call + } - // match: json_last_error() === JSON_ERROR_NONE OR JSON_ERROR_NONE === json_last_error() - if (!($booleanAnd->right instanceof Identical)) { - return null; } + return null; + } - $errorMatch = $this->binaryOpManipulator->matchFirstAndSecondConditionNode( - $booleanAnd->right, - fn($node) => $node instanceof FuncCall && $this->isName($node->name, 'json_last_error'), - fn($node) => $node instanceof ConstFetch && $this->isName($node->name, 'JSON_ERROR_NONE') - ); + protected function getJsonNode(NotIdentical $notIdentical): ?FuncCall + { - if (! $errorMatch instanceof TwoNodeMatch) { - return null; + if ($notIdentical->left instanceof FuncCall + && $this->isName($notIdentical->left->name, 'json_decode') + ) { + return $notIdentical->left; } - // always return the json_decode(...) call - $funcCall = $decodeMatch->getFirstExpr(); - if(!$funcCall instanceof FuncCall){ - return null; + if ($notIdentical->right instanceof FuncCall + && $this->isName($notIdentical->right->name, 'json_decode') + ) { + return $notIdentical->right; } - return $funcCall; + return null; } } From a26229b320d2a5a5347c827cdfc3f6a5395f1766 Mon Sep 17 00:00:00 2001 From: Arshid Date: Mon, 1 Sep 2025 16:04:09 +0530 Subject: [PATCH 30/48] [php 8.3] Add json_validate rule --- .../Rector/BooleanAnd/JsonValidateRector.php | 71 +++++++++---------- 1 file changed, 34 insertions(+), 37 deletions(-) diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index fdbb0017a20..23bcdf687b8 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -11,6 +11,8 @@ use PhpParser\Node\Expr\ConstFetch; use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Name; +use Rector\NodeManipulator\BinaryOpManipulator; +use Rector\Php71\ValueObject\TwoNodeMatch; use Rector\Rector\AbstractRector; use Rector\ValueObject\PhpVersionFeature; use Rector\ValueObject\PolyfillPackage; @@ -24,6 +26,11 @@ */ final class JsonValidateRector extends AbstractRector implements MinPhpVersionInterface, RelatedPolyfillInterface { + public function __construct( + private readonly BinaryOpManipulator $binaryOpManipulator + ) { + } + public function provideMinPhpVersion(): int { return PhpVersionFeature::JSON_VALIDATE; @@ -87,52 +94,42 @@ public function providePolyfillPackage(): string public function matchJsonValidateArg(BooleanAnd $booleanAnd): ?FuncCall { - if ($booleanAnd->left instanceof NotIdentical) { - $notIdentical = $booleanAnd->left; - - $jsonDecodeCall = $this->getJsonNode($notIdentical); - - if (! $booleanAnd->right instanceof Identical) { - return null; - } - - $identical = $booleanAnd->right; + // match: json_decode(...) !== null OR null !== json_decode(...) + if (!($booleanAnd->left instanceof NotIdentical)) { + return null; + } - if ($identical->left instanceof \PhpParser\Node\Expr\FuncCall - && $this->isName($identical->left->name, 'json_last_error') - && $identical->right instanceof ConstFetch - && $this->isName($identical->right->name, 'JSON_ERROR_NONE')) { - return $jsonDecodeCall; // return json_decode(...) call - } + $decodeMatch = $this->binaryOpManipulator->matchFirstAndSecondConditionNode( + $booleanAnd->left, + fn($node) => $node instanceof FuncCall && $this->isName($node->name, 'json_decode'), + fn($node) => $node instanceof ConstFetch && $this->isName($node->name, 'null') + ); - if ( - $identical->left instanceof ConstFetch - && $this->isName($identical->left->name, 'JSON_ERROR_NONE') - && $identical->right instanceof \PhpParser\Node\Expr\FuncCall - && $this->isName($identical->right->name, 'json_last_error') - ) { - return $jsonDecodeCall; // return json_decode(...) call - } + if (! $decodeMatch instanceof TwoNodeMatch) { + return null; + } + // match: json_last_error() === JSON_ERROR_NONE OR JSON_ERROR_NONE === json_last_error() + if (!($booleanAnd->right instanceof Identical)) { + return null; } - return null; - } - protected function getJsonNode(NotIdentical $notIdentical): ?FuncCall - { + $errorMatch = $this->binaryOpManipulator->matchFirstAndSecondConditionNode( + $booleanAnd->right, + fn($node) => $node instanceof FuncCall && $this->isName($node->name, 'json_last_error'), + fn($node) => $node instanceof ConstFetch && $this->isName($node->name, 'JSON_ERROR_NONE') + ); - if ($notIdentical->left instanceof FuncCall - && $this->isName($notIdentical->left->name, 'json_decode') - ) { - return $notIdentical->left; + if (! $errorMatch instanceof TwoNodeMatch) { + return null; } - if ($notIdentical->right instanceof FuncCall - && $this->isName($notIdentical->right->name, 'json_decode') - ) { - return $notIdentical->right; + // always return the json_decode(...) call + $funcCall = $decodeMatch->getFirstExpr(); + if(!$funcCall instanceof FuncCall){ + return null; } - return null; + return $funcCall; } } From 0bef2537bc6bb2cd6098c92bc025bfa887906b5f Mon Sep 17 00:00:00 2001 From: Arshid Date: Mon, 1 Sep 2025 16:16:50 +0530 Subject: [PATCH 31/48] [php 8.3] Add json_validate rule --- .../Fixture/Json_validate_reverse.php.inc | 15 ++++++ .../Rector/BooleanAnd/JsonValidateRector.php | 48 ++++++++++++------- 2 files changed, 47 insertions(+), 16 deletions(-) create mode 100644 rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate_reverse.php.inc diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate_reverse.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate_reverse.php.inc new file mode 100644 index 00000000000..e591b6c68b5 --- /dev/null +++ b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate_reverse.php.inc @@ -0,0 +1,15 @@ + +----- + diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index 23bcdf687b8..7bcd1f8c718 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -94,31 +94,29 @@ public function providePolyfillPackage(): string public function matchJsonValidateArg(BooleanAnd $booleanAnd): ?FuncCall { + $decodeMatch = null; + $errorMatch = null; + // match: json_decode(...) !== null OR null !== json_decode(...) - if (!($booleanAnd->left instanceof NotIdentical)) { - return null; + if ($booleanAnd->left instanceof NotIdentical) { + $decodeMatch = $this->decodeMatch($booleanAnd->left); } - $decodeMatch = $this->binaryOpManipulator->matchFirstAndSecondConditionNode( - $booleanAnd->left, - fn($node) => $node instanceof FuncCall && $this->isName($node->name, 'json_decode'), - fn($node) => $node instanceof ConstFetch && $this->isName($node->name, 'null') - ); + if ($booleanAnd->right instanceof NotIdentical) { + $decodeMatch = $this->decodeMatch($booleanAnd->right); + } if (! $decodeMatch instanceof TwoNodeMatch) { return null; } // match: json_last_error() === JSON_ERROR_NONE OR JSON_ERROR_NONE === json_last_error() - if (!($booleanAnd->right instanceof Identical)) { - return null; + if ($booleanAnd->right instanceof Identical) { + $errorMatch = $this->errorMatch($booleanAnd->right); + } + if ($booleanAnd->left instanceof Identical) { + $errorMatch = $this->errorMatch($booleanAnd->left); } - - $errorMatch = $this->binaryOpManipulator->matchFirstAndSecondConditionNode( - $booleanAnd->right, - fn($node) => $node instanceof FuncCall && $this->isName($node->name, 'json_last_error'), - fn($node) => $node instanceof ConstFetch && $this->isName($node->name, 'JSON_ERROR_NONE') - ); if (! $errorMatch instanceof TwoNodeMatch) { return null; @@ -126,10 +124,28 @@ public function matchJsonValidateArg(BooleanAnd $booleanAnd): ?FuncCall // always return the json_decode(...) call $funcCall = $decodeMatch->getFirstExpr(); - if(!$funcCall instanceof FuncCall){ + if (! $funcCall instanceof FuncCall) { return null; } return $funcCall; } + + protected function decodeMatch(NotIdentical $notIdentical): ?TwoNodeMatch + { + return $this->binaryOpManipulator->matchFirstAndSecondConditionNode( + $notIdentical, + fn ($node) => $node instanceof FuncCall && $this->isName($node->name, 'json_decode'), + fn ($node) => $node instanceof ConstFetch && $this->isName($node->name, 'null') + ); + } + + protected function errorMatch(Identical $identical): ?TwoNodeMatch + { + return $this->binaryOpManipulator->matchFirstAndSecondConditionNode( + $identical, + fn ($node) => $node instanceof FuncCall && $this->isName($node->name, 'json_last_error'), + fn ($node) => $node instanceof ConstFetch && $this->isName($node->name, 'JSON_ERROR_NONE') + ); + } } From 3b8c9b20babcdde855a3e3d05118c28ed61ed1d4 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Sat, 30 Aug 2025 16:23:26 -0700 Subject: [PATCH 32/48] [8.4][DeprecatedAnnotationToDeprecatedAttributeRector] Remove invalid example (#7202) Classes are not affected by the rule and are not supported by the `#[\Deprecated]` attribute --- ...tedAnnotationToDeprecatedAttributeRector.php | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/rules/Php84/Rector/Class_/DeprecatedAnnotationToDeprecatedAttributeRector.php b/rules/Php84/Rector/Class_/DeprecatedAnnotationToDeprecatedAttributeRector.php index 37c4e2ba4cb..fd1e87b1752 100644 --- a/rules/Php84/Rector/Class_/DeprecatedAnnotationToDeprecatedAttributeRector.php +++ b/rules/Php84/Rector/Class_/DeprecatedAnnotationToDeprecatedAttributeRector.php @@ -30,23 +30,6 @@ public function getRuleDefinition(): RuleDefinition return new RuleDefinition('Change @deprecated annotation to Deprecated attribute', [ new CodeSample( <<<'CODE_SAMPLE' -/** - * @deprecated 1.0.0 Use SomeOtherClass instead - */ -class SomeClass -{ -} -CODE_SAMPLE - , - <<<'CODE_SAMPLE' -#[\Deprecated(message: 'Use SomeOtherClass instead', since: '1.0.0')] -class SomeClass -{ -} -CODE_SAMPLE - ), - new CodeSample( - <<<'CODE_SAMPLE' /** * @deprecated 1.0.0 Use SomeOtherFunction instead */ From e8d6723bffca119476c1bdb2fcd36bd1aab1a978 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Sun, 31 Aug 2025 02:38:50 +0200 Subject: [PATCH 33/48] [automated] Apply Coding Standard (#7203) Co-authored-by: TomasVotruba <924196+TomasVotruba@users.noreply.github.com> --- .../ArrayKeyExistsNullToEmptyStringRector.php | 10 +++++----- src/NodeTypeResolver/NodeTypeResolver.php | 16 ++++++++-------- src/Rector/AbstractRector.php | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php b/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php index 84d8c80d9da..b061f553d50 100644 --- a/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php +++ b/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php @@ -105,6 +105,11 @@ public function refactor(Node $node): ?Node return null; } + public function provideMinPhpVersion(): int + { + return PhpVersionFeature::DEPRECATE_NULL_ARG_IN_ARRAY_KEY_EXISTS_FUNCTION; + } + /** * @param Arg[] $args */ @@ -118,9 +123,4 @@ private function resolvePosition(array $args): int return 0; } - - public function provideMinPhpVersion(): int - { - return PhpVersionFeature::DEPRECATE_NULL_ARG_IN_ARRAY_KEY_EXISTS_FUNCTION; - } } diff --git a/src/NodeTypeResolver/NodeTypeResolver.php b/src/NodeTypeResolver/NodeTypeResolver.php index 5ae596a31c1..6cde992ec83 100644 --- a/src/NodeTypeResolver/NodeTypeResolver.php +++ b/src/NodeTypeResolver/NodeTypeResolver.php @@ -255,14 +255,6 @@ public function isNullableType(Node $node): bool return TypeCombinator::containsNull($nodeType); } - private function correctType(Type $type): Type - { - $type = $this->accessoryNonEmptyStringTypeCorrector->correct($type); - $type = $this->genericClassStringTypeCorrector->correct($type); - - return $this->accessoryNonEmptyArrayTypeCorrector->correct($type); - } - public function getNativeType(Expr $expr): Type { $scope = $expr->getAttribute(AttributeKey::SCOPE); @@ -376,6 +368,14 @@ public function isMethodStaticCallOrClassMethodObjectType(Node $node, ObjectType return $classReflection->hasTraitUse($objectType->getClassName()); } + private function correctType(Type $type): Type + { + $type = $this->accessoryNonEmptyStringTypeCorrector->correct($type); + $type = $this->genericClassStringTypeCorrector->correct($type); + + return $this->accessoryNonEmptyArrayTypeCorrector->correct($type); + } + /** * Allow pull type from * diff --git a/src/Rector/AbstractRector.php b/src/Rector/AbstractRector.php index 050b56c21ff..5e22b99ec2b 100644 --- a/src/Rector/AbstractRector.php +++ b/src/Rector/AbstractRector.php @@ -356,7 +356,7 @@ private function postRefactorProcess( $firstNode = current($refactoredNode); if ($firstNode->getAttribute(AttributeKey::HAS_MERGED_COMMENTS, false) === false) { - $this->mirrorComments($firstNode, $originalNode); + $this->mirrorComments($firstNode, $originalNode); } $this->refreshScopeNodes($refactoredNode, $filePath, $currentScope); From bf3716bc44fa8ed8046d19703b85c324db5ea1c1 Mon Sep 17 00:00:00 2001 From: Arshid Date: Mon, 1 Sep 2025 02:15:58 +0530 Subject: [PATCH 34/48] [Php85] Add ChrArgModuloRector (#7190) * Wrap chr() argument with % 256 to avoid deprecated out-of-range integers * Wrap chr() argument with % 256 to avoid deprecated out-of-range integers * Wrap chr() argument with % 256 to avoid deprecated out-of-range integers * Wrap chr() argument with % 256 to avoid deprecated out-of-range integers * Wrap chr() argument with % 256 to avoid deprecated out-of-range integers * Wrap chr() argument with % 256 to avoid deprecated out-of-range integers * Wrap chr() argument with % 256 to avoid deprecated out-of-range integers * Wrap chr() argument with % 256 to avoid deprecated out-of-range integers * Wrap chr() argument with % 256 to avoid deprecated out-of-range integers * Wrap chr() argument with % 256 to avoid deprecated out-of-range integers * Wrap chr() argument with % 256 to avoid deprecated out-of-range integers --------- Co-authored-by: Arshid --- config/set/php85.php | 2 + .../ChrArgModuloRectorTest.php | 28 ++++++ .../ChrArgModuloRector/Fixture/chr.php.inc | 11 +++ .../Fixture/chr_var.php.inc | 13 +++ .../Fixture/skip_chr_inbond.php.inc | 5 + .../config/configured_rule.php | 13 +++ .../Rector/FuncCall/ChrArgModuloRector.php | 97 +++++++++++++++++++ src/ValueObject/PhpVersionFeature.php | 6 ++ 8 files changed, 175 insertions(+) create mode 100644 rules-tests/Php85/Rector/FuncCall/ChrArgModuloRector/ChrArgModuloRectorTest.php create mode 100644 rules-tests/Php85/Rector/FuncCall/ChrArgModuloRector/Fixture/chr.php.inc create mode 100644 rules-tests/Php85/Rector/FuncCall/ChrArgModuloRector/Fixture/chr_var.php.inc create mode 100644 rules-tests/Php85/Rector/FuncCall/ChrArgModuloRector/Fixture/skip_chr_inbond.php.inc create mode 100644 rules-tests/Php85/Rector/FuncCall/ChrArgModuloRector/config/configured_rule.php create mode 100644 rules/Php85/Rector/FuncCall/ChrArgModuloRector.php diff --git a/config/set/php85.php b/config/set/php85.php index 074c18b2af9..be4cad3a560 100644 --- a/config/set/php85.php +++ b/config/set/php85.php @@ -11,6 +11,7 @@ use Rector\Php85\Rector\ClassMethod\NullDebugInfoReturnRector; use Rector\Php85\Rector\Const_\DeprecatedAnnotationToDeprecatedAttributeRector; use Rector\Php85\Rector\FuncCall\ArrayKeyExistsNullToEmptyStringRector; +use Rector\Php85\Rector\FuncCall\ChrArgModuloRector; use Rector\Php85\Rector\FuncCall\RemoveFinfoBufferContextArgRector; use Rector\Php85\Rector\Switch_\ColonAfterSwitchCaseRector; use Rector\Removing\Rector\FuncCall\RemoveFuncCallArgRector; @@ -34,6 +35,7 @@ DeprecatedAnnotationToDeprecatedAttributeRector::class, ColonAfterSwitchCaseRector::class, ArrayKeyExistsNullToEmptyStringRector::class, + ChrArgModuloRector::class, ] ); diff --git a/rules-tests/Php85/Rector/FuncCall/ChrArgModuloRector/ChrArgModuloRectorTest.php b/rules-tests/Php85/Rector/FuncCall/ChrArgModuloRector/ChrArgModuloRectorTest.php new file mode 100644 index 00000000000..093a907ccf2 --- /dev/null +++ b/rules-tests/Php85/Rector/FuncCall/ChrArgModuloRector/ChrArgModuloRectorTest.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/rules-tests/Php85/Rector/FuncCall/ChrArgModuloRector/Fixture/chr.php.inc b/rules-tests/Php85/Rector/FuncCall/ChrArgModuloRector/Fixture/chr.php.inc new file mode 100644 index 00000000000..320ac129c3a --- /dev/null +++ b/rules-tests/Php85/Rector/FuncCall/ChrArgModuloRector/Fixture/chr.php.inc @@ -0,0 +1,11 @@ + +----- + \ No newline at end of file diff --git a/rules-tests/Php85/Rector/FuncCall/ChrArgModuloRector/Fixture/chr_var.php.inc b/rules-tests/Php85/Rector/FuncCall/ChrArgModuloRector/Fixture/chr_var.php.inc new file mode 100644 index 00000000000..2e9bae1ede9 --- /dev/null +++ b/rules-tests/Php85/Rector/FuncCall/ChrArgModuloRector/Fixture/chr_var.php.inc @@ -0,0 +1,13 @@ + +----- + \ No newline at end of file diff --git a/rules-tests/Php85/Rector/FuncCall/ChrArgModuloRector/Fixture/skip_chr_inbond.php.inc b/rules-tests/Php85/Rector/FuncCall/ChrArgModuloRector/Fixture/skip_chr_inbond.php.inc new file mode 100644 index 00000000000..c303cdffff7 --- /dev/null +++ b/rules-tests/Php85/Rector/FuncCall/ChrArgModuloRector/Fixture/skip_chr_inbond.php.inc @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/rules-tests/Php85/Rector/FuncCall/ChrArgModuloRector/config/configured_rule.php b/rules-tests/Php85/Rector/FuncCall/ChrArgModuloRector/config/configured_rule.php new file mode 100644 index 00000000000..15d2a0b412f --- /dev/null +++ b/rules-tests/Php85/Rector/FuncCall/ChrArgModuloRector/config/configured_rule.php @@ -0,0 +1,13 @@ +rule(ChrArgModuloRector::class); + + $rectorConfig->phpVersion(PhpVersion::PHP_85); +}; diff --git a/rules/Php85/Rector/FuncCall/ChrArgModuloRector.php b/rules/Php85/Rector/FuncCall/ChrArgModuloRector.php new file mode 100644 index 00000000000..8a36f3085c7 --- /dev/null +++ b/rules/Php85/Rector/FuncCall/ChrArgModuloRector.php @@ -0,0 +1,97 @@ +isFirstClassCallable()) { + return null; + } + + if (! $this->isName($node, 'chr')) { + return null; + } + + $args = $node->getArgs(); + + if (! isset($node->args[0])) { + return null; + } + + $argExpr = $args[0]->value; + + if ($argExpr instanceof Mod) { + return null; + } + + $value = $this->valueResolver->getValue($argExpr); + if (! is_int($value)) { + return null; + } + + if ( $value >= 0 && $value <= 255) { + return null; + } + + $args[0]->value = new Mod($argExpr, new LNumber(256)); + $node->args = $args; + + return $node; + } + + public function provideMinPhpVersion(): int + { + return PhpVersionFeature::DEPRECATE_OUTSIDE_INTERVEL_VAL_IN_CHR_FUNCTION; + } +} diff --git a/src/ValueObject/PhpVersionFeature.php b/src/ValueObject/PhpVersionFeature.php index e292c50a21d..4d89ca5fd42 100644 --- a/src/ValueObject/PhpVersionFeature.php +++ b/src/ValueObject/PhpVersionFeature.php @@ -803,4 +803,10 @@ final class PhpVersionFeature * @var int */ public const DEPRECATE_NULL_ARG_IN_ARRAY_KEY_EXISTS_FUNCTION = PhpVersion::PHP_85; + + /** + * @see https://wiki.php.net/rfc/deprecations_php_8_5#eprecate_passing_integers_outside_the_interval_0_255_to_chr + * @var int + */ + public const DEPRECATE_OUTSIDE_INTERVEL_VAL_IN_CHR_FUNCTION = PhpVersion::PHP_85; } From 04240664c6f3dd9304d5d07ba7291dbc7c305b38 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Mon, 1 Sep 2025 18:31:15 +0700 Subject: [PATCH 35/48] Remove removed "Rector\Symfony\Set\FOSRestSetList/JMSSetList/SensiolabsSetList" usage (#7204) * Remove removed "Rector\Symfony\Set\FOSRestSetList" usage * SetList more removal --- src/Configuration/RectorConfigBuilder.php | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/Configuration/RectorConfigBuilder.php b/src/Configuration/RectorConfigBuilder.php index 588aec729d7..fde4bec627d 100644 --- a/src/Configuration/RectorConfigBuilder.php +++ b/src/Configuration/RectorConfigBuilder.php @@ -31,9 +31,6 @@ use Rector\Set\SetManager; use Rector\Set\ValueObject\DowngradeLevelSetList; use Rector\Set\ValueObject\SetList; -use Rector\Symfony\Set\FOSRestSetList; -use Rector\Symfony\Set\JMSSetList; -use Rector\Symfony\Set\SensiolabsSetList; use Rector\Symfony\Set\SymfonySetList; use Rector\ValueObject\Configuration\LevelOverflow; use Rector\ValueObject\PhpVersion; @@ -510,18 +507,6 @@ public function withAttributesSets( $this->sets[] = PHPUnitSetList::ANNOTATIONS_TO_ATTRIBUTES; } - if ($fosRest || $all) { - $this->sets[] = FOSRestSetList::ANNOTATIONS_TO_ATTRIBUTES; - } - - if ($jms || $all) { - $this->sets[] = JMSSetList::ANNOTATIONS_TO_ATTRIBUTES; - } - - if ($sensiolabs || $all) { - $this->sets[] = SensiolabsSetList::ANNOTATIONS_TO_ATTRIBUTES; - } - if ($behat || $all) { $this->sets[] = SetList::BEHAT_ANNOTATIONS_TO_ATTRIBUTES; } From 5dcdd8f940ee3cb45a9ef98ef649ed4a963ee8a1 Mon Sep 17 00:00:00 2001 From: Arshid Date: Mon, 1 Sep 2025 17:12:34 +0530 Subject: [PATCH 36/48] [php 8.3] Add json_validate rule --- .../JsonValidateRector/Fixture/json_validate_yoda.php.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda.php.inc index da31c299838..6f29ea59a90 100644 --- a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda.php.inc +++ b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda.php.inc @@ -3,7 +3,7 @@ namespace Rector\Tests\Php83\Rector\BooleanAnd\JsonValidateRector\Fixture; if (null !== json_decode($json) && JSON_ERROR_NONE === json_last_error()){ - echo 1; + echo 2; } ?> ----- @@ -12,6 +12,6 @@ if (null !== json_decode($json) && JSON_ERROR_NONE === json_last_error()){ namespace Rector\Tests\Php83\Rector\BooleanAnd\JsonValidateRector\Fixture; if (json_validate($json)){ - echo 1; + echo 2; } ?> \ No newline at end of file From 125908876974b159cd8e96fb18a95a64ccd24569 Mon Sep 17 00:00:00 2001 From: Arshid Date: Mon, 1 Sep 2025 19:13:10 +0530 Subject: [PATCH 37/48] [php 8.3] Add json_validate rule --- .../Fixture/Json_validate_reverse.php.inc | 15 ----- .../Rector/BooleanAnd/JsonValidateRector.php | 61 ++++++++++--------- 2 files changed, 31 insertions(+), 45 deletions(-) delete mode 100644 rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate_reverse.php.inc diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate_reverse.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate_reverse.php.inc deleted file mode 100644 index e591b6c68b5..00000000000 --- a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate_reverse.php.inc +++ /dev/null @@ -1,15 +0,0 @@ - ------ - diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index 7bcd1f8c718..f21b5bcd7b4 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -94,58 +94,59 @@ public function providePolyfillPackage(): string public function matchJsonValidateArg(BooleanAnd $booleanAnd): ?FuncCall { - $decodeMatch = null; - $errorMatch = null; - // match: json_decode(...) !== null OR null !== json_decode(...) - if ($booleanAnd->left instanceof NotIdentical) { - $decodeMatch = $this->decodeMatch($booleanAnd->left); + if (!($booleanAnd->left instanceof NotIdentical)) { + return null; } - if ($booleanAnd->right instanceof NotIdentical) { - $decodeMatch = $this->decodeMatch($booleanAnd->right); - } + $decodeMatch = $this->binaryOpManipulator->matchFirstAndSecondConditionNode( + $booleanAnd->left, + fn($node) => $node instanceof FuncCall && $this->isName($node->name, 'json_decode'), + fn($node) => $node instanceof ConstFetch && $this->isName($node->name, 'null') + ); if (! $decodeMatch instanceof TwoNodeMatch) { return null; } // match: json_last_error() === JSON_ERROR_NONE OR JSON_ERROR_NONE === json_last_error() - if ($booleanAnd->right instanceof Identical) { - $errorMatch = $this->errorMatch($booleanAnd->right); - } - if ($booleanAnd->left instanceof Identical) { - $errorMatch = $this->errorMatch($booleanAnd->left); + if (!($booleanAnd->right instanceof Identical)) { + return null; } + $errorMatch = $this->binaryOpManipulator->matchFirstAndSecondConditionNode( + $booleanAnd->right, + fn($node) => $node instanceof FuncCall && $this->isName($node->name, 'json_last_error'), + fn($node) => $node instanceof ConstFetch && $this->isName($node->name, 'JSON_ERROR_NONE') + ); + if (! $errorMatch instanceof TwoNodeMatch) { return null; } // always return the json_decode(...) call $funcCall = $decodeMatch->getFirstExpr(); - if (! $funcCall instanceof FuncCall) { + if(!$funcCall instanceof FuncCall){ return null; } - return $funcCall; } - protected function decodeMatch(NotIdentical $notIdentical): ?TwoNodeMatch + protected function getJsonNode(NotIdentical $notIdentical): ?FuncCall { - return $this->binaryOpManipulator->matchFirstAndSecondConditionNode( - $notIdentical, - fn ($node) => $node instanceof FuncCall && $this->isName($node->name, 'json_decode'), - fn ($node) => $node instanceof ConstFetch && $this->isName($node->name, 'null') - ); - } - protected function errorMatch(Identical $identical): ?TwoNodeMatch - { - return $this->binaryOpManipulator->matchFirstAndSecondConditionNode( - $identical, - fn ($node) => $node instanceof FuncCall && $this->isName($node->name, 'json_last_error'), - fn ($node) => $node instanceof ConstFetch && $this->isName($node->name, 'JSON_ERROR_NONE') - ); + if ($notIdentical->left instanceof FuncCall + && $this->isName($notIdentical->left->name, 'json_decode') + ) { + return $notIdentical->left; + } + + if ($notIdentical->right instanceof FuncCall + && $this->isName($notIdentical->right->name, 'json_decode') + ) { + return $notIdentical->right; + } + + return null; } -} +} \ No newline at end of file From 2ef3815da0d21c8900d943fe49b0d11de0bf1874 Mon Sep 17 00:00:00 2001 From: Arshid Date: Tue, 2 Sep 2025 11:15:40 +0530 Subject: [PATCH 38/48] [php 8.3] Add json_validate rule --- .../Fixture/json_validate.php.inc | 17 +++++++++++++++++ .../Fixture/json_validate_named.php.inc | 15 +++++++++++++++ .../Fixture/json_validate_named_base.php.inc | 15 +++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate.php.inc create mode 100644 rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named.php.inc create mode 100644 rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named_base.php.inc diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate.php.inc new file mode 100644 index 00000000000..c5a679544a1 --- /dev/null +++ b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate.php.inc @@ -0,0 +1,17 @@ + +----- + \ No newline at end of file diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named.php.inc new file mode 100644 index 00000000000..7d9e3cda76e --- /dev/null +++ b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named.php.inc @@ -0,0 +1,15 @@ + +----- + diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named_base.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named_base.php.inc new file mode 100644 index 00000000000..dd40a1364a7 --- /dev/null +++ b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named_base.php.inc @@ -0,0 +1,15 @@ + +----- + From c5a036e630183267934c4edafc9d37828f101c81 Mon Sep 17 00:00:00 2001 From: Arshid Date: Tue, 2 Sep 2025 11:46:42 +0530 Subject: [PATCH 39/48] [php 8.3] Add json_validate rule --- .../Fixture/json_validate.php.inc | 17 ----------------- ...lidate.php.inc => json_validate.php.inc.php} | 0 .../Fixture/json_validate_named.php.inc | 15 --------------- ....php.inc => json_validate_named.php.inc.php} | 0 .../Fixture/json_validate_named_base.php.inc | 15 --------------- ...inc => json_validate_named_base.php.inc.php} | 0 ...a.php.inc => json_validate_yoda.php.inc.php} | 0 ....inc => json_validate_yoda_base.php.inc.php} | 0 8 files changed, 47 deletions(-) delete mode 100644 rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate.php.inc rename rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/{Json_validate.php.inc => json_validate.php.inc.php} (100%) delete mode 100644 rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named.php.inc rename rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/{Json_validate_named.php.inc => json_validate_named.php.inc.php} (100%) delete mode 100644 rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named_base.php.inc rename rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/{Json_validate_named_base.php.inc => json_validate_named_base.php.inc.php} (100%) rename rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/{json_validate_yoda.php.inc => json_validate_yoda.php.inc.php} (100%) rename rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/{json_validate_yoda_base.php.inc => json_validate_yoda_base.php.inc.php} (100%) diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate.php.inc deleted file mode 100644 index c5a679544a1..00000000000 --- a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate.php.inc +++ /dev/null @@ -1,17 +0,0 @@ - ------ - \ No newline at end of file diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate.php.inc.php similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate.php.inc rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate.php.inc.php diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named.php.inc deleted file mode 100644 index 7d9e3cda76e..00000000000 --- a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named.php.inc +++ /dev/null @@ -1,15 +0,0 @@ - ------ - diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate_named.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named.php.inc.php similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate_named.php.inc rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named.php.inc.php diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named_base.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named_base.php.inc deleted file mode 100644 index dd40a1364a7..00000000000 --- a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named_base.php.inc +++ /dev/null @@ -1,15 +0,0 @@ - ------ - diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate_named_base.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named_base.php.inc.php similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/Json_validate_named_base.php.inc rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named_base.php.inc.php diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda.php.inc.php similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda.php.inc rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda.php.inc.php diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda_base.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda_base.php.inc.php similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda_base.php.inc rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda_base.php.inc.php From 216124c054e2262c494ac0e0ddfa660d0f56deb7 Mon Sep 17 00:00:00 2001 From: Arshid Date: Tue, 2 Sep 2025 11:47:10 +0530 Subject: [PATCH 40/48] [php 8.3] Add json_validate rule --- .../Fixture/{json_validate.php.inc.php => json_validate.php.inc} | 0 ...son_validate_named.php.inc.php => json_validate_named.php.inc} | 0 ...te_named_base.php.inc.php => json_validate_named_base.php.inc} | 0 ...{json_validate_yoda.php.inc.php => json_validate_yoda.php.inc} | 0 ...date_yoda_base.php.inc.php => json_validate_yoda_base.php.inc} | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/{json_validate.php.inc.php => json_validate.php.inc} (100%) rename rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/{json_validate_named.php.inc.php => json_validate_named.php.inc} (100%) rename rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/{json_validate_named_base.php.inc.php => json_validate_named_base.php.inc} (100%) rename rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/{json_validate_yoda.php.inc.php => json_validate_yoda.php.inc} (100%) rename rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/{json_validate_yoda_base.php.inc.php => json_validate_yoda_base.php.inc} (100%) diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate.php.inc.php b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate.php.inc similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate.php.inc.php rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate.php.inc diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named.php.inc.php b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named.php.inc similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named.php.inc.php rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named.php.inc diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named_base.php.inc.php b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named_base.php.inc similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named_base.php.inc.php rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_named_base.php.inc diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda.php.inc.php b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda.php.inc similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda.php.inc.php rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda.php.inc diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda_base.php.inc.php b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda_base.php.inc similarity index 100% rename from rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda_base.php.inc.php rename to rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_yoda_base.php.inc From 04e2ac3f57d6728ac071d997f2e2d1e0ad67e6b9 Mon Sep 17 00:00:00 2001 From: Arshid Date: Wed, 3 Sep 2025 15:40:27 +0530 Subject: [PATCH 41/48] [php 8.3] Add json_validate rule --- src/ValueObject/PhpVersionFeature.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ValueObject/PhpVersionFeature.php b/src/ValueObject/PhpVersionFeature.php index 4d89ca5fd42..826fdc2de44 100644 --- a/src/ValueObject/PhpVersionFeature.php +++ b/src/ValueObject/PhpVersionFeature.php @@ -704,6 +704,7 @@ final class PhpVersionFeature /** * @var int + * @see https://wiki.php.net/rfc/json_validate */ public const JSON_VALIDATE = PhpVersion::PHP_83; From bfc6cc178a15fe298fc7378df7c46570a91badfa Mon Sep 17 00:00:00 2001 From: Arshid Date: Wed, 3 Sep 2025 16:25:05 +0530 Subject: [PATCH 42/48] [php 8.3] Add json_validate rule --- .../Rector/BooleanAnd/JsonValidateRector.php | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index f21b5bcd7b4..fa9666edcab 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -81,12 +81,31 @@ public function refactor(Node $node): ?Node } $args = $funcCall->getArgs(); + + if(!$this->validateFlag($args)){ + return null; + } + $funcCall->name = new Name('json_validate'); $funcCall->args = $args; return $funcCall; } + protected function validateFlag(array $args){ + if (0 !== $flags && \defined('JSON_INVALID_UTF8_IGNORE') && \JSON_INVALID_UTF8_IGNORE !== $flags) { + throw new \ValueError('json_validate(): Argument #3 ($flags) must be a valid flag (allowed flags: JSON_INVALID_UTF8_IGNORE)'); + } + + if ($depth <= 0) { + throw new \ValueError('json_validate(): Argument #2 ($depth) must be greater than 0'); + } + + if ($depth > self::JSON_MAX_DEPTH) { + throw new \ValueError(sprintf('json_validate(): Argument #2 ($depth) must be less than %d', self::JSON_MAX_DEPTH)); + } + } + public function providePolyfillPackage(): string { return PolyfillPackage::PHP_83; @@ -132,21 +151,4 @@ public function matchJsonValidateArg(BooleanAnd $booleanAnd): ?FuncCall return $funcCall; } - protected function getJsonNode(NotIdentical $notIdentical): ?FuncCall - { - - if ($notIdentical->left instanceof FuncCall - && $this->isName($notIdentical->left->name, 'json_decode') - ) { - return $notIdentical->left; - } - - if ($notIdentical->right instanceof FuncCall - && $this->isName($notIdentical->right->name, 'json_decode') - ) { - return $notIdentical->right; - } - - return null; - } } \ No newline at end of file From f9ad1596504b3d1eadb2bc3025ce90aeedc74771 Mon Sep 17 00:00:00 2001 From: Arshid Date: Wed, 3 Sep 2025 21:29:46 +0530 Subject: [PATCH 43/48] [php 8.3] Add json_validate rule --- ...p_json_validate_invalid_depth.php copy.inc | 8 + .../skip_json_validate_invalid_flag.php.inc | 8 + .../Rector/BooleanAnd/JsonValidateRector.php | 138 +++++++++++++++--- 3 files changed, 130 insertions(+), 24 deletions(-) create mode 100644 rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/skip_json_validate_invalid_depth.php copy.inc create mode 100644 rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/skip_json_validate_invalid_flag.php.inc diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/skip_json_validate_invalid_depth.php copy.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/skip_json_validate_invalid_depth.php copy.inc new file mode 100644 index 00000000000..6e7e9a9f274 --- /dev/null +++ b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/skip_json_validate_invalid_depth.php copy.inc @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/skip_json_validate_invalid_flag.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/skip_json_validate_invalid_flag.php.inc new file mode 100644 index 00000000000..8359236e996 --- /dev/null +++ b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/skip_json_validate_invalid_flag.php.inc @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index fa9666edcab..ef356ed51e2 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -5,15 +5,24 @@ namespace Rector\Php83\Rector\BooleanAnd; use PhpParser\Node; +use PhpParser\Node\Arg; use PhpParser\Node\Expr\BinaryOp\BooleanAnd; use PhpParser\Node\Expr\BinaryOp\Identical; use PhpParser\Node\Expr\BinaryOp\NotIdentical; use PhpParser\Node\Expr\ConstFetch; use PhpParser\Node\Expr\FuncCall; +use PhpParser\Node\Identifier; use PhpParser\Node\Name; +use PHPStan\Analyser\Scope; +use PHPStan\Reflection\Native\NativeFunctionReflection; +use Rector\NodeAnalyzer\ArgsAnalyzer; use Rector\NodeManipulator\BinaryOpManipulator; +use Rector\NodeTypeResolver\Node\AttributeKey; +use Rector\NodeTypeResolver\PHPStan\ParametersAcceptorSelectorVariantsWrapper; use Rector\Php71\ValueObject\TwoNodeMatch; +use Rector\PhpParser\Node\Value\ValueResolver; use Rector\Rector\AbstractRector; +use Rector\Reflection\ReflectionResolver; use Rector\ValueObject\PhpVersionFeature; use Rector\ValueObject\PolyfillPackage; use Rector\VersionBonding\Contract\MinPhpVersionInterface; @@ -26,8 +35,15 @@ */ final class JsonValidateRector extends AbstractRector implements MinPhpVersionInterface, RelatedPolyfillInterface { + protected const ARG_NAMES = ['json', 'associative', 'depth', 'flags']; + + private const JSON_MAX_DEPTH = 0x7FFFFFFF; + public function __construct( - private readonly BinaryOpManipulator $binaryOpManipulator + private readonly BinaryOpManipulator $binaryOpManipulator, + private readonly ReflectionResolver $reflectionResolver, + private readonly ArgsAnalyzer $argsAnalyzer, + private ValueResolver $valueResolver, ) { } @@ -80,32 +96,29 @@ public function refactor(Node $node): ?Node return null; } + $scope = $node->getAttribute(AttributeKey::SCOPE); + if (! $scope instanceof Scope) { + return null; + } + $args = $funcCall->getArgs(); + $positions = $this->argsAnalyzer->hasNamedArg($args) + ? $this->resolveNamedPositions($args) + : $this->resolveOriginalPositions($funcCall, $scope); - if(!$this->validateFlag($args)){ + if ($positions === []) { return null; } + if (! $this->validateArgs($args, $positions)) { + return null; + } $funcCall->name = new Name('json_validate'); $funcCall->args = $args; return $funcCall; } - protected function validateFlag(array $args){ - if (0 !== $flags && \defined('JSON_INVALID_UTF8_IGNORE') && \JSON_INVALID_UTF8_IGNORE !== $flags) { - throw new \ValueError('json_validate(): Argument #3 ($flags) must be a valid flag (allowed flags: JSON_INVALID_UTF8_IGNORE)'); - } - - if ($depth <= 0) { - throw new \ValueError('json_validate(): Argument #2 ($depth) must be greater than 0'); - } - - if ($depth > self::JSON_MAX_DEPTH) { - throw new \ValueError(sprintf('json_validate(): Argument #2 ($depth) must be less than %d', self::JSON_MAX_DEPTH)); - } - } - public function providePolyfillPackage(): string { return PolyfillPackage::PHP_83; @@ -114,14 +127,14 @@ public function providePolyfillPackage(): string public function matchJsonValidateArg(BooleanAnd $booleanAnd): ?FuncCall { // match: json_decode(...) !== null OR null !== json_decode(...) - if (!($booleanAnd->left instanceof NotIdentical)) { + if (! ($booleanAnd->left instanceof NotIdentical)) { return null; } $decodeMatch = $this->binaryOpManipulator->matchFirstAndSecondConditionNode( $booleanAnd->left, - fn($node) => $node instanceof FuncCall && $this->isName($node->name, 'json_decode'), - fn($node) => $node instanceof ConstFetch && $this->isName($node->name, 'null') + fn ($node) => $node instanceof FuncCall && $this->isName($node->name, 'json_decode'), + fn ($node) => $node instanceof ConstFetch && $this->isName($node->name, 'null') ); if (! $decodeMatch instanceof TwoNodeMatch) { @@ -129,14 +142,14 @@ public function matchJsonValidateArg(BooleanAnd $booleanAnd): ?FuncCall } // match: json_last_error() === JSON_ERROR_NONE OR JSON_ERROR_NONE === json_last_error() - if (!($booleanAnd->right instanceof Identical)) { + if (! ($booleanAnd->right instanceof Identical)) { return null; } $errorMatch = $this->binaryOpManipulator->matchFirstAndSecondConditionNode( $booleanAnd->right, - fn($node) => $node instanceof FuncCall && $this->isName($node->name, 'json_last_error'), - fn($node) => $node instanceof ConstFetch && $this->isName($node->name, 'JSON_ERROR_NONE') + fn ($node) => $node instanceof FuncCall && $this->isName($node->name, 'json_last_error'), + fn ($node) => $node instanceof ConstFetch && $this->isName($node->name, 'JSON_ERROR_NONE') ); if (! $errorMatch instanceof TwoNodeMatch) { @@ -145,10 +158,87 @@ public function matchJsonValidateArg(BooleanAnd $booleanAnd): ?FuncCall // always return the json_decode(...) call $funcCall = $decodeMatch->getFirstExpr(); - if(!$funcCall instanceof FuncCall){ + if (! $funcCall instanceof FuncCall) { return null; } return $funcCall; } -} \ No newline at end of file + /** + * @param Arg[] $args + * @param int[]|string[] $positions + */ + protected function validateArgs(array $args, array $positions): bool + { + foreach ($positions as $position) { + $arg = $args[$position] ?? ''; + if ($arg instanceof Arg && $arg->name instanceof Identifier && $arg->name->toString() === 'flags') { + $flags = $this->valueResolver->getValue($arg); + if ($flags !== JSON_INVALID_UTF8_IGNORE) { + return false; + } + } + if ($arg instanceof Arg && $arg->name instanceof Identifier && $arg->name->toString() === 'depth') { + $depth = $this->valueResolver->getValue($arg); + if ($depth <= 0) { + return false; + } + if ($depth > static::JSON_MAX_DEPTH) { + return false; + } + } + } + + return true; + } + + /** + * @param Arg[] $args + * @return int[]|string[] + */ + private function resolveNamedPositions(array $args): array + { + $positions = []; + + foreach ($args as $position => $arg) { + if (! $arg->name instanceof Identifier) { + continue; + } + + if (! $this->isNames($arg->name, static::ARG_NAMES)) { + continue; + } + + $positions[] = $position; + } + + return $positions; + } + + /** + * @return int[]|string[] + */ + private function resolveOriginalPositions(FuncCall $funcCall, Scope $scope): array + { + $functionReflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($funcCall); + if (! $functionReflection instanceof NativeFunctionReflection) { + return []; + } + + $parametersAcceptor = ParametersAcceptorSelectorVariantsWrapper::select( + $functionReflection, + $funcCall, + $scope + ); + + $positions = []; + + foreach ($parametersAcceptor->getParameters() as $position => $parameterReflection) { + if (in_array($parameterReflection->getName(), static::ARG_NAMES, true)) { + $positions[] = $position; + } + } + + return $positions; + } +} From 77c8a6eab66c6e6eb6bebc4558254afd93399573 Mon Sep 17 00:00:00 2001 From: Arshid Date: Wed, 3 Sep 2025 21:35:11 +0530 Subject: [PATCH 44/48] [php 8.3] Add json_validate rule --- rules/Php83/Rector/BooleanAnd/JsonValidateRector.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index ef356ed51e2..7a8a81e4b79 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -183,7 +183,7 @@ protected function validateArgs(array $args, array $positions): bool if ($depth <= 0) { return false; } - if ($depth > static::JSON_MAX_DEPTH) { + if ($depth > self::JSON_MAX_DEPTH) { return false; } } @@ -205,7 +205,7 @@ private function resolveNamedPositions(array $args): array continue; } - if (! $this->isNames($arg->name, static::ARG_NAMES)) { + if (! $this->isNames($arg->name, self::ARG_NAMES)) { continue; } @@ -234,7 +234,7 @@ private function resolveOriginalPositions(FuncCall $funcCall, Scope $scope): arr $positions = []; foreach ($parametersAcceptor->getParameters() as $position => $parameterReflection) { - if (in_array($parameterReflection->getName(), static::ARG_NAMES, true)) { + if (in_array($parameterReflection->getName(), self::ARG_NAMES, true)) { $positions[] = $position; } } From 22de00068a30d066128758f80d2a5c8eca00a756 Mon Sep 17 00:00:00 2001 From: Arshid Date: Wed, 3 Sep 2025 22:20:34 +0530 Subject: [PATCH 45/48] [php 8.3] Add json_validate rule --- .../Fixture/json_validate_base.php.inc | 4 +- .../Rector/BooleanAnd/JsonValidateRector.php | 94 +++---------------- tests/bootstrap.php | 6 +- 3 files changed, 21 insertions(+), 83 deletions(-) diff --git a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_base.php.inc b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_base.php.inc index 002e3c80f8e..13201b3bf84 100644 --- a/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_base.php.inc +++ b/rules-tests/Php83/Rector/BooleanAnd/JsonValidateRector/Fixture/json_validate_base.php.inc @@ -2,7 +2,7 @@ namespace Rector\Tests\Php83\Rector\BooleanAnd\JsonValidateRector\Fixture; -if (json_decode($json) !== null && json_last_error() === JSON_ERROR_NONE){ +if (json_decode($json, true, 512) !== null && json_last_error() === JSON_ERROR_NONE){ echo 1; } ?> @@ -11,7 +11,7 @@ if (json_decode($json) !== null && json_last_error() === JSON_ERROR_NONE){ namespace Rector\Tests\Php83\Rector\BooleanAnd\JsonValidateRector\Fixture; -if (json_validate($json)){ +if (json_validate($json, true, 512)){ echo 1; } ?> \ No newline at end of file diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index 7a8a81e4b79..2395c921fc4 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -11,18 +11,13 @@ use PhpParser\Node\Expr\BinaryOp\NotIdentical; use PhpParser\Node\Expr\ConstFetch; use PhpParser\Node\Expr\FuncCall; -use PhpParser\Node\Identifier; use PhpParser\Node\Name; use PHPStan\Analyser\Scope; -use PHPStan\Reflection\Native\NativeFunctionReflection; -use Rector\NodeAnalyzer\ArgsAnalyzer; use Rector\NodeManipulator\BinaryOpManipulator; use Rector\NodeTypeResolver\Node\AttributeKey; -use Rector\NodeTypeResolver\PHPStan\ParametersAcceptorSelectorVariantsWrapper; use Rector\Php71\ValueObject\TwoNodeMatch; use Rector\PhpParser\Node\Value\ValueResolver; use Rector\Rector\AbstractRector; -use Rector\Reflection\ReflectionResolver; use Rector\ValueObject\PhpVersionFeature; use Rector\ValueObject\PolyfillPackage; use Rector\VersionBonding\Contract\MinPhpVersionInterface; @@ -41,8 +36,6 @@ final class JsonValidateRector extends AbstractRector implements MinPhpVersionIn public function __construct( private readonly BinaryOpManipulator $binaryOpManipulator, - private readonly ReflectionResolver $reflectionResolver, - private readonly ArgsAnalyzer $argsAnalyzer, private ValueResolver $valueResolver, ) { } @@ -102,15 +95,12 @@ public function refactor(Node $node): ?Node } $args = $funcCall->getArgs(); - $positions = $this->argsAnalyzer->hasNamedArg($args) - ? $this->resolveNamedPositions($args) - : $this->resolveOriginalPositions($funcCall, $scope); - if ($positions === []) { + if ($args === []) { return null; } - if (! $this->validateArgs($args, $positions)) { + if (! $this->validateArgs($funcCall)) { return null; } $funcCall->name = new Name('json_validate'); @@ -164,81 +154,25 @@ public function matchJsonValidateArg(BooleanAnd $booleanAnd): ?FuncCall return $funcCall; } - /** - * @param Arg[] $args - * @param int[]|string[] $positions - */ - protected function validateArgs(array $args, array $positions): bool + protected function validateArgs(FuncCall $funcCall): bool { - foreach ($positions as $position) { - $arg = $args[$position] ?? ''; - if ($arg instanceof Arg && $arg->name instanceof Identifier && $arg->name->toString() === 'flags') { - $flags = $this->valueResolver->getValue($arg); - if ($flags !== JSON_INVALID_UTF8_IGNORE) { - return false; - } - } - if ($arg instanceof Arg && $arg->name instanceof Identifier && $arg->name->toString() === 'depth') { - $depth = $this->valueResolver->getValue($arg); - if ($depth <= 0) { - return false; - } - if ($depth > self::JSON_MAX_DEPTH) { - return false; - } - } - } - - return true; - } - - /** - * @param Arg[] $args - * @return int[]|string[] - */ - private function resolveNamedPositions(array $args): array - { - $positions = []; - - foreach ($args as $position => $arg) { - if (! $arg->name instanceof Identifier) { - continue; - } + $depth = $funcCall->getArg('depth', 2); + $flags = $funcCall->getArg('flags', 3); - if (! $this->isNames($arg->name, self::ARG_NAMES)) { - continue; + if ($flags instanceof Arg) { + $flagsValue = $this->valueResolver->getValue($flags); + if ($flagsValue !== JSON_INVALID_UTF8_IGNORE) { + return false; } - - $positions[] = $position; } - return $positions; - } - - /** - * @return int[]|string[] - */ - private function resolveOriginalPositions(FuncCall $funcCall, Scope $scope): array - { - $functionReflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($funcCall); - if (! $functionReflection instanceof NativeFunctionReflection) { - return []; - } - - $parametersAcceptor = ParametersAcceptorSelectorVariantsWrapper::select( - $functionReflection, - $funcCall, - $scope - ); - - $positions = []; - - foreach ($parametersAcceptor->getParameters() as $position => $parameterReflection) { - if (in_array($parameterReflection->getName(), self::ARG_NAMES, true)) { - $positions[] = $position; + if ($depth instanceof Arg) { + $depthValue = $this->valueResolver->getValue($depth); + if ($depthValue <= 0 || $depthValue > self::JSON_MAX_DEPTH) { + return false; } } - return $positions; + return true; } } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 800fd015f78..3efa8c47d2d 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -7,7 +7,11 @@ require_once __DIR__ . '/../vendor/autoload.php'; // silent deprecations, since we test them -error_reporting(E_ALL ^ E_DEPRECATED); +// error_reporting(E_ALL ^ E_DEPRECATED); +error_reporting(E_ALL); +set_error_handler(function (int $severity, string $message, string $file, int $line): bool { + throw new \ErrorException($message, 0, $severity, $file, $line); +}); // performance boost gc_disable(); From d55c5c4e163108433a59a348d52e5904361554f1 Mon Sep 17 00:00:00 2001 From: Arshid Date: Wed, 3 Sep 2025 22:30:42 +0530 Subject: [PATCH 46/48] [php 8.3] Add json_validate rule --- phpunit.xml | 1 + .../Fixture/skip_complex_assign.php | 13 +++++++++++++ .../Php83/Rector/BooleanAnd/JsonValidateRector.php | 9 +-------- tests/bootstrap.php | 6 +----- 4 files changed, 16 insertions(+), 13 deletions(-) create mode 100644 rules-tests/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector/Fixture/skip_complex_assign.php diff --git a/phpunit.xml b/phpunit.xml index 8607c5b0eb2..9aaa4f6b337 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -6,6 +6,7 @@ colors="true" executionOrder="defects" defaultTestSuite="main" + stopOnError="true" displayDetailsOnTestsThatTriggerWarnings="true" displayDetailsOnPhpunitDeprecations="true" > diff --git a/rules-tests/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector/Fixture/skip_complex_assign.php b/rules-tests/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector/Fixture/skip_complex_assign.php new file mode 100644 index 00000000000..1cf85e7444f --- /dev/null +++ b/rules-tests/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector/Fixture/skip_complex_assign.php @@ -0,0 +1,13 @@ +name = $name; + } +} diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index 2395c921fc4..eea87297052 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -12,9 +12,7 @@ use PhpParser\Node\Expr\ConstFetch; use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Name; -use PHPStan\Analyser\Scope; use Rector\NodeManipulator\BinaryOpManipulator; -use Rector\NodeTypeResolver\Node\AttributeKey; use Rector\Php71\ValueObject\TwoNodeMatch; use Rector\PhpParser\Node\Value\ValueResolver; use Rector\Rector\AbstractRector; @@ -89,14 +87,9 @@ public function refactor(Node $node): ?Node return null; } - $scope = $node->getAttribute(AttributeKey::SCOPE); - if (! $scope instanceof Scope) { - return null; - } - $args = $funcCall->getArgs(); - if ($args === []) { + if (count($args) < 1 ){ return null; } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 3efa8c47d2d..800fd015f78 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -7,11 +7,7 @@ require_once __DIR__ . '/../vendor/autoload.php'; // silent deprecations, since we test them -// error_reporting(E_ALL ^ E_DEPRECATED); -error_reporting(E_ALL); -set_error_handler(function (int $severity, string $message, string $file, int $line): bool { - throw new \ErrorException($message, 0, $severity, $file, $line); -}); +error_reporting(E_ALL ^ E_DEPRECATED); // performance boost gc_disable(); From 5340f456ba5bea8bea25d1578678796e7d2378a9 Mon Sep 17 00:00:00 2001 From: Arshid Date: Wed, 3 Sep 2025 23:01:19 +0530 Subject: [PATCH 47/48] [php 8.3] Add json_validate rule --- .../Rector/BooleanAnd/JsonValidateRector.php | 103 +++++++++++++++--- 1 file changed, 88 insertions(+), 15 deletions(-) diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index eea87297052..1a53f4acf4a 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -11,11 +11,18 @@ use PhpParser\Node\Expr\BinaryOp\NotIdentical; use PhpParser\Node\Expr\ConstFetch; use PhpParser\Node\Expr\FuncCall; +use PhpParser\Node\Identifier; use PhpParser\Node\Name; +use PHPStan\Analyser\Scope; +use PHPStan\Reflection\Native\NativeFunctionReflection; +use Rector\NodeAnalyzer\ArgsAnalyzer; use Rector\NodeManipulator\BinaryOpManipulator; +use Rector\NodeTypeResolver\Node\AttributeKey; +use Rector\NodeTypeResolver\PHPStan\ParametersAcceptorSelectorVariantsWrapper; use Rector\Php71\ValueObject\TwoNodeMatch; use Rector\PhpParser\Node\Value\ValueResolver; use Rector\Rector\AbstractRector; +use Rector\Reflection\ReflectionResolver; use Rector\ValueObject\PhpVersionFeature; use Rector\ValueObject\PolyfillPackage; use Rector\VersionBonding\Contract\MinPhpVersionInterface; @@ -34,6 +41,8 @@ final class JsonValidateRector extends AbstractRector implements MinPhpVersionIn public function __construct( private readonly BinaryOpManipulator $binaryOpManipulator, + private readonly ReflectionResolver $reflectionResolver, + private readonly ArgsAnalyzer $argsAnalyzer, private ValueResolver $valueResolver, ) { } @@ -87,13 +96,21 @@ public function refactor(Node $node): ?Node return null; } + $scope = $node->getAttribute(AttributeKey::SCOPE); + if (! $scope instanceof Scope) { + return null; + } + $args = $funcCall->getArgs(); + $positions = $this->argsAnalyzer->hasNamedArg($args) + ? $this->resolveNamedPositions($args) + : $this->resolveOriginalPositions($funcCall, $scope); - if (count($args) < 1 ){ + if ($positions === []) { return null; } - if (! $this->validateArgs($funcCall)) { + if (! $this->validateArgs($args, $positions)) { return null; } $funcCall->name = new Name('json_validate'); @@ -147,25 +164,81 @@ public function matchJsonValidateArg(BooleanAnd $booleanAnd): ?FuncCall return $funcCall; } - protected function validateArgs(FuncCall $funcCall): bool + /** + * @param Arg[] $args + * @param int[]|string[] $positions + */ + protected function validateArgs(array $args, array $positions): bool + { + foreach ($positions as $position) { + $arg = $args[$position] ?? ''; + if ($arg instanceof Arg && $arg->name instanceof Identifier && $arg->name->toString() === 'flags') { + $flags = $this->valueResolver->getValue($arg); + if ($flags !== JSON_INVALID_UTF8_IGNORE) { + return false; + } + } + if ($arg instanceof Arg && $arg->name instanceof Identifier && $arg->name->toString() === 'depth') { + $depth = $this->valueResolver->getValue($arg); + if ($depth <= 0) { + return false; + } + if ($depth > self::JSON_MAX_DEPTH) { + return false; + } + } + } + + return true; + } + + /** + * @param Arg[] $args + * @return int[]|string[] + */ + private function resolveNamedPositions(array $args): array { - $depth = $funcCall->getArg('depth', 2); - $flags = $funcCall->getArg('flags', 3); + $positions = []; - if ($flags instanceof Arg) { - $flagsValue = $this->valueResolver->getValue($flags); - if ($flagsValue !== JSON_INVALID_UTF8_IGNORE) { - return false; + foreach ($args as $position => $arg) { + if (! $arg->name instanceof Identifier) { + continue; } + + if (! $this->isNames($arg->name, self::ARG_NAMES)) { + continue; + } + + $positions[] = $position; } - if ($depth instanceof Arg) { - $depthValue = $this->valueResolver->getValue($depth); - if ($depthValue <= 0 || $depthValue > self::JSON_MAX_DEPTH) { - return false; + return $positions; + } + + /** + * @return int[]|string[] + */ + private function resolveOriginalPositions(FuncCall $funcCall, Scope $scope): array + { + $functionReflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($funcCall); + if (! $functionReflection instanceof NativeFunctionReflection) { + return []; + } + + $parametersAcceptor = ParametersAcceptorSelectorVariantsWrapper::select( + $functionReflection, + $funcCall, + $scope + ); + + $positions = []; + + foreach ($parametersAcceptor->getParameters() as $position => $parameterReflection) { + if (in_array($parameterReflection->getName(), self::ARG_NAMES, true)) { + $positions[] = $position; } } - return true; + return $positions; } -} +} \ No newline at end of file From a6f77c0e4ef9ece3f7a6da7fbb4d5e0684d1d472 Mon Sep 17 00:00:00 2001 From: Arshid Date: Wed, 3 Sep 2025 23:02:31 +0530 Subject: [PATCH 48/48] [php 8.3] Add json_validate rule --- .../Rector/BooleanAnd/JsonValidateRector.php | 101 +++--------------- 1 file changed, 14 insertions(+), 87 deletions(-) diff --git a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php index 1a53f4acf4a..c9841c136c3 100644 --- a/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php +++ b/rules/Php83/Rector/BooleanAnd/JsonValidateRector.php @@ -11,18 +11,11 @@ use PhpParser\Node\Expr\BinaryOp\NotIdentical; use PhpParser\Node\Expr\ConstFetch; use PhpParser\Node\Expr\FuncCall; -use PhpParser\Node\Identifier; use PhpParser\Node\Name; -use PHPStan\Analyser\Scope; -use PHPStan\Reflection\Native\NativeFunctionReflection; -use Rector\NodeAnalyzer\ArgsAnalyzer; use Rector\NodeManipulator\BinaryOpManipulator; -use Rector\NodeTypeResolver\Node\AttributeKey; -use Rector\NodeTypeResolver\PHPStan\ParametersAcceptorSelectorVariantsWrapper; use Rector\Php71\ValueObject\TwoNodeMatch; use Rector\PhpParser\Node\Value\ValueResolver; use Rector\Rector\AbstractRector; -use Rector\Reflection\ReflectionResolver; use Rector\ValueObject\PhpVersionFeature; use Rector\ValueObject\PolyfillPackage; use Rector\VersionBonding\Contract\MinPhpVersionInterface; @@ -41,8 +34,6 @@ final class JsonValidateRector extends AbstractRector implements MinPhpVersionIn public function __construct( private readonly BinaryOpManipulator $binaryOpManipulator, - private readonly ReflectionResolver $reflectionResolver, - private readonly ArgsAnalyzer $argsAnalyzer, private ValueResolver $valueResolver, ) { } @@ -96,21 +87,13 @@ public function refactor(Node $node): ?Node return null; } - $scope = $node->getAttribute(AttributeKey::SCOPE); - if (! $scope instanceof Scope) { - return null; - } - $args = $funcCall->getArgs(); - $positions = $this->argsAnalyzer->hasNamedArg($args) - ? $this->resolveNamedPositions($args) - : $this->resolveOriginalPositions($funcCall, $scope); - if ($positions === []) { + if (count($args) < 1 ){ return null; } - if (! $this->validateArgs($args, $positions)) { + if (! $this->validateArgs($funcCall)) { return null; } $funcCall->name = new Name('json_validate'); @@ -164,81 +147,25 @@ public function matchJsonValidateArg(BooleanAnd $booleanAnd): ?FuncCall return $funcCall; } - /** - * @param Arg[] $args - * @param int[]|string[] $positions - */ - protected function validateArgs(array $args, array $positions): bool - { - foreach ($positions as $position) { - $arg = $args[$position] ?? ''; - if ($arg instanceof Arg && $arg->name instanceof Identifier && $arg->name->toString() === 'flags') { - $flags = $this->valueResolver->getValue($arg); - if ($flags !== JSON_INVALID_UTF8_IGNORE) { - return false; - } - } - if ($arg instanceof Arg && $arg->name instanceof Identifier && $arg->name->toString() === 'depth') { - $depth = $this->valueResolver->getValue($arg); - if ($depth <= 0) { - return false; - } - if ($depth > self::JSON_MAX_DEPTH) { - return false; - } - } - } - - return true; - } - - /** - * @param Arg[] $args - * @return int[]|string[] - */ - private function resolveNamedPositions(array $args): array + protected function validateArgs(FuncCall $funcCall): bool { - $positions = []; + $depth = $funcCall->getArg('depth', 2); + $flags = $funcCall->getArg('flags', 3); - foreach ($args as $position => $arg) { - if (! $arg->name instanceof Identifier) { - continue; + if ($flags instanceof Arg) { + $flagsValue = $this->valueResolver->getValue($flags); + if ($flagsValue !== JSON_INVALID_UTF8_IGNORE) { + return false; } - - if (! $this->isNames($arg->name, self::ARG_NAMES)) { - continue; - } - - $positions[] = $position; - } - - return $positions; - } - - /** - * @return int[]|string[] - */ - private function resolveOriginalPositions(FuncCall $funcCall, Scope $scope): array - { - $functionReflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($funcCall); - if (! $functionReflection instanceof NativeFunctionReflection) { - return []; } - $parametersAcceptor = ParametersAcceptorSelectorVariantsWrapper::select( - $functionReflection, - $funcCall, - $scope - ); - - $positions = []; - - foreach ($parametersAcceptor->getParameters() as $position => $parameterReflection) { - if (in_array($parameterReflection->getName(), self::ARG_NAMES, true)) { - $positions[] = $position; + if ($depth instanceof Arg) { + $depthValue = $this->valueResolver->getValue($depth); + if ($depthValue <= 0 || $depthValue > self::JSON_MAX_DEPTH) { + return false; } } - return $positions; + return true; } } \ No newline at end of file