diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
index 991b64ca4564..a9c5f5341e73 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
@@ -166,21 +166,36 @@ private function addTemplatingSection(NodeBuilder $rootNode)
->beforeNormalization()
->ifTrue(function($v){ return !is_array($v); })
->then(function($v){ return array($v); })
- ->end()
+ ->end()
->prototype('scalar')
->beforeNormalization()
->ifTrue(function($v) { return is_array($v) && isset($v['id']); })
->then(function($v){ return $v['id']; })
->end()
- ->end()
->end()
+ ->end()
->fixXmlConfig('loader')
->arrayNode('loaders')
->beforeNormalization()
->ifTrue(function($v){ return !is_array($v); })
->then(function($v){ return array($v); })
- ->end()
+ ->end()
->prototype('scalar')->end()
+ ->end()
+ ->fixXmlConfig('package')
+ ->arrayNode('packages')
+ ->useAttributeAsKey('name')
+ ->prototype('array')
+ ->scalarNode('version')->defaultNull()->end()
+ ->fixXmlConfig('base_url')
+ ->arrayNode('base_urls')
+ ->prototype('scalar')
+ ->beforeNormalization()
+ ->ifTrue(function($v) { return is_array($v) && isset($v['value']); })
+ ->then(function($v){ return $v['value']; })
+ ->end()
+ ->end()
+ ->end()
->end()
->end()
;
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index bc31dfa277e1..f77d0f05beb7 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -312,6 +312,15 @@ private function registerTemplatingConfiguration(array $config, ContainerBuilder
$container->setParameter('templating.assets.base_urls', $config['assets_base_urls']);
}
+ $packages = array();
+ foreach ($config['packages'] as $name => $package) {
+ $packages[$name] = new Definition('Symfony\\Component\\Templating\\Asset\\AssetPackage', array(
+ $package['base_urls'],
+ $package['version'],
+ ));
+ }
+ $container->setParameter('templating.assets.packages', $packages);
+
if (!empty($config['loaders'])) {
$loaders = array_map(function($loader) { return new Reference($loader); }, $config['loaders']);
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd
index 2fc04e86fa15..1bc8db6c6672 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd
@@ -91,6 +91,7 @@
+
@@ -102,6 +103,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml
index 1d3323aa3aca..a64b3c094efc 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml
@@ -34,6 +34,7 @@
%templating.assets.base_urls%
%templating.assets.version%
+ %templating.assets.packages%
diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/AssetsHelper.php b/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/AssetsHelper.php
index 8a61e31f627f..d73fcb28e252 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/AssetsHelper.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/AssetsHelper.php
@@ -27,9 +27,10 @@ class AssetsHelper extends BaseAssetsHelper
* @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)
+ public function __construct(Request $request, $baseURLs = array(), $version = null, $packages = array())
{
- parent::__construct($request->getBasePath(), $baseURLs, $version);
+ parent::__construct($request->getBasePath(), $baseURLs, $version, $packages);
}
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php
index 7f201cffcf89..1b2fc7cd416f 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php
@@ -35,6 +35,18 @@
'cache_warmer' => true,
'engines' => array('php', 'twig'),
'loader' => array('loader.foo', 'loader.bar'),
+ 'packages' => array(
+ 'images' => array(
+ 'version' => '1.0.0',
+ 'base_urls' => array('http://images1.example.com', 'http://images2.example.com'),
+ ),
+ 'foo' => array(
+ 'version' => '1.0.0',
+ ),
+ 'bar' => array(
+ 'base_urls' => array('http://bar1.example.com', 'http://bar2.example.com'),
+ ),
+ ),
),
'translator' => array(
'enabled' => true,
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml
index 8cdd6929c318..b03ce66b24cf 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml
@@ -18,6 +18,15 @@
http://cdn.example.com
+
+ http://images1.example.com
+ http://images2.example.com
+
+
+
+ http://bar1.example.com
+ http://bar2.example.com
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml
index b0c6ef141aec..b1d92ff195c6 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml
@@ -28,6 +28,14 @@ framework:
cache_warmer: true
engines: [php, twig]
loader: [loader.foo, loader.bar]
+ packages:
+ images:
+ version: 1.0.0
+ base_urls: ["http://images1.example.com", "http://images2.example.com"]
+ foo:
+ version: 1.0.0
+ bar:
+ base_urls: ["http://images1.example.com", "http://images2.example.com"]
translator:
enabled: true
fallback: fr
diff --git a/src/Symfony/Bundle/TwigBundle/Extension/TemplatingExtension.php b/src/Symfony/Bundle/TwigBundle/Extension/TemplatingExtension.php
index f7c84f3f477a..113e7226987d 100644
--- a/src/Symfony/Bundle/TwigBundle/Extension/TemplatingExtension.php
+++ b/src/Symfony/Bundle/TwigBundle/Extension/TemplatingExtension.php
@@ -83,9 +83,9 @@ public function getUrl($name, array $parameters = array())
return $this->container->get('router')->generate($name, $parameters, true);
}
- public function getAssetUrl($location)
+ public function getAssetUrl($location, $packageName = null)
{
- return $this->container->get('templating.helper.assets')->getUrl($location);
+ return $this->container->get('templating.helper.assets')->getUrl($location, $packageName);
}
/**
diff --git a/src/Symfony/Component/Templating/Asset/AssetPackage.php b/src/Symfony/Component/Templating/Asset/AssetPackage.php
new file mode 100644
index 000000000000..ae6f4c834bae
--- /dev/null
+++ b/src/Symfony/Component/Templating/Asset/AssetPackage.php
@@ -0,0 +1,63 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Templating\Asset;
+
+/**
+ * An asset package.
+ *
+ * @author Kris Wallsmith
+ */
+class AssetPackage implements AssetPackageInterface
+{
+ private $baseUrls;
+ private $version;
+
+ /**
+ * Constructor.
+ *
+ * @param array|string $baseUrls The domain URL or an array of domain URLs
+ * @param string $version The version
+ */
+ public function __construct($baseUrls = array(), $version = null)
+ {
+ $this->baseUrls = array();
+ $this->version = $version;
+
+ if (!is_array($baseUrls)) {
+ $baseUrls = (array) $baseUrls;
+ }
+
+ foreach ($baseUrls as $baseUrl) {
+ $this->baseUrls[] = rtrim($baseUrl, '/');
+ }
+ }
+
+ public function getVersion()
+ {
+ return $this->version;
+ }
+
+ public function getBaseUrl($path)
+ {
+ $count = count($this->baseUrls);
+
+ if (0 === $count) {
+ return '';
+ }
+
+ if (1 === $count) {
+ return $this->baseUrls[0];
+ }
+
+ return $this->baseUrls[fmod(hexdec(substr(md5($path), 0, 10)), $count)];
+ }
+}
diff --git a/src/Symfony/Component/Templating/Asset/AssetPackageInterface.php b/src/Symfony/Component/Templating/Asset/AssetPackageInterface.php
new file mode 100644
index 000000000000..b8d15d38e6d3
--- /dev/null
+++ b/src/Symfony/Component/Templating/Asset/AssetPackageInterface.php
@@ -0,0 +1,36 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Templating\Asset;
+
+/**
+ * Asset package interface.
+ *
+ * @author Kris Wallsmith
+ */
+interface AssetPackageInterface
+{
+ /**
+ * Returns the asset package version.
+ *
+ * @return string The version string
+ */
+ function getVersion();
+
+ /**
+ * Returns a base URL for the supplied path.
+ *
+ * @param string $path An asset path
+ *
+ * @return string A base URL
+ */
+ function getBaseUrl($path);
+}
diff --git a/src/Symfony/Component/Templating/Helper/AssetsHelper.php b/src/Symfony/Component/Templating/Helper/AssetsHelper.php
index ff38cdbe6350..5b7b3c2c2fa9 100644
--- a/src/Symfony/Component/Templating/Helper/AssetsHelper.php
+++ b/src/Symfony/Component/Templating/Helper/AssetsHelper.php
@@ -11,6 +11,9 @@
namespace Symfony\Component\Templating\Helper;
+use Symfony\Component\Templating\Asset\AssetPackage;
+use Symfony\Component\Templating\Asset\AssetPackageInterface;
+
/**
* AssetsHelper is the base class for all helper classes that manages assets.
*
@@ -22,11 +25,11 @@
*
* @author Fabien Potencier
*/
-class AssetsHelper extends Helper
+class AssetsHelper extends Helper implements AssetPackageInterface
{
protected $version;
- protected $baseURLs;
- protected $basePath;
+ protected $defaultPackage;
+ protected $packages;
/**
* Constructor.
@@ -34,32 +37,62 @@ class AssetsHelper extends Helper
* @param string $basePath The base path
* @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($basePath = null, $baseURLs = array(), $version = null)
+ public function __construct($basePath = null, $baseUrls = array(), $version = null, $packages = array())
{
$this->setBasePath($basePath);
- $this->setBaseURLs($baseURLs);
- $this->version = $version;
+ $this->defaultPackage = new AssetPackage($baseUrls, $version);
+ $this->packages = array();
+
+ foreach ($packages as $name => $package) {
+ $this->setPackage($name, $package);
+ }
}
/**
- * Gets the version to add to public URL.
+ * Adds an asset package to the helper.
*
- * @return string The current version
+ * @param string $name The package name
+ * @param AssetPackageInterface $package The package
+ */
+ public function setPackage($name, AssetPackageInterface $package)
+ {
+ $this->packages[$name] = $package;
+ }
+
+ /**
+ * Returns an asset package.
+ *
+ * @param string $name The name of the package or null for the default package
+ *
+ * @return AssetPackageInterface An asset package
+ *
+ * @throws InvalidArgumentException If there is no package by that name
*/
- public function getVersion()
+ public function getPackage($name = null)
{
- return $this->version;
+ if (null === $name) {
+ return $this->defaultPackage;
+ }
+
+ if (!isset($this->packages[$name])) {
+ throw new \InvalidArgumentException(sprintf('There is no "%s" asset package.', $name));
+ }
+
+ return $this->packages[$name];
}
/**
- * Sets the version that is added to each public URL.
+ * Gets the version to add to public URL.
+ *
+ * @param string $package A package name
*
- * @param string $id The version
+ * @return string The current version
*/
- public function setVersion($version)
+ public function getVersion($packageName = null)
{
- $this->version = $version;
+ return $this->getPackage($packageName)->getVersion();
}
/**
@@ -96,71 +129,36 @@ public function setBasePath($basePath)
*
* @return string The base URL
*/
- public function getBaseURL($path)
- {
- $count = count($this->baseURLs);
-
- if (0 === $count) {
- return '';
- }
-
- if (1 === $count) {
- return $this->baseURLs[0];
- }
-
- return $this->baseURLs[fmod(hexdec(substr(md5($path), 0, 10)), $count)];
-
- }
-
- /**
- * Gets the base URLs.
- *
- * @return array The base URLs
- */
- public function getBaseURLs()
- {
- return $this->baseURLs;
- }
-
- /**
- * Sets the base URLs.
- *
- * If you pass an array, the getBaseURL() will return a
- * randomly pick one to use for each asset.
- *
- * @param string|array $baseURLs The base URLs
- */
- public function setBaseURLs($baseURLs)
+ public function getBaseUrl($path, $packageName = null)
{
- if (!is_array($baseURLs)) {
- $baseURLs = array($baseURLs);
- }
-
- $this->baseURLs = array();
- foreach ($baseURLs as $URL) {
- $this->baseURLs[] = rtrim($URL, '/');
- }
+ return $this->getPackage($packageName)->getBaseUrl($path);
}
/**
* Returns the public path.
*
- * @param string $path A public path
+ * Absolute paths (i.e. http://...) are returned unmodified.
+ *
+ * @param string $path A public path
+ * @param string $packageName The name of the asset package to use
*
* @return string A public path which takes into account the base path and URL path
*/
- public function getUrl($path)
+ public function getUrl($path, $packageName = null)
{
if (false !== strpos($path, '://')) {
return $path;
}
- $base = $this->getBaseURL($path);
+ $package = $this->getPackage($packageName);
+ $base = $package->getBaseUrl($path);
+ $version = $package->getVersion();
+
if (0 !== strpos($path, '/')) {
$path = $base ? '/'.$path : $this->basePath.$path;
}
- return $base.$path.($this->version ? '?'.$this->version : '');
+ return $base.$path.($version ? '?'.$version : '');
}
/**
diff --git a/tests/Symfony/Tests/Component/Templating/Helper/AssetsTest.php b/tests/Symfony/Tests/Component/Templating/Helper/AssetsHelperTest.php
similarity index 73%
rename from tests/Symfony/Tests/Component/Templating/Helper/AssetsTest.php
rename to tests/Symfony/Tests/Component/Templating/Helper/AssetsHelperTest.php
index e93044e02b06..fd5d01e0733b 100644
--- a/tests/Symfony/Tests/Component/Templating/Helper/AssetsTest.php
+++ b/tests/Symfony/Tests/Component/Templating/Helper/AssetsHelperTest.php
@@ -11,6 +11,7 @@
namespace Symfony\Tests\Component\Templating\Helper;
+use Symfony\Component\Templating\Asset\AssetPackage;
use Symfony\Component\Templating\Helper\AssetsHelper;
class AssetsHelperTest extends \PHPUnit_Framework_TestCase
@@ -19,8 +20,7 @@ public function testConstructor()
{
$helper = new AssetsHelper('foo', 'http://www.example.com', 'abcd');
$this->assertEquals('/foo/', $helper->getBasePath(), '__construct() takes a base path as its first argument');
- $this->assertEquals(array('http://www.example.com'), $helper->getBaseURLs(), '__construct() takes a base URL as its second argument');
- $this->assertEquals('abcd', $helper->getVersion(), '__construct() takes a version as its thrid argument');
+ $this->assertEquals(new AssetPackage('http://www.example.com', 'abcd'), $helper->getPackage(), '->__construct() creates a default asset package');
}
public function testGetSetBasePath()
@@ -36,28 +36,10 @@ public function testGetSetBasePath()
$this->assertEquals('/0/', $helper->getBasePath(), '->setBasePath() returns /0/ if 0 is given');
}
- public function testGetSetVersion()
+ public function testGetVersion()
{
- $helper = new AssetsHelper();
- $helper->setVersion('foo');
- $this->assertEquals('foo', $helper->getVersion(), '->setVersion() sets the version');
- }
-
- public function testSetGetBaseURLs()
- {
- $helper = new AssetsHelper();
- $helper->setBaseURLs('http://www.example.com/');
- $this->assertEquals(array('http://www.example.com'), $helper->getBaseURLs(), '->setBaseURLs() removes the / at the of an absolute base path');
- $helper->setBaseURLs(array('http://www1.example.com/', 'http://www2.example.com/'));
- $URLs = array();
- for ($i = 0; $i < 20; $i++) {
- $URLs[] = $helper->getBaseURL($i);
- }
- $URLs = array_values(array_unique($URLs));
- sort($URLs);
- $this->assertEquals(array('http://www1.example.com', 'http://www2.example.com'), $URLs, '->getBaseURL() returns a random base URL if several are given');
- $helper->setBaseURLs('');
- $this->assertEquals('', $helper->getBaseURL(1), '->getBaseURL() returns an empty string if no base URL exist');
+ $helper = new AssetsHelper(null, array(), 'foo');
+ $this->assertEquals('foo', $helper->getVersion(), '->getVersion() returns the version');
}
public function testGetUrl()