diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/HttpKernelExtensionTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/HttpKernelExtensionTest.php index c0dc42d2f35f0..8e5e4d1d4756b 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/HttpKernelExtensionTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/HttpKernelExtensionTest.php @@ -49,16 +49,8 @@ protected function getFragmentHandler($return) $strategy->expects($this->once())->method('getName')->will($this->returnValue('inline')); $strategy->expects($this->once())->method('render')->will($return); - // simulate a master request - $event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock(); - $event - ->expects($this->once()) - ->method('getRequest') - ->will($this->returnValue(Request::create('/'))) - ; - $renderer = new FragmentHandler(array($strategy)); - $renderer->onKernelRequest($event); + $renderer->setRequest(Request::create('/')); return $renderer; } diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/fragment_renderer.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/fragment_renderer.xml index cbe3db3257b6e..662f042adeeac 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/fragment_renderer.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/fragment_renderer.xml @@ -14,9 +14,9 @@ - %kernel.debug% + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml index 6d6671b7ae33f..9e21db4519151 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml @@ -94,6 +94,7 @@ + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml index fbddc0e07fbfd..c1c28c0fa0939 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml @@ -40,7 +40,7 @@ This service definition only defines the scope of the request. It is used to check references scope. --> - + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml index d34ecdf3c3727..177821a5afb24 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml @@ -38,6 +38,7 @@ %kernel.default_locale% + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/SubRequestController.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/SubRequestController.php new file mode 100644 index 0000000000000..14d002642ba81 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/SubRequestController.php @@ -0,0 +1,66 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\DependencyInjection\ContainerAware; +use Symfony\Component\HttpKernel\Controller\ControllerReference; + +class SubRequestController extends ContainerAware +{ + public function indexAction() + { + $handler = $this->container->get('fragment.handler'); + + $errorUrl = $this->generateUrl('subrequest_fragment_error', array('_locale' => 'fr', '_format' => 'json')); + $altUrl = $this->generateUrl('subrequest_fragment', array('_locale' => 'fr', '_format' => 'json')); + + // simulates a failure during the rendering of a fragment... + // should render fr/json + $content = $handler->render($errorUrl, 'inline', array('alt' => $altUrl)); + + // ...to check that the FragmentListener still references the right Request + // when rendering another fragment after the error occured + // should render en/html instead of fr/json + $content .= $handler->render(new ControllerReference('TestBundle:SubRequest:fragment')); + + // forces the LocaleListener to set fr for the locale... + // should render fr/json + $content .= $handler->render($altUrl); + + // ...and check that after the rendering, the original Request is back + // and en is used as a locale + // should use en/html instead of fr/json + $content .= '--'.$this->generateUrl('subrequest_fragment'); + + // The RouterListener is also tested as if it does not keep the right + // Request in the context, a 301 would be generated + + return new Response($content); + } + + public function fragmentAction(Request $request) + { + return new Response('--'.$request->getLocale().'/'.$request->getRequestFormat()); + } + + public function fragmentErrorAction() + { + throw new \RuntimeException('error'); + } + + protected function generateUrl($name, $arguments = array()) + { + return $this->container->get('router')->generate($name, $arguments); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Resources/config/routing.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Resources/config/routing.yml index d9b380ef8dbd1..6a9f5a8f8be47 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Resources/config/routing.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Resources/config/routing.yml @@ -21,3 +21,18 @@ session_showflash: profiler: path: /profiler defaults: { _controller: TestBundle:Profiler:index } + +subrequest_index: + path: /subrequest/{_locale}.{_format} + defaults: { _controller: TestBundle:SubRequest:index, _format: "html" } + schemes: [https] + +subrequest_fragment_error: + path: /subrequest/fragment/error/{_locale}.{_format} + defaults: { _controller: TestBundle:SubRequest:fragmentError, _format: "html" } + schemes: [http] + +subrequest_fragment: + path: /subrequest/fragment/{_locale}.{_format} + defaults: { _controller: TestBundle:SubRequest:fragment, _format: "html" } + schemes: [http] diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SubRequestsTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SubRequestsTest.php new file mode 100644 index 0000000000000..2676653b1ef6d --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SubRequestsTest.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Functional; + +/** + * @group functional + */ +class SubRequestsTest extends WebTestCase +{ + public function testStateAfterSubRequest() + { + $client = $this->createClient(array('test_case' => 'Session', 'root_config' => 'config.yml')); + $client->request('GET', 'https://localhost/subrequest/en'); + + $this->assertEquals('--fr/json--en/html--fr/json--http://localhost/subrequest/fragment/en', $client->getResponse()->getContent()); + } +} diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php index 6fad9a2841651..93d5806036bde 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php @@ -88,9 +88,7 @@ private function processArguments(array $arguments, $inMethodCall = false) $exists = $this->container->has($id); // resolve invalid behavior - if ($exists && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) { - $arguments[$k] = new Reference($id, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, $argument->isStrict()); - } elseif (!$exists && ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) { + if (!$exists && ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) { $arguments[$k] = null; } elseif (!$exists && ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $invalidBehavior) { if ($inMethodCall) { diff --git a/src/Symfony/Component/DependencyInjection/Container.php b/src/Symfony/Component/DependencyInjection/Container.php index 8a2c1b3a1ed91..be72e8fc686a5 100644 --- a/src/Symfony/Component/DependencyInjection/Container.php +++ b/src/Symfony/Component/DependencyInjection/Container.php @@ -11,6 +11,7 @@ namespace Symfony\Component\DependencyInjection; +use Symfony\Component\DependencyInjection\Exception\InactiveScopeException; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; @@ -206,6 +207,10 @@ public function set($id, $service, $scope = self::SCOPE_CONTAINER) } $this->services[$id] = $service; + + if (method_exists($this, $method = 'synchronize'.strtr($id, array('_' => '', '.' => '_')).'Service')) { + $this->$method(); + } } /** @@ -221,7 +226,7 @@ public function has($id) { $id = strtolower($id); - return isset($this->services[$id]) || method_exists($this, 'get'.strtr($id, array('_' => '', '.' => '_')).'Service'); + return array_key_exists($id, $this->services) || method_exists($this, 'get'.strtr($id, array('_' => '', '.' => '_')).'Service'); } /** @@ -247,7 +252,7 @@ public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE { $id = strtolower($id); - if (isset($this->services[$id])) { + if (array_key_exists($id, $this->services)) { return $this->services[$id]; } @@ -263,10 +268,14 @@ public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE } catch (\Exception $e) { unset($this->loading[$id]); - if (isset($this->services[$id])) { + if (array_key_exists($id, $this->services)) { unset($this->services[$id]); } + if ($e instanceof InactiveScopeException && self::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) { + return null; + } + throw $e; } @@ -289,7 +298,7 @@ public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE */ public function initialized($id) { - return isset($this->services[strtolower($id)]); + return array_key_exists(strtolower($id), $this->services); } /** @@ -393,8 +402,11 @@ public function leaveScope($name) $services = $this->scopeStacks[$name]->pop(); $this->scopedServices += $services; - array_unshift($services, $this->services); - $this->services = call_user_func_array('array_merge', $services); + foreach ($services as $array) { + foreach ($array as $id => $service) { + $this->set($id, $service, $name); + } + } } } diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 5b178714bffee..39c6b0362e5b0 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -46,6 +46,11 @@ class ContainerBuilder extends Container implements TaggedContainerInterface */ private $definitions = array(); + /** + * @var Definition[] + */ + private $obsoleteDefinitions = array(); + /** * @var Alias[] */ @@ -351,14 +356,28 @@ public function set($id, $service, $scope = self::SCOPE_CONTAINER) if ($this->isFrozen()) { // setting a synthetic service on a frozen container is alright - if (!isset($this->definitions[$id]) || !$this->definitions[$id]->isSynthetic()) { + if ( + (!isset($this->definitions[$id]) && !isset($this->obsoleteDefinitions[$id])) + || + (isset($this->definitions[$id]) && !$this->definitions[$id]->isSynthetic()) + || + (isset($this->obsoleteDefinitions[$id]) && !$this->obsoleteDefinitions[$id]->isSynthetic()) + ) { throw new BadMethodCallException(sprintf('Setting service "%s" on a frozen container is not allowed.', $id)); } } + if (isset($this->definitions[$id])) { + $this->obsoleteDefinitions[$id] = $this->definitions[$id]; + } + unset($this->definitions[$id], $this->aliases[$id]); parent::set($id, $service, $scope); + + if (isset($this->obsoleteDefinitions[$id]) && $this->obsoleteDefinitions[$id]->isSynchronized()) { + $this->synchronize($id); + } } /** @@ -885,19 +904,7 @@ private function createService(Definition $definition, $id) } foreach ($definition->getMethodCalls() as $call) { - $services = self::getServiceConditionals($call[1]); - - $ok = true; - foreach ($services as $s) { - if (!$this->has($s)) { - $ok = false; - break; - } - } - - if ($ok) { - call_user_func_array(array($service, $call[0]), $this->resolveServices($parameterBag->resolveValue($call[1]))); - } + $this->callMethod($service, $call); } $properties = $this->resolveServices($parameterBag->resolveValue($definition->getProperties())); @@ -999,4 +1006,43 @@ public static function getServiceConditionals($value) return $services; } + + /** + * Synchronizes a service change. + * + * This method updates all services that depend on the given + * service by calling all methods referencing it. + * + * @param string $id A service id + */ + private function synchronize($id) + { + foreach ($this->definitions as $definitionId => $definition) { + // only check initialized services + if (!$this->initialized($definitionId)) { + continue; + } + + foreach ($definition->getMethodCalls() as $call) { + foreach ($call[1] as $argument) { + if ($argument instanceof Reference && $id == (string) $argument) { + $this->callMethod($this->get($definitionId), $call); + } + } + } + } + } + + private function callMethod($service, $call) + { + $services = self::getServiceConditionals($call[1]); + + foreach ($services as $s) { + if (!$this->has($s)) { + return; + } + } + + call_user_func_array(array($service, $call[0]), $this->resolveServices($this->getParameterBag()->resolveValue($call[1]))); + } } diff --git a/src/Symfony/Component/DependencyInjection/Definition.php b/src/Symfony/Component/DependencyInjection/Definition.php index 359553a0bf469..9d52426121874 100644 --- a/src/Symfony/Component/DependencyInjection/Definition.php +++ b/src/Symfony/Component/DependencyInjection/Definition.php @@ -36,6 +36,7 @@ class Definition private $public; private $synthetic; private $abstract; + private $synchronized; protected $arguments; @@ -56,6 +57,7 @@ public function __construct($class = null, array $arguments = array()) $this->tags = array(); $this->public = true; $this->synthetic = false; + $this->synchronized = false; $this->abstract = false; $this->properties = array(); } @@ -569,6 +571,34 @@ public function isPublic() return $this->public; } + /** + * Sets the synchronized flag of this service. + * + * @param Boolean $boolean + * + * @return Definition The current instance + * + * @api + */ + public function setSynchronized($boolean) + { + $this->synchronized = (Boolean) $boolean; + + return $this; + } + + /** + * Whether this service is synchronized. + * + * @return Boolean + * + * @api + */ + public function isSynchronized() + { + return $this->synchronized; + } + /** * Sets whether this definition is synthetic, that is not constructed by the * container, but dynamically injected. diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 4d66d05c154be..52f80b656d8c8 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -567,7 +567,7 @@ protected function get{$name}Service() */ private function addServices() { - $publicServices = $privateServices = $aliasServices = ''; + $publicServices = $privateServices = $aliasServices = $synchronizers = ''; $definitions = $this->container->getDefinitions(); ksort($definitions); foreach ($definitions as $id => $definition) { @@ -576,6 +576,8 @@ private function addServices() } else { $privateServices .= $this->addService($id, $definition); } + + $synchronizers .= $this->addServiceSynchronizer($id, $definition); } $aliases = $this->container->getAliases(); @@ -584,7 +586,60 @@ private function addServices() $aliasServices .= $this->addServiceAlias($alias, $id); } - return $publicServices.$aliasServices.$privateServices; + return $publicServices.$aliasServices.$synchronizers.$privateServices; + } + + /** + * Adds synchronizer methods. + * + * @param string $id A service identifier + * @param Definition $definition A Definition instance + */ + private function addServiceSynchronizer($id, Definition $definition) + { + if (!$definition->isSynchronized()) { + return; + } + + $code = ''; + foreach ($this->container->getDefinitions() as $definitionId => $definition) { + foreach ($definition->getMethodCalls() as $call) { + foreach ($call[1] as $argument) { + if ($argument instanceof Reference && $id == (string) $argument) { + $arguments = array(); + foreach ($call[1] as $value) { + $arguments[] = $this->dumpValue($value); + } + + $call = $this->wrapServiceConditionals($call[1], sprintf("\$this->get('%s')->%s(%s);", $definitionId, $call[0], implode(', ', $arguments))); + + $code .= <<initialized('$definitionId')) { + $call + } + +EOF; + } + } + } + } + + if (!$code) { + return; + } + + $name = Container::camelize($id); + + return <<isPublic()) { $service->setAttribute('public', 'false'); } + if ($definition->isSynthetic()) { + $service->setAttribute('synthetic', 'true'); + } + if ($definition->isSynchronized()) { + $service->setAttribute('synchronized', 'true'); + } foreach ($definition->getTags() as $name => $tags) { foreach ($tags as $attributes) { @@ -239,6 +245,9 @@ private function convertParameters($parameters, $type, \DOMElement $parent, $key } elseif ($behaviour == ContainerInterface::IGNORE_ON_INVALID_REFERENCE) { $element->setAttribute('on-invalid', 'ignore'); } + if (!$value->isStrict()) { + $element->setAttribute('strict', 'false'); + } } elseif ($value instanceof Definition) { $element->setAttribute('type', 'service'); $this->addService($value, null, $element); diff --git a/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php index e4e168257e4e6..98903bf77b5db 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php @@ -94,6 +94,14 @@ private function addService($id, $definition) $code .= sprintf(" file: %s\n", $definition->getFile()); } + if ($definition->isSynthetic()) { + $code .= sprintf(" synthetic: true\n"); + } + + if ($definition->isSynchronized()) { + $code .= sprintf(" synchronized: true\n"); + } + if ($definition->getFactoryMethod()) { $code .= sprintf(" factory_method: %s\n", $definition->getFactoryMethod()); } diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php index f925f78ab27e1..85898d3d3fe86 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php @@ -148,7 +148,7 @@ private function parseDefinition($id, $service, $file) $definition = new Definition(); } - foreach (array('class', 'scope', 'public', 'factory-class', 'factory-method', 'factory-service', 'synthetic', 'abstract') as $key) { + foreach (array('class', 'scope', 'public', 'factory-class', 'factory-method', 'factory-service', 'synthetic', 'synchronized', 'abstract') as $key) { if (isset($service[$key])) { $method = 'set'.str_replace('-', '', $key); $definition->$method((string) $service->getAttributeAsPhp($key)); diff --git a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php index 71de4ac6592f6..423ca15d45184 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php @@ -153,6 +153,10 @@ private function parseDefinition($id, $service, $file) $definition->setSynthetic($service['synthetic']); } + if (isset($service['synchronized'])) { + $definition->setSynchronized($service['synchronized']); + } + if (isset($service['public'])) { $definition->setPublic($service['public']); } diff --git a/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd b/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd index 316f2d7596870..4d9addcd971f8 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd +++ b/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd @@ -86,6 +86,7 @@ + diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index bfd92798dc4c1..af0181ecc1f1b 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -22,6 +22,7 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\DependencyInjection\Scope; use Symfony\Component\Config\Resource\FileResource; class ContainerBuilderTest extends \PHPUnit_Framework_TestCase @@ -577,6 +578,52 @@ public function testNoExceptionWhenSetSyntheticServiceOnAFrozenContainer() $this->assertEquals($a, $container->get('a')); } + public function testSetOnSynchronizedService() + { + $container = new ContainerBuilder(); + $container->register('baz', 'BazClass') + ->setSynchronized(true) + ; + $container->register('bar', 'BarClass') + ->addMethodCall('setBaz', array(new Reference('baz'))) + ; + + $container->set('baz', $baz = new \BazClass()); + $this->assertSame($baz, $container->get('bar')->getBaz()); + + $container->set('baz', $baz = new \BazClass()); + $this->assertSame($baz, $container->get('bar')->getBaz()); + } + + public function testSynchronizedServiceWithScopes() + { + $container = new ContainerBuilder(); + $container->addScope(new Scope('foo')); + $container->register('baz', 'BazClass') + ->setSynthetic(true) + ->setSynchronized(true) + ->setScope('foo') + ; + $container->register('bar', 'BarClass') + ->addMethodCall('setBaz', array(new Reference('baz', ContainerInterface::NULL_ON_INVALID_REFERENCE, false))) + ; + $container->compile(); + + $container->enterScope('foo'); + $container->set('baz', $outerBaz = new \BazClass(), 'foo'); + $this->assertSame($outerBaz, $container->get('bar')->getBaz()); + + $container->enterScope('foo'); + $container->set('baz', $innerBaz = new \BazClass(), 'foo'); + $this->assertSame($innerBaz, $container->get('bar')->getBaz()); + $container->leaveScope('foo'); + + $this->assertNotSame($innerBaz, $container->get('bar')->getBaz()); + $this->assertSame($outerBaz, $container->get('bar')->getBaz()); + + $container->leaveScope('foo'); + } + /** * @expectedException BadMethodCallException */ diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php index 23c13c5094cb5..726af13904cc7 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php @@ -15,6 +15,7 @@ use Symfony\Component\DependencyInjection\Container; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\DependencyInjection\Exception\InactiveScopeException; class ContainerTest extends \PHPUnit_Framework_TestCase { @@ -98,7 +99,7 @@ public function testGetServiceIds() $this->assertEquals(array('service_container', 'foo', 'bar'), $sc->getServiceIds(), '->getServiceIds() returns all defined service ids'); $sc = new ProjectServiceContainer(); - $this->assertEquals(array('scoped', 'scoped_foo', 'bar', 'foo_bar', 'foo.baz', 'circular', 'throw_exception', 'throws_exception_on_service_configuration', 'service_container'), $sc->getServiceIds(), '->getServiceIds() returns defined service ids by getXXXService() methods'); + $this->assertEquals(array('scoped', 'scoped_foo', 'inactive', 'bar', 'foo_bar', 'foo.baz', 'circular', 'throw_exception', 'throws_exception_on_service_configuration', 'service_container'), $sc->getServiceIds(), '->getServiceIds() returns defined service ids by getXXXService() methods'); } /** @@ -179,6 +180,15 @@ public function testGetCircularReference() } } + /** + * @covers Symfony\Component\DependencyInjection\Container::get + */ + public function testGetReturnsNullOnInactiveScope() + { + $sc = new ProjectServiceContainer(); + $this->assertNull($sc->get('inactive', ContainerInterface::NULL_ON_INVALID_REFERENCE)); + } + /** * @covers Symfony\Component\DependencyInjection\Container::has */ @@ -476,6 +486,11 @@ protected function getScopedFooService() return $this->services['scoped_foo'] = $this->scopedServices['foo']['scoped_foo'] = new \stdClass(); } + protected function getInactiveService() + { + throw new InactiveScopeException('request', 'request'); + } + protected function getBarService() { return $this->__bar; diff --git a/src/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php b/src/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php index 89f7ae1ea0ad0..d9a4282efefbc 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php @@ -149,7 +149,19 @@ public function testSetIsSynthetic() $def = new Definition('stdClass'); $this->assertFalse($def->isSynthetic(), '->isSynthetic() returns false by default'); $this->assertSame($def, $def->setSynthetic(true), '->setSynthetic() implements a fluent interface'); - $this->assertTrue($def->isSynthetic(), '->isSynthetic() returns true if the instance must not be public.'); + $this->assertTrue($def->isSynthetic(), '->isSynthetic() returns true if the service is synthetic.'); + } + + /** + * @covers Symfony\Component\DependencyInjection\Definition::setSynchronized + * @covers Symfony\Component\DependencyInjection\Definition::isSynchronized + */ + public function testSetIsSynchronized() + { + $def = new Definition('stdClass'); + $this->assertFalse($def->isSynchronized(), '->isSynchronized() returns false by default'); + $this->assertSame($def, $def->setSynchronized(true), '->setSynchronized() implements a fluent interface'); + $this->assertTrue($def->isSynchronized(), '->isSynchronized() returns true if the service is synchronized.'); } /** diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php index 71d29f209bfcb..6ba3ad349d5d8 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php @@ -71,5 +71,14 @@ ->register('baz', 'Baz') ->addMethodCall('setFoo', array(new Reference('foo_with_inline'))) ; +$container + ->register('request', 'Request') + ->setSynthetic(true) + ->setSynchronized(true) +; +$container + ->register('depends_on_request', 'stdClass') + ->addMethodCall('setRequest', array(new Reference('request', ContainerInterface::NULL_ON_INVALID_REFERENCE, false))) +; 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 73608e27fc912..cb006641d0b13 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot @@ -12,6 +12,8 @@ digraph sc { node_foo_with_inline [label="foo_with_inline\nFoo\n", shape=record, fillcolor="#eeeeee", style="filled"]; node_inlined [label="inlined\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"]; node_baz [label="baz\nBaz\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_request [label="request\nRequest\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_depends_on_request [label="depends_on_request\nstdClass\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"]; @@ -28,4 +30,5 @@ digraph sc { node_foo_with_inline -> node_inlined [label="setBar()" style="dashed"]; node_inlined -> node_baz [label="setBaz()" style="dashed"]; node_baz -> node_foo_with_inline [label="setFoo()" style="dashed"]; + node_depends_on_request -> node_request [label="setRequest()" style="dashed"]; } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php index fb6d4cf19d5c5..48e1c2c84e12d 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php @@ -13,6 +13,11 @@ public function setBaz(BazClass $baz) { $this->baz = $baz; } + + public function getBaz() + { + return $this->baz; + } } class BazClass diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php index 324b77f66c7fb..4aad5e6e9e506 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php @@ -60,6 +60,23 @@ protected function getBazService() return $instance; } + /** + * Gets the 'depends_on_request' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return stdClass A stdClass instance. + */ + protected function getDependsOnRequestService() + { + $this->services['depends_on_request'] = $instance = new \stdClass(); + + $instance->setRequest($this->get('request', ContainerInterface::NULL_ON_INVALID_REFERENCE)); + + return $instance; + } + /** * Gets the 'factory_service' service. * @@ -168,6 +185,19 @@ protected function getMethodCall1Service() return $instance; } + /** + * Gets the 'request' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @throws RuntimeException always since this service is expected to be injected dynamically + */ + protected function getRequestService() + { + throw new RuntimeException('You have requested a synthetic service ("request"). The DIC does not know how to construct this service.'); + } + /** * Gets the alias_for_foo service alias. * @@ -178,6 +208,16 @@ protected function getAliasForFooService() return $this->get('foo'); } + /** + * Updates the 'request' service. + */ + protected function synchronizeRequestService() + { + if ($this->initialized('depends_on_request')) { + $this->get('depends_on_request')->setRequest($this->get('request', ContainerInterface::NULL_ON_INVALID_REFERENCE)); + } + } + /** * 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 5c71db9e66aba..2deea119f47fc 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php @@ -69,6 +69,23 @@ protected function getBazService() return $instance; } + /** + * Gets the 'depends_on_request' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return stdClass A stdClass instance. + */ + protected function getDependsOnRequestService() + { + $this->services['depends_on_request'] = $instance = new \stdClass(); + + $instance->setRequest($this->get('request', ContainerInterface::NULL_ON_INVALID_REFERENCE)); + + return $instance; + } + /** * Gets the 'factory_service' service. * @@ -174,6 +191,19 @@ protected function getMethodCall1Service() return $instance; } + /** + * Gets the 'request' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @throws RuntimeException always since this service is expected to be injected dynamically + */ + protected function getRequestService() + { + throw new RuntimeException('You have requested a synthetic service ("request"). The DIC does not know how to construct this service.'); + } + /** * Gets the alias_for_foo service alias. * @@ -184,6 +214,16 @@ protected function getAliasForFooService() return $this->get('foo'); } + /** + * Updates the 'request' service. + */ + protected function synchronizeRequestService() + { + if ($this->initialized('depends_on_request')) { + $this->get('depends_on_request')->setRequest($this->get('request', ContainerInterface::NULL_ON_INVALID_REFERENCE)); + } + } + /** * {@inheritdoc} */ diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services6.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services6.xml index 45bc042f61906..4d2aa3d79ae24 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services6.xml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services6.xml @@ -46,5 +46,6 @@ + diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml index 58eb6d79a3c1e..d04d492e8d824 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml @@ -67,6 +67,12 @@ + + + + + + diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services6.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services6.yml index eaa52bda62065..820c364a06556 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services6.yml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services6.yml @@ -24,3 +24,7 @@ services: alias: foo public: false factory_service: { class: BazClass, factory_method: getInstance, factory_service: baz_factory } + request: + class: Request + synthetic: true + synchronized: true diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml index fcbb83f4ae7e1..3d9c6417812f1 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml @@ -57,4 +57,13 @@ services: calls: - [setFoo, ['@foo_with_inline']] + request: + class: Request + synthetic: true + synchronized: true + depends_on_request: + class: stdClass + calls: + - [setRequest, ['@?request']] + alias_for_foo: @foo diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php index 0287a1b0aa334..b355f0ac215c3 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php @@ -185,6 +185,9 @@ public function testLoadServices() $this->assertEquals('getInstance', $services['factory_service']->getFactoryMethod()); $this->assertEquals('baz_factory', $services['factory_service']->getFactoryService()); + $this->assertTrue($services['request']->isSynthetic(), '->load() parses the synthetic flag'); + $this->assertTrue($services['request']->isSynchronized(), '->load() parses the synchronized flag'); + $aliases = $container->getAliases(); $this->assertTrue(isset($aliases['alias_for_foo']), '->load() parses elements'); $this->assertEquals('foo', (string) $aliases['alias_for_foo'], '->load() parses aliases'); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php index e655d3bd8981a..1c700df7b5b9d 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php @@ -128,6 +128,9 @@ public function testLoadServices() $this->assertEquals(array(array('setBar', array('foo', new Reference('foo'), array(true, false)))), $services['method_call2']->getMethodCalls(), '->load() parses the method_call tag'); $this->assertEquals('baz_factory', $services['factory_service']->getFactoryService()); + $this->assertTrue($services['request']->isSynthetic(), '->load() parses the synthetic flag'); + $this->assertTrue($services['request']->isSynchronized(), '->load() parses the synchronized flag'); + $aliases = $container->getAliases(); $this->assertTrue(isset($aliases['alias_for_foo']), '->load() parses aliases'); $this->assertEquals('foo', (string) $aliases['alias_for_foo'], '->load() parses aliases'); diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php b/src/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php index 20b4a5e75e9ad..0aae26b483504 100644 --- a/src/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php +++ b/src/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php @@ -56,11 +56,13 @@ public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQ try { $response = parent::handle($request, $type, $catch); } catch (\Exception $e) { + $this->container->set('request', null, 'request'); $this->container->leaveScope('request'); throw $e; } + $this->container->set('request', null, 'request'); $this->container->leaveScope('request'); return $response; diff --git a/src/Symfony/Component/HttpKernel/EventListener/LocaleListener.php b/src/Symfony/Component/HttpKernel/EventListener/LocaleListener.php index f3cb804832660..0b864c02f2bc4 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/LocaleListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/LocaleListener.php @@ -12,7 +12,6 @@ namespace Symfony\Component\HttpKernel\EventListener; use Symfony\Component\HttpKernel\Event\GetResponseEvent; -use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\RequestContextAwareInterface; @@ -27,7 +26,6 @@ class LocaleListener implements EventSubscriberInterface { private $router; private $defaultLocale; - private $locales = array(); public function __construct($defaultLocale = 'en', RequestContextAwareInterface $router = null) { @@ -35,24 +33,27 @@ public function __construct($defaultLocale = 'en', RequestContextAwareInterface $this->router = $router; } - public function onKernelResponse(FilterResponseEvent $event) + public function setRequest(Request $request = null) { - array_shift($this->locales); + if (null === $request) { + return; + } - // setting back the locale to the previous value - $locale = isset($this->locales[0]) ? $this->locales[0] : $this->defaultLocale; - $request = $event->getRequest(); - $this->setLocale($request, $locale); + if ($locale = $request->attributes->get('_locale')) { + $request->setLocale($locale); + } + + if (null !== $this->router) { + $this->router->getContext()->setParameter('_locale', $request->getLocale()); + } } public function onKernelRequest(GetResponseEvent $event) { $request = $event->getRequest(); - $request->setDefaultLocale($this->defaultLocale); - $this->setLocale($request, $request->attributes->get('_locale', $this->defaultLocale)); - array_unshift($this->locales, $request->getLocale()); + $this->setRequest($request); } public static function getSubscribedEvents() @@ -60,16 +61,6 @@ public static function getSubscribedEvents() return array( // must be registered after the Router to have access to the _locale KernelEvents::REQUEST => array(array('onKernelRequest', 16)), - KernelEvents::RESPONSE => 'onKernelResponse', ); } - - private function setLocale(Request $request, $locale) - { - $request->setLocale($locale); - - if (null !== $this->router) { - $this->router->getContext()->setParameter('_locale', $request->getLocale()); - } - } } diff --git a/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php b/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php index 606b358e72f04..58ea6f0a5436d 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php @@ -23,6 +23,7 @@ use Symfony\Component\Routing\RequestContext; use Symfony\Component\Routing\RequestContextAwareInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpFoundation\Request; /** * Initializes the context from the request and sets request attributes based on a matching route. @@ -59,12 +60,31 @@ public function __construct($matcher, RequestContext $context = null, LoggerInte $this->logger = $logger; } + /** + * Sets the current Request. + * + * The application should call this method whenever the Request + * object changes (entering a Request scope for instance, but + * also when leaving a Request scope -- especially when they are + * nested). + * + * @param Request|null $request A Request instance + */ + public function setRequest(Request $request = null) + { + if (null !== $request) { + $this->context->fromRequest($request); + } + } + public function onKernelRequest(GetResponseEvent $event) { $request = $event->getRequest(); // initialize the context that is also used by the generator (assuming matcher and generator share the same context instance) - $this->context->fromRequest($request); + // we call setRequest even if most of the time, it has already been done to keep compatibility + // with frameworks which do not use the Symfony service container + $this->setRequest($request); if ($request->attributes->has('_controller')) { // routing is already done diff --git a/src/Symfony/Component/HttpKernel/Fragment/FragmentHandler.php b/src/Symfony/Component/HttpKernel/Fragment/FragmentHandler.php index b4f3f9c1eef47..54d0a70b7dbec 100644 --- a/src/Symfony/Component/HttpKernel/Fragment/FragmentHandler.php +++ b/src/Symfony/Component/HttpKernel/Fragment/FragmentHandler.php @@ -15,10 +15,6 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpKernel\Controller\ControllerReference; -use Symfony\Component\HttpKernel\KernelEvents; -use Symfony\Component\HttpKernel\Event\GetResponseEvent; -use Symfony\Component\HttpKernel\Event\FilterResponseEvent; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** * Renders a URI that represents a resource fragment. @@ -30,11 +26,11 @@ * * @see FragmentRendererInterface */ -class FragmentHandler implements EventSubscriberInterface +class FragmentHandler { private $debug; private $renderers; - private $requests; + private $request; /** * Constructor. @@ -49,7 +45,6 @@ public function __construct(array $renderers = array(), $debug = false) $this->addRenderer($renderer); } $this->debug = $debug; - $this->requests = array(); } /** @@ -63,23 +58,13 @@ public function addRenderer(FragmentRendererInterface $renderer) } /** - * Stores the Request object. + * Sets the current Request. * - * @param GetResponseEvent $event A GetResponseEvent instance + * @param Request $request The current Request */ - public function onKernelRequest(GetResponseEvent $event) + public function setRequest(Request $request = null) { - array_unshift($this->requests, $event->getRequest()); - } - - /** - * Removes the most recent Request object. - * - * @param FilterResponseEvent $event A FilterResponseEvent instance - */ - public function onKernelResponse(FilterResponseEvent $event) - { - array_shift($this->requests); + $this->request = $request; } /** @@ -108,7 +93,11 @@ public function render($uri, $renderer = 'inline', array $options = array()) throw new \InvalidArgumentException(sprintf('The "%s" renderer does not exist.', $renderer)); } - return $this->deliver($this->renderers[$renderer]->render($uri, $this->requests[0], $options)); + if (null === $this->request) { + throw new \LogicException('Rendering a fragment can only be done when handling a master Request.'); + } + + return $this->deliver($this->renderers[$renderer]->render($uri, $this->request, $options)); } /** @@ -126,7 +115,7 @@ public function render($uri, $renderer = 'inline', array $options = array()) protected function deliver(Response $response) { if (!$response->isSuccessful()) { - throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $this->requests[0]->getUri(), $response->getStatusCode())); + throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $this->request->getUri(), $response->getStatusCode())); } if (!$response instanceof StreamedResponse) { @@ -136,14 +125,6 @@ protected function deliver(Response $response) $response->sendContent(); } - public static function getSubscribedEvents() - { - return array( - KernelEvents::REQUEST => 'onKernelRequest', - KernelEvents::RESPONSE => 'onKernelResponse', - ); - } - // to be removed in 2.3 public function fixOptions(array $options) { diff --git a/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/ContainerAwareHttpKernelTest.php b/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/ContainerAwareHttpKernelTest.php index 80d5ffa61a664..6da06c01d1544 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/ContainerAwareHttpKernelTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/ContainerAwareHttpKernelTest.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Symfony\Component\HttpKernel\Tests; +namespace Symfony\Component\HttpKernel\Tests\DependencyInjection; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel; @@ -54,10 +54,15 @@ public function testHandle($type) ->with($this->equalTo('request')) ; $container - ->expects($this->once()) + ->expects($this->at(1)) ->method('set') ->with($this->equalTo('request'), $this->equalTo($request), $this->equalTo('request')) ; + $container + ->expects($this->at(2)) + ->method('set') + ->with($this->equalTo('request'), $this->equalTo(null), $this->equalTo('request')) + ; $dispatcher = new EventDispatcher(); $resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface'); @@ -101,10 +106,15 @@ public function testHandleRestoresThePreviousRequestOnException($type) ->with($this->equalTo('request')) ; $container - ->expects($this->once()) + ->expects($this->at(1)) ->method('set') ->with($this->equalTo('request'), $this->equalTo($request), $this->equalTo('request')) ; + $container + ->expects($this->at(2)) + ->method('set') + ->with($this->equalTo('request'), $this->equalTo(null), $this->equalTo('request')) + ; $dispatcher = new EventDispatcher(); $resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface'); diff --git a/src/Symfony/Component/HttpKernel/Tests/Fragment/FragmentHandlerTest.php b/src/Symfony/Component/HttpKernel/Tests/Fragment/FragmentHandlerTest.php index e0a5b0ad59342..f2a0838a46424 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Fragment/FragmentHandlerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Fragment/FragmentHandlerTest.php @@ -17,13 +17,6 @@ class FragmentHandlerTest extends \PHPUnit_Framework_TestCase { - protected function setUp() - { - if (!class_exists('Symfony\Component\EventDispatcher\EventDispatcher')) { - $this->markTestSkipped('The "EventDispatcher" component is not available'); - } - } - /** * @expectedException \InvalidArgumentException */ @@ -102,14 +95,7 @@ protected function getHandler($returnValue, $arguments = array()) $handler = new FragmentHandler(); $handler->addRenderer($renderer); - - $event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock(); - $event - ->expects($this->once()) - ->method('getRequest') - ->will($this->returnValue(Request::create('/'))) - ; - $handler->onKernelRequest($event); + $handler->setRequest(Request::create('/')); return $handler; }