From 320c757aeb4e8fbc2ec3aab865c40519a513682b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20TAMARELLE?= Date: Tue, 26 Oct 2021 00:19:55 +0200 Subject: [PATCH 1/3] [Form] UrlType should not add protocol to emails --- UPGRADE-5.4.md | 1 + .../AbstractBootstrap3LayoutTest.php | 4 +- src/Symfony/Component/Form/CHANGELOG.md | 1 + .../EventListener/FixUrlProtocolListener.php | 15 +++++++ .../Form/Extension/Core/Type/UrlType.php | 10 ++++- .../Form/Tests/AbstractLayoutTest.php | 4 +- .../FixUrlProtocolListenerTest.php | 37 ++++++++++++------ .../Extension/Core/Type/TextTypeTest.php | 8 ++-- .../Extension/Core/Type/UrlTypeLegacyTest.php | 36 +++++++++++++++++ .../Tests/Extension/Core/Type/UrlTypeTest.php | 39 +++++++++++++------ 10 files changed, 123 insertions(+), 32 deletions(-) create mode 100644 src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeLegacyTest.php diff --git a/UPGRADE-5.4.md b/UPGRADE-5.4.md index c5542c4dcf632..de8309412d46b 100644 --- a/UPGRADE-5.4.md +++ b/UPGRADE-5.4.md @@ -22,6 +22,7 @@ Form ------ * Deprecate calling `FormErrorIterator::children()` if the current element is not iterable. + * Add `'default_protocol_skip_email' => true` to `UrlType` options. FrameworkBundle --------------- diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php index 73ec1c18277e2..40ab3e07da651 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php @@ -2648,7 +2648,7 @@ public function testTimezoneWithPlaceholder() public function testUrlWithDefaultProtocol() { $url = 'http://www.example.com?foo1=bar1&foo2=bar2'; - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => 'http']); + $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => 'http', 'default_protocol_skip_email' => true]); $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']], '/input @@ -2664,7 +2664,7 @@ public function testUrlWithDefaultProtocol() public function testUrlWithoutDefaultProtocol() { $url = 'http://www.example.com?foo1=bar1&foo2=bar2'; - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => null]); + $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => null, 'default_protocol_skip_email' => true]); $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']], '/input diff --git a/src/Symfony/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md index 9d7e76445500e..b6b705b9e1c24 100644 --- a/src/Symfony/Component/Form/CHANGELOG.md +++ b/src/Symfony/Component/Form/CHANGELOG.md @@ -7,6 +7,7 @@ CHANGELOG * Deprecate calling `FormErrorIterator::children()` if the current element is not iterable. * Allow to pass `TranslatableMessage` objects to the `help` option * Add the `EnumType` + * Deprecate usage of `UrlType` without option `'default_protocol_skip_email' => true`, added to prevent emails from being converted to valid URLs. 5.3 --- diff --git a/src/Symfony/Component/Form/Extension/Core/EventListener/FixUrlProtocolListener.php b/src/Symfony/Component/Form/Extension/Core/EventListener/FixUrlProtocolListener.php index 53dd4ee8711d2..c26bcd2619a57 100644 --- a/src/Symfony/Component/Form/Extension/Core/EventListener/FixUrlProtocolListener.php +++ b/src/Symfony/Component/Form/Extension/Core/EventListener/FixUrlProtocolListener.php @@ -23,6 +23,7 @@ class FixUrlProtocolListener implements EventSubscriberInterface { private $defaultProtocol; + private $skipEmail = false; /** * @param string|null $defaultProtocol The URL scheme to add when there is none or null to not modify the data @@ -32,11 +33,25 @@ public function __construct(?string $defaultProtocol = 'http') $this->defaultProtocol = $defaultProtocol; } + /** + * @param bool $skipEmail the URL scheme is not added to values that match an email pattern + */ + public function skipEmail(): void + { + $this->skipEmail = true; + } + public function onSubmit(FormEvent $event) { $data = $event->getData(); if ($this->defaultProtocol && $data && \is_string($data) && !preg_match('~^[\w+.-]+://~', $data)) { + if (preg_match('~^[^:/]+@[A-Za-z0-9-.]+\.[A-Za-z0-9]+$~', $data)) { + if ($this->skipEmail) { + return; + } + trigger_deprecation('symfony/form', '5.4', 'Class "%s", will add a scheme to urls that looks like emails in 6.0. Call "setIgnoreEmail(true)"', __CLASS__); + } $event->setData($this->defaultProtocol.'://'.$data); } } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/UrlType.php b/src/Symfony/Component/Form/Extension/Core/Type/UrlType.php index f294a10ac25b6..a3d36fc7ca930 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/UrlType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/UrlType.php @@ -27,7 +27,13 @@ class UrlType extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options) { if (null !== $options['default_protocol']) { - $builder->addEventSubscriber(new FixUrlProtocolListener($options['default_protocol'])); + $subscriber = new FixUrlProtocolListener($options['default_protocol']); + if ($options['default_protocol_skip_email']) { + $subscriber->skipEmail(); + } else { + trigger_deprecation('symfony/form', '5.4', 'Type "%s" option "default_protocol_skip_email" will be "true" in 6.0.', static::class); + } + $builder->addEventSubscriber($subscriber); } } @@ -54,9 +60,11 @@ public function configureOptions(OptionsResolver $resolver) ? $previousValue : 'Please enter a valid URL.'; }, + 'default_protocol_skip_email' => false, ]); $resolver->setAllowedTypes('default_protocol', ['null', 'string']); + $resolver->setAllowedTypes('default_protocol_skip_email', 'bool'); } /** diff --git a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php index 4b5d18b86793f..1f1b8d8c8e4ae 100644 --- a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php @@ -2296,7 +2296,7 @@ public function testTimezoneWithPlaceholder() public function testUrlWithDefaultProtocol() { $url = 'http://www.example.com?foo1=bar1&foo2=bar2'; - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => 'http']); + $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => 'http', 'default_protocol_skip_email' => true]); $this->assertWidgetMatchesXpath($form->createView(), [], '/input @@ -2311,7 +2311,7 @@ public function testUrlWithDefaultProtocol() public function testUrlWithoutDefaultProtocol() { $url = 'http://www.example.com?foo1=bar1&foo2=bar2'; - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => null]); + $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => null, 'default_protocol_skip_email' => true]); $this->assertWidgetMatchesXpath($form->createView(), [], '/input diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php index e00cb9e9e1978..d96183b456f84 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\EventListener; use PHPUnit\Framework\TestCase; +use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\Form\Extension\Core\EventListener\FixUrlProtocolListener; use Symfony\Component\Form\Form; @@ -20,6 +21,8 @@ class FixUrlProtocolListenerTest extends TestCase { + use ExpectDeprecationTrait; + public function testFixHttpUrl() { $data = 'www.symfony.com'; @@ -27,18 +30,7 @@ public function testFixHttpUrl() $event = new FormEvent($form, $data); $filter = new FixUrlProtocolListener('http'); - $filter->onSubmit($event); - - $this->assertEquals('http://www.symfony.com', $event->getData()); - } - - public function testSkipKnownUrl() - { - $data = 'http://www.symfony.com'; - $form = new Form(new FormConfigBuilder('name', null, new EventDispatcher())); - $event = new FormEvent($form, $data); - - $filter = new FixUrlProtocolListener('http'); + $filter->skipEmail(); $filter->onSubmit($event); $this->assertEquals('http://www.symfony.com', $event->getData()); @@ -47,11 +39,14 @@ public function testSkipKnownUrl() public function provideUrlsWithSupportedProtocols() { return [ + ['http://www.symfony.com'], ['ftp://www.symfony.com'], ['chrome-extension://foo'], ['h323://foo'], ['iris.beep://foo'], ['foo+bar://foo'], + ['fabien@symfony.com'], + ['Contact+42@subdomain.example.com'], ]; } @@ -64,8 +59,26 @@ public function testSkipOtherProtocol($url) $event = new FormEvent($form, $url); $filter = new FixUrlProtocolListener('http'); + $filter->skipEmail(); $filter->onSubmit($event); $this->assertEquals($url, $event->getData()); } + + /** + * @group legacy + */ + public function testDeprecatedFixEmail() + { + $this->expectDeprecation('Since symfony/form 5.4: Class "Symfony\Component\Form\Extension\Core\EventListener\FixUrlProtocolListener", will add a scheme to urls that looks like emails in 6.0. Call "setIgnoreEmail(true)"'); + + $data = 'fabien@symfony.com'; + $form = new Form(new FormConfigBuilder('name', null, new EventDispatcher())); + $event = new FormEvent($form, $data); + + $filter = new FixUrlProtocolListener('http'); + $filter->onSubmit($event); + + $this->assertEquals('http://fabien@symfony.com', $event->getData()); + } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/TextTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/TextTypeTest.php index 3f8fbe7725ffc..709798f712510 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/TextTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/TextTypeTest.php @@ -22,9 +22,9 @@ public function testSubmitNull($expected = null, $norm = null, $view = null) public function testSubmitNullReturnsNullWithEmptyDataAsString() { - $form = $this->factory->create(static::TESTED_TYPE, 'name', [ + $form = $this->factory->create(static::TESTED_TYPE, 'name', array_merge($this->getTestOptions(), [ 'empty_data' => '', - ]); + ])); $form->submit(null); $this->assertSame('', $form->getData()); @@ -48,9 +48,9 @@ public function provideZeros() */ public function testSetDataThroughParamsWithZero($data, $dataAsString) { - $form = $this->factory->create(static::TESTED_TYPE, null, [ + $form = $this->factory->create(static::TESTED_TYPE, null, array_merge($this->getTestOptions(), [ 'data' => $data, - ]); + ])); $view = $form->createView(); $this->assertFalse($form->isEmpty()); diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeLegacyTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeLegacyTest.php new file mode 100644 index 0000000000000..18f9f5dfca5fb --- /dev/null +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeLegacyTest.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +/** + * @group legacy + */ +class UrlTypeLegacyTest extends UrlTypeTest +{ + /** + * Legacy behavior. Replace test in parent class. + */ + public function testSubmitAddsNoDefaultProtocolToEmail() + { + $form = $this->factory->create(static::TESTED_TYPE, 'name', $this->getTestOptions()); + + $form->submit('contact@domain.com'); + + $this->assertSame('http://contact@domain.com', $form->getData()); + $this->assertSame('http://contact@domain.com', $form->getViewData()); + } + + protected function getTestOptions(): array + { + return []; + } +} diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeTest.php index b9387d01a45e6..89eaf76fb1938 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeTest.php @@ -19,7 +19,7 @@ class UrlTypeTest extends TextTypeTest public function testSubmitAddsDefaultProtocolIfNoneIsIncluded() { - $form = $this->factory->create(static::TESTED_TYPE, 'name'); + $form = $this->factory->create(static::TESTED_TYPE, 'name', $this->getTestOptions()); $form->submit('www.domain.com'); @@ -27,11 +27,21 @@ public function testSubmitAddsDefaultProtocolIfNoneIsIncluded() $this->assertSame('http://www.domain.com', $form->getViewData()); } + public function testSubmitAddsNoDefaultProtocolToEmail() + { + $form = $this->factory->create(static::TESTED_TYPE, 'name', $this->getTestOptions()); + + $form->submit('contact@domain.com'); + + $this->assertSame('contact@domain.com', $form->getData()); + $this->assertSame('contact@domain.com', $form->getViewData()); + } + public function testSubmitAddsNoDefaultProtocolIfAlreadyIncluded() { - $form = $this->factory->create(static::TESTED_TYPE, null, [ + $form = $this->factory->create(static::TESTED_TYPE, null, array_merge($this->getTestOptions(), [ 'default_protocol' => 'http', - ]); + ])); $form->submit('ftp://www.domain.com'); @@ -41,9 +51,9 @@ public function testSubmitAddsNoDefaultProtocolIfAlreadyIncluded() public function testSubmitAddsNoDefaultProtocolIfEmpty() { - $form = $this->factory->create(static::TESTED_TYPE, null, [ + $form = $this->factory->create(static::TESTED_TYPE, null, array_merge($this->getTestOptions(), [ 'default_protocol' => 'http', - ]); + ])); $form->submit(''); @@ -53,9 +63,9 @@ public function testSubmitAddsNoDefaultProtocolIfEmpty() public function testSubmitAddsNoDefaultProtocolIfNull() { - $form = $this->factory->create(static::TESTED_TYPE, null, [ + $form = $this->factory->create(static::TESTED_TYPE, null, array_merge($this->getTestOptions(), [ 'default_protocol' => 'http', - ]); + ])); $form->submit(null); @@ -65,9 +75,9 @@ public function testSubmitAddsNoDefaultProtocolIfNull() public function testSubmitAddsNoDefaultProtocolIfSetToNull() { - $form = $this->factory->create(static::TESTED_TYPE, null, [ + $form = $this->factory->create(static::TESTED_TYPE, null, array_merge($this->getTestOptions(), [ 'default_protocol' => null, - ]); + ])); $form->submit('www.domain.com'); @@ -85,9 +95,9 @@ public function testThrowExceptionIfDefaultProtocolIsInvalid() public function testSubmitNullUsesDefaultEmptyData($emptyData = 'empty', $expectedData = 'http://empty') { - $form = $this->factory->create(static::TESTED_TYPE, null, [ + $form = $this->factory->create(static::TESTED_TYPE, null, array_merge($this->getTestOptions(), [ 'empty_data' => $emptyData, - ]); + ])); $form->submit(null); // listener normalizes data on submit @@ -95,4 +105,11 @@ public function testSubmitNullUsesDefaultEmptyData($emptyData = 'empty', $expect $this->assertSame($expectedData, $form->getNormData()); $this->assertSame($expectedData, $form->getData()); } + + protected function getTestOptions(): array + { + return [ + 'default_protocol_skip_email' => true, + ]; + } } From 2ae7df423ac154d8d47d7fde3caf675abd5fb2a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20TAMARELLE?= Date: Thu, 28 Oct 2021 19:32:51 +0200 Subject: [PATCH 2/3] [Form] Change UrlType behaviour to not convert emails to valid urls --- UPGRADE-5.4.md | 2 +- .../AbstractBootstrap3LayoutTest.php | 4 +-- src/Symfony/Component/Form/CHANGELOG.md | 2 +- .../EventListener/FixUrlProtocolListener.php | 19 +++------- .../Form/Extension/Core/Type/UrlType.php | 10 +----- .../Form/Tests/AbstractLayoutTest.php | 4 +-- .../FixUrlProtocolListenerTest.php | 22 +++++++----- .../Extension/Core/Type/UrlTypeLegacyTest.php | 36 ------------------- .../Tests/Extension/Core/Type/UrlTypeTest.php | 7 ---- 9 files changed, 25 insertions(+), 81 deletions(-) delete mode 100644 src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeLegacyTest.php diff --git a/UPGRADE-5.4.md b/UPGRADE-5.4.md index de8309412d46b..87b34cd35fd7f 100644 --- a/UPGRADE-5.4.md +++ b/UPGRADE-5.4.md @@ -22,7 +22,7 @@ Form ------ * Deprecate calling `FormErrorIterator::children()` if the current element is not iterable. - * Add `'default_protocol_skip_email' => true` to `UrlType` options. + * `UrlType` does not add the default protocol to urls that looks like emails or does not contain a dot or a slash. FrameworkBundle --------------- diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php index 40ab3e07da651..73ec1c18277e2 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php @@ -2648,7 +2648,7 @@ public function testTimezoneWithPlaceholder() public function testUrlWithDefaultProtocol() { $url = 'http://www.example.com?foo1=bar1&foo2=bar2'; - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => 'http', 'default_protocol_skip_email' => true]); + $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => 'http']); $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']], '/input @@ -2664,7 +2664,7 @@ public function testUrlWithDefaultProtocol() public function testUrlWithoutDefaultProtocol() { $url = 'http://www.example.com?foo1=bar1&foo2=bar2'; - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => null, 'default_protocol_skip_email' => true]); + $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => null]); $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']], '/input diff --git a/src/Symfony/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md index b6b705b9e1c24..bbb90c0b40ff0 100644 --- a/src/Symfony/Component/Form/CHANGELOG.md +++ b/src/Symfony/Component/Form/CHANGELOG.md @@ -7,7 +7,7 @@ CHANGELOG * Deprecate calling `FormErrorIterator::children()` if the current element is not iterable. * Allow to pass `TranslatableMessage` objects to the `help` option * Add the `EnumType` - * Deprecate usage of `UrlType` without option `'default_protocol_skip_email' => true`, added to prevent emails from being converted to valid URLs. + * `UrlType` does not add the default protocol to urls that looks like emails or does not contain a dot or a slash. 5.3 --- diff --git a/src/Symfony/Component/Form/Extension/Core/EventListener/FixUrlProtocolListener.php b/src/Symfony/Component/Form/Extension/Core/EventListener/FixUrlProtocolListener.php index c26bcd2619a57..d5053a285e887 100644 --- a/src/Symfony/Component/Form/Extension/Core/EventListener/FixUrlProtocolListener.php +++ b/src/Symfony/Component/Form/Extension/Core/EventListener/FixUrlProtocolListener.php @@ -23,7 +23,6 @@ class FixUrlProtocolListener implements EventSubscriberInterface { private $defaultProtocol; - private $skipEmail = false; /** * @param string|null $defaultProtocol The URL scheme to add when there is none or null to not modify the data @@ -33,24 +32,16 @@ public function __construct(?string $defaultProtocol = 'http') $this->defaultProtocol = $defaultProtocol; } - /** - * @param bool $skipEmail the URL scheme is not added to values that match an email pattern - */ - public function skipEmail(): void - { - $this->skipEmail = true; - } - public function onSubmit(FormEvent $event) { $data = $event->getData(); if ($this->defaultProtocol && $data && \is_string($data) && !preg_match('~^[\w+.-]+://~', $data)) { - if (preg_match('~^[^:/]+@[A-Za-z0-9-.]+\.[A-Za-z0-9]+$~', $data)) { - if ($this->skipEmail) { - return; - } - trigger_deprecation('symfony/form', '5.4', 'Class "%s", will add a scheme to urls that looks like emails in 6.0. Call "setIgnoreEmail(true)"', __CLASS__); + // Detect email & non-url + if (preg_match('~^([^:/?@]++@|[^./]+$)~', $data)) { + trigger_deprecation('symfony/form', '5.4', 'Form type "url", does not add a default protocol to urls that looks like emails or does not contain a dot or slash.'); + + return; } $event->setData($this->defaultProtocol.'://'.$data); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/UrlType.php b/src/Symfony/Component/Form/Extension/Core/Type/UrlType.php index a3d36fc7ca930..f294a10ac25b6 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/UrlType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/UrlType.php @@ -27,13 +27,7 @@ class UrlType extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options) { if (null !== $options['default_protocol']) { - $subscriber = new FixUrlProtocolListener($options['default_protocol']); - if ($options['default_protocol_skip_email']) { - $subscriber->skipEmail(); - } else { - trigger_deprecation('symfony/form', '5.4', 'Type "%s" option "default_protocol_skip_email" will be "true" in 6.0.', static::class); - } - $builder->addEventSubscriber($subscriber); + $builder->addEventSubscriber(new FixUrlProtocolListener($options['default_protocol'])); } } @@ -60,11 +54,9 @@ public function configureOptions(OptionsResolver $resolver) ? $previousValue : 'Please enter a valid URL.'; }, - 'default_protocol_skip_email' => false, ]); $resolver->setAllowedTypes('default_protocol', ['null', 'string']); - $resolver->setAllowedTypes('default_protocol_skip_email', 'bool'); } /** diff --git a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php index 1f1b8d8c8e4ae..4b5d18b86793f 100644 --- a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php @@ -2296,7 +2296,7 @@ public function testTimezoneWithPlaceholder() public function testUrlWithDefaultProtocol() { $url = 'http://www.example.com?foo1=bar1&foo2=bar2'; - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => 'http', 'default_protocol_skip_email' => true]); + $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => 'http']); $this->assertWidgetMatchesXpath($form->createView(), [], '/input @@ -2311,7 +2311,7 @@ public function testUrlWithDefaultProtocol() public function testUrlWithoutDefaultProtocol() { $url = 'http://www.example.com?foo1=bar1&foo2=bar2'; - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => null, 'default_protocol_skip_email' => true]); + $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => null]); $this->assertWidgetMatchesXpath($form->createView(), [], '/input diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php index d96183b456f84..9d304232d61a4 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php @@ -30,7 +30,6 @@ public function testFixHttpUrl() $event = new FormEvent($form, $data); $filter = new FixUrlProtocolListener('http'); - $filter->skipEmail(); $filter->onSubmit($event); $this->assertEquals('http://www.symfony.com', $event->getData()); @@ -45,8 +44,6 @@ public function provideUrlsWithSupportedProtocols() ['h323://foo'], ['iris.beep://foo'], ['foo+bar://foo'], - ['fabien@symfony.com'], - ['Contact+42@subdomain.example.com'], ]; } @@ -59,7 +56,6 @@ public function testSkipOtherProtocol($url) $event = new FormEvent($form, $url); $filter = new FixUrlProtocolListener('http'); - $filter->skipEmail(); $filter->onSubmit($event); $this->assertEquals($url, $event->getData()); @@ -67,18 +63,26 @@ public function testSkipOtherProtocol($url) /** * @group legacy + * @dataProvider provideNonUrls */ - public function testDeprecatedFixEmail() + public function testDeprecatedFixEmail($url) { - $this->expectDeprecation('Since symfony/form 5.4: Class "Symfony\Component\Form\Extension\Core\EventListener\FixUrlProtocolListener", will add a scheme to urls that looks like emails in 6.0. Call "setIgnoreEmail(true)"'); + $this->expectDeprecation('Since symfony/form 5.4: Form type "url", does not add a default protocol to urls that looks like emails or does not contain a dot or slash.'); - $data = 'fabien@symfony.com'; $form = new Form(new FormConfigBuilder('name', null, new EventDispatcher())); - $event = new FormEvent($form, $data); + $event = new FormEvent($form, $url); $filter = new FixUrlProtocolListener('http'); $filter->onSubmit($event); - $this->assertEquals('http://fabien@symfony.com', $event->getData()); + $this->assertEquals($url, $event->getData()); + } + + public function provideNonUrls() + { + return [ + ['fabien@symfony.com'], + ['foo'], + ]; } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeLegacyTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeLegacyTest.php deleted file mode 100644 index 18f9f5dfca5fb..0000000000000 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeLegacyTest.php +++ /dev/null @@ -1,36 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Form\Tests\Extension\Core\Type; - -/** - * @group legacy - */ -class UrlTypeLegacyTest extends UrlTypeTest -{ - /** - * Legacy behavior. Replace test in parent class. - */ - public function testSubmitAddsNoDefaultProtocolToEmail() - { - $form = $this->factory->create(static::TESTED_TYPE, 'name', $this->getTestOptions()); - - $form->submit('contact@domain.com'); - - $this->assertSame('http://contact@domain.com', $form->getData()); - $this->assertSame('http://contact@domain.com', $form->getViewData()); - } - - protected function getTestOptions(): array - { - return []; - } -} diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeTest.php index 89eaf76fb1938..9c2c0f68f2a1d 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeTest.php @@ -105,11 +105,4 @@ public function testSubmitNullUsesDefaultEmptyData($emptyData = 'empty', $expect $this->assertSame($expectedData, $form->getNormData()); $this->assertSame($expectedData, $form->getData()); } - - protected function getTestOptions(): array - { - return [ - 'default_protocol_skip_email' => true, - ]; - } } From 0501d5627f12f9e5350cbccb610b1f6e788032e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20TAMARELLE?= Date: Thu, 28 Oct 2021 23:01:12 +0200 Subject: [PATCH 3/3] Removes deprecation message --- .../EventListener/FixUrlProtocolListener.php | 12 ++++----- .../FixUrlProtocolListenerTest.php | 27 ++----------------- .../Tests/Extension/Core/Type/UrlTypeTest.php | 2 +- 3 files changed, 8 insertions(+), 33 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Core/EventListener/FixUrlProtocolListener.php b/src/Symfony/Component/Form/Extension/Core/EventListener/FixUrlProtocolListener.php index d5053a285e887..0dd42350bbc2e 100644 --- a/src/Symfony/Component/Form/Extension/Core/EventListener/FixUrlProtocolListener.php +++ b/src/Symfony/Component/Form/Extension/Core/EventListener/FixUrlProtocolListener.php @@ -36,13 +36,11 @@ public function onSubmit(FormEvent $event) { $data = $event->getData(); - if ($this->defaultProtocol && $data && \is_string($data) && !preg_match('~^[\w+.-]+://~', $data)) { - // Detect email & non-url - if (preg_match('~^([^:/?@]++@|[^./]+$)~', $data)) { - trigger_deprecation('symfony/form', '5.4', 'Form type "url", does not add a default protocol to urls that looks like emails or does not contain a dot or slash.'); - - return; - } + if ($this->defaultProtocol && $data && \is_string($data) + && !preg_match('~^[\w+.-]+://~', $data) + // skip email & non-url values + && !preg_match('~^([^:/?@]++@|[^./]+$)~', $data) + ) { $event->setData($this->defaultProtocol.'://'.$data); } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php index 9d304232d61a4..113b4bb6afa89 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php @@ -44,6 +44,8 @@ public function provideUrlsWithSupportedProtocols() ['h323://foo'], ['iris.beep://foo'], ['foo+bar://foo'], + ['fabien@symfony.com'], + ['foo'], ]; } @@ -60,29 +62,4 @@ public function testSkipOtherProtocol($url) $this->assertEquals($url, $event->getData()); } - - /** - * @group legacy - * @dataProvider provideNonUrls - */ - public function testDeprecatedFixEmail($url) - { - $this->expectDeprecation('Since symfony/form 5.4: Form type "url", does not add a default protocol to urls that looks like emails or does not contain a dot or slash.'); - - $form = new Form(new FormConfigBuilder('name', null, new EventDispatcher())); - $event = new FormEvent($form, $url); - - $filter = new FixUrlProtocolListener('http'); - $filter->onSubmit($event); - - $this->assertEquals($url, $event->getData()); - } - - public function provideNonUrls() - { - return [ - ['fabien@symfony.com'], - ['foo'], - ]; - } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeTest.php index 9c2c0f68f2a1d..3e51d56432a71 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeTest.php @@ -93,7 +93,7 @@ public function testThrowExceptionIfDefaultProtocolIsInvalid() ]); } - public function testSubmitNullUsesDefaultEmptyData($emptyData = 'empty', $expectedData = 'http://empty') + public function testSubmitNullUsesDefaultEmptyData($emptyData = 'empty.com', $expectedData = 'http://empty.com') { $form = $this->factory->create(static::TESTED_TYPE, null, array_merge($this->getTestOptions(), [ 'empty_data' => $emptyData,