Explorar el Código

[FrameworkBundle] Add request scope to assets helper only if needed

Builds upon aead4a9836180cabae4d47fe27c634dcd79ac8f2, which prematurely removed request scoping from the assets templating helper in all cases. The helper need only be request-scoped if one or more request-scoped packages (e.g. PathPackages) are injected into it. This change makes it possible to utilize the assets helper outside of a request (e.g. during a console script).

To ensure that the assets helper is not assigned a request scope, all asset base URL's must be defined for all packages (default and any named) and both protocols: HTTP and SSL. The included test config fixtures concisely accomplish this by specifying a single HTTPS URL as the base URL for our default and named package, since FrameworkExtension's Configuration conveniently registers this URL for both protocols.
Jeremy Mikola hace 13 años
padre
commit
369f181005

+ 14 - 0
src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

@@ -13,6 +13,7 @@ namespace Symfony\Bundle\FrameworkBundle\DependencyInjection;
 
 use Symfony\Component\Config\Loader\LoaderInterface;
 use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\DependencyInjection\Definition;
 use Symfony\Component\DependencyInjection\DefinitionDecorator;
 use Symfony\Component\DependencyInjection\Parameter;
@@ -342,6 +343,19 @@ class FrameworkExtension extends Extension
             $namedPackages,
         ));
 
+        // Apply request scope to assets helper if one or more packages are request-scoped
+        $requireRequestScope = array_reduce(
+            $namedPackages,
+            function($v, Reference $ref) use ($container) {
+                return $v || 'request' === $container->getDefinition($ref)->getScope();
+            },
+            'request' === $defaultPackage->getScope()
+        );
+
+        if ($requireRequestScope) {
+            $container->getDefinition('templating.helper.assets')->setScope('request');
+        }
+
         if (!empty($config['loaders'])) {
             $loaders = array_map(function($loader) { return new Reference($loader); }, $config['loaders']);
 

+ 14 - 0
src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/templating_url_package.php

@@ -0,0 +1,14 @@
+<?php
+
+$container->loadFromExtension('framework', array(
+    'secret' => 's3cr3t',
+    'templating' => array(
+        'assets_base_urls' => 'https://cdn.example.com',
+        'engines'          => array('php', 'twig'),
+        'packages'         => array(
+            'images' => array(
+                'base_urls' => 'https://images.example.com',
+            ),
+        ),
+    ),
+));

+ 19 - 0
src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/templating_url_package.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" ?>
+
+<container xmlns="http://symfony.com/schema/dic/services"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:framework="http://symfony.com/schema/dic/symfony"
+    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
+                        http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+
+    <framework:config secret="s3cr3t">
+        <framework:templating>
+            <framework:engine>php</framework:engine>
+            <framework:engine>twig</framework:engine>
+            <framework:assets-base-url>https://cdn.example.com</framework:assets-base-url>
+            <framework:package name="images">
+                <framework:base-url>https://images.example.com</framework:base-url>
+            </framework:package>
+        </framework:templating>
+    </framework:config>
+</container>

+ 8 - 0
src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/templating_url_package.yml

@@ -0,0 +1,8 @@
+framework:
+    secret: s3cr3t
+    templating:
+        assets_base_urls: https://cdn.example.com
+        engines:          [php, twig]
+        packages:
+            images:
+                base_urls: https://images.example.com

+ 9 - 0
src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php

@@ -96,6 +96,8 @@ abstract class FrameworkExtensionTest extends TestCase
 
         $this->assertTrue($container->hasDefinition('templating.name_parser'), '->registerTemplatingConfiguration() loads templating.xml');
 
+        $this->assertEquals('request', $container->getDefinition('templating.helper.assets')->getScope(), '->registerTemplatingConfiguration() sets request scope on assets helper if one or more packages are request-scopes');
+
         // default package should have one http base url and path package ssl url
         $this->assertTrue($container->hasDefinition('templating.asset.default_package.http'));
         $package = $container->getDefinition('templating.asset.default_package.http');
@@ -125,6 +127,13 @@ abstract class FrameworkExtensionTest extends TestCase
         $this->assertEquals(array('FrameworkBundle:Form', 'theme1', 'theme2'), $container->getParameter('templating.helper.form.resources'), '->registerTemplatingConfiguration() registers the theme and adds the base theme');
     }
 
+    public function testTemplatingAssetsHelperScopeDependsOnPackageArgumentScopes()
+    {
+        $container = $this->createContainerFromFile('templating_url_package');
+
+        $this->assertNotEquals('request', $container->getDefinition('templating.helper.assets')->getScope(), '->registerTemplatingConfiguration() does not set request scope on assets helper if no packages are request-scopes');
+    }
+
     public function testTranslator()
     {
         $container = $this->createContainerFromFile('full');