Merge remote branch 'kriswallsmith/assetic/asset-config'
* kriswallsmith/assetic/asset-config: Revert "[AsseticBundle] updated configuration to assume values with integer keys are inputs" [AsseticBundle] updated configuration to assume values with integer keys are inputs [AsseticBundle] made test of route loader less brittle [AsseticBundle] added the ability to define assets outside of the view layer [AsseticBundle] injected container into factory for better stability
This commit is contained in:
commit
9e407d7e91
@ -52,6 +52,19 @@ class AsseticExtension extends Extension
|
||||
$container->setParameter('assetic.node.bin', $config['node']);
|
||||
$container->setParameter('assetic.sass.bin', $config['sass']);
|
||||
|
||||
// register formulae
|
||||
$formulae = array();
|
||||
foreach ($config['assets'] as $name => $formula) {
|
||||
$formulae[$name] = array($formula['inputs'], $formula['filters'], $formula['options']);
|
||||
}
|
||||
|
||||
if ($formulae) {
|
||||
$container->getDefinition('assetic.config_resource')->replaceArgument(0, $formulae);
|
||||
} else {
|
||||
$container->removeDefinition('assetic.config_loader');
|
||||
$container->removeDefinition('assetic.config_resource');
|
||||
}
|
||||
|
||||
// register filters
|
||||
foreach ($config['filters'] as $name => $filter) {
|
||||
if (isset($filter['resource'])) {
|
||||
|
@ -77,6 +77,61 @@ class Configuration implements ConfigurationInterface
|
||||
->end()
|
||||
->end()
|
||||
|
||||
// assets
|
||||
->fixXmlConfig('asset')
|
||||
->children()
|
||||
->arrayNode('assets')
|
||||
->addDefaultsIfNotSet()
|
||||
->requiresAtLeastOneElement()
|
||||
->useAttributeAsKey('name')
|
||||
->prototype('array')
|
||||
->beforeNormalization()
|
||||
// a scalar is a simple formula of one input file
|
||||
->ifTrue(function($v) { return !is_array($v); })
|
||||
->then(function($v) { return array('inputs' => array($v)); })
|
||||
->end()
|
||||
->beforeNormalization()
|
||||
->always()
|
||||
->then(function($v)
|
||||
{
|
||||
// cast scalars as array
|
||||
foreach (array('input', 'inputs', 'filter', 'filters') as $key) {
|
||||
if (isset($v[$key]) && !is_array($v[$key])) {
|
||||
$v[$key] = array($v[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
// organize arbitrary options
|
||||
foreach ($v as $key => $value) {
|
||||
if (!in_array($key, array('input', 'inputs', 'filter', 'filters', 'option', 'options'))) {
|
||||
$v['options'][$key] = $value;
|
||||
unset($v[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return $v;
|
||||
})
|
||||
->end()
|
||||
|
||||
// the formula
|
||||
->fixXmlConfig('input')
|
||||
->fixXmlConfig('filter')
|
||||
->children()
|
||||
->arrayNode('inputs')
|
||||
->prototype('scalar')->end()
|
||||
->end()
|
||||
->arrayNode('filters')
|
||||
->prototype('scalar')->end()
|
||||
->end()
|
||||
->arrayNode('options')
|
||||
->useAttributeAsKey('name')
|
||||
->prototype('variable')->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
|
||||
// filters
|
||||
->fixXmlConfig('filter')
|
||||
->children()
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace Symfony\Bundle\AsseticBundle\Factory;
|
||||
|
||||
use Assetic\Factory\AssetFactory as BaseAssetFactory;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpKernel\KernelInterface;
|
||||
|
||||
/**
|
||||
@ -21,11 +22,21 @@ use Symfony\Component\HttpKernel\KernelInterface;
|
||||
*/
|
||||
class AssetFactory extends BaseAssetFactory
|
||||
{
|
||||
protected $kernel;
|
||||
private $kernel;
|
||||
private $container;
|
||||
|
||||
public function __construct(KernelInterface $kernel, $baseDir, $debug = false)
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param KernelInterface $kernel The kernel is used to parse bundle notation
|
||||
* @param ContainerInterface $container The container is used to load the managers lazily, thus avoiding a circular dependency
|
||||
* @param string $baseDir The base directory for relative inputs
|
||||
* @param Boolean $debug The current debug mode
|
||||
*/
|
||||
public function __construct(KernelInterface $kernel, ContainerInterface $container, $baseDir, $debug = false)
|
||||
{
|
||||
$this->kernel = $kernel;
|
||||
$this->container = $container;
|
||||
|
||||
parent::__construct($baseDir, $debug);
|
||||
}
|
||||
@ -51,4 +62,22 @@ class AssetFactory extends BaseAssetFactory
|
||||
|
||||
return parent::parseInput($input);
|
||||
}
|
||||
|
||||
protected function createAssetReference($name)
|
||||
{
|
||||
if (!$this->getAssetManager()) {
|
||||
$this->setAssetManager($this->container->get('assetic.asset_manager'));
|
||||
}
|
||||
|
||||
return parent::createAssetReference($name);
|
||||
}
|
||||
|
||||
protected function getFilter($name)
|
||||
{
|
||||
if (!$this->getFilterManager()) {
|
||||
$this->setFilterManager($this->container->get('assetic.filter_manager'));
|
||||
}
|
||||
|
||||
return parent::getFilter($name);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.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\Factory\Loader;
|
||||
|
||||
use Assetic\Factory\Loader\FormulaLoaderInterface;
|
||||
use Assetic\Factory\Resource\ResourceInterface;
|
||||
use Symfony\Bundle\AsseticBundle\Factory\ConfigurationResource;
|
||||
|
||||
/**
|
||||
* Loads configured formulae.
|
||||
*
|
||||
* @author Kris Wallsmith <kris@symfony.com>
|
||||
*/
|
||||
class ConfigurationLoader implements FormulaLoaderInterface
|
||||
{
|
||||
public function load(ResourceInterface $resource)
|
||||
{
|
||||
return $resource instanceof ConfigurationResource ? $resource->getContent() : array();
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.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\Factory\Resource;
|
||||
|
||||
use Assetic\Factory\Resource\ResourceInterface;
|
||||
|
||||
/**
|
||||
* A configured resource.
|
||||
*
|
||||
* @author Kris Wallsmith <kris@symfony.com>
|
||||
*/
|
||||
class ConfigurationResource implements ResourceInterface
|
||||
{
|
||||
private $formulae;
|
||||
|
||||
public function __construct(array $formulae)
|
||||
{
|
||||
$this->formulae = $formulae;
|
||||
}
|
||||
|
||||
public function isFresh($timestamp)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getContent()
|
||||
{
|
||||
return $this->formulae;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return 'symfony';
|
||||
}
|
||||
}
|
@ -10,6 +10,8 @@
|
||||
<parameter key="assetic.asset_manager_cache_warmer.class">Symfony\Bundle\AsseticBundle\CacheWarmer\AssetManagerCacheWarmer</parameter>
|
||||
<parameter key="assetic.cached_formula_loader.class">Assetic\Factory\Loader\CachedFormulaLoader</parameter>
|
||||
<parameter key="assetic.config_cache.class">Assetic\Cache\ConfigCache</parameter>
|
||||
<parameter key="assetic.config_loader.class">Symfony\Bundle\AsseticBundle\Factory\Loader\ConfigurationLoader</parameter>
|
||||
<parameter key="assetic.config_resource.class">Symfony\Bundle\AsseticBundle\Factory\Resource\ConfigurationResource</parameter>
|
||||
<parameter key="assetic.coalescing_directory_resource.class">Assetic\Factory\Resource\CoalescingDirectoryResource</parameter>
|
||||
<parameter key="assetic.directory_resource.class">Symfony\Bundle\AsseticBundle\Factory\Resource\DirectoryResource</parameter>
|
||||
<parameter key="assetic.filter_manager.class">Symfony\Bundle\AsseticBundle\FilterManager</parameter>
|
||||
@ -31,9 +33,17 @@
|
||||
|
||||
<service id="assetic.asset_factory" class="%assetic.asset_factory.class%" public="false">
|
||||
<argument type="service" id="kernel" />
|
||||
<argument type="service" id="service_container" />
|
||||
<argument>%assetic.read_from%</argument>
|
||||
<argument>%assetic.debug%</argument>
|
||||
<call method="setFilterManager"><argument type="service" id="assetic.filter_manager" /></call>
|
||||
</service>
|
||||
|
||||
<service id="assetic.config_loader" class="%assetic.config_loader.class%" public="false">
|
||||
<tag name="assetic.formula_loader" alias="config" />
|
||||
</service>
|
||||
<service id="assetic.config_resource" class="%assetic.config_resource.class%" public="false">
|
||||
<tag name="assetic.formula_resource" loader="config" />
|
||||
<argument type="collection" /> <!-- configured formulae -->
|
||||
</service>
|
||||
|
||||
<service id="assetic.config_cache" class="%assetic.config_cache.class%" public="false">
|
||||
|
@ -28,6 +28,17 @@
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="asset">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="input" type="xsd:string" minOccurs="1" maxOccurs="unbounded" />
|
||||
<xsd:element name="filter" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
<xsd:attribute name="output" type="xsd:string" />
|
||||
<xsd:attribute name="debug" type="xsd:string" />
|
||||
<xsd:anyAttribute namespace="##any" processContents="lax" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="filter">
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
<xsd:attribute name="resource" type="xsd:string" />
|
||||
|
@ -17,6 +17,7 @@ class AssetFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $kernel;
|
||||
protected $factory;
|
||||
protected $container;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
@ -25,7 +26,8 @@ class AssetFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
}
|
||||
|
||||
$this->kernel = $this->getMock('Symfony\\Component\\HttpKernel\\KernelInterface');
|
||||
$this->factory = new AssetFactory($this->kernel, '/path/to/web');
|
||||
$this->container = $this->getMock('Symfony\\Component\\DependencyInjection\\ContainerInterface');
|
||||
$this->factory = new AssetFactory($this->kernel, $this->container, '/path/to/web');
|
||||
}
|
||||
|
||||
public function testBundleNotation()
|
||||
|
@ -43,33 +43,39 @@ class FunctionalTest extends \PHPUnit_Framework_TestCase
|
||||
$filesystem->remove($this->cacheDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideAmDebugAndAssetCount
|
||||
*/
|
||||
public function testKernel($debug, $count)
|
||||
public function testRoutes()
|
||||
{
|
||||
$kernel = new TestKernel('test', $debug);
|
||||
$countRoutes = function($router)
|
||||
{
|
||||
$count = 0;
|
||||
foreach ($router->getRouteCollection()->all() as $name => $route) {
|
||||
if (0 === strpos($name, '_assetic_')) {
|
||||
++$count;
|
||||
}
|
||||
}
|
||||
|
||||
return $count;
|
||||
};
|
||||
|
||||
$kernel = new TestKernel('test', false);
|
||||
$kernel->boot();
|
||||
|
||||
$this->assertEquals($count, count($kernel->getContainer()->get('assetic.asset_manager')->getNames()));
|
||||
}
|
||||
$am = $kernel->getContainer()->get('assetic.asset_manager');
|
||||
$names = $am->getNames();
|
||||
$baseline = $expected = count($names);
|
||||
|
||||
/**
|
||||
* @dataProvider provideRouterDebugAndAssetCount
|
||||
*/
|
||||
public function testRoutes($debug, $count)
|
||||
{
|
||||
$kernel = new TestKernel('test', $debug);
|
||||
$kernel->boot();
|
||||
|
||||
$matches = 0;
|
||||
foreach (array_keys($kernel->getContainer()->get('router')->getRouteCollection()->all()) as $name) {
|
||||
if (0 === strpos($name, '_assetic_')) {
|
||||
++$matches;
|
||||
foreach ($names as $name) {
|
||||
$asset = $am->get($name);
|
||||
foreach ($asset as $leaf) {
|
||||
++$expected;
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertEquals($count, $matches);
|
||||
$this->assertEquals($baseline, $countRoutes($kernel->getContainer()->get('router')));
|
||||
|
||||
$kernel = new TestKernel('test', true);
|
||||
$kernel->boot();
|
||||
$this->assertEquals($expected, $countRoutes($kernel->getContainer()->get('router')));
|
||||
}
|
||||
|
||||
public function testTwigRenderDebug()
|
||||
@ -101,20 +107,4 @@ class FunctionalTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals(3, count($crawler->filter('link[href$=".css"]')));
|
||||
$this->assertEquals(2, count($crawler->filter('script[src$=".js"]')));
|
||||
}
|
||||
|
||||
public function provideAmDebugAndAssetCount()
|
||||
{
|
||||
return array(
|
||||
array(true, 3),
|
||||
array(false, 3),
|
||||
);
|
||||
}
|
||||
|
||||
public function provideRouterDebugAndAssetCount()
|
||||
{
|
||||
return array(
|
||||
array(true, 9),
|
||||
array(false, 3),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -18,8 +18,21 @@ twig:
|
||||
assetic:
|
||||
use_controller: true
|
||||
read_from: "%kernel.root_dir%/web"
|
||||
bundles: [TestBundle]
|
||||
bundles: [ TestBundle ]
|
||||
assets:
|
||||
jquery: js/jquery.js
|
||||
app_css:
|
||||
inputs:
|
||||
- css/main.css
|
||||
- css/more.css
|
||||
- @widget_css
|
||||
filters: [ ?yui_css ]
|
||||
output: css/packed/app.css
|
||||
widget_css:
|
||||
inputs: css/widget.sass
|
||||
filters: sass
|
||||
filters:
|
||||
sass: ~
|
||||
yui_css:
|
||||
jar: %kernel.root_dir/java/yui-compressor-2.4.6.jar
|
||||
twig:
|
||||
|
Reference in New Issue
Block a user