From dcde4458f070f88cd319ee89068289f19f321225 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 8 Apr 2015 20:26:59 +0200 Subject: [PATCH 01/11] [FrameworkBundle] Workaround php -S ignoring auto_prepend_file --- .../Bundle/FrameworkBundle/Resources/config/router_dev.php | 5 +++++ .../Bundle/FrameworkBundle/Resources/config/router_prod.php | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/router_dev.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/router_dev.php index 9e70bf7acd..1e9fa748e7 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/router_dev.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/router_dev.php @@ -21,6 +21,11 @@ * @author: Albert Jessurum */ +// Workaround https://bugs.php.net/64566 +if (ini_get('auto_prepend_file') && !in_array(realpath(ini_get('auto_prepend_file')), get_included_files(), true)) { + require ini_get('auto_prepend_file'); +} + if (is_file($_SERVER['DOCUMENT_ROOT'].DIRECTORY_SEPARATOR.$_SERVER['SCRIPT_NAME'])) { return false; } diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/router_prod.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/router_prod.php index a3ef29d8db..231fbead56 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/router_prod.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/router_prod.php @@ -21,6 +21,11 @@ * @author: Albert Jessurum */ +// Workaround https://bugs.php.net/64566 +if (ini_get('auto_prepend_file') && !in_array(realpath(ini_get('auto_prepend_file')), get_included_files(), true)) { + require ini_get('auto_prepend_file'); +} + if (is_file($_SERVER['DOCUMENT_ROOT'].DIRECTORY_SEPARATOR.$_SERVER['SCRIPT_NAME'])) { return false; } From c0f0258c562e69abe040395fa312662939405108 Mon Sep 17 00:00:00 2001 From: Jingyu Wang Date: Sat, 11 Apr 2015 10:00:20 +0800 Subject: [PATCH 02/11] [Validator] Added missing Simplified Chinese (zh_CN) translations --- .../translations/validators.zh_CN.xlf | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.zh_CN.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.zh_CN.xlf index ae680a7792..2eabc6acb3 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.zh_CN.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.zh_CN.xlf @@ -278,6 +278,38 @@ This value should not be identical to {{ compared_value_type }} {{ compared_value }}. 该值不应与 {{ compared_value_type }} {{ compared_value }} 相同。 + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + 图片宽高比太大 ({{ ratio }})。允许的最大宽高比为 {{ max_ratio }}。 + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + 图片宽高比太小 ({{ ratio }})。允许的最大宽高比为 {{ min_ratio }}。 + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + 图片是方形的 ({{ width }}x{{ height }}px)。不允许使用方形的图片。 + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + 图片是横向的 ({{ width }}x{{ height }}px)。不允许使用横向的图片。 + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + 图片是纵向的 ({{ width }}x{{ height }}px)。不允许使用纵向的图片。 + + + An empty file is not allowed. + 不允许使用空文件。 + + + The host could not be resolved. + 主机名无法解析。 + + + This value does not match the expected {{ charset }} charset. + 该值不符合 {{ charset }} 编码。 + From 04b8e4e77ec1f48a4845e68e08dc979316f9e6c7 Mon Sep 17 00:00:00 2001 From: Abdellatif Ait boudad Date: Tue, 14 Apr 2015 08:53:08 +0100 Subject: [PATCH 03/11] [Translation][fixed test] refresh cache when resources are no longer fresh. --- .../Tests/Translation/TranslatorTest.php | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php index 5c2ab2c9cc..3617d3858a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php @@ -93,27 +93,27 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase $this->assertEquals('other choice 1 (PT-BR)', $translator->transChoice('other choice', 1)); $this->assertEquals('foobarbaz (fr.UTF-8)', $translator->trans('foobarbaz')); $this->assertEquals('foobarbax (sr@latin)', $translator->trans('foobarbax')); + } - // refresh cache again when resource file resources file change + public function testRefreshCacheWhenResourcesAreNoLongerFresh() + { $resource = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface'); - $resource - ->expects($this->at(0)) - ->method('isFresh') - ->will($this->returnValue(false)) - ; - $catalogue = $this->getCatalogue('fr', array('foo' => 'foo fresh')); - $catalogue->addResource($resource); - $loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface'); + $resource->method('isFresh')->will($this->returnValue(false)); $loader - ->expects($this->at(0)) + ->expects($this->exactly(2)) ->method('load') - ->will($this->returnValue($catalogue)) - ; + ->will($this->returnValue($this->getCatalogue('fr', array(), array($resource)))); - $translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir)); + // prime the cache + $translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir, 'debug' => true)); $translator->setLocale('fr'); - $this->assertEquals('foo fresh', $translator->trans('foo')); + $translator->trans('foo'); + + // prime the cache second time + $translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir, 'debug' => true)); + $translator->setLocale('fr'); + $translator->trans('foo'); } public function testTransWithCachingWithInvalidLocale() @@ -235,12 +235,15 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase $this->assertEquals('bar', $translator->trans('bar')); } - protected function getCatalogue($locale, $messages) + protected function getCatalogue($locale, $messages, $resources = array()) { $catalogue = new MessageCatalogue($locale); foreach ($messages as $key => $translation) { $catalogue->set($key, $translation); } + foreach ($resources as $resource) { + $catalogue->addResource($resource); + } return $catalogue; } From 78cc93c3b29cdb1f28c45845b6a4eff9d05f6492 Mon Sep 17 00:00:00 2001 From: Vladimir Reznichenko Date: Thu, 9 Apr 2015 16:55:17 +0200 Subject: [PATCH 04/11] [2.3] Static Code Analysis for Components --- src/Symfony/Component/BrowserKit/Cookie.php | 1 + .../Component/Console/Descriptor/ApplicationDescription.php | 6 ++++-- src/Symfony/Component/Console/Helper/DialogHelper.php | 2 +- src/Symfony/Component/Console/Helper/TableHelper.php | 2 +- .../Compiler/ResolveDefinitionTemplatesPass.php | 2 +- src/Symfony/Component/DependencyInjection/Container.php | 2 +- .../Component/DependencyInjection/Loader/YamlFileLoader.php | 2 +- .../DependencyInjection/ParameterBag/ParameterBag.php | 2 +- src/Symfony/Component/DomCrawler/Link.php | 2 +- .../EventDispatcher/ContainerAwareEventDispatcher.php | 2 +- src/Symfony/Component/EventDispatcher/EventDispatcher.php | 2 +- .../Component/Finder/Tests/Iterator/IteratorTestCase.php | 2 +- .../Core/DataTransformer/BaseDateTimeTransformer.php | 4 ++-- .../Core/DataTransformer/DateTimeToArrayTransformer.php | 2 ++ .../Core/EventListener/MergeCollectionListener.php | 2 +- src/Symfony/Component/HttpFoundation/Request.php | 4 ++-- .../Component/HttpKernel/Debug/TraceableEventDispatcher.php | 6 +++--- 17 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/Symfony/Component/BrowserKit/Cookie.php b/src/Symfony/Component/BrowserKit/Cookie.php index b8d9dffd91..b225056f4b 100644 --- a/src/Symfony/Component/BrowserKit/Cookie.php +++ b/src/Symfony/Component/BrowserKit/Cookie.php @@ -93,6 +93,7 @@ class Cookie $dateTime = \DateTime::createFromFormat('U', $this->expires, new \DateTimeZone('GMT')); if ($dateTime === false) { + // this throw will provoke PHP fatal throw new \UnexpectedValueException(sprintf('The cookie expiration time "%s" is not valid.'), $this->expires); } diff --git a/src/Symfony/Component/Console/Descriptor/ApplicationDescription.php b/src/Symfony/Component/Console/Descriptor/ApplicationDescription.php index cdf1493c40..81aa1b0e27 100644 --- a/src/Symfony/Component/Console/Descriptor/ApplicationDescription.php +++ b/src/Symfony/Component/Console/Descriptor/ApplicationDescription.php @@ -144,9 +144,11 @@ class ApplicationDescription } ksort($namespacedCommands); - foreach ($namespacedCommands as &$commands) { - ksort($commands); + foreach ($namespacedCommands as &$commandsSet) { + ksort($commandsSet); } + // unset reference to keep scope clear + unset($commandsSet); return $namespacedCommands; } diff --git a/src/Symfony/Component/Console/Helper/DialogHelper.php b/src/Symfony/Component/Console/Helper/DialogHelper.php index 7c00cb82f5..0e383c5c2d 100644 --- a/src/Symfony/Component/Console/Helper/DialogHelper.php +++ b/src/Symfony/Component/Console/Helper/DialogHelper.php @@ -71,7 +71,7 @@ class DialogHelper extends Helper if (empty($choices[$value])) { throw new \InvalidArgumentException(sprintf($errorMessage, $value)); } - array_push($multiselectChoices, $value); + $multiselectChoices[] = $value; } if ($multiselect) { diff --git a/src/Symfony/Component/Console/Helper/TableHelper.php b/src/Symfony/Component/Console/Helper/TableHelper.php index 90357cc214..c8c343dbd4 100644 --- a/src/Symfony/Component/Console/Helper/TableHelper.php +++ b/src/Symfony/Component/Console/Helper/TableHelper.php @@ -148,7 +148,7 @@ class TableHelper extends Helper reset($this->rows); foreach ($row as $key => $cellValue) { - if (!strstr($cellValue, "\n")) { + if (false === strpos($cellValue, "\n")) { continue; } diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php index 4af68809fc..7dc428c7bf 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php @@ -39,7 +39,7 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface $this->compiler = $container->getCompiler(); $this->formatter = $this->compiler->getLoggingFormatter(); - foreach (array_keys($container->getDefinitions()) as $id) { + foreach ($container->getDefinitions() as $id => $definition) { // yes, we are specifically fetching the definition from the // container to ensure we are not operating on stale data $definition = $container->getDefinition($id); diff --git a/src/Symfony/Component/DependencyInjection/Container.php b/src/Symfony/Component/DependencyInjection/Container.php index af567a11cb..4a9fa8905e 100644 --- a/src/Symfony/Component/DependencyInjection/Container.php +++ b/src/Symfony/Component/DependencyInjection/Container.php @@ -312,7 +312,7 @@ class Container implements IntrospectableContainerInterface } $alternatives = array(); - foreach (array_keys($this->services) as $key) { + foreach ($this->services as $key => $associatedService) { $lev = levenshtein($id, $key); if ($lev <= strlen($id) / 3 || false !== strpos($key, $id)) { $alternatives[] = $key; diff --git a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php index fa2f6520c2..d269d6cbfa 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php @@ -304,7 +304,7 @@ class YamlFileLoader extends FileLoader throw new InvalidArgumentException(sprintf('The service file "%s" is not valid. It should contain an array. Check your YAML syntax.', $file)); } - foreach (array_keys($content) as $namespace) { + foreach ($content as $namespace => $data) { if (in_array($namespace, array('imports', 'parameters', 'services'))) { continue; } diff --git a/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php b/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php index c058b57da1..291748d4d9 100644 --- a/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php +++ b/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php @@ -98,7 +98,7 @@ class ParameterBag implements ParameterBagInterface } $alternatives = array(); - foreach (array_keys($this->parameters) as $key) { + foreach ($this->parameters as $key => $parameterValue) { $lev = levenshtein($name, $key); if ($lev <= strlen($name) / 3 || false !== strpos($key, $name)) { $alternatives[] = $key; diff --git a/src/Symfony/Component/DomCrawler/Link.php b/src/Symfony/Component/DomCrawler/Link.php index 86ed2bedcd..b1ed5e5fd2 100644 --- a/src/Symfony/Component/DomCrawler/Link.php +++ b/src/Symfony/Component/DomCrawler/Link.php @@ -163,7 +163,7 @@ class Link if ('..' === $segment) { array_pop($output); } elseif ('.' !== $segment) { - array_push($output, $segment); + $output[] = $segment; } } diff --git a/src/Symfony/Component/EventDispatcher/ContainerAwareEventDispatcher.php b/src/Symfony/Component/EventDispatcher/ContainerAwareEventDispatcher.php index 897fafd4f1..aedad6ef77 100644 --- a/src/Symfony/Component/EventDispatcher/ContainerAwareEventDispatcher.php +++ b/src/Symfony/Component/EventDispatcher/ContainerAwareEventDispatcher.php @@ -124,7 +124,7 @@ class ContainerAwareEventDispatcher extends EventDispatcher public function getListeners($eventName = null) { if (null === $eventName) { - foreach (array_keys($this->listenerIds) as $serviceEventName) { + foreach ($this->listenerIds as $serviceEventName => $args) { $this->lazyLoad($serviceEventName); } } else { diff --git a/src/Symfony/Component/EventDispatcher/EventDispatcher.php b/src/Symfony/Component/EventDispatcher/EventDispatcher.php index 12c75fcafd..a2435e9978 100644 --- a/src/Symfony/Component/EventDispatcher/EventDispatcher.php +++ b/src/Symfony/Component/EventDispatcher/EventDispatcher.php @@ -68,7 +68,7 @@ class EventDispatcher implements EventDispatcherInterface return $this->sorted[$eventName]; } - foreach (array_keys($this->listeners) as $eventName) { + foreach ($this->listeners as $eventName => $eventListeners) { if (!isset($this->sorted[$eventName])) { $this->sortListeners($eventName); } diff --git a/src/Symfony/Component/Finder/Tests/Iterator/IteratorTestCase.php b/src/Symfony/Component/Finder/Tests/Iterator/IteratorTestCase.php index ae7388ea2e..9d2cf5fe45 100644 --- a/src/Symfony/Component/Finder/Tests/Iterator/IteratorTestCase.php +++ b/src/Symfony/Component/Finder/Tests/Iterator/IteratorTestCase.php @@ -51,7 +51,7 @@ abstract class IteratorTestCase extends \PHPUnit_Framework_TestCase foreach ($expected as $subarray) { $temp = array(); while (count($values) && count($temp) < count($subarray)) { - array_push($temp, array_shift($values)); + $temp[] = array_shift($values); } sort($temp); sort($subarray); diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/BaseDateTimeTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/BaseDateTimeTransformer.php index 0cf9741dce..309d46074e 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/BaseDateTimeTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/BaseDateTimeTransformer.php @@ -40,11 +40,11 @@ abstract class BaseDateTimeTransformer implements DataTransformerInterface */ public function __construct($inputTimezone = null, $outputTimezone = null) { - if (!is_string($inputTimezone) && null !== $inputTimezone) { + if (null !== $inputTimezone && !is_string($inputTimezone)) { throw new UnexpectedTypeException($inputTimezone, 'string'); } - if (!is_string($outputTimezone) && null !== $outputTimezone) { + if (null !== $outputTimezone && !is_string($outputTimezone)) { throw new UnexpectedTypeException($outputTimezone, 'string'); } diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php index e36be12009..b3f4dbdd63 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php @@ -99,6 +99,8 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer // remove leading zeros $entry = (string) (int) $entry; } + // unset reference to keep scope clear + unset($entry); } return $result; diff --git a/src/Symfony/Component/Form/Extension/Core/EventListener/MergeCollectionListener.php b/src/Symfony/Component/Form/Extension/Core/EventListener/MergeCollectionListener.php index a14f99a985..a7d31c2e9a 100644 --- a/src/Symfony/Component/Form/Extension/Core/EventListener/MergeCollectionListener.php +++ b/src/Symfony/Component/Form/Extension/Core/EventListener/MergeCollectionListener.php @@ -74,7 +74,7 @@ class MergeCollectionListener implements EventSubscriberInterface } // If we are not allowed to change anything, return immediately - if ((!$this->allowAdd && !$this->allowDelete) || $data === $dataToMergeInto) { + if ($data === $dataToMergeInto || (!$this->allowAdd && !$this->allowDelete)) { $event->setData($dataToMergeInto); return; diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index 75ef72d0c7..021d3de1ee 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -1546,8 +1546,8 @@ class Request $languages = AcceptHeader::fromString($this->headers->get('Accept-Language'))->all(); $this->languages = array(); - foreach (array_keys($languages) as $lang) { - if (strstr($lang, '-')) { + foreach ($languages as $lang => $acceptHeaderItem) { + if (false !== strpos($lang, '-')) { $codes = explode('-', $lang); if ('i' === $codes[0]) { // Language not listed in ISO 639 that are not variants diff --git a/src/Symfony/Component/HttpKernel/Debug/TraceableEventDispatcher.php b/src/Symfony/Component/HttpKernel/Debug/TraceableEventDispatcher.php index 5a95296fca..f4cd11d252 100644 --- a/src/Symfony/Component/HttpKernel/Debug/TraceableEventDispatcher.php +++ b/src/Symfony/Component/HttpKernel/Debug/TraceableEventDispatcher.php @@ -472,9 +472,9 @@ class TraceableEventDispatcher implements EventDispatcherInterface, TraceableEve // get the original listener if (is_object($listener)) { if (null === $eventId) { - foreach (array_keys($this->wrappedListeners) as $eventId) { - if (isset($this->wrappedListeners[$eventId][$listener])) { - return $this->wrappedListeners[$eventId][$listener]; + foreach ($this->wrappedListeners as $eventId => $eventListeners) { + if (isset($eventListeners[$listener])) { + return $eventListeners[$listener]; } } } elseif (isset($this->wrappedListeners[$eventId][$listener])) { From f732659219cb3e77c332a314562d611f27da7a8a Mon Sep 17 00:00:00 2001 From: Vladimir Reznichenko Date: Sat, 4 Apr 2015 11:33:09 +0200 Subject: [PATCH 05/11] [2.3] SCA for Components - reference mismatches --- .../Session/Attribute/NamespacedAttributeBag.php | 2 ++ src/Symfony/Component/PropertyAccess/PropertyAccessor.php | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php b/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php index 132d28fbd5..79d5e92806 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php +++ b/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php @@ -43,6 +43,7 @@ class NamespacedAttributeBag extends AttributeBag */ public function has($name) { + // reference mismatch: if fixed, re-introduced in array_key_exists; keep as it is $attributes = $this->resolveAttributePath($name); $name = $this->resolveKey($name); @@ -58,6 +59,7 @@ class NamespacedAttributeBag extends AttributeBag */ public function get($name, $default = null) { + // reference mismatch: if fixed, re-introduced in array_key_exists; keep as it is $attributes = $this->resolveAttributePath($name); $name = $this->resolveKey($name); diff --git a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php index 2aeb1a8a6e..2f786ca6bb 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php +++ b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php @@ -304,8 +304,10 @@ class PropertyAccessor implements PropertyAccessorInterface // see https://github.com/symfony/symfony/issues/4670 $itemsToAdd = is_object($value) ? iterator_to_array($value) : $value; $itemToRemove = array(); - $propertyValue = $this->readProperty($object, $property); + $propertyValue = &$this->readProperty($object, $property); $previousValue = $propertyValue[self::VALUE]; + // remove reference to avoid modifications + unset($propertyValue); if (is_array($previousValue) || $previousValue instanceof \Traversable) { foreach ($previousValue as $previousItem) { From 870a299eb3385ca5d261068811fb8f17e1a5f74b Mon Sep 17 00:00:00 2001 From: Diego Saint Esteben Date: Mon, 6 Apr 2015 10:14:07 -0300 Subject: [PATCH 06/11] [DependencyInjection] Show better error when the Yaml component is not installed --- .../DependencyInjection/Dumper/YamlDumper.php | 23 +++++++------------ .../Loader/YamlFileLoader.php | 5 ++++ 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php index 310eb74e70..a3d9ea37b6 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php @@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Parameter; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Exception\RuntimeException; -use Symfony\Component\DependencyInjection\ContainerBuilder; /** * YamlDumper dumps a service container as a YAML string. @@ -31,20 +30,6 @@ class YamlDumper extends Dumper { private $dumper; - /** - * Constructor. - * - * @param ContainerBuilder $container The service container to dump - * - * @api - */ - public function __construct(ContainerBuilder $container) - { - parent::__construct($container); - - $this->dumper = new YmlDumper(); - } - /** * Dumps the service container as an YAML string. * @@ -56,6 +41,14 @@ class YamlDumper extends Dumper */ public function dump(array $options = array()) { + if (!class_exists('Symfony\Component\Yaml\Dumper')) { + throw new RuntimeException('Unable to dump the container as the Symfony Yaml Component is not installed.'); + } + + if (null === $this->dumper) { + $this->dumper = new YmlDumper(); + } + return $this->addParameters()."\n".$this->addServices(); } diff --git a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php index fa2f6520c2..40e90bbb31 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php @@ -17,6 +17,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\Config\Resource\FileResource; use Symfony\Component\Yaml\Parser as YamlParser; @@ -269,6 +270,10 @@ class YamlFileLoader extends FileLoader */ protected function loadFile($file) { + if (!class_exists('Symfony\Component\Yaml\Parser')) { + throw new RuntimeException('Unable to load YAML config files as the Symfony Yaml Component is not installed.'); + } + if (!stream_is_local($file)) { throw new InvalidArgumentException(sprintf('This is not a local file "%s".', $file)); } From cfa3e95f4dd5d94e9d412cd603b06143cb52456d Mon Sep 17 00:00:00 2001 From: Dariusz Ruminski Date: Thu, 16 Apr 2015 09:01:03 +0200 Subject: [PATCH 07/11] CS fixes --- .../Bridge/Twig/Extension/CodeExtension.php | 8 ++++---- .../Templating/Helper/CodeHelper.php | 8 ++++---- .../Console/Descriptor/TextDescriptor.php | 2 +- .../Tests/Formatter/OutputFormatterTest.php | 4 ++-- .../Component/CssSelector/Parser/TokenStream.php | 2 +- src/Symfony/Component/Debug/ExceptionHandler.php | 2 +- .../DependencyInjection/Dumper/PhpDumper.php | 4 ++-- .../Tests/Dumper/XmlDumperTest.php | 16 ++++++++-------- .../Tests/Loader/PhpFileLoaderTest.php | 1 - .../Tests/Loader/XmlFileLoaderTest.php | 1 - .../Tests/Loader/YamlFileLoaderTest.php | 1 - .../Tests/Debug/TraceableEventDispatcherTest.php | 10 +++++----- .../Firewall/DigestAuthenticationListener.php | 2 +- src/Symfony/Component/Yaml/Escaper.php | 10 +++++----- src/Symfony/Component/Yaml/Tests/InlineTest.php | 2 +- 15 files changed, 35 insertions(+), 38 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Extension/CodeExtension.php b/src/Symfony/Bridge/Twig/Extension/CodeExtension.php index b5f619d327..bf210c63a5 100644 --- a/src/Symfony/Bridge/Twig/Extension/CodeExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/CodeExtension.php @@ -58,7 +58,7 @@ class CodeExtension extends \Twig_Extension $parts = explode('\\', $class); $short = array_pop($parts); - return sprintf("%s", $class, $short); + return sprintf('%s', $class, $short); } public function abbrMethod($method) @@ -67,9 +67,9 @@ class CodeExtension extends \Twig_Extension list($class, $method) = explode('::', $method, 2); $result = sprintf('%s::%s()', $this->abbrClass($class), $method); } elseif ('Closure' === $method) { - $result = sprintf("%s", $method, $method); + $result = sprintf('%s', $method, $method); } else { - $result = sprintf("%s()", $method, $method); + $result = sprintf('%s()', $method, $method); } return $result; @@ -89,7 +89,7 @@ class CodeExtension extends \Twig_Extension if ('object' === $item[0]) { $parts = explode('\\', $item[1]); $short = array_pop($parts); - $formattedValue = sprintf("object(%s)", $item[1], $short); + $formattedValue = sprintf('object(%s)', $item[1], $short); } elseif ('array' === $item[0]) { $formattedValue = sprintf('array(%s)', is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]); } elseif ('string' === $item[0]) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/CodeHelper.php b/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/CodeHelper.php index e7042e0dc3..2c79ca3526 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/CodeHelper.php +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/CodeHelper.php @@ -55,7 +55,7 @@ class CodeHelper extends Helper $parts = explode('\\', $class); $short = array_pop($parts); - return sprintf("%s", $class, $short); + return sprintf('%s', $class, $short); } public function abbrMethod($method) @@ -64,9 +64,9 @@ class CodeHelper extends Helper list($class, $method) = explode('::', $method, 2); $result = sprintf('%s::%s()', $this->abbrClass($class), $method); } elseif ('Closure' === $method) { - $result = sprintf("%s", $method, $method); + $result = sprintf('%s', $method, $method); } else { - $result = sprintf("%s()", $method, $method); + $result = sprintf('%s()', $method, $method); } return $result; @@ -86,7 +86,7 @@ class CodeHelper extends Helper if ('object' === $item[0]) { $parts = explode('\\', $item[1]); $short = array_pop($parts); - $formattedValue = sprintf("object(%s)", $item[1], $short); + $formattedValue = sprintf('object(%s)', $item[1], $short); } elseif ('array' === $item[0]) { $formattedValue = sprintf('array(%s)', is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]); } elseif ('string' === $item[0]) { diff --git a/src/Symfony/Component/Console/Descriptor/TextDescriptor.php b/src/Symfony/Component/Console/Descriptor/TextDescriptor.php index 6a51519f7b..fffd0e8486 100644 --- a/src/Symfony/Component/Console/Descriptor/TextDescriptor.php +++ b/src/Symfony/Component/Console/Descriptor/TextDescriptor.php @@ -155,7 +155,7 @@ class TextDescriptor extends Descriptor $messages[] = ''; if ($describedNamespace) { - $messages[] = sprintf("Available commands for the \"%s\" namespace:", $describedNamespace); + $messages[] = sprintf('Available commands for the "%s" namespace:', $describedNamespace); } else { $messages[] = 'Available commands:'; } diff --git a/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php b/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php index 9856760c11..3542680a88 100644 --- a/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php +++ b/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php @@ -28,7 +28,7 @@ class OutputFormatterTest extends \PHPUnit_Framework_TestCase $this->assertEquals('fooformat('foo\\assertEquals('some info', $formatter->format('\\some info\\')); - $this->assertEquals("\\some info\\", OutputFormatter::escape('some info')); + $this->assertEquals('\\some info\\', OutputFormatter::escape('some info')); $this->assertEquals( "\033[33mSymfony\\Component\\Console does work very well!\033[0m", @@ -162,7 +162,7 @@ class OutputFormatterTest extends \PHPUnit_Framework_TestCase public function testFormatLongString() { $formatter = new OutputFormatter(true); - $long = str_repeat("\\", 14000); + $long = str_repeat('\\', 14000); $this->assertEquals("\033[37;41msome error\033[0m".$long, $formatter->format('some error'.$long)); } diff --git a/src/Symfony/Component/CssSelector/Parser/TokenStream.php b/src/Symfony/Component/CssSelector/Parser/TokenStream.php index 8184b832b3..c0525d7a83 100644 --- a/src/Symfony/Component/CssSelector/Parser/TokenStream.php +++ b/src/Symfony/Component/CssSelector/Parser/TokenStream.php @@ -100,7 +100,7 @@ class TokenStream throw new InternalErrorException('Unexpected token stream end.'); } - return $this->tokens[$this->cursor ++]; + return $this->tokens[$this->cursor++]; } /** diff --git a/src/Symfony/Component/Debug/ExceptionHandler.php b/src/Symfony/Component/Debug/ExceptionHandler.php index 6d55d8afa3..a96bbe1020 100644 --- a/src/Symfony/Component/Debug/ExceptionHandler.php +++ b/src/Symfony/Component/Debug/ExceptionHandler.php @@ -278,7 +278,7 @@ EOF; { $parts = explode('\\', $class); - return sprintf("%s", $class, array_pop($parts)); + return sprintf('%s', $class, array_pop($parts)); } /** diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 3b9039d29c..385400dac6 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -539,7 +539,7 @@ class PhpDumper extends Dumper if ($definition->isSynthetic()) { $return[] = '@throws RuntimeException always since this service is expected to be injected dynamically'; } elseif ($class = $definition->getClass()) { - $return[] = sprintf('@return %s A %s instance.', 0 === strpos($class, '%') ? 'object' : "\\".$class, $class); + $return[] = sprintf('@return %s A %s instance.', 0 === strpos($class, '%') ? 'object' : '\\'.$class, $class); } elseif ($definition->getFactoryClass()) { $return[] = sprintf('@return object An instance returned by %s::%s().', $definition->getFactoryClass(), $definition->getFactoryMethod()); } elseif ($definition->getFactoryService()) { @@ -1231,7 +1231,7 @@ EOF; } } - return sprintf("new \\%s(%s)", substr(str_replace('\\\\', '\\', $class), 1, -1), implode(', ', $arguments)); + return sprintf('new \\%s(%s)', substr(str_replace('\\\\', '\\', $class), 1, -1), implode(', ', $arguments)); } elseif ($value instanceof Variable) { return '$'.$value; } elseif ($value instanceof Reference) { diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/XmlDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/XmlDumperTest.php index 9dc41dcd09..1e00f83215 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/XmlDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/XmlDumperTest.php @@ -65,21 +65,21 @@ class XmlDumperTest extends \PHPUnit_Framework_TestCase { include self::$fixturesPath.'/containers/container11.php'; $dumper = new XmlDumper($container); - $this->assertEquals(" - + $this->assertEquals(' + - - - - - + + + + + -", $dumper->dump()); +', $dumper->dump()); } public function testDumpEntities() diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/PhpFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/PhpFileLoaderTest.php index 505f710cbe..5ae097ca7d 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/PhpFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/PhpFileLoaderTest.php @@ -12,7 +12,6 @@ namespace Symfony\Component\DependencyInjection\Tests\Loader; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\Config\Loader\Loader; use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; use Symfony\Component\Config\FileLocator; diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php index 4a10654bb7..9c6fd2bdd6 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php @@ -14,7 +14,6 @@ namespace Symfony\Component\DependencyInjection\Tests\Loader; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; -use Symfony\Component\Config\Loader\Loader; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\DependencyInjection\Loader\IniFileLoader; diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php index f10ecb04d0..c3ff984b40 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php @@ -13,7 +13,6 @@ namespace Symfony\Component\DependencyInjection\Tests\Loader; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; -use Symfony\Component\Config\Loader\Loader; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\DependencyInjection\Loader\IniFileLoader; diff --git a/src/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php b/src/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php index c7a3edb890..5ef85bad27 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php @@ -98,8 +98,8 @@ class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase $tdispatcher->addListener('foo', $listener1 = function () {; }); $tdispatcher->addListener('foo', $listener2 = function () {; }); - $logger->expects($this->at(0))->method('debug')->with("Notified event \"foo\" to listener \"closure\"."); - $logger->expects($this->at(1))->method('debug')->with("Notified event \"foo\" to listener \"closure\"."); + $logger->expects($this->at(0))->method('debug')->with('Notified event "foo" to listener "closure".'); + $logger->expects($this->at(1))->method('debug')->with('Notified event "foo" to listener "closure".'); $tdispatcher->dispatch('foo'); } @@ -113,9 +113,9 @@ class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase $tdispatcher->addListener('foo', $listener1 = function (Event $event) { $event->stopPropagation(); }); $tdispatcher->addListener('foo', $listener2 = function () {; }); - $logger->expects($this->at(0))->method('debug')->with("Notified event \"foo\" to listener \"closure\"."); - $logger->expects($this->at(1))->method('debug')->with("Listener \"closure\" stopped propagation of the event \"foo\"."); - $logger->expects($this->at(2))->method('debug')->with("Listener \"closure\" was not called for event \"foo\"."); + $logger->expects($this->at(0))->method('debug')->with('Notified event "foo" to listener "closure".'); + $logger->expects($this->at(1))->method('debug')->with('Listener "closure" stopped propagation of the event "foo".'); + $logger->expects($this->at(2))->method('debug')->with('Listener "closure" was not called for event "foo".'); $tdispatcher->dispatch('foo'); } diff --git a/src/Symfony/Component/Security/Http/Firewall/DigestAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/DigestAuthenticationListener.php index ea85e776a8..358c3c7a7c 100644 --- a/src/Symfony/Component/Security/Http/Firewall/DigestAuthenticationListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/DigestAuthenticationListener.php @@ -162,7 +162,7 @@ class DigestData public function getUsername() { - return strtr($this->elements['username'], array("\\\"" => "\"", "\\\\" => "\\")); + return strtr($this->elements['username'], array('\\"' => '"', '\\\\' => '\\')); } public function validateAndDecode($entryPointKey, $expectedRealm) diff --git a/src/Symfony/Component/Yaml/Escaper.php b/src/Symfony/Component/Yaml/Escaper.php index f4987652aa..ac325a2c2f 100644 --- a/src/Symfony/Component/Yaml/Escaper.php +++ b/src/Symfony/Component/Yaml/Escaper.php @@ -33,11 +33,11 @@ class Escaper "\x18", "\x19", "\x1a", "\x1b", "\x1c", "\x1d", "\x1e", "\x1f", "\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9",); private static $escaped = array('\\\\', '\\"', '\\\\', '\\"', - "\\0", "\\x01", "\\x02", "\\x03", "\\x04", "\\x05", "\\x06", "\\a", - "\\b", "\\t", "\\n", "\\v", "\\f", "\\r", "\\x0e", "\\x0f", - "\\x10", "\\x11", "\\x12", "\\x13", "\\x14", "\\x15", "\\x16", "\\x17", - "\\x18", "\\x19", "\\x1a", "\\e", "\\x1c", "\\x1d", "\\x1e", "\\x1f", - "\\N", "\\_", "\\L", "\\P",); + '\\0', '\\x01', '\\x02', '\\x03', '\\x04', '\\x05', '\\x06', '\\a', + '\\b', '\\t', '\\n', '\\v', '\\f', '\\r', '\\x0e', '\\x0f', + '\\x10', '\\x11', '\\x12', '\\x13', '\\x14', '\\x15', '\\x16', '\\x17', + '\\x18', '\\x19', '\\x1a', '\\e', '\\x1c', '\\x1d', '\\x1e', '\\x1f', + '\\N', '\\_', '\\L', '\\P',); /** * Determines if a PHP value would require double quoting in YAML. diff --git a/src/Symfony/Component/Yaml/Tests/InlineTest.php b/src/Symfony/Component/Yaml/Tests/InlineTest.php index d3329bc2f1..bd8147b3c9 100644 --- a/src/Symfony/Component/Yaml/Tests/InlineTest.php +++ b/src/Symfony/Component/Yaml/Tests/InlineTest.php @@ -218,7 +218,7 @@ class InlineTest extends \PHPUnit_Framework_TestCase '{ foo : bar, bar : foo, false : false, null : null, integer : 12 }' => array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12), '{foo: \'bar\', bar: \'foo: bar\'}' => array('foo' => 'bar', 'bar' => 'foo: bar'), '{\'foo\': \'bar\', "bar": \'foo: bar\'}' => array('foo' => 'bar', 'bar' => 'foo: bar'), - '{\'foo\'\'\': \'bar\', "bar\"": \'foo: bar\'}' => array('foo\'' => 'bar', "bar\"" => 'foo: bar'), + '{\'foo\'\'\': \'bar\', "bar\"": \'foo: bar\'}' => array('foo\'' => 'bar', 'bar"' => 'foo: bar'), '{\'foo: \': \'bar\', "bar: ": \'foo: bar\'}' => array('foo: ' => 'bar', 'bar: ' => 'foo: bar'), // nested sequences and mappings From d97279e942bf3a135634ad90a32f1d5cd05a22ba Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 16 Apr 2015 10:51:32 +0200 Subject: [PATCH 08/11] [HttpKernel] Cleanup ExceptionListener --- .../EventListener/ExceptionListener.php | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php b/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php index b1c1982f45..9860f35502 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php @@ -38,14 +38,6 @@ class ExceptionListener implements EventSubscriberInterface public function onKernelException(GetResponseForExceptionEvent $event) { - static $handling; - - if (true === $handling) { - return false; - } - - $handling = true; - $exception = $event->getException(); $request = $event->getRequest(); @@ -65,13 +57,10 @@ class ExceptionListener implements EventSubscriberInterface $request->setMethod('GET'); try { - $response = $event->getKernel()->handle($request, HttpKernelInterface::SUB_REQUEST, true); + $response = $event->getKernel()->handle($request, HttpKernelInterface::SUB_REQUEST, false); } catch (\Exception $e) { $this->logException($e, sprintf('Exception thrown when handling an exception (%s: %s at %s line %s)', get_class($e), $e->getMessage(), $e->getFile(), $e->getLine()), false); - // set handling to false otherwise it wont be able to handle further more - $handling = false; - $wrapper = $e; while ($prev = $wrapper->getPrevious()) { @@ -88,8 +77,6 @@ class ExceptionListener implements EventSubscriberInterface } $event->setResponse($response); - - $handling = false; } public static function getSubscribedEvents() From 7e95a244d82a3435cd8896e08765d6d12ff1d6e7 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 15 Apr 2015 09:53:47 +0200 Subject: [PATCH 09/11] [FrameworkBundle] Fix Routing\DelegatingLoader resiliency to fatal errors --- .../Routing/DelegatingLoader.php | 40 +++++++++++++++---- .../Component/Config/Loader/FileLoader.php | 7 +++- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php b/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php index 4d0e849edc..b37bee83d4 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php +++ b/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php @@ -12,10 +12,10 @@ namespace Symfony\Bundle\FrameworkBundle\Routing; use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser; +use Symfony\Component\Config\Exception\FileLoaderLoadException; use Symfony\Component\Config\Loader\DelegatingLoader as BaseDelegatingLoader; use Symfony\Component\Config\Loader\LoaderResolverInterface; use Psr\Log\LoggerInterface; -use Symfony\Component\Routing\RouteCollection; /** * DelegatingLoader delegates route loading to other loaders using a loader resolver. @@ -29,6 +29,7 @@ class DelegatingLoader extends BaseDelegatingLoader { protected $parser; protected $logger; + private $loading = false; /** * Constructor. @@ -46,16 +47,39 @@ class DelegatingLoader extends BaseDelegatingLoader } /** - * Loads a resource. - * - * @param mixed $resource A resource - * @param string $type The resource type - * - * @return RouteCollection A RouteCollection instance + * {@inheritdoc} */ public function load($resource, $type = null) { - $collection = parent::load($resource, $type); + if ($this->loading) { + // This can happen if a fatal error occurs in parent::load(). + // Here is the scenario: + // - while routes are being loaded by parent::load() below, a fatal error + // occurs (e.g. parse error in a controller while loading annotations); + // - PHP abruptly empties the stack trace, bypassing all catch blocks; + // it then calls the registered shutdown functions; + // - the ErrorHandler catches the fatal error and re-injects it for rendering + // thanks to HttpKernel->terminateWithException() (that calls handleException()); + // - at this stage, if we try to load the routes again, we must prevent + // the fatal error from occurring a second time, + // otherwise the PHP process would be killed immediately; + // - while rendering the exception page, the router can be required + // (by e.g. the web profiler that needs to generate an URL); + // - this handles the case and prevents the second fatal error + // by triggering an exception beforehand. + + throw new FileLoaderLoadException($resource); + } + $this->loading = true; + + try { + $collection = parent::load($resource, $type); + } catch (\Exception $e) { + $this->loading = false; + throw $e; + } + + $this->loading = false; foreach ($collection->all() as $route) { if ($controller = $route->getDefault('_controller')) { diff --git a/src/Symfony/Component/Config/Loader/FileLoader.php b/src/Symfony/Component/Config/Loader/FileLoader.php index c1add20cea..db754e0a63 100644 --- a/src/Symfony/Component/Config/Loader/FileLoader.php +++ b/src/Symfony/Component/Config/Loader/FileLoader.php @@ -103,7 +103,12 @@ abstract class FileLoader extends Loader } self::$loading[$resource] = true; - $ret = $loader->load($resource, $type); + try { + $ret = $loader->load($resource, $type); + } catch (\Exception $e) { + unset(self::$loading[$resource]); + throw $e; + } unset(self::$loading[$resource]); From a2deb618db5a99d044dbc5bd9475f18f40e0677d Mon Sep 17 00:00:00 2001 From: Luis Cordova Date: Fri, 27 Mar 2015 09:54:14 -0500 Subject: [PATCH 10/11] [DX] improve file loader error for router/other resources in bundle --- .../Component/Config/Exception/FileLoaderLoadException.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Config/Exception/FileLoaderLoadException.php b/src/Symfony/Component/Config/Exception/FileLoaderLoadException.php index b2a567ecda..09956438a5 100644 --- a/src/Symfony/Component/Config/Exception/FileLoaderLoadException.php +++ b/src/Symfony/Component/Config/Exception/FileLoaderLoadException.php @@ -36,7 +36,8 @@ class FileLoaderLoadException extends \Exception if ('@' === $resource[0]) { $parts = explode(DIRECTORY_SEPARATOR, $resource); $bundle = substr($parts[0], 1); - $message .= ' '.sprintf('Make sure the "%s" bundle is correctly registered and loaded in the application kernel class.', $bundle); + $message .= sprintf(' Make sure the "%s" bundle is correctly registered and loaded in the application kernel class.', $bundle); + $message .= sprintf(' If the bundle is registered, make sure the bundle path "%s" is not empty.', $resource); } elseif ($previous) { // include the previous exception, to help the user see what might be the underlying cause $message .= ' '.sprintf('(%s)', $previous->getMessage()); From dd5a811de6fc24aa4917ca6c195169d94e443632 Mon Sep 17 00:00:00 2001 From: Tomasz Kowalczyk Date: Sun, 12 Apr 2015 11:10:52 +0200 Subject: [PATCH 11/11] [Routing][DependencyInjection] Support .yaml extension in YAML loaders --- .../Component/DependencyInjection/Loader/YamlFileLoader.php | 2 +- .../DependencyInjection/Tests/Loader/YamlFileLoaderTest.php | 1 + src/Symfony/Component/Routing/Loader/YamlFileLoader.php | 2 +- .../Component/Routing/Tests/Loader/YamlFileLoaderTest.php | 2 ++ 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php index fa2f6520c2..a706f19fe6 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php @@ -73,7 +73,7 @@ class YamlFileLoader extends FileLoader */ public function supports($resource, $type = null) { - return is_string($resource) && 'yml' === pathinfo($resource, PATHINFO_EXTENSION); + return is_string($resource) && in_array(pathinfo($resource, PATHINFO_EXTENSION), array('yml', 'yaml'), true); } /** diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php index f10ecb04d0..df37d4f9cb 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php @@ -187,6 +187,7 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator()); $this->assertTrue($loader->supports('foo.yml'), '->supports() returns true if the resource is loadable'); + $this->assertTrue($loader->supports('foo.yaml'), '->supports() returns true if the resource is loadable'); $this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable'); } diff --git a/src/Symfony/Component/Routing/Loader/YamlFileLoader.php b/src/Symfony/Component/Routing/Loader/YamlFileLoader.php index 9deea7fe4f..3653eaa550 100644 --- a/src/Symfony/Component/Routing/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/Routing/Loader/YamlFileLoader.php @@ -104,7 +104,7 @@ class YamlFileLoader extends FileLoader */ public function supports($resource, $type = null) { - return is_string($resource) && 'yml' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'yaml' === $type); + return is_string($resource) && in_array(pathinfo($resource, PATHINFO_EXTENSION), array('yml', 'yaml'), true) && (!$type || 'yaml' === $type); } /** diff --git a/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php index 1463326094..167fab00d3 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php @@ -22,9 +22,11 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase $loader = new YamlFileLoader($this->getMock('Symfony\Component\Config\FileLocator')); $this->assertTrue($loader->supports('foo.yml'), '->supports() returns true if the resource is loadable'); + $this->assertTrue($loader->supports('foo.yaml'), '->supports() returns true if the resource is loadable'); $this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable'); $this->assertTrue($loader->supports('foo.yml', 'yaml'), '->supports() checks the resource type if specified'); + $this->assertTrue($loader->supports('foo.yaml', 'yaml'), '->supports() checks the resource type if specified'); $this->assertFalse($loader->supports('foo.yml', 'foo'), '->supports() checks the resource type if specified'); }