Merge branch '4.3' into 4.4
* 4.3: [Mailer] Remove line breaks in email attachment content Update links to documentation [Validator] Add the missing translations for the Arabic (ar) locale ensure to expect no validation for the right reasons [PhpUnitBridge] Add test case for @expectedDeprecation annotation [PhpUnitBridge][SymfonyTestsListenerTrait] Remove $testsWithWarnings stack [Mailer][MailchimpBridge] Fix missing attachments when sending via Mandrill API [Mailer][MailchimpBridge] Fix incorrect sender address when sender has name [HttpClient] fix capturing SSL certificates with NativeHttpClient [TwigBridge][Form] Added missing help messages in form themes Update year in license files Update year in license files [HttpClient] fix typo [Console][FormatterHelper] Use helper strlen statically and remove duplicated code [Routing] Fix i18n routing when the url contains the locale Fix BC issue in phpDoc Reflection library [Translator] Performance improvement in MessageCatalogue and catalogue operations.
This commit is contained in:
commit
c000577edb
2
LICENSE
2
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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)) {
|
||||
|
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -64,6 +64,7 @@ col-sm-10
|
||||
<div class="{{ block('form_label_class') }}"></div>{#--#}
|
||||
<div class="{{ block('form_group_class') }}">
|
||||
{{- form_widget(form) -}}
|
||||
{{- form_help(form) -}}
|
||||
{{- form_errors(form) -}}
|
||||
</div>{#--#}
|
||||
</div>
|
||||
|
@ -148,6 +148,7 @@
|
||||
{% block checkbox_row -%}
|
||||
<div{% with {attr: row_attr|merge({class: (row_attr.class|default('') ~ ' form-group' ~ (not valid ? ' has-error'))|trim})} %}{{ block('attributes') }}{% endwith %}>
|
||||
{{- form_widget(form) -}}
|
||||
{{- form_help(form) -}}
|
||||
{{- form_errors(form) -}}
|
||||
</div>
|
||||
{%- endblock checkbox_row %}
|
||||
@ -155,6 +156,7 @@
|
||||
{% block radio_row -%}
|
||||
<div{% with {attr: row_attr|merge({class: (row_attr.class|default('') ~ ' form-group' ~ (not valid ? ' has-error'))|trim})} %}{{ block('attributes') }}{% endwith %}>
|
||||
{{- form_widget(form) -}}
|
||||
{{- form_help(form) -}}
|
||||
{{- form_errors(form) -}}
|
||||
</div>
|
||||
{%- endblock radio_row %}
|
||||
|
@ -311,6 +311,7 @@
|
||||
<div{% with {attr: row_attr|merge({class: (row_attr.class|default('') ~ ' row')|trim})} %}{{ block('attributes') }}{% endwith %}>
|
||||
<div class="large-12 columns{% if not valid %} error{% endif %}">
|
||||
{{ form_widget(form) }}
|
||||
{{- form_help(form) -}}
|
||||
{{ form_errors(form) }}
|
||||
</div>
|
||||
</div>
|
||||
@ -320,6 +321,7 @@
|
||||
<div{% with {attr: row_attr|merge({class: (row_attr.class|default('') ~ ' row')|trim})} %}{{ block('attributes') }}{% endwith %}>
|
||||
<div class="large-12 columns{% if not valid %} error{% endif %}">
|
||||
{{ form_widget(form) }}
|
||||
{{- form_help(form) -}}
|
||||
{{ form_errors(form) }}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -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]"]
|
||||
]
|
||||
]
|
||||
'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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', [
|
||||
@ -2284,6 +2299,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]]);
|
||||
|
@ -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]"]
|
||||
]
|
||||
]
|
||||
'
|
||||
);
|
||||
}
|
||||
|
@ -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, [
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -54,12 +54,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);
|
||||
@ -83,17 +83,13 @@ class FormatterHelper extends Helper
|
||||
*/
|
||||
public function truncate($message, $length, $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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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:');
|
||||
});
|
||||
}
|
||||
|
@ -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];
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -97,4 +97,56 @@ 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);
|
||||
}
|
||||
}
|
||||
|
@ -132,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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -116,7 +116,6 @@ EOF;
|
||||
if (null !== $locale && null !== $name) {
|
||||
do {
|
||||
if ((self::$declaredRoutes[$name.'.'.$locale][1]['_canonical_route'] ?? null) === $name) {
|
||||
unset($parameters['_locale']);
|
||||
$name .= '.'.$locale;
|
||||
break;
|
||||
}
|
||||
@ -129,6 +128,14 @@ EOF;
|
||||
|
||||
list($variables, $defaults, $requirements, $tokens, $hostTokens, $requiredSchemes) = self::$declaredRoutes[$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);
|
||||
}
|
||||
EOF;
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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']));
|
||||
}
|
||||
}
|
||||
|
@ -140,9 +140,9 @@ class PhpGeneratorDumperTest 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([
|
||||
'class' => 'FallbackLocaleLocalizedProjectUrlGenerator',
|
||||
@ -250,4 +250,32 @@ class PhpGeneratorDumperTest 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([
|
||||
'class' => 'PreserveTheGoodLocaleInTheUrlGenerator',
|
||||
]));
|
||||
include $this->testTmpFilepath;
|
||||
|
||||
$requestContext = new RequestContext();
|
||||
$requestContext->setParameter('_locale', 'fr');
|
||||
|
||||
$phpGenerator = new \PreserveTheGoodLocaleInTheUrlGenerator($requestContext);
|
||||
|
||||
$this->assertSame('/fr/foo', $phpGenerator->generate('foo'));
|
||||
$this->assertSame('/en/foo', $phpGenerator->generate('foo.en'));
|
||||
$this->assertSame('/en/foo', $phpGenerator->generate('foo', ['_locale' => 'en']));
|
||||
$this->assertSame('/en/foo', $phpGenerator->generate('foo.fr', ['_locale' => 'en']));
|
||||
|
||||
$this->assertSame('/amusant', $phpGenerator->generate('fun'));
|
||||
$this->assertSame('/fun', $phpGenerator->generate('fun.en'));
|
||||
$this->assertSame('/fun', $phpGenerator->generate('fun', ['_locale' => 'en']));
|
||||
$this->assertSame('/amusant', $phpGenerator->generate('fun.fr', ['_locale' => 'en']));
|
||||
}
|
||||
}
|
||||
|
@ -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');
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -11,7 +11,7 @@ roles.
|
||||
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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -160,7 +160,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user