Explorar el Código

[FrameworkBundle] updated for templating changes, added http/ssl logic

Kris Wallsmith hace 14 años
padre
commit
d9f5c99fab

+ 57 - 4
src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

@@ -179,21 +179,56 @@ class Configuration implements ConfigurationInterface
 
     private function addTemplatingSection(ArrayNodeDefinition $rootNode)
     {
+        $organizeUrls = function($urls)
+        {
+            $urls += array(
+                'http' => array(),
+                'ssl'  => array(),
+            );
+
+            foreach ($urls as $i => $url) {
+                if (is_integer($i)) {
+                    if (0 === strpos($url, 'https://') || 0 === strpos($url, '//')) {
+                        $urls['http'][] = $urls['ssl'][] = $url;
+                    } else {
+                        $urls['http'][] = $url;
+                    }
+                    unset($urls[$i]);
+                }
+            }
+
+            return $urls;
+        };
+
         $rootNode
             ->children()
                 ->arrayNode('templating')
                     ->canBeUnset()
                     ->children()
                         ->scalarNode('assets_version')->defaultValue(null)->end()
+                        ->scalarNode('assets_version_format')->defaultValue(null)->end()
                     ->end()
                     ->fixXmlConfig('assets_base_url')
                     ->children()
                         ->arrayNode('assets_base_urls')
+                            ->addDefaultsIfNotSet()
+                            ->defaultValue(array('http' => array(), 'ssl' => array()))
                             ->beforeNormalization()
-                                ->ifTrue(function($v){ return !is_array($v); })
-                                ->then(function($v){ return array($v); })
+                                ->ifTrue(function($v) { return !is_array($v); })
+                                ->then(function($v) { return array($v); })
+                            ->end()
+                            ->beforeNormalization()
+                                ->always()
+                                ->then($organizeUrls)
+                            ->end()
+                            ->children()
+                                ->arrayNode('http')
+                                    ->prototype('scalar')->end()
+                                ->end()
+                                ->arrayNode('ssl')
+                                    ->prototype('scalar')->end()
+                                ->end()
                             ->end()
-                            ->prototype('scalar')->end()
                         ->end()
                         ->scalarNode('cache')->end()
                         ->scalarNode('cache_warmer')->defaultFalse()->end()
@@ -228,8 +263,26 @@ class Configuration implements ConfigurationInterface
                                 ->fixXmlConfig('base_url')
                                 ->children()
                                     ->scalarNode('version')->defaultNull()->end()
+                                    ->scalarNode('version_format')->defaultNull()->end()
                                     ->arrayNode('base_urls')
-                                        ->prototype('scalar')->end()
+                                        ->addDefaultsIfNotSet()
+                                        ->defaultValue(array('http' => array(), 'ssl' => array()))
+                                        ->beforeNormalization()
+                                            ->ifTrue(function($v) { return !is_array($v); })
+                                            ->then(function($v) { return array($v); })
+                                        ->end()
+                                        ->beforeNormalization()
+                                            ->always()
+                                            ->then($organizeUrls)
+                                        ->end()
+                                        ->children()
+                                            ->arrayNode('http')
+                                                ->prototype('scalar')->end()
+                                            ->end()
+                                            ->arrayNode('ssl')
+                                                ->prototype('scalar')->end()
+                                            ->end()
+                                        ->end()
                                     ->end()
                                 ->end()
                             ->end()

+ 79 - 9
src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

@@ -14,6 +14,7 @@ namespace Symfony\Bundle\FrameworkBundle\DependencyInjection;
 use Symfony\Component\Config\Loader\LoaderInterface;
 use Symfony\Component\DependencyInjection\ContainerBuilder;
 use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\DefinitionDecorator;
 use Symfony\Component\DependencyInjection\Parameter;
 use Symfony\Component\DependencyInjection\Reference;
 use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
@@ -332,17 +333,19 @@ class FrameworkExtension extends Extension
             $loader->load('templating_debug.xml');
         }
 
-        $packages = array();
+        // create package definitions and add them to the assets helper
+        $defaultPackage = $this->createPackageDefinition($container, $config['assets_base_urls']['http'], $config['assets_base_urls']['ssl'], $config['assets_version'], $config['assets_version_format']);
+        $container->setDefinition('templating.asset.default_package', $defaultPackage);
+        $namedPackages = array();
         foreach ($config['packages'] as $name => $package) {
-            $packages[$name] = new Definition('%templating.asset_package.class%', array(
-                $package['base_urls'],
-                $package['version'],
-            ));
+            $namedPackage = $this->createPackageDefinition($container, $package['base_urls']['http'], $package['base_urls']['ssl'], $package['version'], $package['version_format'], $name);
+            $container->setDefinition('templating.asset.package.'.$name, $namedPackage);
+            $namedPackages[$name] = new Reference('templating.asset.package.'.$name);
         }
-
-        $container->setParameter('templating.helper.assets.assets_base_urls', isset($config['assets_base_urls']) ? $config['assets_base_urls'] : array());
-        $container->setParameter('templating.helper.assets.assets_version', $config['assets_version']);
-        $container->getDefinition('templating.helper.assets')->replaceArgument(3, $packages);
+        $container->getDefinition('templating.helper.assets')->setArguments(array(
+            new Reference('templating.asset.default_package'),
+            $namedPackages,
+        ));
 
         if (!empty($config['loaders'])) {
             $loaders = array_map(function($loader) { return new Reference($loader); }, $config['loaders']);
@@ -412,6 +415,73 @@ class FrameworkExtension extends Extension
         }
     }
 
+    /**
+     * Returns a definition for an asset package.
+     */
+    private function createPackageDefinition(ContainerBuilder $container, array $httpUrls, array $sslUrls, $version, $format, $name = null)
+    {
+        if (!$httpUrls) {
+            $package = new DefinitionDecorator('templating.asset.path_package');
+            $package
+                ->setPublic(false)
+                ->setScope('request')
+                ->replaceArgument(1, $version)
+                ->replaceArgument(2, $format)
+            ;
+
+            return $package;
+        }
+
+        if ($httpUrls == $sslUrls) {
+            $package = new DefinitionDecorator('templating.asset.url_package');
+            $package
+                ->setPublic(false)
+                ->replaceArgument(0, $sslUrls)
+                ->replaceArgument(1, $version)
+                ->replaceArgument(2, $format)
+            ;
+
+            return $package;
+        }
+
+        $prefix = $name ? 'templating.asset.package.'.$name : 'templating.asset.default_package';
+
+        $httpPackage = new DefinitionDecorator('templating.asset.url_package');
+        $httpPackage
+            ->replaceArgument(0, $httpUrls)
+            ->replaceArgument(1, $version)
+            ->replaceArgument(2, $format)
+        ;
+        $container->setDefinition($prefix.'.http', $httpPackage);
+
+        if ($sslUrls) {
+            $sslPackage = new DefinitionDecorator('templating.asset.url_package');
+            $sslPackage
+                ->replaceArgument(0, $sslUrls)
+                ->replaceArgument(1, $version)
+                ->replaceArgument(2, $format)
+            ;
+        } else {
+            $sslPackage = new DefinitionDecorator('templating.asset.path_package');
+            $sslPackage
+                ->setScope('request')
+                ->replaceArgument(1, $version)
+                ->replaceArgument(2, $format)
+            ;
+        }
+        $container->setDefinition($prefix.'.ssl', $sslPackage);
+
+        $package = new DefinitionDecorator('templating.asset.request_aware_package');
+        $package
+            ->setPublic(false)
+            ->setScope('request')
+            ->replaceArgument(1, $prefix.'.http')
+            ->replaceArgument(2, $prefix.'.ssl')
+        ;
+
+        return $package;
+    }
+
     /**
      * Loads the translator configuration.
      *

+ 2 - 0
src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd

@@ -103,6 +103,7 @@
         </xsd:sequence>
 
         <xsd:attribute name="assets-version" type="xsd:string" />
+        <xsd:attribute name="assets-version-format" type="xsd:string" />
         <xsd:attribute name="cache" type="xsd:string" />
         <xsd:attribute name="cache-warmer" type="cache_warmer" />
     </xsd:complexType>
@@ -114,6 +115,7 @@
 
         <xsd:attribute name="name" type="xsd:string" use="required" />
         <xsd:attribute name="version" type="xsd:string" />
+        <xsd:attribute name="version-format" type="xsd:string" />
     </xsd:complexType>
 
     <xsd:complexType name="translator">

+ 28 - 6
src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml

@@ -7,7 +7,7 @@
     <parameters>
         <parameter key="templating.engine.php.class">Symfony\Bundle\FrameworkBundle\Templating\PhpEngine</parameter>
         <parameter key="templating.helper.slots.class">Symfony\Component\Templating\Helper\SlotsHelper</parameter>
-        <parameter key="templating.helper.assets.class">Symfony\Bundle\FrameworkBundle\Templating\Helper\AssetsHelper</parameter>
+        <parameter key="templating.helper.assets.class">Symfony\Component\Templating\Helper\CoreAssetsHelper</parameter>
         <parameter key="templating.helper.actions.class">Symfony\Bundle\FrameworkBundle\Templating\Helper\ActionsHelper</parameter>
         <parameter key="templating.helper.router.class">Symfony\Bundle\FrameworkBundle\Templating\Helper\RouterHelper</parameter>
         <parameter key="templating.helper.request.class">Symfony\Bundle\FrameworkBundle\Templating\Helper\RequestHelper</parameter>
@@ -16,7 +16,9 @@
         <parameter key="templating.helper.translator.class">Symfony\Bundle\FrameworkBundle\Templating\Helper\TranslatorHelper</parameter>
         <parameter key="templating.helper.form.class">Symfony\Bundle\FrameworkBundle\Templating\Helper\FormHelper</parameter>
         <parameter key="templating.globals.class">Symfony\Bundle\FrameworkBundle\Templating\GlobalVariables</parameter>
-        <parameter key="templating.asset_package.class">Symfony\Component\Templating\Asset\AssetPackage</parameter>
+        <parameter key="templating.asset.path_package.class">Symfony\Bundle\FrameworkBundle\Templating\Asset\PathPackage</parameter>
+        <parameter key="templating.asset.url_package.class">Symfony\Component\Templating\Asset\UrlPackage</parameter>
+        <parameter key="templating.asset.package_factory.class">Symfony\Bundle\FrameworkBundle\Templating\Asset\PackageFactory</parameter>
     </parameters>
 
     <services>
@@ -32,12 +34,32 @@
             <tag name="templating.helper" alias="slots" />
         </service>
 
-        <service id="templating.helper.assets" class="%templating.helper.assets.class%">
+        <service id="templating.helper.assets" class="%templating.helper.assets.class%" scope="request">
             <tag name="templating.helper" alias="assets" />
+            <argument /> <!-- default package -->
+            <argument type="collection" /> <!-- named packages -->
+        </service>
+
+        <service id="templating.asset.path_package" class="%templating.asset.path_package.class%" abstract="true">
+            <argument type="service" id="request" />
+            <argument /> <!-- version -->
+            <argument /> <!-- version format -->
+        </service>
+
+        <service id="templating.asset.url_package" class="%templating.asset.url_package.class%" abstract="true">
+            <argument /> <!-- base urls -->
+            <argument /> <!-- version -->
+            <argument /> <!-- version format -->
+        </service>
+
+        <service id="templating.asset.request_aware_package" class="Symfony\Component\Templating\Asset\PackageInterface" factory-service="templating.asset.package_factory" factory-method="getPackage" abstract="true">
             <argument type="service" id="request" strict="false" />
-            <argument>%templating.helper.assets.assets_base_urls%</argument>
-            <argument>%templating.helper.assets.assets_version%</argument>
-            <argument type="collection" /> <!-- packages -->
+            <argument /> <!-- http id -->
+            <argument /> <!-- ssl id -->
+        </service>
+
+        <service id="templating.asset.package_factory" class="%templating.asset.package_factory.class%">
+            <argument type="service" id="service_container" />
         </service>
 
         <service id="templating.helper.request" class="%templating.helper.request.class%">

+ 44 - 0
src/Symfony/Bundle/FrameworkBundle/Templating/Asset/PackageFactory.php

@@ -0,0 +1,44 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\FrameworkBundle\Templating\Asset;
+
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Creates packages based on whether the current request is secure.
+ *
+ * @author Kris Wallsmith <kris@symfony.com>
+ */
+class PackageFactory
+{
+    private $container;
+
+    public function __construct(ContainerInterface $container)
+    {
+        $this->container = $container;
+    }
+
+    /**
+     * Returns either the HTTP or SSL version of an asset package.
+     *
+     * @param Request $request The current request
+     * @param string  $httpId  The id for the package to use when the current request is HTTP
+     * @param string  $sslId   The id for the package to use when the current request is SSL
+     *
+     * @return PackageInterface The package
+     */
+    public function getPackage(Request $request, $httpId, $sslId)
+    {
+        return $this->container->get($request->isSecure() ? $sslId : $httpId);
+    }
+}

+ 35 - 0
src/Symfony/Bundle/FrameworkBundle/Templating/Asset/PathPackage.php

@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\FrameworkBundle\Templating\Asset;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Templating\Asset\PathPackage as BasePathPackage;
+
+/**
+ * The path packages adds a version and a base path to asset URLs.
+ *
+ * @author Kris Wallsmith <kris@symfony.com>
+ */
+class PathPackage extends BasePathPackage
+{
+    /**
+     * Constructor.
+     *
+     * @param Request $request The current request
+     * @param string  $version The version
+     * @param string  $format  The version format
+     */
+    public function __construct(Request $request, $version = null, $format = null)
+    {
+        parent::__construct($request->getBasePath(), $version, $format);
+    }
+}

+ 0 - 36
src/Symfony/Bundle/FrameworkBundle/Templating/Helper/AssetsHelper.php

@@ -1,36 +0,0 @@
-<?php
-
-/*
- * This file is part of the Symfony package.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Bundle\FrameworkBundle\Templating\Helper;
-
-use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\Templating\Helper\AssetsHelper as BaseAssetsHelper;
-
-/**
- * AssetsHelper is the base class for all helper classes that manages assets.
- *
- * @author Fabien Potencier <fabien@symfony.com>
- */
-class AssetsHelper extends BaseAssetsHelper
-{
-    /**
-     * Constructor.
-     *
-     * @param Request      $request  A Request instance
-     * @param string|array $baseURLs The domain URL or an array of domain URLs
-     * @param string       $version  The version
-     * @param array        $packages Asset packages indexed by name
-     */
-    public function __construct(Request $request, $baseURLs = array(), $version = null, $packages = array())
-    {
-        parent::__construct($request->getBasePath(), $baseURLs, $version, $packages);
-    }
-}

+ 15 - 5
src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php

@@ -97,11 +97,21 @@ abstract class FrameworkExtensionTest extends TestCase
         $container = $this->createContainerFromFile('full');
 
         $this->assertTrue($container->hasDefinition('templating.name_parser'), '->registerTemplatingConfiguration() loads templating.xml');
-        $arguments = $container->getDefinition('templating.helper.assets')->getArguments();
-        $this->assertEquals('%templating.helper.assets.assets_version%', $arguments[2]);
-        $this->assertEquals('SomeVersionScheme', $container->getParameter('templating.helper.assets.assets_version'));
-        $this->assertEquals('%templating.helper.assets.assets_base_urls%', $arguments[1]);
-        $this->assertEquals(array('http://cdn.example.com'), $container->getParameter('templating.helper.assets.assets_base_urls'));
+
+        // 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');
+        $this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\DefinitionDecorator', $package);
+        $this->assertEquals('templating.asset.url_package', $package->getParent());
+        $arguments = array_values($package->getArguments());
+        $this->assertEquals(array('http://cdn.example.com'), $arguments[0]);
+        $this->assertEquals('SomeVersionScheme', $arguments[1]);
+        $this->assertNull($arguments[2]);
+
+        $this->assertTrue($container->hasDefinition('templating.asset.default_package.ssl'));
+        $package = $container->getDefinition('templating.asset.default_package.ssl');
+        $this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\DefinitionDecorator', $package);
+        $this->assertEquals('templating.asset.path_package', $package->getParent());
 
         $this->assertTrue($container->getDefinition('templating.cache_warmer.template_paths')->hasTag('kernel.cache_warmer'), '->registerTemplatingConfiguration() tags templating cache warmer if cache warming is set');
         $this->assertEquals('templating.locator.cached', (string) $container->getAlias('templating.locator'), '->registerTemplatingConfiguration() changes templating.locator alias to cached if cache warming is set');