8000 [Form] UrlType should not add protocol to emails by GromNaN · Pull Request #43707 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Form] UrlType should not add protocol to emails #43707

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10000
Prev Previous commit
Next Next commit
[Form] Change UrlType behaviour to not convert emails to valid urls
  • Loading branch information
GromNaN committed Oct 28, 2021
commit 2ae7df423ac154d8d47d7fde3caf675abd5fb2a8
2 changes: 1 addition & 1 deletion UPGRADE-5.4.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
---------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Component/Form/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
}
Expand Down
10 changes: 1 addition & 9 deletions src/Symfony/Component/Form/Extension/Core/Type/UrlType.php
Original file line number Diff line number Diff line change
Expand Up @@ -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']));
}
}

Expand All @@ -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');
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/Symfony/Component/Form/Tests/AbstractLayoutTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand All @@ -45,8 +44,6 @@ public function provideUrlsWithSupportedProtocols()
['h323://foo'],
['iris.beep://foo'],
['foo+bar://foo'],
['fabien@symfony.com'],
['Contact+42@subdomain.example.com'],
];
}

Expand All @@ -59,26 +56,33 @@ 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
* @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'],
];
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -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,
];
}
}
0