diff --git a/LICENSE b/LICENSE
index a677f43763..9e936ec044 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Bridge/Doctrine/LICENSE b/src/Symfony/Bridge/Doctrine/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Bridge/Doctrine/LICENSE
+++ b/src/Symfony/Bridge/Doctrine/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Bridge/Monolog/LICENSE b/src/Symfony/Bridge/Monolog/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Bridge/Monolog/LICENSE
+++ b/src/Symfony/Bridge/Monolog/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Bridge/PhpUnit/LICENSE b/src/Symfony/Bridge/PhpUnit/LICENSE
index cf8b3ebe87..684fbf94df 100644
--- a/src/Symfony/Bridge/PhpUnit/LICENSE
+++ b/src/Symfony/Bridge/PhpUnit/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2014-2019 Fabien Potencier
+Copyright (c) 2014-2020 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
diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV5.php b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV5.php
index 2da40f2c20..a760d126ca 100644
--- a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV5.php
+++ b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV5.php
@@ -47,11 +47,6 @@ class SymfonyTestsListenerForV5 extends \PHPUnit_Framework_BaseTestListener
$this->trait->startTest($test);
}
- public function addWarning(\PHPUnit_Framework_Test $test, \PHPUnit_Framework_Warning $e, $time)
- {
- $this->trait->addWarning($test, $e, $time);
- }
-
public function endTest(\PHPUnit_Framework_Test $test, $time)
{
$this->trait->endTest($test, $time);
diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV6.php b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV6.php
index 5b864bfe58..bcab4be4ee 100644
--- a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV6.php
+++ b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV6.php
@@ -52,11 +52,6 @@ class SymfonyTestsListenerForV6 extends BaseTestListener
$this->trait->startTest($test);
}
- public function addWarning(Test $test, Warning $e, $time)
- {
- $this->trait->addWarning($test, $e, $time);
- }
-
public function endTest(Test $test, $time)
{
$this->trait->endTest($test, $time);
diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV7.php b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV7.php
index 18bbdbeba0..0c2069c66b 100644
--- a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV7.php
+++ b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV7.php
@@ -55,11 +55,6 @@ class SymfonyTestsListenerForV7 implements TestListener
$this->trait->startTest($test);
}
- public function addWarning(Test $test, Warning $e, float $time): void
- {
- $this->trait->addWarning($test, $e, $time);
- }
-
public function endTest(Test $test, float $time): void
{
$this->trait->endTest($test, $time);
diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php
index 27a0d32654..35e806b10c 100644
--- a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php
+++ b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php
@@ -40,7 +40,6 @@ class SymfonyTestsListenerTrait
private $expectedDeprecations = array();
private $gatheredDeprecations = array();
private $previousErrorHandler;
- private $testsWithWarnings;
private $reportUselessTests;
private $error;
private $runsInSeparateProcess = false;
@@ -112,7 +111,6 @@ class SymfonyTestsListenerTrait
public function startTestSuite($suite)
{
$suiteName = $suite->getName();
- $this->testsWithWarnings = array();
foreach ($suite->tests() as $test) {
if (!($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase)) {
@@ -236,13 +234,6 @@ class SymfonyTestsListenerTrait
}
}
- public function addWarning($test, $e, $time)
- {
- if ($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase) {
- $this->testsWithWarnings[$test->getName()] = true;
- }
- }
-
public function endTest($test, $time)
{
if (class_exists(DebugClassLoader::class, false)) {
diff --git a/src/Symfony/Bridge/PhpUnit/Tests/ExpectedDeprecationAnnotationTest.php b/src/Symfony/Bridge/PhpUnit/Tests/ExpectedDeprecationAnnotationTest.php
new file mode 100644
index 0000000000..259c99162a
--- /dev/null
+++ b/src/Symfony/Bridge/PhpUnit/Tests/ExpectedDeprecationAnnotationTest.php
@@ -0,0 +1,43 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bridge\PhpUnit\Tests;
+
+use PHPUnit\Framework\TestCase;
+
+final class ExpectedDeprecationAnnotationTest extends TestCase
+{
+ /**
+ * Do not remove this test in the next major versions.
+ *
+ * @group legacy
+ *
+ * @expectedDeprecation foo
+ */
+ public function testOne()
+ {
+ @trigger_error('foo', E_USER_DEPRECATED);
+ }
+
+ /**
+ * Do not remove this test in the next major versions.
+ *
+ * @group legacy
+ *
+ * @expectedDeprecation foo
+ * @expectedDeprecation bar
+ */
+ public function testMany()
+ {
+ @trigger_error('foo', E_USER_DEPRECATED);
+ @trigger_error('bar', E_USER_DEPRECATED);
+ }
+}
diff --git a/src/Symfony/Bridge/ProxyManager/LICENSE b/src/Symfony/Bridge/ProxyManager/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Bridge/ProxyManager/LICENSE
+++ b/src/Symfony/Bridge/ProxyManager/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Bridge/Twig/LICENSE b/src/Symfony/Bridge/Twig/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Bridge/Twig/LICENSE
+++ b/src/Symfony/Bridge/Twig/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_horizontal_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_horizontal_layout.html.twig
index 4dc3e9c896..49cd804398 100644
--- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_horizontal_layout.html.twig
+++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_horizontal_layout.html.twig
@@ -64,6 +64,7 @@ col-sm-10
{#--#}
{{- form_widget(form) -}}
+ {{- form_help(form) -}}
{{- form_errors(form) -}}
{#--#}
diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig
index f0cf0ad818..44492cebe7 100644
--- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig
+++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig
@@ -148,6 +148,7 @@
{% block checkbox_row -%}
{{- form_widget(form) -}}
+ {{- form_help(form) -}}
{{- form_errors(form) -}}
{%- endblock checkbox_row %}
@@ -155,6 +156,7 @@
{% block radio_row -%}
{{- form_widget(form) -}}
+ {{- form_help(form) -}}
{{- form_errors(form) -}}
{%- endblock radio_row %}
diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/foundation_5_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/foundation_5_layout.html.twig
index 83c5e30d80..8ab44ccc77 100644
--- a/src/Symfony/Bridge/Twig/Resources/views/Form/foundation_5_layout.html.twig
+++ b/src/Symfony/Bridge/Twig/Resources/views/Form/foundation_5_layout.html.twig
@@ -311,6 +311,7 @@
{{ form_widget(form) }}
+ {{- form_help(form) -}}
{{ form_errors(form) }}
@@ -320,6 +321,7 @@
{{ form_widget(form) }}
+ {{- form_help(form) -}}
{{ form_errors(form) }}
diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3HorizontalLayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3HorizontalLayoutTest.php
index 9131216182..69064a003d 100644
--- a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3HorizontalLayoutTest.php
+++ b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3HorizontalLayoutTest.php
@@ -163,4 +163,23 @@ abstract class AbstractBootstrap3HorizontalLayoutTest extends AbstractBootstrap3
$this->assertMatchesXpath($html, '/div[@class="form-group"]/div[@class="col-sm-2" or @class="col-sm-10"]', 2);
}
+
+ public function testCheckboxRowWithHelp()
+ {
+ $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\CheckboxType');
+ $html = $this->renderRow($form->createView(), ['label' => 'foo', 'help' => 'really helpful text']);
+
+ $this->assertMatchesXpath($html,
+'/div
+ [@class="form-group"]
+ [
+ ./div[@class="col-sm-2" or @class="col-sm-10"]
+ /following-sibling::div[@class="col-sm-2" or @class="col-sm-10"]
+ [
+ ./span[text() = "[trans]really helpful text[/trans]"]
+ ]
+ ]
+'
+ );
+ }
}
diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php
index 8f38c8486f..ff5c677c19 100644
--- a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php
+++ b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php
@@ -333,6 +333,21 @@ abstract class AbstractBootstrap3LayoutTest extends AbstractLayoutTest
);
}
+ public function testCheckboxRowWithHelp()
+ {
+ $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\CheckboxType');
+ $html = $this->renderRow($form->createView(), ['label' => 'foo', 'help' => 'really helpful text']);
+
+ $this->assertMatchesXpath($html,
+'/div
+ [@class="form-group"]
+ [
+ ./span[text() = "[trans]really helpful text[/trans]"]
+ ]
+'
+ );
+ }
+
public function testSingleChoice()
{
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', [
@@ -2265,6 +2280,21 @@ abstract class AbstractBootstrap3LayoutTest extends AbstractLayoutTest
);
}
+ public function testRadioRowWithHelp()
+ {
+ $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\RadioType', false);
+ $html = $this->renderRow($form->createView(), ['label' => 'foo', 'help' => 'really helpful text']);
+
+ $this->assertMatchesXpath($html,
+'/div
+ [@class="form-group"]
+ [
+ ./span[text() = "[trans]really helpful text[/trans]"]
+ ]
+'
+ );
+ }
+
public function testRange()
{
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\RangeType', 42, ['attr' => ['min' => 5]]);
diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap4HorizontalLayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap4HorizontalLayoutTest.php
index e9416b0221..e20f4818b2 100644
--- a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap4HorizontalLayoutTest.php
+++ b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap4HorizontalLayoutTest.php
@@ -231,6 +231,25 @@ abstract class AbstractBootstrap4HorizontalLayoutTest extends AbstractBootstrap4
./small[text() = "[trans]really helpful text[/trans]"]
]
]
+'
+ );
+ }
+
+ public function testRadioRowWithHelp()
+ {
+ $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\RadioType', false);
+ $html = $this->renderRow($form->createView(), ['label' => 'foo', 'help' => 'really helpful text']);
+
+ $this->assertMatchesXpath($html,
+'/div
+ [@class="form-group row"]
+ [
+ ./div[@class="col-sm-2" or @class="col-sm-10"]
+ /following-sibling::div[@class="col-sm-2" or @class="col-sm-10"]
+ [
+ ./small[text() = "[trans]really helpful text[/trans]"]
+ ]
+ ]
'
);
}
diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap4LayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap4LayoutTest.php
index 89fbacf2fc..2643274d47 100644
--- a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap4LayoutTest.php
+++ b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap4LayoutTest.php
@@ -422,6 +422,21 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
);
}
+ public function testCheckboxRowWithHelp()
+ {
+ $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\CheckboxType');
+ $html = $this->renderRow($form->createView(), ['label' => 'foo', 'help' => 'really helpful text']);
+
+ $this->assertMatchesXpath($html,
+ '/div
+ [@class="form-group"]
+ [
+ ./small[text() = "[trans]really helpful text[/trans]"]
+ ]
+'
+ );
+ }
+
public function testSingleChoiceExpanded()
{
$form = $this->factory->createNamed('name', ChoiceType::class, '&a', [
@@ -1027,6 +1042,21 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
);
}
+ public function testRadioRowWithHelp()
+ {
+ $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\RadioType', false);
+ $html = $this->renderRow($form->createView(), ['label' => 'foo', 'help' => 'really helpful text']);
+
+ $this->assertMatchesXpath($html,
+'/div
+ [@class="form-group"]
+ [
+ ./small[text() = "[trans]really helpful text[/trans]"]
+ ]
+'
+ );
+ }
+
public function testButtonAttributeNameRepeatedIfTrue()
{
$form = $this->factory->createNamed('button', ButtonType::class, null, [
diff --git a/src/Symfony/Bundle/DebugBundle/LICENSE b/src/Symfony/Bundle/DebugBundle/LICENSE
index cf8b3ebe87..684fbf94df 100644
--- a/src/Symfony/Bundle/DebugBundle/LICENSE
+++ b/src/Symfony/Bundle/DebugBundle/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2014-2019 Fabien Potencier
+Copyright (c) 2014-2020 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
diff --git a/src/Symfony/Bundle/FrameworkBundle/LICENSE b/src/Symfony/Bundle/FrameworkBundle/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Bundle/FrameworkBundle/LICENSE
+++ b/src/Symfony/Bundle/FrameworkBundle/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md b/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md
index 7f0fe56f17..fc75ace882 100644
--- a/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md
+++ b/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md
@@ -20,6 +20,7 @@ CHANGELOG
4.4.0
-----
+ * Added `anonymous: lazy` mode to firewalls to make them (not) start the session as late as possible
* Added `migrate_from` option to encoders configuration.
* Added new `argon2id` encoder, undeprecated the `bcrypt` and `argon2i` ones (using `auto` is still recommended by default.)
* Deprecated the usage of "query_string" without a "search_dn" and a "search_password" config key in Ldap factories.
@@ -28,7 +29,6 @@ CHANGELOG
4.3.0
-----
- * Added `anonymous: lazy` mode to firewalls to make them (not) start the session as late as possible
* Added new encoder types: `auto` (recommended), `native` and `sodium`
* The normalization of the cookie names configured in the `logout.delete_cookies`
option is deprecated and will be disabled in Symfony 5.0. This affects to cookies
diff --git a/src/Symfony/Bundle/SecurityBundle/LICENSE b/src/Symfony/Bundle/SecurityBundle/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Bundle/SecurityBundle/LICENSE
+++ b/src/Symfony/Bundle/SecurityBundle/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Bundle/TwigBundle/LICENSE b/src/Symfony/Bundle/TwigBundle/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Bundle/TwigBundle/LICENSE
+++ b/src/Symfony/Bundle/TwigBundle/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Bundle/WebProfilerBundle/LICENSE b/src/Symfony/Bundle/WebProfilerBundle/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Bundle/WebProfilerBundle/LICENSE
+++ b/src/Symfony/Bundle/WebProfilerBundle/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/Asset/LICENSE b/src/Symfony/Component/Asset/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/Asset/LICENSE
+++ b/src/Symfony/Component/Asset/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/BrowserKit/LICENSE b/src/Symfony/Component/BrowserKit/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/BrowserKit/LICENSE
+++ b/src/Symfony/Component/BrowserKit/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/Cache/LICENSE b/src/Symfony/Component/Cache/LICENSE
index 3c464ca943..a7ec708018 100644
--- a/src/Symfony/Component/Cache/LICENSE
+++ b/src/Symfony/Component/Cache/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2016-2019 Fabien Potencier
+Copyright (c) 2016-2020 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
diff --git a/src/Symfony/Component/Config/LICENSE b/src/Symfony/Component/Config/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/Config/LICENSE
+++ b/src/Symfony/Component/Config/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/Config/README.md b/src/Symfony/Component/Config/README.md
index bf400da196..0bbde55230 100644
--- a/src/Symfony/Component/Config/README.md
+++ b/src/Symfony/Component/Config/README.md
@@ -8,7 +8,7 @@ may be (YAML, XML, INI files, or for instance a database).
Resources
---------
- * [Documentation](https://symfony.com/doc/current/components/config/index.html)
+ * [Documentation](https://symfony.com/doc/current/components/config.html)
* [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)
diff --git a/src/Symfony/Component/Console/Helper/FormatterHelper.php b/src/Symfony/Component/Console/Helper/FormatterHelper.php
index 75c9b613f1..a505415cff 100644
--- a/src/Symfony/Component/Console/Helper/FormatterHelper.php
+++ b/src/Symfony/Component/Console/Helper/FormatterHelper.php
@@ -48,12 +48,12 @@ class FormatterHelper extends Helper
foreach ($messages as $message) {
$message = OutputFormatter::escape($message);
$lines[] = sprintf($large ? ' %s ' : ' %s ', $message);
- $len = max($this->strlen($message) + ($large ? 4 : 2), $len);
+ $len = max(self::strlen($message) + ($large ? 4 : 2), $len);
}
$messages = $large ? [str_repeat(' ', $len)] : [];
for ($i = 0; isset($lines[$i]); ++$i) {
- $messages[] = $lines[$i].str_repeat(' ', $len - $this->strlen($lines[$i]));
+ $messages[] = $lines[$i].str_repeat(' ', $len - self::strlen($lines[$i]));
}
if ($large) {
$messages[] = str_repeat(' ', $len);
@@ -73,17 +73,13 @@ class FormatterHelper extends Helper
*/
public function truncate(string $message, int $length, string $suffix = '...')
{
- $computedLength = $length - $this->strlen($suffix);
+ $computedLength = $length - self::strlen($suffix);
- if ($computedLength > $this->strlen($message)) {
+ if ($computedLength > self::strlen($message)) {
return $message;
}
- if (false === $encoding = mb_detect_encoding($message, null, true)) {
- return substr($message, 0, $length).$suffix;
- }
-
- return mb_substr($message, 0, $length, $encoding).$suffix;
+ return self::substr($message, 0, $length).$suffix;
}
/**
diff --git a/src/Symfony/Component/Console/LICENSE b/src/Symfony/Component/Console/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/Console/LICENSE
+++ b/src/Symfony/Component/Console/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/Console/README.md b/src/Symfony/Component/Console/README.md
index 664a37c0ee..3e2fc605e5 100644
--- a/src/Symfony/Component/Console/README.md
+++ b/src/Symfony/Component/Console/README.md
@@ -7,7 +7,7 @@ interfaces.
Resources
---------
- * [Documentation](https://symfony.com/doc/current/components/console/index.html)
+ * [Documentation](https://symfony.com/doc/current/components/console.html)
* [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)
diff --git a/src/Symfony/Component/CssSelector/LICENSE b/src/Symfony/Component/CssSelector/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/CssSelector/LICENSE
+++ b/src/Symfony/Component/CssSelector/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/DependencyInjection/LICENSE b/src/Symfony/Component/DependencyInjection/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/DependencyInjection/LICENSE
+++ b/src/Symfony/Component/DependencyInjection/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/DependencyInjection/README.md b/src/Symfony/Component/DependencyInjection/README.md
index 932647f94a..cb2d4a11c5 100644
--- a/src/Symfony/Component/DependencyInjection/README.md
+++ b/src/Symfony/Component/DependencyInjection/README.md
@@ -7,7 +7,7 @@ way objects are constructed in your application.
Resources
---------
- * [Documentation](https://symfony.com/doc/current/components/dependency_injection/index.html)
+ * [Documentation](https://symfony.com/doc/current/components/dependency_injection.html)
* [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)
diff --git a/src/Symfony/Component/DomCrawler/LICENSE b/src/Symfony/Component/DomCrawler/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/DomCrawler/LICENSE
+++ b/src/Symfony/Component/DomCrawler/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/Dotenv/LICENSE b/src/Symfony/Component/Dotenv/LICENSE
index 3c464ca943..a7ec708018 100644
--- a/src/Symfony/Component/Dotenv/LICENSE
+++ b/src/Symfony/Component/Dotenv/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2016-2019 Fabien Potencier
+Copyright (c) 2016-2020 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
diff --git a/src/Symfony/Component/ErrorHandler/LICENSE b/src/Symfony/Component/ErrorHandler/LICENSE
index 1a1869751d..4bf0fef4ff 100644
--- a/src/Symfony/Component/ErrorHandler/LICENSE
+++ b/src/Symfony/Component/ErrorHandler/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2019 Fabien Potencier
+Copyright (c) 2019-2020 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
diff --git a/src/Symfony/Component/EventDispatcher/LICENSE b/src/Symfony/Component/EventDispatcher/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/EventDispatcher/LICENSE
+++ b/src/Symfony/Component/EventDispatcher/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/EventDispatcher/README.md b/src/Symfony/Component/EventDispatcher/README.md
index 185c3fecf8..e0d38eed01 100644
--- a/src/Symfony/Component/EventDispatcher/README.md
+++ b/src/Symfony/Component/EventDispatcher/README.md
@@ -8,7 +8,7 @@ them.
Resources
---------
- * [Documentation](https://symfony.com/doc/current/components/event_dispatcher/index.html)
+ * [Documentation](https://symfony.com/doc/current/components/event_dispatcher.html)
* [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)
diff --git a/src/Symfony/Component/ExpressionLanguage/LICENSE b/src/Symfony/Component/ExpressionLanguage/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/ExpressionLanguage/LICENSE
+++ b/src/Symfony/Component/ExpressionLanguage/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/Filesystem/LICENSE b/src/Symfony/Component/Filesystem/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/Filesystem/LICENSE
+++ b/src/Symfony/Component/Filesystem/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/Filesystem/README.md b/src/Symfony/Component/Filesystem/README.md
index 877ab3543f..cb03d43c15 100644
--- a/src/Symfony/Component/Filesystem/README.md
+++ b/src/Symfony/Component/Filesystem/README.md
@@ -6,7 +6,7 @@ The Filesystem component provides basic utilities for the filesystem.
Resources
---------
- * [Documentation](https://symfony.com/doc/current/components/filesystem/index.html)
+ * [Documentation](https://symfony.com/doc/current/components/filesystem.html)
* [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)
diff --git a/src/Symfony/Component/Finder/LICENSE b/src/Symfony/Component/Finder/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/Finder/LICENSE
+++ b/src/Symfony/Component/Finder/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/Form/LICENSE b/src/Symfony/Component/Form/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/Form/LICENSE
+++ b/src/Symfony/Component/Form/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/Form/README.md b/src/Symfony/Component/Form/README.md
index 3fe6f8bbf3..5519cd0005 100644
--- a/src/Symfony/Component/Form/README.md
+++ b/src/Symfony/Component/Form/README.md
@@ -6,7 +6,7 @@ The Form component allows you to easily create, process and reuse HTML forms.
Resources
---------
- * [Documentation](https://symfony.com/doc/current/components/form/index.html)
+ * [Documentation](https://symfony.com/doc/current/components/form.html)
* [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)
diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php
index 46733786a8..3f6294c53b 100644
--- a/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php
+++ b/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php
@@ -135,7 +135,10 @@ class FormValidatorTest extends ConstraintValidatorTestCase
$parent->add($form);
$form->setData($object);
+ $parent->submit([]);
+ $this->assertTrue($form->isSubmitted());
+ $this->assertTrue($form->isSynchronized());
$this->expectNoValidate();
$this->validator->validate($form, new Form());
@@ -190,10 +193,15 @@ class FormValidatorTest extends ConstraintValidatorTestCase
'validation_groups' => [],
])
->setData($object)
+ ->setCompound(true)
+ ->setDataMapper(new PropertyPathMapper())
->getForm();
$form->setData($object);
+ $form->submit([]);
+ $this->assertTrue($form->isSubmitted());
+ $this->assertTrue($form->isSynchronized());
$this->expectNoValidate();
$this->validator->validate($form, new Form());
@@ -216,6 +224,8 @@ class FormValidatorTest extends ConstraintValidatorTestCase
// Launch transformer
$form->submit('foo');
+ $this->assertTrue($form->isSubmitted());
+ $this->assertTrue($form->isSynchronized());
$this->expectNoValidate();
$this->validator->validate($form, new Form());
@@ -238,6 +248,8 @@ class FormValidatorTest extends ConstraintValidatorTestCase
$form->add($child);
$form->submit([]);
+ $this->assertTrue($form->isSubmitted());
+ $this->assertTrue($form->isSynchronized());
$this->expectNoValidate();
$this->validator->validate($form, new Form());
@@ -266,6 +278,8 @@ class FormValidatorTest extends ConstraintValidatorTestCase
// Launch transformer
$form->submit('foo');
+ $this->assertTrue($form->isSubmitted());
+ $this->assertFalse($form->isSynchronized());
$this->expectNoValidate();
$this->validator->validate($form, new Form());
@@ -301,6 +315,8 @@ class FormValidatorTest extends ConstraintValidatorTestCase
// Launch transformer
$form->submit('foo');
+ $this->assertTrue($form->isSubmitted());
+ $this->assertFalse($form->isSynchronized());
$this->expectNoValidate();
$this->validator->validate($form, new Form());
@@ -412,6 +428,8 @@ class FormValidatorTest extends ConstraintValidatorTestCase
// Launch transformer
$form->submit(['child' => 'foo']);
+ $this->assertTrue($form->isSubmitted());
+ $this->assertFalse($form->isSynchronized());
$this->expectNoValidate();
$this->validator->validate($form, new Form());
@@ -617,7 +635,10 @@ class FormValidatorTest extends ConstraintValidatorTestCase
$form = $this->getBuilder()
->setData('scalar')
->getForm();
+ $form->submit('foo');
+ $this->assertTrue($form->isSubmitted());
+ $this->assertTrue($form->isSynchronized());
$this->expectNoValidate();
$this->validator->validate($form, new Form());
@@ -635,6 +656,8 @@ class FormValidatorTest extends ConstraintValidatorTestCase
$form->submit(['foo' => 'bar']);
+ $this->assertTrue($form->isSubmitted());
+ $this->assertTrue($form->isSynchronized());
$this->expectNoValidate();
$this->validator->validate($form, new Form());
@@ -656,6 +679,8 @@ class FormValidatorTest extends ConstraintValidatorTestCase
$form->submit(['foo' => 'bar', 'baz' => 'qux', 'quux' => 'quuz']);
+ $this->assertTrue($form->isSubmitted());
+ $this->assertTrue($form->isSynchronized());
$this->expectNoValidate();
$this->validator->validate($form, new Form());
diff --git a/src/Symfony/Component/HttpClient/CurlHttpClient.php b/src/Symfony/Component/HttpClient/CurlHttpClient.php
index d26b48c19a..a36372c619 100644
--- a/src/Symfony/Component/HttpClient/CurlHttpClient.php
+++ b/src/Symfony/Component/HttpClient/CurlHttpClient.php
@@ -288,7 +288,7 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface,
$pushedResponse = $pushedResponse->response;
$pushedResponse->__construct($this->multi, $url, $options, $this->logger);
} else {
- $this->logger && $this->logger->debug(sprintf('Rejecting pushed response: "%s".', $url));
+ $this->logger && $this->logger->debug(sprintf('Rejecting pushed response: "%s"', $url));
$pushedResponse = null;
}
}
@@ -412,7 +412,7 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface,
return false;
}
- foreach (['proxy', 'no_proxy', 'bindto'] as $k) {
+ foreach (['proxy', 'no_proxy', 'bindto', 'local_cert', 'local_pk'] as $k) {
if ($options[$k] !== $pushedResponse->parentOptions[$k]) {
return false;
}
diff --git a/src/Symfony/Component/HttpClient/LICENSE b/src/Symfony/Component/HttpClient/LICENSE
index 3f853aaf35..69d925ba75 100644
--- a/src/Symfony/Component/HttpClient/LICENSE
+++ b/src/Symfony/Component/HttpClient/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2018-2019 Fabien Potencier
+Copyright (c) 2018-2020 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
diff --git a/src/Symfony/Component/HttpClient/NativeHttpClient.php b/src/Symfony/Component/HttpClient/NativeHttpClient.php
index 745f81fb2a..9e95d1170e 100644
--- a/src/Symfony/Component/HttpClient/NativeHttpClient.php
+++ b/src/Symfony/Component/HttpClient/NativeHttpClient.php
@@ -169,7 +169,7 @@ final class NativeHttpClient implements HttpClientInterface, LoggerAwareInterfac
$this->multi->dnsCache = $options['resolve'] + $this->multi->dnsCache;
}
- $this->logger && $this->logger->info(sprintf('Request: %s %s', $method, implode('', $url)));
+ $this->logger && $this->logger->info(sprintf('Request: "%s %s"', $method, implode('', $url)));
[$host, $port, $url['authority']] = self::dnsResolve($url, $this->multi, $info, $onProgress);
@@ -187,7 +187,7 @@ final class NativeHttpClient implements HttpClientInterface, LoggerAwareInterfac
$context = [
'http' => [
- 'protocol_version' => $options['http_version'] ?: '1.1',
+ 'protocol_version' => min($options['http_version'] ?: '1.1', '1.1'),
'method' => $method,
'content' => $options['body'],
'ignore_errors' => true,
@@ -357,7 +357,7 @@ final class NativeHttpClient implements HttpClientInterface, LoggerAwareInterfac
});
if (isset($options['normalized_headers']['authorization']) || isset($options['normalized_headers']['cookie'])) {
- $redirectHeaders['no_auth'] = array_filter($options['headers'], static function ($h) {
+ $redirectHeaders['no_auth'] = array_filter($redirectHeaders['no_auth'], static function ($h) {
return 0 !== stripos($h, 'Authorization:') && 0 !== stripos($h, 'Cookie:');
});
}
diff --git a/src/Symfony/Component/HttpClient/Response/NativeResponse.php b/src/Symfony/Component/HttpClient/Response/NativeResponse.php
index f9f89f36cc..db0540d28b 100644
--- a/src/Symfony/Component/HttpClient/Response/NativeResponse.php
+++ b/src/Symfony/Component/HttpClient/Response/NativeResponse.php
@@ -162,13 +162,13 @@ final class NativeResponse implements ResponseInterface
restore_error_handler();
}
- stream_set_blocking($h, false);
- $this->context = $this->resolveRedirect = null;
-
- if (isset($context['ssl']['peer_certificate_chain'])) {
+ if (isset($context['ssl']['capture_peer_cert_chain']) && isset(($context = stream_context_get_options($this->context))['ssl']['peer_certificate_chain'])) {
$this->info['peer_certificate_chain'] = $context['ssl']['peer_certificate_chain'];
}
+ stream_set_blocking($h, false);
+ $this->context = $this->resolveRedirect = null;
+
// Create dechunk and inflate buffers
if (isset($this->headers['content-length'])) {
$this->remaining = (int) $this->headers['content-length'][0];
diff --git a/src/Symfony/Component/HttpClient/Response/ResponseTrait.php b/src/Symfony/Component/HttpClient/Response/ResponseTrait.php
index 0ea434e3a0..71a04f1e8a 100644
--- a/src/Symfony/Component/HttpClient/Response/ResponseTrait.php
+++ b/src/Symfony/Component/HttpClient/Response/ResponseTrait.php
@@ -204,7 +204,11 @@ trait ResponseTrait
$this->getHeaders($throw);
}
- return StreamWrapper::createResource($this, null, $this->content, $this->handle && 'stream' === get_resource_type($this->handle) ? $this->handle : null);
+ $stream = StreamWrapper::createResource($this);
+ stream_get_meta_data($stream)['wrapper_data']
+ ->bindHandles($this->handle, $this->content);
+
+ return $stream;
}
/**
diff --git a/src/Symfony/Component/HttpClient/Response/StreamWrapper.php b/src/Symfony/Component/HttpClient/Response/StreamWrapper.php
index 59fd118e86..105d11671a 100644
--- a/src/Symfony/Component/HttpClient/Response/StreamWrapper.php
+++ b/src/Symfony/Component/HttpClient/Response/StreamWrapper.php
@@ -37,19 +37,17 @@ class StreamWrapper
/** @var resource|null */
private $handle;
+ private $blocking = true;
+ private $timeout;
private $eof = false;
private $offset = 0;
/**
* Creates a PHP stream resource from a ResponseInterface.
*
- * @param resource|null $contentBuffer The seekable resource where the response body is buffered
- * @param resource|null $selectHandle The resource handle that should be monitored when
- * stream_select() is used on the created stream
- *
* @return resource
*/
- public static function createResource(ResponseInterface $response, HttpClientInterface $client = null, $contentBuffer = null, $selectHandle = null)
+ public static function createResource(ResponseInterface $response, HttpClientInterface $client = null)
{
if (null === $client && !method_exists($response, 'stream')) {
throw new \InvalidArgumentException(sprintf('Providing a client to "%s()" is required when the response doesn\'t have any "stream()" method.', __CLASS__));
@@ -63,8 +61,6 @@ class StreamWrapper
$context = [
'client' => $client ?? $response,
'response' => $response,
- 'content' => $contentBuffer,
- 'handle' => $selectHandle,
];
return fopen('symfony://'.$response->getInfo('url'), 'r', false, stream_context_create(['symfony' => $context])) ?: null;
@@ -78,6 +74,17 @@ class StreamWrapper
return $this->response;
}
+ /**
+ * @param resource|null $handle The resource handle that should be monitored when
+ * stream_select() is used on the created stream
+ * @param resource|null $content The seekable resource where the response body is buffered
+ */
+ public function bindHandles(&$handle, &$content): void
+ {
+ $this->handle = &$handle;
+ $this->content = &$content;
+ }
+
public function stream_open(string $path, string $mode, int $options): bool
{
if ('r' !== $mode) {
@@ -91,8 +98,6 @@ class StreamWrapper
$context = stream_context_get_options($this->context)['symfony'] ?? null;
$this->client = $context['client'] ?? null;
$this->response = $context['response'] ?? null;
- $this->content = $context['content'] ?? null;
- $this->handle = $context['handle'] ?? null;
$this->context = null;
if (null !== $this->client && null !== $this->response) {
@@ -147,7 +152,7 @@ class StreamWrapper
return $data;
}
- foreach ($this->client->stream([$this->response]) as $chunk) {
+ foreach ($this->client->stream([$this->response], $this->blocking ? $this->timeout : 0) as $chunk) {
try {
$this->eof = true;
$this->eof = !$chunk->isTimeout();
@@ -178,6 +183,19 @@ class StreamWrapper
return '';
}
+ public function stream_set_option(int $option, int $arg1, ?int $arg2): bool
+ {
+ if (STREAM_OPTION_BLOCKING === $option) {
+ $this->blocking = (bool) $arg1;
+ } elseif (STREAM_OPTION_READ_TIMEOUT === $option) {
+ $this->timeout = $arg1 + $arg2 / 1e6;
+ } else {
+ return false;
+ }
+
+ return true;
+ }
+
public function stream_tell(): int
{
return $this->offset;
@@ -238,6 +256,8 @@ class StreamWrapper
public function stream_cast(int $castAs)
{
if (STREAM_CAST_FOR_SELECT === $castAs) {
+ $this->response->getHeaders(false);
+
return $this->handle ?? false;
}
diff --git a/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php b/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php
index b4b5b9ec1a..29171969b4 100644
--- a/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php
+++ b/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php
@@ -75,4 +75,20 @@ abstract class HttpClientTestCase extends BaseHttpClientTestCase
$response = $client->request('GET', 'http://localhost:8057/404');
$stream = $response->toStream();
}
+
+ public function testNonBlockingStream()
+ {
+ $client = $this->getHttpClient(__FUNCTION__);
+ $response = $client->request('GET', 'http://localhost:8057/timeout-body');
+ $stream = $response->toStream();
+
+ $this->assertTrue(stream_set_blocking($stream, false));
+ $this->assertSame('<1>', fread($stream, 8192));
+ $this->assertFalse(feof($stream));
+
+ $this->assertTrue(stream_set_blocking($stream, true));
+ $this->assertSame('<2>', fread($stream, 8192));
+ $this->assertSame('', fread($stream, 8192));
+ $this->assertTrue(feof($stream));
+ }
}
diff --git a/src/Symfony/Component/HttpClient/Tests/MockHttpClientTest.php b/src/Symfony/Component/HttpClient/Tests/MockHttpClientTest.php
index 7bc5283548..bce4bfafea 100644
--- a/src/Symfony/Component/HttpClient/Tests/MockHttpClientTest.php
+++ b/src/Symfony/Component/HttpClient/Tests/MockHttpClientTest.php
@@ -171,6 +171,10 @@ class MockHttpClientTest extends HttpClientTestCase
return $client;
+ case 'testNonBlockingStream':
+ $responses[] = new MockResponse((function () { yield '<1>'; yield ''; yield '<2>'; })(), ['response_headers' => $headers]);
+ break;
+
case 'testMaxDuration':
$mock = $this->getMockBuilder(ResponseInterface::class)->getMock();
$mock->expects($this->any())
diff --git a/src/Symfony/Component/HttpFoundation/LICENSE b/src/Symfony/Component/HttpFoundation/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/HttpFoundation/LICENSE
+++ b/src/Symfony/Component/HttpFoundation/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/HttpFoundation/README.md b/src/Symfony/Component/HttpFoundation/README.md
index 8907f0b967..ac98f9b80a 100644
--- a/src/Symfony/Component/HttpFoundation/README.md
+++ b/src/Symfony/Component/HttpFoundation/README.md
@@ -7,7 +7,7 @@ specification.
Resources
---------
- * [Documentation](https://symfony.com/doc/current/components/http_foundation/index.html)
+ * [Documentation](https://symfony.com/doc/current/components/http_foundation.html)
* [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)
diff --git a/src/Symfony/Component/HttpKernel/LICENSE b/src/Symfony/Component/HttpKernel/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/HttpKernel/LICENSE
+++ b/src/Symfony/Component/HttpKernel/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/HttpKernel/README.md b/src/Symfony/Component/HttpKernel/README.md
index cc5e74b6bc..abdaf513f9 100644
--- a/src/Symfony/Component/HttpKernel/README.md
+++ b/src/Symfony/Component/HttpKernel/README.md
@@ -9,7 +9,7 @@ an advanced CMS system (Drupal).
Resources
---------
- * [Documentation](https://symfony.com/doc/current/components/http_kernel/index.html)
+ * [Documentation](https://symfony.com/doc/current/components/http_kernel.html)
* [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)
diff --git a/src/Symfony/Component/Inflector/LICENSE b/src/Symfony/Component/Inflector/LICENSE
index f03153cc4a..2749b15672 100644
--- a/src/Symfony/Component/Inflector/LICENSE
+++ b/src/Symfony/Component/Inflector/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2012-2019 Fabien Potencier
+Copyright (c) 2012-2020 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
diff --git a/src/Symfony/Component/Intl/LICENSE b/src/Symfony/Component/Intl/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/Intl/LICENSE
+++ b/src/Symfony/Component/Intl/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/Ldap/LICENSE b/src/Symfony/Component/Ldap/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/Ldap/LICENSE
+++ b/src/Symfony/Component/Ldap/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/Lock/LICENSE b/src/Symfony/Component/Lock/LICENSE
index 3c464ca943..a7ec708018 100644
--- a/src/Symfony/Component/Lock/LICENSE
+++ b/src/Symfony/Component/Lock/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2016-2019 Fabien Potencier
+Copyright (c) 2016-2020 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
diff --git a/src/Symfony/Component/Mailer/Bridge/Amazon/LICENSE b/src/Symfony/Component/Mailer/Bridge/Amazon/LICENSE
index 1a1869751d..4bf0fef4ff 100644
--- a/src/Symfony/Component/Mailer/Bridge/Amazon/LICENSE
+++ b/src/Symfony/Component/Mailer/Bridge/Amazon/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2019 Fabien Potencier
+Copyright (c) 2019-2020 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
diff --git a/src/Symfony/Component/Mailer/Bridge/Google/LICENSE b/src/Symfony/Component/Mailer/Bridge/Google/LICENSE
index 1a1869751d..4bf0fef4ff 100644
--- a/src/Symfony/Component/Mailer/Bridge/Google/LICENSE
+++ b/src/Symfony/Component/Mailer/Bridge/Google/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2019 Fabien Potencier
+Copyright (c) 2019-2020 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
diff --git a/src/Symfony/Component/Mailer/Bridge/Mailchimp/LICENSE b/src/Symfony/Component/Mailer/Bridge/Mailchimp/LICENSE
index 1a1869751d..4bf0fef4ff 100644
--- a/src/Symfony/Component/Mailer/Bridge/Mailchimp/LICENSE
+++ b/src/Symfony/Component/Mailer/Bridge/Mailchimp/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2019 Fabien Potencier
+Copyright (c) 2019-2020 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
diff --git a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Tests/Transport/MandrillApiTransportTest.php b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Tests/Transport/MandrillApiTransportTest.php
index 2bec482818..af4cdbeebe 100644
--- a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Tests/Transport/MandrillApiTransportTest.php
+++ b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Tests/Transport/MandrillApiTransportTest.php
@@ -13,6 +13,9 @@ namespace Symfony\Component\Mailer\Bridge\Mailchimp\Tests\Transport;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Mailer\Bridge\Mailchimp\Transport\MandrillApiTransport;
+use Symfony\Component\Mailer\Envelope;
+use Symfony\Component\Mime\Address;
+use Symfony\Component\Mime\Email;
class MandrillApiTransportTest extends TestCase
{
@@ -41,4 +44,21 @@ class MandrillApiTransportTest extends TestCase
],
];
}
+
+ 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 MandrillApiTransport('ACCESS_KEY');
+ $method = new \ReflectionMethod(MandrillApiTransport::class, 'getPayload');
+ $method->setAccessible(true);
+ $payload = $method->invoke($transport, $email, $envelope);
+
+ $this->assertArrayHasKey('message', $payload);
+ $this->assertArrayHasKey('headers', $payload['message']);
+ $this->assertCount(1, $payload['message']['headers']);
+ $this->assertEquals('foo: bar', $payload['message']['headers'][0]);
+ }
}
diff --git a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillApiTransport.php b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillApiTransport.php
index 50fc33baaa..af221ca66e 100644
--- a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillApiTransport.php
+++ b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillApiTransport.php
@@ -94,10 +94,14 @@ class MandrillApiTransport extends AbstractApiTransport
'type' => $headers->get('Content-Type')->getBody(),
];
+ if ($name = $headers->getHeaderParameter('Content-Disposition', 'name')) {
+ $att['name'] = $name;
+ }
+
if ('inline' === $disposition) {
- $payload['images'][] = $att;
+ $payload['message']['images'][] = $att;
} else {
- $payload['attachments'][] = $att;
+ $payload['message']['attachments'][] = $att;
}
}
@@ -107,7 +111,7 @@ class MandrillApiTransport extends AbstractApiTransport
continue;
}
- $payload['message']['headers'][] = $name.': '.$header->toString();
+ $payload['message']['headers'][] = $name.': '.$header->getBodyAsString();
}
return $payload;
diff --git a/src/Symfony/Component/Mailer/Bridge/Mailgun/LICENSE b/src/Symfony/Component/Mailer/Bridge/Mailgun/LICENSE
index 1a1869751d..4bf0fef4ff 100644
--- a/src/Symfony/Component/Mailer/Bridge/Mailgun/LICENSE
+++ b/src/Symfony/Component/Mailer/Bridge/Mailgun/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2019 Fabien Potencier
+Copyright (c) 2019-2020 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
diff --git a/src/Symfony/Component/Mailer/Bridge/Mailgun/Tests/Transport/MailgunApiTransportTest.php b/src/Symfony/Component/Mailer/Bridge/Mailgun/Tests/Transport/MailgunApiTransportTest.php
index eb9838390a..f30fa0285c 100644
--- a/src/Symfony/Component/Mailer/Bridge/Mailgun/Tests/Transport/MailgunApiTransportTest.php
+++ b/src/Symfony/Component/Mailer/Bridge/Mailgun/Tests/Transport/MailgunApiTransportTest.php
@@ -13,6 +13,9 @@ namespace Symfony\Component\Mailer\Bridge\Mailgun\Tests\Transport;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Mailer\Bridge\Mailgun\Transport\MailgunApiTransport;
+use Symfony\Component\Mailer\Envelope;
+use Symfony\Component\Mime\Address;
+use Symfony\Component\Mime\Email;
class MailgunApiTransportTest extends TestCase
{
@@ -45,4 +48,20 @@ class MailgunApiTransportTest extends TestCase
],
];
}
+
+ public function testCustomHeader()
+ {
+ $json = json_encode(['foo' => 'bar']);
+ $email = new Email();
+ $email->getHeaders()->addTextHeader('X-Mailgun-Variables', $json);
+ $envelope = new Envelope(new Address('alice@system.com'), [new Address('bob@system.com')]);
+
+ $transport = new MailgunApiTransport('ACCESS_KEY', 'DOMAIN');
+ $method = new \ReflectionMethod(MailgunApiTransport::class, 'getPayload');
+ $method->setAccessible(true);
+ $payload = $method->invoke($transport, $email, $envelope);
+
+ $this->assertArrayHasKey('h:x-mailgun-variables', $payload);
+ $this->assertEquals($json, $payload['h:x-mailgun-variables']);
+ }
}
diff --git a/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunApiTransport.php b/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunApiTransport.php
index 8d7b5cc7e2..cf40a8cf1e 100644
--- a/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunApiTransport.php
+++ b/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunApiTransport.php
@@ -114,7 +114,7 @@ class MailgunApiTransport extends AbstractApiTransport
continue;
}
- $payload['h:'.$name] = $header->toString();
+ $payload['h:'.$name] = $header->getBodyAsString();
}
return $payload;
diff --git a/src/Symfony/Component/Mailer/Bridge/Postmark/LICENSE b/src/Symfony/Component/Mailer/Bridge/Postmark/LICENSE
index 1a1869751d..4bf0fef4ff 100644
--- a/src/Symfony/Component/Mailer/Bridge/Postmark/LICENSE
+++ b/src/Symfony/Component/Mailer/Bridge/Postmark/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2019 Fabien Potencier
+Copyright (c) 2019-2020 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
diff --git a/src/Symfony/Component/Mailer/Bridge/Postmark/Tests/Transport/PostmarkApiTransportTest.php b/src/Symfony/Component/Mailer/Bridge/Postmark/Tests/Transport/PostmarkApiTransportTest.php
index b6568706f8..6996997b65 100644
--- a/src/Symfony/Component/Mailer/Bridge/Postmark/Tests/Transport/PostmarkApiTransportTest.php
+++ b/src/Symfony/Component/Mailer/Bridge/Postmark/Tests/Transport/PostmarkApiTransportTest.php
@@ -13,6 +13,9 @@ namespace Symfony\Component\Mailer\Bridge\Postmark\Tests\Transport;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Mailer\Bridge\Postmark\Transport\PostmarkApiTransport;
+use Symfony\Component\Mailer\Envelope;
+use Symfony\Component\Mime\Address;
+use Symfony\Component\Mime\Email;
class PostmarkApiTransportTest extends TestCase
{
@@ -41,4 +44,21 @@ class PostmarkApiTransportTest extends TestCase
],
];
}
+
+ 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 PostmarkApiTransport('ACCESS_KEY');
+ $method = new \ReflectionMethod(PostmarkApiTransport::class, 'getPayload');
+ $method->setAccessible(true);
+ $payload = $method->invoke($transport, $email, $envelope);
+
+ $this->assertArrayHasKey('Headers', $payload);
+ $this->assertCount(1, $payload['Headers']);
+
+ $this->assertEquals(['Name' => 'foo', 'Value' => 'bar'], $payload['Headers'][0]);
+ }
}
diff --git a/src/Symfony/Component/Mailer/Bridge/Postmark/Transport/PostmarkApiTransport.php b/src/Symfony/Component/Mailer/Bridge/Postmark/Transport/PostmarkApiTransport.php
index 96dd8d4a65..610f858260 100644
--- a/src/Symfony/Component/Mailer/Bridge/Postmark/Transport/PostmarkApiTransport.php
+++ b/src/Symfony/Component/Mailer/Bridge/Postmark/Transport/PostmarkApiTransport.php
@@ -84,7 +84,7 @@ class PostmarkApiTransport extends AbstractApiTransport
$payload['Headers'][] = [
'Name' => $name,
- 'Value' => $header->toString(),
+ 'Value' => $header->getBodyAsString(),
];
}
diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/LICENSE b/src/Symfony/Component/Mailer/Bridge/Sendgrid/LICENSE
index 1a1869751d..4bf0fef4ff 100644
--- a/src/Symfony/Component/Mailer/Bridge/Sendgrid/LICENSE
+++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2019 Fabien Potencier
+Copyright (c) 2019-2020 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
diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Transport/SendgridApiTransportTest.php b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Transport/SendgridApiTransportTest.php
index 9ad5c280ec..ab271d574c 100644
--- a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Transport/SendgridApiTransportTest.php
+++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Transport/SendgridApiTransportTest.php
@@ -13,6 +13,8 @@ namespace Symfony\Component\Mailer\Bridge\Sendgrid\Tests\Transport;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Mailer\Bridge\Sendgrid\Transport\SendgridApiTransport;
+use Symfony\Component\Mailer\Envelope;
+use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;
@@ -48,8 +50,8 @@ class SendgridApiTransportTest extends TestCase
public function testSend()
{
$email = new Email();
- $email->from('foo@example.com')
- ->to('bar@example.com')
+ $email->from(new Address('foo@example.com', 'Ms. Foo Bar'))
+ ->to(new Address('bar@example.com', 'Mr. Recipient'))
->bcc('baz@example.com')
->text('content');
@@ -73,12 +75,18 @@ class SendgridApiTransportTest extends TestCase
'json' => [
'personalizations' => [
[
- 'to' => [['email' => 'bar@example.com']],
+ 'to' => [[
+ 'email' => 'bar@example.com',
+ 'name' => 'Mr. Recipient',
+ ]],
'subject' => null,
'bcc' => [['email' => 'baz@example.com']],
],
],
- 'from' => ['email' => 'foo@example.com'],
+ 'from' => [
+ 'email' => 'foo@example.com',
+ 'name' => 'Ms. Foo Bar',
+ ],
'content' => [
['type' => 'text/plain', 'value' => 'content'],
],
@@ -90,4 +98,72 @@ class SendgridApiTransportTest extends TestCase
$mailer = new SendgridApiTransport('foo', $httpClient);
$mailer->send($email);
}
+
+ public function testLineBreaksInEncodedAttachment()
+ {
+ $email = new Email();
+ $email->from('foo@example.com')
+ ->to('bar@example.com')
+ // even if content doesn't include new lines, the base64 encoding performed later may add them
+ ->attach('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod', 'lorem.txt');
+
+ $response = $this->createMock(ResponseInterface::class);
+
+ $response
+ ->expects($this->once())
+ ->method('getStatusCode')
+ ->willReturn(202);
+ $response
+ ->expects($this->once())
+ ->method('getHeaders')
+ ->willReturn(['x-message-id' => '1']);
+
+ $httpClient = $this->createMock(HttpClientInterface::class);
+
+ $httpClient
+ ->expects($this->once())
+ ->method('request')
+ ->with('POST', 'https://api.sendgrid.com/v3/mail/send', [
+ 'json' => [
+ 'personalizations' => [
+ [
+ 'to' => [['email' => 'bar@example.com']],
+ 'subject' => null,
+ ],
+ ],
+ 'from' => ['email' => 'foo@example.com'],
+ 'content' => [],
+ 'attachments' => [
+ [
+ 'content' => 'TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdCwgc2VkIGRvIGVpdXNtb2Q=',
+ 'filename' => 'lorem.txt',
+ 'type' => 'application/octet-stream',
+ 'disposition' => 'attachment',
+ ],
+ ],
+ ],
+ 'auth_bearer' => 'foo',
+ ])
+ ->willReturn($response);
+
+ $mailer = new SendgridApiTransport('foo', $httpClient);
+
+ $mailer->send($email);
+ }
+
+ 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 SendgridApiTransport('ACCESS_KEY');
+ $method = new \ReflectionMethod(SendgridApiTransport::class, 'getPayload');
+ $method->setAccessible(true);
+ $payload = $method->invoke($transport, $email, $envelope);
+
+ $this->assertArrayHasKey('headers', $payload);
+ $this->assertArrayHasKey('foo', $payload['headers']);
+ $this->assertEquals('bar', $payload['headers']['foo']);
+ }
}
diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Transport/SendgridApiTransport.php b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Transport/SendgridApiTransport.php
index 262983afd7..df90d21472 100644
--- a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Transport/SendgridApiTransport.php
+++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Transport/SendgridApiTransport.php
@@ -63,11 +63,19 @@ class SendgridApiTransport extends AbstractApiTransport
private function getPayload(Email $email, Envelope $envelope): array
{
- $addressStringifier = function (Address $address) {return ['email' => $address->toString()]; };
+ $addressStringifier = function (Address $address) {
+ $stringified = ['email' => $address->getAddress()];
+
+ if ($address->getName()) {
+ $stringified['name'] = $address->getName();
+ }
+
+ return $stringified;
+ };
$payload = [
'personalizations' => [],
- 'from' => ['email' => $envelope->getSender()->toString()],
+ 'from' => $addressStringifier($envelope->getSender()),
'content' => $this->getContent($email),
];
@@ -96,7 +104,7 @@ class SendgridApiTransport extends AbstractApiTransport
continue;
}
- $payload['headers'][$name] = $header->toString();
+ $payload['headers'][$name] = $header->getBodyAsString();
}
return $payload;
@@ -124,7 +132,7 @@ class SendgridApiTransport extends AbstractApiTransport
$disposition = $headers->getHeaderBody('Content-Disposition');
$att = [
- 'content' => $attachment->bodyToString(),
+ 'content' => str_replace("\r\n", '', $attachment->bodyToString()),
'type' => $headers->get('Content-Type')->getBody(),
'filename' => $filename,
'disposition' => $disposition,
diff --git a/src/Symfony/Component/Mailer/LICENSE b/src/Symfony/Component/Mailer/LICENSE
index 1a1869751d..4bf0fef4ff 100644
--- a/src/Symfony/Component/Mailer/LICENSE
+++ b/src/Symfony/Component/Mailer/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2019 Fabien Potencier
+Copyright (c) 2019-2020 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
diff --git a/src/Symfony/Component/Messenger/LICENSE b/src/Symfony/Component/Messenger/LICENSE
index 3f853aaf35..69d925ba75 100644
--- a/src/Symfony/Component/Messenger/LICENSE
+++ b/src/Symfony/Component/Messenger/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2018-2019 Fabien Potencier
+Copyright (c) 2018-2020 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
diff --git a/src/Symfony/Component/Mime/LICENSE b/src/Symfony/Component/Mime/LICENSE
index 9a9a61b1c6..d53be68356 100644
--- a/src/Symfony/Component/Mime/LICENSE
+++ b/src/Symfony/Component/Mime/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2010-2019 Fabien Potencier
+Copyright (c) 2010-2020 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
diff --git a/src/Symfony/Component/OptionsResolver/LICENSE b/src/Symfony/Component/OptionsResolver/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/OptionsResolver/LICENSE
+++ b/src/Symfony/Component/OptionsResolver/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/Process/LICENSE b/src/Symfony/Component/Process/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/Process/LICENSE
+++ b/src/Symfony/Component/Process/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/PropertyAccess/LICENSE b/src/Symfony/Component/PropertyAccess/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/PropertyAccess/LICENSE
+++ b/src/Symfony/Component/PropertyAccess/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/PropertyAccess/README.md b/src/Symfony/Component/PropertyAccess/README.md
index 1959fd9e93..891528d29c 100644
--- a/src/Symfony/Component/PropertyAccess/README.md
+++ b/src/Symfony/Component/PropertyAccess/README.md
@@ -7,7 +7,7 @@ object or array using a simple string notation.
Resources
---------
- * [Documentation](https://symfony.com/doc/current/components/property_access/index.html)
+ * [Documentation](https://symfony.com/doc/current/components/property_access.html)
* [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)
diff --git a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php
index e5f2d4f0d5..97a106a616 100644
--- a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php
+++ b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php
@@ -201,6 +201,8 @@ class PhpDocExtractor implements PropertyDescriptionExtractorInterface, Property
return $this->docBlockFactory->create($reflectionProperty, $this->createFromReflector($reflectionProperty->getDeclaringClass()));
} catch (\InvalidArgumentException $e) {
return null;
+ } catch (\RuntimeException $e) {
+ return null;
}
}
@@ -237,6 +239,8 @@ class PhpDocExtractor implements PropertyDescriptionExtractorInterface, Property
return [$this->docBlockFactory->create($reflectionMethod, $this->createFromReflector($reflectionMethod->getDeclaringClass())), $prefix];
} catch (\InvalidArgumentException $e) {
return null;
+ } catch (\RuntimeException $e) {
+ return null;
}
}
diff --git a/src/Symfony/Component/PropertyInfo/LICENSE b/src/Symfony/Component/PropertyInfo/LICENSE
index 4cd8bdd300..5612f967a2 100644
--- a/src/Symfony/Component/PropertyInfo/LICENSE
+++ b/src/Symfony/Component/PropertyInfo/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2015-2019 Fabien Potencier
+Copyright (c) 2015-2020 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
diff --git a/src/Symfony/Component/Routing/Generator/CompiledUrlGenerator.php b/src/Symfony/Component/Routing/Generator/CompiledUrlGenerator.php
index 8c489f8d4c..b10edce4e9 100644
--- a/src/Symfony/Component/Routing/Generator/CompiledUrlGenerator.php
+++ b/src/Symfony/Component/Routing/Generator/CompiledUrlGenerator.php
@@ -40,7 +40,6 @@ class CompiledUrlGenerator extends UrlGenerator
if (null !== $locale) {
do {
if (($this->compiledRoutes[$name.'.'.$locale][1]['_canonical_route'] ?? null) === $name) {
- unset($parameters['_locale']);
$name .= '.'.$locale;
break;
}
@@ -53,6 +52,14 @@ class CompiledUrlGenerator extends UrlGenerator
list($variables, $defaults, $requirements, $tokens, $hostTokens, $requiredSchemes) = $this->compiledRoutes[$name];
+ if (isset($defaults['_canonical_route']) && isset($defaults['_locale'])) {
+ if (!\in_array('_locale', $variables, true)) {
+ unset($parameters['_locale']);
+ } elseif (!isset($parameters['_locale'])) {
+ $parameters['_locale'] = $defaults['_locale'];
+ }
+ }
+
return $this->doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, $requiredSchemes);
}
}
diff --git a/src/Symfony/Component/Routing/Generator/UrlGenerator.php b/src/Symfony/Component/Routing/Generator/UrlGenerator.php
index 504dd321fd..5473e856e1 100644
--- a/src/Symfony/Component/Routing/Generator/UrlGenerator.php
+++ b/src/Symfony/Component/Routing/Generator/UrlGenerator.php
@@ -134,7 +134,6 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
if (null !== $locale) {
do {
if (null !== ($route = $this->routes->get($name.'.'.$locale)) && $route->getDefault('_canonical_route') === $name) {
- unset($parameters['_locale']);
break;
}
} while (false !== $locale = strstr($locale, '_', true));
@@ -147,7 +146,18 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
// the Route has a cache of its own and is not recompiled as long as it does not get modified
$compiledRoute = $route->compile();
- return $this->doGenerate($compiledRoute->getVariables(), $route->getDefaults(), $route->getRequirements(), $compiledRoute->getTokens(), $parameters, $name, $referenceType, $compiledRoute->getHostTokens(), $route->getSchemes());
+ $defaults = $route->getDefaults();
+ $variables = $compiledRoute->getVariables();
+
+ if (isset($defaults['_canonical_route']) && isset($defaults['_locale'])) {
+ if (!\in_array('_locale', $variables, true)) {
+ unset($parameters['_locale']);
+ } elseif (!isset($parameters['_locale'])) {
+ $parameters['_locale'] = $defaults['_locale'];
+ }
+ }
+
+ return $this->doGenerate($variables, $defaults, $route->getRequirements(), $compiledRoute->getTokens(), $parameters, $name, $referenceType, $compiledRoute->getHostTokens(), $route->getSchemes());
}
/**
diff --git a/src/Symfony/Component/Routing/LICENSE b/src/Symfony/Component/Routing/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/Routing/LICENSE
+++ b/src/Symfony/Component/Routing/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/Routing/README.md b/src/Symfony/Component/Routing/README.md
index 88fb1fde5a..a16d9d7fcb 100644
--- a/src/Symfony/Component/Routing/README.md
+++ b/src/Symfony/Component/Routing/README.md
@@ -6,7 +6,7 @@ The Routing component maps an HTTP request to a set of configuration variables.
Resources
---------
- * [Documentation](https://symfony.com/doc/current/components/routing/index.html)
+ * [Documentation](https://symfony.com/doc/current/components/routing.html)
* [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)
diff --git a/src/Symfony/Component/Routing/Tests/Generator/Dumper/CompiledUrlGeneratorDumperTest.php b/src/Symfony/Component/Routing/Tests/Generator/Dumper/CompiledUrlGeneratorDumperTest.php
index 521f0f126c..de4776ff78 100644
--- a/src/Symfony/Component/Routing/Tests/Generator/Dumper/CompiledUrlGeneratorDumperTest.php
+++ b/src/Symfony/Component/Routing/Tests/Generator/Dumper/CompiledUrlGeneratorDumperTest.php
@@ -131,9 +131,9 @@ class CompiledUrlGeneratorDumperTest extends TestCase
public function testDumpWithFallbackLocaleLocalizedRoutes()
{
- $this->routeCollection->add('test.en', (new Route('/testing/is/fun'))->setDefault('_canonical_route', 'test'));
- $this->routeCollection->add('test.nl', (new Route('/testen/is/leuk'))->setDefault('_canonical_route', 'test'));
- $this->routeCollection->add('test.fr', (new Route('/tester/est/amusant'))->setDefault('_canonical_route', 'test'));
+ $this->routeCollection->add('test.en', (new Route('/testing/is/fun'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'test'));
+ $this->routeCollection->add('test.nl', (new Route('/testen/is/leuk'))->setDefault('_locale', 'nl')->setDefault('_canonical_route', 'test'));
+ $this->routeCollection->add('test.fr', (new Route('/tester/est/amusant'))->setDefault('_locale', 'fr')->setDefault('_canonical_route', 'test'));
$code = $this->generatorDumper->dump();
file_put_contents($this->testTmpFilepath, $code);
@@ -231,4 +231,29 @@ class CompiledUrlGeneratorDumperTest extends TestCase
$this->assertEquals('https://localhost/app.php/testing', $absoluteUrl);
$this->assertEquals('/app.php/testing', $relativeUrl);
}
+
+ public function testDumpWithLocalizedRoutesPreserveTheGoodLocaleInTheUrl()
+ {
+ $this->routeCollection->add('foo.en', (new Route('/{_locale}/foo'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'foo'));
+ $this->routeCollection->add('foo.fr', (new Route('/{_locale}/foo'))->setDefault('_locale', 'fr')->setDefault('_canonical_route', 'foo'));
+ $this->routeCollection->add('fun.en', (new Route('/fun'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'fun'));
+ $this->routeCollection->add('fun.fr', (new Route('/amusant'))->setDefault('_locale', 'fr')->setDefault('_canonical_route', 'fun'));
+
+ file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump());
+
+ $requestContext = new RequestContext();
+ $requestContext->setParameter('_locale', 'fr');
+
+ $compiledUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, $requestContext, null, null);
+
+ $this->assertSame('/fr/foo', $compiledUrlGenerator->generate('foo'));
+ $this->assertSame('/en/foo', $compiledUrlGenerator->generate('foo.en'));
+ $this->assertSame('/en/foo', $compiledUrlGenerator->generate('foo', ['_locale' => 'en']));
+ $this->assertSame('/en/foo', $compiledUrlGenerator->generate('foo.fr', ['_locale' => 'en']));
+
+ $this->assertSame('/amusant', $compiledUrlGenerator->generate('fun'));
+ $this->assertSame('/fun', $compiledUrlGenerator->generate('fun.en'));
+ $this->assertSame('/fun', $compiledUrlGenerator->generate('fun', ['_locale' => 'en']));
+ $this->assertSame('/amusant', $compiledUrlGenerator->generate('fun.fr', ['_locale' => 'en']));
+ }
}
diff --git a/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php b/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php
index a768384747..01215da2c0 100644
--- a/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php
+++ b/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php
@@ -236,6 +236,29 @@ class UrlGeneratorTest extends TestCase
);
}
+ public function testDumpWithLocalizedRoutesPreserveTheGoodLocaleInTheUrl()
+ {
+ $routeCollection = new RouteCollection();
+
+ $routeCollection->add('foo.en', (new Route('/{_locale}/foo'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'foo'));
+ $routeCollection->add('foo.fr', (new Route('/{_locale}/foo'))->setDefault('_locale', 'fr')->setDefault('_canonical_route', 'foo'));
+ $routeCollection->add('fun.en', (new Route('/fun'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'fun'));
+ $routeCollection->add('fun.fr', (new Route('/amusant'))->setDefault('_locale', 'fr')->setDefault('_canonical_route', 'fun'));
+
+ $urlGenerator = $this->getGenerator($routeCollection);
+ $urlGenerator->getContext()->setParameter('_locale', 'fr');
+
+ $this->assertSame('/app.php/fr/foo', $urlGenerator->generate('foo'));
+ $this->assertSame('/app.php/en/foo', $urlGenerator->generate('foo.en'));
+ $this->assertSame('/app.php/en/foo', $urlGenerator->generate('foo', ['_locale' => 'en']));
+ $this->assertSame('/app.php/en/foo', $urlGenerator->generate('foo.fr', ['_locale' => 'en']));
+
+ $this->assertSame('/app.php/amusant', $urlGenerator->generate('fun'));
+ $this->assertSame('/app.php/fun', $urlGenerator->generate('fun.en'));
+ $this->assertSame('/app.php/fun', $urlGenerator->generate('fun', ['_locale' => 'en']));
+ $this->assertSame('/app.php/amusant', $urlGenerator->generate('fun.fr', ['_locale' => 'en']));
+ }
+
public function testGenerateWithoutRoutes()
{
$this->expectException('Symfony\Component\Routing\Exception\RouteNotFoundException');
diff --git a/src/Symfony/Component/Security/Core/LICENSE b/src/Symfony/Component/Security/Core/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/Security/Core/LICENSE
+++ b/src/Symfony/Component/Security/Core/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/Security/Core/README.md b/src/Symfony/Component/Security/Core/README.md
index ede185bd3b..70476d9e7f 100644
--- a/src/Symfony/Component/Security/Core/README.md
+++ b/src/Symfony/Component/Security/Core/README.md
@@ -9,7 +9,7 @@ the Java Spring framework.
Resources
---------
- * [Documentation](https://symfony.com/doc/current/components/security/index.html)
+ * [Documentation](https://symfony.com/doc/current/components/security.html)
* [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)
diff --git a/src/Symfony/Component/Security/Csrf/LICENSE b/src/Symfony/Component/Security/Csrf/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/Security/Csrf/LICENSE
+++ b/src/Symfony/Component/Security/Csrf/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/Security/Csrf/README.md b/src/Symfony/Component/Security/Csrf/README.md
index aff72a0c32..15b9ace238 100644
--- a/src/Symfony/Component/Security/Csrf/README.md
+++ b/src/Symfony/Component/Security/Csrf/README.md
@@ -7,7 +7,7 @@ The Security CSRF (cross-site request forgery) component provides a class
Resources
---------
- * [Documentation](https://symfony.com/doc/current/components/security/index.html)
+ * [Documentation](https://symfony.com/doc/current/components/security.html)
* [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)
diff --git a/src/Symfony/Component/Security/Guard/LICENSE b/src/Symfony/Component/Security/Guard/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/Security/Guard/LICENSE
+++ b/src/Symfony/Component/Security/Guard/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/Security/Guard/PasswordAuthenticatedInterface.php b/src/Symfony/Component/Security/Guard/PasswordAuthenticatedInterface.php
index 4dd7a7b446..dd2eeba33d 100644
--- a/src/Symfony/Component/Security/Guard/PasswordAuthenticatedInterface.php
+++ b/src/Symfony/Component/Security/Guard/PasswordAuthenticatedInterface.php
@@ -19,7 +19,7 @@ interface PasswordAuthenticatedInterface
/**
* Returns the clear-text password contained in credentials if any.
*
- * @param mixed The user credentials
+ * @param mixed $credentials The user credentials
*/
public function getPassword($credentials): ?string;
}
diff --git a/src/Symfony/Component/Security/Guard/README.md b/src/Symfony/Component/Security/Guard/README.md
index ce70622390..40083a48d7 100644
--- a/src/Symfony/Component/Security/Guard/README.md
+++ b/src/Symfony/Component/Security/Guard/README.md
@@ -8,7 +8,7 @@ total control.
Resources
---------
- * [Documentation](https://symfony.com/doc/current/components/security/index.html)
+ * [Documentation](https://symfony.com/doc/current/components/security.html)
* [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)
diff --git a/src/Symfony/Component/Security/Http/LICENSE b/src/Symfony/Component/Security/Http/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/Security/Http/LICENSE
+++ b/src/Symfony/Component/Security/Http/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/Security/Http/README.md b/src/Symfony/Component/Security/Http/README.md
index 5be2111830..dbac8c659c 100644
--- a/src/Symfony/Component/Security/Http/README.md
+++ b/src/Symfony/Component/Security/Http/README.md
@@ -9,7 +9,7 @@ the Java Spring framework.
Resources
---------
- * [Documentation](https://symfony.com/doc/current/components/security/index.html)
+ * [Documentation](https://symfony.com/doc/current/components/security.html)
* [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)
diff --git a/src/Symfony/Component/Serializer/LICENSE b/src/Symfony/Component/Serializer/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/Serializer/LICENSE
+++ b/src/Symfony/Component/Serializer/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/Stopwatch/LICENSE b/src/Symfony/Component/Stopwatch/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/Stopwatch/LICENSE
+++ b/src/Symfony/Component/Stopwatch/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/Templating/LICENSE b/src/Symfony/Component/Templating/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/Templating/LICENSE
+++ b/src/Symfony/Component/Templating/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/Templating/README.md b/src/Symfony/Component/Templating/README.md
index 58e2a0a5c6..2b8ecad873 100644
--- a/src/Symfony/Component/Templating/README.md
+++ b/src/Symfony/Component/Templating/README.md
@@ -12,7 +12,7 @@ layouts.
Resources
---------
- * [Documentation](https://symfony.com/doc/current/components/templating/index.html)
+ * [Documentation](https://symfony.com/doc/current/components/templating.html)
* [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)
diff --git a/src/Symfony/Component/Translation/LICENSE b/src/Symfony/Component/Translation/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/Translation/LICENSE
+++ b/src/Symfony/Component/Translation/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/Translation/MessageCatalogue.php b/src/Symfony/Component/Translation/MessageCatalogue.php
index e0b18e9801..429a3c6877 100644
--- a/src/Symfony/Component/Translation/MessageCatalogue.php
+++ b/src/Symfony/Component/Translation/MessageCatalogue.php
@@ -156,7 +156,9 @@ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterf
if (!isset($this->messages[$domain])) {
$this->messages[$domain] = $messages;
} else {
- $this->messages[$domain] = array_replace($this->messages[$domain], $messages);
+ foreach ($messages as $id => $message) {
+ $this->messages[$domain][$id] = $message;
+ }
}
}
diff --git a/src/Symfony/Component/Translation/README.md b/src/Symfony/Component/Translation/README.md
index 46f3d1f2f2..e80a70cad0 100644
--- a/src/Symfony/Component/Translation/README.md
+++ b/src/Symfony/Component/Translation/README.md
@@ -6,7 +6,7 @@ The Translation component provides tools to internationalize your application.
Resources
---------
- * [Documentation](https://symfony.com/doc/current/components/translation/index.html)
+ * [Documentation](https://symfony.com/doc/current/components/translation.html)
* [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)
diff --git a/src/Symfony/Component/Validator/LICENSE b/src/Symfony/Component/Validator/LICENSE
index a677f43763..9e936ec044 100644
--- a/src/Symfony/Component/Validator/LICENSE
+++ b/src/Symfony/Component/Validator/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 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
diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.ar.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.ar.xlf
index 12f26fdc88..79dab63d7d 100644
--- a/src/Symfony/Component/Validator/Resources/translations/validators.ar.xlf
+++ b/src/Symfony/Component/Validator/Resources/translations/validators.ar.xlf
@@ -334,6 +334,38 @@
هذه القيمة يجب أن تكون صالحة ل JSON.
+
+
+ يجب أن تحتوي هذه المجموعة علي عناصر فريدة فقط.
+
+
+
+ يجب أن تكون هذه القيمة موجبة.
+
+
+
+ يجب أن تكون هذه القيمة إما موجبة او صفر.
+
+
+
+ يجب أن تكون هذه القيمة سالبة.
+
+
+
+ يجب أن تكون هذه القيمة إما سالبة او صفر.
+
+
+
+ هذه القيمة ليست منطقة زمنية صحيحة.
+
+
+
+ تم تسريب كلمة المرور هذه في خرق للبيانات، ويجب عدم استخدامها. يرجي استخدام كلمة مرور أخري.
+
+
+
+ يجب أن تكون هذه القيمة بين {{ min }} و {{ max }}.
+