diff --git a/config/set/php85.php b/config/set/php85.php index 19715d7a0c2..cee158fa245 100644 --- a/config/set/php85.php +++ b/config/set/php85.php @@ -9,6 +9,7 @@ use Rector\Config\RectorConfig; use Rector\Php85\Rector\ArrayDimFetch\ArrayFirstLastRector; use Rector\Php85\Rector\ClassMethod\NullDebugInfoReturnRector; +use Rector\Php85\Rector\Class_\SleepToSerializeRector; use Rector\Php85\Rector\Const_\DeprecatedAnnotationToDeprecatedAttributeRector; use Rector\Php85\Rector\FuncCall\ArrayKeyExistsNullToEmptyStringRector; use Rector\Php85\Rector\FuncCall\ChrArgModuloRector; @@ -38,6 +39,7 @@ ColonAfterSwitchCaseRector::class, ArrayKeyExistsNullToEmptyStringRector::class, ChrArgModuloRector::class, + SleepToSerializeRector::class, OrdSingleByteRector::class, ] ); diff --git a/rules-tests/Php85/Rector/Class_/SleepToSerializeRector/Fixture/skip_sleep_empty.php.inc b/rules-tests/Php85/Rector/Class_/SleepToSerializeRector/Fixture/skip_sleep_empty.php.inc new file mode 100644 index 00000000000..c0aba35565e --- /dev/null +++ b/rules-tests/Php85/Rector/Class_/SleepToSerializeRector/Fixture/skip_sleep_empty.php.inc @@ -0,0 +1,15 @@ + +?> diff --git a/rules-tests/Php85/Rector/Class_/SleepToSerializeRector/Fixture/skip_sleep_null.php.inc b/rules-tests/Php85/Rector/Class_/SleepToSerializeRector/Fixture/skip_sleep_null.php.inc new file mode 100644 index 00000000000..93efd11e174 --- /dev/null +++ b/rules-tests/Php85/Rector/Class_/SleepToSerializeRector/Fixture/skip_sleep_null.php.inc @@ -0,0 +1,14 @@ + diff --git a/rules-tests/Php85/Rector/Class_/SleepToSerializeRector/Fixture/sleep.php.inc b/rules-tests/Php85/Rector/Class_/SleepToSerializeRector/Fixture/sleep.php.inc new file mode 100644 index 00000000000..d41ff9bef18 --- /dev/null +++ b/rules-tests/Php85/Rector/Class_/SleepToSerializeRector/Fixture/sleep.php.inc @@ -0,0 +1,29 @@ + +----- + $this->id, 'name' => $this->name]; + } +} +?> diff --git a/rules-tests/Php85/Rector/Class_/SleepToSerializeRector/SleepToSerializeRectorTest.php b/rules-tests/Php85/Rector/Class_/SleepToSerializeRector/SleepToSerializeRectorTest.php new file mode 100644 index 00000000000..5234b35a750 --- /dev/null +++ b/rules-tests/Php85/Rector/Class_/SleepToSerializeRector/SleepToSerializeRectorTest.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/Class_/SleepToSerializeRector/config/configured_rule.php b/rules-tests/Php85/Rector/Class_/SleepToSerializeRector/config/configured_rule.php new file mode 100644 index 00000000000..56ac5753670 --- /dev/null +++ b/rules-tests/Php85/Rector/Class_/SleepToSerializeRector/config/configured_rule.php @@ -0,0 +1,10 @@ +rule(SleepToSerializeRector::class); +}; diff --git a/rules/Php85/Rector/Class_/SleepToSerializeRector.php b/rules/Php85/Rector/Class_/SleepToSerializeRector.php new file mode 100644 index 00000000000..a389d570d96 --- /dev/null +++ b/rules/Php85/Rector/Class_/SleepToSerializeRector.php @@ -0,0 +1,139 @@ + $this->id, + 'name' => $this->name, + ]; + } +} +CODE_SAMPLE + ), + ] + ); + } + + /** + * @return array> + */ + public function getNodeTypes(): array + { + return [Class_::class]; + } + + /** + * @param Class_ $node + */ + public function refactor(Node $node): ?Node + { + if ($node->getMethod('__serialize') instanceof ClassMethod) { + return null; + } + + $classMethod = $node->getMethod('__sleep'); + if (! $classMethod instanceof ClassMethod) { + return null; + } + + if ($classMethod->returnType instanceof Identifier && $this->isName($classMethod->returnType, 'array')) { + return null; + } + + $returns = $this->betterNodeFinder->findReturnsScoped($classMethod); + if (! $this->returnAnalyzer->hasOnlyReturnWithExpr($classMethod, $returns)) { + return null; + } + + $hasChanged = false; + foreach ($returns as $return) { + if (! $return->expr instanceof Array_) { + return null; + } + + if (count($return->expr->items) > 0) { + $newItems = []; + foreach ($return->expr->items as $item) { + if ($item !== null && $item->value instanceof Node\Scalar\String_) { + $propName = $item->value->value; + $newItems[] = new ArrayItem( + new PropertyFetch(new Node\Expr\Variable('this'), $propName), + $item->value + ); + } + } + if (count($newItems) > 0) { + $hasChanged = true; + $return->expr->items = $newItems; + } + } + } + + if ($hasChanged) { + $classMethod->name = new Identifier('__serialize'); + $classMethod->returnType = new Identifier('array'); + return $node; + } + + return null; + } +} diff --git a/src/ValueObject/PhpVersionFeature.php b/src/ValueObject/PhpVersionFeature.php index 9747fdb8345..78a946ee218 100644 --- a/src/ValueObject/PhpVersionFeature.php +++ b/src/ValueObject/PhpVersionFeature.php @@ -811,6 +811,12 @@ final class PhpVersionFeature */ public const DEPRECATE_OUTSIDE_INTERVEL_VAL_IN_CHR_FUNCTION = PhpVersion::PHP_85; + /** + * @see https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_the_sleep_and_wakeup_magic_methods + * @var int + */ + public const DEPRECATED_METHOD_SLEEP = 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