From ae7fa11c9179517007419ffc0b44741fbdfc4d18 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 23 Jul 2013 14:30:22 +0200 Subject: [PATCH 1/8] [Twig] fixed TwigEngine::exists() method when a template contains a syntax error (closes #88546) --- .../Bridge/Twig/Tests/TwigEngineTest.php | 56 +++++++++++++++++++ src/Symfony/Bridge/Twig/TwigEngine.php | 14 ++++- 2 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 src/Symfony/Bridge/Twig/Tests/TwigEngineTest.php diff --git a/src/Symfony/Bridge/Twig/Tests/TwigEngineTest.php b/src/Symfony/Bridge/Twig/Tests/TwigEngineTest.php new file mode 100644 index 0000000000..1e6a3c4933 --- /dev/null +++ b/src/Symfony/Bridge/Twig/Tests/TwigEngineTest.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Twig\Tests; + +use Symfony\Bridge\Twig\TwigEngine; + +class TwigEngineTest extends TestCase +{ + public function testExistsWithTemplateInstances() + { + $engine = $this->getTwig(); + + $this->assertTrue($engine->exists($this->getMockForAbstractClass('Twig_Template', array(), '', false))); + } + + public function testExistsWithNonExistentTemplates() + { + $engine = $this->getTwig(); + + $this->assertFalse($engine->exists('foobar')); + } + + public function testExistsWithTemplateWithSyntaxErrors() + { + $engine = $this->getTwig(); + + $this->assertTrue($engine->exists('error')); + } + + public function testExists() + { + $engine = $this->getTwig(); + + $this->assertTrue($engine->exists('index')); + } + + protected function getTwig() + { + $twig = new \Twig_Environment(new \Twig_Loader_Array(array( + 'index' => 'foo', + 'error' => '{{ foo }', + ))); + $parser = $this->getMock('Symfony\Component\Templating\TemplateNameParserInterface'); + + return new TwigEngine($twig, $parser); + } +} diff --git a/src/Symfony/Bridge/Twig/TwigEngine.php b/src/Symfony/Bridge/Twig/TwigEngine.php index 955d4e0bae..41e15bacaa 100644 --- a/src/Symfony/Bridge/Twig/TwigEngine.php +++ b/src/Symfony/Bridge/Twig/TwigEngine.php @@ -75,9 +75,19 @@ class TwigEngine implements EngineInterface, StreamingEngineInterface */ public function exists($name) { + if ($name instanceof \Twig_Template) { + return true; + } + + $loader = $this->environment->getLoader(); + + if ($loader instanceof \Twig_ExistsLoaderInterface) { + return $loader->exists($name); + } + try { - $this->load($name); - } catch (\InvalidArgumentException $e) { + $loader->getSource($name); + } catch (\Twig_Error_Loader $e) { return false; } From 0086ee392ba0088517dcef1f6590aca2f9ed689a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Wed, 24 Jul 2013 14:55:10 +0200 Subject: [PATCH 2/8] [Tests] Tests on php 5.5 should pass Because php 5.5 is stable now --- .travis.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index dbbcc91e35..cb5f0ac5f2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,10 +6,6 @@ php: - 5.4 - 5.5 -matrix: - allow_failures: - - php: 5.5 - before_script: - echo '' > ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini - sh -c 'if [ $(php -r "echo PHP_MINOR_VERSION;") -le 4 ]; then echo "extension = apc.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi;' From dc1fff0fe1d5d6a65b364b62b60f1ec03c695129 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Wed, 24 Jul 2013 17:20:53 +0200 Subject: [PATCH 3/8] The ignoreAttributes itself should be ignored, too. --- .../Bundle/FrameworkBundle/Controller/RedirectController.php | 2 +- .../FrameworkBundle/Tests/Controller/RedirectControllerTest.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php b/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php index 59df4ae2a6..8d515d4bcb 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php +++ b/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php @@ -49,7 +49,7 @@ class RedirectController extends ContainerAware $attributes = array(); if (false === $ignoreAttributes || is_array($ignoreAttributes)) { $attributes = $request->attributes->get('_route_params'); - unset($attributes['route'], $attributes['permanent']); + unset($attributes['route'], $attributes['permanent'], $attributes['ignoreAttributes']); if ($ignoreAttributes) { $attributes = array_diff_key($attributes, array_flip($ignoreAttributes)); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.php index 6bd636ae2a..9baec8dd95 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.php @@ -53,6 +53,7 @@ class RedirectControllerTest extends TestCase 'route' => $route, 'permanent' => $permanent, 'additional-parameter' => 'value', + 'ignoreAttributes' => $ignoreAttributes ), ); From 2e2a36ca2468e3fcd1b41aa40654ea9dcf086a26 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 24 Jul 2013 19:57:25 +0200 Subject: [PATCH 4/8] fixed file permission --- .../Component/Validator/Resources/translations/validators.sl.xlf | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 src/Symfony/Component/Validator/Resources/translations/validators.sl.xlf diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.sl.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.sl.xlf old mode 100755 new mode 100644 From 970ce2c413fb8f2541828eea1ad06d5ca5e08be1 Mon Sep 17 00:00:00 2001 From: bronze1man Date: Thu, 25 Jul 2013 13:55:15 +0800 Subject: [PATCH 5/8] [DependencyInjection] fixed #8570 --- .../ResolveDefinitionTemplatesPass.php | 4 +++ .../DefinitionDecorator.php | 12 ++++++++ .../ResolveDefinitionTemplatesPassTest.php | 30 +++++++++++++++++++ .../Tests/DefinitionDecoratorTest.php | 10 +++++++ 4 files changed, 56 insertions(+) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php index 4fb5b0d3bf..c5187f3b91 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php @@ -87,6 +87,7 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface $def->setConfigurator($parentDef->getConfigurator()); $def->setFile($parentDef->getFile()); $def->setPublic($parentDef->isPublic()); + $def->setLazy($parentDef->isLazy()); // overwrite with values specified in the decorator $changes = $definition->getChanges(); @@ -111,6 +112,9 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface if (isset($changes['public'])) { $def->setPublic($definition->isPublic()); } + if (isset($changes['lazy'])){ + $def->setLazy($definition->isLazy()); + } // merge arguments foreach ($definition->getArguments() as $k => $v) { diff --git a/src/Symfony/Component/DependencyInjection/DefinitionDecorator.php b/src/Symfony/Component/DependencyInjection/DefinitionDecorator.php index ad3c3c1dd0..1f72b8f16b 100644 --- a/src/Symfony/Component/DependencyInjection/DefinitionDecorator.php +++ b/src/Symfony/Component/DependencyInjection/DefinitionDecorator.php @@ -149,6 +149,18 @@ class DefinitionDecorator extends Definition return parent::setPublic($boolean); } + /** + * {@inheritDoc} + * + * @api + */ + public function setLazy($boolean) + { + $this->changes['lazy'] = true; + + return parent::setLazy($boolean); + } + /** * Gets an argument to pass to the service constructor/factory method. * diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php index f3c5b1544d..98e0c871e0 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php @@ -143,6 +143,36 @@ class ResolveDefinitionTemplatesPassTest extends \PHPUnit_Framework_TestCase $this->assertEquals('foo', $def->getClass()); } + public function testSetLazyOnServiceHasParent() + { + $container = new ContainerBuilder(); + + $container->register('parent','stdClass'); + + $container->setDefinition('child1',new DefinitionDecorator('parent')) + ->setLazy(true) + ; + + $this->process($container); + + $this->assertTrue($container->getDefinition('child1')->isLazy()); + } + + public function testSetLazyOnServiceIsParent() + { + $container = new ContainerBuilder(); + + $container->register('parent','stdClass') + ->setLazy(true) + ; + + $container->setDefinition('child1',new DefinitionDecorator('parent')); + + $this->process($container); + + $this->assertTrue($container->getDefinition('child1')->isLazy()); + } + protected function process(ContainerBuilder $container) { $pass = new ResolveDefinitionTemplatesPass(); diff --git a/src/Symfony/Component/DependencyInjection/Tests/DefinitionDecoratorTest.php b/src/Symfony/Component/DependencyInjection/Tests/DefinitionDecoratorTest.php index bf1bab1e29..8be8b64230 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/DefinitionDecoratorTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/DefinitionDecoratorTest.php @@ -61,6 +61,16 @@ class DefinitionDecoratorTest extends \PHPUnit_Framework_TestCase $this->assertEquals(array('public' => true), $def->getChanges()); } + public function testSetLazy() + { + $def = new DefinitionDecorator('foo'); + + $this->assertFalse($def->isLazy()); + $this->assertSame($def, $def->setLazy(false)); + $this->assertFalse($def->isLazy()); + $this->assertEquals(array('lazy' => true), $def->getChanges()); + } + public function testSetArgument() { $def = new DefinitionDecorator('foo'); From 50d07274779c837cb2c494c400c3d9ea8e272cd2 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 25 Jul 2013 17:13:34 +0200 Subject: [PATCH 6/8] [DependencyInjection] fixed regression where setting a service to null did not trigger a re-creation of the service when getting it --- .../Component/DependencyInjection/Container.php | 11 +++++++++++ .../DependencyInjection/Tests/ContainerTest.php | 10 ++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/Symfony/Component/DependencyInjection/Container.php b/src/Symfony/Component/DependencyInjection/Container.php index b97f8a2c03..f99eccd401 100644 --- a/src/Symfony/Component/DependencyInjection/Container.php +++ b/src/Symfony/Component/DependencyInjection/Container.php @@ -184,6 +184,9 @@ class Container implements IntrospectableContainerInterface /** * Sets a service. * + * Setting a service to null resets the service: has() returns false and get() + * behaves in the same way as if the service was never created. + * * @param string $id The service identifier * @param object $service The service instance * @param string $scope The scope of the service @@ -214,6 +217,14 @@ class Container implements IntrospectableContainerInterface if (method_exists($this, $method = 'synchronize'.strtr($id, array('_' => '', '.' => '_')).'Service')) { $this->$method(); } + + if (self::SCOPE_CONTAINER !== $scope && null === $service) { + unset($this->scopedServices[$scope][$id]); + } + + if (null === $service) { + unset($this->services[$id]); + } } /** diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php index c87f2c2b9a..bb0c728f93 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php @@ -112,6 +112,16 @@ class ContainerTest extends \PHPUnit_Framework_TestCase $this->assertEquals($foo, $sc->get('foo'), '->set() sets a service'); } + /** + * @covers Symfony\Component\DependencyInjection\Container::set + */ + public function testSetWithNullResetTheService() + { + $sc = new Container(); + $sc->set('foo', null); + $this->assertFalse($sc->has('foo')); + } + /** * @expectedException \InvalidArgumentException */ From 3553c71d1abd1fcfc7b9377aa0597a15f197a5fc Mon Sep 17 00:00:00 2001 From: Dominik Zogg Date: Thu, 25 Jul 2013 16:45:03 +0200 Subject: [PATCH 7/8] return 0 if there is no valid data --- .../HttpKernel/DataCollector/TimeDataCollector.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Symfony/Component/HttpKernel/DataCollector/TimeDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/TimeDataCollector.php index 5fd2378499..3b1bda5084 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/TimeDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/TimeDataCollector.php @@ -72,6 +72,10 @@ class TimeDataCollector extends DataCollector */ public function getDuration() { + if (!isset($this->data['events']['__section__'])) { + return 0; + } + $lastEvent = $this->data['events']['__section__']; return $lastEvent->getOrigin() + $lastEvent->getDuration() - $this->getStartTime(); @@ -86,6 +90,10 @@ class TimeDataCollector extends DataCollector */ public function getInitTime() { + if (!isset($this->data['events']['__section__'])) { + return 0; + } + return $this->data['events']['__section__']->getOrigin() - $this->getStartTime(); } From e5fba3cf83d9f1b91814846d67825b61a5b504e3 Mon Sep 17 00:00:00 2001 From: Flavian Sierk Date: Thu, 25 Jul 2013 11:50:20 +0200 Subject: [PATCH 8/8] [Form] fixes empty file-inputs get treated as extra field --- src/Symfony/Component/Form/Form.php | 2 +- .../Component/Form/Tests/CompoundFormTest.php | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Form/Form.php b/src/Symfony/Component/Form/Form.php index e151484708..43f46ca228 100644 --- a/src/Symfony/Component/Form/Form.php +++ b/src/Symfony/Component/Form/Form.php @@ -546,7 +546,7 @@ class Form implements \IteratorAggregate, FormInterface foreach ($this->children as $name => $child) { $fieldValue = null; - if (isset($submittedData[$name])) { + if (array_key_exists($name, $submittedData)) { $fieldValue = $submittedData[$name]; unset($submittedData[$name]); } diff --git a/src/Symfony/Component/Form/Tests/CompoundFormTest.php b/src/Symfony/Component/Form/Tests/CompoundFormTest.php index 71c7b2a734..34b11d3949 100644 --- a/src/Symfony/Component/Form/Tests/CompoundFormTest.php +++ b/src/Symfony/Component/Form/Tests/CompoundFormTest.php @@ -13,6 +13,7 @@ namespace Symfony\Component\Form\Tests; use Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationRequestHandler; use Symfony\Component\Form\FormError; +use Symfony\Component\Form\Forms; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\Form\Tests\Fixtures\FixedDataTransformer; @@ -73,6 +74,19 @@ class CompoundFormTest extends AbstractFormTest $this->form->submit(array(), false); } + public function testSubmitDoesNotAddExtraFieldForNullValues() + { + $factory = Forms::createFormFactoryBuilder() + ->getFormFactory(); + + $child = $factory->create('file', null, array('auto_initialize' => false)); + + $this->form->add($child); + $this->form->submit(array('file' => null)); + + $this->assertCount(0, $this->form->getExtraData()); + } + public function testClearMissingFlagIsForwarded() { $child = $this->getMockForm('firstName');