From 18390f1f8d6d8580189f7efab111adf385bd79dc Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 15 Mar 2025 14:10:48 +0100 Subject: [PATCH] Various cleanups --- .github/expected-missing-return-types.diff | 17 --- UPGRADE-7.3.md | 116 +++++++++--------- .../Cache/Tests/Traits/RedisProxiesTest.php | 7 +- .../DependencyInjection/ServicesResetter.php | 4 + .../CacheWarmer/LazyGhostCacheWarmer.php | 2 + .../CacheWarmer/LazyGhostCacheWarmerTest.php | 3 + .../Tests/PropertyAccessorTest.php | 26 ++-- .../VarExporter/Tests/ProxyHelperTest.php | 4 +- 8 files changed, 87 insertions(+), 92 deletions(-) diff --git a/.github/expected-missing-return-types.diff b/.github/expected-missing-return-types.diff index 30ac60ab98ad7..20ae4c8f3e17e 100644 --- a/.github/expected-missing-return-types.diff +++ b/.github/expected-missing-return-types.diff @@ -593,23 +593,6 @@ diff --git a/src/Symfony/Component/VarDumper/Dumper/DataDumperInterface.php b/sr - public function dump(Data $data); + public function dump(Data $data): ?string; } -diff --git a/src/Symfony/Component/VarExporter/Tests/ProxyHelperTest.php b/src/Symfony/Component/VarExporter/Tests/ProxyHelperTest.php ---- a/src/Symfony/Component/VarExporter/Tests/ProxyHelperTest.php -+++ b/src/Symfony/Component/VarExporter/Tests/ProxyHelperTest.php -@@ -172,5 +172,5 @@ class ProxyHelperTest extends TestCase - { - yield 'not type hinted __unserialize method' => [new class { -- public function __unserialize($array) -+ public function __unserialize($array): void - { - } -@@ -192,5 +192,5 @@ class ProxyHelperTest extends TestCase - - yield 'type hinted __unserialize method' => [new class { -- public function __unserialize(array $array) -+ public function __unserialize(array $array): void - { - } diff --git a/src/Symfony/Contracts/Translation/LocaleAwareInterface.php b/src/Symfony/Contracts/Translation/LocaleAwareInterface.php --- a/src/Symfony/Contracts/Translation/LocaleAwareInterface.php +++ b/src/Symfony/Contracts/Translation/LocaleAwareInterface.php diff --git a/UPGRADE-7.3.md b/UPGRADE-7.3.md index fced14c227469..e30440e089f1a 100644 --- a/UPGRADE-7.3.md +++ b/UPGRADE-7.3.md @@ -8,59 +8,10 @@ Read more about this in the [Symfony documentation](https://symfony.com/doc/7.3/ If you're upgrading from a version below 7.2, follow the [7.2 upgrade guide](UPGRADE-7.2.md) first. -Ldap ----- - - * Deprecate `LdapUser::eraseCredentials()` in favor of `__serialize()` - -Security --------- - - * Deprecate `UserInterface::eraseCredentials()` and `TokenInterface::eraseCredentials()`; - erase credentials e.g. using `__serialize()` instead - - Before: - - ```php - public function eraseCredentials(): void - { - } - ``` - - After: - - ```php - #[\Deprecated] - public function eraseCredentials(): void - { - } - - // If your eraseCredentials() method was used to empty a "password" property: - public function __serialize(): array - { - $data = (array) $this; - unset($data["\0".self::class."\0password"]); - - return $data; - } - ``` - - * Add argument `$vote` to `VoterInterface::vote()` and to `Voter::voteOnAttribute()`; - it should be used to report the reason of a vote. E.g: - - ```php - protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token, ?Vote $vote = null): bool - { - $vote ??= new Vote(); - - $vote->reasons[] = 'A brief explanation of why access is granted or denied, as appropriate.'; - } - ``` - - * Add argument `$accessDecision` to `AccessDecisionManagerInterface::decide()` and `AuthorizationCheckerInterface::isGranted()`; - it should be used to report the reason of a decision, including all the related votes. +AssetMapper +----------- - * Add discovery support to `OidcTokenHandler` and `OidcUserInfoTokenHandler` + * `ImportMapRequireCommand` now takes `projectDir` as a required third constructor argument Console ------- @@ -96,10 +47,15 @@ FrameworkBundle * Deprecate the `--show-arguments` option of the `container:debug` command, as arguments are now always shown * Deprecate the `framework.validation.cache` config option +Ldap +---- + + * Deprecate `LdapUser::eraseCredentials()` in favor of `__serialize()` + OptionsResolver --------------- -* Deprecate defining nested options via `setDefault()`, use `setOptions()` instead + * Deprecate defining nested options via `setDefault()`, use `setOptions()` instead *Before* ```php @@ -115,6 +71,55 @@ OptionsResolver }); ``` +Security +-------- + + * Deprecate `UserInterface::eraseCredentials()` and `TokenInterface::eraseCredentials()`; + erase credentials e.g. using `__serialize()` instead + + Before: + + ```php + public function eraseCredentials(): void + { + } + ``` + + After: + + ```php + #[\Deprecated] + public function eraseCredentials(): void + { + } + + // If your eraseCredentials() method was used to empty a "password" property: + public function __serialize(): array + { + $data = (array) $this; + unset($data["\0".self::class."\0password"]); + + return $data; + } + ``` + + * Add argument `$vote` to `VoterInterface::vote()` and to `Voter::voteOnAttribute()`; + it should be used to report the reason of a vote. E.g: + + ```php + protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token, ?Vote $vote = null): bool + { + $vote ??= new Vote(); + + $vote->reasons[] = 'A brief explanation of why access is granted or denied, as appropriate.'; + } + ``` + + * Add argument `$accessDecision` to `AccessDecisionManagerInterface::decide()` and `AuthorizationCheckerInterface::isGranted()`; + it should be used to report the reason of a decision, including all the related votes. + + * Add discovery support to `OidcTokenHandler` and `OidcUserInfoTokenHandler` + SecurityBundle -------------- @@ -191,8 +196,3 @@ VarDumper * Deprecate `ResourceCaster::castCurl()`, `ResourceCaster::castGd()` and `ResourceCaster::castOpensslX509()` * Mark all casters as `@internal` - -AssetMapper ------------ - - * `ImportMapRequireCommand` now takes `projectDir` as a required third constructor argument diff --git a/src/Symfony/Component/Cache/Tests/Traits/RedisProxiesTest.php b/src/Symfony/Component/Cache/Tests/Traits/RedisProxiesTest.php index 051275d649e61..50f784da162be 100644 --- a/src/Symfony/Component/Cache/Tests/Traits/RedisProxiesTest.php +++ b/src/Symfony/Component/Cache/Tests/Traits/RedisProxiesTest.php @@ -17,7 +17,6 @@ use Symfony\Component\Cache\Traits\RedisProxyTrait; use Symfony\Component\Cache\Traits\RelayClusterProxy; use Symfony\Component\Cache\Traits\RelayProxy; -use Symfony\Component\VarExporter\LazyProxyTrait; use Symfony\Component\VarExporter\ProxyHelper; class RedisProxiesTest extends TestCase @@ -37,7 +36,7 @@ public function testRedisProxy($class) $methods = []; foreach ((new \ReflectionClass(\sprintf('Symfony\Component\Cache\Traits\\%s%dProxy', $class, $version)))->getMethods() as $method) { - if ('reset' === $method->name || method_exists(LazyProxyTrait::class, $method->name)) { + if ('reset' === $method->name || method_exists(RedisProxyTrait::class, $method->name)) { continue; } $return = '__construct' === $method->name || $method->getReturnType() instanceof \ReflectionNamedType && 'void' === (string) $method->getReturnType() ? '' : 'return '; @@ -89,7 +88,7 @@ public function testRelayProxy() $expectedMethods = []; foreach ((new \ReflectionClass(RelayProxy::class))->getMethods() as $method) { - if ('reset' === $method->name || method_exists(LazyProxyTrait::class, $method->name) || $method->isStatic()) { + if ('reset' === $method->name || method_exists(RedisProxyTrait::class, $method->name) || $method->isStatic()) { continue; } @@ -136,7 +135,7 @@ public function testRelayClusterProxy() $expectedMethods = []; foreach ((new \ReflectionClass(RelayClusterProxy::class))->getMethods() as $method) { - if ('reset' === $method->name || method_exists(LazyProxyTrait::class, $method->name) || $method->isStatic()) { + if ('reset' === $method->name || method_exists(RedisProxyTrait::class, $method->name) || $method->isStatic()) { continue; } diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/ServicesResetter.php b/src/Symfony/Component/HttpKernel/DependencyInjection/ServicesResetter.php index 7636e52a18239..c2a19d992f08a 100644 --- a/src/Symfony/Component/HttpKernel/DependencyInjection/ServicesResetter.php +++ b/src/Symfony/Component/HttpKernel/DependencyInjection/ServicesResetter.php @@ -46,6 +46,10 @@ public function reset(): void continue; } + if (\PHP_VERSION_ID >= 80400 && (new \ReflectionClass($service))->isUninitializedLazyObject($service)) { + continue; + } + foreach ((array) $this->resetMethods[$id] as $resetMethod) { if ('?' === $resetMethod[0] && !method_exists($service, $resetMethod = substr($resetMethod, 1))) { continue; diff --git a/src/Symfony/Component/JsonStreamer/CacheWarmer/LazyGhostCacheWarmer.php b/src/Symfony/Component/JsonStreamer/CacheWarmer/LazyGhostCacheWarmer.php index 99b651d26d9e2..9160496142968 100644 --- a/src/Symfony/Component/JsonStreamer/CacheWarmer/LazyGhostCacheWarmer.php +++ b/src/Symfony/Component/JsonStreamer/CacheWarmer/LazyGhostCacheWarmer.php @@ -22,6 +22,8 @@ * * @author Mathias Arlaud * + * @deprecated since Symfony 7.3, native lazy objects will be used instead + * * @internal */ final class LazyGhostCacheWarmer extends CacheWarmer diff --git a/src/Symfony/Component/JsonStreamer/Tests/CacheWarmer/LazyGhostCacheWarmerTest.php b/src/Symfony/Component/JsonStreamer/Tests/CacheWarmer/LazyGhostCacheWarmerTest.php index 86f2f9d4964f7..fb10cc1c90d66 100644 --- a/src/Symfony/Component/JsonStreamer/Tests/CacheWarmer/LazyGhostCacheWarmerTest.php +++ b/src/Symfony/Component/JsonStreamer/Tests/CacheWarmer/LazyGhostCacheWarmerTest.php @@ -15,6 +15,9 @@ use Symfony\Component\JsonStreamer\CacheWarmer\LazyGhostCacheWarmer; use Symfony\Component\JsonStreamer\Tests\Fixtures\Model\ClassicDummy; +/** + * @group legacy + */ class LazyGhostCacheWarmerTest extends TestCase { private string $lazyGhostsDir; diff --git a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php index f96d6aff7e36c..b9aa911cfaf3f 100644 --- a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php +++ b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php @@ -1032,21 +1032,25 @@ public function testIsReadableWithMissingPropertyAndLazyGhost() private function createUninitializedObjectPropertyGhost(): UninitializedObjectProperty { - if (!class_exists(ProxyHelper::class)) { - $this->markTestSkipped(\sprintf('Class "%s" is required to run this test.', ProxyHelper::class)); - } + if (\PHP_VERSION_ID < 80400) { + if (!class_exists(ProxyHelper::class)) { + $this->markTestSkipped(\sprintf('Class "%s" is required to run this test.', ProxyHelper::class)); + } - $class = 'UninitializedObjectPropertyGhost'; + $class = 'UninitializedObjectPropertyGhost'; - if (!class_exists($class)) { - eval('class '.$class.ProxyHelper::generateLazyGhost(new \ReflectionClass(UninitializedObjectProperty::class))); - } + if (!class_exists($class)) { + eval('class '.$class.ProxyHelper::generateLazyGhost(new \ReflectionClass(UninitializedObjectProperty::class))); + } - $this->assertTrue(class_exists($class)); + $this->assertTrue(class_exists($class)); - return $class::createLazyGhost(initializer: function ($instance) { - }); - } + return $class::createLazyGhost(initializer: function ($instance) { + }); + } + + return (new \ReflectionClass(UninitializedObjectProperty::class))->newLazyGhost(fn () => null); +} /** * @requires PHP 8.4 diff --git a/src/Symfony/Component/VarExporter/Tests/ProxyHelperTest.php b/src/Symfony/Component/VarExporter/Tests/ProxyHelperTest.php index b9c67adf17437..8457e08f901ed 100644 --- a/src/Symfony/Component/VarExporter/Tests/ProxyHelperTest.php +++ b/src/Symfony/Component/VarExporter/Tests/ProxyHelperTest.php @@ -172,7 +172,7 @@ public function testGenerateLazyProxyForClassWithUnserializeMagicMethod(object $ public static function classWithUnserializeMagicMethodProvider(): iterable { yield 'not type hinted __unserialize method' => [new class { - public function __unserialize($array) + public function __unserialize($array): void { } }, <<<'EOPHP' @@ -192,7 +192,7 @@ public function __unserialize($data): void EOPHP]; yield 'type hinted __unserialize method' => [new class { - public function __unserialize(array $array) + public function __unserialize(array $array): void { } }, <<<'EOPHP'