From b49459b4691c2c8e26e1242693a082cb4606e4f6 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 13 May 2016 13:32:48 -0500 Subject: [PATCH 01/24] updated CHANGELOG for 3.1.0-BETA1 --- CHANGELOG-3.1.md | 136 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 CHANGELOG-3.1.md diff --git a/CHANGELOG-3.1.md b/CHANGELOG-3.1.md new file mode 100644 index 0000000000..9b183cb3a8 --- /dev/null +++ b/CHANGELOG-3.1.md @@ -0,0 +1,136 @@ +CHANGELOG for 3.1.x +=================== + +This changelog references the relevant changes (bug and security fixes) done +in 3.1 minor versions. + +To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash +To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v3.1.0...v3.1.1 + +* 3.1.0-BETA1 (2016-05-13) + + * feature #18725 [Ldap] Added the possibility to configure all available Ldap options for connection (csarrazi) + * feature #18715 [FrameworkBundle] Default to Apcu+Filesystem cache chain (nicolas-grekas) + * feature #18184 [DomCrawler] Expose getter for uri (hason) + * feature #18654 [Bridge/Doctrine] Use better exception in the register mapping pass (dantleech) + * feature #18676 [HttpKernel] Add request method to logger messages (gnat42) + * feature #18716 [Cache] Add nonce based cache invalidation to ApcuAdapter (nicolas-grekas) + * feature #18762 [Translation] XLIFF Add `id` to meta data. (SpacePossum) + * feature #18689 [Cache] Add support for Predis, RedisArray and RedisCluster (nicolas-grekas) + * feature #18667 [FrameworkBundle] Semantic config for app/system/pool caches (tgalopin, nicolas-grekas) + * feature #18685 move event listener method type hint docs to @Event annotations defau… (Haehnchen) + * feature #18681 [Cache] Add DSN based Redis connection factory (nicolas-grekas) + * feature #18656 Updating the error message of an AuthenticationEntryPointInterface (weaverryan) + * feature #18069 [DoctrineBridge] deprecate `MergeDoctrineCollectionListener::onBind()` (HeahDude) + * feature #18492 [LDAP] Check whether an entry attribute exists (hiddewie) + * feature #18359 [Form] [DoctrineBridge] optimized LazyChoiceList and DoctrineChoiceLoader (HeahDude) + * feature #18357 [Form] Let `TextType` implement `DataTransformerInterface` (HeahDude) + * feature #18631 [FrameworkBundle] Add optional logger to cache pools (nicolas-grekas) + * feature #18597 [Cache] Add CacheItem::validateKey utility method (nicolas-grekas) + * feature #17660 [Serializer] Integrate the PropertyInfo Component (recursive denormalization and hardening) (mihai-stancu, dunglas) + * feature #18561 [FrameworkBundle] Fallback to default cache system in production for serializer (tgalopin) + * feature #18567 [FrameworkBundle][Serializer] Fix APC cache service name (tgalopin) + * feature #17959 [Serializer] Harden the ObjectNormalizer (dunglas) + * feature #18547 DX: better error message if factory class is empty (dbu) + * feature #18020 fix #17993 - Deprecated callable strings (hamza) + * feature #18487 [Cache] Add DoctrineProvider, for using PSR-6 pools in Doctrine Cache (nicolas-grekas) + * feature #18544 [FrameworkBundle] Fallback to default cache system in production for validation (tgalopin) + * feature #18416 [FrameworkBundle] Calls support for debug:container (JhonnyL) + * feature #18513 [Process] Turn getIterator() args to flags & add ITER_SKIP_OUT/ERR modes (nicolas-grekas) + * feature #18371 [FrameworkBundle] integrate the Cache component (xabbuh, nicolas-grekas) + * feature #18440 Add the kernel.controller_arguments event (stof) + * feature #18308 Added an ArgumentResolver with clean extension point (iltar, HeahDude) + * feature #18414 [Process] Implement IteratorAggregate to stream output (nicolas-grekas) + * feature #18144 [DI] Only rebuild autowiring cache when actually needed (weaverryan) + * feature #18386 [Process] Add InputStream to seamlessly feed running processes (nicolas-grekas) + * feature #18167 [DependencyInjection] Fix a limitation of the PhpDumper (Ener-Getick) + * feature #18387 [DX] [LDAP] Added default service name for the Security component's Ldap providers (csarrazi) + * feature #18290 [Translation] deprecate the backup feature (xabbuh) + * feature #18036 [Serializer] XmlEncoder: Make load flags configurable (dunglas) + * feature #17589 [WebProfilerBundle] [DX] Feature allow forward and redirection detection in wdt (HeahDude) + * feature #18260 Add Inflector component (from StringUtil of PropertyAccess) (teohhanhui) + * feature #18356 [FrameworkBundle] Deprecated form types as services (HeahDude) + * feature #17458 Add strict image validation (Koc) + * feature #18350 [Process] Accept Traversable input (nicolas-grekas) + * feature #18135 [Security] Deprecate onAuthenticationSuccess() (weaverryan) + * feature #18294 [Yaml] dump non UTF-8 encoded strings as binary data (xabbuh) + * feature #18215 [Cache] Add a Chain adapter (dunglas, nicolas-grekas) + * feature #18242 [FrameworkBundle][TwigBundle] Make EngineInterface autowirable (dunglas) + * feature #18197 Make Request::isFromTrustedProxy() public. (Peter Bex) + * feature #18211 [Security] Use auth trust resolver to determine anonymous in ContextListener (WouterJ) + * feature #18232 [Bridge\PhpUnit] Add "disabled" mode to SYMFONY_DEPRECATIONS_HELPER (nicolas-grekas) + * feature #18181 [PhpUnitBridge] Mock DNS functions (nicolas-grekas) + * feature #18176 [Cache] Restrict flushes to namespace scopes (nicolas-grekas) + * feature #18172 [Cache] Redis adapter (gcds, nicolas-grekas) + * feature #18101 [Console] Allow to register commands privately (Ener-Getick) + * feature #18143 [DomCrawler] Exposed getter for baseHref (AAstakhov) + * feature #18034 [FrameworkBundle] Deprecate absolute template paths (jakzal) + * feature #18105 [HttpFoundation] Add support for sending raw cookies in the response (jakzal) + * feature #17255 [Console] ApplicationTester - test stdout and stderr (SpacePossum) + * feature #18024 [Cache] Add namespace handling to all adapters (nicolas-grekas) + * feature #17734 [Cache] Count cache hits/misses in ProxyAdapter (nicolas-grekas) + * feature #17887 Show more information in the security profiler (javiereguiluz) + * feature #17642 [FrameworkBundle] [DX] Add `Controller::json` method to make it easy to send json (mcfedr) + * feature #17484 [FrameworkBundle][DX] Add Levenshtein suggesters to AbstractConfigCommand (kix) + * feature #17690 [FrameworkBundle] Use canBeEnabled() instead of canBeUnset() for consistency (Ener-Getick) + * feature #17714 Adding new TargetPathTrait to get/set the authentication "target_path" (weaverryan) + * feature #17852 Improved the logger panel when the log context is very long (javiereguiluz) + * feature #17761 [Console] Add non-auto column width functionality (akeeman) + * feature #17943 [Yaml] option to dump multi line strings as scalar blocks (xabbuh) + * feature #17553 [Validator] Added a format option to the DateTime constraint. (dosten) + * feature #17728 [Yaml] add option to dump objects as maps (xabbuh) + * feature #17863 [Yaml] add support for parsing the !!binary tag (xabbuh) + * feature #17738 [PropertyAccess] Throw an InvalidArgumentException when the type do not match (dunglas) + * feature #17531 [PropertyInfo] Use last version of reflection docblock (joelwurtz) + * feature #17782 Support autowiring for Doctrine\Common\Annotations\Reader (maryo) + * feature #17603 [Serializer] Add a normalizer that support JsonSerializable objects (mcfedr) + * feature #17630 [FrameworkBundle] Register the DateTimeNormalizer (dunglas) + * feature #17631 [FrameworkBundle] Register the DataUriNormalizer (dunglas) + * feature #17545 [Serializer] Add normalizer / denormalizer awarness (joelwurtz) + * feature #17877 [DependencyInjection] Improving autowiring error messages (weaverryan) + * feature #17732 [DEPRECATION] : deprecated support for Traversable in method ResizeFormListener::PreSubmit (ybensacq) + * feature #17721 [Cache] Add FilesystemAdapter (nicolas-grekas) + * feature #17836 [Yaml] support to parse and dump DateTime objects (xabbuh) + * feature #17809 [Yaml] deprecate starting plain scalars with characters (xabbuh) + * feature #17817 [Ldap] Add write support for the Ldap component (csarrazi) + * feature #17560 [Ldap] Improving the LDAP component (csarrazi) + * feature #17726 [FrameworkBundle] Improve debug:container command (voronkovich) + * feature #17743 [Yaml] dumper flag for enabling exceptions on invalid type (xabbuh) + * feature #17746 [Yaml] deprecate the Dumper::setIndentation() method (xabbuh) + * feature #17730 [Yaml] introduce flags to customize the parser behavior (xabbuh) + * feature #17125 Webprofiler add status code to search form (oktapodia) + * feature #17705 [TwigBridge] deprecate the boolean object support trigger (xabbuh) + * feature #17578 [Yaml] dump customization option with dumper flags (xabbuh) + * feature #17585 [DomCrawler] Abstract URI logic and crawl images (valeriangalliat) + * feature #17654 [Cache] Don't clone, serialize (nicolas-grekas) + * feature #16947 [FrameworkBundle] PropertyInfo: register the SerializerExtractor (dunglas) + * feature #17611 [HttpKernel] Deprecate passing objects as URI attributes to the ESI and SSI renderers (jakzal) + * feature #14288 [Console] Add getters for Application::$autoExit and $catchExceptions (VasekPurchart) + * feature #17504 [Console] Show code when an exception is thrown (maidmaid) + * feature #17540 [WebProfilerBundle] Add HTTP return code in the Ajax request list table (kucharovic) + * feature #17446 [Serializer] Add PSR-6 adapter (dunglas) + * feature #16917 [PropertyInfo] Cache support (dunglas) + * feature #17532 [Asset] Version as service (ewgRa) + * feature #17440 [Validator] Add a PSR-6 adapter (dunglas) + * feature #17113 [Serializer] Add a MaxDepth option (dunglas) + * feature #17530 [Cache] Handle and log errors properly (nicolas-grekas) + * feature #17522 [Cache] Use generator in ArrayAdapter (gcds) + * feature #16164 [Serializer] Add a data: URI normalizer (dunglas) + * feature #15279 Added {{ value }} message placeholder to UniqueEntityValidator (jperovic) + * feature #16652 [console] Add truncate method to FormatterHelper (mheki) + * feature #17438 [Cache] Allow and use generators in AbstractAdapter (nicolas-grekas) + * feature #17111 [HttpKernel] added a setter for the headers property in the HttpException (smatyas) + * feature #17132 [DependencyInjection] Properly ignore invalid reference arguments in collection arguments (ogizanagi) + * feature #17427 [Process] Allow a callback whenever the output is disabled (romainneutron) + * feature #17327 Added support links to exception and toolbar (peterrehm) + * feature #16909 Allows access to payload in callback validator (conradkleinespel) + * feature #17402 [Profiler] make it possible to omit the link var (xabbuh) + * feature #17411 [Serializer] Add a new DateTime normalizer (dunglas) + * feature #17462 [Yaml] deprecate parsing the !!php/object tag (xabbuh) + * feature #17408 [Cache] Symfony PSR-6 implementation (nicolas-grekas) + * feature #17323 [DependencyInjection] Deprecate unsupported attributes/elements for alias (Ener-Getick) + * feature #17305 [VarDumper] Add flags to allow fine tuning dumps representation (nicolas-grekas) + * feature #17318 [HttpFoundation] Allow to get all the mime types associated to a format in the Request (Ener-Getick) + * feature #17133 [DependencyInjection] Make YamlFileLoader raise a deprecation notice if a service definition contains unsupported keywords. (hhamon) + * feature #17191 [Serializer] Move the normalization logic in an abstract class (dunglas) + * feature #16994 [Form] Deprecate the "choices_as_values" option of ChoiceType (nicolas-grekas) From 14d4d5837ac218f8d92b08284f1d17002139b684 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 13 May 2016 13:33:36 -0500 Subject: [PATCH 02/24] updated VERSION for 3.1.0-BETA1 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index e891863321..7318cb2fed 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -59,12 +59,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '3.1.0-DEV'; + const VERSION = '3.1.0-BETA1'; const VERSION_ID = 30100; const MAJOR_VERSION = 3; const MINOR_VERSION = 1; const RELEASE_VERSION = 0; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = 'BETA1'; const END_OF_MAINTENANCE = '01/2017'; const END_OF_LIFE = '07/2017'; From 7a4019bbcf3f82fe7bbc410dd3b61f187a44944a Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 13 May 2016 14:21:08 -0500 Subject: [PATCH 03/24] bumped Symfony version to 3.1.0 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 7318cb2fed..e891863321 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -59,12 +59,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '3.1.0-BETA1'; + const VERSION = '3.1.0-DEV'; const VERSION_ID = 30100; const MAJOR_VERSION = 3; const MINOR_VERSION = 1; const RELEASE_VERSION = 0; - const EXTRA_VERSION = 'BETA1'; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '01/2017'; const END_OF_LIFE = '07/2017'; From 834f55026345ffc220995091b2095c6651ec38dd Mon Sep 17 00:00:00 2001 From: Mathieu Lemoine Date: Fri, 13 May 2016 15:34:52 -0400 Subject: [PATCH 04/24] [DX][DI] Make Autowiring exceptions more future friendly --- .../Compiler/AutowirePass.php | 15 +++++--- .../Tests/Compiler/AutowirePassTest.php | 37 ++++++++++--------- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php index e4457d4608..a7812fe03d 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php @@ -225,13 +225,16 @@ class AutowirePass implements CompilerPassInterface private function createAutowiredDefinition(\ReflectionClass $typeHint, $id) { if (isset($this->notGuessableTypes[$typeHint->name])) { - throw new RuntimeException(sprintf('Unable to autowire argument of type "%s" for the service "%s". Several services implementing this type have been declared: "%s".', $typeHint->name, $id, implode('", "', $this->types[$typeHint->name]))); + $classOrInterface = $typeHint->isInterface() ? 'interface' : 'class'; + $matchingServices = implode(', ', $this->types[$typeHint->name]); + + throw new RuntimeException(sprintf('Unable to autowire argument of type "%s" for the service "%s". Multiple services exist for this %s (%s).', $typeHint->name, $id, $classOrInterface, $matchingServices)); + } - $noAvailableDefinitionMessage = sprintf('Unable to autowire argument of type "%s" for the service "%s". This type cannot be instantiated automatically and no service implementing this type is declared.', $typeHint->name, $id); - if (!$typeHint->isInstantiable()) { - throw new RuntimeException($noAvailableDefinitionMessage); + $classOrInterface = $typeHint->isInterface() ? 'interface' : 'class'; + throw new RuntimeException(sprintf('Unable to autowire argument of type "%s" for the service "%s". No services were found matching this %s and it cannot be auto-registered.', $typeHint->name, $id, $classOrInterface)); } $argumentId = sprintf('autowired.%s', $typeHint->name); @@ -244,7 +247,9 @@ class AutowirePass implements CompilerPassInterface try { $this->completeDefinition($argumentId, $argumentDefinition); } catch (RuntimeException $e) { - throw new RuntimeException($noAvailableDefinitionMessage, 0, $e); + $classOrInterface = $typeHint->isInterface() ? 'interface' : 'class'; + $message = sprintf('Unable to autowire argument of type "%s" for the service "%s". No services were found matching this %s and it cannot be auto-registered.', $typeHint->name, $id, $classOrInterface); + throw new RuntimeException($message, 0, $e); } return new Reference($argumentId); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php index 6098d9a913..b5badc31fd 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php @@ -103,7 +103,7 @@ class AutowirePassTest extends \PHPUnit_Framework_TestCase /** * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException - * @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" for the service "a". Several services implementing this type have been declared: "c1", "c2". + * @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" for the service "a". Multiple services exist for this interface (c1, c2, c3). */ public function testTypeCollision() { @@ -111,6 +111,7 @@ class AutowirePassTest extends \PHPUnit_Framework_TestCase $container->register('c1', __NAMESPACE__.'\CollisionA'); $container->register('c2', __NAMESPACE__.'\CollisionB'); + $container->register('c3', __NAMESPACE__.'\CollisionB'); $aDefinition = $container->register('a', __NAMESPACE__.'\CannotBeAutowired'); $aDefinition->setAutowired(true); @@ -120,7 +121,7 @@ class AutowirePassTest extends \PHPUnit_Framework_TestCase /** * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException - * @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\Foo" for the service "a". Several services implementing this type have been declared: "a1", "a2". + * @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\Foo" for the service "a". Multiple services exist for this class (a1, a2). */ public function testTypeNotGuessable() { @@ -137,7 +138,7 @@ class AutowirePassTest extends \PHPUnit_Framework_TestCase /** * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException - * @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\A" for the service "a". Several services implementing this type have been declared: "a1", "a2". + * @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\A" for the service "a". Multiple services exist for this class (a1, a2). */ public function testTypeNotGuessableWithSubclass() { @@ -152,6 +153,21 @@ class AutowirePassTest extends \PHPUnit_Framework_TestCase $pass->process($container); } + /** + * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException + * @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" for the service "a". No services were found matching this interface and it cannot be auto-registered. + */ + public function testTypeNotGuessableNoServicesFound() + { + $container = new ContainerBuilder(); + + $aDefinition = $container->register('a', __NAMESPACE__.'\CannotBeAutowired'); + $aDefinition->setAutowired(true); + + $pass = new AutowirePass(); + $pass->process($container); + } + public function testTypeNotGuessableWithTypeSet() { $container = new ContainerBuilder(); @@ -207,21 +223,6 @@ class AutowirePassTest extends \PHPUnit_Framework_TestCase $this->assertEquals(__NAMESPACE__.'\Lille', $lilleDefinition->getClass()); } - /** - * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException - * @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" for the service "a". This type cannot be instantiated automatically and no service implementing this type is declared. - */ - public function testCreateNonInstanciable() - { - $container = new ContainerBuilder(); - - $aDefinition = $container->register('a', __NAMESPACE__.'\CannotBeAutowired'); - $aDefinition->setAutowired(true); - - $pass = new AutowirePass(); - $pass->process($container); - } - public function testResolveParameter() { $container = new ContainerBuilder(); From 7d9e74e340134e3288b8d11525e8319ba592af99 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 14 May 2016 13:17:24 +0200 Subject: [PATCH 05/24] remove methods that were needed for PHP 5.3 --- .../Console/Helper/ProgressIndicator.php | 42 ++----------------- 1 file changed, 3 insertions(+), 39 deletions(-) diff --git a/src/Symfony/Component/Console/Helper/ProgressIndicator.php b/src/Symfony/Component/Console/Helper/ProgressIndicator.php index ccf9771bcf..f90a85c291 100644 --- a/src/Symfony/Component/Console/Helper/ProgressIndicator.php +++ b/src/Symfony/Component/Console/Helper/ProgressIndicator.php @@ -76,42 +76,6 @@ class ProgressIndicator $this->display(); } - /** - * Gets the current indicator message. - * - * @return string|null - * - * @internal for PHP 5.3 compatibility - */ - public function getMessage() - { - return $this->message; - } - - /** - * Gets the progress bar start time. - * - * @return int The progress bar start time - * - * @internal for PHP 5.3 compatibility - */ - public function getStartTime() - { - return $this->startTime; - } - - /** - * Gets the current animated indicator character. - * - * @return string - * - * @internal for PHP 5.3 compatibility - */ - public function getCurrentValue() - { - return $this->indicatorValues[$this->indicatorCurrent % count($this->indicatorValues)]; - } - /** * Starts the indicator output. * @@ -294,13 +258,13 @@ class ProgressIndicator { return array( 'indicator' => function (ProgressIndicator $indicator) { - return $indicator->getCurrentValue(); + return $indicator->indicatorValues[$indicator->indicatorCurrent % count($indicator->indicatorValues)]; }, 'message' => function (ProgressIndicator $indicator) { - return $indicator->getMessage(); + return $indicator->message; }, 'elapsed' => function (ProgressIndicator $indicator) { - return Helper::formatTime(time() - $indicator->getStartTime()); + return Helper::formatTime(time() - $indicator->startTime); }, 'memory' => function () { return Helper::formatMemory(memory_get_usage(true)); From f8dd87d7cc2e9c2551322662fb3d9bed7f332d3c Mon Sep 17 00:00:00 2001 From: Romain Neutron Date: Sat, 2 Apr 2016 12:30:41 +0200 Subject: [PATCH 06/24] [WebProfilerBundle] Fix CORS ajax security issues --- .../Resources/views/Profiler/base_js.html.twig | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig index 8c10c95655..d9f92ca26a 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig @@ -80,6 +80,20 @@ requestStack = [], + extractHeaders = function(xhr, stackElement) { + // Here we avoid to call xhr.getResponseHeader in order to + // prevent polluting the console with CORS security errors + var allHeaders = xhr.getAllResponseHeaders(); + var ret; + + if (ret = allHeaders.match(/^x-debug-token:\s+(.*)$/im)) { + stackElement.profile = ret[1]; + } + if (ret = allHeaders.match(/^x-debug-token-link:\s+(.*)$/im)) { + stackElement.profilerUrl = ret[1]; + } + }, + renderAjaxRequests = function() { var requestCounter = document.querySelectorAll('.sf-toolbar-ajax-requests'); if (!requestCounter.length) { @@ -239,8 +253,8 @@ stackElement.duration = new Date() - stackElement.start; stackElement.loading = false; stackElement.error = self.status < 200 || self.status >= 400; - stackElement.profile = self.getResponseHeader("X-Debug-Token"); - stackElement.profilerUrl = self.getResponseHeader("X-Debug-Token-Link"); + + extractHeaders(self, stackElement); Sfjs.renderAjaxRequests(); } From ac7f74eccac01ce7b279c41b72f1422e575e67f6 Mon Sep 17 00:00:00 2001 From: Jeremy Benoist Date: Tue, 17 May 2016 14:52:22 +0200 Subject: [PATCH 07/24] Use levenshtein level for better Bundle matching --- .../Controller/ControllerNameParser.php | 1 + .../Tests/Controller/ControllerNameParserTest.php | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php b/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php index 873c736841..374d0eba10 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php +++ b/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php @@ -142,6 +142,7 @@ class ControllerNameParser $lev = levenshtein($nonExistentBundleName, $bundleName); if ($lev <= strlen($nonExistentBundleName) / 3 && ($alternative === null || $lev < $shortest)) { $alternative = $bundleName; + $shortest = $lev; } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php index 4718c1eb0b..0fe47b0908 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php @@ -59,8 +59,8 @@ class ControllerNameParserTest extends TestCase { $parser = $this->createParser(); - $this->assertEquals('FooBundle:Default:index', $parser->build('TestBundle\FooBundle\Controller\DefaultController::indexAction'), '->parse() converts a class::method string to a short a:b:c notation string'); - $this->assertEquals('FooBundle:Sub\Default:index', $parser->build('TestBundle\FooBundle\Controller\Sub\DefaultController::indexAction'), '->parse() converts a class::method string to a short a:b:c notation string'); + $this->assertEquals('FoooooBundle:Default:index', $parser->build('TestBundle\FooBundle\Controller\DefaultController::indexAction'), '->parse() converts a class::method string to a short a:b:c notation string'); + $this->assertEquals('FoooooBundle:Sub\Default:index', $parser->build('TestBundle\FooBundle\Controller\Sub\DefaultController::indexAction'), '->parse() converts a class::method string to a short a:b:c notation string'); try { $parser->build('TestBundle\FooBundle\Controller\DefaultController::index'); @@ -132,8 +132,9 @@ class ControllerNameParserTest extends TestCase public function getInvalidBundleNameTests() { return array( - array('FoodBundle:Default:index', 'FooBundle:Default:index'), - array('CrazyBundle:Default:index', false), + 'Alternative will be found using levenshtein' => array('FoodBundle:Default:index', 'FooBundle:Default:index'), + 'Alternative will be found using partial match' => array('FabpotFooBund:Default:index', 'FabpotFooBundle:Default:index'), + 'Bundle does not exist at all' => array('CrazyBundle:Default:index', false), ); } @@ -162,6 +163,7 @@ class ControllerNameParserTest extends TestCase $bundles = array( 'SensioFooBundle' => $this->getBundle('TestBundle\Fabpot\FooBundle', 'FabpotFooBundle'), 'SensioCmsFooBundle' => $this->getBundle('TestBundle\Sensio\Cms\FooBundle', 'SensioCmsFooBundle'), + 'FoooooBundle' => $this->getBundle('TestBundle\FooBundle', 'FoooooBundle'), 'FooBundle' => $this->getBundle('TestBundle\FooBundle', 'FooBundle'), 'FabpotFooBundle' => $this->getBundle('TestBundle\Fabpot\FooBundle', 'FabpotFooBundle'), ); From 187b64561586b81a0c8896328826cbe5dcb51e5a Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 17 May 2016 18:47:41 +0200 Subject: [PATCH 08/24] [FrameworkBundle] update upgrade instructions --- UPGRADE-3.0.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md index 8925b91189..327a36bf93 100644 --- a/UPGRADE-3.0.md +++ b/UPGRADE-3.0.md @@ -636,6 +636,11 @@ UPGRADE FROM 2.x to 3.0 be removed in Symfony 3.0. Use the `debug:config`, `debug:container`, `debug:router`, `debug:translation` and `lint:yaml` commands instead. + * The base `Controller`class is now abstract. + + * The visibility of all methods of the base `Controller` class has been changed from + `public` to `protected`. + * The `getRequest` method of the base `Controller` class has been deprecated since Symfony 2.4 and must be therefore removed in 3.0. The only reliable way to get the `Request` object is to inject it in the action method. From 0c8358b3fe30ba50f0d42186b4ffeb216b48a51d Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 16 May 2016 11:02:32 +0200 Subject: [PATCH 09/24] [Cache] Rename nonce to version --- .../DependencyInjection/FrameworkExtension.php | 6 +++--- .../Bundle/FrameworkBundle/Resources/config/cache.xml | 4 ++-- .../Component/Cache/Adapter/AbstractAdapter.php | 4 ++-- src/Symfony/Component/Cache/Adapter/ApcuAdapter.php | 10 +++++----- .../Component/Cache/Tests/Adapter/ApcuAdapterTest.php | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 84a5e3d094..c434cac057 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -1037,9 +1037,9 @@ class FrameworkExtension extends Extension private function registerCacheConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader) { - $nonce = substr(str_replace('/', '-', base64_encode(md5(uniqid(mt_rand(), true), true))), 0, -2); - $container->getDefinition('cache.adapter.apcu')->replaceArgument(2, $nonce); - $container->getDefinition('cache.adapter.system')->replaceArgument(2, $nonce); + $version = substr(str_replace('/', '-', base64_encode(md5(uniqid(mt_rand(), true), true))), 0, -2); + $container->getDefinition('cache.adapter.apcu')->replaceArgument(2, $version); + $container->getDefinition('cache.adapter.system')->replaceArgument(2, $version); $container->getDefinition('cache.adapter.filesystem')->replaceArgument(2, $config['directory']); foreach (array('doctrine', 'psr6', 'redis') as $name) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml index 931b74a58d..c438a1a66f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml @@ -28,7 +28,7 @@ - + %kernel.cache_dir%/pools @@ -38,7 +38,7 @@ - + diff --git a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php index 8c753fb814..01207f54e6 100644 --- a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php @@ -68,7 +68,7 @@ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface ); } - public static function createSystemCache($namespace, $defaultLifetime, $nonce, $directory, LoggerInterface $logger = null) + public static function createSystemCache($namespace, $defaultLifetime, $version, $directory, LoggerInterface $logger = null) { $fs = new FilesystemAdapter($namespace, $defaultLifetime, $directory); if (null !== $logger) { @@ -78,7 +78,7 @@ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface return $fs; } - $apcu = new ApcuAdapter($namespace, $defaultLifetime / 5, $nonce); + $apcu = new ApcuAdapter($namespace, $defaultLifetime / 5, $version); if (null !== $logger) { $apcu->setLogger($logger); } diff --git a/src/Symfony/Component/Cache/Adapter/ApcuAdapter.php b/src/Symfony/Component/Cache/Adapter/ApcuAdapter.php index 35a4d987e3..a1c24a6350 100644 --- a/src/Symfony/Component/Cache/Adapter/ApcuAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/ApcuAdapter.php @@ -24,7 +24,7 @@ class ApcuAdapter extends AbstractAdapter return function_exists('apcu_fetch') && ini_get('apc.enabled') && !('cli' === PHP_SAPI && !ini_get('apc.enable_cli')); } - public function __construct($namespace = '', $defaultLifetime = 0, $nonce = null) + public function __construct($namespace = '', $defaultLifetime = 0, $version = null) { if (!static::isSupported()) { throw new CacheException('APCu is not enabled'); @@ -34,12 +34,12 @@ class ApcuAdapter extends AbstractAdapter } parent::__construct($namespace, $defaultLifetime); - if (null !== $nonce) { - CacheItem::validateKey($nonce); + if (null !== $version) { + CacheItem::validateKey($version); - if (!apcu_exists($nonce.':nonce'.$namespace)) { + if (!apcu_exists($version.':'.$namespace)) { $this->clear($namespace); - apcu_add($nonce.':nonce'.$namespace, null); + apcu_add($version.':'.$namespace, null); } } } diff --git a/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php index 9dcbb5ba9d..1cd4269b45 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php @@ -44,7 +44,7 @@ class ApcuAdapterTest extends CachePoolTest $this->assertFalse($item->isHit()); } - public function testNonce() + public function testVersion() { $namespace = str_replace('\\', '.', __CLASS__); From 6bcb74d27cece7062d77fdfa967661267ab9e596 Mon Sep 17 00:00:00 2001 From: Jules Pietri Date: Wed, 18 May 2016 11:23:21 +0200 Subject: [PATCH 10/24] [YAML] fixed "dump" signature in upgrade file --- UPGRADE-3.1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UPGRADE-3.1.md b/UPGRADE-3.1.md index fffb06bad9..134dfa4e5d 100644 --- a/UPGRADE-3.1.md +++ b/UPGRADE-3.1.md @@ -202,7 +202,7 @@ Yaml After: ```php - Yaml::dump(array('foo' => new A(), 'bar' => 1), 0, 0, false, Yaml::DUMP_OBJECT); + Yaml::dump(array('foo' => new A(), 'bar' => 1), 0, 0, Yaml::DUMP_OBJECT); ``` * The `!!php/object` tag to indicate dumped PHP objects has been deprecated From f49659f1372d4bfc9d9616f92c316e4cc5fd8726 Mon Sep 17 00:00:00 2001 From: Krzysiek Piasecki Date: Thu, 12 May 2016 08:29:24 +0200 Subject: [PATCH 11/24] [Validator] Support for DateTimeImmutable --- .../Component/Validator/Constraints/DateTimeValidator.php | 2 +- .../Component/Validator/Constraints/DateValidator.php | 2 +- .../Validator/Tests/Constraints/DateTimeValidatorTest.php | 7 +++++++ .../Validator/Tests/Constraints/DateValidatorTest.php | 7 +++++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Validator/Constraints/DateTimeValidator.php b/src/Symfony/Component/Validator/Constraints/DateTimeValidator.php index 8d82bd8ca9..0a867a7d4b 100644 --- a/src/Symfony/Component/Validator/Constraints/DateTimeValidator.php +++ b/src/Symfony/Component/Validator/Constraints/DateTimeValidator.php @@ -30,7 +30,7 @@ class DateTimeValidator extends DateValidator throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\DateTime'); } - if (null === $value || '' === $value || $value instanceof \DateTime) { + if (null === $value || '' === $value || $value instanceof \DateTimeInterface) { return; } diff --git a/src/Symfony/Component/Validator/Constraints/DateValidator.php b/src/Symfony/Component/Validator/Constraints/DateValidator.php index bfeb5fca30..ed836de9ac 100644 --- a/src/Symfony/Component/Validator/Constraints/DateValidator.php +++ b/src/Symfony/Component/Validator/Constraints/DateValidator.php @@ -47,7 +47,7 @@ class DateValidator extends ConstraintValidator throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Date'); } - if (null === $value || '' === $value || $value instanceof \DateTime) { + if (null === $value || '' === $value || $value instanceof \DateTimeInterface) { return; } diff --git a/src/Symfony/Component/Validator/Tests/Constraints/DateTimeValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/DateTimeValidatorTest.php index ebb1f3e6b7..dbc4d1aa68 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/DateTimeValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/DateTimeValidatorTest.php @@ -42,6 +42,13 @@ class DateTimeValidatorTest extends AbstractConstraintValidatorTest $this->assertNoViolation(); } + public function testDateTimeImmutableClassIsValid() + { + $this->validator->validate(new \DateTimeImmutable(), new DateTime()); + + $this->assertNoViolation(); + } + /** * @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException */ diff --git a/src/Symfony/Component/Validator/Tests/Constraints/DateValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/DateValidatorTest.php index 67bb2340c3..ec62de6281 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/DateValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/DateValidatorTest.php @@ -42,6 +42,13 @@ class DateValidatorTest extends AbstractConstraintValidatorTest $this->assertNoViolation(); } + public function testDateTimeImmutableClassIsValid() + { + $this->validator->validate(new \DateTimeImmutable(), new Date()); + + $this->assertNoViolation(); + } + /** * @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException */ From 2718a6c764416ede6afa87fe4aaa28a480b93091 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Sat, 30 Apr 2016 12:40:11 +0200 Subject: [PATCH 12/24] [DependencyInjection] Avoid generating call_user_func in more cases --- .../DependencyInjection/Dumper/PhpDumper.php | 8 +++ .../Tests/Fixtures/containers/container9.php | 18 +++++ .../Tests/Fixtures/graphviz/services9.dot | 4 ++ .../Tests/Fixtures/php/services19.php | 2 +- .../Tests/Fixtures/php/services9.php | 68 +++++++++++++++++++ .../Tests/Fixtures/php/services9_compiled.php | 32 +++++++++ .../Tests/Fixtures/xml/services9.xml | 12 ++++ .../Tests/Fixtures/yaml/services9.yml | 14 ++++ 8 files changed, 157 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index e0a763dfe8..ba7fa385d8 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -537,6 +537,10 @@ class PhpDumper extends Dumper return sprintf(" %s::%s(\$%s);\n", $this->dumpLiteralClass($class), $callable[1], $variableName); } + if (0 === strpos($class, 'new ')) { + return sprintf(" (%s)->%s(\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); + } + return sprintf(" call_user_func(array(%s, '%s'), \$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); } @@ -713,6 +717,10 @@ EOF; return sprintf(" $return{$instantiation}%s::%s(%s);\n", $this->dumpLiteralClass($class), $callable[1], $arguments ? implode(', ', $arguments) : ''); } + if (0 === strpos($class, 'new ')) { + return sprintf(" $return{$instantiation}(%s)->%s(%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? implode(', ', $arguments) : ''); + } + return sprintf(" $return{$instantiation}call_user_func(array(%s, '%s')%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? ', '.implode(', ', $arguments) : ''); } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php index 96f334fdd1..f499635604 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php @@ -78,6 +78,15 @@ $container ->register('configured_service', 'stdClass') ->setConfigurator(array(new Reference('configurator_service'), 'configureStdClass')) ; +$container + ->register('configurator_service_simple', 'ConfClass') + ->addArgument('bar') + ->setPublic(false) +; +$container + ->register('configured_service_simple', 'stdClass') + ->setConfigurator(array(new Reference('configurator_service_simple'), 'configureStdClass')) +; $container ->register('decorated', 'stdClass') ; @@ -111,5 +120,14 @@ $container ->register('service_from_static_method', 'Bar\FooClass') ->setFactory(array('Bar\FooClass', 'getInstance')) ; +$container + ->register('factory_simple', 'SimpleFactoryClass') + ->addArgument('foo') + ->setPublic(false) +; +$container + ->register('factory_service_simple', 'Bar') + ->setFactory(array(new Reference('factory_simple'), 'getInstance')) +; return $container; diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot index f6536980aa..3b24ef8ffb 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot @@ -14,6 +14,8 @@ digraph sc { node_request [label="request\nRequest\n", shape=record, fillcolor="#eeeeee", style="filled"]; node_configurator_service [label="configurator_service\nConfClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; node_configured_service [label="configured_service\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_configurator_service_simple [label="configurator_service_simple\nConfClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_configured_service_simple [label="configured_service_simple\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; node_decorated [label="decorated\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; node_decorator_service [label="decorator_service\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; node_decorator_service_with_name [label="decorator_service_with_name\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; @@ -22,6 +24,8 @@ digraph sc { node_factory_service [label="factory_service\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"]; node_new_factory_service [label="new_factory_service\nFooBarBaz\n", shape=record, fillcolor="#eeeeee", style="filled"]; node_service_from_static_method [label="service_from_static_method\nBar\\FooClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_factory_simple [label="factory_simple\nSimpleFactoryClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_factory_service_simple [label="factory_service_simple\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"]; node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=record, fillcolor="#9999ff", style="filled"]; node_foo2 [label="foo2\n\n", shape=record, fillcolor="#ff9999", style="filled"]; node_foo3 [label="foo3\n\n", shape=record, fillcolor="#ff9999", style="filled"]; diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services19.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services19.php index cc2a18dcd1..6c56cfcebf 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services19.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services19.php @@ -40,7 +40,7 @@ class ProjectServiceContainer extends Container */ protected function getServiceFromAnonymousFactoryService() { - return $this->services['service_from_anonymous_factory'] = call_user_func(array(new \Bar\FooClass(), 'getInstance')); + return $this->services['service_from_anonymous_factory'] = (new \Bar\FooClass())->getInstance(); } /** diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php index a29f7dd768..cb84452bca 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php @@ -28,12 +28,16 @@ class ProjectServiceContainer extends Container 'bar' => 'getBarService', 'baz' => 'getBazService', 'configurator_service' => 'getConfiguratorServiceService', + 'configurator_service_simple' => 'getConfiguratorServiceSimpleService', 'configured_service' => 'getConfiguredServiceService', + 'configured_service_simple' => 'getConfiguredServiceSimpleService', 'decorated' => 'getDecoratedService', 'decorator_service' => 'getDecoratorServiceService', 'decorator_service_with_name' => 'getDecoratorServiceWithNameService', 'deprecated_service' => 'getDeprecatedServiceService', 'factory_service' => 'getFactoryServiceService', + 'factory_service_simple' => 'getFactoryServiceSimpleService', + 'factory_simple' => 'getFactorySimpleService', 'foo' => 'getFooService', 'foo.baz' => 'getFoo_BazService', 'foo_bar' => 'getFooBarService', @@ -104,6 +108,23 @@ class ProjectServiceContainer extends Container return $instance; } + /** + * Gets the 'configured_service_simple' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return \stdClass A stdClass instance. + */ + protected function getConfiguredServiceSimpleService() + { + $this->services['configured_service_simple'] = $instance = new \stdClass(); + + $this->get('configurator_service_simple')->configureStdClass($instance); + + return $instance; + } + /** * Gets the 'decorated' service. * @@ -173,6 +194,19 @@ class ProjectServiceContainer extends Container return $this->services['factory_service'] = $this->get('foo.baz')->getInstance(); } + /** + * Gets the 'factory_service_simple' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return \Bar A Bar instance. + */ + protected function getFactoryServiceSimpleService() + { + return $this->services['factory_service_simple'] = $this->get('factory_simple')->getInstance(); + } + /** * Gets the 'foo' service. * @@ -334,6 +368,40 @@ class ProjectServiceContainer extends Container return $instance; } + /** + * Gets the 'configurator_service_simple' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * This service is private. + * If you want to be able to request this service from the container directly, + * make it public, otherwise you might end up with broken code. + * + * @return \ConfClass A ConfClass instance. + */ + protected function getConfiguratorServiceSimpleService() + { + return $this->services['configurator_service_simple'] = new \ConfClass('bar'); + } + + /** + * Gets the 'factory_simple' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * This service is private. + * If you want to be able to request this service from the container directly, + * make it public, otherwise you might end up with broken code. + * + * @return \SimpleFactoryClass A SimpleFactoryClass instance. + */ + protected function getFactorySimpleService() + { + return $this->services['factory_simple'] = new \SimpleFactoryClass('foo'); + } + /** * Gets the 'inlined' service. * diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php index 5386b12a99..4fd1ac90f3 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php @@ -30,10 +30,12 @@ class ProjectServiceContainer extends Container 'bar' => 'getBarService', 'baz' => 'getBazService', 'configured_service' => 'getConfiguredServiceService', + 'configured_service_simple' => 'getConfiguredServiceSimpleService', 'decorator_service' => 'getDecoratorServiceService', 'decorator_service_with_name' => 'getDecoratorServiceWithNameService', 'deprecated_service' => 'getDeprecatedServiceService', 'factory_service' => 'getFactoryServiceService', + 'factory_service_simple' => 'getFactoryServiceSimpleService', 'foo' => 'getFooService', 'foo.baz' => 'getFoo_BazService', 'foo_bar' => 'getFooBarService', @@ -114,6 +116,23 @@ class ProjectServiceContainer extends Container return $instance; } + /** + * Gets the 'configured_service_simple' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return \stdClass A stdClass instance. + */ + protected function getConfiguredServiceSimpleService() + { + $this->services['configured_service_simple'] = $instance = new \stdClass(); + + (new \ConfClass('bar'))->configureStdClass($instance); + + return $instance; + } + /** * Gets the 'decorator_service' service. * @@ -170,6 +189,19 @@ class ProjectServiceContainer extends Container return $this->services['factory_service'] = $this->get('foo.baz')->getInstance(); } + /** + * Gets the 'factory_service_simple' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return \Bar A Bar instance. + */ + protected function getFactoryServiceSimpleService() + { + return $this->services['factory_service_simple'] = (new \SimpleFactoryClass('foo'))->getInstance(); + } + /** * Gets the 'foo' service. * diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml index 4ddb8655c5..d3974c07b0 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml @@ -84,6 +84,12 @@ + + bar + + + + @@ -103,6 +109,12 @@ + + foo + + + + diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml index 6efeb37e74..4a97dcadff 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml @@ -67,6 +67,13 @@ services: configured_service: class: stdClass configurator: ['@configurator_service', configureStdClass] + configurator_service_simple: + class: ConfClass + public: false + arguments: ['bar'] + configured_service_simple: + class: stdClass + configurator: ['@configurator_service_simple', configureStdClass] decorated: class: stdClass decorator_service: @@ -93,5 +100,12 @@ services: service_from_static_method: class: Bar\FooClass factory: [Bar\FooClass, getInstance] + factory_simple: + class: SimpleFactoryClass + public: false + arguments: ['foo'] + factory_service_simple: + class: Bar + factory: ['@factory_simple', getInstance] alias_for_foo: '@foo' alias_for_alias: '@foo' From 103526b40f6cfc46ad2f627e4e19c8f02cc08276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Proch=C3=A1zka?= Date: Thu, 12 May 2016 17:11:08 +0200 Subject: [PATCH 13/24] Catch \Throwable --- src/Symfony/Component/Debug/DebugClassLoader.php | 4 ++++ src/Symfony/Component/Debug/ErrorHandler.php | 6 ++++++ src/Symfony/Component/OptionsResolver/OptionsResolver.php | 6 ++++++ src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php | 2 ++ 4 files changed, 18 insertions(+) diff --git a/src/Symfony/Component/Debug/DebugClassLoader.php b/src/Symfony/Component/Debug/DebugClassLoader.php index 36afa36930..603c814b56 100644 --- a/src/Symfony/Component/Debug/DebugClassLoader.php +++ b/src/Symfony/Component/Debug/DebugClassLoader.php @@ -175,6 +175,10 @@ class DebugClassLoader } catch (\Exception $e) { ErrorHandler::unstackErrors(); + throw $e; + } catch (\Throwable $e) { + ErrorHandler::unstackErrors(); + throw $e; } diff --git a/src/Symfony/Component/Debug/ErrorHandler.php b/src/Symfony/Component/Debug/ErrorHandler.php index 33779af325..9c30ffea44 100644 --- a/src/Symfony/Component/Debug/ErrorHandler.php +++ b/src/Symfony/Component/Debug/ErrorHandler.php @@ -447,6 +447,10 @@ class ErrorHandler } catch (\Exception $e) { $this->isRecursive = false; + throw $e; + } catch (\Throwable $e) { + $this->isRecursive = false; + throw $e; } } @@ -555,6 +559,8 @@ class ErrorHandler } } catch (\Exception $exception) { // Handled below + } catch (\Throwable $exception) { + // Handled below } if ($error && $error['type'] &= E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR) { diff --git a/src/Symfony/Component/OptionsResolver/OptionsResolver.php b/src/Symfony/Component/OptionsResolver/OptionsResolver.php index e0578af717..bc763202f2 100644 --- a/src/Symfony/Component/OptionsResolver/OptionsResolver.php +++ b/src/Symfony/Component/OptionsResolver/OptionsResolver.php @@ -861,6 +861,9 @@ class OptionsResolver implements Options, OptionsResolverInterface } catch (\Exception $e) { unset($this->calling[$option]); throw $e; + } catch (\Throwable $e) { + unset($this->calling[$option]); + throw $e; } unset($this->calling[$option]); // END @@ -963,6 +966,9 @@ class OptionsResolver implements Options, OptionsResolverInterface } catch (\Exception $e) { unset($this->calling[$option]); throw $e; + } catch (\Throwable $e) { + unset($this->calling[$option]); + throw $e; } unset($this->calling[$option]); // END diff --git a/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php b/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php index cc4b2ef498..1035bd70c2 100644 --- a/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php +++ b/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php @@ -141,6 +141,8 @@ abstract class AbstractDumper implements DataDumperInterface, DumperInterface $this->dumpLine(-1); } catch (\Exception $exception) { // Re-thrown below + } catch (\Throwable $exception) { + // Re-thrown below } if ($output) { $this->setOutput($prevOutput); From de671f4cb2299f46fdbbd43e3bc747e813b0a90e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Proch=C3=A1zka?= Date: Thu, 12 May 2016 17:11:08 +0200 Subject: [PATCH 14/24] Catch \Throwable --- .../Component/DependencyInjection/Compiler/AutowirePass.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php index e4457d4608..7bb0516dc0 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php @@ -44,8 +44,8 @@ class AutowirePass implements CompilerPassInterface $this->completeDefinition($id, $definition); } } - } catch (\Error $e) { } catch (\Exception $e) { + } catch (\Throwable $e) { } spl_autoload_unregister($throwingAutoloader); From 3234ca491c20f3b173448115838056ac284b8c80 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Thu, 19 May 2016 21:50:23 +0200 Subject: [PATCH 15/24] fix removed commands wording in upgrade file --- UPGRADE-3.0.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md index 35823d8aaf..aef162311c 100644 --- a/UPGRADE-3.0.md +++ b/UPGRADE-3.0.md @@ -1604,8 +1604,7 @@ UPGRADE FROM 2.x to 3.0 ### WebProfiler - * The `profiler:import` and `profiler:export` commands have been deprecated and - will be removed in 3.0. + * The `profiler:import` and `profiler:export` commands have been removed. * All the profiler storages different than `FileProfilerStorage` have been removed. The removed classes are: From c73f34d2bc19d87a73a7b43482546e855db18354 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 20 May 2016 13:48:17 +0200 Subject: [PATCH 16/24] [Config] Allow schemed path in FileResource --- src/Symfony/Component/Config/Resource/FileResource.php | 4 ++++ .../Component/Config/Tests/Resource/FileResourceTest.php | 8 +++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Config/Resource/FileResource.php b/src/Symfony/Component/Config/Resource/FileResource.php index f94640fffc..65a195f5d2 100644 --- a/src/Symfony/Component/Config/Resource/FileResource.php +++ b/src/Symfony/Component/Config/Resource/FileResource.php @@ -36,6 +36,10 @@ class FileResource implements SelfCheckingResourceInterface, \Serializable { $this->resource = realpath($resource); + if (false === $this->resource && file_exists($resource)) { + $this->resource = $resource; + } + if (false === $this->resource) { throw new \InvalidArgumentException(sprintf('The file "%s" does not exist.', $resource)); } diff --git a/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php index 4151f66bc5..6a168e6351 100644 --- a/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php @@ -21,7 +21,7 @@ class FileResourceTest extends \PHPUnit_Framework_TestCase protected function setUp() { - $this->file = realpath(sys_get_temp_dir()).'/tmp.xml'; + $this->file = sys_get_temp_dir().'/tmp.xml'; $this->time = time(); touch($this->file, $this->time); $this->resource = new FileResource($this->file); @@ -41,6 +41,12 @@ class FileResourceTest extends \PHPUnit_Framework_TestCase $this->assertSame(realpath($this->file), $this->resource->getResource(), '->getResource() returns the path to the resource'); } + public function testGetResourceWithScheme() + { + $resource = new FileResource('file://'.$this->file); + $this->assertSame('file://'.$this->file, $resource->getResource(), '->getResource() returns the path to the schemed resource'); + } + public function testToString() { $this->assertSame(realpath($this->file), (string) $this->resource); From cd66a452c6576fd308716f1c20905c08d20903f2 Mon Sep 17 00:00:00 2001 From: bradbyu Date: Fri, 13 May 2016 10:45:14 -0400 Subject: [PATCH 17/24] Update UPGRADE FROM 2.x to 3.0 --- UPGRADE-3.0.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md index 475fcbbc80..467c13e644 100644 --- a/UPGRADE-3.0.md +++ b/UPGRADE-3.0.md @@ -132,7 +132,10 @@ UPGRADE FROM 2.x to 3.0 ### Form - * The `ChoiceToBooleanArrayTransformer`, `ChoicesToBooleanArrayTransformer`, + * The `max_length` option was removed. Use the `attr` option instead by setting it to + an `array` with a `maxlength` key. + + * The `ChoiceToBooleanArrayTransformer`, `ChoicesToBooleanArrayTransformer`, `FixRadioInputListener`, and `FixCheckboxInputListener` classes were removed. * The `choice_list` option of `ChoiceType` was removed. From 94e4706609b5bfe5f0ac2c26f53141042a65b55c Mon Sep 17 00:00:00 2001 From: Peter Rehm Date: Thu, 19 May 2016 16:20:34 +0200 Subject: [PATCH 18/24] Fixed server status command when port has been omitted --- .../Bundle/FrameworkBundle/Command/ServerStatusCommand.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ServerStatusCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ServerStatusCommand.php index 2c6d2c49ff..fa5c537a0c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/ServerStatusCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/ServerStatusCommand.php @@ -13,6 +13,7 @@ namespace Symfony\Bundle\FrameworkBundle\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; /** @@ -31,6 +32,7 @@ class ServerStatusCommand extends ServerCommand $this ->setDefinition(array( new InputArgument('address', InputArgument::OPTIONAL, 'Address:port', '127.0.0.1:8000'), + new InputOption('port', 'p', InputOption::VALUE_REQUIRED, 'Address port number', '8000'), )) ->setName('server:status') ->setDescription('Outputs the status of the built-in web server for the given address') @@ -44,6 +46,10 @@ class ServerStatusCommand extends ServerCommand { $address = $input->getArgument('address'); + if (false === strpos($address, ':')) { + $address = $address.':'.$input->getOption('port'); + } + // remove an orphaned lock file if (file_exists($this->getLockFile($address)) && !$this->isServerRunning($address)) { unlink($this->getLockFile($address)); From a4b1fa669432ff433df65a7e89e122c3d7d8b892 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 14 May 2016 17:57:37 +0200 Subject: [PATCH 19/24] chomp newlines only at the end of YAML documents --- src/Symfony/Component/Yaml/Parser.php | 26 ++++++++++++++----- .../Component/Yaml/Tests/ParserTest.php | 3 ++- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index a37e3e6948..67f780aaae 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -25,6 +25,7 @@ class Parser const FOLDED_SCALAR_PATTERN = self::BLOCK_SCALAR_HEADER_PATTERN; private $offset = 0; + private $totalNumberOfLines; private $lines = array(); private $currentLineNb = -1; private $currentLine = ''; @@ -33,11 +34,13 @@ class Parser /** * Constructor. * - * @param int $offset The offset of YAML document (used for line numbers in error messages) + * @param int $offset The offset of YAML document (used for line numbers in error messages) + * @param int|null $totalNumberOfLines The overall number of lines being parsed */ - public function __construct($offset = 0) + public function __construct($offset = 0, $totalNumberOfLines = null) { $this->offset = $offset; + $this->totalNumberOfLines = $totalNumberOfLines; } /** @@ -61,6 +64,10 @@ class Parser $value = $this->cleanup($value); $this->lines = explode("\n", $value); + if (null === $this->totalNumberOfLines) { + $this->totalNumberOfLines = count($this->lines); + } + if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) { $mbEncoding = mb_internal_encoding(); mb_internal_encoding('UTF-8'); @@ -93,7 +100,7 @@ class Parser // array if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) { $c = $this->getRealCurrentLineNb() + 1; - $parser = new self($c); + $parser = new self($c, $this->totalNumberOfLines); $parser->refs = &$this->refs; $data[] = $parser->parse($this->getNextEmbedBlock(null, true), $exceptionOnInvalidType, $objectSupport); } else { @@ -102,7 +109,7 @@ class Parser ) { // this is a compact notation element, add to next block and parse $c = $this->getRealCurrentLineNb(); - $parser = new self($c); + $parser = new self($c, $this->totalNumberOfLines); $parser->refs = &$this->refs; $block = $values['value']; @@ -153,7 +160,7 @@ class Parser $value = $this->getNextEmbedBlock(); } $c = $this->getRealCurrentLineNb() + 1; - $parser = new self($c); + $parser = new self($c, $this->totalNumberOfLines); $parser->refs = &$this->refs; $parsed = $parser->parse($value, $exceptionOnInvalidType, $objectSupport); @@ -190,7 +197,7 @@ class Parser $data[$key] = null; } else { $c = $this->getRealCurrentLineNb() + 1; - $parser = new self($c); + $parser = new self($c, $this->totalNumberOfLines); $parser->refs = &$this->refs; $data[$key] = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport); } @@ -528,6 +535,8 @@ class Parser if ($notEOF) { $blockLines[] = ''; $this->moveToPreviousLine(); + } elseif (!$notEOF && !$this->isCurrentLineLastLineInDocument()) { + $blockLines[] = ''; } // folded style @@ -634,6 +643,11 @@ class Parser return '' !== $ltrimmedLine && $ltrimmedLine[0] === '#'; } + private function isCurrentLineLastLineInDocument() + { + return ($this->offset + $this->currentLineNb) >= ($this->totalNumberOfLines - 1); + } + /** * Cleanups a YAML string to be parsed. * diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index 34cc81b2d3..6645c36108 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -826,6 +826,7 @@ EOT foo # bar baz + EOT , ), @@ -854,7 +855,7 @@ EOT; $expected = array( 'foo' => array( 'bar' => array( - 'scalar-block' => 'line1 line2>', + 'scalar-block' => "line1 line2>\n", ), 'baz' => array( 'foobar' => null, From c2f7fedfd6494ac8e97347e554b0d3d16f7086eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 22 May 2016 13:47:44 +0200 Subject: [PATCH 20/24] [Serializer] Add test for ignored attributes during denormalization --- .../Tests/Normalizer/ObjectNormalizerTest.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php index c0602d7fa6..398a579b9f 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php @@ -324,6 +324,19 @@ class ObjectNormalizerTest extends \PHPUnit_Framework_TestCase ); } + public function testIgnoredAttributesDenormalize() + { + $this->normalizer->setIgnoredAttributes(array('fooBar', 'bar', 'baz')); + + $obj = new ObjectDummy(); + $obj->setFoo('foo'); + + $this->assertEquals( + $obj, + $this->normalizer->denormalize(array('fooBar' => 'fooBar', 'foo' => 'foo', 'baz' => 'baz'), __NAMESPACE__.'\ObjectDummy') + ); + } + public function provideCallbacks() { return array( From 717e1a9e47d0899efcb65676cf10285a43a03a23 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sun, 22 May 2016 18:02:36 +0200 Subject: [PATCH 21/24] [Yaml] properly handle unindented collections --- src/Symfony/Component/Yaml/Parser.php | 2 +- .../Component/Yaml/Tests/ParserTest.php | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index a37e3e6948..d27968bb40 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -711,7 +711,7 @@ class Parser */ private function isStringUnIndentedCollectionItem() { - return 0 === strpos($this->currentLine, '- '); + return '-' === rtrim($this->currentLine) || 0 === strpos($this->currentLine, '- '); } /** diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index 34cc81b2d3..ba4064272a 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -557,6 +557,34 @@ EOF ); } + public function testSequenceInMappingStartedBySingleDashLine() + { + $yaml = << array( + array( + 'b' => array( + array( + 'bar' => 'baz', + ), + ), + ), + 'foo', + ), + 'd' => 'e', + ); + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + /** * @expectedException \Symfony\Component\Yaml\Exception\ParseException */ From 02070f9fd353df6395db1cff0a46eb0ea3cbb605 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Mor=C3=A1vek=20=28moravek=2Emartin=29?= Date: Sun, 22 May 2016 21:49:29 +0900 Subject: [PATCH 22/24] People - person singularization --- src/Symfony/Component/PropertyAccess/StringUtil.php | 3 +++ src/Symfony/Component/PropertyAccess/Tests/StringUtilTest.php | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/Symfony/Component/PropertyAccess/StringUtil.php b/src/Symfony/Component/PropertyAccess/StringUtil.php index 248a6483d8..caa8c3d7e1 100644 --- a/src/Symfony/Component/PropertyAccess/StringUtil.php +++ b/src/Symfony/Component/PropertyAccess/StringUtil.php @@ -124,6 +124,9 @@ class StringUtil // chateaux (chateau) array('xuae', 4, false, true, 'eau'), + + // people (person) + array('elpoep', 6, true, true, 'person'), ); /** diff --git a/src/Symfony/Component/PropertyAccess/Tests/StringUtilTest.php b/src/Symfony/Component/PropertyAccess/Tests/StringUtilTest.php index 0fd6bb69b2..983e355cb9 100644 --- a/src/Symfony/Component/PropertyAccess/Tests/StringUtilTest.php +++ b/src/Symfony/Component/PropertyAccess/Tests/StringUtilTest.php @@ -107,6 +107,8 @@ class StringUtilTest extends \PHPUnit_Framework_TestCase array('objectives', 'objective'), array('oxen', 'ox'), array('parties', 'party'), + array('people', 'person'), + array('persons', 'person'), array('phenomena', array('phenomenon', 'phenomenum')), array('photos', 'photo'), array('pianos', 'piano'), From 55d9a7a7324371feb20fdea3103669350b544f5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Mor=C3=A1vek=20=28moravek=2Emartin=29?= Date: Sat, 21 May 2016 01:03:47 +0900 Subject: [PATCH 23/24] Added people - person inflection --- src/Symfony/Component/Inflector/Inflector.php | 3 +++ src/Symfony/Component/Inflector/Tests/InflectorTest.php | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/Symfony/Component/Inflector/Inflector.php b/src/Symfony/Component/Inflector/Inflector.php index 0fc58982fe..7b227c5ac6 100644 --- a/src/Symfony/Component/Inflector/Inflector.php +++ b/src/Symfony/Component/Inflector/Inflector.php @@ -126,6 +126,9 @@ final class Inflector // chateaux (chateau) array('xuae', 4, false, true, 'eau'), + + // people (person) + array('elpoep', 6, true, true, 'person'), ); /** diff --git a/src/Symfony/Component/Inflector/Tests/InflectorTest.php b/src/Symfony/Component/Inflector/Tests/InflectorTest.php index 0f3643374a..43aa682f37 100644 --- a/src/Symfony/Component/Inflector/Tests/InflectorTest.php +++ b/src/Symfony/Component/Inflector/Tests/InflectorTest.php @@ -107,6 +107,8 @@ class InflectorTest extends \PHPUnit_Framework_TestCase array('objectives', 'objective'), array('oxen', 'ox'), array('parties', 'party'), + array('people', 'person'), + array('persons', 'person'), array('phenomena', array('phenomenon', 'phenomenum')), array('photos', 'photo'), array('pianos', 'piano'), From 9bdaba48018b459bb8fdc3673e6155e0e418adb7 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Mon, 23 May 2016 11:57:38 +0200 Subject: [PATCH 24/24] [Yaml] fix exception contexts --- src/Symfony/Component/Yaml/Parser.php | 8 ++++---- src/Symfony/Component/Yaml/Tests/ParserTest.php | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index 46e7549749..2739723c7e 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -88,7 +88,7 @@ class Parser $isRef = $isInPlace = $isProcessed = false; if (preg_match('#^\-((?P\s+)(?P.+?))?\s*$#u', $this->currentLine, $values)) { if ($context && 'mapping' == $context) { - throw new ParseException('You cannot define a sequence item when in a mapping'); + throw new ParseException('You cannot define a sequence item when in a mapping', $this->getRealCurrentLineNb() + 1, $this->currentLine); } $context = 'sequence'; @@ -127,7 +127,7 @@ class Parser } } elseif (preg_match('#^(?P'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\[\{].*?) *\:(\s+(?P.+?))?\s*$#u', $this->currentLine, $values) && (false === strpos($values['key'], ' #') || in_array($values['key'][0], array('"', "'")))) { if ($context && 'sequence' == $context) { - throw new ParseException('You cannot define a mapping item when in a sequence'); + throw new ParseException('You cannot define a mapping item when in a sequence', $this->currentLineNb + 1, $this->currentLine); } $context = 'mapping'; @@ -214,7 +214,7 @@ class Parser } else { // multiple documents are not supported if ('---' === $this->currentLine) { - throw new ParseException('Multiple documents are not supported.'); + throw new ParseException('Multiple documents are not supported.', $this->currentLineNb + 1, $this->currentLine); } // 1-liner optionally followed by newline(s) @@ -449,7 +449,7 @@ class Parser } if (!array_key_exists($value, $this->refs)) { - throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLine); + throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLineNb + 1, $this->currentLine); } return $this->refs[$value]; diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index c3fc6b2ada..87f0cdbb1b 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -525,7 +525,7 @@ EOF; /** * @expectedException \Symfony\Component\Yaml\Exception\ParseException - * @expectedExceptionMessage Multiple documents are not supported. + * @expectedExceptionMessageRegExp /^Multiple documents are not supported.+/ */ public function testMultipleDocumentsNotSupportedException() {