From e620cbfce225a1b459ae5e1ff01e5ff8f8db94fd Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 10 Jan 2015 23:10:57 +0100 Subject: [PATCH 1/3] lazy-load fragment renderers --- .../Compiler/FragmentRendererPass.php | 4 + .../FrameworkBundle/FrameworkBundle.php | 2 +- .../Resources/config/fragment_renderer.xml | 12 +- .../LegacyFragmentRendererPassTest.php | 114 ++++++++++++++++++ .../FragmentRendererPass.php | 73 +++++++++++ .../LazyLoadingFragmentHandler.php | 58 +++++++++ .../FragmentRendererPassTest.php | 24 ++-- .../LazyLoadingFragmentHandlerTest.php | 40 ++++++ 8 files changed, 309 insertions(+), 18 deletions(-) create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/LegacyFragmentRendererPassTest.php create mode 100644 src/Symfony/Component/HttpKernel/DependencyInjection/FragmentRendererPass.php create mode 100644 src/Symfony/Component/HttpKernel/DependencyInjection/LazyLoadingFragmentHandler.php rename src/Symfony/{Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler => Component/HttpKernel/Tests/DependencyInjection}/FragmentRendererPassTest.php (79%) create mode 100644 src/Symfony/Component/HttpKernel/Tests/DependencyInjection/LazyLoadingFragmentHandlerTest.php diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/FragmentRendererPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/FragmentRendererPass.php index e3284ab45c..66c3caa6a9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/FragmentRendererPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/FragmentRendererPass.php @@ -11,6 +11,8 @@ namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler; +trigger_error('The '.__NAMESPACE__.'\FragmentRendererPass class is deprecated since version 2.7 and will be removed in 3.0. Use Symfony\Component\HttpKernel\DependencyInjection\FragmentRendererPass instead.', E_USER_DEPRECATED); + use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; @@ -19,6 +21,8 @@ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; * Adds services tagged kernel.fragment_renderer as HTTP content rendering strategies. * * @author Fabien Potencier + * + * @deprecated since version 2.7, to be removed in 3.0. Use Symfony\Component\HttpKernel\DependencyInjection\FragmentRendererPass instead. */ class FragmentRendererPass implements CompilerPassInterface { diff --git a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php index 10896786c9..5ddc397560 100644 --- a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php +++ b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php @@ -28,13 +28,13 @@ use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ContainerBuilder use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CompilerDebugDumpPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslationExtractorPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslationDumperPass; -use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\FragmentRendererPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\SerializerPass; use Symfony\Component\Debug\ErrorHandler; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\PassConfig; use Symfony\Component\DependencyInjection\Scope; use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass; +use Symfony\Component\HttpKernel\DependencyInjection\FragmentRendererPass; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Bundle\Bundle; diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/fragment_renderer.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/fragment_renderer.xml index e542c6ea32..7ac0d68dc9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/fragment_renderer.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/fragment_renderer.xml @@ -5,7 +5,7 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - Symfony\Component\HttpKernel\Fragment\FragmentHandler + Symfony\Component\HttpKernel\DependencyInjection\LazyLoadingFragmentHandler Symfony\Component\HttpKernel\Fragment\InlineFragmentRenderer Symfony\Bundle\FrameworkBundle\Fragment\ContainerAwareHIncludeFragmentRenderer @@ -15,20 +15,20 @@ - + %kernel.debug% - + %fragment.path% - + %fragment.renderer.hinclude.global_template% @@ -36,7 +36,7 @@ - + @@ -44,7 +44,7 @@ - + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/LegacyFragmentRendererPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/LegacyFragmentRendererPassTest.php new file mode 100644 index 0000000000..3ddea4f4c6 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/LegacyFragmentRendererPassTest.php @@ -0,0 +1,114 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\FragmentRendererPass; + +class LegacyFragmentRendererPassTest extends \PHPUnit_Framework_TestCase +{ + public function setUp() + { + $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED); + } + + /** + * Tests that content rendering not implementing FragmentRendererInterface + * trigger an exception. + * + * @expectedException \InvalidArgumentException + */ + public function testContentRendererWithoutInterface() + { + // one service, not implementing any interface + $services = array( + 'my_content_renderer' => array(), + ); + + $definition = $this->getMock('Symfony\Component\DependencyInjection\Definition'); + $definition->expects($this->atLeastOnce()) + ->method('getClass') + ->will($this->returnValue('stdClass')); + + $builder = $this->getMock( + 'Symfony\Component\DependencyInjection\ContainerBuilder', + array('hasDefinition', 'findTaggedServiceIds', 'getDefinition') + ); + $builder->expects($this->any()) + ->method('hasDefinition') + ->will($this->returnValue(true)); + + // We don't test kernel.fragment_renderer here + $builder->expects($this->atLeastOnce()) + ->method('findTaggedServiceIds') + ->will($this->returnValue($services)); + + $builder->expects($this->atLeastOnce()) + ->method('getDefinition') + ->will($this->returnValue($definition)); + + $pass = new FragmentRendererPass(); + $pass->process($builder); + } + + public function testValidContentRenderer() + { + $services = array( + 'my_content_renderer' => array(), + ); + + $renderer = $this->getMock('Symfony\Component\DependencyInjection\Definition'); + $renderer + ->expects($this->once()) + ->method('addMethodCall') + ->with('addRenderer', array(new Reference('my_content_renderer'))) + ; + + $definition = $this->getMock('Symfony\Component\DependencyInjection\Definition'); + $definition->expects($this->atLeastOnce()) + ->method('getClass') + ->will($this->returnValue('Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler\RendererService')); + + $builder = $this->getMock( + 'Symfony\Component\DependencyInjection\ContainerBuilder', + array('hasDefinition', 'findTaggedServiceIds', 'getDefinition') + ); + $builder->expects($this->any()) + ->method('hasDefinition') + ->will($this->returnValue(true)); + + // We don't test kernel.fragment_renderer here + $builder->expects($this->atLeastOnce()) + ->method('findTaggedServiceIds') + ->will($this->returnValue($services)); + + $builder->expects($this->atLeastOnce()) + ->method('getDefinition') + ->will($this->onConsecutiveCalls($renderer, $definition)); + + $pass = new FragmentRendererPass(); + $pass->process($builder); + } +} + +class RendererService implements \Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface +{ + public function render($uri, Request $request = null, array $options = array()) + { + } + + public function getName() + { + return 'test'; + } +} diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/FragmentRendererPass.php b/src/Symfony/Component/HttpKernel/DependencyInjection/FragmentRendererPass.php new file mode 100644 index 0000000000..5a2f1e85b5 --- /dev/null +++ b/src/Symfony/Component/HttpKernel/DependencyInjection/FragmentRendererPass.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\DependencyInjection; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Adds services tagged kernel.fragment_renderer as HTTP content rendering strategies. + * + * @author Fabien Potencier + */ +class FragmentRendererPass implements CompilerPassInterface +{ + private $handlerService; + private $rendererTag; + + /** + * @param string $handlerService Service name of the fragment handler in the container + * @param string $rendererTag Tag name used for fragments + */ + public function __construct($handlerService = 'fragment.handler', $rendererTag = 'kernel.fragment_renderer') + { + $this->handlerService = $handlerService; + $this->rendererTag = $rendererTag; + } + + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition($this->handlerService)) { + return; + } + + $definition = $container->getDefinition($this->handlerService); + foreach ($container->findTaggedServiceIds($this->rendererTag) as $id => $tags) { + $def = $container->getDefinition($id); + if (!$def->isPublic()) { + throw new \InvalidArgumentException(sprintf('The service "%s" must be public as fragment renderer are lazy-loaded.', $id)); + } + + if ($def->isAbstract()) { + throw new \InvalidArgumentException(sprintf('The service "%s" must not be abstract as fragment renderer are lazy-loaded.', $id)); + } + + $refClass = new \ReflectionClass($container->getParameterBag()->resolveValue($def->getClass())); + $interface = 'Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface'; + if (!$refClass->implementsInterface($interface)) { + throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface)); + } + + foreach ($tags as $tag) { + if (!isset($tag['alias'])) { + trigger_error(sprintf('Service "%s" will have to define the "alias" attribute on the "%s" tag as of Symfony 3.0.', $id, $this->fragmentTag), E_USER_DEPRECATED); + + // register the handler as a non-lazy-loaded one + $definition->addMethodCall('addRenderer', array(new Reference($id))); + } + + $definition->addMethodCall('addRendererService', array($tag['alias'], $id)); + } + } + } +} diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/LazyLoadingFragmentHandler.php b/src/Symfony/Component/HttpKernel/DependencyInjection/LazyLoadingFragmentHandler.php new file mode 100644 index 0000000000..4efe7cb620 --- /dev/null +++ b/src/Symfony/Component/HttpKernel/DependencyInjection/LazyLoadingFragmentHandler.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\DependencyInjection; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\HttpKernel\Fragment\FragmentHandler; + +/** + * Lazily loads fragment renderers from the dependency injection container. + * + * @author Fabien Potencier + */ +class LazyLoadingFragmentHandler extends FragmentHandler +{ + private $container; + private $rendererIds = array(); + + public function __construct(ContainerInterface $container, $debug = false, RequestStack $requestStack = null) + { + $this->container = $container; + + parent::__construct(array(), $debug, $requestStack); + } + + /** + * Adds a service as a fragment renderer. + * + * @param string $renderer The render service id + */ + public function addRendererService($name, $renderer) + { + $this->rendererIds[$name] = $renderer; + } + + /** + * {@inheritdoc} + */ + public function render($uri, $renderer = 'inline', array $options = array()) + { + if (isset($this->rendererIds[$renderer])) { + $this->addRenderer($this->container->get($this->rendererIds[$renderer])); + + unset($this->rendererIds[$renderer]); + } + + return parent::render($uri, $renderer, $options); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/FragmentRendererPassTest.php b/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/FragmentRendererPassTest.php similarity index 79% rename from src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/FragmentRendererPassTest.php rename to src/Symfony/Component/HttpKernel/Tests/DependencyInjection/FragmentRendererPassTest.php index 00e5096ec4..dd18f1585c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/FragmentRendererPassTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/FragmentRendererPassTest.php @@ -9,11 +9,11 @@ * file that was distributed with this source code. */ -namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler; +namespace Symfony\Component\HttpKernel\Tests\DependencyInjection; -use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpFoundation\Request; -use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\FragmentRendererPass; +use Symfony\Component\HttpKernel\DependencyInjection\FragmentRendererPass; +use Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface; class FragmentRendererPassTest extends \PHPUnit_Framework_TestCase { @@ -27,13 +27,10 @@ class FragmentRendererPassTest extends \PHPUnit_Framework_TestCase { // one service, not implementing any interface $services = array( - 'my_content_renderer' => array(), + 'my_content_renderer' => array('alias' => 'foo'), ); $definition = $this->getMock('Symfony\Component\DependencyInjection\Definition'); - $definition->expects($this->atLeastOnce()) - ->method('getClass') - ->will($this->returnValue('stdClass')); $builder = $this->getMock( 'Symfony\Component\DependencyInjection\ContainerBuilder', @@ -59,20 +56,25 @@ class FragmentRendererPassTest extends \PHPUnit_Framework_TestCase public function testValidContentRenderer() { $services = array( - 'my_content_renderer' => array(), + 'my_content_renderer' => array(array('alias' => 'foo')), ); $renderer = $this->getMock('Symfony\Component\DependencyInjection\Definition'); $renderer ->expects($this->once()) ->method('addMethodCall') - ->with('addRenderer', array(new Reference('my_content_renderer'))) + ->with('addRendererService', array('foo', 'my_content_renderer')) ; $definition = $this->getMock('Symfony\Component\DependencyInjection\Definition'); $definition->expects($this->atLeastOnce()) ->method('getClass') - ->will($this->returnValue('Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler\RendererService')); + ->will($this->returnValue('Symfony\Component\HttpKernel\Tests\DependencyInjection\RendererService')); + $definition + ->expects($this->once()) + ->method('isPublic') + ->will($this->returnValue(true)) + ; $builder = $this->getMock( 'Symfony\Component\DependencyInjection\ContainerBuilder', @@ -96,7 +98,7 @@ class FragmentRendererPassTest extends \PHPUnit_Framework_TestCase } } -class RendererService implements \Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface +class RendererService implements FragmentRendererInterface { public function render($uri, Request $request = null, array $options = array()) { diff --git a/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/LazyLoadingFragmentHandlerTest.php b/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/LazyLoadingFragmentHandlerTest.php new file mode 100644 index 0000000000..581db45658 --- /dev/null +++ b/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/LazyLoadingFragmentHandlerTest.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Tests\DependencyInjection; + +use Symfony\Component\HttpKernel\DependencyInjection\LazyLoadingFragmentHandler; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +class LazyLoadingFragmentHandlerTest extends \PHPUnit_Framework_TestCase +{ + public function test() + { + $renderer = $this->getMock('Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface'); + $renderer->expects($this->once())->method('getName')->will($this->returnValue('foo')); + $renderer->expects($this->any())->method('render')->will($this->returnValue(new Response())); + + $requestStack = $this->getMock('Symfony\Component\HttpFoundation\RequestStack'); + $requestStack->expects($this->any())->method('getCurrentRequest')->will($this->returnValue(Request::create('/'))); + + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $container->expects($this->once())->method('get')->will($this->returnValue($renderer)); + + $handler = new LazyLoadingFragmentHandler($container, false, $requestStack); + $handler->addRendererService('foo', 'foo'); + + $handler->render('/foo', 'foo'); + + // second call should not lazy-load anymore (see once() above on the get() method) + $handler->render('/foo', 'foo'); + } +} From 6148652d05efab79ff891d29a403fadd8ec624c1 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 12 Jan 2015 14:49:09 +0100 Subject: [PATCH 2/3] [FrameworkBundle] removed obsolete ContainerAwareHIncludeFragmentRenderer class --- .../DependencyInjection/FrameworkExtension.php | 5 +++++ .../ContainerAwareHIncludeFragmentRenderer.php | 4 ++++ .../Resources/config/fragment_renderer.xml | 5 ++--- ...ainerAwareHIncludeFragmentRendererTest.php} | 4 +++- .../Controller/FragmentController.php | 18 +----------------- .../Functional/app/Resources/fragment.html.php | 14 ++++++++++++++ 6 files changed, 29 insertions(+), 21 deletions(-) rename src/Symfony/Bundle/FrameworkBundle/Tests/Fragment/{ContainerAwareHIncludeFragmentRendererTest.php => LegacyContainerAwareHIncludeFragmentRendererTest.php} (86%) create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Resources/fragment.html.php diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 0adf3cb6f8..2a67e53d8a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -539,6 +539,11 @@ class FrameworkExtension extends Extension $container->setAlias('templating', 'templating.engine.delegating'); } + $container->getDefinition('fragment.renderer.hinclude') + ->addTag('kernel.fragment_renderer', array('alias' => 'hinclude')) + ->replaceArgument(0, new Reference('templating')) + ; + // configure the PHP engine if needed if (in_array('php', $config['engines'], true)) { $loader->load('templating_php.xml'); diff --git a/src/Symfony/Bundle/FrameworkBundle/Fragment/ContainerAwareHIncludeFragmentRenderer.php b/src/Symfony/Bundle/FrameworkBundle/Fragment/ContainerAwareHIncludeFragmentRenderer.php index 698d979082..9772912d74 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Fragment/ContainerAwareHIncludeFragmentRenderer.php +++ b/src/Symfony/Bundle/FrameworkBundle/Fragment/ContainerAwareHIncludeFragmentRenderer.php @@ -11,6 +11,8 @@ namespace Symfony\Bundle\FrameworkBundle\Fragment; +trigger_error('The '.__NAMESPACE__.'\ContainerAwareHIncludeFragmentRenderer class is deprecated since version 2.7 and will be removed in 3.0. Use Symfony\Bundle\FrameworkBundle\Fragment\HIncludeFragmentRenderer instead.', E_USER_DEPRECATED); + use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\UriSigner; @@ -20,6 +22,8 @@ use Symfony\Component\HttpKernel\Fragment\HIncludeFragmentRenderer; * Implements the Hinclude rendering strategy. * * @author Fabien Potencier + * + * @deprecated since version 2.7, to be removed in 3.0. Use Symfony\Bundle\FrameworkBundle\Fragment\HIncludeFragmentRenderer instead. */ class ContainerAwareHIncludeFragmentRenderer extends HIncludeFragmentRenderer { diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/fragment_renderer.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/fragment_renderer.xml index 7ac0d68dc9..d3687da13a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/fragment_renderer.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/fragment_renderer.xml @@ -7,7 +7,7 @@ Symfony\Component\HttpKernel\DependencyInjection\LazyLoadingFragmentHandler Symfony\Component\HttpKernel\Fragment\InlineFragmentRenderer - Symfony\Bundle\FrameworkBundle\Fragment\ContainerAwareHIncludeFragmentRenderer + Symfony\Component\HttpKernel\Fragment\HIncludeFragmentRenderer Symfony\Component\HttpKernel\Fragment\EsiFragmentRenderer /_fragment @@ -28,8 +28,7 @@ - - + %fragment.renderer.hinclude.global_template% %fragment.path% diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fragment/ContainerAwareHIncludeFragmentRendererTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Fragment/LegacyContainerAwareHIncludeFragmentRendererTest.php similarity index 86% rename from src/Symfony/Bundle/FrameworkBundle/Tests/Fragment/ContainerAwareHIncludeFragmentRendererTest.php rename to src/Symfony/Bundle/FrameworkBundle/Tests/Fragment/LegacyContainerAwareHIncludeFragmentRendererTest.php index 546d48bc0b..3ccdab8385 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fragment/ContainerAwareHIncludeFragmentRendererTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fragment/LegacyContainerAwareHIncludeFragmentRendererTest.php @@ -15,10 +15,12 @@ use Symfony\Bundle\FrameworkBundle\Tests\TestCase; use Symfony\Bundle\FrameworkBundle\Fragment\ContainerAwareHIncludeFragmentRenderer; use Symfony\Component\HttpFoundation\Request; -class ContainerAwareHIncludeFragmentRendererTest extends TestCase +class LegacyContainerAwareHIncludeFragmentRendererTest extends TestCase { public function testRender() { + $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED); + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); $container->expects($this->once()) ->method('get') diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/FragmentController.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/FragmentController.php index cefa7de7c1..783014ee9e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/FragmentController.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/FragmentController.php @@ -19,23 +19,7 @@ class FragmentController extends ContainerAware { public function indexAction(Request $request) { - $actions = $this->container->get('templating')->get('actions'); - - $html1 = $actions->render($actions->controller('TestBundle:Fragment:inlined', array( - 'options' => array( - 'bar' => new Bar(), - 'eleven' => 11, - ), - ))); - - $html2 = $actions->render($actions->controller('TestBundle:Fragment:customformat', array('_format' => 'html'))); - - $html3 = $actions->render($actions->controller('TestBundle:Fragment:customlocale', array('_locale' => 'es'))); - - $request->setLocale('fr'); - $html4 = $actions->render($actions->controller('TestBundle:Fragment:forwardlocale')); - - return new Response($html1.'--'.$html2.'--'.$html3.'--'.$html4); + return $this->container->get('templating')->renderResponse('fragment.html.php', array('bar' => new Bar())); } public function inlinedAction($options, $_format) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Resources/fragment.html.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Resources/fragment.html.php new file mode 100644 index 0000000000..8ea3c36f8a --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Resources/fragment.html.php @@ -0,0 +1,14 @@ +get('actions')->render($this->get('actions')->controller('TestBundle:Fragment:inlined', array( + 'options' => array( + 'bar' => $bar, + 'eleven' => 11, + ), + ))); +?>--get('actions')->render($this->get('actions')->controller('TestBundle:Fragment:customformat', array('_format' => 'html'))); +?>--get('actions')->render($this->get('actions')->controller('TestBundle:Fragment:customlocale', array('_locale' => 'es'))); +?>--getRequest()->setLocale('fr'); + echo $this->get('actions')->render($this->get('actions')->controller('TestBundle:Fragment:forwardlocale')); +?> From 2be8b6e2eac24f9f576c5591cc9e7bf49244a19f Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 12 Jan 2015 14:42:13 +0100 Subject: [PATCH 3/3] [TwigBundle] optimized the hinclude fragement renderer when only Twig is used --- .../DependencyInjection/Compiler/ExtensionPass.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php index 953a9dd9dd..b325836281 100644 --- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php +++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php @@ -13,6 +13,7 @@ namespace Symfony\Bundle\TwigBundle\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; /** * @author Jean-François Simon @@ -41,6 +42,17 @@ class ExtensionPass implements CompilerPassInterface if ($container->has('fragment.handler')) { $container->getDefinition('twig.extension.httpkernel')->addTag('twig.extension'); + + // inject Twig in the hinclude service if Twig is the only registered templating engine + if ( + !$container->hasParameter('templating.engines') + || array('twig') == $container->getParameter('templating.engines') + ) { + $container->getDefinition('fragment.renderer.hinclude') + ->addTag('kernel.fragment_renderer', array('alias' => 'hinclude')) + ->replaceArgument(0, new Reference('twig')) + ; + } } if ($container->has('request_stack')) {