From 2642b0012ffce0189fc83f598052265e1d9e4a72 Mon Sep 17 00:00:00 2001 From: Kris Wallsmith Date: Fri, 20 May 2011 05:59:39 -0700 Subject: [PATCH 1/2] [Templating] reworked asset helper and packages Added support for a configurable format string used to apply version to a path (defaults to '%s?%s'). Moved base url/base path logic to packages. --- .../Templating/Asset/AssetPackage.php | 59 ------- .../Component/Templating/Asset/Package.php | 71 ++++++++ ...kageInterface.php => PackageInterface.php} | 10 +- .../Templating/Asset/PathPackage.php | 70 ++++++++ .../Component/Templating/Asset/UrlPackage.php | 77 +++++++++ .../Templating/Helper/AssetsHelper.php | 157 ++---------------- .../Templating/Helper/CoreAssetsHelper.php | 128 ++++++++++++++ .../Templating/Helper/AssetsHelperTest.php | 20 --- 8 files changed, 368 insertions(+), 224 deletions(-) delete mode 100644 src/Symfony/Component/Templating/Asset/AssetPackage.php create mode 100644 src/Symfony/Component/Templating/Asset/Package.php rename src/Symfony/Component/Templating/Asset/{AssetPackageInterface.php => PackageInterface.php} (74%) create mode 100644 src/Symfony/Component/Templating/Asset/PathPackage.php create mode 100644 src/Symfony/Component/Templating/Asset/UrlPackage.php create mode 100644 src/Symfony/Component/Templating/Helper/CoreAssetsHelper.php diff --git a/src/Symfony/Component/Templating/Asset/AssetPackage.php b/src/Symfony/Component/Templating/Asset/AssetPackage.php deleted file mode 100644 index 19ace2af3a0f2..0000000000000 --- a/src/Symfony/Component/Templating/Asset/AssetPackage.php +++ /dev/null @@ -1,59 +0,0 @@ - - * - * 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; - - foreach ((array) $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/Package.php b/src/Symfony/Component/Templating/Asset/Package.php new file mode 100644 index 0000000000000..f693fd519a7fe --- /dev/null +++ b/src/Symfony/Component/Templating/Asset/Package.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Templating\Asset; + +/** + * The basic package will add a version to asset URLs. + * + * @author Kris Wallsmith + */ +class Package implements PackageInterface +{ + private $version; + private $format; + + /** + * Constructor. + * + * @param string $version The package version + * @param string $format The format used to apply the version + */ + public function __construct($version = null, $format = null) + { + $this->version = $version; + $this->format = $format ?: '%s?%s'; + } + + public function getVersion() + { + return $this->version; + } + + public function getUrl($path) + { + if (false !== strpos($path, '://') || 0 === strpos($path, '//')) { + return $path; + } + + return $this->applyVersion($path); + } + + /** + * Applies version to the supplied path. + * + * @param string $path A path + * + * @return string The versionized path + */ + protected function applyVersion($path) + { + if (null === $this->version) { + return $path; + } + + $versionized = sprintf($this->format, ltrim($path, '/'), $this->version); + + if ($path && '/' == $path[0]) { + $versionized = '/'.$versionized; + } + + return $versionized; + } +} diff --git a/src/Symfony/Component/Templating/Asset/AssetPackageInterface.php b/src/Symfony/Component/Templating/Asset/PackageInterface.php similarity index 74% rename from src/Symfony/Component/Templating/Asset/AssetPackageInterface.php rename to src/Symfony/Component/Templating/Asset/PackageInterface.php index b8d15d38e6d30..a3dcde979bd54 100644 --- a/src/Symfony/Component/Templating/Asset/AssetPackageInterface.php +++ b/src/Symfony/Component/Templating/Asset/PackageInterface.php @@ -16,7 +16,7 @@ * * @author Kris Wallsmith */ -interface AssetPackageInterface +interface PackageInterface { /** * Returns the asset package version. @@ -26,11 +26,11 @@ interface AssetPackageInterface function getVersion(); /** - * Returns a base URL for the supplied path. + * Returns an absolute or root-relative public path. * - * @param string $path An asset path + * @param string $path A path * - * @return string A base URL + * @return string The public path */ - function getBaseUrl($path); + function getUrl($path); } diff --git a/src/Symfony/Component/Templating/Asset/PathPackage.php b/src/Symfony/Component/Templating/Asset/PathPackage.php new file mode 100644 index 0000000000000..c245560b204ed --- /dev/null +++ b/src/Symfony/Component/Templating/Asset/PathPackage.php @@ -0,0 +1,70 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Templating\Asset; + +/** + * The path packages adds a version and a base path to asset URLs. + * + * @author Kris Wallsmith + */ +class PathPackage extends Package +{ + private $basePath; + + /** + * Constructor. + * + * @param string $basePath The base path to be prepended to relative paths + * @param string $version The package version + * @param string $format The format used to apply the version + */ + public function __construct($basePath = null, $version = null, $format = null) + { + parent::__construct($version, $format); + + if (!$basePath) { + $this->basePath = '/'; + } else { + if ('/' != $basePath[0]) { + $basePath = '/'.$basePath; + } + + $this->basePath = rtrim($basePath, '/').'/'; + } + } + + public function getUrl($path) + { + if (false !== strpos($path, '://') || 0 === strpos($path, '//')) { + return $path; + } + + $url = $this->applyVersion($path); + + // apply the base path + if ($url && '/' != $url[0]) { + $url = $this->basePath.$url; + } + + return $url; + } + + /** + * Returns the base path. + * + * @return string The base path + */ + public function getBasePath() + { + return $this->basePath; + } +} diff --git a/src/Symfony/Component/Templating/Asset/UrlPackage.php b/src/Symfony/Component/Templating/Asset/UrlPackage.php new file mode 100644 index 0000000000000..1a4c493fb614b --- /dev/null +++ b/src/Symfony/Component/Templating/Asset/UrlPackage.php @@ -0,0 +1,77 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Templating\Asset; + +/** + * The URL packages adds a version and a base URL to asset URLs. + * + * @author Kris Wallsmith + */ +class UrlPackage extends Package +{ + private $baseUrls; + + /** + * Constructor. + * + * @param string|array $baseUrls Base asset URLs + * @param string $version The package version + * @param string $format The format used to apply the version + */ + public function __construct($baseUrls = array(), $version = null, $format = null) + { + parent::__construct($version, $format); + + if (!is_array($baseUrls)) { + $baseUrls = (array) $baseUrls; + } + + $this->baseUrls = array(); + foreach ($baseUrls as $baseUrl) { + $this->baseUrls[] = rtrim($baseUrl, '/'); + } + } + + public function getUrl($path) + { + if (false !== strpos($path, '://') || 0 === strpos($path, '//')) { + return $path; + } + + $url = $this->applyVersion($path); + + if ($url && '/' != $url[0]) { + $url = '/'.$url; + } + + return $this->getBaseUrl($path).$url; + } + + /** + * Returns the base URL for a path. + * + * @return string The base URL + */ + public function getBaseUrl($path) + { + switch ($count = count($this->baseUrls)) { + case 0: + return ''; + + case 1: + return $this->baseUrls[0]; + + default: + return $this->baseUrls[fmod(hexdec(substr(md5($path), 0, 10)), $count)]; + } + } +} diff --git a/src/Symfony/Component/Templating/Helper/AssetsHelper.php b/src/Symfony/Component/Templating/Helper/AssetsHelper.php index 04b4c6f407ccc..32cafafb1f799 100644 --- a/src/Symfony/Component/Templating/Helper/AssetsHelper.php +++ b/src/Symfony/Component/Templating/Helper/AssetsHelper.php @@ -11,11 +11,12 @@ namespace Symfony\Component\Templating\Helper; -use Symfony\Component\Templating\Asset\AssetPackage; -use Symfony\Component\Templating\Asset\AssetPackageInterface; +use Symfony\Component\Templating\Asset\Package; +use Symfony\Component\Templating\Asset\PathPackage; +use Symfony\Component\Templating\Asset\UrlPackage; /** - * AssetsHelper is the base class for all helper classes that manages assets. + * AssetsHelper helps manage asset URLs. * * Usage: * @@ -24,151 +25,27 @@ * * * @author Fabien Potencier + * @author Kris Wallsmith */ -class AssetsHelper extends Helper implements AssetPackageInterface +class AssetsHelper extends CoreAssetsHelper { - protected $version; - protected $defaultPackage; - protected $packages; - /** * Constructor. * - * @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, $packages = array()) - { - $this->setBasePath($basePath); - $this->defaultPackage = new AssetPackage($baseUrls, $version); - $this->packages = array(); - - foreach ($packages as $name => $package) { - $this->setPackage($name, $package); - } - } - - /** - * Adds an asset package to the helper. - * - * @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 + * @param string $basePath The base path + * @param string|array $baseUrls Base asset URLs + * @param string $version The asset version + * @param string $format The version format + * @param array $namedPackages Additional packages */ - public function getPackage($name = null) + public function __construct($basePath = null, $baseUrls = array(), $version = null, $format = null, $namedPackages = array()) { - if (null === $name) { - return $this->defaultPackage; + if ($baseUrls) { + $defaultPackage = new UrlPackage($baseUrls, $version, $format); + } else { + $defaultPackage = new PathPackage($basePath, $version, $format); } - if (!isset($this->packages[$name])) { - throw new \InvalidArgumentException(sprintf('There is no "%s" asset package.', $name)); - } - - return $this->packages[$name]; - } - - /** - * Gets the version to add to public URL. - * - * @param string $packageName A package name - * - * @return string The current version - */ - public function getVersion($packageName = null) - { - return $this->getPackage($packageName)->getVersion(); - } - - /** - * Gets the base path. - * - * @return string The base path - */ - public function getBasePath() - { - return $this->basePath; - } - - /** - * Sets the base path. - * - * @param string $basePath The base path - */ - public function setBasePath($basePath) - { - if (strlen($basePath) && '/' != $basePath[0]) { - $basePath = '/'.$basePath; - } - - $this->basePath = rtrim($basePath, '/').'/'; - } - - /** - * Gets the base URL. - * - * If multiple base URLs have been defined a random one will be picked for each asset. - * In other words: for one asset path the same base URL will always be picked among the available base URLs. - * - * @param string $path The path - * @param string $packageName The package name - * - * @return string The base URL - */ - public function getBaseUrl($path, $packageName = null) - { - return $this->getPackage($packageName)->getBaseUrl($path); - } - - /** - * Returns the 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, $packageName = null) - { - if (false !== strpos($path, '://') || 0 === strpos($path, '//')) { - return $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.($version ? '?'.$version : ''); - } - - /** - * Returns the canonical name of this helper. - * - * @return string The canonical name - */ - public function getName() - { - return 'assets'; + parent::__construct($defaultPackage, $namedPackages); } } diff --git a/src/Symfony/Component/Templating/Helper/CoreAssetsHelper.php b/src/Symfony/Component/Templating/Helper/CoreAssetsHelper.php new file mode 100644 index 0000000000000..95f2ff1bd3df0 --- /dev/null +++ b/src/Symfony/Component/Templating/Helper/CoreAssetsHelper.php @@ -0,0 +1,128 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Templating\Helper; + +use Symfony\Component\Templating\Asset\PackageInterface; + +/** + * CoreAssetsHelper helps manage asset URLs. + * + * Usage: + * + * + * + * + * + * @author Fabien Potencier + * @author Kris Wallsmith + */ +class CoreAssetsHelper extends Helper implements PackageInterface +{ + protected $defaultPackage; + protected $namedPackages; + + /** + * Constructor. + * + * @param PackageInterface $defaultPackage The default package + * @param array $namedPackages Additional packages indexed by name + */ + public function __construct(PackageInterface $defaultPackage, array $namedPackages = array()) + { + $this->defaultPackage = $defaultPackage; + $this->namedPackages = array(); + + foreach ($namedPackages as $name => $package) { + $this->addPackage($name, $package); + } + } + + /** + * Sets the default package. + * + * @param PackageInterface $defaultPackage The default package + */ + public function setDefaultPackage(PackageInterface $defaultPackage) + { + $this->defaultPackage = $defaultPackage; + } + + /** + * Adds an asset package to the helper. + * + * @param string $name The package name + * @param PackageInterface $package The package + */ + public function addPackage($name, PackageInterface $package) + { + $this->namedPackages[$name] = $package; + } + + /** + * Returns an asset package. + * + * @param string $name The name of the package or null for the default package + * + * @return PackageInterface An asset package + * + * @throws InvalidArgumentException If there is no package by that name + */ + public function getPackage($name = null) + { + if (null === $name) { + return $this->defaultPackage; + } + + if (!isset($this->namedPackages[$name])) { + throw new \InvalidArgumentException(sprintf('There is no "%s" asset package.', $name)); + } + + return $this->namedPackages[$name]; + } + + /** + * Gets the version to add to public URL. + * + * @param string $packageName A package name + * + * @return string The current version + */ + public function getVersion($packageName = null) + { + return $this->getPackage($packageName)->getVersion(); + } + + /** + * Returns the 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, $packageName = null) + { + return $this->getPackage($packageName)->getUrl($path); + } + + /** + * Returns the canonical name of this helper. + * + * @return string The canonical name + */ + public function getName() + { + return 'assets'; + } +} diff --git a/tests/Symfony/Tests/Component/Templating/Helper/AssetsHelperTest.php b/tests/Symfony/Tests/Component/Templating/Helper/AssetsHelperTest.php index e7b6d90d943f4..3f500051ca6c1 100644 --- a/tests/Symfony/Tests/Component/Templating/Helper/AssetsHelperTest.php +++ b/tests/Symfony/Tests/Component/Templating/Helper/AssetsHelperTest.php @@ -16,26 +16,6 @@ class AssetsHelperTest extends \PHPUnit_Framework_TestCase { - 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(new AssetPackage('http://www.example.com', 'abcd'), $helper->getPackage(), '->__construct() creates a default asset package'); - } - - public function testGetSetBasePath() - { - $helper = new AssetsHelper(); - $helper->setBasePath('foo/'); - $this->assertEquals('/foo/', $helper->getBasePath(), '->setBasePath() prepends a / if needed'); - $helper->setBasePath('/foo'); - $this->assertEquals('/foo/', $helper->getBasePath(), '->setBasePath() appends a / is needed'); - $helper->setBasePath(''); - $this->assertEquals('/', $helper->getBasePath(), '->setBasePath() returns / if no base path is defined'); - $helper->setBasePath('0'); - $this->assertEquals('/0/', $helper->getBasePath(), '->setBasePath() returns /0/ if 0 is given'); - } - public function testGetVersion() { $helper = new AssetsHelper(null, array(), 'foo'); From d9f5c99fabc649b7067daf6f2f69bdd86f6f715b Mon Sep 17 00:00:00 2001 From: Kris Wallsmith Date: Fri, 20 May 2011 16:08:03 -0700 Subject: [PATCH 2/2] [FrameworkBundle] updated for templating changes, added http/ssl logic --- .../DependencyInjection/Configuration.php | 61 ++++++++++++- .../FrameworkExtension.php | 88 +++++++++++++++++-- .../Resources/config/schema/symfony-1.0.xsd | 2 + .../Resources/config/templating_php.xml | 34 +++++-- .../Templating/Asset/PackageFactory.php | 44 ++++++++++ .../Templating/Asset/PathPackage.php | 35 ++++++++ .../Templating/Helper/AssetsHelper.php | 36 -------- .../FrameworkExtensionTest.php | 20 +++-- 8 files changed, 260 insertions(+), 60 deletions(-) create mode 100644 src/Symfony/Bundle/FrameworkBundle/Templating/Asset/PackageFactory.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Templating/Asset/PathPackage.php delete mode 100644 src/Symfony/Bundle/FrameworkBundle/Templating/Helper/AssetsHelper.php diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index 802abe8cbdb4b..da0d6d6e7b714 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -179,21 +179,56 @@ private function addSessionSection(ArrayNodeDefinition $rootNode) 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 @@ private function addTemplatingSection(ArrayNodeDefinition $rootNode) ->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() diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index c3d8abf4b8a52..a10b0548a5533 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -14,6 +14,7 @@ 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 @@ private function registerTemplatingConfiguration(array $config, $ide, ContainerB $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 @@ private function registerTemplatingConfiguration(array $config, $ide, ContainerB } } + /** + * 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. * 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 161ad6690749a..16f8366a4135a 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 @@ -103,6 +103,7 @@ + @@ -114,6 +115,7 @@ + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml index f2b2eec5d4241..ebdf3e6181188 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml @@ -7,7 +7,7 @@ Symfony\Bundle\FrameworkBundle\Templating\PhpEngine Symfony\Component\Templating\Helper\SlotsHelper - Symfony\Bundle\FrameworkBundle\Templating\Helper\AssetsHelper + Symfony\Component\Templating\Helper\CoreAssetsHelper Symfony\Bundle\FrameworkBundle\Templating\Helper\ActionsHelper Symfony\Bundle\FrameworkBundle\Templating\Helper\RouterHelper Symfony\Bundle\FrameworkBundle\Templating\Helper\RequestHelper @@ -16,7 +16,9 @@ Symfony\Bundle\FrameworkBundle\Templating\Helper\TranslatorHelper Symfony\Bundle\FrameworkBundle\Templating\Helper\FormHelper Symfony\Bundle\FrameworkBundle\Templating\GlobalVariables - Symfony\Component\Templating\Asset\AssetPackage + Symfony\Bundle\FrameworkBundle\Templating\Asset\PathPackage + Symfony\Component\Templating\Asset\UrlPackage + Symfony\Bundle\FrameworkBundle\Templating\Asset\PackageFactory @@ -32,12 +34,32 @@ - + + + + + + + + + + + + + + + + + + - %templating.helper.assets.assets_base_urls% - %templating.helper.assets.assets_version% - + + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/Asset/PackageFactory.php b/src/Symfony/Bundle/FrameworkBundle/Templating/Asset/PackageFactory.php new file mode 100644 index 0000000000000..de36a32831960 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/Asset/PackageFactory.php @@ -0,0 +1,44 @@ + + * + * 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 + */ +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); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/Asset/PathPackage.php b/src/Symfony/Bundle/FrameworkBundle/Templating/Asset/PathPackage.php new file mode 100644 index 0000000000000..6aa8c58824669 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/Asset/PathPackage.php @@ -0,0 +1,35 @@ + + * + * 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 + */ +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); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/AssetsHelper.php b/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/AssetsHelper.php deleted file mode 100644 index d73fcb28e2528..0000000000000 --- a/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/AssetsHelper.php +++ /dev/null @@ -1,36 +0,0 @@ - - * - * 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 - */ -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); - } -} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index af9e12b1e2620..4b6948c513155 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -97,11 +97,21 @@ public function testTemplating() $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');