diff --git a/.github/expected-missing-return-types.diff b/.github/expected-missing-return-types.diff index 2545ad099f7a1..e0c0131a2631a 100644 --- a/.github/expected-missing-return-types.diff +++ b/.github/expected-missing-return-types.diff @@ -7,17 +7,6 @@ git checkout src/Symfony/Contracts/Service/ResetInterface.php (echo "$head" && echo && git diff -U2 src/) > .github/expected-missing-return-types.diff git checkout composer.json src/ -diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php -index 4b79ab7363..b72ff1d63b 100644 ---- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php -+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php -@@ -2902,5 +2902,5 @@ class FrameworkExtension extends Extension - * @return void - */ -- public static function registerRateLimiter(ContainerBuilder $container, string $name, array $limiterConfig) -+ public static function registerRateLimiter(ContainerBuilder $container, string $name, array $limiterConfig): void - { - trigger_deprecation('symfony/framework-bundle', '6.2', 'The "%s()" method is deprecated.', __METHOD__); diff --git a/src/Symfony/Component/Asset/Packages.php b/src/Symfony/Component/Asset/Packages.php index cffea43c49..0645fbd756 100644 --- a/src/Symfony/Component/Asset/Packages.php @@ -607,10 +596,10 @@ index bb40307e17..998fb85b27 100644 + public function setBuilder(NodeBuilder $builder): void; } diff --git a/src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php b/src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php -index 7cda0bc7d8..b2311826f4 100644 +index 49b73c8045..51b0719782 100644 --- a/src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php +++ b/src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php -@@ -111,5 +111,5 @@ class NodeBuilder implements NodeParentInterface +@@ -108,5 +108,5 @@ class NodeBuilder implements NodeParentInterface * @return NodeDefinition&ParentNodeDefinitionInterface */ - public function end() @@ -2935,7 +2924,7 @@ index 2d6542660b..20287f9286 100644 { $this->extensionConfig = []; diff --git a/src/Symfony/Component/DependencyInjection/Container.php b/src/Symfony/Component/DependencyInjection/Container.php -index 3ea2228b94..f1d7078383 100644 +index 2b9eeb84cc..29905ed51b 100644 --- a/src/Symfony/Component/DependencyInjection/Container.php +++ b/src/Symfony/Component/DependencyInjection/Container.php @@ -83,5 +83,5 @@ class Container implements ContainerInterface, ResetInterface @@ -3811,7 +3800,7 @@ index f1b982315c..ed8ad1fab4 100644 { } diff --git a/src/Symfony/Component/EventDispatcher/DependencyInjection/RegisterListenersPass.php b/src/Symfony/Component/EventDispatcher/DependencyInjection/RegisterListenersPass.php -index c86f438d41..3bfb39db57 100644 +index 47fa9ce841..67d01c3c5b 100644 --- a/src/Symfony/Component/EventDispatcher/DependencyInjection/RegisterListenersPass.php +++ b/src/Symfony/Component/EventDispatcher/DependencyInjection/RegisterListenersPass.php @@ -52,5 +52,5 @@ class RegisterListenersPass implements CompilerPassInterface @@ -4371,7 +4360,7 @@ index 422f28bf33..b1d608fd4d 100644 { } diff --git a/src/Symfony/Component/Form/ButtonBuilder.php b/src/Symfony/Component/Form/ButtonBuilder.php -index 20a30968d4..dbded1d7f3 100644 +index 2c8c12ce23..8c484d7275 100644 --- a/src/Symfony/Component/Form/ButtonBuilder.php +++ b/src/Symfony/Component/Form/ButtonBuilder.php @@ -57,5 +57,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface @@ -4447,151 +4436,151 @@ index 20a30968d4..dbded1d7f3 100644 @@ -221,5 +221,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface * @throws BadMethodCallException */ -- public function setDataMapper(DataMapperInterface $dataMapper = null): static -+ public function setDataMapper(DataMapperInterface $dataMapper = null): never +- public function setDataMapper(?DataMapperInterface $dataMapper): static ++ public function setDataMapper(?DataMapperInterface $dataMapper): never { - if (1 > \func_num_args()) { -@@ -249,5 +249,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface + throw new BadMethodCallException('Buttons do not support data mappers.'); +@@ -245,5 +245,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface * @throws BadMethodCallException */ - public function setEmptyData(mixed $emptyData): static + public function setEmptyData(mixed $emptyData): never { throw new BadMethodCallException('Buttons do not support empty data.'); -@@ -261,5 +261,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface +@@ -257,5 +257,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface * @throws BadMethodCallException */ - public function setErrorBubbling(bool $errorBubbling): static + public function setErrorBubbling(bool $errorBubbling): never { throw new BadMethodCallException('Buttons do not support error bubbling.'); -@@ -273,5 +273,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface +@@ -269,5 +269,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface * @throws BadMethodCallException */ - public function setRequired(bool $required): static + public function setRequired(bool $required): never { throw new BadMethodCallException('Buttons cannot be required.'); -@@ -285,5 +285,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface +@@ -281,5 +281,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface * @throws BadMethodCallException */ - public function setPropertyPath(string|PropertyPathInterface|null $propertyPath): static + public function setPropertyPath(string|PropertyPathInterface|null $propertyPath): never { throw new BadMethodCallException('Buttons do not support property paths.'); -@@ -297,5 +297,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface +@@ -293,5 +293,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface * @throws BadMethodCallException */ - public function setMapped(bool $mapped): static + public function setMapped(bool $mapped): never { throw new BadMethodCallException('Buttons do not support data mapping.'); -@@ -309,5 +309,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface +@@ -305,5 +305,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface * @throws BadMethodCallException */ - public function setByReference(bool $byReference): static + public function setByReference(bool $byReference): never { throw new BadMethodCallException('Buttons do not support data mapping.'); -@@ -321,5 +321,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface +@@ -317,5 +317,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface * @throws BadMethodCallException */ - public function setCompound(bool $compound): static + public function setCompound(bool $compound): never { throw new BadMethodCallException('Buttons cannot be compound.'); -@@ -345,5 +345,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface +@@ -341,5 +341,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface * @throws BadMethodCallException */ - public function setData(mixed $data): static + public function setData(mixed $data): never { throw new BadMethodCallException('Buttons do not support data.'); -@@ -357,5 +357,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface +@@ -353,5 +353,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface * @throws BadMethodCallException */ - public function setDataLocked(bool $locked): static + public function setDataLocked(bool $locked): never { throw new BadMethodCallException('Buttons do not support data locking.'); -@@ -369,5 +369,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface +@@ -365,5 +365,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface * @throws BadMethodCallException */ - public function setFormFactory(FormFactoryInterface $formFactory) + public function setFormFactory(FormFactoryInterface $formFactory): never { throw new BadMethodCallException('Buttons do not support form factories.'); -@@ -381,5 +381,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface +@@ -377,5 +377,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface * @throws BadMethodCallException */ - public function setAction(string $action): static + public function setAction(string $action): never { throw new BadMethodCallException('Buttons do not support actions.'); -@@ -393,5 +393,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface +@@ -389,5 +389,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface * @throws BadMethodCallException */ - public function setMethod(string $method): static + public function setMethod(string $method): never { throw new BadMethodCallException('Buttons do not support methods.'); -@@ -405,5 +405,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface +@@ -401,5 +401,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface * @throws BadMethodCallException */ - public function setRequestHandler(RequestHandlerInterface $requestHandler): static + public function setRequestHandler(RequestHandlerInterface $requestHandler): never { throw new BadMethodCallException('Buttons do not support request handlers.'); -@@ -433,5 +433,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface +@@ -429,5 +429,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface * @throws BadMethodCallException */ - public function setInheritData(bool $inheritData): static + public function setInheritData(bool $inheritData): never { throw new BadMethodCallException('Buttons do not support data inheritance.'); -@@ -457,5 +457,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface +@@ -453,5 +453,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface * @throws BadMethodCallException */ - public function setIsEmptyCallback(?callable $isEmptyCallback): static + public function setIsEmptyCallback(?callable $isEmptyCallback): never { throw new BadMethodCallException('Buttons do not support "is empty" callback.'); -@@ -469,5 +469,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface +@@ -465,5 +465,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface * @throws BadMethodCallException */ - public function getEventDispatcher(): EventDispatcherInterface + public function getEventDispatcher(): never { throw new BadMethodCallException('Buttons do not support event dispatching.'); -@@ -628,5 +628,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface +@@ -624,5 +624,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface * @return never */ - public function getFormFactory(): FormFactoryInterface + public function getFormFactory(): never { throw new BadMethodCallException('Buttons do not support adding children.'); -@@ -640,5 +640,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface +@@ -636,5 +636,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface * @throws BadMethodCallException */ - public function getAction(): string + public function getAction(): never { throw new BadMethodCallException('Buttons do not support actions.'); -@@ -652,5 +652,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface +@@ -648,5 +648,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface * @throws BadMethodCallException */ - public function getMethod(): string + public function getMethod(): never { throw new BadMethodCallException('Buttons do not support methods.'); -@@ -664,5 +664,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface +@@ -660,5 +660,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface * @throws BadMethodCallException */ - public function getRequestHandler(): RequestHandlerInterface + public function getRequestHandler(): never { throw new BadMethodCallException('Buttons do not support request handlers.'); -@@ -716,5 +716,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface +@@ -712,5 +712,5 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface * @throws BadMethodCallException */ - public function getIsEmptyCallback(): ?callable @@ -4955,7 +4944,7 @@ index 655ef6682f..0e525d09f6 100644 { $compound = static fn (Options $options) => 'single_text' !== $options['widget']; diff --git a/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php b/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php -index 9ec4c9cca4..28a33fb6d6 100644 +index 73ae5708c9..90815a20cf 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php @@ -53,5 +53,5 @@ class DateTimeType extends AbstractType @@ -4965,14 +4954,14 @@ index 9ec4c9cca4..28a33fb6d6 100644 + public function buildForm(FormBuilderInterface $builder, array $options): void { $parts = ['year', 'month', 'day', 'hour']; -@@ -217,5 +217,5 @@ class DateTimeType extends AbstractType +@@ -216,5 +216,5 @@ class DateTimeType extends AbstractType * @return void */ - public function buildView(FormView $view, FormInterface $form, array $options) + public function buildView(FormView $view, FormInterface $form, array $options): void { $view->vars['widget'] = $options['widget']; -@@ -245,5 +245,5 @@ class DateTimeType extends AbstractType +@@ -244,5 +244,5 @@ class DateTimeType extends AbstractType * @return void */ - public function configureOptions(OptionsResolver $resolver) @@ -4980,7 +4969,7 @@ index 9ec4c9cca4..28a33fb6d6 100644 { $compound = static fn (Options $options) => 'single_text' !== $options['widget']; diff --git a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php -index 480afc315f..e9f6364b07 100644 +index d204a914bd..7ae99cbfa6 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php @@ -49,5 +49,5 @@ class DateType extends AbstractType @@ -4990,14 +4979,14 @@ index 480afc315f..e9f6364b07 100644 + public function buildForm(FormBuilderInterface $builder, array $options): void { $dateFormat = \is_int($options['format']) ? $options['format'] : self::DEFAULT_FORMAT; -@@ -201,5 +201,5 @@ class DateType extends AbstractType +@@ -200,5 +200,5 @@ class DateType extends AbstractType * @return void */ - public function finishView(FormView $view, FormInterface $form, array $options) + public function finishView(FormView $view, FormInterface $form, array $options): void { $view->vars['widget'] = $options['widget']; -@@ -241,5 +241,5 @@ class DateType extends AbstractType +@@ -240,5 +240,5 @@ class DateType extends AbstractType * @return void */ - public function configureOptions(OptionsResolver $resolver) @@ -5347,7 +5336,7 @@ index 40e7580d80..18c58e30c0 100644 { $view->vars['pattern'] = null; diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php b/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php -index 623259f17a..1b7bd9a33f 100644 +index 7788290d7a..fff39fbc5d 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php @@ -38,5 +38,5 @@ class TimeType extends AbstractType @@ -5357,14 +5346,14 @@ index 623259f17a..1b7bd9a33f 100644 + public function buildForm(FormBuilderInterface $builder, array $options): void { $parts = ['hour']; -@@ -229,5 +229,5 @@ class TimeType extends AbstractType +@@ -228,5 +228,5 @@ class TimeType extends AbstractType * @return void */ - public function buildView(FormView $view, FormInterface $form, array $options) + public function buildView(FormView $view, FormInterface $form, array $options): void { $view->vars = array_replace($view->vars, [ -@@ -260,5 +260,5 @@ class TimeType extends AbstractType +@@ -259,5 +259,5 @@ class TimeType extends AbstractType * @return void */ - public function configureOptions(OptionsResolver $resolver) @@ -5822,10 +5811,10 @@ index ed363a7b15..967d95cc27 100644 { return $this->path->mapsForm($this->key()); diff --git a/src/Symfony/Component/Form/FormConfigBuilder.php b/src/Symfony/Component/Form/FormConfigBuilder.php -index 9fed3d1a0a..5cd4eb5f16 100644 +index 29e643680e..ef10087b80 100644 --- a/src/Symfony/Component/Form/FormConfigBuilder.php +++ b/src/Symfony/Component/Form/FormConfigBuilder.php -@@ -537,5 +537,5 @@ class FormConfigBuilder implements FormConfigBuilderInterface +@@ -534,5 +534,5 @@ class FormConfigBuilder implements FormConfigBuilderInterface * @return $this */ - public function setFormFactory(FormFactoryInterface $formFactory) @@ -6757,7 +6746,7 @@ index ebe4b748ad..059a6b5ac8 100644 { $this->name = $name; diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/MockArraySessionStorage.php b/src/Symfony/Component/HttpFoundation/Session/Storage/MockArraySessionStorage.php -index d30b56d691..0f002902bd 100644 +index 65f06c69e4..8f51fbbacd 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/MockArraySessionStorage.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/MockArraySessionStorage.php @@ -72,5 +72,5 @@ class MockArraySessionStorage implements SessionStorageInterface @@ -6805,11 +6794,11 @@ index d30b56d691..0f002902bd 100644 @@ -193,5 +193,5 @@ class MockArraySessionStorage implements SessionStorageInterface * @return void */ -- public function setMetadataBag(MetadataBag $bag = null) -+ public function setMetadataBag(MetadataBag $bag = null): void +- public function setMetadataBag(?MetadataBag $bag) ++ public function setMetadataBag(?MetadataBag $bag): void { - if (1 > \func_num_args()) { -@@ -223,5 +223,5 @@ class MockArraySessionStorage implements SessionStorageInterface + $this->metadataBag = $bag ?? new MetadataBag(); +@@ -220,5 +220,5 @@ class MockArraySessionStorage implements SessionStorageInterface * @return void */ - protected function loadSession() @@ -6828,7 +6817,7 @@ index 95f69f2e13..971b890f0f 100644 { if (!$this->started) { diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php -index 7c6b6f9296..0b63abb810 100644 +index e2e6f9f1f9..5c08f6f102 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php @@ -187,5 +187,5 @@ class NativeSessionStorage implements SessionStorageInterface @@ -6869,25 +6858,25 @@ index 7c6b6f9296..0b63abb810 100644 @@ -318,5 +318,5 @@ class NativeSessionStorage implements SessionStorageInterface * @return void */ -- public function setMetadataBag(MetadataBag $metaBag = null) -+ public function setMetadataBag(MetadataBag $metaBag = null): void +- public function setMetadataBag(?MetadataBag $metaBag) ++ public function setMetadataBag(?MetadataBag $metaBag): void { - if (1 > \func_num_args()) { -@@ -351,5 +351,5 @@ class NativeSessionStorage implements SessionStorageInterface + $this->metadataBag = $metaBag ?? new MetadataBag(); +@@ -348,5 +348,5 @@ class NativeSessionStorage implements SessionStorageInterface * @return void */ - public function setOptions(array $options) + public function setOptions(array $options): void { if (headers_sent() || \PHP_SESSION_ACTIVE === session_status()) { -@@ -397,5 +397,5 @@ class NativeSessionStorage implements SessionStorageInterface +@@ -394,5 +394,5 @@ class NativeSessionStorage implements SessionStorageInterface * @throws \InvalidArgumentException */ -- public function setSaveHandler(AbstractProxy|\SessionHandlerInterface $saveHandler = null) -+ public function setSaveHandler(AbstractProxy|\SessionHandlerInterface $saveHandler = null): void +- public function setSaveHandler(AbstractProxy|\SessionHandlerInterface|null $saveHandler) ++ public function setSaveHandler(AbstractProxy|\SessionHandlerInterface|null $saveHandler): void { - if (1 > \func_num_args()) { -@@ -430,5 +430,5 @@ class NativeSessionStorage implements SessionStorageInterface + // Wrap $saveHandler in proxy and prevent double wrapping of proxy +@@ -423,5 +423,5 @@ class NativeSessionStorage implements SessionStorageInterface * @return void */ - protected function loadSession(array &$session = null) @@ -7487,17 +7476,17 @@ index 47027233a7..2be5cfc7de 100644 { $this->fragmentPath = $path; diff --git a/src/Symfony/Component/HttpKernel/HttpCache/AbstractSurrogate.php b/src/Symfony/Component/HttpKernel/HttpCache/AbstractSurrogate.php -index 95518bed2b..2f7d5ee3b5 100644 +index e3f4d9552d..723e2c2f9c 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/AbstractSurrogate.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/AbstractSurrogate.php -@@ -63,5 +63,5 @@ abstract class AbstractSurrogate implements SurrogateInterface +@@ -55,5 +55,5 @@ abstract class AbstractSurrogate implements SurrogateInterface * @return void */ - public function addSurrogateCapability(Request $request) + public function addSurrogateCapability(Request $request): void { $current = $request->headers->get('Surrogate-Capability'); -@@ -112,5 +112,5 @@ abstract class AbstractSurrogate implements SurrogateInterface +@@ -104,5 +104,5 @@ abstract class AbstractSurrogate implements SurrogateInterface * @return void */ - protected function removeFromControl(Response $response) @@ -7516,31 +7505,31 @@ index 5db840a802..c16398a8ea 100644 { if (str_contains($response->getContent(), 'surrogate?->addSurrogateCapability($request); -@@ -600,5 +600,5 @@ class HttpCache implements HttpKernelInterface, TerminableInterface +@@ -592,5 +592,5 @@ class HttpCache implements HttpKernelInterface, TerminableInterface * @throws \Exception */ - protected function store(Request $request, Response $response) + protected function store(Request $request, Response $response): void { try { -@@ -678,5 +678,5 @@ class HttpCache implements HttpKernelInterface, TerminableInterface +@@ -670,5 +670,5 @@ class HttpCache implements HttpKernelInterface, TerminableInterface * @return void */ - protected function processResponseBody(Request $request, Response $response) @@ -7697,7 +7686,7 @@ index 0f3630e7fe..ddf77b8a19 100644 { return <<<'EOF' diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php -index 76205bc0b8..f4240cdd1b 100644 +index 563b663262..6118d09871 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -107,5 +107,5 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl @@ -8534,31 +8523,31 @@ index 88233655f9..abfb1fe7a6 100644 { $token = $this->getUniqueToken($key); diff --git a/src/Symfony/Component/Lock/Store/MongoDbStore.php b/src/Symfony/Component/Lock/Store/MongoDbStore.php -index ada843883c..afebb3f3d8 100644 +index 20ef3bc4ac..1417a5d84c 100644 --- a/src/Symfony/Component/Lock/Store/MongoDbStore.php +++ b/src/Symfony/Component/Lock/Store/MongoDbStore.php -@@ -194,5 +194,5 @@ class MongoDbStore implements PersistingStoreInterface +@@ -187,5 +187,5 @@ class MongoDbStore implements PersistingStoreInterface * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function createTtlIndex(int $expireAfterSeconds = 0) + public function createTtlIndex(int $expireAfterSeconds = 0): void { $this->getCollection()->createIndex( -@@ -211,5 +211,5 @@ class MongoDbStore implements PersistingStoreInterface +@@ -204,5 +204,5 @@ class MongoDbStore implements PersistingStoreInterface * @throws LockExpiredException when save is called on an expired lock */ - public function save(Key $key) + public function save(Key $key): void { $key->reduceLifetime($this->initialTtl); -@@ -237,5 +237,5 @@ class MongoDbStore implements PersistingStoreInterface +@@ -230,5 +230,5 @@ class MongoDbStore implements PersistingStoreInterface * @throws LockExpiredException */ - public function putOffExpiration(Key $key, float $ttl) + public function putOffExpiration(Key $key, float $ttl): void { $key->reduceLifetime($ttl); -@@ -256,5 +256,5 @@ class MongoDbStore implements PersistingStoreInterface +@@ -249,5 +249,5 @@ class MongoDbStore implements PersistingStoreInterface * @return void */ - public function delete(Key $key) @@ -8799,10 +8788,10 @@ index 3b6d6b8a39..98bc75ecd7 100644 { $this diff --git a/src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php b/src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php -index 86fa255015..08cbde055f 100644 +index f6f26d6946..5a98a6a0dc 100644 --- a/src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php +++ b/src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php -@@ -37,5 +37,5 @@ class MessengerPass implements CompilerPassInterface +@@ -34,5 +34,5 @@ class MessengerPass implements CompilerPassInterface * @return void */ - public function process(ContainerBuilder $container) @@ -8898,10 +8887,10 @@ index 70fa786331..f27afd0f01 100644 { if ($container->has('mime_types')) { diff --git a/src/Symfony/Component/Mime/Email.php b/src/Symfony/Component/Mime/Email.php -index 7f3496d1fc..be6a1eff61 100644 +index 67eea6c877..101d432675 100644 --- a/src/Symfony/Component/Mime/Email.php +++ b/src/Symfony/Component/Mime/Email.php -@@ -400,5 +400,5 @@ class Email extends Message +@@ -388,5 +388,5 @@ class Email extends Message * @return void */ - public function ensureValidity() @@ -8984,10 +8973,10 @@ index 61c06d8f50..883293f6e0 100644 { $this->value = $value; diff --git a/src/Symfony/Component/Mime/Message.php b/src/Symfony/Component/Mime/Message.php -index e636c2e8e5..4c0597d16f 100644 +index 6b78316606..91797a13d2 100644 --- a/src/Symfony/Component/Mime/Message.php +++ b/src/Symfony/Component/Mime/Message.php -@@ -129,5 +129,5 @@ class Message extends RawMessage +@@ -126,5 +126,5 @@ class Message extends RawMessage * @return void */ - public function ensureValidity() @@ -9196,7 +9185,7 @@ index 40dbd41620..ac31fdc922 100644 { if (self::STATUS_STARTED !== $this->status) { diff --git a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php -index 0bf5c0afa9..dc0f2eae19 100644 +index ac45dbe3b0..24bd3924f2 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php +++ b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php @@ -123,5 +123,5 @@ class PropertyAccessor implements PropertyAccessorInterface @@ -10340,16 +10329,6 @@ index c925e00050..95d5bd4321 100644 + public function setTranslator(?TranslatorInterface $translator): void { $this->translator = $translator; -diff --git a/src/Symfony/Component/Security/Http/EntryPoint/AuthenticationEntryPointInterface.php b/src/Symfony/Component/Security/Http/EntryPoint/AuthenticationEntryPointInterface.php -index 91271d14a3..100c2fb549 100644 ---- a/src/Symfony/Component/Security/Http/EntryPoint/AuthenticationEntryPointInterface.php -+++ b/src/Symfony/Component/Security/Http/EntryPoint/AuthenticationEntryPointInterface.php -@@ -43,4 +43,4 @@ interface AuthenticationEntryPointInterface - * @return Response - */ -- public function start(Request $request, AuthenticationException $authException = null); -+ public function start(Request $request, AuthenticationException $authException = null): Response; - } diff --git a/src/Symfony/Component/Security/Http/Event/LoginFailureEvent.php b/src/Symfony/Component/Security/Http/Event/LoginFailureEvent.php index 3b7c5086f2..97fb99f0b5 100644 --- a/src/Symfony/Component/Security/Http/Event/LoginFailureEvent.php @@ -10726,10 +10705,10 @@ index 7cb1164034..b3feecc078 100644 /** diff --git a/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php -index 3d11567a7b..22e873b151 100644 +index 7873f651a2..2778c8d3bf 100644 --- a/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php -@@ -131,5 +131,5 @@ class GetSetMethodNormalizer extends AbstractObjectNormalizer +@@ -129,5 +129,5 @@ final class GetSetMethodNormalizer extends AbstractObjectNormalizer * @return void */ - protected function setAttributeValue(object $object, string $attribute, mixed $value, string $format = null, array $context = []) @@ -10787,10 +10766,10 @@ index 533c07e6dd..66f30c7f93 100644 { try { diff --git a/src/Symfony/Component/Serializer/Normalizer/PropertyNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/PropertyNormalizer.php -index cfe93bc10b..7f1d8e5e13 100644 +index d4c5a97e89..c64626e1d6 100644 --- a/src/Symfony/Component/Serializer/Normalizer/PropertyNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/PropertyNormalizer.php -@@ -171,5 +171,5 @@ class PropertyNormalizer extends AbstractObjectNormalizer +@@ -169,5 +169,5 @@ final class PropertyNormalizer extends AbstractObjectNormalizer * @return void */ - protected function setAttributeValue(object $object, string $attribute, mixed $value, string $format = null, array $context = []) @@ -11273,31 +11252,6 @@ index 642130af75..c9ae2693a4 100644 - public function setPrefix(string $prefix); + public function setPrefix(string $prefix): void; } -diff --git a/src/Symfony/Component/Translation/Extractor/PhpExtractor.php b/src/Symfony/Component/Translation/Extractor/PhpExtractor.php -index 7ff27f7c80..495067ed2e 100644 ---- a/src/Symfony/Component/Translation/Extractor/PhpExtractor.php -+++ b/src/Symfony/Component/Translation/Extractor/PhpExtractor.php -@@ -136,5 +136,5 @@ class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface - * @return void - */ -- public function extract(string|iterable $resource, MessageCatalogue $catalog) -+ public function extract(string|iterable $resource, MessageCatalogue $catalog): void - { - $files = $this->extractFiles($resource); -@@ -149,5 +149,5 @@ class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface - * @return void - */ -- public function setPrefix(string $prefix) -+ public function setPrefix(string $prefix): void - { - $this->prefix = $prefix; -@@ -265,5 +265,5 @@ class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface - * @return void - */ -- protected function parseTokens(array $tokens, MessageCatalogue $catalog, string $filename) -+ protected function parseTokens(array $tokens, MessageCatalogue $catalog, string $filename): void - { - $tokenIterator = new \ArrayIterator($tokens); diff --git a/src/Symfony/Component/Translation/Loader/CsvFileLoader.php b/src/Symfony/Component/Translation/Loader/CsvFileLoader.php index 7f2f96be64..266c7f48c9 100644 --- a/src/Symfony/Component/Translation/Loader/CsvFileLoader.php @@ -11591,38 +11545,38 @@ index acb00d7242..37cc40a06f 100644 { $this diff --git a/src/Symfony/Component/Validator/Constraint.php b/src/Symfony/Component/Validator/Constraint.php -index d53bbb196f..4eecf85f8e 100644 +index 8156c99196..cfab6055f1 100644 --- a/src/Symfony/Component/Validator/Constraint.php +++ b/src/Symfony/Component/Validator/Constraint.php -@@ -236,5 +236,5 @@ abstract class Constraint +@@ -225,5 +225,5 @@ abstract class Constraint * @return void */ - public function addImplicitGroupName(string $group) + public function addImplicitGroupName(string $group): void { if (null === $this->groups && \array_key_exists('groups', (array) $this)) { -@@ -256,5 +256,5 @@ abstract class Constraint +@@ -245,5 +245,5 @@ abstract class Constraint * @see __construct() */ - public function getDefaultOption() + public function getDefaultOption(): ?string { return null; -@@ -270,5 +270,5 @@ abstract class Constraint +@@ -259,5 +259,5 @@ abstract class Constraint * @see __construct() */ - public function getRequiredOptions() + public function getRequiredOptions(): array { return []; -@@ -284,5 +284,5 @@ abstract class Constraint +@@ -273,5 +273,5 @@ abstract class Constraint * @return string */ - public function validatedBy() + public function validatedBy(): string { return static::class.'Validator'; -@@ -298,5 +298,5 @@ abstract class Constraint +@@ -287,5 +287,5 @@ abstract class Constraint * @return string|string[] One or more constant values */ - public function getTargets() @@ -11810,10 +11764,10 @@ index 5528252c52..de7c2c1257 100644 { if (!$constraint instanceof Choice) { diff --git a/src/Symfony/Component/Validator/Constraints/Collection.php b/src/Symfony/Component/Validator/Constraints/Collection.php -index ee50fca169..62effcb311 100644 +index a857c2aa43..21c0f07a19 100644 --- a/src/Symfony/Component/Validator/Constraints/Collection.php +++ b/src/Symfony/Component/Validator/Constraints/Collection.php -@@ -61,5 +61,5 @@ class Collection extends Composite +@@ -56,5 +56,5 @@ class Collection extends Composite * @return void */ - protected function initializeNestedConstraints() @@ -11916,10 +11870,10 @@ index 0e3d848430..b4a6755388 100644 { if (!$constraint instanceof Date) { diff --git a/src/Symfony/Component/Validator/Constraints/EmailValidator.php b/src/Symfony/Component/Validator/Constraints/EmailValidator.php -index 8c0ff77308..ca64a5fe88 100644 +index 72765dfbf7..6d14b36e92 100644 --- a/src/Symfony/Component/Validator/Constraints/EmailValidator.php +++ b/src/Symfony/Component/Validator/Constraints/EmailValidator.php -@@ -55,5 +55,5 @@ class EmailValidator extends ConstraintValidator +@@ -49,5 +49,5 @@ class EmailValidator extends ConstraintValidator * @return void */ - public function validate(mixed $value, Constraint $constraint) @@ -13613,10 +13567,10 @@ index 98c2149330..2e85547efb 100644 { if (!$this->connection->write($data) && $this->wrappedDumper) { diff --git a/src/Symfony/Component/VarDumper/VarDumper.php b/src/Symfony/Component/VarDumper/VarDumper.php -index a89f2369bb..78905c797d 100644 +index eda2727d50..5fde05973b 100644 --- a/src/Symfony/Component/VarDumper/VarDumper.php +++ b/src/Symfony/Component/VarDumper/VarDumper.php -@@ -43,5 +43,5 @@ class VarDumper +@@ -41,5 +41,5 @@ class VarDumper * @return mixed */ - public static function dump(mixed $var, string $label = null) @@ -13813,7 +13767,7 @@ index 9acd540dcc..495573aec4 100644 + public function getMetadata(string $key, string|Transition $subject = null): mixed; } diff --git a/src/Symfony/Component/Workflow/Registry.php b/src/Symfony/Component/Workflow/Registry.php -index 287d8b750f..9462747d84 100644 +index ad72693c5a..50bf899d1c 100644 --- a/src/Symfony/Component/Workflow/Registry.php +++ b/src/Symfony/Component/Workflow/Registry.php @@ -28,5 +28,5 @@ class Registry diff --git a/UPGRADE-7.0.md b/UPGRADE-7.0.md index d8c88af9916bb..2ddc9324de2b3 100644 --- a/UPGRADE-7.0.md +++ b/UPGRADE-7.0.md @@ -11,6 +11,11 @@ Cache * Add parameter `$isSameDatabase` to `DoctrineDbalAdapter::configureSchema()` +Config +------ + + * Require explicit argument when calling `NodeBuilder::setParent()` + Console ------- @@ -41,7 +46,7 @@ Console } ``` - * Passing null to `*Command::setApplication()`, `*FormatterStyle::setForeground/setBackground()`, `Helper::setHelpSet()`, `Input*::setDefault()` and `Question::setAutocompleterCallback/setValidator()` must be done explicitly + * Require explicit argument when calling `*Command::setApplication()`, `*FormatterStyle::setForeground/setBackground()`, `Helper::setHelpSet()`, `Input*::setDefault()` and `Question::setAutocompleterCallback/setValidator()` * Remove `StringInput::REGEX_STRING` * Add method `__toString()` to `InputInterface` @@ -52,7 +57,7 @@ DependencyInjection * Remove `ProxyHelper`, use `Symfony\Component\VarExporter\ProxyHelper` instead * Remove `ReferenceSetArgumentTrait` * Remove support of `@required` annotation, use the `Symfony\Contracts\Service\Attribute\Required` attribute instead - * Passing `null` to `ContainerAwareTrait::setContainer()` must be done explicitly + * Require explicit argument when calling `ContainerAwareTrait::setContainer()` * Remove `PhpDumper` options `inline_factories_parameter` and `inline_class_loader_parameter`, use options `inline_factories` and `inline_class_loader` instead * Parameter names of `ParameterBag` cannot be numerics * Remove `ContainerAwareInterface` and `ContainerAwareTrait`, use dependency injection instead @@ -82,10 +87,34 @@ Filesystem * Add argument `$lock` to `Filesystem::appendToFile()` +Form +---- + + * Throw when using `DateTime` or `DateTimeImmutable` model data with a different timezone than configured with the + `model_timezone` option in `DateType`, `DateTimeType`, and `TimeType` + * Make the "widget" option of date/time form types default to "single_text" + * Require explicit argument when calling `Button/Form::setParent()`, `ButtonBuilder/FormConfigBuilder::setDataMapper()`, `TransformationFailedException::setInvalidMessage()` + FrameworkBundle --------------- * Remove command `translation:update`, use `translation:extract` instead + * Make the `http_method_override` config option default to `false` + * Remove the `Symfony\Component\Serializer\Normalizer\ObjectNormalizer` and + `Symfony\Component\Serializer\Normalizer\PropertyNormalizer` autowiring aliases, type-hint against + `Symfony\Component\Serializer\Normalizer\NormalizerInterface` or implement `NormalizerAwareInterface` instead + * Remove the `Http\Client\HttpClient` service, use `Psr\Http\Client\ClientInterface` instead + * Remove `AbstractController::renderForm()`, use `render()` instead + + *Before* + ```php + $this->renderForm(..., ['form' => $form]); + ``` + + *After* + ```php + $this->render(..., ['form' => $form]); + ``` HttpFoundation -------------- @@ -99,6 +128,7 @@ HttpFoundation * Replace `ExpressionRequestMatcher` with `RequestMatcher\ExpressionRequestMatcher` * Remove `Request::getContentType()`, use `Request::getContentTypeFormat()` instead * Throw an `InvalidArgumentException` when calling `Request::create()` with a malformed URI + * Require explicit argument when calling `JsonResponse::setCallback()`, `Response::setExpires/setLastModified/setEtag()`, `MockArraySessionStorage/NativeSessionStorage::setMetadataBag()`, `NativeSessionStorage::setSaveHandler()` HttpClient ---------- @@ -114,6 +144,7 @@ HttpKernel * Remove `AbstractSurrogate::$phpEscapeMap` * Remove `HttpKernelInterface::MASTER_REQUEST` * Remove `terminate_on_cache_hit` option from `HttpCache` + * Require explicit argument when calling `ConfigDataCollector::setKernel()`, `RouterListener::setCurrentRequest()` Lock ---- @@ -121,21 +152,34 @@ Lock * Add parameter `$isSameDatabase` to `DoctrineDbalStore::configureSchema()` * Remove the `gcProbablity` (notice the typo) option, use `gcProbability` instead +Mailer +------ + + * Remove the OhMySmtp bridge in favor of the MailPace bridge + Messenger --------- * Add parameter `$isSameDatabase` to `DoctrineTransport::configureSchema()` + * Remove `MessageHandlerInterface` and `MessageSubscriberInterface`, use `#[AsMessageHandler]` instead + * Remove `StopWorkerOnSigtermSignalListener` in favor of + `StopWorkerOnSignalsListener` and make it configurable with SIGINT and + * Remove `Symfony\Component\Messenger\Transport\InMemoryTransport` and + `Symfony\Component\Messenger\Transport\InMemoryTransportFactory` in favor of + `Symfony\Component\Messenger\Transport\InMemory\InMemoryTransport` and + `Symfony\Component\Messenger\Transport\InMemory\InMemoryTransportFactory` Mime ---- * Remove `Email::attachPart()` method, use `Email::addPart()` instead - * Parameter `$body` is now required (at least null) in `Message::setBody()` + * Require explicit argument when calling `Message::setBody()` PropertyAccess -------------- * Add method `isNullSafe()` to `PropertyPathInterface` + * Require explicit argument when calling `PropertyAccessorBuilder::setCacheItemPool()` ProxyManagerBridge ------------------ @@ -152,6 +196,7 @@ Security * Add argument `$badgeFqcn` to `Passport::addBadge()` * Add argument `$lifetime` to `LoginLinkHandlerInterface::createLoginLink()` + * Require explicit argument when calling `TokenStorage::setToken()` SecurityBundle -------------- @@ -189,6 +234,7 @@ Serializer } } ``` + * Remove `CacheableSupportsMethodInterface`, use `NormalizerInterface` and `DenormalizerInterface` instead *Before* @@ -233,9 +279,24 @@ Serializer // ... } ``` - * First argument of `AttributeMetadata::setSerializedName()` is now required + + * Require explicit argument when calling `AttributeMetadata::setSerializedName()` and `ClassMetadata::setClassDiscriminatorMapping()` * Add argument `$context` to `NormalizerInterface::supportsNormalization()` and `DenormalizerInterface::supportsDenormalization()` +Translation +----------- + + * Remove `PhpStringTokenParser` + * Remove `PhpExtractor` in favor of `PhpAstExtractor` + +TwigBundle +---------- + + * Remove the `Twig_Environment` autowiring alias, use `Twig\Environment` instead + * Remove option `twig.autoescape`; create a class that implements your escaping strategy + (check `FileExtensionEscapingStrategy::guess()` for inspiration) and reference it using + the `twig.autoescape_service` option instead + Validator --------- @@ -250,3 +311,14 @@ VarDumper --------- * Add argument `$label` to `VarDumper::dump()` + * Require explicit argument when calling `VarDumper::setHandler()` + +Workflow +-------- + + * Require explicit argument when calling `Definition::setInitialPlaces()` + +Yaml +---- + + * Remove the `!php/const:` tag, use `!php/const` instead (without the colon) diff --git a/composer.json b/composer.json index 8144b42e051ad..0a270471df520 100644 --- a/composer.json +++ b/composer.json @@ -141,7 +141,6 @@ "pda/pheanstalk": "^4.0", "php-http/discovery": "^1.15", "php-http/httplug": "^1.0|^2.0", - "php-http/message-factory": "^1.0", "phpdocumentor/reflection-docblock": "^5.2", "phpstan/phpdoc-parser": "^1.0", "predis/predis": "^1.1|^2.0", diff --git a/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php b/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php index 1382eaf66645a..82cc8a5b7bc88 100644 --- a/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php +++ b/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php @@ -22,7 +22,7 @@ use Symfony\Component\DependencyInjection\Reference; /** - * Registers event listeners and subscribers to the available doctrine connections. + * Registers event listeners to the available doctrine connections. * * @author Jeremy Mikola * @author Alexander @@ -44,7 +44,7 @@ class RegisterEventListenersAndSubscribersPass implements CompilerPassInterface /** * @param string $managerTemplate sprintf() template for generating the event * manager's service ID for a connection name - * @param string $tagPrefix Tag prefix for listeners and subscribers + * @param string $tagPrefix Tag prefix for listeners */ public function __construct(string $connectionsParameter, string $managerTemplate, string $tagPrefix) { @@ -72,18 +72,13 @@ public function process(ContainerBuilder $container): void private function addTaggedServices(ContainerBuilder $container): array { - $listenerTag = $this->tagPrefix.'.event_listener'; - $subscriberTag = $this->tagPrefix.'.event_subscriber'; $listenerRefs = []; - $taggedServices = $this->findAndSortTags($subscriberTag, $listenerTag, $container); - $managerDefs = []; - foreach ($taggedServices as $taggedSubscriber) { - [$tagName, $id, $tag] = $taggedSubscriber; + foreach ($this->findAndSortTags($container) as [$id, $tag]) { $connections = isset($tag['connection']) ? [$container->getParameterBag()->resolveValue($tag['connection'])] : array_keys($this->connections); - if ($listenerTag === $tagName && !isset($tag['event'])) { + if (!isset($tag['event'])) { throw new InvalidArgumentException(sprintf('Doctrine event listener "%s" must specify the "event" attribute.', $id)); } foreach ($connections as $con) { @@ -105,19 +100,10 @@ private function addTaggedServices(ContainerBuilder $container): array if (ContainerAwareEventManager::class === $managerClass) { $refs = $managerDef->getArguments()[1] ?? []; $listenerRefs[$con][$id] = new Reference($id); - if ($subscriberTag === $tagName) { - trigger_deprecation('symfony/doctrine-bridge', '6.3', 'Registering "%s" as a Doctrine subscriber is deprecated. Register it as a listener instead, using e.g. the #[AsDoctrineListener] attribute.', $id); - $refs[] = $id; - } else { - $refs[] = [[$tag['event']], $id]; - } + $refs[] = [[$tag['event']], $id]; $managerDef->setArgument(1, $refs); } else { - if ($subscriberTag === $tagName) { - $managerDef->addMethodCall('addEventSubscriber', [new Reference($id)]); - } else { - $managerDef->addMethodCall('addEventListener', [[$tag['event']], new Reference($id)]); - } + $managerDef->addMethodCall('addEventListener', [[$tag['event']], new Reference($id)]); } } } @@ -144,21 +130,14 @@ private function getEventManagerDef(ContainerBuilder $container, string $name): * @see https://bugs.php.net/53710 * @see https://bugs.php.net/60926 */ - private function findAndSortTags(string $subscriberTag, string $listenerTag, ContainerBuilder $container): array + private function findAndSortTags(ContainerBuilder $container): array { $sortedTags = []; - $taggedIds = [ - $subscriberTag => $container->findTaggedServiceIds($subscriberTag, true), - $listenerTag => $container->findTaggedServiceIds($listenerTag, true), - ]; - $taggedIds[$subscriberTag] = array_diff_key($taggedIds[$subscriberTag], $taggedIds[$listenerTag]); - - foreach ($taggedIds as $tagName => $serviceIds) { - foreach ($serviceIds as $serviceId => $tags) { - foreach ($tags as $attributes) { - $priority = $attributes['priority'] ?? 0; - $sortedTags[$priority][] = [$tagName, $serviceId, $attributes]; - } + + foreach ($container->findTaggedServiceIds($this->tagPrefix.'.event_listener', true) as $serviceId => $tags) { + foreach ($tags as $attributes) { + $priority = $attributes['priority'] ?? 0; + $sortedTags[$priority][] = [$serviceId, $attributes]; } } diff --git a/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPassTest.php b/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPassTest.php index 254953c9d6a2a..0966d5ae1bec7 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPassTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPassTest.php @@ -14,7 +14,6 @@ use PHPUnit\Framework\TestCase; use Symfony\Bridge\Doctrine\ContainerAwareEventManager; use Symfony\Bridge\Doctrine\DependencyInjection\CompilerPass\RegisterEventListenersAndSubscribersPass; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; @@ -23,22 +22,6 @@ class RegisterEventListenersAndSubscribersPassTest extends TestCase { - use ExpectDeprecationTrait; - - public function testExceptionOnAbstractTaggedSubscriber() - { - $this->expectException(\InvalidArgumentException::class); - $container = $this->createBuilder(); - - $abstractDefinition = new Definition('stdClass'); - $abstractDefinition->setAbstract(true); - $abstractDefinition->addTag('doctrine.event_subscriber'); - - $container->setDefinition('a', $abstractDefinition); - - $this->process($container); - } - public function testExceptionOnAbstractTaggedListener() { $this->expectException(\InvalidArgumentException::class); @@ -198,300 +181,6 @@ public function testProcessEventListenersWithMultipleConnections() ); } - /** - * @group legacy - */ - public function testProcessEventSubscribersWithMultipleConnections() - { - $container = $this->createBuilder(true); - - $container->setParameter('connection_param', 'second'); - - $container - ->register('a', 'stdClass') - ->addTag('doctrine.event_subscriber', [ - 'event' => 'onFlush', - ]) - ; - - $container - ->register('b', 'stdClass') - ->addTag('doctrine.event_subscriber', [ - 'event' => 'onFlush', - 'connection' => 'default', - ]) - ; - - $container - ->register('c', 'stdClass') - ->addTag('doctrine.event_subscriber', [ - 'event' => 'onFlush', - 'connection' => 'second', - ]) - ; - - $container - ->register('d', 'stdClass') - ->addTag('doctrine.event_subscriber', [ - 'event' => 'onFlush', - 'connection' => '%connection_param%', - ]) - ; - - $this->expectDeprecation('Since symfony/doctrine-bridge 6.3: Registering "d" as a Doctrine subscriber is deprecated. Register it as a listener instead, using e.g. the #[AsDoctrineListener] attribute.'); - $this->process($container); - - $eventManagerDef = $container->getDefinition('doctrine.dbal.default_connection.event_manager'); - - // first connection - $this->assertEquals( - [ - 'a', - 'b', - ], - $eventManagerDef->getArgument(1) - ); - - $serviceLocatorDef = $container->getDefinition((string) $eventManagerDef->getArgument(0)); - $this->assertSame(ServiceLocator::class, $serviceLocatorDef->getClass()); - $this->assertEquals( - [ - 'a' => new ServiceClosureArgument(new Reference('a')), - 'b' => new ServiceClosureArgument(new Reference('b')), - ], - $serviceLocatorDef->getArgument(0) - ); - - $eventManagerDef = $container->getDefinition('doctrine.dbal.second_connection.event_manager'); - - // second connection - $this->assertEquals( - [ - 'a', - 'c', - 'd', - ], - $eventManagerDef->getArgument(1) - ); - - $serviceLocatorDef = $container->getDefinition((string) $eventManagerDef->getArgument(0)); - $this->assertSame(ServiceLocator::class, $serviceLocatorDef->getClass()); - $this->assertEquals( - [ - 'a' => new ServiceClosureArgument(new Reference('a')), - 'c' => new ServiceClosureArgument(new Reference('c')), - 'd' => new ServiceClosureArgument(new Reference('d')), - ], - $serviceLocatorDef->getArgument(0) - ); - } - - /** - * @group legacy - */ - public function testProcessEventSubscribersWithPriorities() - { - $container = $this->createBuilder(); - - $container - ->register('a', 'stdClass') - ->addTag('doctrine.event_subscriber') - ; - $container - ->register('b', 'stdClass') - ->addTag('doctrine.event_subscriber', [ - 'priority' => 5, - ]) - ; - $container - ->register('c', 'stdClass') - ->addTag('doctrine.event_subscriber', [ - 'priority' => 10, - ]) - ; - $container - ->register('d', 'stdClass') - ->addTag('doctrine.event_subscriber', [ - 'priority' => 10, - ]) - ; - $container - ->register('e', 'stdClass') - ->addTag('doctrine.event_subscriber', [ - 'priority' => 10, - ]) - ; - - $this->expectDeprecation('Since symfony/doctrine-bridge 6.3: Registering "d" as a Doctrine subscriber is deprecated. Register it as a listener instead, using e.g. the #[AsDoctrineListener] attribute.'); - $this->process($container); - - $eventManagerDef = $container->getDefinition('doctrine.dbal.default_connection.event_manager'); - - $this->assertEquals( - [ - 'c', - 'd', - 'e', - 'b', - 'a', - ], - $eventManagerDef->getArgument(1) - ); - - $serviceLocatorDef = $container->getDefinition((string) $eventManagerDef->getArgument(0)); - $this->assertSame(ServiceLocator::class, $serviceLocatorDef->getClass()); - $this->assertEquals( - [ - 'a' => new ServiceClosureArgument(new Reference('a')), - 'b' => new ServiceClosureArgument(new Reference('b')), - 'c' => new ServiceClosureArgument(new Reference('c')), - 'd' => new ServiceClosureArgument(new Reference('d')), - 'e' => new ServiceClosureArgument(new Reference('e')), - ], - $serviceLocatorDef->getArgument(0) - ); - } - - /** - * @group legacy - */ - public function testProcessEventSubscribersAndListenersWithPriorities() - { - $container = $this->createBuilder(); - - $container - ->register('a', 'stdClass') - ->addTag('doctrine.event_subscriber') - ; - $container - ->register('b', 'stdClass') - ->addTag('doctrine.event_subscriber', [ - 'priority' => 5, - ]) - ; - $container - ->register('c', 'stdClass') - ->addTag('doctrine.event_subscriber', [ - 'priority' => 10, - ]) - ; - $container - ->register('d', 'stdClass') - ->addTag('doctrine.event_subscriber', [ - 'priority' => 10, - ]) - ; - $container - ->register('e', 'stdClass') - ->addTag('doctrine.event_subscriber', [ - 'priority' => 10, - ]) - ; - $container - ->register('f', 'stdClass') - ->setPublic(false) - ->addTag('doctrine.event_listener', [ - 'event' => 'bar', - ]) - ->addTag('doctrine.event_listener', [ - 'event' => 'foo', - 'priority' => -5, - ]) - ->addTag('doctrine.event_listener', [ - 'event' => 'foo_bar', - 'priority' => 3, - ]) - ; - $container - ->register('g', 'stdClass') - ->addTag('doctrine.event_listener', [ - 'event' => 'foo', - ]) - ; - $container - ->register('h', 'stdClass') - ->addTag('doctrine.event_listener', [ - 'event' => 'foo_bar', - 'priority' => 4, - ]) - ; - - $this->expectDeprecation('Since symfony/doctrine-bridge 6.3: Registering "d" as a Doctrine subscriber is deprecated. Register it as a listener instead, using e.g. the #[AsDoctrineListener] attribute.'); - $this->process($container); - - $eventManagerDef = $container->getDefinition('doctrine.dbal.default_connection.event_manager'); - - $this->assertEquals( - [ - 'c', - 'd', - 'e', - 'b', - [['foo_bar'], 'h'], - [['foo_bar'], 'f'], - 'a', - [['bar'], 'f'], - [['foo'], 'g'], - [['foo'], 'f'], - ], - $eventManagerDef->getArgument(1) - ); - - $serviceLocatorDef = $container->getDefinition((string) $eventManagerDef->getArgument(0)); - $this->assertSame(ServiceLocator::class, $serviceLocatorDef->getClass()); - $this->assertEquals( - [ - 'a' => new ServiceClosureArgument(new Reference('a')), - 'b' => new ServiceClosureArgument(new Reference('b')), - 'c' => new ServiceClosureArgument(new Reference('c')), - 'd' => new ServiceClosureArgument(new Reference('d')), - 'e' => new ServiceClosureArgument(new Reference('e')), - 'f' => new ServiceClosureArgument(new Reference('f')), - 'g' => new ServiceClosureArgument(new Reference('g')), - 'h' => new ServiceClosureArgument(new Reference('h')), - ], - $serviceLocatorDef->getArgument(0) - ); - } - - public function testSubscribersAreSkippedIfListenerDefinedForSameDefinition() - { - $container = $this->createBuilder(); - - $container - ->register('a', 'stdClass') - ->setPublic(false) - ->addTag('doctrine.event_listener', [ - 'event' => 'bar', - 'priority' => 3, - ]) - ; - $container - ->register('b', 'stdClass') - ->setPublic(false) - ->addTag('doctrine.event_listener', [ - 'event' => 'bar', - ]) - ->addTag('doctrine.event_listener', [ - 'event' => 'foo', - 'priority' => -5, - ]) - ->addTag('doctrine.event_subscriber') - ; - $this->process($container); - - $eventManagerDef = $container->getDefinition('doctrine.dbal.default_connection.event_manager'); - - $this->assertEquals( - [ - [['bar'], 'a'], - [['bar'], 'b'], - [['foo'], 'b'], - ], - $eventManagerDef->getArgument(1) - ); - } - public function testProcessNoTaggedServices() { $container = $this->createBuilder(true); diff --git a/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php b/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php index bbe50eba9c748..266f1bf0caba4 100644 --- a/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php @@ -48,7 +48,7 @@ protected function getDefaultFormatter() /** * @author Grégoire Pineau * - * @internal since Symfony 6.1 + * @internal */ trait ServerLogHandlerTrait { diff --git a/src/Symfony/Bridge/Monolog/Processor/AbstractTokenProcessor.php b/src/Symfony/Bridge/Monolog/Processor/AbstractTokenProcessor.php index c455be29a33ec..5d92298fea6fc 100644 --- a/src/Symfony/Bridge/Monolog/Processor/AbstractTokenProcessor.php +++ b/src/Symfony/Bridge/Monolog/Processor/AbstractTokenProcessor.php @@ -21,20 +21,15 @@ * @author Dany Maillard * @author Igor Timoshenko * - * @internal since Symfony 6.1 + * @internal */ abstract class AbstractTokenProcessor { use CompatibilityProcessor; - /** - * @var TokenStorageInterface - */ - protected $tokenStorage; - - public function __construct(TokenStorageInterface $tokenStorage) - { - $this->tokenStorage = $tokenStorage; + public function __construct( + protected TokenStorageInterface $tokenStorage, + ) { } abstract protected function getKey(): string; diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md index effe9a43031c3..79c157980652c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md @@ -5,6 +5,12 @@ CHANGELOG --- * Remove command `translation:update`, use `translation:extract` instead + * Make the `http_method_override` config option default to `false` + * Remove `AbstractController::renderForm()`, use `render()` instead + * Remove the `Symfony\Component\Serializer\Normalizer\ObjectNormalizer` and + `Symfony\Component\Serializer\Normalizer\PropertyNormalizer` autowiring aliases, type-hint against + `Symfony\Component\Serializer\Normalizer\NormalizerInterface` or implement `NormalizerAwareInterface` instead + * Remove the `Http\Client\HttpClient` service, use `Psr\Http\Client\ClientInterface` instead 6.3 --- diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php index f84a560c6d44b..f69a0e11e2863 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php @@ -21,7 +21,6 @@ use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\DependencyInjection\ServiceLocator; -use Symfony\Component\Workflow\Definition; use Symfony\Component\Workflow\Dumper\GraphvizDumper; use Symfony\Component\Workflow\Dumper\MermaidDumper; use Symfony\Component\Workflow\Dumper\PlantUmlDumper; @@ -37,33 +36,16 @@ #[AsCommand(name: 'workflow:dump', description: 'Dump a workflow')] class WorkflowDumpCommand extends Command { - /** - * string is the service id. - * - * @var array - */ - private array $definitions = []; - - private ServiceLocator $workflows; - private const DUMP_FORMAT_OPTIONS = [ 'puml', 'mermaid', 'dot', ]; - public function __construct($workflows) - { + public function __construct( + private ServiceLocator $workflows, + ) { parent::__construct(); - - if ($workflows instanceof ServiceLocator) { - $this->workflows = $workflows; - } elseif (\is_array($workflows)) { - $this->definitions = $workflows; - trigger_deprecation('symfony/framework-bundle', '6.2', 'Passing an array of definitions in "%s()" is deprecated. Inject a ServiceLocator filled with all workflows instead.', __METHOD__); - } else { - throw new \TypeError(sprintf('Argument 1 passed to "%s()" must be an array or a ServiceLocator, "%s" given.', __METHOD__, \gettype($workflows))); - } } protected function configure(): void @@ -92,20 +74,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int { $workflowName = $input->getArgument('name'); - if (isset($this->workflows)) { - if (!$this->workflows->has($workflowName)) { - throw new InvalidArgumentException(sprintf('The workflow named "%s" cannot be found.', $workflowName)); - } - $workflow = $this->workflows->get($workflowName); - $type = $workflow instanceof StateMachine ? 'state_machine' : 'workflow'; - $definition = $workflow->getDefinition(); - } elseif (isset($this->definitions['workflow.'.$workflowName])) { - $definition = $this->definitions['workflow.'.$workflowName]; - $type = 'workflow'; - } elseif (isset($this->definitions['state_machine.'.$workflowName])) { - $definition = $this->definitions['state_machine.'.$workflowName]; - $type = 'state_machine'; + if (!$this->workflows->has($workflowName)) { + throw new InvalidArgumentException(sprintf('The workflow named "%s" cannot be found.', $workflowName)); } + $workflow = $this->workflows->get($workflowName); + $type = $workflow instanceof StateMachine ? 'state_machine' : 'workflow'; + $definition = $workflow->getDefinition(); if (null === $definition) { throw new InvalidArgumentException(sprintf('No service found for "workflow.%1$s" nor "state_machine.%1$s".', $workflowName)); @@ -147,11 +121,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void { if ($input->mustSuggestArgumentValuesFor('name')) { - if (isset($this->workflows)) { - $suggestions->suggestValues(array_keys($this->workflows->getProvidedServices())); - } else { - $suggestions->suggestValues(array_keys($this->definitions)); - } + $suggestions->suggestValues(array_keys($this->workflows->getProvidedServices())); } if ($input->mustSuggestOptionValuesFor('dump-format')) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/AbstractController.php b/src/Symfony/Bundle/FrameworkBundle/Controller/AbstractController.php index 13e155235358b..4af31ad7d1dd0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Controller/AbstractController.php +++ b/src/Symfony/Bundle/FrameworkBundle/Controller/AbstractController.php @@ -186,7 +186,7 @@ protected function addFlash(string $type, mixed $message): void } if (!$session instanceof FlashBagAwareSessionInterface) { - trigger_deprecation('symfony/framework-bundle', '6.2', 'Calling "addFlash()" method when the session does not implement %s is deprecated.', FlashBagAwareSessionInterface::class); + throw new \LogicException(sprintf('You cannot use the addFlash method because class "%s" doesn\'t implement "%s".', get_debug_type($session), FlashBagAwareSessionInterface::class)); } $session->getFlashBag()->add($type, $message); @@ -268,20 +268,6 @@ protected function render(string $view, array $parameters = [], Response $respon return $response; } - /** - * Renders a view and sets the appropriate status code when a form is listed in parameters. - * - * If an invalid form is found in the list of parameters, a 422 status code is returned. - * - * @deprecated since Symfony 6.2, use render() instead - */ - protected function renderForm(string $view, array $parameters = [], Response $response = null): Response - { - trigger_deprecation('symfony/framework-bundle', '6.2', 'The "%s::renderForm()" method is deprecated, use "render()" instead.', get_debug_type($this)); - - return $this->render($view, $parameters, $response); - } - /** * Streams a view. */ diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index 708b43b840c84..8ca6a54c06803 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -81,23 +81,12 @@ public function getConfigTreeBuilder(): TreeBuilder return $v; }) ->end() - ->validate() - ->always(function ($v) { - if (!isset($v['http_method_override'])) { - trigger_deprecation('symfony/framework-bundle', '6.1', 'Not setting the "framework.http_method_override" config option is deprecated. It will default to "false" in 7.0.'); - - $v['http_method_override'] = true; - } - - return $v; - }) - ->end() ->fixXmlConfig('enabled_locale') ->children() ->scalarNode('secret')->end() ->booleanNode('http_method_override') ->info("Set true to enable support for the '_method' request parameter to determine the intended HTTP method on POST requests. Note: When using the HttpCache, you need to call the method in your front controller instead") - ->treatNullLike(false) + ->defaultFalse() ->end() ->scalarNode('trust_x_sendfile_type_header') ->info('Set true to enable support for xsendfile in binary file responses.') @@ -244,9 +233,6 @@ private function addFormSection(ArrayNodeDefinition $rootNode, callable $enableI ->scalarNode('field_name')->defaultValue('_token')->end() ->end() ->end() - ->booleanNode('legacy_error_messages') - ->setDeprecated('symfony/framework-bundle', '6.2') - ->end() ->end() ->end() ->end() @@ -1303,27 +1289,6 @@ private function addExceptionsSection(ArrayNodeDefinition $rootNode): void ->arrayNode('exceptions') ->info('Exception handling configuration') ->useAttributeAsKey('class') - ->beforeNormalization() - // Handle legacy XML configuration - ->ifArray() - ->then(function (array $v): array { - if (!\array_key_exists('exception', $v)) { - return $v; - } - - trigger_deprecation('symfony/framework-bundle', '6.3', '"framework:exceptions" tag is deprecated. Unwrap it and replace your "framework:exception" tags\' "name" attribute by "class".'); - - $v = $v['exception']; - unset($v['exception']); - - foreach ($v as &$exception) { - $exception['class'] = $exception['name']; - unset($exception['name']); - } - - return $v; - }) - ->end() ->prototype('array') ->children() ->scalarNode('log_level') @@ -1620,15 +1585,6 @@ function ($a) { ->defaultNull() ->info('Transport name to send failed messages to (after all retries have failed).') ->end() - ->booleanNode('reset_on_message') - ->defaultTrue() - ->info('Reset container services after each message.') - ->setDeprecated('symfony/framework-bundle', '6.1', 'Option "%node%" at "%path%" is deprecated. It does nothing and will be removed in version 7.0.') - ->validate() - ->ifTrue(static fn ($v) => true !== $v) - ->thenInvalid('The "framework.messenger.reset_on_message" configuration option can be set to "true" only. To prevent services resetting after each message you can set the "--no-reset" option in "messenger:consume" command.') - ->end() - ->end() ->arrayNode('stop_worker_on_signals') ->defaultValue([]) ->info('A list of signals that should stop the worker; defaults to SIGTERM and SIGINT.') diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index f5ddf2fac6aa3..34e8c93b932ba 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -111,7 +111,6 @@ use Symfony\Component\Messenger\Bridge as MessengerBridge; use Symfony\Component\Messenger\Command\StatsCommand; use Symfony\Component\Messenger\Handler\BatchHandlerInterface; -use Symfony\Component\Messenger\Handler\MessageHandlerInterface; use Symfony\Component\Messenger\MessageBus; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Messenger\Middleware\RouterContextMiddleware; @@ -213,7 +212,7 @@ public function load(array $configs, ContainerBuilder $container): void $loader = new PhpFileLoader($container, new FileLocator(\dirname(__DIR__).'/Resources/config')); if (class_exists(InstalledVersions::class) && InstalledVersions::isInstalled('symfony/symfony') && 'symfony/symfony' !== (InstalledVersions::getRootPackage()['name'] ?? '')) { - trigger_deprecation('symfony/symfony', '6.1', 'Requiring the "symfony/symfony" package is deprecated; replace it with standalone components instead.'); + throw new \LogicException('Requiring the "symfony/symfony" package is unsupported; replace it with standalone components instead.'); } $loader->load('web.php'); @@ -647,8 +646,6 @@ public function load(array $configs, ContainerBuilder $container): void ->addTag('validator.constraint_validator'); $container->registerForAutoconfiguration(ObjectInitializerInterface::class) ->addTag('validator.initializer'); - $container->registerForAutoconfiguration(MessageHandlerInterface::class) - ->addTag('messenger.message_handler'); $container->registerForAutoconfiguration(BatchHandlerInterface::class) ->addTag('messenger.message_handler'); $container->registerForAutoconfiguration(MessengerTransportFactoryInterface::class) @@ -2591,7 +2588,6 @@ private function registerMailerConfiguration(array $config, ContainerBuilder $co MailerBridge\Mailjet\Transport\MailjetTransportFactory::class => 'mailer.transport_factory.mailjet', MailerBridge\MailPace\Transport\MailPaceTransportFactory::class => 'mailer.transport_factory.mailpace', MailerBridge\Mailchimp\Transport\MandrillTransportFactory::class => 'mailer.transport_factory.mailchimp', - MailerBridge\OhMySmtp\Transport\OhMySmtpTransportFactory::class => 'mailer.transport_factory.ohmysmtp', MailerBridge\Postmark\Transport\PostmarkTransportFactory::class => 'mailer.transport_factory.postmark', MailerBridge\Sendgrid\Transport\SendgridTransportFactory::class => 'mailer.transport_factory.sendgrid', MailerBridge\Sendinblue\Transport\SendinblueTransportFactory::class => 'mailer.transport_factory.sendinblue', @@ -2893,45 +2889,6 @@ private function registerRateLimiterConfiguration(array $config, ContainerBuilde } } - /** - * @deprecated since Symfony 6.2 - * - * @return void - */ - public static function registerRateLimiter(ContainerBuilder $container, string $name, array $limiterConfig) - { - trigger_deprecation('symfony/framework-bundle', '6.2', 'The "%s()" method is deprecated.', __METHOD__); - - // default configuration (when used by other DI extensions) - $limiterConfig += ['lock_factory' => 'lock.factory', 'cache_pool' => 'cache.rate_limiter']; - - $limiter = $container->setDefinition($limiterId = 'limiter.'.$name, new ChildDefinition('limiter')); - - if (null !== $limiterConfig['lock_factory']) { - if (!interface_exists(LockInterface::class)) { - throw new LogicException(sprintf('Rate limiter "%s" requires the Lock component to be installed. Try running "composer require symfony/lock".', $name)); - } - if (!$container->hasDefinition('lock.factory.abstract')) { - throw new LogicException(sprintf('Rate limiter "%s" requires the Lock component to be configured.', $name)); - } - - $limiter->replaceArgument(2, new Reference($limiterConfig['lock_factory'])); - } - unset($limiterConfig['lock_factory']); - - if (null === $storageId = $limiterConfig['storage_service'] ?? null) { - $container->register($storageId = 'limiter.storage.'.$name, CacheStorage::class)->addArgument(new Reference($limiterConfig['cache_pool'])); - } - - $limiter->replaceArgument(1, new Reference($storageId)); - unset($limiterConfig['storage_service'], $limiterConfig['cache_pool']); - - $limiterConfig['id'] = $name; - $limiter->replaceArgument(0, $limiterConfig); - - $container->registerAliasForArgument($limiterId, RateLimiterFactory::class, $name.'.limiter'); - } - private function registerUidConfiguration(array $config, ContainerBuilder $container, PhpFileLoader $loader): void { $loader->load('uid.php'); diff --git a/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php b/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php index 694714faa0feb..794f4f454427d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php +++ b/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php @@ -110,10 +110,6 @@ public function loginUser(object $user, string $firewallContext = 'main'): stati } $token = new TestBrowserToken($user->getRoles(), $user, $firewallContext); - // required for compatibility with Symfony 5.4 - if (method_exists($token, 'isAuthenticated')) { - $token->setAuthenticated(true, false); - } $container = $this->getContainer(); $container->get('security.untracked_token_storage')->setToken($token); diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/annotations.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/annotations.php index f043c87ec7d73..0f561d9d3a571 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/annotations.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/annotations.php @@ -22,7 +22,7 @@ return static function (ContainerConfigurator $container) { $container->services() ->set('annotations.reader', AnnotationReader::class) - ->call('addGlobalIgnoredName', ['required']) // @deprecated since Symfony 6.3 + ->call('addGlobalIgnoredName', ['required']) ->set('annotations.cached_reader', PsrCachedReader::class) ->args([ diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/http_client.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/http_client.php index 23b794f45b2dd..ed932fdf8e7f6 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/http_client.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/http_client.php @@ -58,8 +58,6 @@ ]) ->alias(HttpAsyncClient::class, 'httplug.http_client') - ->alias(\Http\Client\HttpClient::class, 'httplug.http_client') - ->deprecate('symfony/framework-bundle', '6.3', 'The "%alias_id%" service is deprecated, use "'.ClientInterface::class.'" instead.') ->set('http_client.abstract_retry_strategy', GenericRetryStrategy::class) ->abstract() diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer_transports.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer_transports.php index d352eb5bee856..bc5900a76c65c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer_transports.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer_transports.php @@ -19,7 +19,6 @@ use Symfony\Component\Mailer\Bridge\Mailgun\Transport\MailgunTransportFactory; use Symfony\Component\Mailer\Bridge\Mailjet\Transport\MailjetTransportFactory; use Symfony\Component\Mailer\Bridge\MailPace\Transport\MailPaceTransportFactory; -use Symfony\Component\Mailer\Bridge\OhMySmtp\Transport\OhMySmtpTransportFactory; use Symfony\Component\Mailer\Bridge\Postmark\Transport\PostmarkTransportFactory; use Symfony\Component\Mailer\Bridge\Sendgrid\Transport\SendgridTransportFactory; use Symfony\Component\Mailer\Bridge\Sendinblue\Transport\SendinblueTransportFactory; @@ -92,10 +91,6 @@ ->parent('mailer.transport_factory.abstract') ->tag('mailer.transport_factory') - ->set('mailer.transport_factory.ohmysmtp', OhMySmtpTransportFactory::class) - ->parent('mailer.transport_factory.abstract') - ->tag('mailer.transport_factory') - ->set('mailer.transport_factory.smtp', EsmtpTransportFactory::class) ->parent('mailer.transport_factory.abstract') ->tag('mailer.transport_factory', ['priority' => -100]) diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.php index 3fe593ac673ff..0096ff1e099f3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.php @@ -209,9 +209,6 @@ ->tag('kernel.event_subscriber') ->tag('monolog.logger', ['channel' => 'messenger']) - ->alias('messenger.listener.stop_worker_on_sigterm_signal_listener', 'messenger.listener.stop_worker_signals_listener') - ->deprecate('6.3', 'symfony/messenger', 'The "%alias_id%" service is deprecated, use "messenger.listener.stop_worker_signals_listener" instead.') - ->set('messenger.listener.stop_worker_on_stop_exception_listener', StopWorkerOnCustomStopExceptionListener::class) ->tag('kernel.event_subscriber') diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier.php index 6ce674148a878..3bd19b8ddc061 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier.php @@ -129,8 +129,5 @@ ->set('notifier.notification_logger_listener', NotificationLoggerListener::class) ->tag('kernel.event_subscriber') - ->alias('notifier.logger_notification_listener', 'notifier.notification_logger_listener') - ->deprecate('symfony/framework-bundle', '6.3', 'The "%alias_id%" service is deprecated, use "notifier.notification_logger_listener" instead.') - ; }; diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd index a2abb5bc0c42a..69475e307a1ca 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd @@ -31,8 +31,7 @@ - - + @@ -67,7 +66,6 @@ - @@ -409,31 +407,10 @@ - - - - - - - + - - - - - - - - - - - - - - - - + @@ -585,7 +562,6 @@ - diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.php index 6459dfa4442bd..94107237f0bae 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.php @@ -42,7 +42,6 @@ use Symfony\Component\Serializer\Normalizer\FormErrorNormalizer; use Symfony\Component\Serializer\Normalizer\JsonSerializableNormalizer; use Symfony\Component\Serializer\Normalizer\MimeMessageNormalizer; -use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; use Symfony\Component\Serializer\Normalizer\ProblemNormalizer; @@ -127,9 +126,6 @@ ]) ->tag('serializer.normalizer', ['priority' => -1000]) - ->alias(ObjectNormalizer::class, 'serializer.normalizer.object') - ->deprecate('symfony/serializer', '6.2', 'The "%alias_id%" service alias is deprecated, type-hint against "'.NormalizerInterface::class.'" or implement "'.NormalizerAwareInterface::class.'" instead.') - ->set('serializer.normalizer.property', PropertyNormalizer::class) ->args([ service('serializer.mapping.class_metadata_factory'), @@ -139,9 +135,6 @@ null, ]) - ->alias(PropertyNormalizer::class, 'serializer.normalizer.property') - ->deprecate('symfony/serializer', '6.2', 'The "%alias_id%" service alias is deprecated, type-hint against "'.NormalizerInterface::class.'" or implement "'.NormalizerAwareInterface::class.'" instead.') - ->set('serializer.denormalizer.array', ArrayDenormalizer::class) ->tag('serializer.normalizer', ['priority' => -990]) diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.php index dcfa2bc15716d..a450e6894cc8a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.php @@ -27,7 +27,6 @@ use Symfony\Component\Translation\Extractor\ChainExtractor; use Symfony\Component\Translation\Extractor\ExtractorInterface; use Symfony\Component\Translation\Extractor\PhpAstExtractor; -use Symfony\Component\Translation\Extractor\PhpExtractor; use Symfony\Component\Translation\Extractor\Visitor\ConstraintVisitor; use Symfony\Component\Translation\Extractor\Visitor\TranslatableMessageVisitor; use Symfony\Component\Translation\Extractor\Visitor\TransMethodVisitor; @@ -152,10 +151,6 @@ ->set('translation.dumper.res', IcuResFileDumper::class) ->tag('translation.dumper', ['alias' => 'res']) - ->set('translation.extractor.php', PhpExtractor::class) - ->deprecate('symfony/framework-bundle', '6.2', 'The "%service_id%" service is deprecated, use "translation.extractor.php_ast" instead.') - ->tag('translation.extractor', ['alias' => 'php']) - ->set('translation.extractor.php_ast', PhpAstExtractor::class) ->args([tagged_iterator('translation.extractor.visitor')]) ->tag('translation.extractor', ['alias' => 'php']) diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/workflow.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/workflow.php index 85d786537f031..2c47fa96058ba 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/workflow.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/workflow.php @@ -40,10 +40,6 @@ ->set('workflow.marking_store.method', MethodMarkingStore::class) ->abstract() ->set('.workflow.registry', Registry::class) - ->alias(Registry::class, '.workflow.registry') - ->deprecate('symfony/workflow', '6.2', 'The "%alias_id%" alias is deprecated, inject the workflow directly.') - ->alias('workflow.registry', '.workflow.registry') - ->deprecate('symfony/workflow', '6.2', 'The "%alias_id%" alias is deprecated, inject the workflow directly.') ->set('workflow.security.expression_language', ExpressionLanguage::class) ; }; diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/AbstractControllerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/AbstractControllerTest.php index efa9c7becab59..14e5abd0115d0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/AbstractControllerTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/AbstractControllerTest.php @@ -471,58 +471,6 @@ public function testRenderWithFormSubmittedAndInvalid() $this->assertSame('bar', $response->getContent()); } - /** - * @group legacy - */ - public function testRenderForm() - { - $formView = new FormView(); - - $form = $this->getMockBuilder(FormInterface::class)->getMock(); - $form->expects($this->once())->method('createView')->willReturn($formView); - - $twig = $this->getMockBuilder(Environment::class)->disableOriginalConstructor()->getMock(); - $twig->expects($this->once())->method('render')->with('foo', ['bar' => $formView])->willReturn('bar'); - - $container = new Container(); - $container->set('twig', $twig); - - $controller = $this->createController(); - $controller->setContainer($container); - - $response = $controller->renderForm('foo', ['bar' => $form]); - - $this->assertTrue($response->isSuccessful()); - $this->assertSame('bar', $response->getContent()); - } - - /** - * @group legacy - */ - public function testRenderFormSubmittedAndInvalid() - { - $formView = new FormView(); - - $form = $this->getMockBuilder(FormInterface::class)->getMock(); - $form->expects($this->once())->method('createView')->willReturn($formView); - $form->expects($this->once())->method('isSubmitted')->willReturn(true); - $form->expects($this->once())->method('isValid')->willReturn(false); - - $twig = $this->getMockBuilder(Environment::class)->disableOriginalConstructor()->getMock(); - $twig->expects($this->once())->method('render')->with('foo', ['bar' => $formView])->willReturn('bar'); - - $container = new Container(); - $container->set('twig', $twig); - - $controller = $this->createController(); - $controller->setContainer($container); - - $response = $controller->renderForm('foo', ['bar' => $form]); - - $this->assertSame(422, $response->getStatusCode()); - $this->assertSame('bar', $response->getContent()); - } - public function testStreamTwig() { $twig = $this->createMock(Environment::class); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php index e3ecd982d3cc8..2e291157abcbd 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php @@ -676,7 +676,6 @@ class_exists(SemaphoreStore::class) && SemaphoreStore::isSupported() ? 'semaphor ], 'default_bus' => null, 'buses' => ['messenger.bus.default' => ['default_middleware' => ['enabled' => true, 'allow_no_handlers' => false, 'allow_no_senders' => true], 'middleware' => []]], - 'reset_on_message' => true, 'stop_worker_on_signals' => [], ], 'disallow_search_engine_index' => true, diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_with_disabled_reset_on_message.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_with_disabled_reset_on_message.php deleted file mode 100644 index 3cb006c46750b..0000000000000 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_with_disabled_reset_on_message.php +++ /dev/null @@ -1,20 +0,0 @@ -loadFromExtension('framework', [ - 'http_method_override' => false, - 'messenger' => [ - 'reset_on_message' => false, - 'routing' => [ - FooMessage::class => ['sender.bar', 'sender.biz'], - BarMessage::class => 'sender.foo', - ], - 'transports' => [ - 'sender.biz' => 'null://', - 'sender.bar' => 'null://', - 'sender.foo' => 'null://', - ], - ], -]); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_with_explict_reset_on_message_legacy.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_with_explict_reset_on_message_legacy.php deleted file mode 100644 index ee689ae0932db..0000000000000 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_with_explict_reset_on_message_legacy.php +++ /dev/null @@ -1,20 +0,0 @@ -loadFromExtension('framework', [ - 'http_method_override' => false, - 'messenger' => [ - 'reset_on_message' => true, - 'routing' => [ - FooMessage::class => ['sender.bar', 'sender.biz'], - BarMessage::class => 'sender.foo', - ], - 'transports' => [ - 'sender.biz' => 'null://', - 'sender.bar' => 'null://', - 'sender.foo' => 'null://', - ], - ], -]); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/exceptions_legacy.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/exceptions_legacy.xml deleted file mode 100644 index 2e6048fa7c7aa..0000000000000 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/exceptions_legacy.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_with_disabled_reset_on_message.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_with_disabled_reset_on_message.xml deleted file mode 100644 index c0bc33bcde151..0000000000000 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_with_disabled_reset_on_message.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_with_explict_reset_on_message_legacy.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_with_explict_reset_on_message_legacy.xml deleted file mode 100644 index 4c208aad2f0b2..0000000000000 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_with_explict_reset_on_message_legacy.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php index 97831b04e7773..968195153f38e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php @@ -14,7 +14,6 @@ use Doctrine\Common\Annotations\Annotation; use Psr\Cache\CacheItemPoolInterface; use Psr\Log\LoggerAwareInterface; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddAnnotationsCachedReaderPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\FrameworkExtension; use Symfony\Bundle\FrameworkBundle\FrameworkBundle; @@ -93,8 +92,6 @@ abstract class FrameworkExtensionTestCase extends TestCase { - use ExpectDeprecationTrait; - private static $containerCache = []; abstract protected function loadFromFile(ContainerBuilder $container, $file); @@ -507,7 +504,7 @@ public function testWorkflowServicesCanBeEnabled() { $container = $this->createContainerFromFile('workflows_enabled'); - $this->assertTrue($container->has(Workflow\Registry::class)); + $this->assertTrue($container->hasDefinition('.workflow.registry')); $this->assertTrue($container->hasDefinition('console.command.workflow_dump')); } @@ -791,26 +788,6 @@ public function testMessengerServicesRemovedWhenDisabled() $this->assertFalse($container->hasDefinition('cache.messenger.restart_workers_signal')); } - /** - * @group legacy - */ - public function testMessengerWithExplictResetOnMessageLegacy() - { - $this->expectDeprecation('Since symfony/framework-bundle 6.1: Option "reset_on_message" at "framework.messenger" is deprecated. It does nothing and will be removed in version 7.0.'); - - $container = $this->createContainerFromFile('messenger_with_explict_reset_on_message_legacy'); - - $this->assertTrue($container->hasDefinition('console.command.messenger_consume_messages')); - $this->assertTrue($container->hasAlias('messenger.default_bus')); - $this->assertTrue($container->getAlias('messenger.default_bus')->isPublic()); - $this->assertTrue($container->hasDefinition('messenger.transport.amqp.factory')); - $this->assertTrue($container->hasDefinition('messenger.transport.redis.factory')); - $this->assertTrue($container->hasDefinition('messenger.transport_factory')); - $this->assertSame(TransportFactory::class, $container->getDefinition('messenger.transport_factory')->getClass()); - $this->assertTrue($container->hasDefinition('messenger.listener.reset_services')); - $this->assertSame('messenger.listener.reset_services', (string) $container->getDefinition('console.command.messenger_consume_messages')->getArgument(5)); - } - public function testMessenger() { $container = $this->createContainerFromFile('messenger', [], true, false); @@ -1117,17 +1094,6 @@ public function testMessengerInvalidWildcardRouting() $this->createContainerFromFile('messenger_routing_invalid_transport'); } - /** - * @group legacy - */ - public function testMessengerWithDisabledResetOnMessage() - { - $this->expectException(InvalidConfigurationException::class); - $this->expectExceptionMessage('The "framework.messenger.reset_on_message" configuration option can be set to "true" only. To prevent services resetting after each message you can set the "--no-reset" option in "messenger:consume" command.'); - - $this->createContainerFromFile('messenger_with_disabled_reset_on_message'); - } - public function testTranslator() { $container = $this->createContainerFromFile('full'); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/XmlFrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/XmlFrameworkExtensionTest.php index 36d3f5e379d3e..40b3588d77a1c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/XmlFrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/XmlFrameworkExtensionTest.php @@ -33,40 +33,6 @@ public function testMessengerMiddlewareFactoryErroneousFormat() $this->markTestSkipped('XML configuration will not allow erroneous format.'); } - public function testLegacyExceptionsConfig() - { - $container = $this->createContainerFromFile('exceptions_legacy'); - - $configuration = $container->getDefinition('exception_listener')->getArgument(3); - - $this->assertSame([ - \Symfony\Component\HttpKernel\Exception\BadRequestHttpException::class, - \Symfony\Component\HttpKernel\Exception\NotFoundHttpException::class, - \Symfony\Component\HttpKernel\Exception\ConflictHttpException::class, - \Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException::class, - ], array_keys($configuration)); - - $this->assertEqualsCanonicalizing([ - 'log_level' => 'info', - 'status_code' => 422, - ], $configuration[\Symfony\Component\HttpKernel\Exception\BadRequestHttpException::class]); - - $this->assertEqualsCanonicalizing([ - 'log_level' => 'info', - 'status_code' => null, - ], $configuration[\Symfony\Component\HttpKernel\Exception\NotFoundHttpException::class]); - - $this->assertEqualsCanonicalizing([ - 'log_level' => 'info', - 'status_code' => null, - ], $configuration[\Symfony\Component\HttpKernel\Exception\ConflictHttpException::class]); - - $this->assertEqualsCanonicalizing([ - 'log_level' => null, - 'status_code' => 500, - ], $configuration[\Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException::class]); - } - public function testRateLimiter() { $container = $this->createContainerFromFile('rate_limiter'); diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index 722a4c5f10243..069dcc7b4dec9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -22,7 +22,6 @@ "symfony/cache": "^6.4|^7.0", "symfony/config": "^6.4|^7.0", "symfony/dependency-injection": "^6.4|^7.0", - "symfony/deprecation-contracts": "^2.5|^3", "symfony/error-handler": "^6.4|^7.0", "symfony/event-dispatcher": "^6.4|^7.0", "symfony/http-foundation": "^6.4|^7.0", diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php index cc93d323df7e9..10ceb6826f4f3 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php @@ -12,7 +12,6 @@ namespace Symfony\Bundle\SecurityBundle\Tests\DependencyInjection; use PHPUnit\Framework\TestCase; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\AuthenticatorFactoryInterface; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\FirewallListenerFactoryInterface; use Symfony\Bundle\SecurityBundle\DependencyInjection\SecurityExtension; @@ -40,8 +39,6 @@ class SecurityExtensionTest extends TestCase { - use ExpectDeprecationTrait; - public function testInvalidCheckPath() { $this->expectException(InvalidConfigurationException::class); diff --git a/src/Symfony/Bundle/TwigBundle/CHANGELOG.md b/src/Symfony/Bundle/TwigBundle/CHANGELOG.md index ba5a3f08850d8..1b2f57f979f52 100644 --- a/src/Symfony/Bundle/TwigBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/TwigBundle/CHANGELOG.md @@ -1,6 +1,14 @@ CHANGELOG ========= +7.0 +--- + + * Remove the `Twig_Environment` autowiring alias, use `Twig\Environment` instead + * Remove option `twig.autoescape`; create a class that implements your escaping strategy + (check `FileExtensionEscapingStrategy::guess()` for inspiration) and reference it using + the `twig.autoescape_service` option instead + 6.3 --- diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php index 4712b18a6ac1b..e5e3310eeddb5 100644 --- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php @@ -127,10 +127,6 @@ private function addTwigOptions(ArrayNodeDefinition $rootNode): void $rootNode ->fixXmlConfig('path') ->children() - ->variableNode('autoescape') - ->defaultValue('name') - ->setDeprecated('symfony/twig-bundle', '6.1', 'Option "%node%" at "%path%" is deprecated, use autoescape_service[_method] instead.') - ->end() ->scalarNode('autoescape_service')->defaultNull()->end() ->scalarNode('autoescape_service_method')->defaultNull()->end() ->scalarNode('base_template_class')->example('Twig\Template')->cannotBeEmpty()->end() diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php index f606e7ae4b591..73a069e5df7a9 100644 --- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php +++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php @@ -150,6 +150,8 @@ public function load(array $configs, ContainerBuilder $container): void if (isset($config['autoescape_service']) && isset($config['autoescape_service_method'])) { $config['autoescape'] = [new Reference($config['autoescape_service']), $config['autoescape_service_method']]; + } else { + $config['autoescape'] = 'name'; } $container->getDefinition('twig')->replaceArgument(1, array_intersect_key($config, [ diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/schema/twig-1.0.xsd b/src/Symfony/Bundle/TwigBundle/Resources/config/schema/twig-1.0.xsd index 50eff2bc29923..05f949e943ab2 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/config/schema/twig-1.0.xsd +++ b/src/Symfony/Bundle/TwigBundle/Resources/config/schema/twig-1.0.xsd @@ -18,7 +18,6 @@ - diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.php b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.php index 6525d875a5737..002d284f87727 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.php +++ b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.php @@ -66,9 +66,6 @@ ->tag('container.preload', ['class' => ExtensionSet::class]) ->tag('container.preload', ['class' => Template::class]) ->tag('container.preload', ['class' => TemplateWrapper::class]) - - ->alias('Twig_Environment', 'twig') - ->deprecate('symfony/twig-bundle', '6.3', 'The "%alias_id%" service alias is deprecated, use "'.Environment::class.'" or "twig" instead.') ->alias(Environment::class, 'twig') ->set('twig.app_variable', AppVariable::class) diff --git a/src/Symfony/Component/Config/CHANGELOG.md b/src/Symfony/Component/Config/CHANGELOG.md index 094d5abba0637..51e2d1fee567b 100644 --- a/src/Symfony/Component/Config/CHANGELOG.md +++ b/src/Symfony/Component/Config/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +7.0 +--- + + * Require explicit argument when calling `NodeBuilder::setParent()` + 6.3 --- diff --git a/src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php b/src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php index 7cda0bc7d8b1e..49b73c8045868 100644 --- a/src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php +++ b/src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php @@ -39,11 +39,8 @@ public function __construct() * * @return $this */ - public function setParent(ParentNodeDefinitionInterface $parent = null): static + public function setParent(?ParentNodeDefinitionInterface $parent): static { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/form', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } $this->parent = $parent; return $this; diff --git a/src/Symfony/Component/Config/Resource/ReflectionClassResource.php b/src/Symfony/Component/Config/Resource/ReflectionClassResource.php index dbd47e66de25c..dbc927b592041 100644 --- a/src/Symfony/Component/Config/Resource/ReflectionClassResource.php +++ b/src/Symfony/Component/Config/Resource/ReflectionClassResource.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Config\Resource; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Symfony\Component\Messenger\Handler\MessageSubscriberInterface; use Symfony\Contracts\Service\ServiceSubscriberInterface; /** @@ -191,13 +190,6 @@ private function generateSignature(\ReflectionClass $class): iterable yield print_r($class->name::getSubscribedEvents(), true); } - if (interface_exists(MessageSubscriberInterface::class, false) && $class->isSubclassOf(MessageSubscriberInterface::class)) { - yield MessageSubscriberInterface::class; - foreach ($class->name::getHandledMessages() as $key => $value) { - yield $key.print_r($value, true); - } - } - if (interface_exists(ServiceSubscriberInterface::class, false) && $class->isSubclassOf(ServiceSubscriberInterface::class)) { yield ServiceSubscriberInterface::class; yield print_r($class->name::getSubscribedServices(), true); diff --git a/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php index ef7a9b420fbdd..fa12c4cf78ca7 100644 --- a/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php @@ -14,7 +14,6 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Config\Resource\ReflectionClassResource; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Symfony\Component\Messenger\Handler\MessageSubscriberInterface; use Symfony\Contracts\Service\ServiceSubscriberInterface; class ReflectionClassResourceTest extends TestCase @@ -175,27 +174,6 @@ public function testEventSubscriber() $this->assertTrue($res->isFresh(0)); } - /** - * @group legacy - */ - public function testMessageSubscriber() - { - $res = new ReflectionClassResource(new \ReflectionClass(TestMessageSubscriber::class)); - $this->assertTrue($res->isFresh(0)); - - TestMessageSubscriberConfigHolder::$handledMessages = ['SomeMessageClass' => []]; - $this->assertFalse($res->isFresh(0)); - - $res = new ReflectionClassResource(new \ReflectionClass(TestMessageSubscriber::class)); - $this->assertTrue($res->isFresh(0)); - - TestMessageSubscriberConfigHolder::$handledMessages = ['OtherMessageClass' => []]; - $this->assertFalse($res->isFresh(0)); - - $res = new ReflectionClassResource(new \ReflectionClass(TestMessageSubscriber::class)); - $this->assertTrue($res->isFresh(0)); - } - public function testServiceSubscriber() { $res = new ReflectionClassResource(new \ReflectionClass(TestServiceSubscriber::class)); @@ -232,22 +210,6 @@ public static function getSubscribedEvents(): array } } -if (interface_exists(MessageSubscriberInterface::class)) { - class TestMessageSubscriber implements MessageSubscriberInterface - { - public static function getHandledMessages(): iterable - { - foreach (TestMessageSubscriberConfigHolder::$handledMessages as $key => $subscribedMessage) { - yield $key => $subscribedMessage; - } - } - } - class TestMessageSubscriberConfigHolder - { - public static $handledMessages = []; - } -} - class TestServiceSubscriber implements ServiceSubscriberInterface { public static $subscribedServices = []; diff --git a/src/Symfony/Component/Console/CHANGELOG.md b/src/Symfony/Component/Console/CHANGELOG.md index 1406d75f6970b..fe4425a9a2848 100644 --- a/src/Symfony/Component/Console/CHANGELOG.md +++ b/src/Symfony/Component/Console/CHANGELOG.md @@ -6,7 +6,7 @@ CHANGELOG * Add method `__toString()` to `InputInterface` * Remove `Command::$defaultName` and `Command::$defaultDescription`, use the `AsCommand` attribute instead - * Passing null to `*Command::setApplication()`, `*FormatterStyle::setForeground/setBackground()`, `Helper::setHelpSet()`, `Input*::setDefault()` and `Question::setAutocompleterCallback/setValidator()` must be done explicitly + * Require explicit argument when calling `*Command::setApplication()`, `*FormatterStyle::setForeground/setBackground()`, `Helper::setHelpSet()`, `Input*::setDefault()` and `Question::setAutocompleterCallback/setValidator()` * Remove `StringInput::REGEX_STRING` 6.4 diff --git a/src/Symfony/Component/Console/Tests/Command/CommandTest.php b/src/Symfony/Component/Console/Tests/Command/CommandTest.php index 48ba927063c77..6c1c60d776cce 100644 --- a/src/Symfony/Component/Console/Tests/Command/CommandTest.php +++ b/src/Symfony/Component/Console/Tests/Command/CommandTest.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Console\Tests\Command; use PHPUnit\Framework\TestCase; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\Console\Application; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; @@ -29,8 +28,6 @@ class CommandTest extends TestCase { - use ExpectDeprecationTrait; - protected static $fixturesPath; public static function setUpBeforeClass(): void diff --git a/src/Symfony/Component/Console/composer.json b/src/Symfony/Component/Console/composer.json index ef0925176bbf9..5ca14fd4c4a9b 100644 --- a/src/Symfony/Component/Console/composer.json +++ b/src/Symfony/Component/Console/composer.json @@ -17,7 +17,6 @@ ], "require": { "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0", "symfony/service-contracts": "^2.5|^3", "symfony/string": "^6.4|^7.0" diff --git a/src/Symfony/Component/DependencyInjection/CHANGELOG.md b/src/Symfony/Component/DependencyInjection/CHANGELOG.md index ad4e39a4524a3..e11f32348e2c8 100644 --- a/src/Symfony/Component/DependencyInjection/CHANGELOG.md +++ b/src/Symfony/Component/DependencyInjection/CHANGELOG.md @@ -8,7 +8,7 @@ CHANGELOG * Remove `ProxyHelper`, use `Symfony\Component\VarExporter\ProxyHelper` instead * Remove `ReferenceSetArgumentTrait` * Remove support of `@required` annotation, use the `Symfony\Contracts\Service\Attribute\Required` attribute instead - * Passing `null` to `ContainerAwareTrait::setContainer()` must be done explicitly + * Require explicit argument when calling `ContainerAwareTrait::setContainer()` * Remove `PhpDumper` options `inline_factories_parameter` and `inline_class_loader_parameter`, use options `inline_factories` and `inline_class_loader` instead * Parameter names of `ParameterBag` cannot be numerics * Remove `ContainerAwareInterface` and `ContainerAwareTrait`, use dependency injection instead diff --git a/src/Symfony/Component/DependencyInjection/Compiler/RegisterServiceSubscribersPass.php b/src/Symfony/Component/DependencyInjection/Compiler/RegisterServiceSubscribersPass.php index 089da1e79e0fb..75726d3700d89 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/RegisterServiceSubscribersPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/RegisterServiceSubscribersPass.php @@ -12,14 +12,12 @@ namespace Symfony\Component\DependencyInjection\Compiler; use Psr\Container\ContainerInterface as PsrContainerInterface; -use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\DependencyInjection\Argument\BoundArgument; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\TypedReference; -use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Contracts\Service\Attribute\SubscribedService; use Symfony\Contracts\Service\ServiceProviderInterface; use Symfony\Contracts\Service\ServiceSubscriberInterface; @@ -71,8 +69,6 @@ protected function processValue(mixed $value, bool $isRoot = false): mixed throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $this->currentId, ServiceSubscriberInterface::class)); } $class = $r->name; - // to remove when symfony/dependency-injection will stop being compatible with symfony/framework-bundle<6.0 - $replaceDeprecatedSession = $this->container->has('.session.deprecated') && $r->isSubclassOf(AbstractController::class); $subscriberMap = []; foreach ($class::getSubscribedServices() as $key => $type) { @@ -99,11 +95,6 @@ protected function processValue(mixed $value, bool $isRoot = false): mixed if (!$autowire) { throw new InvalidArgumentException(sprintf('Service "%s" misses a "container.service_subscriber" tag with "key"/"id" attributes corresponding to entry "%s" as returned by "%s::getSubscribedServices()".', $this->currentId, $key, $class)); } - if ($replaceDeprecatedSession && SessionInterface::class === $type) { - // This prevents triggering the deprecation when building the container - // to remove when symfony/dependency-injection will stop being compatible with symfony/framework-bundle<6.0 - $type = '.session.deprecated'; - } $serviceMap[$key] = new Reference($type); } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveBindingsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveBindingsPassTest.php index 544322ba3348e..c67ce1994a91e 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveBindingsPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveBindingsPassTest.php @@ -12,7 +12,6 @@ namespace Symfony\Component\DependencyInjection\Tests\Compiler; use PHPUnit\Framework\TestCase; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\DependencyInjection\Argument\BoundArgument; use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; @@ -38,8 +37,6 @@ class ResolveBindingsPassTest extends TestCase { - use ExpectDeprecationTrait; - public function testProcess() { $container = new ContainerBuilder(); diff --git a/src/Symfony/Component/ErrorHandler/Resources/bin/patch-type-declarations b/src/Symfony/Component/ErrorHandler/Resources/bin/patch-type-declarations index f24c99689706b..5be1db42f6dca 100755 --- a/src/Symfony/Component/ErrorHandler/Resources/bin/patch-type-declarations +++ b/src/Symfony/Component/ErrorHandler/Resources/bin/patch-type-declarations @@ -19,7 +19,7 @@ if (\in_array('-h', $argv) || \in_array('--help', $argv)) { ' Patches type declarations based on "@return" PHPDoc and triggers deprecations for', ' incompatible method declarations.', '', - ' This assists you to make your package compatible with Symfony 6, but it can be used', + ' This assists you to make your package compatible with Symfony 7, but it can be used', ' for any class/package.', '', ' Available configuration via environment variables:', diff --git a/src/Symfony/Component/Form/Button.php b/src/Symfony/Component/Form/Button.php index 00373b3770452..67772ccfe1c6b 100644 --- a/src/Symfony/Component/Form/Button.php +++ b/src/Symfony/Component/Form/Button.php @@ -81,11 +81,8 @@ public function offsetUnset(mixed $offset): void throw new BadMethodCallException('Buttons cannot have children.'); } - public function setParent(FormInterface $parent = null): static + public function setParent(?FormInterface $parent): static { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/form', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } if ($this->submitted) { throw new AlreadySubmittedException('You cannot set the parent of a submitted button.'); } diff --git a/src/Symfony/Component/Form/ButtonBuilder.php b/src/Symfony/Component/Form/ButtonBuilder.php index 20a30968d402e..2c8c12ce23d45 100644 --- a/src/Symfony/Component/Form/ButtonBuilder.php +++ b/src/Symfony/Component/Form/ButtonBuilder.php @@ -220,12 +220,8 @@ public function setAttributes(array $attributes): static * * @throws BadMethodCallException */ - public function setDataMapper(DataMapperInterface $dataMapper = null): static + public function setDataMapper(?DataMapperInterface $dataMapper): static { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/form', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } - throw new BadMethodCallException('Buttons do not support data mappers.'); } diff --git a/src/Symfony/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md index 22597f3b47215..73c85c2271d51 100644 --- a/src/Symfony/Component/Form/CHANGELOG.md +++ b/src/Symfony/Component/Form/CHANGELOG.md @@ -1,6 +1,14 @@ CHANGELOG ========= +7.0 +--- + + * Throw when using `DateTime` or `DateTimeImmutable` model data with a different timezone than configured with the + `model_timezone` option in `DateType`, `DateTimeType`, and `TimeType` + * Make the "widget" option of date/time form types default to "single_text" + * Require explicit argument when calling `Button/Form::setParent()`, `ButtonBuilder/FormConfigBuilder::setDataMapper()`, `TransformationFailedException::setInvalidMessage()` + 6.4 --- diff --git a/src/Symfony/Component/Form/Exception/TransformationFailedException.php b/src/Symfony/Component/Form/Exception/TransformationFailedException.php index 409b51517a674..ceb01f1a9a1b1 100644 --- a/src/Symfony/Component/Form/Exception/TransformationFailedException.php +++ b/src/Symfony/Component/Form/Exception/TransformationFailedException.php @@ -34,11 +34,8 @@ public function __construct(string $message = '', int $code = 0, \Throwable $pre * @param string|null $invalidMessage The message or message key * @param array $invalidMessageParameters Data to be passed into the translator */ - public function setInvalidMessage(string $invalidMessage = null, array $invalidMessageParameters = []): void + public function setInvalidMessage(?string $invalidMessage, array $invalidMessageParameters = []): void { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/form', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } $this->invalidMessage = $invalidMessage; $this->invalidMessageParameters = $invalidMessageParameters; } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php b/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php index 9ec4c9cca4739..73ae5708c9236 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php @@ -206,8 +206,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) } if ($date->getTimezone()->getName() !== $options['model_timezone']) { - trigger_deprecation('symfony/form', '6.4', sprintf('Using a "%s" instance with a timezone ("%s") not matching the configured model timezone "%s" is deprecated.', $date::class, $date->getTimezone()->getName(), $options['model_timezone'])); - // throw new LogicException(sprintf('Using a "%s" instance with a timezone ("%s") not matching the configured model timezone "%s" is not supported.', $date::class, $date->getTimezone()->getName(), $options['model_timezone'])); + throw new LogicException(sprintf('Using a "%s" instance with a timezone ("%s") not matching the configured model timezone "%s" is not supported.', get_debug_type($date), $date->getTimezone()->getName(), $options['model_timezone'])); } }); } @@ -335,8 +334,7 @@ public function configureOptions(OptionsResolver $resolver) throw new LogicException(sprintf('Cannot use the "time_widget" option of the "%s" when the "widget" option is set to "single_text".', self::class)); } } elseif (null === $widget && null === $options['date_widget'] && null === $options['time_widget']) { - trigger_deprecation('symfony/form', '6.3', 'Not configuring the "widget" option of form type "datetime" is deprecated. It will default to "single_text" in Symfony 7.0.'); - // return 'single_text'; + return 'single_text'; } return $widget; diff --git a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php index 480afc315f2ad..d204a914bd5aa 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php @@ -190,8 +190,7 @@ class_exists(\IntlTimeZone::class, false) ? \IntlTimeZone::createDefault() : nul } if ($date->getTimezone()->getName() !== $options['model_timezone']) { - trigger_deprecation('symfony/form', '6.4', sprintf('Using a "%s" instance with a timezone ("%s") not matching the configured model timezone "%s" is deprecated.', $date::class, $date->getTimezone()->getName(), $options['model_timezone'])); - // throw new LogicException(sprintf('Using a "%s" instance with a timezone ("%s") not matching the configured model timezone "%s" is not supported.', $date::class, $date->getTimezone()->getName(), $options['model_timezone'])); + throw new LogicException(sprintf('Using a "%s" instance with a timezone ("%s") not matching the configured model timezone "%s" is not supported.', get_debug_type($date), $date->getTimezone()->getName(), $options['model_timezone'])); } }); } @@ -286,11 +285,7 @@ public function configureOptions(OptionsResolver $resolver) 'years' => range((int) date('Y') - 5, (int) date('Y') + 5), 'months' => range(1, 12), 'days' => range(1, 31), - 'widget' => static function (Options $options) { - trigger_deprecation('symfony/form', '6.3', 'Not configuring the "widget" option of form type "date" is deprecated. It will default to "single_text" in Symfony 7.0.'); - - return 'choice'; - }, + 'widget' => 'single_text', 'input' => 'datetime', 'format' => $format, 'model_timezone' => null, diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php b/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php index 623259f17a001..7788290d7a4ae 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php @@ -218,8 +218,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) } if ($date->getTimezone()->getName() !== $options['model_timezone']) { - trigger_deprecation('symfony/form', '6.4', sprintf('Using a "%s" instance with a timezone ("%s") not matching the configured model timezone "%s" is deprecated.', $date::class, $date->getTimezone()->getName(), $options['model_timezone'])); - // throw new LogicException(sprintf('Using a "%s" instance with a timezone ("%s") not matching the configured model timezone "%s" is not supported.', $date::class, $date->getTimezone()->getName(), $options['model_timezone'])); + throw new LogicException(sprintf('Using a "%s" instance with a timezone ("%s") not matching the configured model timezone "%s" is not supported.', get_debug_type($date), $date->getTimezone()->getName(), $options['model_timezone'])); } }); } @@ -327,11 +326,7 @@ public function configureOptions(OptionsResolver $resolver) 'hours' => range(0, 23), 'minutes' => range(0, 59), 'seconds' => range(0, 59), - 'widget' => static function (Options $options) { - trigger_deprecation('symfony/form', '6.3', 'Not configuring the "widget" option of form type "time" is deprecated. It will default to "single_text" in Symfony 7.0.'); - - return 'choice'; - }, + 'widget' => 'single_text', 'input' => 'datetime', 'input_format' => 'H:i:s', 'with_minutes' => true, diff --git a/src/Symfony/Component/Form/Form.php b/src/Symfony/Component/Form/Form.php index a4b76506a2f91..5c86d27b56f64 100644 --- a/src/Symfony/Component/Form/Form.php +++ b/src/Symfony/Component/Form/Form.php @@ -218,12 +218,8 @@ public function isDisabled(): bool return true; } - public function setParent(FormInterface $parent = null): static + public function setParent(?FormInterface $parent): static { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/form', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } - if ($this->submitted) { throw new AlreadySubmittedException('You cannot set the parent of a submitted form.'); } diff --git a/src/Symfony/Component/Form/FormConfigBuilder.php b/src/Symfony/Component/Form/FormConfigBuilder.php index 9fed3d1a0a5f4..29e643680e5b8 100644 --- a/src/Symfony/Component/Form/FormConfigBuilder.php +++ b/src/Symfony/Component/Form/FormConfigBuilder.php @@ -347,11 +347,8 @@ public function setAttributes(array $attributes): static /** * @return $this */ - public function setDataMapper(DataMapperInterface $dataMapper = null): static + public function setDataMapper(?DataMapperInterface $dataMapper): static { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/form', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } if ($this->locked) { throw new BadMethodCallException('FormConfigBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.'); } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php index 71020a06b9b44..eb6538e6a6d7d 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php @@ -11,14 +11,12 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; +use Symfony\Component\Form\Exception\LogicException; use Symfony\Component\Form\FormError; use Symfony\Component\Form\FormInterface; class DateTimeTypeTest extends BaseTypeTestCase { - use ExpectDeprecationTrait; - public const TESTED_TYPE = 'Symfony\Component\Form\Extension\Core\Type\DateTimeType'; private $defaultLocale; @@ -751,28 +749,20 @@ public function testSubmitStringWithCustomInputFormat() $this->assertSame('14/01/2018 21:29:00 +00:00', $form->getData()); } - /** - * @group legacy - */ public function testDateTimeInputTimezoneNotMatchingModelTimezone() { - $this->expectDeprecation('Since symfony/form 6.4: Using a "DateTime" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is deprecated.'); - // $this->expectException(LogicException::class); - // $this->expectExceptionMessage('Using a "DateTime" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is not supported.'); + $this->expectException(LogicException::class); + $this->expectExceptionMessage('Using a "DateTime" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is not supported.'); $this->factory->create(static::TESTED_TYPE, new \DateTime('now', new \DateTimeZone('UTC')), [ 'model_timezone' => 'Europe/Berlin', ]); } - /** - * @group legacy - */ public function testDateTimeImmutableInputTimezoneNotMatchingModelTimezone() { - $this->expectDeprecation('Since symfony/form 6.4: Using a "DateTimeImmutable" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is deprecated.'); - // $this->expectException(LogicException::class); - // $this->expectExceptionMessage('Using a "DateTimeImmutable" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is not supported.'); + $this->expectException(LogicException::class); + $this->expectExceptionMessage('Using a "DateTimeImmutable" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is not supported.'); $this->factory->create(static::TESTED_TYPE, new \DateTimeImmutable('now', new \DateTimeZone('UTC')), [ 'input' => 'datetime_immutable', diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php index bb171ffe88735..976836553e9ee 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php @@ -11,8 +11,8 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\Form\ChoiceList\View\ChoiceView; +use Symfony\Component\Form\Exception\LogicException; use Symfony\Component\Form\FormError; use Symfony\Component\Form\FormInterface; use Symfony\Component\Intl\Util\IntlTestHelper; @@ -20,8 +20,6 @@ class DateTypeTest extends BaseTypeTestCase { - use ExpectDeprecationTrait; - public const TESTED_TYPE = 'Symfony\Component\Form\Extension\Core\Type\DateType'; private $defaultTimezone; @@ -1115,28 +1113,20 @@ public function testSubmitStringWithCustomInputFormat() $this->assertSame('14/01/2018', $form->getData()); } - /** - * @group legacy - */ public function testDateTimeInputTimezoneNotMatchingModelTimezone() { - $this->expectDeprecation('Since symfony/form 6.4: Using a "DateTime" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is deprecated.'); - // $this->expectException(LogicException::class); - // $this->expectExceptionMessage('Using a "DateTime" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is not supported.'); + $this->expectException(LogicException::class); + $this->expectExceptionMessage('Using a "DateTime" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is not supported.'); $this->factory->create(static::TESTED_TYPE, new \DateTime('now', new \DateTimeZone('UTC')), [ 'model_timezone' => 'Europe/Berlin', ]); } - /** - * @group legacy - */ public function testDateTimeImmutableInputTimezoneNotMatchingModelTimezone() { - $this->expectDeprecation('Since symfony/form 6.4: Using a "DateTimeImmutable" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is deprecated.'); - // $this->expectException(LogicException::class); - // $this->expectExceptionMessage('Using a "DateTimeImmutable" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is not supported.'); + $this->expectException(LogicException::class); + $this->expectExceptionMessage('Using a "DateTimeImmutable" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is not supported.'); $this->factory->create(static::TESTED_TYPE, new \DateTimeImmutable('now', new \DateTimeZone('UTC')), [ 'input' => 'datetime_immutable', diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php index 3e8e42f4a8f7a..155657038f29e 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\Form\ChoiceList\View\ChoiceView; use Symfony\Component\Form\Exception\InvalidConfigurationException; use Symfony\Component\Form\Exception\LogicException; @@ -21,8 +20,6 @@ class TimeTypeTest extends BaseTypeTestCase { - use ExpectDeprecationTrait; - public const TESTED_TYPE = 'Symfony\Component\Form\Extension\Core\Type\TimeType'; public function testSubmitDateTime() @@ -1164,28 +1161,20 @@ public static function provideEmptyData() ]; } - /** - * @group legacy - */ public function testDateTimeInputTimezoneNotMatchingModelTimezone() { - $this->expectDeprecation('Since symfony/form 6.4: Using a "DateTime" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is deprecated.'); - // $this->expectException(LogicException::class); - // $this->expectExceptionMessage('Using a "DateTime" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is not supported.'); + $this->expectException(LogicException::class); + $this->expectExceptionMessage('Using a "DateTime" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is not supported.'); $this->factory->create(static::TESTED_TYPE, new \DateTime('now', new \DateTimeZone('UTC')), [ 'model_timezone' => 'Europe/Berlin', ]); } - /** - * @group legacy - */ public function testDateTimeImmutableInputTimezoneNotMatchingModelTimezone() { - $this->expectDeprecation('Since symfony/form 6.4: Using a "DateTimeImmutable" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is deprecated.'); - // $this->expectException(LogicException::class); - // $this->expectExceptionMessage('Using a "DateTimeImmutable" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is not supported.'); + $this->expectException(LogicException::class); + $this->expectExceptionMessage('Using a "DateTimeImmutable" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is not supported.'); $this->factory->create(static::TESTED_TYPE, new \DateTimeImmutable('now', new \DateTimeZone('UTC')), [ 'input' => 'datetime_immutable', diff --git a/src/Symfony/Component/Form/composer.json b/src/Symfony/Component/Form/composer.json index 7ee167817f352..914ddc6c52b32 100644 --- a/src/Symfony/Component/Form/composer.json +++ b/src/Symfony/Component/Form/composer.json @@ -17,7 +17,6 @@ ], "require": { "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3", "symfony/event-dispatcher": "^6.4|^7.0", "symfony/options-resolver": "^6.4|^7.0", "symfony/polyfill-ctype": "~1.8", diff --git a/src/Symfony/Component/HttpFoundation/CHANGELOG.md b/src/Symfony/Component/HttpFoundation/CHANGELOG.md index 2d3669d2f0b17..ce2bdb638f0f1 100644 --- a/src/Symfony/Component/HttpFoundation/CHANGELOG.md +++ b/src/Symfony/Component/HttpFoundation/CHANGELOG.md @@ -9,6 +9,7 @@ CHANGELOG * Remove classes `RequestMatcher` and `ExpressionRequestMatcher` * Remove `Request::getContentType()`, use `Request::getContentTypeFormat()` instead * Throw an `InvalidArgumentException` when calling `Request::create()` with a malformed URI + * Require explicit argument when calling `JsonResponse::setCallback()`, `Response::setExpires/setLastModified/setEtag()`, `MockArraySessionStorage/NativeSessionStorage::setMetadataBag()`, `NativeSessionStorage::setSaveHandler()` 6.4 --- diff --git a/src/Symfony/Component/HttpFoundation/JsonResponse.php b/src/Symfony/Component/HttpFoundation/JsonResponse.php index 8dd250a369e55..62278b657ad9b 100644 --- a/src/Symfony/Component/HttpFoundation/JsonResponse.php +++ b/src/Symfony/Component/HttpFoundation/JsonResponse.php @@ -75,11 +75,8 @@ public static function fromJsonString(string $data, int $status = 200, array $he * * @throws \InvalidArgumentException When the callback name is not valid */ - public function setCallback(string $callback = null): static + public function setCallback(?string $callback): static { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/http-foundation', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } if (null !== $callback) { // partially taken from https://geekality.net/2011/08/03/valid-javascript-identifier/ // partially taken from https://github.com/willdurand/JsonpCallbackValidator diff --git a/src/Symfony/Component/HttpFoundation/Response.php b/src/Symfony/Component/HttpFoundation/Response.php index 8e09c46d46580..cff6fe40cc81f 100644 --- a/src/Symfony/Component/HttpFoundation/Response.php +++ b/src/Symfony/Component/HttpFoundation/Response.php @@ -761,11 +761,8 @@ public function getExpires(): ?\DateTimeImmutable * * @final */ - public function setExpires(\DateTimeInterface $date = null): static + public function setExpires(?\DateTimeInterface $date): static { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/http-foundation', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } if (null === $date) { $this->headers->remove('Expires'); @@ -942,11 +939,8 @@ public function getLastModified(): ?\DateTimeImmutable * * @final */ - public function setLastModified(\DateTimeInterface $date = null): static + public function setLastModified(?\DateTimeInterface $date): static { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/http-foundation', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } if (null === $date) { $this->headers->remove('Last-Modified'); @@ -980,11 +974,8 @@ public function getEtag(): ?string * * @final */ - public function setEtag(string $etag = null, bool $weak = false): static + public function setEtag(?string $etag, bool $weak = false): static { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/http-foundation', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } if (null === $etag) { $this->headers->remove('Etag'); } else { diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/MockArraySessionStorage.php b/src/Symfony/Component/HttpFoundation/Session/Storage/MockArraySessionStorage.php index d30b56d691ec0..65f06c69e4a3d 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/MockArraySessionStorage.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/MockArraySessionStorage.php @@ -192,11 +192,8 @@ public function isStarted(): bool /** * @return void */ - public function setMetadataBag(MetadataBag $bag = null) + public function setMetadataBag(?MetadataBag $bag) { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/http-foundation', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } $this->metadataBag = $bag ?? new MetadataBag(); } diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php index 7c6b6f9296c6f..e2e6f9f1f9d30 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php @@ -317,11 +317,8 @@ public function getBag(string $name): SessionBagInterface /** * @return void */ - public function setMetadataBag(MetadataBag $metaBag = null) + public function setMetadataBag(?MetadataBag $metaBag) { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/http-foundation', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } $this->metadataBag = $metaBag ?? new MetadataBag(); } @@ -396,12 +393,8 @@ public function setOptions(array $options) * * @throws \InvalidArgumentException */ - public function setSaveHandler(AbstractProxy|\SessionHandlerInterface $saveHandler = null) + public function setSaveHandler(AbstractProxy|\SessionHandlerInterface|null $saveHandler) { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/http-foundation', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } - // Wrap $saveHandler in proxy and prevent double wrapping of proxy if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) { $saveHandler = new SessionHandlerProxy($saveHandler); diff --git a/src/Symfony/Component/HttpFoundation/composer.json b/src/Symfony/Component/HttpFoundation/composer.json index ae25848cd590d..151c4133b92fd 100644 --- a/src/Symfony/Component/HttpFoundation/composer.json +++ b/src/Symfony/Component/HttpFoundation/composer.json @@ -17,7 +17,6 @@ ], "require": { "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.1", "symfony/polyfill-php83": "^1.27" }, diff --git a/src/Symfony/Component/HttpKernel/CHANGELOG.md b/src/Symfony/Component/HttpKernel/CHANGELOG.md index 3a15ecfd0d195..0f4e3482d137f 100644 --- a/src/Symfony/Component/HttpKernel/CHANGELOG.md +++ b/src/Symfony/Component/HttpKernel/CHANGELOG.md @@ -10,6 +10,7 @@ CHANGELOG * Remove `AbstractSurrogate::$phpEscapeMap` * Remove `HttpKernelInterface::MASTER_REQUEST` * Remove `terminate_on_cache_hit` option from `HttpCache` + * Require explicit argument when calling `ConfigDataCollector::setKernel()`, `RouterListener::setCurrentRequest()` 6.4 --- diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php index b3e096d11e5d5..9cb77b4cadea2 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php @@ -11,7 +11,6 @@ namespace Symfony\Component\HttpKernel\Tests\HttpCache; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -27,8 +26,6 @@ */ class HttpCacheTest extends HttpCacheTestCase { - use ExpectDeprecationTrait; - public function testTerminateDelegatesTerminationOnlyForTerminableInterface() { $storeMock = $this->getMockBuilder(StoreInterface::class) diff --git a/src/Symfony/Component/HttpKernel/Tests/KernelTest.php b/src/Symfony/Component/HttpKernel/Tests/KernelTest.php index 92cb6fcbbf985..3417565755f5c 100644 --- a/src/Symfony/Component/HttpKernel/Tests/KernelTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/KernelTest.php @@ -12,7 +12,6 @@ namespace Symfony\Component\HttpKernel\Tests; use PHPUnit\Framework\TestCase; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; diff --git a/src/Symfony/Component/Lock/composer.json b/src/Symfony/Component/Lock/composer.json index f9d53d036c667..ee8426dd3b69b 100644 --- a/src/Symfony/Component/Lock/composer.json +++ b/src/Symfony/Component/Lock/composer.json @@ -17,8 +17,7 @@ ], "require": { "php": ">=8.2", - "psr/log": "^1|^2|^3", - "symfony/deprecation-contracts": "^2.5|^3" + "psr/log": "^1|^2|^3" }, "require-dev": { "doctrine/dbal": "^3.6", diff --git a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/.gitattributes b/src/Symfony/Component/Mailer/Bridge/OhMySmtp/.gitattributes deleted file mode 100644 index 84c7add058fb5..0000000000000 --- a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/.gitattributes +++ /dev/null @@ -1,4 +0,0 @@ -/Tests export-ignore -/phpunit.xml.dist export-ignore -/.gitattributes export-ignore -/.gitignore export-ignore diff --git a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/.gitignore b/src/Symfony/Component/Mailer/Bridge/OhMySmtp/.gitignore deleted file mode 100644 index c49a5d8df5c65..0000000000000 --- a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -vendor/ -composer.lock -phpunit.xml diff --git a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/CHANGELOG.md b/src/Symfony/Component/Mailer/Bridge/OhMySmtp/CHANGELOG.md deleted file mode 100644 index e2bc1aafc7c37..0000000000000 --- a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/CHANGELOG.md +++ /dev/null @@ -1,12 +0,0 @@ -CHANGELOG -========= - -6.2 ---- - - * Deprecate the bridge in favor of the MailPace bridge - -5.4 ---- - - * Add the bridge diff --git a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/LICENSE b/src/Symfony/Component/Mailer/Bridge/OhMySmtp/LICENSE deleted file mode 100644 index 99c6bdf356ee7..0000000000000 --- a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2021-present Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/README.md b/src/Symfony/Component/Mailer/Bridge/OhMySmtp/README.md deleted file mode 100644 index c0f421db0605a..0000000000000 --- a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/README.md +++ /dev/null @@ -1,25 +0,0 @@ -OhMySMTP Bridge -=============== - -Provides [OhMySMTP](https://ohmysmtp.com) integration for Symfony Mailer. - -Configuration example: - -```env -# SMTP -MAILER_DSN=ohmysmtp+smtp://API_TOKEN@default - -# API -MAILER_DSN=ohmysmtp+api://API_TOKEN@default -``` - -where: - - `API_TOKEN` is your OhMySMTP API Token - -Resources ---------- - - * [Contributing](https://symfony.com/doc/current/contributing/index.html) - * [Report issues](https://github.com/symfony/symfony/issues) and - [send Pull Requests](https://github.com/symfony/symfony/pulls) - in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/Tests/Transport/OhMySmtpApiTransportTest.php b/src/Symfony/Component/Mailer/Bridge/OhMySmtp/Tests/Transport/OhMySmtpApiTransportTest.php deleted file mode 100644 index d7f7285cf4bc7..0000000000000 --- a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/Tests/Transport/OhMySmtpApiTransportTest.php +++ /dev/null @@ -1,164 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Mailer\Bridge\OhMySmtp\Tests\Transport; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\HttpClient\MockHttpClient; -use Symfony\Component\HttpClient\Response\MockResponse; -use Symfony\Component\Mailer\Bridge\OhMySmtp\Transport\OhMySmtpApiTransport; -use Symfony\Component\Mailer\Envelope; -use Symfony\Component\Mailer\Exception\HttpTransportException; -use Symfony\Component\Mailer\Header\TagHeader; -use Symfony\Component\Mime\Address; -use Symfony\Component\Mime\Email; -use Symfony\Contracts\HttpClient\ResponseInterface; - -/** - * @group legacy - */ -final class OhMySmtpApiTransportTest extends TestCase -{ - /** - * @dataProvider getTransportData - */ - public function testToString(OhMySmtpApiTransport $transport, string $expected) - { - $this->assertSame($expected, (string) $transport); - } - - public static function getTransportData(): array - { - return [ - [ - new OhMySmtpApiTransport('KEY'), - 'ohmysmtp+api://app.ohmysmtp.com/api/v1', - ], - [ - (new OhMySmtpApiTransport('KEY'))->setHost('example.com'), - 'ohmysmtp+api://example.com', - ], - [ - (new OhMySmtpApiTransport('KEY'))->setHost('example.com')->setPort(99), - 'ohmysmtp+api://example.com:99', - ], - ]; - } - - public function testCustomHeader() - { - $email = new Email(); - $email->getHeaders()->addTextHeader('foo', 'bar'); - $envelope = new Envelope(new Address('alice@system.com'), [new Address('bob@system.com')]); - - $transport = new OhMySmtpApiTransport('ACCESS_KEY'); - $method = new \ReflectionMethod(OhMySmtpApiTransport::class, 'getPayload'); - $payload = $method->invoke($transport, $email, $envelope); - - $this->assertArrayHasKey('Headers', $payload); - $this->assertCount(1, $payload['Headers']); - - $this->assertEquals(['Name' => 'foo', 'Value' => 'bar'], $payload['Headers'][0]); - } - - public function testSend() - { - $client = new MockHttpClient(function (string $method, string $url, array $options): ResponseInterface { - $this->assertSame('POST', $method); - $this->assertSame('https://app.ohmysmtp.com/api/v1/send', $url); - $this->assertStringContainsStringIgnoringCase('OhMySMTP-Server-Token: KEY', $options['headers'][1] ?? $options['request_headers'][1]); - - $body = json_decode($options['body'], true); - $this->assertSame('"Fabien" ', $body['from']); - $this->assertSame('"Saif Eddin" ', $body['to']); - $this->assertSame('Hello!', $body['subject']); - $this->assertSame('Hello There!', $body['textbody']); - - return new MockResponse(json_encode(['id' => 'foobar', 'status' => 'pending']), [ - 'http_code' => 200, - ]); - }); - - $transport = new OhMySmtpApiTransport('KEY', $client); - - $mail = new Email(); - $mail->subject('Hello!') - ->to(new Address('saif.gmati@symfony.com', 'Saif Eddin')) - ->from(new Address('fabpot@symfony.com', 'Fabien')) - ->text('Hello There!'); - - $message = $transport->send($mail); - - $this->assertSame('foobar', $message->getMessageId()); - } - - public function testSendThrowsForErrorResponse() - { - $client = new MockHttpClient(static fn (string $method, string $url, array $options): ResponseInterface => new MockResponse(json_encode(['error' => 'i\'m a teapot']), [ - 'http_code' => 418, - 'response_headers' => [ - 'content-type' => 'application/json', - ], - ])); - $transport = new OhMySmtpApiTransport('KEY', $client); - $transport->setPort(8984); - - $mail = new Email(); - $mail->subject('Hello!') - ->to(new Address('saif.gmati@symfony.com', 'Saif Eddin')) - ->from(new Address('fabpot@symfony.com', 'Fabien')) - ->text('Hello There!'); - - $this->expectException(HttpTransportException::class); - $this->expectExceptionMessage('Unable to send an email: {"error":"i\'m a teapot"}'); - $transport->send($mail); - } - - public function testSendThrowsForMultipleErrorResponses() - { - $client = new MockHttpClient(static fn (string $method, string $url, array $options): ResponseInterface => new MockResponse(json_encode(['errors' => ['to' => 'undefined field']]), [ - 'http_code' => 418, - 'response_headers' => [ - 'content-type' => 'application/json', - ], - ])); - $transport = new OhMySmtpApiTransport('KEY', $client); - $transport->setPort(8984); - - $mail = new Email(); - $mail->subject('Hello!') - ->to(new Address('saif.gmati@symfony.com', 'Saif Eddin')) - ->from(new Address('fabpot@symfony.com', 'Fabien')) - ->text('Hello There!'); - - $this->expectException(HttpTransportException::class); - $this->expectExceptionMessage('Unable to send an email: {"errors":{"to":"undefined field"}}'); - $transport->send($mail); - } - - public function testTagAndMetadataHeaders() - { - $email = new Email(); - $email->getHeaders()->add(new TagHeader('password-reset')); - $email->getHeaders()->add(new TagHeader('2nd-tag')); - - $envelope = new Envelope(new Address('alice@system.com'), [new Address('bob@system.com')]); - - $transport = new OhMySmtpApiTransport('ACCESS_KEY'); - $method = new \ReflectionMethod(OhMySmtpApiTransport::class, 'getPayload'); - $payload = $method->invoke($transport, $email, $envelope); - - $this->assertArrayNotHasKey('Headers', $payload); - $this->assertArrayHasKey('tags', $payload); - - $this->assertSame(['password-reset', '2nd-tag'], $payload['tags']); - } -} diff --git a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/Tests/Transport/OhMySmtpSmtpTransportTest.php b/src/Symfony/Component/Mailer/Bridge/OhMySmtp/Tests/Transport/OhMySmtpSmtpTransportTest.php deleted file mode 100644 index edbd50662f991..0000000000000 --- a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/Tests/Transport/OhMySmtpSmtpTransportTest.php +++ /dev/null @@ -1,52 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Mailer\Bridge\OhMySmtp\Tests\Transport; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Mailer\Bridge\OhMySmtp\Transport\OhMySmtpSmtpTransport; -use Symfony\Component\Mailer\Header\TagHeader; -use Symfony\Component\Mime\Email; - -/** - * @group legacy - */ -final class OhMySmtpSmtpTransportTest extends TestCase -{ - public function testCustomHeader() - { - $email = new Email(); - $email->getHeaders()->addTextHeader('foo', 'bar'); - - $transport = new OhMySmtpSmtpTransport('ACCESS_KEY'); - $method = new \ReflectionMethod(OhMySmtpSmtpTransport::class, 'addOhMySmtpHeaders'); - $method->invoke($transport, $email); - - $this->assertCount(1, $email->getHeaders()->toArray()); - $this->assertSame('foo: bar', $email->getHeaders()->get('FOO')->toString()); - } - - public function testTagAndMetadataHeaders() - { - $email = new Email(); - $email->getHeaders()->addTextHeader('foo', 'bar'); - $email->getHeaders()->add(new TagHeader('password-reset')); - $email->getHeaders()->add(new TagHeader('2nd-tag')); - - $transport = new OhMySmtpSmtpTransport('ACCESS_KEY'); - $method = new \ReflectionMethod(OhMySmtpSmtpTransport::class, 'addOhMySmtpHeaders'); - $method->invoke($transport, $email); - - $this->assertCount(2, $email->getHeaders()->toArray()); - $this->assertSame('foo: bar', $email->getHeaders()->get('FOO')->toString()); - $this->assertSame('X-OMS-Tags: password-reset, 2nd-tag', $email->getHeaders()->get('X-OMS-Tags')->toString()); - } -} diff --git a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/Tests/Transport/OhMySmtpTransportFactoryTest.php b/src/Symfony/Component/Mailer/Bridge/OhMySmtp/Tests/Transport/OhMySmtpTransportFactoryTest.php deleted file mode 100644 index 503f0410791d0..0000000000000 --- a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/Tests/Transport/OhMySmtpTransportFactoryTest.php +++ /dev/null @@ -1,103 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Mailer\Bridge\OhMySmtp\Tests\Transport; - -use Psr\Log\NullLogger; -use Symfony\Component\HttpClient\MockHttpClient; -use Symfony\Component\Mailer\Bridge\OhMySmtp\Transport\OhMySmtpApiTransport; -use Symfony\Component\Mailer\Bridge\OhMySmtp\Transport\OhMySmtpSmtpTransport; -use Symfony\Component\Mailer\Bridge\OhMySmtp\Transport\OhMySmtpTransportFactory; -use Symfony\Component\Mailer\Test\TransportFactoryTestCase; -use Symfony\Component\Mailer\Transport\Dsn; -use Symfony\Component\Mailer\Transport\TransportFactoryInterface; - -/** - * @group legacy - */ -final class OhMySmtpTransportFactoryTest extends TransportFactoryTestCase -{ - public function getFactory(): TransportFactoryInterface - { - return new OhMySmtpTransportFactory(null, new MockHttpClient(), new NullLogger()); - } - - public static function supportsProvider(): iterable - { - yield [ - new Dsn('ohmysmtp+api', 'default'), - true, - ]; - - yield [ - new Dsn('ohmysmtp', 'default'), - true, - ]; - - yield [ - new Dsn('ohmysmtp+smtp', 'default'), - true, - ]; - - yield [ - new Dsn('ohmysmtp+smtps', 'default'), - true, - ]; - - yield [ - new Dsn('ohmysmtp+smtp', 'example.com'), - true, - ]; - } - - public static function createProvider(): iterable - { - $logger = new NullLogger(); - - yield [ - new Dsn('ohmysmtp+api', 'default', self::USER), - new OhMySmtpApiTransport(self::USER, new MockHttpClient(), null, $logger), - ]; - - yield [ - new Dsn('ohmysmtp+api', 'example.com', self::USER, '', 8080), - (new OhMySmtpApiTransport(self::USER, new MockHttpClient(), null, $logger))->setHost('example.com')->setPort(8080), - ]; - - yield [ - new Dsn('ohmysmtp', 'default', self::USER), - new OhMySmtpSmtpTransport(self::USER, null, $logger), - ]; - - yield [ - new Dsn('ohmysmtp+smtp', 'default', self::USER), - new OhMySmtpSmtpTransport(self::USER, null, $logger), - ]; - - yield [ - new Dsn('ohmysmtp+smtps', 'default', self::USER), - new OhMySmtpSmtpTransport(self::USER, null, $logger), - ]; - } - - public static function unsupportedSchemeProvider(): iterable - { - yield [ - new Dsn('ohmysmtp+foo', 'default', self::USER), - 'The "ohmysmtp+foo" scheme is not supported; supported schemes for mailer "ohmysmtp" are: "ohmysmtp", "ohmysmtp+api", "ohmysmtp+smtp", "ohmysmtp+smtps".', - ]; - } - - public static function incompleteDsnProvider(): iterable - { - yield [new Dsn('ohmysmtp+api', 'default')]; - } -} diff --git a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/Transport/OhMySmtpApiTransport.php b/src/Symfony/Component/Mailer/Bridge/OhMySmtp/Transport/OhMySmtpApiTransport.php deleted file mode 100644 index 9d749c75e0a63..0000000000000 --- a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/Transport/OhMySmtpApiTransport.php +++ /dev/null @@ -1,147 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Mailer\Bridge\OhMySmtp\Transport; - -use Psr\EventDispatcher\EventDispatcherInterface; -use Psr\Log\LoggerInterface; -use Symfony\Component\Mailer\Bridge\MailPace\Transport\MailPaceApiTransport; -use Symfony\Component\Mailer\Envelope; -use Symfony\Component\Mailer\Exception\HttpTransportException; -use Symfony\Component\Mailer\Header\TagHeader; -use Symfony\Component\Mailer\SentMessage; -use Symfony\Component\Mailer\Transport\AbstractApiTransport; -use Symfony\Component\Mime\Email; -use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface; -use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; -use Symfony\Contracts\HttpClient\HttpClientInterface; -use Symfony\Contracts\HttpClient\ResponseInterface; - -trigger_deprecation('symfony/oh-my-smtp-mailer', '6.2', 'The "%s" class is deprecated, use "%s" instead.', OhMySmtpApiTransport::class, MailPaceApiTransport::class); - -/** - * @author Paul Oms - * - * @deprecated since Symfony 6.2, use MailPaceApiTransport instead - */ -final class OhMySmtpApiTransport extends AbstractApiTransport -{ - private const HOST = 'app.ohmysmtp.com/api/v1'; - - private string $key; - - public function __construct(string $key, HttpClientInterface $client = null, EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null) - { - $this->key = $key; - - parent::__construct($client, $dispatcher, $logger); - } - - public function __toString(): string - { - return sprintf('ohmysmtp+api://%s', $this->getEndpoint()); - } - - protected function doSendApi(SentMessage $sentMessage, Email $email, Envelope $envelope): ResponseInterface - { - $response = $this->client->request('POST', 'https://'.$this->getEndpoint().'/send', [ - 'headers' => [ - 'Accept' => 'application/json', - 'OhMySMTP-Server-Token' => $this->key, - 'Content-Type' => 'application/json', - 'User-Agent' => 'OhMySMTP Symfony Mailer', - ], - 'json' => $this->getPayload($email, $envelope), - ]); - - try { - $statusCode = $response->getStatusCode(); - $result = $response->toArray(false); - } catch (DecodingExceptionInterface) { - throw new HttpTransportException('Unable to send an email: '.$response->getContent(false).sprintf(' (code %d).', $statusCode), $response); - } catch (TransportExceptionInterface $e) { - throw new HttpTransportException('Could not reach the remote OhMySMTP endpoint.', $response, 0, $e); - } - - if (200 !== $statusCode) { - throw new HttpTransportException('Unable to send an email: '.$response->getContent(false), $response); - } - - $sentMessage->setMessageId($result['id']); - - return $response; - } - - private function getPayload(Email $email, Envelope $envelope): array - { - $payload = [ - 'from' => $envelope->getSender()->toString(), - 'to' => implode(',', $this->stringifyAddresses($this->getRecipients($email, $envelope))), - 'cc' => implode(',', $this->stringifyAddresses($email->getCc())), - 'bcc' => implode(',', $this->stringifyAddresses($email->getBcc())), - 'replyto' => implode(',', $this->stringifyAddresses($email->getReplyTo())), - 'subject' => $email->getSubject(), - 'textbody' => $email->getTextBody(), - 'htmlbody' => $email->getHtmlBody(), - 'attachments' => $this->getAttachments($email), - 'tags' => [], - ]; - - $headersToBypass = ['from', 'to', 'cc', 'bcc', 'subject', 'content-type', 'sender', 'reply-to']; - - foreach ($email->getHeaders()->all() as $name => $header) { - if (\in_array($name, $headersToBypass, true)) { - continue; - } - - if ($header instanceof TagHeader) { - $payload['tags'][] = $header->getValue(); - continue; - } - - $payload['Headers'][] = [ - 'Name' => $header->getName(), - 'Value' => $header->getBodyAsString(), - ]; - } - - return $payload; - } - - private function getAttachments(Email $email): array - { - $attachments = []; - foreach ($email->getAttachments() as $attachment) { - $headers = $attachment->getPreparedHeaders(); - $filename = $headers->getHeaderParameter('Content-Disposition', 'filename'); - $disposition = $headers->getHeaderBody('Content-Disposition'); - - $att = [ - 'name' => $filename, - 'content' => $attachment->bodyToString(), - 'content_type' => $headers->get('Content-Type')->getBody(), - ]; - - if ('inline' === $disposition) { - $att['cid'] = 'cid:'.$filename; - } - - $attachments[] = $att; - } - - return $attachments; - } - - private function getEndpoint(): ?string - { - return ($this->host ?: self::HOST).($this->port ? ':'.$this->port : ''); - } -} diff --git a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/Transport/OhMySmtpSmtpTransport.php b/src/Symfony/Component/Mailer/Bridge/OhMySmtp/Transport/OhMySmtpSmtpTransport.php deleted file mode 100644 index 09b5fdd4fac09..0000000000000 --- a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/Transport/OhMySmtpSmtpTransport.php +++ /dev/null @@ -1,67 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Mailer\Bridge\OhMySmtp\Transport; - -use Psr\EventDispatcher\EventDispatcherInterface; -use Psr\Log\LoggerInterface; -use Symfony\Component\Mailer\Bridge\MailPace\Transport\MailPaceSmtpTransport; -use Symfony\Component\Mailer\Envelope; -use Symfony\Component\Mailer\Header\TagHeader; -use Symfony\Component\Mailer\SentMessage; -use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport; -use Symfony\Component\Mime\Message; -use Symfony\Component\Mime\RawMessage; - -trigger_deprecation('symfony/oh-my-smtp-mailer', '6.2', 'The "%s" class is deprecated, use "%s" instead.', OhMySmtpSmtpTransport::class, MailPaceSmtpTransport::class); - -/** - * @author Paul Oms - * - * @deprecated since Symfony 6.2, use MailPaceSmtpTransport instead - */ -final class OhMySmtpSmtpTransport extends EsmtpTransport -{ - public function __construct(string $id, EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null) - { - parent::__construct('smtp.ohmysmtp.com', 587, false, $dispatcher, $logger); - - $this->setUsername($id); - $this->setPassword($id); - } - - public function send(RawMessage $message, Envelope $envelope = null): ?SentMessage - { - if ($message instanceof Message) { - $this->addOhMySmtpHeaders($message); - } - - return parent::send($message, $envelope); - } - - private function addOhMySmtpHeaders(Message $message): void - { - $headers = $message->getHeaders(); - - foreach ($headers->all() as $name => $header) { - if ($header instanceof TagHeader) { - if (null != $headers->get('X-OMS-Tags')) { - $existing = $headers->get('X-OMS-Tags')->getBody(); - $headers->remove('X-OMS-Tags'); - $headers->addTextHeader('X-OMS-Tags', $existing.', '.$header->getValue()); - } else { - $headers->addTextHeader('X-OMS-Tags', $header->getValue()); - } - $headers->remove($name); - } - } - } -} diff --git a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/Transport/OhMySmtpTransportFactory.php b/src/Symfony/Component/Mailer/Bridge/OhMySmtp/Transport/OhMySmtpTransportFactory.php deleted file mode 100644 index 62c2b24e7cdc9..0000000000000 --- a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/Transport/OhMySmtpTransportFactory.php +++ /dev/null @@ -1,51 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Mailer\Bridge\OhMySmtp\Transport; - -use Symfony\Component\Mailer\Bridge\MailPace\Transport\MailPaceTransportFactory; -use Symfony\Component\Mailer\Exception\UnsupportedSchemeException; -use Symfony\Component\Mailer\Transport\AbstractTransportFactory; -use Symfony\Component\Mailer\Transport\Dsn; -use Symfony\Component\Mailer\Transport\TransportInterface; - -/** - * @author Paul Oms - * - * @deprecated since Symfony 6.2, use MailPaceTransportFactory instead - */ -final class OhMySmtpTransportFactory extends AbstractTransportFactory -{ - public function create(Dsn $dsn): TransportInterface - { - trigger_deprecation('symfony/oh-my-smtp-mailer', '6.2', 'The "%s" class is deprecated, use "%s" instead.', self::class, MailPaceTransportFactory::class); - - $scheme = $dsn->getScheme(); - - if ('ohmysmtp+api' === $scheme) { - $host = 'default' === $dsn->getHost() ? null : $dsn->getHost(); - $port = $dsn->getPort(); - - return (new OhMySmtpApiTransport($this->getUser($dsn), $this->client, $this->dispatcher, $this->logger))->setHost($host)->setPort($port); - } - - if ('ohmysmtp+smtp' === $scheme || 'ohmysmtp+smtps' === $scheme || 'ohmysmtp' === $scheme) { - return new OhMySmtpSmtpTransport($this->getUser($dsn), $this->dispatcher, $this->logger); - } - - throw new UnsupportedSchemeException($dsn, 'ohmysmtp', $this->getSupportedSchemes()); - } - - protected function getSupportedSchemes(): array - { - return ['ohmysmtp', 'ohmysmtp+api', 'ohmysmtp+smtp', 'ohmysmtp+smtps']; - } -} diff --git a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/composer.json b/src/Symfony/Component/Mailer/Bridge/OhMySmtp/composer.json deleted file mode 100644 index a11f305c24ebe..0000000000000 --- a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/composer.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "symfony/oh-my-smtp-mailer", - "type": "symfony-mailer-bridge", - "description": "Symfony OhMySMTP Mailer Bridge", - "keywords": [], - "homepage": "https://symfony.com", - "license": "MIT", - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - }, - { - "name": "Paul Oms", - "homepage": "https://ohmysmtp.com" - } - ], - "require": { - "php": ">=8.2", - "psr/event-dispatcher": "^1", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/mailer": "^6.4|^7.0" - }, - "require-dev": { - "symfony/http-client": "^6.4|^7.0" - }, - "autoload": { - "psr-4": { "Symfony\\Component\\Mailer\\Bridge\\OhMySmtp\\": "" }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "minimum-stability": "dev" -} diff --git a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/phpunit.xml.dist b/src/Symfony/Component/Mailer/Bridge/OhMySmtp/phpunit.xml.dist deleted file mode 100644 index 706e4cf3c1339..0000000000000 --- a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/phpunit.xml.dist +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - ./Tests/ - - - - - - ./ - - ./Resources - ./Tests - ./vendor - - - - diff --git a/src/Symfony/Component/Mailer/CHANGELOG.md b/src/Symfony/Component/Mailer/CHANGELOG.md index 291125f3aec32..3ac8882d352bb 100644 --- a/src/Symfony/Component/Mailer/CHANGELOG.md +++ b/src/Symfony/Component/Mailer/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +7.0 +--- + + * Remove the OhMySmtp bridge in favor of the MailPace bridge + 6.3 --- diff --git a/src/Symfony/Component/Mailer/Exception/UnsupportedSchemeException.php b/src/Symfony/Component/Mailer/Exception/UnsupportedSchemeException.php index b0612b23808fe..8f87fe18f1af6 100644 --- a/src/Symfony/Component/Mailer/Exception/UnsupportedSchemeException.php +++ b/src/Symfony/Component/Mailer/Exception/UnsupportedSchemeException.php @@ -44,10 +44,6 @@ class UnsupportedSchemeException extends LogicException 'class' => Bridge\Mailchimp\Transport\MandrillTransportFactory::class, 'package' => 'symfony/mailchimp-mailer', ], - 'ohmysmtp' => [ - 'class' => Bridge\OhMySmtp\Transport\OhMySmtpTransportFactory::class, - 'package' => 'symfony/oh-my-smtp-mailer', - ], 'postmark' => [ 'class' => Bridge\Postmark\Transport\PostmarkTransportFactory::class, 'package' => 'symfony/postmark-mailer', diff --git a/src/Symfony/Component/Mailer/Tests/Exception/UnsupportedSchemeExceptionTest.php b/src/Symfony/Component/Mailer/Tests/Exception/UnsupportedSchemeExceptionTest.php index 5dcf0f1bbfd7c..430ca774f4b02 100644 --- a/src/Symfony/Component/Mailer/Tests/Exception/UnsupportedSchemeExceptionTest.php +++ b/src/Symfony/Component/Mailer/Tests/Exception/UnsupportedSchemeExceptionTest.php @@ -20,7 +20,6 @@ use Symfony\Component\Mailer\Bridge\MailerSend\Transport\MailerSendTransportFactory; use Symfony\Component\Mailer\Bridge\Mailgun\Transport\MailgunTransportFactory; use Symfony\Component\Mailer\Bridge\Mailjet\Transport\MailjetTransportFactory; -use Symfony\Component\Mailer\Bridge\OhMySmtp\Transport\OhMySmtpTransportFactory; use Symfony\Component\Mailer\Bridge\Postmark\Transport\PostmarkTransportFactory; use Symfony\Component\Mailer\Bridge\Sendgrid\Transport\SendgridTransportFactory; use Symfony\Component\Mailer\Bridge\Sendinblue\Transport\SendinblueTransportFactory; @@ -42,7 +41,6 @@ public static function setUpBeforeClass(): void MailgunTransportFactory::class => false, MailjetTransportFactory::class => false, MandrillTransportFactory::class => false, - OhMySmtpTransportFactory::class => false, PostmarkTransportFactory::class => false, SendgridTransportFactory::class => false, SendinblueTransportFactory::class => false, @@ -71,7 +69,6 @@ public static function messageWhereSchemeIsPartOfSchemeToPackageMapProvider(): \ yield ['mailgun', 'symfony/mailgun-mailer']; yield ['mailjet', 'symfony/mailjet-mailer']; yield ['mandrill', 'symfony/mailchimp-mailer']; - yield ['ohmysmtp', 'symfony/oh-my-smtp-mailer']; yield ['postmark', 'symfony/postmark-mailer']; yield ['sendgrid', 'symfony/sendgrid-mailer']; yield ['sendinblue', 'symfony/sendinblue-mailer']; diff --git a/src/Symfony/Component/Mailer/Transport.php b/src/Symfony/Component/Mailer/Transport.php index 2c6fdd5505e70..ea404095ed50a 100644 --- a/src/Symfony/Component/Mailer/Transport.php +++ b/src/Symfony/Component/Mailer/Transport.php @@ -20,7 +20,6 @@ use Symfony\Component\Mailer\Bridge\MailerSend\Transport\MailerSendTransportFactory; use Symfony\Component\Mailer\Bridge\Mailgun\Transport\MailgunTransportFactory; use Symfony\Component\Mailer\Bridge\Mailjet\Transport\MailjetTransportFactory; -use Symfony\Component\Mailer\Bridge\OhMySmtp\Transport\OhMySmtpTransportFactory; use Symfony\Component\Mailer\Bridge\Postmark\Transport\PostmarkTransportFactory; use Symfony\Component\Mailer\Bridge\Sendgrid\Transport\SendgridTransportFactory; use Symfony\Component\Mailer\Bridge\Sendinblue\Transport\SendinblueTransportFactory; @@ -51,7 +50,6 @@ final class Transport MailgunTransportFactory::class, MailjetTransportFactory::class, MandrillTransportFactory::class, - OhMySmtpTransportFactory::class, PostmarkTransportFactory::class, SendgridTransportFactory::class, SendinblueTransportFactory::class, diff --git a/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Transport/AmazonSqsTransportTest.php b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Transport/AmazonSqsTransportTest.php index 541b543f699d0..0b874e06941bc 100644 --- a/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Transport/AmazonSqsTransportTest.php +++ b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Transport/AmazonSqsTransportTest.php @@ -53,7 +53,6 @@ class AmazonSqsTransportTest extends TestCase protected function setUp(): void { $this->connection = $this->createMock(Connection::class); - // Mocking the concrete receiver class because mocking multiple interfaces is deprecated $this->receiver = $this->createMock(AmazonSqsReceiver::class); $this->sender = $this->createMock(SenderInterface::class); diff --git a/src/Symfony/Component/Messenger/CHANGELOG.md b/src/Symfony/Component/Messenger/CHANGELOG.md index a92c40183ea8b..4f410f97cb1a9 100644 --- a/src/Symfony/Component/Messenger/CHANGELOG.md +++ b/src/Symfony/Component/Messenger/CHANGELOG.md @@ -5,6 +5,13 @@ CHANGELOG --- * Add parameter `$isSameDatabase` to `DoctrineTransport::configureSchema()` + * Remove `MessageHandlerInterface` and `MessageSubscriberInterface`, use `#[AsMessageHandler]` instead + * Remove `StopWorkerOnSigtermSignalListener` in favor of + `StopWorkerOnSignalsListener` and make it configurable with SIGINT and + * Remove `Symfony\Component\Messenger\Transport\InMemoryTransport` and + `Symfony\Component\Messenger\Transport\InMemoryTransportFactory` in favor of + `Symfony\Component\Messenger\Transport\InMemory\InMemoryTransport` and + `Symfony\Component\Messenger\Transport\InMemory\InMemoryTransportFactory` 6.3 --- diff --git a/src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php b/src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php index 03f48edfcd93a..f6f26d6946de2 100644 --- a/src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php +++ b/src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php @@ -20,11 +20,8 @@ use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException; use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\DependencyInjection\Reference; -use Symfony\Component\Messenger\Attribute\AsMessageHandler; use Symfony\Component\Messenger\Handler\HandlerDescriptor; use Symfony\Component\Messenger\Handler\HandlersLocator; -use Symfony\Component\Messenger\Handler\MessageHandlerInterface; -use Symfony\Component\Messenger\Handler\MessageSubscriberInterface; use Symfony\Component\Messenger\TraceableMessageBus; use Symfony\Component\Messenger\Transport\Receiver\ReceiverInterface; @@ -109,9 +106,7 @@ private function registerHandlers(ContainerBuilder $container, array $busIds): v if (isset($options['bus'])) { if (!\in_array($options['bus'], $busIds)) { - // @deprecated since Symfony 6.2, in 7.0 change to: - // $messageLocation = isset($tag['handles']) ? 'declared in your tag attribute "handles"' : sprintf('used as argument type in method "%s::%s()"', $r->getName(), $method); - $messageLocation = isset($tag['handles']) ? 'declared in your tag attribute "handles"' : ($r->implementsInterface(MessageSubscriberInterface::class) ? sprintf('returned by method "%s::getHandledMessages()"', $r->getName()) : sprintf('used as argument type in method "%s::%s()"', $r->getName(), $method)); + $messageLocation = isset($tag['handles']) ? 'declared in your tag attribute "handles"' : sprintf('used as argument type in method "%s::%s()"', $r->getName(), $method); throw new RuntimeException(sprintf('Invalid configuration '.$messageLocation.' for message "%s": bus "%s" does not exist.', $message, $options['bus'])); } @@ -120,9 +115,7 @@ private function registerHandlers(ContainerBuilder $container, array $busIds): v } if ('*' !== $message && !class_exists($message) && !interface_exists($message, false)) { - // @deprecated since Symfony 6.2, in 7.0 change to: - // $messageLocation = isset($tag['handles']) ? 'declared in your tag attribute "handles"' : sprintf('used as argument type in method "%s::%s()"', $r->getName(), $method); - $messageLocation = isset($tag['handles']) ? 'declared in your tag attribute "handles"' : ($r->implementsInterface(MessageSubscriberInterface::class) ? sprintf('returned by method "%s::getHandledMessages()"', $r->getName()) : sprintf('used as argument type in method "%s::%s()"', $r->getName(), $method)); + $messageLocation = isset($tag['handles']) ? 'declared in your tag attribute "handles"' : sprintf('used as argument type in method "%s::%s()"', $r->getName(), $method); throw new RuntimeException(sprintf('Invalid handler service "%s": class or interface "%s" '.$messageLocation.' not found.', $serviceId, $message)); } @@ -147,7 +140,7 @@ private function registerHandlers(ContainerBuilder $container, array $busIds): v } if (null === $message) { - throw new RuntimeException(sprintf('Invalid handler service "%s": method "%s::getHandledMessages()" must return one or more messages.', $serviceId, $r->getName())); + throw new RuntimeException(sprintf('Invalid handler service "%s": the list of messages to handle is empty.', $serviceId, $r->getName())); } } } @@ -203,16 +196,6 @@ private function registerHandlers(ContainerBuilder $container, array $busIds): v private function guessHandledClasses(\ReflectionClass $handlerClass, string $serviceId, string $methodName): iterable { - if ($handlerClass->implementsInterface(MessageSubscriberInterface::class)) { - trigger_deprecation('symfony/messenger', '6.2', 'Implementing "%s" is deprecated, use the "%s" attribute instead.', MessageSubscriberInterface::class, AsMessageHandler::class); - - return $handlerClass->getName()::getHandledMessages(); - } - - if ($handlerClass->implementsInterface(MessageHandlerInterface::class)) { - trigger_deprecation('symfony/messenger', '6.2', 'Implementing "%s" is deprecated, use the "%s" attribute instead.', MessageHandlerInterface::class, AsMessageHandler::class); - } - try { $method = $handlerClass->getMethod($methodName); } catch (\ReflectionException) { diff --git a/src/Symfony/Component/Messenger/EventListener/StopWorkerOnSigtermSignalListener.php b/src/Symfony/Component/Messenger/EventListener/StopWorkerOnSigtermSignalListener.php deleted file mode 100644 index eeddf7d5fc675..0000000000000 --- a/src/Symfony/Component/Messenger/EventListener/StopWorkerOnSigtermSignalListener.php +++ /dev/null @@ -1,29 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Messenger\EventListener; - -trigger_deprecation('symfony/messenger', '6.3', '"%s" is deprecated, use "%s" instead.', StopWorkerOnSigtermSignalListener::class, StopWorkerOnSignalsListener::class); - -use Psr\Log\LoggerInterface; - -/** - * @author Tobias Schultze - * - * @deprecated since Symfony 6.3, use the StopWorkerOnSignalsListener instead - */ -class StopWorkerOnSigtermSignalListener extends StopWorkerOnSignalsListener -{ - public function __construct(LoggerInterface $logger = null) - { - parent::__construct([SIGTERM], $logger); - } -} diff --git a/src/Symfony/Component/Messenger/Handler/MessageHandlerInterface.php b/src/Symfony/Component/Messenger/Handler/MessageHandlerInterface.php deleted file mode 100644 index 80d510cecde0c..0000000000000 --- a/src/Symfony/Component/Messenger/Handler/MessageHandlerInterface.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Messenger\Handler; - -use Symfony\Component\Messenger\Attribute\AsMessageHandler; - -/** - * Marker interface for message handlers. - * - * @author Samuel Roze - * - * @deprecated since Symfony 6.2, use the {@see AsMessageHandler} attribute instead - */ -interface MessageHandlerInterface -{ -} diff --git a/src/Symfony/Component/Messenger/Handler/MessageSubscriberInterface.php b/src/Symfony/Component/Messenger/Handler/MessageSubscriberInterface.php deleted file mode 100644 index d24fc6b1dc4b1..0000000000000 --- a/src/Symfony/Component/Messenger/Handler/MessageSubscriberInterface.php +++ /dev/null @@ -1,53 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Messenger\Handler; - -use Symfony\Component\Messenger\Attribute\AsMessageHandler; - -/** - * Handlers can implement this interface to handle multiple messages. - * - * @author Samuel Roze - * - * @deprecated since Symfony 6.2, use the {@see AsMessageHandler} attribute instead - */ -interface MessageSubscriberInterface extends MessageHandlerInterface -{ - /** - * Returns a list of messages to be handled. - * - * It returns a list of messages like in the following example: - * - * yield MyMessage::class; - * - * It can also change the priority per classes. - * - * yield FirstMessage::class => ['priority' => 0]; - * yield SecondMessage::class => ['priority' => -10]; - * - * It can also specify a method, a priority, a bus and/or a transport per message: - * - * yield FirstMessage::class => ['method' => 'firstMessageMethod']; - * yield SecondMessage::class => [ - * 'method' => 'secondMessageMethod', - * 'priority' => 20, - * 'bus' => 'my_bus_name', - * 'from_transport' => 'your_transport_name', - * ]; - * - * The benefit of using `yield` instead of returning an array is that you can `yield` multiple times the - * same key and therefore subscribe to the same message multiple times with different options. - * - * The `__invoke` method of the handler will be called as usual with the message to handle. - */ - public static function getHandledMessages(): iterable; -} diff --git a/src/Symfony/Component/Messenger/Tests/DependencyInjection/MessengerPassTest.php b/src/Symfony/Component/Messenger/Tests/DependencyInjection/MessengerPassTest.php index 226c8d71fb27a..4cc283bca94f3 100644 --- a/src/Symfony/Component/Messenger/Tests/DependencyInjection/MessengerPassTest.php +++ b/src/Symfony/Component/Messenger/Tests/DependencyInjection/MessengerPassTest.php @@ -34,8 +34,6 @@ use Symfony\Component\Messenger\DependencyInjection\MessengerPass; use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\Handler\HandlersLocator; -use Symfony\Component\Messenger\Handler\MessageHandlerInterface; -use Symfony\Component\Messenger\Handler\MessageSubscriberInterface; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Messenger\Middleware\HandleMessageMiddleware; use Symfony\Component\Messenger\Middleware\MiddlewareInterface; @@ -152,19 +150,6 @@ public function testHandledMessageTypeResolvedWithMethodAndNoHandlesViaTagAttrib public function testTaggedMessageHandler() { $container = $this->getContainerBuilder($busId = 'message_bus'); - $container->registerAttributeForAutoconfiguration(AsMessageHandler::class, static function (ChildDefinition $definition, AsMessageHandler $attribute, \ReflectionClass|\ReflectionMethod $reflector): void { - $tagAttributes = get_object_vars($attribute); - $tagAttributes['from_transport'] = $tagAttributes['fromTransport']; - unset($tagAttributes['fromTransport']); - if ($reflector instanceof \ReflectionMethod) { - if (isset($tagAttributes['method'])) { - throw new LogicException(sprintf('AsMessageHandler attribute cannot declare a method on "%s::%s()".', $reflector->class, $reflector->name)); - } - $tagAttributes['method'] = $reflector->getName(); - } - - $definition->addTag('messenger.message_handler', $tagAttributes); - }); $container ->register(TaggedDummyHandler::class, TaggedDummyHandler::class) ->setAutoconfigured(true) @@ -192,19 +177,6 @@ public function testTaggedMessageHandler() public function testTaggedMessageHandlerWithUnionTypes() { $container = $this->getContainerBuilder($busId = 'message_bus'); - $container->registerAttributeForAutoconfiguration(AsMessageHandler::class, static function (ChildDefinition $definition, AsMessageHandler $attribute, \ReflectionClass|\ReflectionMethod $reflector): void { - $tagAttributes = get_object_vars($attribute); - $tagAttributes['from_transport'] = $tagAttributes['fromTransport']; - unset($tagAttributes['fromTransport']); - if ($reflector instanceof \ReflectionMethod) { - if (isset($tagAttributes['method'])) { - throw new LogicException(sprintf('AsMessageHandler attribute cannot declare a method on "%s::%s()".', $reflector->class, $reflector->name)); - } - $tagAttributes['method'] = $reflector->getName(); - } - - $definition->addTag('messenger.message_handler', $tagAttributes); - }); $container ->register(TaggedDummyHandlerWithUnionTypes::class, TaggedDummyHandlerWithUnionTypes::class) ->setAutoconfigured(true) @@ -309,22 +281,20 @@ public function testProcessTagWithUnknownBus() (new MessengerPass())->process($container); } - /** - * @group legacy - */ - public function testGetClassesFromTheHandlerSubscriberInterface() + public function testGetClassesFromTheAttribute() { $container = $this->getContainerBuilder($busId = 'message_bus'); $container ->register(HandlerWithMultipleMessages::class, HandlerWithMultipleMessages::class) - ->addTag('messenger.message_handler') + ->setAutoconfigured(true) ; $container ->register(PrioritizedHandler::class, PrioritizedHandler::class) - ->addTag('messenger.message_handler') + ->setAutoconfigured(true) ; - $this->expectDeprecation('Since symfony/messenger 6.2: Implementing "Symfony\Component\Messenger\Handler\MessageSubscriberInterface" is deprecated, use the "Symfony\Component\Messenger\Attribute\AsMessageHandler" attribute instead.'); + (new AttributeAutoconfigurationPass())->process($container); + (new ResolveInstanceofConditionalsPass())->process($container); (new MessengerPass())->process($container); $handlersMapping = $container->getDefinition($busId.'.messenger.handlers_locator')->getArgument(0); @@ -336,21 +306,20 @@ public function testGetClassesFromTheHandlerSubscriberInterface() $this->assertHandlerDescriptor($container, $handlersMapping, SecondMessage::class, [PrioritizedHandler::class, HandlerWithMultipleMessages::class], [['priority' => 10]]); } - /** - * @group legacy - */ - public function testGetClassesAndMethodsAndPrioritiesFromTheSubscriber() + public function testGetClassesAndMethodsAndPrioritiesFromTheAttribute() { $container = $this->getContainerBuilder($busId = 'message_bus'); $container ->register(HandlerMappingMethods::class, HandlerMappingMethods::class) - ->addTag('messenger.message_handler') + ->setAutoconfigured(true) ; $container ->register(PrioritizedHandler::class, PrioritizedHandler::class) - ->addTag('messenger.message_handler') + ->setAutoconfigured(true) ; + (new AttributeAutoconfigurationPass())->process($container); + (new ResolveInstanceofConditionalsPass())->process($container); (new MessengerPass())->process($container); $handlersMapping = $container->getDefinition($busId.'.messenger.handlers_locator')->getArgument(0); @@ -418,9 +387,6 @@ public function testThrowsExceptionIfTheHandlerClassDoesNotExist() (new MessengerPass())->process($container); } - /** - * @group legacy - */ public function testThrowsExceptionIfTheHandlerMethodDoesNotExist() { $this->expectException(RuntimeException::class); @@ -429,9 +395,11 @@ public function testThrowsExceptionIfTheHandlerMethodDoesNotExist() $container->register('message_bus', MessageBusInterface::class)->addTag('messenger.bus'); $container ->register(HandlerMappingWithNonExistentMethod::class, HandlerMappingWithNonExistentMethod::class) - ->addTag('messenger.message_handler') + ->setAutoconfigured(true) ; + (new AttributeAutoconfigurationPass())->process($container); + (new ResolveInstanceofConditionalsPass())->process($container); (new MessengerPass())->process($container); } @@ -492,39 +460,6 @@ public function testItSetsTheReceiverNamesOnTheSetupTransportsCommand() $this->assertSame(['amqp', 'dummy'], $container->getDefinition('console.command.messenger_setup_transports')->getArgument(1)); } - /** - * @group legacy - */ - public function testItShouldNotThrowIfGeneratorIsReturnedInsteadOfArray() - { - $container = $this->getContainerBuilder($busId = 'message_bus'); - $container - ->register(HandlerWithGenerators::class, HandlerWithGenerators::class) - ->addTag('messenger.message_handler') - ; - - (new MessengerPass())->process($container); - - $handlersMapping = $container->getDefinition($busId.'.messenger.handlers_locator')->getArgument(0); - - $this->assertHandlerDescriptor( - $container, - $handlersMapping, - DummyMessage::class, - [[HandlerWithGenerators::class, 'dummyMethod']] - ); - - $this->assertHandlerDescriptor( - $container, - $handlersMapping, - SecondMessage::class, - [[HandlerWithGenerators::class, 'secondMessage']] - ); - } - - /** - * @group legacy - */ public function testItRegistersHandlersOnDifferentBuses() { $container = $this->getContainerBuilder($eventsBusId = 'event_bus'); @@ -532,8 +467,11 @@ public function testItRegistersHandlersOnDifferentBuses() $container ->register(HandlerOnSpecificBuses::class, HandlerOnSpecificBuses::class) - ->addTag('messenger.message_handler'); + ->setAutoconfigured(true) + ; + (new AttributeAutoconfigurationPass())->process($container); + (new ResolveInstanceofConditionalsPass())->process($container); (new MessengerPass())->process($container); $eventsHandlerMapping = $container->getDefinition($eventsBusId.'.messenger.handlers_locator')->getArgument(0); @@ -557,19 +495,18 @@ public function testItRegistersHandlersOnDifferentBuses() ); } - /** - * @group legacy - */ public function testItThrowsAnExceptionOnUnknownBus() { $this->expectException(RuntimeException::class); - $this->expectExceptionMessage('Invalid configuration returned by method "Symfony\Component\Messenger\Tests\DependencyInjection\HandlerOnUndefinedBus::getHandledMessages()" for message "Symfony\Component\Messenger\Tests\Fixtures\DummyMessage": bus "some_undefined_bus" does not exist.'); + $this->expectExceptionMessage('Invalid handler service "Symfony\Component\Messenger\Tests\DependencyInjection\HandlerOnUndefinedBus": bus "some_undefined_bus" specified on the tag "messenger.message_handler" does not exist (known ones are: "message_bus").'); $container = $this->getContainerBuilder(); $container ->register(HandlerOnUndefinedBus::class, HandlerOnUndefinedBus::class) - ->addTag('messenger.message_handler') + ->setAutoconfigured(true) ; + (new AttributeAutoconfigurationPass())->process($container); + (new ResolveInstanceofConditionalsPass())->process($container); (new MessengerPass())->process($container); } @@ -586,35 +523,18 @@ public function testUndefinedMessageClassForHandler() (new MessengerPass())->process($container); } - /** - * @group legacy - */ - public function testUndefinedMessageClassForHandlerImplementingMessageHandlerInterface() + public function testUndefinedMessageClassForHandlerViaAttribute() { $this->expectException(RuntimeException::class); - $this->expectExceptionMessage('Invalid handler service "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessageHandlerViaHandlerInterface": class or interface "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessage" used as argument type in method "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessageHandlerViaHandlerInterface::__invoke()" not found.'); + $this->expectExceptionMessage('Invalid handler service "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessageHandlerViaAttribute": class or interface "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessage" used as argument type in method "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessageHandlerViaAttribute::__invoke()" not found.'); $container = $this->getContainerBuilder(); $container - ->register(UndefinedMessageHandlerViaHandlerInterface::class, UndefinedMessageHandlerViaHandlerInterface::class) - ->addTag('messenger.message_handler') - ; - - (new MessengerPass())->process($container); - } - - /** - * @group legacy - */ - public function testUndefinedMessageClassForHandlerImplementingMessageSubscriberInterface() - { - $this->expectException(RuntimeException::class); - $this->expectExceptionMessage('Invalid handler service "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessageHandlerViaSubscriberInterface": class or interface "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessage" returned by method "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessageHandlerViaSubscriberInterface::getHandledMessages()" not found.'); - $container = $this->getContainerBuilder(); - $container - ->register(UndefinedMessageHandlerViaSubscriberInterface::class, UndefinedMessageHandlerViaSubscriberInterface::class) - ->addTag('messenger.message_handler') + ->register(UndefinedMessageHandlerViaAttribute::class, UndefinedMessageHandlerViaAttribute::class) + ->setAutoconfigured(true) ; + (new AttributeAutoconfigurationPass())->process($container); + (new ResolveInstanceofConditionalsPass())->process($container); (new MessengerPass())->process($container); } @@ -701,19 +621,20 @@ public function testUnionBuiltinArgumentTypeHandler() (new MessengerPass())->process($container); } - /** - * @group legacy - */ public function testNeedsToHandleAtLeastOneMessage() { - $this->expectException(RuntimeException::class); - $this->expectExceptionMessage('Invalid handler service "Symfony\Component\Messenger\Tests\DependencyInjection\HandleNoMessageHandler": method "Symfony\Component\Messenger\Tests\DependencyInjection\HandleNoMessageHandler::getHandledMessages()" must return one or more messages.'); $container = $this->getContainerBuilder(); $container ->register(HandleNoMessageHandler::class, HandleNoMessageHandler::class) - ->addTag('messenger.message_handler') + ->setAutoconfigured(true) ; + (new AttributeAutoconfigurationPass())->process($container); + (new ResolveInstanceofConditionalsPass())->process($container); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('Invalid handler service "Symfony\Component\Messenger\Tests\DependencyInjection\HandleNoMessageHandler": method "Symfony\Component\Messenger\Tests\DependencyInjection\HandleNoMessageHandler::__invoke()" requires at least one argument, first one being the message it handles.'); + (new MessengerPass())->process($container); } @@ -739,7 +660,7 @@ public function testRegistersMiddlewareFromServices() $container->setParameter($middlewareParameter = $fooBusId.'.middleware', [ ['id' => UselessMiddleware::class], - ['id' => 'middleware_with_factory', 'arguments' => $factoryChildMiddlewareArgs1 = ['index_0' => 'foo', 'bar']], + ['id' => 'middleware_with_factory', 'arguments' => ['index_0' => 'foo', 'bar']], ['id' => 'middleware_with_factory', 'arguments' => $factoryChildMiddlewareArgs2 = ['index_0' => 'baz']], ['id' => 'middleware_with_factory_using_default'], ]); @@ -788,7 +709,7 @@ public function testCannotRegistersAnUndefinedMiddleware() $this->expectException(RuntimeException::class); $this->expectExceptionMessage('Invalid middleware: service "not_defined_middleware" not found.'); $container = $this->getContainerBuilder($fooBusId = 'messenger.bus.foo'); - $container->setParameter($middlewareParameter = $fooBusId.'.middleware', [ + $container->setParameter($fooBusId.'.middleware', [ ['id' => 'not_defined_middleware', 'arguments' => []], ]); @@ -801,7 +722,7 @@ public function testMiddlewareFactoryDefinitionMustBeAbstract() $this->expectExceptionMessage('Invalid middleware factory "not_an_abstract_definition": a middleware factory must be an abstract definition.'); $container = $this->getContainerBuilder($fooBusId = 'messenger.bus.foo'); $container->register('not_an_abstract_definition', UselessMiddleware::class); - $container->setParameter($middlewareParameter = $fooBusId.'.middleware', [ + $container->setParameter($fooBusId.'.middleware', [ ['id' => 'not_an_abstract_definition', 'arguments' => ['foo']], ]); @@ -862,6 +783,20 @@ private function getContainerBuilder(string $busId = 'message_bus'): ContainerBu ->addArgument(new Reference('service_container')) ; + $container->registerAttributeForAutoconfiguration(AsMessageHandler::class, static function (ChildDefinition $definition, AsMessageHandler $attribute, \ReflectionClass|\ReflectionMethod $reflector): void { + $tagAttributes = get_object_vars($attribute); + $tagAttributes['from_transport'] = $tagAttributes['fromTransport']; + unset($tagAttributes['fromTransport']); + if ($reflector instanceof \ReflectionMethod) { + if (isset($tagAttributes['method'])) { + throw new LogicException(sprintf('AsMessageHandler attribute cannot declare a method on "%s::%s()".', $reflector->class, $reflector->name)); + } + $tagAttributes['method'] = $reflector->getName(); + } + + $definition->addTag('messenger.message_handler', $tagAttributes); + }); + return $container; } @@ -958,25 +893,14 @@ public function __invoke(UndefinedMessage $message) } } -class UndefinedMessageHandlerViaHandlerInterface implements MessageHandlerInterface +#[AsMessageHandler] +class UndefinedMessageHandlerViaAttribute { public function __invoke(UndefinedMessage $message) { } } -class UndefinedMessageHandlerViaSubscriberInterface implements MessageSubscriberInterface -{ - public static function getHandledMessages(): iterable - { - return [UndefinedMessage::class]; - } - - public function __invoke() - { - } -} - class NotInvokableHandler { } @@ -1002,114 +926,66 @@ public function __invoke(string $message) } } -class HandlerWithMultipleMessages implements MessageSubscriberInterface +#[AsMessageHandler(handles: DummyMessage::class)] +#[AsMessageHandler(handles: SecondMessage::class)] +class HandlerWithMultipleMessages { - public static function getHandledMessages(): iterable - { - return [ - DummyMessage::class, - SecondMessage::class, - ]; - } - - public function __invoke() + public function __invoke($message) { } } -class PrioritizedHandler implements MessageSubscriberInterface +#[AsMessageHandler(handles: SecondMessage::class, priority: 10)] +class PrioritizedHandler { - public static function getHandledMessages(): iterable - { - yield SecondMessage::class => ['priority' => 10]; - } - - public function __invoke() + public function __invoke(SecondMessage $message) { } } -class HandlerMappingMethods implements MessageSubscriberInterface +#[AsMessageHandler(handles: DummyMessage::class, method: 'dummyMethod')] +#[AsMessageHandler(handles: SecondMessage::class, method: 'secondMessage', priority: 20)] +class HandlerMappingMethods { - public static function getHandledMessages(): iterable - { - yield DummyMessage::class => 'dummyMethod'; - yield SecondMessage::class => ['method' => 'secondMessage', 'priority' => 20]; - } - - public function dummyMethod() + public function dummyMethod(DummyMessage $message) { } - public function secondMessage() + public function secondMessage(SecondMessage $message) { } } -class HandlerMappingWithNonExistentMethod implements MessageSubscriberInterface +#[AsMessageHandler(handles: DummyMessage::class, method: 'dummyMethod')] +class HandlerMappingWithNonExistentMethod { - public static function getHandledMessages(): iterable - { - return [ - DummyMessage::class => 'dummyMethod', - ]; - } } -class HandleNoMessageHandler implements MessageSubscriberInterface +#[AsMessageHandler] +class HandleNoMessageHandler { - public static function getHandledMessages(): iterable - { - return []; - } - public function __invoke() { } } -class HandlerWithGenerators implements MessageSubscriberInterface +#[AsMessageHandler(handles: DummyMessage::class, method: 'dummyMethodForEvents', bus: 'event_bus')] +#[AsMessageHandler(handles: DummyMessage::class, method: 'dummyMethodForCommands', bus: 'command_bus')] +class HandlerOnSpecificBuses { - public static function getHandledMessages(): iterable - { - yield DummyMessage::class => 'dummyMethod'; - yield SecondMessage::class => 'secondMessage'; - } - - public function dummyMethod() + public function dummyMethodForEvents(DummyMessage $message) { } - public function secondMessage() + public function dummyMethodForCommands(DummyMessage $message) { } } -class HandlerOnSpecificBuses implements MessageSubscriberInterface +#[AsMessageHandler(handles: DummyMessage::class, bus: 'some_undefined_bus', method: 'dummyMethodForSomeBus')] +class HandlerOnUndefinedBus { - public static function getHandledMessages(): iterable - { - yield DummyMessage::class => ['method' => 'dummyMethodForEvents', 'bus' => 'event_bus']; - yield DummyMessage::class => ['method' => 'dummyMethodForCommands', 'bus' => 'command_bus']; - } - - public function dummyMethodForEvents() - { - } - - public function dummyMethodForCommands() - { - } -} - -class HandlerOnUndefinedBus implements MessageSubscriberInterface -{ - public static function getHandledMessages(): iterable - { - yield DummyMessage::class => ['method' => 'dummyMethodForSomeBus', 'bus' => 'some_undefined_bus']; - } - - public function dummyMethodForSomeBus() + public function dummyMethodForSomeBus(DummyMessage $message) { } } diff --git a/src/Symfony/Component/Messenger/Transport/InMemoryTransport.php b/src/Symfony/Component/Messenger/Transport/InMemoryTransport.php deleted file mode 100644 index a8941b00b67ad..0000000000000 --- a/src/Symfony/Component/Messenger/Transport/InMemoryTransport.php +++ /dev/null @@ -1,23 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Messenger\Transport; - -use Symfony\Component\Messenger\Transport\InMemory\InMemoryTransport as BaseInMemoryTransport; - -trigger_deprecation('symfony/messenger', '6.3', 'The "%s" class is deprecated, use "%s" instead. ', InMemoryTransport::class, BaseInMemoryTransport::class); - -/** - * @deprecated since Symfony 6.3, use {@link BaseInMemoryTransport} instead - */ -class InMemoryTransport extends BaseInMemoryTransport -{ -} diff --git a/src/Symfony/Component/Messenger/Transport/InMemoryTransportFactory.php b/src/Symfony/Component/Messenger/Transport/InMemoryTransportFactory.php deleted file mode 100644 index bdd4817d6a600..0000000000000 --- a/src/Symfony/Component/Messenger/Transport/InMemoryTransportFactory.php +++ /dev/null @@ -1,23 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Messenger\Transport; - -use Symfony\Component\Messenger\Transport\InMemory\InMemoryTransportFactory as BaseInMemoryTransportFactory; - -trigger_deprecation('symfony/messenger', '6.3', 'The "%s" class is deprecated, use "%s" instead. ', InMemoryTransportFactory::class, BaseInMemoryTransportFactory::class); - -/** - * @deprecated since Symfony 6.3, use {@link BaseInMemoryTransportFactory} instead - */ -class InMemoryTransportFactory extends BaseInMemoryTransportFactory -{ -} diff --git a/src/Symfony/Component/Mime/CHANGELOG.md b/src/Symfony/Component/Mime/CHANGELOG.md index 810018ba32327..8d593e6ff3e33 100644 --- a/src/Symfony/Component/Mime/CHANGELOG.md +++ b/src/Symfony/Component/Mime/CHANGELOG.md @@ -6,6 +6,7 @@ CHANGELOG * Remove `Email::attachPart()`, use `Email::addPart()` instead * Argument `$body` is now required (at least null) in `Message::setBody()` + * Require explicit argument when calling `Message::setBody()` 6.3 --- diff --git a/src/Symfony/Component/Notifier/Bridge/GoogleChat/CHANGELOG.md b/src/Symfony/Component/Notifier/Bridge/GoogleChat/CHANGELOG.md index c01ece62d544a..4e40ad9fce639 100644 --- a/src/Symfony/Component/Notifier/Bridge/GoogleChat/CHANGELOG.md +++ b/src/Symfony/Component/Notifier/Bridge/GoogleChat/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +7.0 +--- + + * Remove `GoogleChatOptions::card()` in favor of `cardV2()` + 6.3 --- diff --git a/src/Symfony/Component/Notifier/Bridge/GoogleChat/GoogleChatOptions.php b/src/Symfony/Component/Notifier/Bridge/GoogleChat/GoogleChatOptions.php index 231a5df4361d5..74b606f7588a3 100644 --- a/src/Symfony/Component/Notifier/Bridge/GoogleChat/GoogleChatOptions.php +++ b/src/Symfony/Component/Notifier/Bridge/GoogleChat/GoogleChatOptions.php @@ -61,20 +61,6 @@ public function toArray(): array return $this->options; } - /** - * @deprecated since Symfony 6.3, use "cardV2()" instead - * - * @return $this - */ - public function card(array $card): static - { - trigger_deprecation('symfony/google-chat-notifier', '6.3', '"%s()" is deprecated, use "cardV2()" instead.', __METHOD__); - - $this->options['cards'][] = $card; - - return $this; - } - /** * @return $this */ diff --git a/src/Symfony/Component/Notifier/Bridge/GoogleChat/Tests/GoogleChatOptionsTest.php b/src/Symfony/Component/Notifier/Bridge/GoogleChat/Tests/GoogleChatOptionsTest.php index 00984a60044c9..9c0ae8a0c0633 100644 --- a/src/Symfony/Component/Notifier/Bridge/GoogleChat/Tests/GoogleChatOptionsTest.php +++ b/src/Symfony/Component/Notifier/Bridge/GoogleChat/Tests/GoogleChatOptionsTest.php @@ -16,27 +16,6 @@ final class GoogleChatOptionsTest extends TestCase { - /** - * @group legacy - */ - public function testToArray() - { - $options = new GoogleChatOptions(); - - $options - ->text('Pizza Bot') - ->card(['header' => ['Pizza Bot Customer Support']]); - - $expected = [ - 'text' => 'Pizza Bot', - 'cards' => [ - ['header' => ['Pizza Bot Customer Support']], - ], - ]; - - $this->assertSame($expected, $options->toArray()); - } - public function testToArrayWithCardV2() { $options = new GoogleChatOptions(); diff --git a/src/Symfony/Component/Notifier/Bridge/Novu/Tests/NovuOptionsTest.php b/src/Symfony/Component/Notifier/Bridge/Novu/Tests/NovuOptionsTest.php index 6d1125bf18bb0..3bcf25100730f 100644 --- a/src/Symfony/Component/Notifier/Bridge/Novu/Tests/NovuOptionsTest.php +++ b/src/Symfony/Component/Notifier/Bridge/Novu/Tests/NovuOptionsTest.php @@ -16,9 +16,6 @@ class NovuOptionsTest extends TestCase { - /** - * @group legacy - */ public function testToArray() { $options = new NovuOptions( diff --git a/src/Symfony/Component/PropertyAccess/CHANGELOG.md b/src/Symfony/Component/PropertyAccess/CHANGELOG.md index 3d515960ad641..0dacd605277bf 100644 --- a/src/Symfony/Component/PropertyAccess/CHANGELOG.md +++ b/src/Symfony/Component/PropertyAccess/CHANGELOG.md @@ -5,6 +5,7 @@ CHANGELOG --- * Add method `isNullSafe()` to `PropertyPathInterface` + * Require explicit argument when calling `PropertyAccessorBuilder::setCacheItemPool()` 6.3 --- diff --git a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php index 0bf5c0afa903a..ac45dbe3b0010 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php +++ b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php @@ -290,14 +290,7 @@ private function readPropertiesUntil(array $zval, PropertyPathInterface $propert for ($i = 0; $i < $lastIndex; ++$i) { $property = $propertyPath->getElement($i); $isIndex = $propertyPath->isIndex($i); - - $isNullSafe = false; - if (method_exists($propertyPath, 'isNullSafe')) { - // To be removed in symfony 7 once we are sure isNullSafe is always implemented. - $isNullSafe = $propertyPath->isNullSafe($i); - } else { - trigger_deprecation('symfony/property-access', '6.2', 'The "%s()" method in class "%s" needs to be implemented in version 7.0, not defining it is deprecated.', 'isNullSafe', PropertyPathInterface::class); - } + $isNullSafe = $propertyPath->isNullSafe($i); if ($isIndex) { // Create missing nested arrays on demand diff --git a/src/Symfony/Component/PropertyAccess/PropertyAccessorBuilder.php b/src/Symfony/Component/PropertyAccess/PropertyAccessorBuilder.php index 51362afeb93a8..3a62b44dcdc76 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyAccessorBuilder.php +++ b/src/Symfony/Component/PropertyAccess/PropertyAccessorBuilder.php @@ -239,11 +239,8 @@ public function isExceptionOnInvalidPropertyPath(): bool * * @return $this */ - public function setCacheItemPool(CacheItemPoolInterface $cacheItemPool = null): static + public function setCacheItemPool(?CacheItemPoolInterface $cacheItemPool): static { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/property-access', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } $this->cacheItemPool = $cacheItemPool; return $this; diff --git a/src/Symfony/Component/PropertyAccess/composer.json b/src/Symfony/Component/PropertyAccess/composer.json index 95258ff7dd20f..376ee7e1afd0d 100644 --- a/src/Symfony/Component/PropertyAccess/composer.json +++ b/src/Symfony/Component/PropertyAccess/composer.json @@ -17,7 +17,6 @@ ], "require": { "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3", "symfony/property-info": "^6.4|^7.0" }, "require-dev": { diff --git a/src/Symfony/Component/Routing/Exception/MissingMandatoryParametersException.php b/src/Symfony/Component/Routing/Exception/MissingMandatoryParametersException.php index e5b83af6be2f1..37f0145c97a58 100644 --- a/src/Symfony/Component/Routing/Exception/MissingMandatoryParametersException.php +++ b/src/Symfony/Component/Routing/Exception/MissingMandatoryParametersException.php @@ -26,18 +26,11 @@ class MissingMandatoryParametersException extends \InvalidArgumentException impl * @param string[] $missingParameters * @param int $code */ - public function __construct(string $routeName = '', $missingParameters = null, $code = 0, \Throwable $previous = null) + public function __construct(string $routeName = '', array $missingParameters = [], int $code = 0, \Throwable $previous = null) { - if (\is_array($missingParameters)) { - $this->routeName = $routeName; - $this->missingParameters = $missingParameters; - $message = sprintf('Some mandatory parameters are missing ("%s") to generate a URL for route "%s".', implode('", "', $missingParameters), $routeName); - } else { - trigger_deprecation('symfony/routing', '6.1', 'Construction of "%s" with an exception message is deprecated, provide the route name and an array of missing parameters instead.', __CLASS__); - $message = $routeName; - $previous = $code instanceof \Throwable ? $code : null; - $code = (int) $missingParameters; - } + $this->routeName = $routeName; + $this->missingParameters = $missingParameters; + $message = sprintf('Some mandatory parameters are missing ("%s") to generate a URL for route "%s".', implode('", "', $missingParameters), $routeName); parent::__construct($message, $code, $previous); } diff --git a/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php b/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php index a6335b7ba856c..2c599730f0b09 100644 --- a/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php +++ b/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php @@ -321,29 +321,6 @@ public function testGenerateWithInvalidLocale() $generator->generate($name); } - /** - * @group legacy - */ - public function testLegacyThrowingMissingMandatoryParameters() - { - $this->expectDeprecation('Since symfony/routing 6.1: Construction of "Symfony\Component\Routing\Exception\MissingMandatoryParametersException" with an exception message is deprecated, provide the route name and an array of missing parameters instead.'); - - $exception = new MissingMandatoryParametersException('expected legacy message'); - $this->assertSame('expected legacy message', $exception->getMessage()); - } - - /** - * @group legacy - */ - public function testLegacyThrowingMissingMandatoryParametersWithAllParameters() - { - $this->expectDeprecation('Since symfony/routing 6.1: Construction of "Symfony\Component\Routing\Exception\MissingMandatoryParametersException" with an exception message is deprecated, provide the route name and an array of missing parameters instead.'); - - $exception = new MissingMandatoryParametersException('expected legacy message', 256, new \Exception()); - $this->assertSame('expected legacy message', $exception->getMessage()); - $this->assertInstanceOf(\Exception::class, $exception->getPrevious()); - } - public function testGenerateForRouteWithoutMandatoryParameter() { $this->expectException(MissingMandatoryParametersException::class); diff --git a/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php b/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php index 57f61c7e865f2..63186881afb33 100644 --- a/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php +++ b/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php @@ -186,7 +186,7 @@ public static function provideCompileData() /** * @dataProvider provideCompileImplicitUtf8Data */ - public function testCompileImplicitUtf8Data($name, $arguments, $prefix, $regex, $variables, $tokens, $deprecationType) + public function testCompileImplicitUtf8Data($name, $arguments, $prefix, $regex, $variables, $tokens) { $this->expectException(\LogicException::class); $r = new \ReflectionClass(Route::class); diff --git a/src/Symfony/Component/Security/Core/CHANGELOG.md b/src/Symfony/Component/Security/Core/CHANGELOG.md index b489556c919bb..663b5999cafce 100644 --- a/src/Symfony/Component/Security/Core/CHANGELOG.md +++ b/src/Symfony/Component/Security/Core/CHANGELOG.md @@ -1,6 +1,12 @@ CHANGELOG ========= +7.0 +--- + + * Remove the `Security` class, use `Symfony\Bundle\SecurityBundle\Security` instead + * Require explicit argument when calling `TokenStorage::setToken()` + 6.3 --- diff --git a/src/Symfony/Component/Security/Core/Security.php b/src/Symfony/Component/Security/Core/Security.php deleted file mode 100644 index bb2576a7ab9dc..0000000000000 --- a/src/Symfony/Component/Security/Core/Security.php +++ /dev/null @@ -1,69 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core; - -use Psr\Container\ContainerInterface; -use Symfony\Bundle\SecurityBundle\Security as NewSecurityHelper; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; -use Symfony\Component\Security\Core\User\UserInterface; - -/** - * Helper class for commonly-needed security tasks. - * - * @deprecated since Symfony 6.2, use \Symfony\Bundle\SecurityBundle\Security instead - */ -class Security implements AuthorizationCheckerInterface -{ - public const ACCESS_DENIED_ERROR = '_security.403_error'; - public const AUTHENTICATION_ERROR = '_security.last_error'; - public const LAST_USERNAME = '_security.last_username'; - - /** - * @deprecated since Symfony 6.2, use \Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge::MAX_USERNAME_LENGTH instead - */ - public const MAX_USERNAME_LENGTH = 4096; - - private ContainerInterface $container; - - public function __construct(ContainerInterface $container, bool $triggerDeprecation = true) - { - $this->container = $container; - - if ($triggerDeprecation) { - trigger_deprecation('symfony/security-core', '6.2', 'The "%s" class is deprecated, use "%s" instead.', __CLASS__, NewSecurityHelper::class); - } - } - - public function getUser(): ?UserInterface - { - if (!$token = $this->getToken()) { - return null; - } - - return $token->getUser(); - } - - /** - * Checks if the attributes are granted against the current authentication token and optionally supplied subject. - */ - public function isGranted(mixed $attributes, mixed $subject = null): bool - { - return $this->container->get('security.authorization_checker') - ->isGranted($attributes, $subject); - } - - public function getToken(): ?TokenInterface - { - return $this->container->get('security.token_storage')->getToken(); - } -} diff --git a/src/Symfony/Component/Security/Http/Authenticator/RemoteUserAuthenticator.php b/src/Symfony/Component/Security/Http/Authenticator/RemoteUserAuthenticator.php index 2cbb90a8767d8..946206c70fadb 100644 --- a/src/Symfony/Component/Security/Http/Authenticator/RemoteUserAuthenticator.php +++ b/src/Symfony/Component/Security/Http/Authenticator/RemoteUserAuthenticator.php @@ -24,11 +24,9 @@ * @author Fabien Potencier * @author Maxime Douailin * - * @final - * - * @internal in Symfony 5.1 + * @internal */ -class RemoteUserAuthenticator extends AbstractPreAuthenticatedAuthenticator +final class RemoteUserAuthenticator extends AbstractPreAuthenticatedAuthenticator { private string $userKey; diff --git a/src/Symfony/Component/Security/Http/EntryPoint/AuthenticationEntryPointInterface.php b/src/Symfony/Component/Security/Http/EntryPoint/AuthenticationEntryPointInterface.php index 91271d14a3d98..d4c7acd826028 100644 --- a/src/Symfony/Component/Security/Http/EntryPoint/AuthenticationEntryPointInterface.php +++ b/src/Symfony/Component/Security/Http/EntryPoint/AuthenticationEntryPointInterface.php @@ -39,8 +39,6 @@ interface AuthenticationEntryPointInterface * - For an API token authentication system, you return a 401 response * * return new Response('Auth header required', 401); - * - * @return Response */ - public function start(Request $request, AuthenticationException $authException = null); + public function start(Request $request, AuthenticationException $authException = null): Response; } diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php index 6e4d862d2c069..5b79943d24b3e 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php @@ -75,29 +75,6 @@ public static function getAuthenticationExceptionProvider() ]; } - /** - * This test should be removed in Symfony 7.0 when adding native return types to AuthenticationEntryPointInterface::start(). - * - * @group legacy - */ - public function testExceptionWhenEntryPointReturnsBadValue() - { - if ((new \ReflectionMethod(AuthenticationEntryPointInterface::class, 'start'))->hasReturnType()) { - $this->markTestSkipped('Native return type found'); - } - - $event = $this->createEvent(new AuthenticationException()); - - $entryPoint = $this->createMock(AuthenticationEntryPointInterface::class); - $entryPoint->expects($this->once())->method('start')->willReturn('NOT A RESPONSE'); - - $listener = $this->createExceptionListener(null, null, null, $entryPoint); - $listener->onKernelException($event); - // the exception has been replaced by our LogicException - $this->assertInstanceOf(\LogicException::class, $event->getThrowable()); - $this->assertStringEndsWith('start()" method must return a Response object ("string" returned).', $event->getThrowable()->getMessage()); - } - /** * @dataProvider getAccessDeniedExceptionProvider */ diff --git a/src/Symfony/Component/Serializer/CHANGELOG.md b/src/Symfony/Component/Serializer/CHANGELOG.md index 2eccea3cb1e2c..fad14fca498f9 100644 --- a/src/Symfony/Component/Serializer/CHANGELOG.md +++ b/src/Symfony/Component/Serializer/CHANGELOG.md @@ -10,7 +10,7 @@ CHANGELOG * Remove `ContextAwareDenormalizerInterface`, use `DenormalizerInterface` instead * Remove `ContextAwareNormalizerInterface`, use `NormalizerInterface` instead * Remove `CacheableSupportsMethodInterface`, use `NormalizerInterface` and `DenormalizerInterface` instead - * First argument of `AttributeMetadata::setSerializedName()` is now required + * Require explicit argument when calling `AttributeMetadata::setSerializedName()` and `ClassMetadata::setClassDiscriminatorMapping()` * Add argument `$context` to `NormalizerInterface::supportsNormalization()` and `DenormalizerInterface::supportsDenormalization()` 6.3 diff --git a/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php index 3d11567a7bfaa..7873f651a267b 100644 --- a/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php @@ -33,10 +33,8 @@ * * @author Nils Adermann * @author Kévin Dunglas - * - * @final since Symfony 6.3 */ -class GetSetMethodNormalizer extends AbstractObjectNormalizer +final class GetSetMethodNormalizer extends AbstractObjectNormalizer { private static $setterAccessibleCache = []; diff --git a/src/Symfony/Component/Serializer/Normalizer/PropertyNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/PropertyNormalizer.php index cfe93bc10b51a..d4c5a97e89bd9 100644 --- a/src/Symfony/Component/Serializer/Normalizer/PropertyNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/PropertyNormalizer.php @@ -33,10 +33,8 @@ * * @author Matthieu Napoli * @author Kévin Dunglas - * - * @final since Symfony 6.3 */ -class PropertyNormalizer extends AbstractObjectNormalizer +final class PropertyNormalizer extends AbstractObjectNormalizer { public const NORMALIZE_PUBLIC = 1; public const NORMALIZE_PROTECTED = 2; diff --git a/src/Symfony/Component/Translation/CHANGELOG.md b/src/Symfony/Component/Translation/CHANGELOG.md index 07ba0d031029e..eef7aa2d9bc60 100644 --- a/src/Symfony/Component/Translation/CHANGELOG.md +++ b/src/Symfony/Component/Translation/CHANGELOG.md @@ -1,6 +1,12 @@ CHANGELOG ========= +7.0 +--- + + * Remove `PhpStringTokenParser` + * Remove `PhpExtractor` in favor of `PhpAstExtractor` + 6.2.7 ----- diff --git a/src/Symfony/Component/Translation/Extractor/PhpExtractor.php b/src/Symfony/Component/Translation/Extractor/PhpExtractor.php deleted file mode 100644 index 7ff27f7c8096b..0000000000000 --- a/src/Symfony/Component/Translation/Extractor/PhpExtractor.php +++ /dev/null @@ -1,333 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Translation\Extractor; - -trigger_deprecation('symfony/translation', '6.2', '"%s" is deprecated, use "%s" instead.', PhpExtractor::class, PhpAstExtractor::class); - -use Symfony\Component\Finder\Finder; -use Symfony\Component\Translation\MessageCatalogue; - -/** - * PhpExtractor extracts translation messages from a PHP template. - * - * @author Michel Salib - * - * @deprecated since Symfony 6.2, use the PhpAstExtractor instead - */ -class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface -{ - public const MESSAGE_TOKEN = 300; - public const METHOD_ARGUMENTS_TOKEN = 1000; - public const DOMAIN_TOKEN = 1001; - - /** - * Prefix for new found message. - */ - private string $prefix = ''; - - /** - * The sequence that captures translation messages. - */ - protected $sequences = [ - [ - '->', - 'trans', - '(', - self::MESSAGE_TOKEN, - ',', - self::METHOD_ARGUMENTS_TOKEN, - ',', - self::DOMAIN_TOKEN, - ], - [ - '->', - 'trans', - '(', - self::MESSAGE_TOKEN, - ], - [ - 'new', - 'TranslatableMessage', - '(', - self::MESSAGE_TOKEN, - ',', - self::METHOD_ARGUMENTS_TOKEN, - ',', - self::DOMAIN_TOKEN, - ], - [ - 'new', - 'TranslatableMessage', - '(', - self::MESSAGE_TOKEN, - ], - [ - 'new', - '\\', - 'Symfony', - '\\', - 'Component', - '\\', - 'Translation', - '\\', - 'TranslatableMessage', - '(', - self::MESSAGE_TOKEN, - ',', - self::METHOD_ARGUMENTS_TOKEN, - ',', - self::DOMAIN_TOKEN, - ], - [ - 'new', - '\Symfony\Component\Translation\TranslatableMessage', - '(', - self::MESSAGE_TOKEN, - ',', - self::METHOD_ARGUMENTS_TOKEN, - ',', - self::DOMAIN_TOKEN, - ], - [ - 'new', - '\\', - 'Symfony', - '\\', - 'Component', - '\\', - 'Translation', - '\\', - 'TranslatableMessage', - '(', - self::MESSAGE_TOKEN, - ], - [ - 'new', - '\Symfony\Component\Translation\TranslatableMessage', - '(', - self::MESSAGE_TOKEN, - ], - [ - 't', - '(', - self::MESSAGE_TOKEN, - ',', - self::METHOD_ARGUMENTS_TOKEN, - ',', - self::DOMAIN_TOKEN, - ], - [ - 't', - '(', - self::MESSAGE_TOKEN, - ], - ]; - - /** - * @return void - */ - public function extract(string|iterable $resource, MessageCatalogue $catalog) - { - $files = $this->extractFiles($resource); - foreach ($files as $file) { - $this->parseTokens(token_get_all(file_get_contents($file)), $catalog, $file); - - gc_mem_caches(); - } - } - - /** - * @return void - */ - public function setPrefix(string $prefix) - { - $this->prefix = $prefix; - } - - /** - * Normalizes a token. - */ - protected function normalizeToken(mixed $token): ?string - { - if (isset($token[1]) && 'b"' !== $token) { - return $token[1]; - } - - return $token; - } - - /** - * Seeks to a non-whitespace token. - */ - private function seekToNextRelevantToken(\Iterator $tokenIterator): void - { - for (; $tokenIterator->valid(); $tokenIterator->next()) { - $t = $tokenIterator->current(); - if (\T_WHITESPACE !== $t[0]) { - break; - } - } - } - - private function skipMethodArgument(\Iterator $tokenIterator): void - { - $openBraces = 0; - - for (; $tokenIterator->valid(); $tokenIterator->next()) { - $t = $tokenIterator->current(); - - if ('[' === $t[0] || '(' === $t[0]) { - ++$openBraces; - } - - if (']' === $t[0] || ')' === $t[0]) { - --$openBraces; - } - - if ((0 === $openBraces && ',' === $t[0]) || (-1 === $openBraces && ')' === $t[0])) { - break; - } - } - } - - /** - * Extracts the message from the iterator while the tokens - * match allowed message tokens. - */ - private function getValue(\Iterator $tokenIterator): string - { - $message = ''; - $docToken = ''; - $docPart = ''; - - for (; $tokenIterator->valid(); $tokenIterator->next()) { - $t = $tokenIterator->current(); - if ('.' === $t) { - // Concatenate with next token - continue; - } - if (!isset($t[1])) { - break; - } - - switch ($t[0]) { - case \T_START_HEREDOC: - $docToken = $t[1]; - break; - case \T_ENCAPSED_AND_WHITESPACE: - case \T_CONSTANT_ENCAPSED_STRING: - if ('' === $docToken) { - $message .= PhpStringTokenParser::parse($t[1]); - } else { - $docPart = $t[1]; - } - break; - case \T_END_HEREDOC: - if ($indentation = strspn($t[1], ' ')) { - $docPartWithLineBreaks = $docPart; - $docPart = ''; - - foreach (preg_split('~(\r\n|\n|\r)~', $docPartWithLineBreaks, -1, \PREG_SPLIT_DELIM_CAPTURE) as $str) { - if (\in_array($str, ["\r\n", "\n", "\r"], true)) { - $docPart .= $str; - } else { - $docPart .= substr($str, $indentation); - } - } - } - - $message .= PhpStringTokenParser::parseDocString($docToken, $docPart); - $docToken = ''; - $docPart = ''; - break; - case \T_WHITESPACE: - break; - default: - break 2; - } - } - - return $message; - } - - /** - * Extracts trans message from PHP tokens. - * - * @return void - */ - protected function parseTokens(array $tokens, MessageCatalogue $catalog, string $filename) - { - $tokenIterator = new \ArrayIterator($tokens); - - for ($key = 0; $key < $tokenIterator->count(); ++$key) { - foreach ($this->sequences as $sequence) { - $message = ''; - $domain = 'messages'; - $tokenIterator->seek($key); - - foreach ($sequence as $sequenceKey => $item) { - $this->seekToNextRelevantToken($tokenIterator); - - if ($this->normalizeToken($tokenIterator->current()) === $item) { - $tokenIterator->next(); - continue; - } elseif (self::MESSAGE_TOKEN === $item) { - $message = $this->getValue($tokenIterator); - - if (\count($sequence) === ($sequenceKey + 1)) { - break; - } - } elseif (self::METHOD_ARGUMENTS_TOKEN === $item) { - $this->skipMethodArgument($tokenIterator); - } elseif (self::DOMAIN_TOKEN === $item) { - $domainToken = $this->getValue($tokenIterator); - if ('' !== $domainToken) { - $domain = $domainToken; - } - - break; - } else { - break; - } - } - - if ($message) { - $catalog->set($message, $this->prefix.$message, $domain); - $metadata = $catalog->getMetadata($message, $domain) ?? []; - $normalizedFilename = preg_replace('{[\\\\/]+}', '/', $filename); - $metadata['sources'][] = $normalizedFilename.':'.$tokens[$key][2]; - $catalog->setMetadata($message, $metadata, $domain); - break; - } - } - } - } - - /** - * @throws \InvalidArgumentException - */ - protected function canBeExtracted(string $file): bool - { - return $this->isFile($file) && 'php' === pathinfo($file, \PATHINFO_EXTENSION); - } - - protected function extractFromDirectory(string|array $directory): iterable - { - if (!class_exists(Finder::class)) { - throw new \LogicException(sprintf('You cannot use "%s" as the "symfony/finder" package is not installed. Try running "composer require symfony/finder".', static::class)); - } - - $finder = new Finder(); - - return $finder->files()->name('*.php')->in($directory); - } -} diff --git a/src/Symfony/Component/Translation/Extractor/PhpStringTokenParser.php b/src/Symfony/Component/Translation/Extractor/PhpStringTokenParser.php deleted file mode 100644 index 3b854ce73cb38..0000000000000 --- a/src/Symfony/Component/Translation/Extractor/PhpStringTokenParser.php +++ /dev/null @@ -1,141 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Translation\Extractor; - -trigger_deprecation('symfony/translation', '6.2', '"%s" is deprecated.', PhpStringTokenParser::class); - -/* - * The following is derived from code at http://github.com/nikic/PHP-Parser - * - * Copyright (c) 2011 by Nikita Popov - * - * Some rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * * The names of the contributors may not be used to endorse or - * promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @deprecated since Symfony 6.2 - */ -class PhpStringTokenParser -{ - protected static $replacements = [ - '\\' => '\\', - '$' => '$', - 'n' => "\n", - 'r' => "\r", - 't' => "\t", - 'f' => "\f", - 'v' => "\v", - 'e' => "\x1B", - ]; - - /** - * Parses a string token. - * - * @param string $str String token content - */ - public static function parse(string $str): string - { - $bLength = 0; - if ('b' === $str[0]) { - $bLength = 1; - } - - if ('\'' === $str[$bLength]) { - return str_replace( - ['\\\\', '\\\''], - ['\\', '\''], - substr($str, $bLength + 1, -1) - ); - } else { - return self::parseEscapeSequences(substr($str, $bLength + 1, -1), '"'); - } - } - - /** - * Parses escape sequences in strings (all string types apart from single quoted). - * - * @param string $str String without quotes - * @param string|null $quote Quote type - */ - public static function parseEscapeSequences(string $str, string $quote = null): string - { - if (null !== $quote) { - $str = str_replace('\\'.$quote, $quote, $str); - } - - return preg_replace_callback( - '~\\\\([\\\\$nrtfve]|[xX][0-9a-fA-F]{1,2}|[0-7]{1,3})~', - [__CLASS__, 'parseCallback'], - $str - ); - } - - private static function parseCallback(array $matches): string - { - $str = $matches[1]; - - if (isset(self::$replacements[$str])) { - return self::$replacements[$str]; - } elseif ('x' === $str[0] || 'X' === $str[0]) { - return \chr(hexdec($str)); - } else { - return \chr(octdec($str)); - } - } - - /** - * Parses a constant doc string. - * - * @param string $startToken Doc string start token content (<< - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Translation\Tests\Extractor; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Translation\Extractor\PhpExtractor; -use Symfony\Component\Translation\MessageCatalogue; - -/** - * @group legacy - */ -class PhpExtractorTest extends TestCase -{ - /** - * @dataProvider resourcesProvider - * - * @param array|string $resource - */ - public function testExtraction($resource) - { - // Arrange - $extractor = new PhpExtractor(); - $extractor->setPrefix('prefix'); - $catalogue = new MessageCatalogue('en'); - - // Act - $extractor->extract($resource, $catalogue); - - $expectedHeredoc = << [ - 'translatable single-quoted key' => 'prefixtranslatable single-quoted key', - 'translatable double-quoted key' => 'prefixtranslatable double-quoted key', - 'translatable heredoc key' => 'prefixtranslatable heredoc key', - 'translatable nowdoc key' => 'prefixtranslatable nowdoc key', - "translatable double-quoted key with whitespace and escaped \$\n\" sequences" => "prefixtranslatable double-quoted key with whitespace and escaped \$\n\" sequences", - 'translatable single-quoted key with whitespace and nonescaped \$\n\' sequences' => 'prefixtranslatable single-quoted key with whitespace and nonescaped \$\n\' sequences', - 'translatable single-quoted key with "quote mark at the end"' => 'prefixtranslatable single-quoted key with "quote mark at the end"', - 'translatable '.$expectedHeredoc => 'prefixtranslatable '.$expectedHeredoc, - 'translatable '.$expectedNowdoc => 'prefixtranslatable '.$expectedNowdoc, - 'translatable concatenated message with heredoc and nowdoc' => 'prefixtranslatable concatenated message with heredoc and nowdoc', - 'translatable default domain' => 'prefixtranslatable default domain', - 'translatable-fqn single-quoted key' => 'prefixtranslatable-fqn single-quoted key', - 'translatable-fqn double-quoted key' => 'prefixtranslatable-fqn double-quoted key', - 'translatable-fqn heredoc key' => 'prefixtranslatable-fqn heredoc key', - 'translatable-fqn nowdoc key' => 'prefixtranslatable-fqn nowdoc key', - "translatable-fqn double-quoted key with whitespace and escaped \$\n\" sequences" => "prefixtranslatable-fqn double-quoted key with whitespace and escaped \$\n\" sequences", - 'translatable-fqn single-quoted key with whitespace and nonescaped \$\n\' sequences' => 'prefixtranslatable-fqn single-quoted key with whitespace and nonescaped \$\n\' sequences', - 'translatable-fqn single-quoted key with "quote mark at the end"' => 'prefixtranslatable-fqn single-quoted key with "quote mark at the end"', - 'translatable-fqn '.$expectedHeredoc => 'prefixtranslatable-fqn '.$expectedHeredoc, - 'translatable-fqn '.$expectedNowdoc => 'prefixtranslatable-fqn '.$expectedNowdoc, - 'translatable-fqn concatenated message with heredoc and nowdoc' => 'prefixtranslatable-fqn concatenated message with heredoc and nowdoc', - 'translatable-fqn default domain' => 'prefixtranslatable-fqn default domain', - 'translatable-short single-quoted key' => 'prefixtranslatable-short single-quoted key', - 'translatable-short double-quoted key' => 'prefixtranslatable-short double-quoted key', - 'translatable-short heredoc key' => 'prefixtranslatable-short heredoc key', - 'translatable-short nowdoc key' => 'prefixtranslatable-short nowdoc key', - "translatable-short double-quoted key with whitespace and escaped \$\n\" sequences" => "prefixtranslatable-short double-quoted key with whitespace and escaped \$\n\" sequences", - 'translatable-short single-quoted key with whitespace and nonescaped \$\n\' sequences' => 'prefixtranslatable-short single-quoted key with whitespace and nonescaped \$\n\' sequences', - 'translatable-short single-quoted key with "quote mark at the end"' => 'prefixtranslatable-short single-quoted key with "quote mark at the end"', - 'translatable-short '.$expectedHeredoc => 'prefixtranslatable-short '.$expectedHeredoc, - 'translatable-short '.$expectedNowdoc => 'prefixtranslatable-short '.$expectedNowdoc, - 'translatable-short concatenated message with heredoc and nowdoc' => 'prefixtranslatable-short concatenated message with heredoc and nowdoc', - 'translatable-short default domain' => 'prefixtranslatable-short default domain', - 'single-quoted key' => 'prefixsingle-quoted key', - 'double-quoted key' => 'prefixdouble-quoted key', - 'heredoc key' => 'prefixheredoc key', - 'nowdoc key' => 'prefixnowdoc key', - "double-quoted key with whitespace and escaped \$\n\" sequences" => "prefixdouble-quoted key with whitespace and escaped \$\n\" sequences", - 'single-quoted key with whitespace and nonescaped \$\n\' sequences' => 'prefixsingle-quoted key with whitespace and nonescaped \$\n\' sequences', - 'single-quoted key with "quote mark at the end"' => 'prefixsingle-quoted key with "quote mark at the end"', - $expectedHeredoc => 'prefix'.$expectedHeredoc, - $expectedNowdoc => 'prefix'.$expectedNowdoc, - 'concatenated message with heredoc and nowdoc' => 'prefixconcatenated message with heredoc and nowdoc', - 'default domain' => 'prefixdefault domain', - ], - 'not_messages' => [ - 'translatable other-domain-test-no-params-short-array' => 'prefixtranslatable other-domain-test-no-params-short-array', - 'translatable other-domain-test-no-params-long-array' => 'prefixtranslatable other-domain-test-no-params-long-array', - 'translatable other-domain-test-params-short-array' => 'prefixtranslatable other-domain-test-params-short-array', - 'translatable other-domain-test-params-long-array' => 'prefixtranslatable other-domain-test-params-long-array', - 'translatable typecast' => 'prefixtranslatable typecast', - 'translatable-fqn other-domain-test-no-params-short-array' => 'prefixtranslatable-fqn other-domain-test-no-params-short-array', - 'translatable-fqn other-domain-test-no-params-long-array' => 'prefixtranslatable-fqn other-domain-test-no-params-long-array', - 'translatable-fqn other-domain-test-params-short-array' => 'prefixtranslatable-fqn other-domain-test-params-short-array', - 'translatable-fqn other-domain-test-params-long-array' => 'prefixtranslatable-fqn other-domain-test-params-long-array', - 'translatable-fqn typecast' => 'prefixtranslatable-fqn typecast', - 'translatable-short other-domain-test-no-params-short-array' => 'prefixtranslatable-short other-domain-test-no-params-short-array', - 'translatable-short other-domain-test-no-params-long-array' => 'prefixtranslatable-short other-domain-test-no-params-long-array', - 'translatable-short other-domain-test-params-short-array' => 'prefixtranslatable-short other-domain-test-params-short-array', - 'translatable-short other-domain-test-params-long-array' => 'prefixtranslatable-short other-domain-test-params-long-array', - 'translatable-short typecast' => 'prefixtranslatable-short typecast', - 'other-domain-test-no-params-short-array' => 'prefixother-domain-test-no-params-short-array', - 'other-domain-test-no-params-long-array' => 'prefixother-domain-test-no-params-long-array', - 'other-domain-test-params-short-array' => 'prefixother-domain-test-params-short-array', - 'other-domain-test-params-long-array' => 'prefixother-domain-test-params-long-array', - 'typecast' => 'prefixtypecast', - ], - ]; - $actualCatalogue = $catalogue->all(); - - $this->assertEquals($expectedCatalogue, $actualCatalogue); - - $filename = str_replace(\DIRECTORY_SEPARATOR, '/', __DIR__).'/../fixtures/extractor/translatable.html.php'; - $this->assertEquals(['sources' => [$filename.':2']], $catalogue->getMetadata('translatable single-quoted key')); - $this->assertEquals(['sources' => [$filename.':37']], $catalogue->getMetadata('translatable other-domain-test-no-params-short-array', 'not_messages')); - - $filename = str_replace(\DIRECTORY_SEPARATOR, '/', __DIR__).'/../fixtures/extractor/translatable-fqn.html.php'; - $this->assertEquals(['sources' => [$filename.':2']], $catalogue->getMetadata('translatable-fqn single-quoted key')); - $this->assertEquals(['sources' => [$filename.':37']], $catalogue->getMetadata('translatable-fqn other-domain-test-no-params-short-array', 'not_messages')); - - $filename = str_replace(\DIRECTORY_SEPARATOR, '/', __DIR__).'/../fixtures/extractor/translatable-short.html.php'; - $this->assertEquals(['sources' => [$filename.':2']], $catalogue->getMetadata('translatable-short single-quoted key')); - $this->assertEquals(['sources' => [$filename.':37']], $catalogue->getMetadata('translatable-short other-domain-test-no-params-short-array', 'not_messages')); - - $filename = str_replace(\DIRECTORY_SEPARATOR, '/', __DIR__).'/../fixtures/extractor/translation.html.php'; - $this->assertEquals(['sources' => [$filename.':2']], $catalogue->getMetadata('single-quoted key')); - $this->assertEquals(['sources' => [$filename.':37']], $catalogue->getMetadata('other-domain-test-no-params-short-array', 'not_messages')); - } - - public function testExtractionFromIndentedHeredocNowdoc() - { - $catalogue = new MessageCatalogue('en'); - - $extractor = new PhpExtractor(); - $extractor->setPrefix('prefix'); - $extractor->extract(__DIR__.'/../fixtures/extractor-7.3/translation.html.php', $catalogue); - - $expectedCatalogue = [ - 'messages' => [ - "heredoc\nindented\n further" => "prefixheredoc\nindented\n further", - "nowdoc\nindented\n further" => "prefixnowdoc\nindented\n further", - ], - ]; - - $this->assertEquals($expectedCatalogue, $catalogue->all()); - } - - public static function resourcesProvider() - { - $directory = __DIR__.'/../fixtures/extractor/'; - $phpFiles = []; - $splFiles = []; - foreach (new \DirectoryIterator($directory) as $fileInfo) { - if ($fileInfo->isDot()) { - continue; - } - if (\in_array($fileInfo->getBasename(), ['translatable.html.php', 'translatable-fqn.html.php', 'translatable-short.html.php', 'translation.html.php'], true)) { - $phpFiles[] = $fileInfo->getPathname(); - } - $splFiles[] = $fileInfo->getFileInfo(); - } - - return [ - [$directory], - [$phpFiles], - [glob($directory.'*')], - [$splFiles], - [new \ArrayObject(glob($directory.'*'))], - [new \ArrayObject($splFiles)], - ]; - } -} diff --git a/src/Symfony/Component/VarDumper/CHANGELOG.md b/src/Symfony/Component/VarDumper/CHANGELOG.md index 4c3bba6636fa4..9843da0d82151 100644 --- a/src/Symfony/Component/VarDumper/CHANGELOG.md +++ b/src/Symfony/Component/VarDumper/CHANGELOG.md @@ -5,6 +5,7 @@ CHANGELOG --- * Add argument `$label` to `VarDumper::dump()` + * Require explicit argument when calling `VarDumper::setHandler()` 6.3 --- diff --git a/src/Symfony/Component/VarDumper/VarDumper.php b/src/Symfony/Component/VarDumper/VarDumper.php index a89f2369bb015..eda2727d50709 100644 --- a/src/Symfony/Component/VarDumper/VarDumper.php +++ b/src/Symfony/Component/VarDumper/VarDumper.php @@ -38,8 +38,6 @@ class VarDumper private static $handler; /** - * @param string|null $label - * * @return mixed */ public static function dump(mixed $var, string $label = null) @@ -51,11 +49,8 @@ public static function dump(mixed $var, string $label = null) return (self::$handler)($var, $label); } - public static function setHandler(callable $callable = null): ?callable + public static function setHandler(?callable $callable): ?callable { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/var-dumper', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } $prevHandler = self::$handler; // Prevent replacing the handler with expected format as soon as the env var was set: diff --git a/src/Symfony/Component/Workflow/CHANGELOG.md b/src/Symfony/Component/Workflow/CHANGELOG.md index ff7162853d0fa..bec98b076e98d 100644 --- a/src/Symfony/Component/Workflow/CHANGELOG.md +++ b/src/Symfony/Component/Workflow/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +7.0 +--- + + * Require explicit argument when calling `Definition::setInitialPlaces()` + 6.4 --- diff --git a/src/Symfony/Component/Workflow/Definition.php b/src/Symfony/Component/Workflow/Definition.php index cdb180976895e..91172dcebce82 100644 --- a/src/Symfony/Component/Workflow/Definition.php +++ b/src/Symfony/Component/Workflow/Definition.php @@ -76,11 +76,8 @@ public function getMetadataStore(): MetadataStoreInterface return $this->metadataStore; } - private function setInitialPlaces(string|array $places = null): void + private function setInitialPlaces(string|array|null $places): void { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/workflow', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } if (!$places) { return; } diff --git a/src/Symfony/Component/Workflow/Registry.php b/src/Symfony/Component/Workflow/Registry.php index 287d8b750f9b4..ad72693c5a64f 100644 --- a/src/Symfony/Component/Workflow/Registry.php +++ b/src/Symfony/Component/Workflow/Registry.php @@ -18,7 +18,7 @@ * @author Fabien Potencier * @author Grégoire Pineau * - * @internal since Symfony 6.2. Inject the workflow where you need it. + * @internal */ class Registry { diff --git a/src/Symfony/Component/Yaml/CHANGELOG.md b/src/Symfony/Component/Yaml/CHANGELOG.md index 0c2021f48b2ef..4342bb3cd490c 100644 --- a/src/Symfony/Component/Yaml/CHANGELOG.md +++ b/src/Symfony/Component/Yaml/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +7.0 +--- + + * Remove the `!php/const:` tag, use `!php/const` instead (without the colon) + 6.3 --- diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index ddfbcfd83a06f..fb0bfeaa69766 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -198,14 +198,9 @@ private function doParse(string $value, int $flags): mixed array_pop($this->refsBeingParsed); } } elseif ( - // @todo in 7.0 remove legacy "(?:!?!php/const:)?" - self::preg_match('#^(?P(?:![^\s]++\s++)?(?:'.Inline::REGEX_QUOTED_STRING.'|(?:!?!php/const:)?[^ \'"\[\{!].*?)) *\:(( |\t)++(?P.+))?$#u', rtrim($this->currentLine), $values) + self::preg_match('#^(?P(?:![^\s]++\s++)?(?:'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\[\{!].*?)) *\:(( |\t)++(?P.+))?$#u', rtrim($this->currentLine), $values) && (!str_contains($values['key'], ' #') || \in_array($values['key'][0], ['"', "'"])) ) { - if (str_starts_with($values['key'], '!php/const:')) { - trigger_deprecation('symfony/yaml', '6.2', 'YAML syntax for key "%s" is deprecated and replaced by "!php/const %s".', $values['key'], substr($values['key'], 11)); - } - if ($context && 'sequence' == $context) { throw new ParseException('You cannot define a mapping item when in a sequence.', $this->currentLineNb + 1, $this->currentLine, $this->filename); } @@ -413,7 +408,7 @@ private function doParse(string $value, int $flags): mixed throw new ParseException('Multiple documents are not supported.', $this->currentLineNb + 1, $this->currentLine, $this->filename); } - if ($deprecatedUsage = (isset($this->currentLine[1]) && '?' === $this->currentLine[0] && ' ' === $this->currentLine[1])) { + if (isset($this->currentLine[1]) && '?' === $this->currentLine[0] && ' ' === $this->currentLine[1]) { throw new ParseException('Complex mappings are not supported.', $this->getRealCurrentLineNb() + 1, $this->currentLine); } @@ -443,7 +438,7 @@ private function doParse(string $value, int $flags): mixed continue; } // If the indentation is not consistent at offset 0, it is to be considered as a ParseError - if (0 === $this->offset && !$deprecatedUsage && isset($line[0]) && ' ' === $line[0]) { + if (0 === $this->offset && isset($line[0]) && ' ' === $line[0]) { throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); } diff --git a/src/Symfony/Component/Yaml/Tests/InlineTest.php b/src/Symfony/Component/Yaml/Tests/InlineTest.php index e5da4c224e422..4a3543d121574 100644 --- a/src/Symfony/Component/Yaml/Tests/InlineTest.php +++ b/src/Symfony/Component/Yaml/Tests/InlineTest.php @@ -824,7 +824,7 @@ public function testTheEmptyStringIsAValidMappingKey() /** * @dataProvider getNotPhpCompatibleMappingKeyData */ - public function testImplicitStringCastingOfMappingKeysIsDeprecated($yaml, $expected) + public function testImplicitStringCastingOfMappingKeysThrows($yaml, $expected) { $this->expectException(ParseException::class); $this->expectExceptionMessage('Implicit casting of incompatible mapping keys to strings is not supported. Quote your evaluable mapping keys instead'); diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index 2918d1b07c337..5d1968252bb2d 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Yaml\Tests; use PHPUnit\Framework\TestCase; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\Yaml\Exception\ParseException; use Symfony\Component\Yaml\Parser; use Symfony\Component\Yaml\Tag\TaggedValue; @@ -20,8 +19,6 @@ class ParserTest extends TestCase { - use ExpectDeprecationTrait; - private ?Parser $parser; protected function setUp(): void @@ -662,7 +659,7 @@ public function testObjectsSupportDisabledWithExceptions() $this->parser->parse($yaml, Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE); } - public function testMappingKeyInMultiLineStringTriggersDeprecationNotice() + public function testMappingKeyInMultiLineStringThrowsException() { $this->expectException(ParseException::class); $this->expectExceptionMessage('Mapping values are not allowed in multi-line blocks at line 2 (near "dbal:wrong").'); @@ -2483,7 +2480,7 @@ public function testPhpConstantTagMappingKey() $this->assertSame($expected, $this->parser->parse($yaml, Yaml::PARSE_CONSTANT)); } - public function testDeprecatedPhpConstantSyntax() + public function testWrongPhpConstantSyntax() { $this->expectException(ParseException::class); $this->expectExceptionMessage('Missing value for tag "php/const:App\Kernel::SEMART_VERSION" at line 1 (near "!php/const:App\Kernel::SEMART_VERSION").'); @@ -2491,17 +2488,6 @@ public function testDeprecatedPhpConstantSyntax() $this->parser->parse('!php/const:App\Kernel::SEMART_VERSION', Yaml::PARSE_CUSTOM_TAGS | Yaml::PARSE_CONSTANT); } - /** - * @group legacy - */ - public function testDeprecatedPhpConstantSyntaxAsScalarKey() - { - $this->expectDeprecation('Since symfony/yaml 6.2: YAML syntax for key "!php/const:Symfony\Component\Yaml\Tests\B::BAR" is deprecated and replaced by "!php/const Symfony\Component\Yaml\Tests\B::BAR".'); - $actual = $this->parser->parse('!php/const:Symfony\Component\Yaml\Tests\B::BAR: value', Yaml::PARSE_CUSTOM_TAGS | Yaml::PARSE_CONSTANT); - - $this->assertSame(['bar' => 'value'], $actual); - } - public function testPhpConstantTagMappingAsScalarKey() { $yaml = << - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Contracts\Service\Test; - -class_alias(ServiceLocatorTestCase::class, ServiceLocatorTest::class); - -if (false) { - /** - * @deprecated since PHPUnit 9.6 - */ - class ServiceLocatorTest - { - } -} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy