Ver código fonte

[AsseticBundle] made the filter manager lazy

Kris Wallsmith 14 anos atrás
pai
commit
c01be42933

+ 6 - 2
src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/FilterManagerPass.php

@@ -28,13 +28,17 @@ class FilterManagerPass implements CompilerPassInterface
             return;
         }
 
-        $fm = $container->getDefinition('assetic.filter_manager');
+        $mapping = array();
         foreach ($container->findTaggedServiceIds('assetic.filter') as $id => $attributes) {
             foreach ($attributes as $attr) {
                 if (isset($attr['alias'])) {
-                    $fm->addMethodCall('set', array($attr['alias'], new Reference($id)));
+                    $mapping[$attr['alias']] = $id;
                 }
             }
         }
+
+        $container
+            ->getDefinition('assetic.filter_manager')
+            ->setArgument(1, $mapping);
     }
 }

+ 60 - 0
src/Symfony/Bundle/AsseticBundle/LazyFilterManager.php

@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Symfony framework.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Symfony\Bundle\AsseticBundle;
+
+use Assetic\FilterManager;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Lazy filter manager.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@symfony-project.com>
+ */
+class LazyFilterManager extends FilterManager
+{
+    protected $container;
+    protected $mappings;
+
+    /**
+     * Constructor.
+     *
+     * @param ContainerInterface $container The service container
+     * @param array              $mappings  A hash of filter names to service ids
+     */
+    public function __construct(ContainerInterface $container, array $mappings)
+    {
+        $this->container = $container;
+        $this->mappings = $mappings;
+    }
+
+    public function get($name)
+    {
+        return isset($this->mappings[$name])
+            ? $this->container->get($this->mappings[$name])
+            : parent::get($name);
+    }
+
+    public function has($name)
+    {
+        return isset($this->mappings) || parent::has($name);
+    }
+
+    public function all()
+    {
+        $filters = array();
+        foreach ($this->mappings as $name => $id) {
+            $filters[$name] = $this->container->get($id);
+        }
+
+        return $filters + parent::all();
+    }
+}

+ 12 - 9
src/Symfony/Bundle/AsseticBundle/Resources/config/assetic.xml

@@ -7,7 +7,7 @@
     <parameters>
         <parameter key="assetic.asset_factory.class">Symfony\Bundle\AsseticBundle\Factory\AssetFactory</parameter>
         <parameter key="assetic.asset_manager.class">Symfony\Bundle\AsseticBundle\Factory\CachedAssetManager</parameter>
-        <parameter key="assetic.filter_manager.class">Assetic\FilterManager</parameter>
+        <parameter key="assetic.filter_manager.class">Symfony\Bundle\AsseticBundle\LazyFilterManager</parameter>
 
         <parameter key="assetic.filter.coffee.class">Assetic\Filter\CoffeeScriptFilter</parameter>
         <parameter key="assetic.filter.cssrewrite.class">Assetic\Filter\CssRewriteFilter</parameter>
@@ -28,7 +28,10 @@
 
     <services>
         <!-- managers -->
-        <service id="assetic.filter_manager" class="%assetic.filter_manager.class%" />
+        <service id="assetic.filter_manager" class="%assetic.filter_manager.class%">
+            <argument type="service" id="service_container" />
+            <argument type="collection"></argument>
+        </service>
         <service id="assetic.asset_manager" class="%assetic.asset_manager.class%">
             <argument type="service" id="assetic.asset_factory" />
         </service>
@@ -40,33 +43,33 @@
         </service>
 
         <!-- filters -->
-        <service id="assetic.filter.cssrewrite" class="%assetic.filter.cssrewrite.class%" public="false">
+        <service id="assetic.filter.cssrewrite" class="%assetic.filter.cssrewrite.class%">
             <tag name="assetic.filter" alias="cssrewrite" />
             <argument type="service" id="assetic.css_tokenizer" />
         </service>
-        <service id="assetic.filter.less" class="%assetic.filter.less.class%" public="false">
+        <service id="assetic.filter.less" class="%assetic.filter.less.class%">
             <tag name="assetic.filter" alias="less" />
             <argument>%assetic.document_root%</argument>
             <argument>%assetic.node_bin%</argument>
             <argument>%assetic.node_paths%</argument>
         </service>
-        <service id="assetic.filter.sass" class="%assetic.filter.sass.class%" public="false">
+        <service id="assetic.filter.sass" class="%assetic.filter.sass.class%">
             <tag name="assetic.filter" alias="sass" />
             <argument>%assetic.sass_bin%</argument>
         </service>
-        <service id="assetic.filter.scss" class="%assetic.filter.scss.class%" public="false">
+        <service id="assetic.filter.scss" class="%assetic.filter.scss.class%">
             <tag name="assetic.filter" alias="scss" />
             <argument>%assetic.sass_bin%</argument>
         </service>
-        <service id="assetic.filter.google_closure_compiler" class="%assetic.filter.google_closure_compiler_api.class%" public="false">
+        <service id="assetic.filter.google_closure_compiler" class="%assetic.filter.google_closure_compiler_api.class%">
             <tag name="assetic.filter" alias="closure" />
         </service>
-        <service id="assetic.filter.sprockets" class="%assetic.filter.sprockets.class%" public="false">
+        <service id="assetic.filter.sprockets" class="%assetic.filter.sprockets.class%">
             <tag name="assetic.filter" alias="sprockets" />
             <argument>%assetic.document_root%</argument>
             <argument>%assetic.sprocketize_bin%</argument>
         </service>
-        <service id="assetic.filter.coffee" class="%assetic.filter.coffee.class%" public="false">
+        <service id="assetic.filter.coffee" class="%assetic.filter.coffee.class%">
             <tag name="assetic.filter" alias="coffee" />
             <argument>%assetic.coffee_bin%</argument>
             <argument>%assetic.node_bin%</argument>

+ 64 - 0
src/Symfony/Bundle/AsseticBundle/Tests/LazyFilterManagerTest.php

@@ -0,0 +1,64 @@
+<?php
+
+/*
+ * This file is part of the Symfony framework.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Symfony\Bundle\AsseticBundle\Tests;
+
+use Symfony\Bundle\AsseticBundle\LazyFilterManager;
+
+class LazyFilterManagerTest extends \PHPUnit_Framework_TestCase
+{
+    protected function setUp()
+    {
+        if (!class_exists('Assetic\\AssetManager')) {
+            $this->markTestSkipped('Assetic is not available.');
+        }
+    }
+
+    public function testGet()
+    {
+        $container = $this->getMock('Symfony\\Component\\DependencyInjection\\ContainerInterface');
+        $filter = $this->getMock('Assetic\\Filter\\FilterInterface');
+
+        $container->expects($this->exactly(2))
+            ->method('get')
+            ->with('assetic.filter.bar')
+            ->will($this->returnValue($filter));
+
+        $fm = new LazyFilterManager($container, array('foo' => 'assetic.filter.bar'));
+
+        $this->assertSame($filter, $fm->get('foo'), '->get() loads the filter from the container');
+        $this->assertSame($filter, $fm->get('foo'), '->get() loads the filter from the container');
+    }
+
+    public function testHas()
+    {
+        $container = $this->getMock('Symfony\\Component\\DependencyInjection\\ContainerInterface');
+
+        $fm = new LazyFilterManager($container, array('foo' => 'assetic.filter.bar'));
+        $this->assertTrue($fm->has('foo'), '->has() returns true for lazily mapped filters');
+    }
+
+    public function testAll()
+    {
+        $container = $this->getMock('Symfony\\Component\\DependencyInjection\\ContainerInterface');
+        $filter = $this->getMock('Assetic\\Filter\\FilterInterface');
+
+        $container->expects($this->once())
+            ->method('get')
+            ->with('assetic.filter.bar')
+            ->will($this->returnValue($filter));
+
+        $fm = new LazyFilterManager($container, array('foo' => 'assetic.filter.bar'));
+        $fm->set('bar', $filter);
+        $all = $fm->all();
+        $this->assertEquals(2, count($all), '->all() returns all lazy and normal filters');
+    }
+}