diff --git a/src/Symfony/Bridge/Twig/Tests/Node/DumpNodeTest.php b/src/Symfony/Bridge/Twig/Tests/Node/DumpNodeTest.php index 5d8ea6f086..035dc4f671 100644 --- a/src/Symfony/Bridge/Twig/Tests/Node/DumpNodeTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Node/DumpNodeTest.php @@ -80,7 +80,13 @@ if ($this->env->isDebug()) { } EOTXT; - $expected = preg_replace('/%(.*?)%/', PHP_VERSION_ID >= 50400 ? '(isset($context["$1"]) ? $context["$1"] : null)' : '$this->getContext($context, "$1")', $expected); + if (PHP_VERSION_ID >= 70000) { + $expected = preg_replace('/%(.*?)%/', '($context["$1"] ?? null)', $expected); + } elseif (PHP_VERSION_ID >= 50400) { + $expected = preg_replace('/%(.*?)%/', '(isset($context["$1"]) ? $context["$1"] : null)', $expected); + } else { + $expected = preg_replace('/%(.*?)%/', '$this->getContext($context, "$1")', $expected); + } $this->assertSame($expected, $compiler->compile($node)->getSource()); } @@ -106,7 +112,14 @@ if ($this->env->isDebug()) { } EOTXT; - $expected = preg_replace('/%(.*?)%/', PHP_VERSION_ID >= 50400 ? '(isset($context["$1"]) ? $context["$1"] : null)' : '$this->getContext($context, "$1")', $expected); + + if (PHP_VERSION_ID >= 70000) { + $expected = preg_replace('/%(.*?)%/', '($context["$1"] ?? null)', $expected); + } elseif (PHP_VERSION_ID >= 50400) { + $expected = preg_replace('/%(.*?)%/', '(isset($context["$1"]) ? $context["$1"] : null)', $expected); + } else { + $expected = preg_replace('/%(.*?)%/', '$this->getContext($context, "$1")', $expected); + } $this->assertSame($expected, $compiler->compile($node)->getSource()); } diff --git a/src/Symfony/Bridge/Twig/Tests/Node/FormThemeTest.php b/src/Symfony/Bridge/Twig/Tests/Node/FormThemeTest.php index f407afdcd6..590b9ef75c 100644 --- a/src/Symfony/Bridge/Twig/Tests/Node/FormThemeTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Node/FormThemeTest.php @@ -66,6 +66,10 @@ class FormThemeTest extends \PHPUnit_Framework_TestCase protected function getVariableGetter($name) { + if (PHP_VERSION_ID >= 70000) { + return sprintf('($context["%s"] ?? null)', $name, $name); + } + if (PHP_VERSION_ID >= 50400) { return sprintf('(isset($context["%s"]) ? $context["%s"] : null)', $name, $name); } diff --git a/src/Symfony/Bridge/Twig/Tests/Node/SearchAndRenderBlockNodeTest.php b/src/Symfony/Bridge/Twig/Tests/Node/SearchAndRenderBlockNodeTest.php index ad76e25e8e..0a3d30bdd5 100644 --- a/src/Symfony/Bridge/Twig/Tests/Node/SearchAndRenderBlockNodeTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Node/SearchAndRenderBlockNodeTest.php @@ -263,6 +263,10 @@ class SearchAndRenderBlockNodeTest extends \PHPUnit_Framework_TestCase protected function getVariableGetter($name) { + if (PHP_VERSION_ID >= 70000) { + return sprintf('($context["%s"] ?? null)', $name, $name); + } + if (PHP_VERSION_ID >= 50400) { return sprintf('(isset($context["%s"]) ? $context["%s"] : null)', $name, $name); } diff --git a/src/Symfony/Bridge/Twig/Tests/Node/TransNodeTest.php b/src/Symfony/Bridge/Twig/Tests/Node/TransNodeTest.php index 032975a8f2..cbd21fc46e 100644 --- a/src/Symfony/Bridge/Twig/Tests/Node/TransNodeTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Node/TransNodeTest.php @@ -39,6 +39,10 @@ class TransNodeTest extends \PHPUnit_Framework_TestCase protected function getVariableGetterWithoutStrictCheck($name) { + if (PHP_VERSION_ID >= 70000) { + return sprintf('($context["%s"] ?? null)', $name, $name); + } + if (PHP_VERSION_ID >= 50400) { return sprintf('(isset($context["%s"]) ? $context["%s"] : null)', $name, $name); } @@ -48,10 +52,14 @@ class TransNodeTest extends \PHPUnit_Framework_TestCase protected function getVariableGetterWithStrictCheck($name) { - if (version_compare(\Twig_Environment::VERSION, '2.0.0-DEV', '>=')) { + if (\Twig_Environment::MAJOR_VERSION >= 2) { return sprintf('(isset($context["%s"]) || array_key_exists("%s", $context) ? $context["%s"] : $this->notFound("%s", 0))', $name, $name, $name, $name); } + if (PHP_VERSION_ID >= 70000) { + return sprintf('($context["%s"] ?? $this->getContext($context, "%s"))', $name, $name, $name); + } + if (PHP_VERSION_ID >= 50400) { return sprintf('(isset($context["%s"]) ? $context["%s"] : $this->getContext($context, "%s"))', $name, $name, $name); } diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index 746da0a05a..f7c36adc57 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -17,7 +17,7 @@ ], "require": { "php": ">=5.3.9", - "twig/twig": "~1.27|~2.0" + "twig/twig": "~1.28|~2.0" }, "require-dev": { "symfony/asset": "~2.7|~3.0.0", diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php index f73ac6f4ba..4404f3a0f6 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php @@ -21,6 +21,8 @@ use Symfony\Component\HttpKernel\Kernel; use Symfony\Component\Translation\Catalogue\MergeOperation; use Symfony\Component\Translation\MessageCatalogue; use Symfony\Component\Translation\Translator; +use Symfony\Component\Translation\DataCollectorTranslator; +use Symfony\Component\Translation\LoggingTranslator; /** * Helps finding unused or missing translation messages in a given locale @@ -301,7 +303,7 @@ EOF { $fallbackCatalogues = array(); $translator = $this->getContainer()->get('translator'); - if ($translator instanceof Translator) { + if ($translator instanceof Translator || $translator instanceof DataCollectorTranslator || $translator instanceof LoggingTranslator) { foreach ($translator->getFallbackLocales() as $fallbackLocale) { if ($fallbackLocale === $locale) { continue; diff --git a/src/Symfony/Component/Console/Command/Command.php b/src/Symfony/Component/Console/Command/Command.php index fff9439c5a..aadc60cdff 100644 --- a/src/Symfony/Component/Console/Command/Command.php +++ b/src/Symfony/Component/Console/Command/Command.php @@ -205,8 +205,6 @@ class Command * * @return int The command exit code * - * @throws \Exception - * * @see setCode() * @see execute() */ diff --git a/src/Symfony/Component/DomCrawler/FormFieldRegistry.php b/src/Symfony/Component/DomCrawler/FormFieldRegistry.php index dbd08ff720..7dd3d3e7a3 100644 --- a/src/Symfony/Component/DomCrawler/FormFieldRegistry.php +++ b/src/Symfony/Component/DomCrawler/FormFieldRegistry.php @@ -15,6 +15,8 @@ use Symfony\Component\DomCrawler\Field\FormField; /** * This is an internal class that must not be used directly. + * + * @internal */ class FormFieldRegistry { diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php b/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php index e39117c5cc..81edfd6c42 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php @@ -12,6 +12,8 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\FormEvent; +use Symfony\Component\Form\FormEvents; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\ReversedTransformer; @@ -54,6 +56,17 @@ class TimeType extends AbstractType if ('single_text' === $options['widget']) { $builder->addViewTransformer(new DateTimeToStringTransformer($options['model_timezone'], $options['view_timezone'], $format)); + + // handle seconds ignored by user's browser when with_seconds enabled + // https://codereview.chromium.org/450533009/ + if ($options['with_seconds']) { + $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $e) { + $data = $e->getData(); + if ($data && preg_match('/^\d{2}:\d{2}$/', $data)) { + $e->setData($data.':00'); + } + }); + } } else { $hourOptions = $minuteOptions = $secondOptions = array( 'error_bubbling' => true, diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php index 7374298fee..5429bce5cd 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php @@ -231,6 +231,22 @@ class TimeTypeTest extends TestCase $this->assertEquals('03', $form->getViewData()); } + public function testSubmitWithSecondsAndBrowserOmissionSeconds() + { + $form = $this->factory->create('time', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'input' => 'string', + 'widget' => 'single_text', + 'with_seconds' => true, + )); + + $form->submit('03:04'); + + $this->assertEquals('03:04:00', $form->getData()); + $this->assertEquals('03:04:00', $form->getViewData()); + } + public function testSetDataWithoutMinutes() { $form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\TimeType', null, array( diff --git a/src/Symfony/Component/Translation/DataCollectorTranslator.php b/src/Symfony/Component/Translation/DataCollectorTranslator.php index 2446723358..50e4a2ff93 100644 --- a/src/Symfony/Component/Translation/DataCollectorTranslator.php +++ b/src/Symfony/Component/Translation/DataCollectorTranslator.php @@ -88,6 +88,20 @@ class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInter return $this->translator->getCatalogue($locale); } + /** + * Gets the fallback locales. + * + * @return array $locales The fallback locales + */ + public function getFallbackLocales() + { + if ($this->translator instanceof Translator) { + return $this->translator->getFallbackLocales(); + } + + return array(); + } + /** * Passes through all unknown calls onto the translator object. */ diff --git a/src/Symfony/Component/Translation/LoggingTranslator.php b/src/Symfony/Component/Translation/LoggingTranslator.php index fa5c5cc5b5..b259df5e0a 100644 --- a/src/Symfony/Component/Translation/LoggingTranslator.php +++ b/src/Symfony/Component/Translation/LoggingTranslator.php @@ -88,6 +88,20 @@ class LoggingTranslator implements TranslatorInterface, TranslatorBagInterface return $this->translator->getCatalogue($locale); } + /** + * Gets the fallback locales. + * + * @return array $locales The fallback locales + */ + public function getFallbackLocales() + { + if ($this->translator instanceof Translator) { + return $this->translator->getFallbackLocales(); + } + + return array(); + } + /** * Passes through all unknown calls onto the translator object. */ diff --git a/src/Symfony/Component/Translation/Tests/TranslatorTest.php b/src/Symfony/Component/Translation/Tests/TranslatorTest.php index f5dad8fc91..becc41567c 100644 --- a/src/Symfony/Component/Translation/Tests/TranslatorTest.php +++ b/src/Symfony/Component/Translation/Tests/TranslatorTest.php @@ -273,6 +273,16 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase $translator->trans('foo'); } + public function testNestedFallbackCatalogueWhenUsingMultipleLocales() + { + $translator = new Translator('fr'); + $translator->setFallbackLocales(array('ru', 'en')); + + $translator->getCatalogue('fr'); + + $this->assertNotNull($translator->getCatalogue('ru')->getFallbackCatalogue()); + } + public function testFallbackCatalogueResources() { $translator = new Translator('en_GB', new MessageSelector()); diff --git a/src/Symfony/Component/Translation/Translator.php b/src/Symfony/Component/Translation/Translator.php index e68baeba12..ac0d757a9a 100644 --- a/src/Symfony/Component/Translation/Translator.php +++ b/src/Symfony/Component/Translation/Translator.php @@ -159,7 +159,7 @@ class Translator implements TranslatorInterface, TranslatorBagInterface * * @throws \InvalidArgumentException If a locale contains invalid characters * - * @deprecated since version 2.3, to be removed in 3.0. Use setFallbackLocales() instead. + * @deprecated since version 2.3, to be removed in 3.0. Use setFallbackLocales() instead */ public function setFallbackLocale($locales) { @@ -424,7 +424,7 @@ EOF foreach ($this->computeFallbackLocales($locale) as $fallback) { if (!isset($this->catalogues[$fallback])) { - $this->doLoadCatalogue($fallback); + $this->loadCatalogue($fallback); } $fallbackCatalogue = new MessageCatalogue($fallback, $this->catalogues[$fallback]->all()); diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.sv.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.sv.xlf index 693f12b5b1..879c0a5c55 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.sv.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.sv.xlf @@ -310,6 +310,10 @@ This value does not match the expected {{ charset }} charset. Detta värde har inte den förväntade teckenkodningen {{ charset }}. + + This is not a valid Business Identifier Code (BIC). + Detta är inte en giltig BIC-kod. + diff --git a/src/Symfony/Component/Yaml/Inline.php b/src/Symfony/Component/Yaml/Inline.php index e64cb4e500..74d23be0a7 100644 --- a/src/Symfony/Component/Yaml/Inline.php +++ b/src/Symfony/Component/Yaml/Inline.php @@ -28,7 +28,7 @@ class Inline private static $objectForMap = false; /** - * Converts a YAML string to a PHP array. + * Converts a YAML string to a PHP value. * * @param string $value A YAML string * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise @@ -36,7 +36,7 @@ class Inline * @param bool $objectForMap true if maps should return a stdClass instead of array() * @param array $references Mapping of variable names to values * - * @return array A PHP array representing the YAML string + * @return mixed A PHP value * * @throws ParseException */ @@ -90,7 +90,7 @@ class Inline * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise * @param bool $objectSupport true if object support is enabled, false otherwise * - * @return string The YAML string representing the PHP array + * @return string The YAML string representing the PHP value * * @throws DumpException When trying to dump PHP resource */ @@ -210,7 +210,7 @@ class Inline } /** - * Parses a scalar to a YAML string. + * Parses a YAML scalar. * * @param string $scalar * @param string $delimiters @@ -219,7 +219,7 @@ class Inline * @param bool $evaluate * @param array $references * - * @return string A YAML string + * @return string * * @throws ParseException When malformed inline YAML string is parsed * @@ -271,12 +271,12 @@ class Inline } /** - * Parses a quoted scalar to YAML. + * Parses a YAML quoted scalar. * * @param string $scalar * @param int &$i * - * @return string A YAML string + * @return string * * @throws ParseException When malformed inline YAML string is parsed */ @@ -301,13 +301,13 @@ class Inline } /** - * Parses a sequence to a YAML string. + * Parses a YAML sequence. * * @param string $sequence * @param int &$i * @param array $references * - * @return string A YAML string + * @return array * * @throws ParseException When malformed inline YAML string is parsed */ @@ -360,13 +360,13 @@ class Inline } /** - * Parses a mapping to a YAML string. + * Parses a YAML mapping. * * @param string $mapping * @param int &$i * @param array $references * - * @return string A YAML string + * @return array|\stdClass * * @throws ParseException When malformed inline YAML string is parsed */