[Asset] added the component
This commit is contained in:
parent
ac389b6714
commit
d33c41d436
@ -22,6 +22,7 @@
|
|||||||
"psr/log": "~1.0"
|
"psr/log": "~1.0"
|
||||||
},
|
},
|
||||||
"replace": {
|
"replace": {
|
||||||
|
"symfony/asset": "self.version",
|
||||||
"symfony/browser-kit": "self.version",
|
"symfony/browser-kit": "self.version",
|
||||||
"symfony/class-loader": "self.version",
|
"symfony/class-loader": "self.version",
|
||||||
"symfony/config": "self.version",
|
"symfony/config": "self.version",
|
||||||
|
@ -6,6 +6,7 @@ CHANGELOG
|
|||||||
|
|
||||||
* added LogoutUrlExtension (provides `logout_url` and `logout_path`)
|
* added LogoutUrlExtension (provides `logout_url` and `logout_path`)
|
||||||
* added an HttpFoundation extension (provides the `absolute_url` and the `relative_path` functions)
|
* added an HttpFoundation extension (provides the `absolute_url` and the `relative_path` functions)
|
||||||
|
* added AssetExtension (provides the `asset_path` function)
|
||||||
|
|
||||||
2.5.0
|
2.5.0
|
||||||
-----
|
-----
|
||||||
|
79
src/Symfony/Bridge/Twig/Extension/AssetExtension.php
Normal file
79
src/Symfony/Bridge/Twig/Extension/AssetExtension.php
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<?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\Bridge\Twig\Extension;
|
||||||
|
|
||||||
|
use Symfony\Component\Asset\Packages;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Twig extension for the Symfony Asset component.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
class AssetExtension extends \Twig_Extension
|
||||||
|
{
|
||||||
|
private $packages;
|
||||||
|
|
||||||
|
public function __construct(Packages $packages)
|
||||||
|
{
|
||||||
|
$this->packages = $packages;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getFunctions()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
new \Twig_SimpleFunction('asset_path', array($this, 'getAssetPath')),
|
||||||
|
new \Twig_SimpleFunction('asset_version', array($this, 'getAssetVersion')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the public path of an asset.
|
||||||
|
*
|
||||||
|
* If the package used to generate the path is an instance of
|
||||||
|
* UrlPackage, you will always get a URL and not a path.
|
||||||
|
*
|
||||||
|
* @param string $path A public path
|
||||||
|
* @param string $packageName The name of the asset package to use
|
||||||
|
*
|
||||||
|
* @return string The public path of the asset
|
||||||
|
*/
|
||||||
|
public function getAssetPath($path, $packageName = null)
|
||||||
|
{
|
||||||
|
return $this->packages->getUrl($path, $packageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the version of an asset.
|
||||||
|
*
|
||||||
|
* @param string $path A public path
|
||||||
|
* @param string $packageName The name of the asset package to use
|
||||||
|
*
|
||||||
|
* @return string The asset version
|
||||||
|
*/
|
||||||
|
public function getAssetVersion($path, $packageName = null)
|
||||||
|
{
|
||||||
|
return $this->packages->getVersion($path, $packageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the extension.
|
||||||
|
*
|
||||||
|
* @return string The extension name
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return 'asset';
|
||||||
|
}
|
||||||
|
}
|
@ -37,6 +37,7 @@
|
|||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"symfony/finder": "",
|
"symfony/finder": "",
|
||||||
|
"symfony/asset": "For using the AssetExtension",
|
||||||
"symfony/form": "For using the FormExtension",
|
"symfony/form": "For using the FormExtension",
|
||||||
"symfony/http-kernel": "For using the HttpKernelExtension",
|
"symfony/http-kernel": "For using the HttpKernelExtension",
|
||||||
"symfony/routing": "For using the RoutingExtension",
|
"symfony/routing": "For using the RoutingExtension",
|
||||||
|
@ -16,6 +16,9 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
|
|||||||
use Symfony\Component\DependencyInjection\Definition;
|
use Symfony\Component\DependencyInjection\Definition;
|
||||||
use Symfony\Component\DependencyInjection\Reference;
|
use Symfony\Component\DependencyInjection\Reference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated since 2.7, will be removed in 3.0
|
||||||
|
*/
|
||||||
class TemplatingAssetHelperPass implements CompilerPassInterface
|
class TemplatingAssetHelperPass implements CompilerPassInterface
|
||||||
{
|
{
|
||||||
public function process(ContainerBuilder $container)
|
public function process(ContainerBuilder $container)
|
||||||
|
@ -108,6 +108,7 @@ class Configuration implements ConfigurationInterface
|
|||||||
$this->addSessionSection($rootNode);
|
$this->addSessionSection($rootNode);
|
||||||
$this->addRequestSection($rootNode);
|
$this->addRequestSection($rootNode);
|
||||||
$this->addTemplatingSection($rootNode);
|
$this->addTemplatingSection($rootNode);
|
||||||
|
$this->addAssetsSection($rootNode);
|
||||||
$this->addTranslatorSection($rootNode);
|
$this->addTranslatorSection($rootNode);
|
||||||
$this->addValidationSection($rootNode);
|
$this->addValidationSection($rootNode);
|
||||||
$this->addAnnotationsSection($rootNode);
|
$this->addAnnotationsSection($rootNode);
|
||||||
@ -347,8 +348,8 @@ class Configuration implements ConfigurationInterface
|
|||||||
->info('templating configuration')
|
->info('templating configuration')
|
||||||
->canBeUnset()
|
->canBeUnset()
|
||||||
->children()
|
->children()
|
||||||
->scalarNode('assets_version')->defaultValue(null)->end()
|
->scalarNode('assets_version')->defaultNull()->info('Deprecated since 2.7, will be removed in 3.0. Use the new assets entry instead.')->end()
|
||||||
->scalarNode('assets_version_format')->defaultValue('%%s?%%s')->end()
|
->scalarNode('assets_version_format')->defaultValue('%%s?%%s')->info('Deprecated since 2.7, will be removed in 3.0. Use the new assets entry instead.')->end()
|
||||||
->scalarNode('hinclude_default_template')->defaultNull()->end()
|
->scalarNode('hinclude_default_template')->defaultNull()->end()
|
||||||
->arrayNode('form')
|
->arrayNode('form')
|
||||||
->addDefaultsIfNotSet()
|
->addDefaultsIfNotSet()
|
||||||
@ -370,6 +371,7 @@ class Configuration implements ConfigurationInterface
|
|||||||
->fixXmlConfig('assets_base_url')
|
->fixXmlConfig('assets_base_url')
|
||||||
->children()
|
->children()
|
||||||
->arrayNode('assets_base_urls')
|
->arrayNode('assets_base_urls')
|
||||||
|
->info('Deprecated since 2.7, will be removed in 3.0. Use the new assets entry instead.')
|
||||||
->performNoDeepMerging()
|
->performNoDeepMerging()
|
||||||
->addDefaultsIfNotSet()
|
->addDefaultsIfNotSet()
|
||||||
->beforeNormalization()
|
->beforeNormalization()
|
||||||
@ -417,6 +419,7 @@ class Configuration implements ConfigurationInterface
|
|||||||
->fixXmlConfig('package')
|
->fixXmlConfig('package')
|
||||||
->children()
|
->children()
|
||||||
->arrayNode('packages')
|
->arrayNode('packages')
|
||||||
|
->info('Deprecated since 2.7, will be removed in 3.0. Use the new assets entry instead.')
|
||||||
->useAttributeAsKey('name')
|
->useAttributeAsKey('name')
|
||||||
->prototype('array')
|
->prototype('array')
|
||||||
->fixXmlConfig('base_url')
|
->fixXmlConfig('base_url')
|
||||||
@ -452,6 +455,54 @@ class Configuration implements ConfigurationInterface
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function addAssetsSection(ArrayNodeDefinition $rootNode)
|
||||||
|
{
|
||||||
|
$rootNode
|
||||||
|
->children()
|
||||||
|
->arrayNode('assets')
|
||||||
|
->info('assets configuration')
|
||||||
|
->canBeUnset()
|
||||||
|
->fixXmlConfig('base_url')
|
||||||
|
->children()
|
||||||
|
->scalarNode('version')->defaultNull()->end()
|
||||||
|
->scalarNode('version_format')->defaultValue('%%s?%%s')->end()
|
||||||
|
->scalarNode('base_path')->defaultValue('')->end()
|
||||||
|
->arrayNode('base_urls')
|
||||||
|
->requiresAtLeastOneElement()
|
||||||
|
->beforeNormalization()
|
||||||
|
->ifTrue(function ($v) { return !is_array($v); })
|
||||||
|
->then(function ($v) { return array($v); })
|
||||||
|
->end()
|
||||||
|
->prototype('scalar')->end()
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
|
->fixXmlConfig('package')
|
||||||
|
->children()
|
||||||
|
->arrayNode('packages')
|
||||||
|
->useAttributeAsKey('name')
|
||||||
|
->prototype('array')
|
||||||
|
->fixXmlConfig('base_url')
|
||||||
|
->children()
|
||||||
|
->scalarNode('version')->defaultNull()->end()
|
||||||
|
->scalarNode('version_format')->defaultNull()->end()
|
||||||
|
->scalarNode('base_path')->defaultValue('')->end()
|
||||||
|
->arrayNode('base_urls')
|
||||||
|
->requiresAtLeastOneElement()
|
||||||
|
->beforeNormalization()
|
||||||
|
->ifTrue(function ($v) { return !is_array($v); })
|
||||||
|
->then(function ($v) { return array($v); })
|
||||||
|
->end()
|
||||||
|
->prototype('scalar')->end()
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
private function addTranslatorSection(ArrayNodeDefinition $rootNode)
|
private function addTranslatorSection(ArrayNodeDefinition $rootNode)
|
||||||
{
|
{
|
||||||
$rootNode
|
$rootNode
|
||||||
|
@ -101,6 +101,10 @@ class FrameworkExtension extends Extension
|
|||||||
|
|
||||||
$this->registerSecurityCsrfConfiguration($config['csrf_protection'], $container, $loader);
|
$this->registerSecurityCsrfConfiguration($config['csrf_protection'], $container, $loader);
|
||||||
|
|
||||||
|
if (isset($config['assets'])) {
|
||||||
|
$this->registerAssetsConfiguration($config['assets'], $container, $loader);
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($config['templating'])) {
|
if (isset($config['templating'])) {
|
||||||
$this->registerTemplatingConfiguration($config['templating'], $config['ide'], $container, $loader);
|
$this->registerTemplatingConfiguration($config['templating'], $config['ide'], $container, $loader);
|
||||||
}
|
}
|
||||||
@ -632,6 +636,86 @@ class FrameworkExtension extends Extension
|
|||||||
return $package;
|
return $package;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the assets configuration.
|
||||||
|
*
|
||||||
|
* @param array $config A assets configuration array
|
||||||
|
* @param ContainerBuilder $container A ContainerBuilder instance
|
||||||
|
* @param XmlFileLoader $loader An XmlFileLoader instance
|
||||||
|
*/
|
||||||
|
private function registerAssetsConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader)
|
||||||
|
{
|
||||||
|
$loader->load('assets.xml');
|
||||||
|
|
||||||
|
$defaultVersion = $this->createVersion($container, $config['version'], $config['version_format']);
|
||||||
|
|
||||||
|
$defaultPackage = $this->createPackageDefinition($config['base_path'], $config['base_urls'], $defaultVersion);
|
||||||
|
$container->setDefinition('assets._default_package', $defaultPackage);
|
||||||
|
|
||||||
|
$namedPackages = array();
|
||||||
|
foreach ($config['packages'] as $name => $package) {
|
||||||
|
if (null === $package['version']) {
|
||||||
|
$version = $defaultVersion;
|
||||||
|
} else {
|
||||||
|
$format = $package['version_format'] ?: $config['version_format'];
|
||||||
|
|
||||||
|
$version = $this->createVersion($container, $package['version'], $format, $name);
|
||||||
|
}
|
||||||
|
|
||||||
|
$container->setDefinition('assets._package_'.$name, $this->createPackageDefinition($package['base_path'], $package['base_urls'], $version));
|
||||||
|
$namedPackages[$name] = new Reference('assets._package_'.$name);
|
||||||
|
}
|
||||||
|
|
||||||
|
$container->getDefinition('assets.packages')
|
||||||
|
->replaceArgument(0, new Reference('assets._default_package'))
|
||||||
|
->replaceArgument(1, $namedPackages)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a definition for an asset package.
|
||||||
|
*/
|
||||||
|
private function createPackageDefinition($basePath, array $baseUrls, Reference $version)
|
||||||
|
{
|
||||||
|
if ($basePath && $baseUrls) {
|
||||||
|
throw new \LogicException('An asset package cannot have base URLs and base paths.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$baseUrls) {
|
||||||
|
$package = new DefinitionDecorator('assets.path_package');
|
||||||
|
|
||||||
|
return $package
|
||||||
|
->setPublic(false)
|
||||||
|
->replaceArgument(0, $basePath)
|
||||||
|
->replaceArgument(1, $version)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
$package = new DefinitionDecorator('assets.url_package');
|
||||||
|
|
||||||
|
return $package
|
||||||
|
->setPublic(false)
|
||||||
|
->replaceArgument(0, $baseUrls)
|
||||||
|
->replaceArgument(1, $version)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createVersion(ContainerBuilder $container, $version, $format, $name = null)
|
||||||
|
{
|
||||||
|
if (!$version) {
|
||||||
|
return new Reference('assets.empty_version_strategy');
|
||||||
|
}
|
||||||
|
|
||||||
|
$def = new DefinitionDecorator('assets.static_version_strategy');
|
||||||
|
$def
|
||||||
|
->replaceArgument(0, $version)
|
||||||
|
->replaceArgument(1, $format)
|
||||||
|
;
|
||||||
|
$container->setDefinition('assets._version_'.$name, $def);
|
||||||
|
|
||||||
|
return new Reference('assets._version_'.$name);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the translator configuration.
|
* Loads the translator configuration.
|
||||||
*
|
*
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" ?>
|
||||||
|
|
||||||
|
<container xmlns="http://symfony.com/schema/dic/services"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||||
|
|
||||||
|
<services>
|
||||||
|
|
||||||
|
<service id="assets.packages" class="Symfony\Component\Asset\Packages">
|
||||||
|
<argument /> <!-- default package -->
|
||||||
|
<argument type="collection" /> <!-- named packages -->
|
||||||
|
</service>
|
||||||
|
|
||||||
|
<service id="assets.context" class="Symfony\Component\Asset\Context\RequestStackContext">
|
||||||
|
<argument type="service" id="request_stack" />
|
||||||
|
</service>
|
||||||
|
|
||||||
|
<service id="assets.path_package" class="Symfony\Component\Asset\PathPackage" abstract="true">
|
||||||
|
<argument /> <!-- base path -->
|
||||||
|
<argument type="service" /> <!-- version strategy -->
|
||||||
|
<call method="setContext">
|
||||||
|
<argument type="service" id="assets.context" />
|
||||||
|
</call>
|
||||||
|
</service>
|
||||||
|
|
||||||
|
<service id="assets.url_package" class="Symfony\Component\Asset\UrlPackage" abstract="true">
|
||||||
|
<argument /> <!-- base URLs -->
|
||||||
|
<argument type="service" /> <!-- version strategy -->
|
||||||
|
<call method="setContext">
|
||||||
|
<argument type="service" id="assets.context" />
|
||||||
|
</call>
|
||||||
|
</service>
|
||||||
|
|
||||||
|
<service id="assets.static_version_strategy" class="Symfony\Component\Asset\VersionStrategy\StaticVersionStrategy" abstract="true">
|
||||||
|
<argument /> <!-- version -->
|
||||||
|
<argument /> <!-- format -->
|
||||||
|
</service>
|
||||||
|
|
||||||
|
<service id="assets.empty_version_strategy" class="Symfony\Component\Asset\VersionStrategy\EmptyVersionStrategy" public="false" />
|
||||||
|
|
||||||
|
</services>
|
||||||
|
</container>
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
namespace Symfony\Bundle\FrameworkBundle\Templating\Asset;
|
namespace Symfony\Bundle\FrameworkBundle\Templating\Asset;
|
||||||
|
|
||||||
|
trigger_error('The Symfony\Bundle\FrameworkBundle\Templating\Asset\PackageFactory is deprecated since version 2.7 and will be removed in 3.0. Use the Asset component instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\Templating\Asset\PackageInterface;
|
use Symfony\Component\Templating\Asset\PackageInterface;
|
||||||
@ -19,6 +21,8 @@ use Symfony\Component\Templating\Asset\PackageInterface;
|
|||||||
* Creates packages based on whether the current request is secure.
|
* Creates packages based on whether the current request is secure.
|
||||||
*
|
*
|
||||||
* @author Kris Wallsmith <kris@symfony.com>
|
* @author Kris Wallsmith <kris@symfony.com>
|
||||||
|
*
|
||||||
|
* @deprecated since 2.7, will be removed in 3.0. Use the Asset component instead.
|
||||||
*/
|
*/
|
||||||
class PackageFactory
|
class PackageFactory
|
||||||
{
|
{
|
||||||
|
@ -14,10 +14,14 @@ namespace Symfony\Bundle\FrameworkBundle\Templating\Asset;
|
|||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\Templating\Asset\PathPackage as BasePathPackage;
|
use Symfony\Component\Templating\Asset\PathPackage as BasePathPackage;
|
||||||
|
|
||||||
|
trigger_error('The Symfony\Bundle\FrameworkBundle\Templating\Asset\PathPackage is deprecated since version 2.7 and will be removed in 3.0. Use the Asset component instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The path packages adds a version and a base path to asset URLs.
|
* The path packages adds a version and a base path to asset URLs.
|
||||||
*
|
*
|
||||||
* @author Kris Wallsmith <kris@symfony.com>
|
* @author Kris Wallsmith <kris@symfony.com>
|
||||||
|
*
|
||||||
|
* @deprecated since 2.7, will be removed in 3.0. Use the Asset component instead.
|
||||||
*/
|
*/
|
||||||
class PathPackage extends BasePathPackage
|
class PathPackage extends BasePathPackage
|
||||||
{
|
{
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
"doctrine/annotations": "~1.0"
|
"doctrine/annotations": "~1.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
"symfony/asset": "~2.7|~3.0.0",
|
||||||
"symfony/browser-kit": "~2.4|~3.0.0",
|
"symfony/browser-kit": "~2.4|~3.0.0",
|
||||||
"symfony/console": "~2.6|~3.0.0",
|
"symfony/console": "~2.6|~3.0.0",
|
||||||
"symfony/css-selector": "~2.0,>=2.0.5|~3.0.0",
|
"symfony/css-selector": "~2.0,>=2.0.5|~3.0.0",
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
CHANGELOG
|
CHANGELOG
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
2.7.0
|
||||||
|
-----
|
||||||
|
|
||||||
|
* added support for the new Asset component (from Twig bridge)
|
||||||
|
* deprecated the assets extension (use the one from the Twig bridge instead)
|
||||||
|
|
||||||
2.6.0
|
2.6.0
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
@ -82,5 +82,9 @@ class ExtensionPass implements CompilerPassInterface
|
|||||||
// we are on Symfony <3.0, where the setContainer method exists
|
// we are on Symfony <3.0, where the setContainer method exists
|
||||||
$container->getDefinition('twig.app_variable')->addMethodCall('setContainer', array(new Reference('service_container')));
|
$container->getDefinition('twig.app_variable')->addMethodCall('setContainer', array(new Reference('service_container')));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($container->has('assets.packages')) {
|
||||||
|
$container->getDefinition('twig.extension.new_assets')->addTag('twig.extension');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,8 @@ use Symfony\Component\Routing\RequestContext;
|
|||||||
* Twig extension for Symfony assets helper.
|
* Twig extension for Symfony assets helper.
|
||||||
*
|
*
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* @deprecated since 2.7, to be removed in 3.0. Use Symfony\Component\Twig\Extension\AssetExtension instead.
|
||||||
*/
|
*/
|
||||||
class AssetsExtension extends \Twig_Extension
|
class AssetsExtension extends \Twig_Extension
|
||||||
{
|
{
|
||||||
@ -57,6 +59,8 @@ class AssetsExtension extends \Twig_Extension
|
|||||||
*/
|
*/
|
||||||
public function getAssetUrl($path, $packageName = null, $absolute = false, $version = null)
|
public function getAssetUrl($path, $packageName = null, $absolute = false, $version = null)
|
||||||
{
|
{
|
||||||
|
trigger_error('The Twig asset() function was deprecated in 2.7 and will be removed in 3.0. Please use asset_path() instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
$url = $this->container->get('templating.helper.assets')->getUrl($path, $packageName, $version);
|
$url = $this->container->get('templating.helper.assets')->getUrl($path, $packageName, $version);
|
||||||
|
|
||||||
if (!$absolute) {
|
if (!$absolute) {
|
||||||
@ -75,6 +79,8 @@ class AssetsExtension extends \Twig_Extension
|
|||||||
*/
|
*/
|
||||||
public function getAssetsVersion($packageName = null)
|
public function getAssetsVersion($packageName = null)
|
||||||
{
|
{
|
||||||
|
trigger_error('The Twig assets_version() function was deprecated in 2.7 and will be removed in 3.0. Please use asset_version() instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
return $this->container->get('templating.helper.assets')->getVersion($packageName);
|
return $this->container->get('templating.helper.assets')->getVersion($packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +92,10 @@
|
|||||||
<argument type="service" id="router.request_context" on-invalid="null" />
|
<argument type="service" id="router.request_context" on-invalid="null" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
|
<service id="twig.extension.new_assets" class="Symfony\Bridge\Twig\Extension\AssetExtension" public="false">
|
||||||
|
<argument type="service" id="assets.packages" />
|
||||||
|
</service>
|
||||||
|
|
||||||
<service id="twig.extension.actions" class="%twig.extension.actions.class%" public="false">
|
<service id="twig.extension.actions" class="%twig.extension.actions.class%" public="false">
|
||||||
<argument type="service" id="fragment.handler" />
|
<argument type="service" id="fragment.handler" />
|
||||||
</service>
|
</service>
|
||||||
|
@ -15,7 +15,7 @@ use Symfony\Bundle\TwigBundle\Extension\AssetsExtension;
|
|||||||
use Symfony\Bundle\TwigBundle\Tests\TestCase;
|
use Symfony\Bundle\TwigBundle\Tests\TestCase;
|
||||||
use Symfony\Component\Routing\RequestContext;
|
use Symfony\Component\Routing\RequestContext;
|
||||||
|
|
||||||
class AssetsExtensionTest extends TestCase
|
class LegacyAssetsExtensionTest extends TestCase
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @dataProvider provideGetGetAssetUrlArguments
|
* @dataProvider provideGetGetAssetUrlArguments
|
3
src/Symfony/Component/Asset/.gitignore
vendored
Normal file
3
src/Symfony/Component/Asset/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
vendor/
|
||||||
|
composer.lock
|
||||||
|
phpunit.xml
|
7
src/Symfony/Component/Asset/CHANGELOG.md
Normal file
7
src/Symfony/Component/Asset/CHANGELOG.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
CHANGELOG
|
||||||
|
=========
|
||||||
|
|
||||||
|
2.7.0
|
||||||
|
-----
|
||||||
|
|
||||||
|
* added the component
|
34
src/Symfony/Component/Asset/Context/ContextInterface.php
Normal file
34
src/Symfony/Component/Asset/Context/ContextInterface.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?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\Component\Asset\Context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds information about the current request.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
interface ContextInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Gets the base path.
|
||||||
|
*
|
||||||
|
* @return string The base path
|
||||||
|
*/
|
||||||
|
public function getBasePath();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the request is secure or not.
|
||||||
|
*
|
||||||
|
* @return bool true if the request is secure, false otherwise
|
||||||
|
*/
|
||||||
|
public function isSecure();
|
||||||
|
}
|
53
src/Symfony/Component/Asset/Context/RequestStackContext.php
Normal file
53
src/Symfony/Component/Asset/Context/RequestStackContext.php
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?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\Component\Asset\Context;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpFoundation\RequestStack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses a RequestStack to populate the context.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
class RequestStackContext implements ContextInterface
|
||||||
|
{
|
||||||
|
private $requestStack;
|
||||||
|
|
||||||
|
public function __construct(RequestStack $requestStack)
|
||||||
|
{
|
||||||
|
$this->requestStack = $requestStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getBasePath()
|
||||||
|
{
|
||||||
|
if (!$request = $this->requestStack->getMasterRequest()) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $request->getBasePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function isSecure()
|
||||||
|
{
|
||||||
|
if (!$request = $this->requestStack->getMasterRequest()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $request->isSecure();
|
||||||
|
}
|
||||||
|
}
|
21
src/Symfony/Component/Asset/Exception/ExceptionInterface.php
Normal file
21
src/Symfony/Component/Asset/Exception/ExceptionInterface.php
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?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\Component\Asset\Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base ExceptionInterface for the Asset component.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
interface ExceptionInterface
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
<?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\Component\Asset\Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base InvalidArgumentException for the Asset component.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
|
||||||
|
{
|
||||||
|
}
|
21
src/Symfony/Component/Asset/Exception/LogicException.php
Normal file
21
src/Symfony/Component/Asset/Exception/LogicException.php
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?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\Component\Asset\Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base LogicException for the Asset component.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
class LogicException extends \LogicException implements ExceptionInterface
|
||||||
|
{
|
||||||
|
}
|
19
src/Symfony/Component/Asset/LICENSE
Normal file
19
src/Symfony/Component/Asset/LICENSE
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Copyright (c) 2004-2015 Fabien Potencier
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is furnished
|
||||||
|
to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
75
src/Symfony/Component/Asset/Package.php
Normal file
75
src/Symfony/Component/Asset/Package.php
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<?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\Component\Asset;
|
||||||
|
|
||||||
|
use Symfony\Component\Asset\Context\ContextInterface;
|
||||||
|
use Symfony\Component\Asset\VersionStrategy\VersionStrategyInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic package that adds a version to asset URLs.
|
||||||
|
*
|
||||||
|
* @author Kris Wallsmith <kris@symfony.com>
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
class Package implements PackageInterface
|
||||||
|
{
|
||||||
|
private $versionStrategy;
|
||||||
|
private $context;
|
||||||
|
|
||||||
|
public function __construct(VersionStrategyInterface $versionStrategy)
|
||||||
|
{
|
||||||
|
$this->versionStrategy = $versionStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getVersion($path)
|
||||||
|
{
|
||||||
|
return $this->versionStrategy->getVersion($path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getUrl($path)
|
||||||
|
{
|
||||||
|
if ($this->isAbsoluteUrl($path)) {
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->versionStrategy->applyVersion($path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setContext(ContextInterface $context)
|
||||||
|
{
|
||||||
|
$this->context = $context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ContextInterface|null
|
||||||
|
*/
|
||||||
|
protected function getContext()
|
||||||
|
{
|
||||||
|
return $this->context;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getVersionStrategy()
|
||||||
|
{
|
||||||
|
return $this->versionStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function isAbsoluteUrl($url)
|
||||||
|
{
|
||||||
|
return false !== strpos($url, '://') || '//' === substr($url, 0, 2);
|
||||||
|
}
|
||||||
|
}
|
38
src/Symfony/Component/Asset/PackageInterface.php
Normal file
38
src/Symfony/Component/Asset/PackageInterface.php
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?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\Component\Asset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asset package interface.
|
||||||
|
*
|
||||||
|
* @author Kris Wallsmith <kris@symfony.com>
|
||||||
|
*/
|
||||||
|
interface PackageInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns the asset version for an asset.
|
||||||
|
*
|
||||||
|
* @param string $path A path
|
||||||
|
*
|
||||||
|
* @return string The version string
|
||||||
|
*/
|
||||||
|
public function getVersion($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an absolute or root-relative public path.
|
||||||
|
*
|
||||||
|
* @param string $path A path
|
||||||
|
*
|
||||||
|
* @return string The public path
|
||||||
|
*/
|
||||||
|
public function getUrl($path);
|
||||||
|
}
|
116
src/Symfony/Component/Asset/Packages.php
Normal file
116
src/Symfony/Component/Asset/Packages.php
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
<?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\Component\Asset;
|
||||||
|
|
||||||
|
use Symfony\Component\Asset\Exception\InvalidArgumentException;
|
||||||
|
use Symfony\Component\Asset\Exception\LogicException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helps manage asset URLs.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
* @author Kris Wallsmith <kris@symfony.com>
|
||||||
|
*/
|
||||||
|
class Packages
|
||||||
|
{
|
||||||
|
private $defaultPackage;
|
||||||
|
private $packages = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param PackageInterface $defaultPackage The default package
|
||||||
|
* @param PackageInterface[] $packages Additional packages indexed by name
|
||||||
|
*/
|
||||||
|
public function __construct(PackageInterface $defaultPackage = null, array $packages = array())
|
||||||
|
{
|
||||||
|
$this->defaultPackage = $defaultPackage;
|
||||||
|
|
||||||
|
foreach ($packages 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 a package.
|
||||||
|
*
|
||||||
|
* @param string $name The package name
|
||||||
|
* @param PackageInterface $package The package
|
||||||
|
*/
|
||||||
|
public function addPackage($name, PackageInterface $package)
|
||||||
|
{
|
||||||
|
$this->packages[$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
|
||||||
|
* @throws LogicException If no default package is defined
|
||||||
|
*/
|
||||||
|
public function getPackage($name = null)
|
||||||
|
{
|
||||||
|
if (null === $name) {
|
||||||
|
if (null === $this->defaultPackage) {
|
||||||
|
throw new LogicException('There is no default asset package, configure one first.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->defaultPackage;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 $path A public path
|
||||||
|
* @param string $packageName A package name
|
||||||
|
*
|
||||||
|
* @return string The current version
|
||||||
|
*/
|
||||||
|
public function getVersion($path, $packageName = null)
|
||||||
|
{
|
||||||
|
return $this->getPackage($packageName)->getVersion($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)
|
||||||
|
{
|
||||||
|
return $this->getPackage($packageName)->getUrl($path);
|
||||||
|
}
|
||||||
|
}
|
74
src/Symfony/Component/Asset/PathPackage.php
Normal file
74
src/Symfony/Component/Asset/PathPackage.php
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
<?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\Component\Asset;
|
||||||
|
|
||||||
|
use Symfony\Component\Asset\VersionStrategy\VersionStrategyInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Package that adds a base path to asset URLs in addition to a version.
|
||||||
|
*
|
||||||
|
* In addition to the provided base path, this package also automatically
|
||||||
|
* prepends the current request base path if a Context is available to
|
||||||
|
* allow a website to be hosted easily under any given path under the Web
|
||||||
|
* Server root directory.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
class PathPackage extends Package
|
||||||
|
{
|
||||||
|
private $basePath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $basePath The base path to be prepended to relative paths
|
||||||
|
* @param VersionStrategyInterface $versionStrategy The version strategy
|
||||||
|
*/
|
||||||
|
public function __construct($basePath, VersionStrategyInterface $versionStrategy)
|
||||||
|
{
|
||||||
|
parent::__construct($versionStrategy);
|
||||||
|
|
||||||
|
if (!$basePath) {
|
||||||
|
$this->basePath = '/';
|
||||||
|
} else {
|
||||||
|
if ('/' != $basePath[0]) {
|
||||||
|
$basePath = '/'.$basePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->basePath = rtrim($basePath, '/').'/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getUrl($path)
|
||||||
|
{
|
||||||
|
if ($this->isAbsoluteUrl($path)) {
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->getBasePath().ltrim($this->getVersionStrategy()->applyVersion($path), '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the base path.
|
||||||
|
*
|
||||||
|
* @return string The base path
|
||||||
|
*/
|
||||||
|
public function getBasePath()
|
||||||
|
{
|
||||||
|
if (null !== $context = $this->getContext()) {
|
||||||
|
return $context->getBasePath().$this->basePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->basePath;
|
||||||
|
}
|
||||||
|
}
|
166
src/Symfony/Component/Asset/README.md
Normal file
166
src/Symfony/Component/Asset/README.md
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
Asset Component
|
||||||
|
===============
|
||||||
|
|
||||||
|
The Asset component manages asset URLs.
|
||||||
|
|
||||||
|
Versioned Asset URLs
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
The basic `Package` adds a version to generated asset URLs:
|
||||||
|
|
||||||
|
```php
|
||||||
|
use Symfony\Component\Asset\Package;
|
||||||
|
use Symfony\Component\Asset\VersionStrategy\StaticVersionStrategy;
|
||||||
|
|
||||||
|
$package = new Package(new StaticVersionStrategy('v1'));
|
||||||
|
|
||||||
|
echo $package->getUrl('/me.png');
|
||||||
|
// /me.png?v1
|
||||||
|
```
|
||||||
|
|
||||||
|
The default format can be configured:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$package = new Package(new StaticVersionStrategy('v1', '%s?version=%s'));
|
||||||
|
|
||||||
|
echo $package->getUrl('/me.png');
|
||||||
|
// /me.png?version=v1
|
||||||
|
|
||||||
|
// put the version before the path
|
||||||
|
$package = new Package(new StaticVersionStrategy('v1', 'version-%2$s/%1$s'));
|
||||||
|
|
||||||
|
echo $package->getUrl('/me.png');
|
||||||
|
// /version-v1/me.png
|
||||||
|
```
|
||||||
|
|
||||||
|
Asset URLs Base Path
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
When all assets are stored in a common path, use the `PathPackage` to avoid
|
||||||
|
repeating yourself:
|
||||||
|
|
||||||
|
```php
|
||||||
|
use Symfony\Component\Asset\PathPackage;
|
||||||
|
|
||||||
|
$package = new PathPackage('/images', new StaticVersionStrategy('v1'));
|
||||||
|
|
||||||
|
echo $package->getUrl('/me.png');
|
||||||
|
// /images/me.png?v1
|
||||||
|
```
|
||||||
|
|
||||||
|
Asset URLs Base URLs
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
If your assets are hosted on different domain name than the main website, use
|
||||||
|
the `UrlPackage` class:
|
||||||
|
|
||||||
|
```php
|
||||||
|
use Symfony\Component\Asset\UrlPackage;
|
||||||
|
|
||||||
|
$package = new UrlPackage('http://assets.example.com/images/', new StaticVersionStrategy('v1'));
|
||||||
|
|
||||||
|
echo $package->getUrl('/me.png');
|
||||||
|
// http://assets.example.com/images/me.png?v1
|
||||||
|
```
|
||||||
|
|
||||||
|
One technique used to speed up page rendering in browsers is to use several
|
||||||
|
domains for assets; this is possible by passing more than one base URLs:
|
||||||
|
|
||||||
|
```php
|
||||||
|
use Symfony\Component\Asset\UrlPackage;
|
||||||
|
|
||||||
|
$urls = array(
|
||||||
|
'http://a1.example.com/images/',
|
||||||
|
'http://a2.example.com/images/',
|
||||||
|
);
|
||||||
|
$package = new UrlPackage($urls, new StaticVersionStrategy('v1'));
|
||||||
|
|
||||||
|
echo $package->getUrl('/me.png');
|
||||||
|
// http://a1.example.com/images/me.png?v1
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that it's also guaranteed that any given path will always use the same
|
||||||
|
base URL to be nice with HTTP caching mechanisms.
|
||||||
|
|
||||||
|
HttpFoundation Integration
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
If you are using HttpFoundation for your project, set the Context to get
|
||||||
|
additional features for free:
|
||||||
|
|
||||||
|
```php
|
||||||
|
use Symfony\Component\Asset\PathPackage;
|
||||||
|
use Symfony\Component\Asset\Context\RequestStackContext;
|
||||||
|
|
||||||
|
$package = new PathPackage('images', new StaticVersionStrategy('v1'));
|
||||||
|
$package->setContext(new RequestStackContext($requestStack));
|
||||||
|
|
||||||
|
echo $package->getUrl('/me.png');
|
||||||
|
// /somewhere/images/me.png?v1
|
||||||
|
```
|
||||||
|
|
||||||
|
In addition to the configured base path, `PathPackage` now also automatically
|
||||||
|
prepends the current request base URL to assets to allow your website to be
|
||||||
|
hosted anywhere under the web server root directory.
|
||||||
|
|
||||||
|
```php
|
||||||
|
use Symfony\Component\Asset\UrlPackage;
|
||||||
|
use Symfony\Component\Asset\Context\RequestStackContext;
|
||||||
|
|
||||||
|
$package = new UrlPackage(array('http://example.com/', 'https://example.com/'), new StaticVersionStrategy('v1'));
|
||||||
|
$package->setContext(new RequestStackContext($requestStack));
|
||||||
|
|
||||||
|
echo $package->getUrl('/me.png');
|
||||||
|
// https://example.com/images/me.png?v1
|
||||||
|
```
|
||||||
|
|
||||||
|
`UrlPackage` now uses the current request scheme (HTTP or HTTPs) to select an
|
||||||
|
appropriate base URL (HTTPs or protocol-relative URLs for HTTPs requests, any
|
||||||
|
base URL for HTTP requests).
|
||||||
|
|
||||||
|
Named Packages
|
||||||
|
--------------
|
||||||
|
|
||||||
|
The `Packages` class allows to easily manages several packages in a single
|
||||||
|
project by naming packages:
|
||||||
|
|
||||||
|
```php
|
||||||
|
use Symfony\Component\Asset\Package;
|
||||||
|
use Symfony\Component\Asset\PathPackage;
|
||||||
|
use Symfony\Component\Asset\UrlPackage;
|
||||||
|
use Symfony\Component\Asset\Packages;
|
||||||
|
|
||||||
|
// by default, just add a version to all assets
|
||||||
|
$versionStrategy = new StaticVersionStrategy('v1');
|
||||||
|
$defaultPackage = new Asset\Package($versionStrategy);
|
||||||
|
|
||||||
|
$namedPackages = array(
|
||||||
|
// images are hosted on another web server
|
||||||
|
'img' => new Asset\UrlPackage('http://img.example.com/', $versionStrategy),
|
||||||
|
|
||||||
|
// documents are stored deeply under the web root directory
|
||||||
|
// let's create a shortcut
|
||||||
|
'doc' => new Asset\PathPackage('/somewhere/deep/for/documents', $versionStrategy),
|
||||||
|
);
|
||||||
|
|
||||||
|
// bundle all packages to make it easy to use them
|
||||||
|
$packages = new Asset\Packages($defaultPackage, $namedPackages);
|
||||||
|
|
||||||
|
echo $packages->getUrl('/some.css');
|
||||||
|
// /some.css?v1
|
||||||
|
|
||||||
|
echo $packages->getUrl('/me.png', 'img');
|
||||||
|
// http://img.example.com/me.png?v1
|
||||||
|
|
||||||
|
echo $packages->getUrl('/me.pdf', 'doc');
|
||||||
|
// /somewhere/deep/for/documents/me.pdf?v1
|
||||||
|
```
|
||||||
|
|
||||||
|
Resources
|
||||||
|
---------
|
||||||
|
|
||||||
|
You can run the unit tests with the following command:
|
||||||
|
|
||||||
|
$ cd path/to/Symfony/Component/Asset/
|
||||||
|
$ composer update
|
||||||
|
$ phpunit
|
54
src/Symfony/Component/Asset/Tests/PackageTest.php
Normal file
54
src/Symfony/Component/Asset/Tests/PackageTest.php
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?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\Component\Asset\Tests;
|
||||||
|
|
||||||
|
use Symfony\Component\Asset\Package;
|
||||||
|
use Symfony\Component\Asset\VersionStrategy\StaticVersionStrategy;
|
||||||
|
use Symfony\Component\Asset\VersionStrategy\EmptyVersionStrategy;
|
||||||
|
|
||||||
|
class PackageTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @dataProvider getConfigs
|
||||||
|
*/
|
||||||
|
public function testGetUrl($version, $format, $path, $expected)
|
||||||
|
{
|
||||||
|
$package = new Package($version ? new StaticVersionStrategy($version, $format) : new EmptyVersionStrategy());
|
||||||
|
$this->assertEquals($expected, $package->getUrl($path));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getConfigs()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array('v1', '', 'http://example.com/foo', 'http://example.com/foo'),
|
||||||
|
array('v1', '', 'https://example.com/foo', 'https://example.com/foo'),
|
||||||
|
array('v1', '', '//example.com/foo', '//example.com/foo'),
|
||||||
|
|
||||||
|
array('v1', '', '/foo', '/foo?v1'),
|
||||||
|
array('v1', '', 'foo', 'foo?v1'),
|
||||||
|
|
||||||
|
array(null, '', '/foo', '/foo'),
|
||||||
|
array(null, '', 'foo', 'foo'),
|
||||||
|
|
||||||
|
array('v1', 'version-%2$s/%1$s', '/foo', '/version-v1/foo'),
|
||||||
|
array('v1', 'version-%2$s/%1$s', 'foo', 'version-v1/foo'),
|
||||||
|
array('v1', 'version-%2$s/%1$s', 'foo/', 'version-v1/foo/'),
|
||||||
|
array('v1', 'version-%2$s/%1$s', '/foo/', '/version-v1/foo/'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetVersion()
|
||||||
|
{
|
||||||
|
$package = new Package(new StaticVersionStrategy('v1'));
|
||||||
|
$this->assertEquals('v1', $package->getVersion('/foo'));
|
||||||
|
}
|
||||||
|
}
|
76
src/Symfony/Component/Asset/Tests/PackagesTest.php
Normal file
76
src/Symfony/Component/Asset/Tests/PackagesTest.php
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<?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\Component\Asset\Tests;
|
||||||
|
|
||||||
|
use Symfony\Component\Asset\Package;
|
||||||
|
use Symfony\Component\Asset\Packages;
|
||||||
|
use Symfony\Component\Asset\VersionStrategy\StaticVersionStrategy;
|
||||||
|
use Symfony\Component\Asset\Exception\InvalidArgumentException;
|
||||||
|
use Symfony\Component\Asset\Exception\LogicException;
|
||||||
|
|
||||||
|
class PackagesTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
public function testGetterSetters()
|
||||||
|
{
|
||||||
|
$packages = new Packages();
|
||||||
|
$packages->setDefaultPackage($default = $this->getMock('Symfony\Component\Asset\PackageInterface'));
|
||||||
|
$packages->addPackage('a', $a = $this->getMock('Symfony\Component\Asset\PackageInterface'));
|
||||||
|
|
||||||
|
$this->assertEquals($default, $packages->getPackage());
|
||||||
|
$this->assertEquals($a, $packages->getPackage('a'));
|
||||||
|
|
||||||
|
$packages = new Packages($default, array('a' => $a));
|
||||||
|
|
||||||
|
$this->assertEquals($default, $packages->getPackage());
|
||||||
|
$this->assertEquals($a, $packages->getPackage('a'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetVersion()
|
||||||
|
{
|
||||||
|
$packages = new Packages(
|
||||||
|
new Package(new StaticVersionStrategy('default')),
|
||||||
|
array('a' => new Package(new StaticVersionStrategy('a')))
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals('default', $packages->getVersion('/foo'));
|
||||||
|
$this->assertEquals('a', $packages->getVersion('/foo', 'a'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetUrl()
|
||||||
|
{
|
||||||
|
$packages = new Packages(
|
||||||
|
new Package(new StaticVersionStrategy('default')),
|
||||||
|
array('a' => new Package(new StaticVersionStrategy('a')))
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals('/foo?default', $packages->getUrl('/foo'));
|
||||||
|
$this->assertEquals('/foo?a', $packages->getUrl('/foo', 'a'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException LogicException
|
||||||
|
*/
|
||||||
|
public function testNoDefaultPackage()
|
||||||
|
{
|
||||||
|
$packages = new Packages();
|
||||||
|
$packages->getPackage();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function testUndefinedPackage()
|
||||||
|
{
|
||||||
|
$packages = new Packages();
|
||||||
|
$packages->getPackage('a');
|
||||||
|
}
|
||||||
|
}
|
84
src/Symfony/Component/Asset/Tests/PathPackageTest.php
Normal file
84
src/Symfony/Component/Asset/Tests/PathPackageTest.php
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
<?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\Component\Asset\Tests;
|
||||||
|
|
||||||
|
use Symfony\Component\Asset\PathPackage;
|
||||||
|
use Symfony\Component\Asset\VersionStrategy\StaticVersionStrategy;
|
||||||
|
|
||||||
|
class PathPackageTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @dataProvider getConfigs
|
||||||
|
*/
|
||||||
|
public function testGetUrl($basePath, $format, $path, $expected)
|
||||||
|
{
|
||||||
|
$package = new PathPackage($basePath, new StaticVersionStrategy('v1', $format));
|
||||||
|
$this->assertEquals($expected, $package->getUrl($path));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getConfigs()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array('/foo', '', 'http://example.com/foo', 'http://example.com/foo'),
|
||||||
|
array('/foo', '', 'https://example.com/foo', 'https://example.com/foo'),
|
||||||
|
array('/foo', '', '//example.com/foo', '//example.com/foo'),
|
||||||
|
|
||||||
|
array('', '', '/foo', '/foo?v1'),
|
||||||
|
|
||||||
|
array('/foo', '', '/foo', '/foo/foo?v1'),
|
||||||
|
array('/foo', '', 'foo', '/foo/foo?v1'),
|
||||||
|
array('foo', '', 'foo', '/foo/foo?v1'),
|
||||||
|
array('foo/', '', 'foo', '/foo/foo?v1'),
|
||||||
|
array('/foo/', '', 'foo', '/foo/foo?v1'),
|
||||||
|
|
||||||
|
array('/foo', 'version-%2$s/%1$s', '/foo', '/foo/version-v1/foo'),
|
||||||
|
array('/foo', 'version-%2$s/%1$s', 'foo', '/foo/version-v1/foo'),
|
||||||
|
array('/foo', 'version-%2$s/%1$s', 'foo/', '/foo/version-v1/foo/'),
|
||||||
|
array('/foo', 'version-%2$s/%1$s', '/foo/', '/foo/version-v1/foo/'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getContextConfigs
|
||||||
|
*/
|
||||||
|
public function testGetUrlWithContext($basePathRequest, $basePath, $format, $path, $expected)
|
||||||
|
{
|
||||||
|
$package = new PathPackage($basePath, new StaticVersionStrategy('v1', $format));
|
||||||
|
$package->setContext($this->getContext($basePathRequest));
|
||||||
|
$this->assertEquals($expected, $package->getUrl($path));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getContextConfigs()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array('', '/foo', '', '/foo', '/foo/foo?v1'),
|
||||||
|
array('', '/foo', '', 'foo', '/foo/foo?v1'),
|
||||||
|
array('', 'foo', '', 'foo', '/foo/foo?v1'),
|
||||||
|
array('', 'foo/', '', 'foo', '/foo/foo?v1'),
|
||||||
|
array('', '/foo/', '', 'foo', '/foo/foo?v1'),
|
||||||
|
|
||||||
|
array('/bar', '/foo', '', '/foo', '/bar/foo/foo?v1'),
|
||||||
|
array('/bar', '/foo', '', 'foo', '/bar/foo/foo?v1'),
|
||||||
|
array('/bar', 'foo', '', 'foo', '/bar/foo/foo?v1'),
|
||||||
|
array('/bar', 'foo/', '', 'foo', '/bar/foo/foo?v1'),
|
||||||
|
array('/bar', '/foo/', '', 'foo', '/bar/foo/foo?v1'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getContext($basePath)
|
||||||
|
{
|
||||||
|
$context = $this->getMock('Symfony\Component\Asset\Context\ContextInterface');
|
||||||
|
$context->expects($this->any())->method('getBasePath')->will($this->returnValue($basePath));
|
||||||
|
|
||||||
|
return $context;
|
||||||
|
}
|
||||||
|
}
|
104
src/Symfony/Component/Asset/Tests/UrlPackageTest.php
Normal file
104
src/Symfony/Component/Asset/Tests/UrlPackageTest.php
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
<?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\Component\Asset\Tests;
|
||||||
|
|
||||||
|
use Symfony\Component\Asset\UrlPackage;
|
||||||
|
use Symfony\Component\Asset\VersionStrategy\StaticVersionStrategy;
|
||||||
|
use Symfony\Component\Asset\VersionStrategy\EmptyVersionStrategy;
|
||||||
|
use Symfony\Component\Asset\Exception\InvalidArgumentException;
|
||||||
|
use Symfony\Component\Asset\Exception\LogicException;
|
||||||
|
|
||||||
|
class UrlPackageTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @dataProvider getConfigs
|
||||||
|
*/
|
||||||
|
public function testGetUrl($baseUrls, $format, $path, $expected)
|
||||||
|
{
|
||||||
|
$package = new UrlPackage($baseUrls, new StaticVersionStrategy('v1', $format));
|
||||||
|
$this->assertEquals($expected, $package->getUrl($path));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getConfigs()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array('http://example.net', '', 'http://example.com/foo', 'http://example.com/foo'),
|
||||||
|
array('http://example.net', '', 'https://example.com/foo', 'https://example.com/foo'),
|
||||||
|
array('http://example.net', '', '//example.com/foo', '//example.com/foo'),
|
||||||
|
|
||||||
|
array('http://example.com', '', '/foo', 'http://example.com/foo?v1'),
|
||||||
|
array('http://example.com', '', 'foo', 'http://example.com/foo?v1'),
|
||||||
|
array('http://example.com/', '', 'foo', 'http://example.com/foo?v1'),
|
||||||
|
array('http://example.com/foo', '', 'foo', 'http://example.com/foo/foo?v1'),
|
||||||
|
array('http://example.com/foo/', '', 'foo', 'http://example.com/foo/foo?v1'),
|
||||||
|
|
||||||
|
array(array('http://example.com'), '', '/foo', 'http://example.com/foo?v1'),
|
||||||
|
array(array('http://example.com', 'http://example.net'), '', '/foo', 'http://example.com/foo?v1'),
|
||||||
|
array(array('http://example.com', 'http://example.net'), '', '/fooa', 'http://example.net/fooa?v1'),
|
||||||
|
|
||||||
|
array('http://example.com', 'version-%2$s/%1$s', '/foo', 'http://example.com/version-v1/foo'),
|
||||||
|
array('http://example.com', 'version-%2$s/%1$s', 'foo', 'http://example.com/version-v1/foo'),
|
||||||
|
array('http://example.com', 'version-%2$s/%1$s', 'foo/', 'http://example.com/version-v1/foo/'),
|
||||||
|
array('http://example.com', 'version-%2$s/%1$s', '/foo/', 'http://example.com/version-v1/foo/'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getContextConfigs
|
||||||
|
*/
|
||||||
|
public function testGetUrlWithContext($secure, $baseUrls, $format, $path, $expected)
|
||||||
|
{
|
||||||
|
$package = new UrlPackage($baseUrls, new StaticVersionStrategy('v1', $format));
|
||||||
|
$package->setContext($this->getContext($secure));
|
||||||
|
$this->assertEquals($expected, $package->getUrl($path));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getContextConfigs()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array(false, 'http://example.com', '', 'foo', 'http://example.com/foo?v1'),
|
||||||
|
array(false, array('http://example.com'), '', 'foo', 'http://example.com/foo?v1'),
|
||||||
|
array(false, array('http://example.com', 'https://example.com'), '', 'foo', 'http://example.com/foo?v1'),
|
||||||
|
array(false, array('http://example.com', 'https://example.com'), '', 'fooa', 'https://example.com/fooa?v1'),
|
||||||
|
array(false, array('http://example.com/bar'), '', 'foo', 'http://example.com/bar/foo?v1'),
|
||||||
|
array(false, array('http://example.com/bar/'), '', 'foo', 'http://example.com/bar/foo?v1'),
|
||||||
|
array(false, array('//example.com/bar/'), '', 'foo', '//example.com/bar/foo?v1'),
|
||||||
|
|
||||||
|
array(true, array('http://example.com'), '', 'foo', 'http://example.com/foo?v1'),
|
||||||
|
array(true, array('http://example.com', 'https://example.com'), '', 'foo', 'https://example.com/foo?v1'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException LogicException
|
||||||
|
*/
|
||||||
|
public function testNoBaseUrls()
|
||||||
|
{
|
||||||
|
new UrlPackage(array(), new EmptyVersionStrategy());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function testWrongBaseUrl()
|
||||||
|
{
|
||||||
|
new UrlPackage(array('not-a-url'), new EmptyVersionStrategy());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getContext($secure)
|
||||||
|
{
|
||||||
|
$context = $this->getMock('Symfony\Component\Asset\Context\ContextInterface');
|
||||||
|
$context->expects($this->any())->method('isSecure')->will($this->returnValue($secure));
|
||||||
|
|
||||||
|
return $context;
|
||||||
|
}
|
||||||
|
}
|
134
src/Symfony/Component/Asset/UrlPackage.php
Normal file
134
src/Symfony/Component/Asset/UrlPackage.php
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
<?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\Component\Asset;
|
||||||
|
|
||||||
|
use Symfony\Component\Asset\VersionStrategy\VersionStrategyInterface;
|
||||||
|
use Symfony\Component\Asset\Exception\InvalidArgumentException;
|
||||||
|
use Symfony\Component\Asset\Exception\LogicException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Package that adds a base URL to asset URLs in addition to a version.
|
||||||
|
*
|
||||||
|
* The package allows to use more than one base URLs in which case
|
||||||
|
* it randomly chooses one for each asset; it also guarantees that
|
||||||
|
* any given path will always use the same base URL to be nice with
|
||||||
|
* HTTP caching mechanisms.
|
||||||
|
*
|
||||||
|
* When the request context is available, this package can choose the
|
||||||
|
* best base URL to use based on the current request scheme:
|
||||||
|
*
|
||||||
|
* * For HTTP request, it chooses between all base URLs;
|
||||||
|
* * For HTTPs requests, it chooses between HTTPs base URLs and relative protocol URLs
|
||||||
|
* or falls back to any base URL if no secure ones are available.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
class UrlPackage extends Package
|
||||||
|
{
|
||||||
|
private $baseUrls = array();
|
||||||
|
private $sslUrls;
|
||||||
|
private $sslPackage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|array $baseUrls Base asset URLs
|
||||||
|
* @param VersionStrategyInterface $versionStrategy The version strategy
|
||||||
|
*/
|
||||||
|
public function __construct($baseUrls = array(), VersionStrategyInterface $versionStrategy)
|
||||||
|
{
|
||||||
|
parent::__construct($versionStrategy);
|
||||||
|
|
||||||
|
if (!is_array($baseUrls)) {
|
||||||
|
$baseUrls = (array) $baseUrls;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$baseUrls) {
|
||||||
|
throw new LogicException('You must provide at least one base URL.');
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($baseUrls as $baseUrl) {
|
||||||
|
$this->baseUrls[] = rtrim($baseUrl, '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
$sslUrls = $this->getSslUrls($baseUrls);
|
||||||
|
|
||||||
|
if ($sslUrls && $baseUrls !== $sslUrls) {
|
||||||
|
$this->sslPackage = new UrlPackage($sslUrls, $versionStrategy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getUrl($path)
|
||||||
|
{
|
||||||
|
if ($this->isAbsoluteUrl($path)) {
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null !== $this->sslPackage && ($context = $this->getContext()) && $context->isSecure()) {
|
||||||
|
return $this->sslPackage->getUrl($path);
|
||||||
|
}
|
||||||
|
|
||||||
|
$url = $this->getVersionStrategy()->applyVersion($path);
|
||||||
|
|
||||||
|
if ($url && '/' != $url[0]) {
|
||||||
|
$url = '/'.$url;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->getBaseUrl($path).$url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the base URL for a path.
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
*
|
||||||
|
* @return string The base URL
|
||||||
|
*/
|
||||||
|
public function getBaseUrl($path)
|
||||||
|
{
|
||||||
|
if (1 === count($this->baseUrls)) {
|
||||||
|
return $this->baseUrls[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->baseUrls[$this->chooseBaseUrl($path)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines which base URL to use for the given path.
|
||||||
|
*
|
||||||
|
* Override this method to change the default distribution strategy.
|
||||||
|
* This method should always return the same base URL for a given path.
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
*
|
||||||
|
* @return string The base URL for the given path
|
||||||
|
*/
|
||||||
|
protected function chooseBaseUrl($path)
|
||||||
|
{
|
||||||
|
return fmod(hexdec(substr(hash('sha256', $path), 0, 10)), count($this->baseUrls));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getSslUrls($urls)
|
||||||
|
{
|
||||||
|
$sslUrls = array();
|
||||||
|
foreach ($urls as $url) {
|
||||||
|
if ('https://' === substr($url, 0, 8) || '//' === substr($url, 0, 2)) {
|
||||||
|
$sslUrls[] = $url;
|
||||||
|
} elseif ('http://' !== substr($url, 0, 7)) {
|
||||||
|
throw new InvalidArgumentException(sprintf('"%s" is not a valid URL', $url));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sslUrls;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
<?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\Component\Asset\VersionStrategy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable version for all assets.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
class EmptyVersionStrategy implements VersionStrategyInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getVersion($path)
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function applyVersion($path)
|
||||||
|
{
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
<?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\Component\Asset\VersionStrategy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the same version for all assets.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
class StaticVersionStrategy implements VersionStrategyInterface
|
||||||
|
{
|
||||||
|
private $version;
|
||||||
|
private $format;
|
||||||
|
|
||||||
|
public function __construct($version, $format = null)
|
||||||
|
{
|
||||||
|
$this->version = $version;
|
||||||
|
$this->format = $format ?: '%s?%s';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getVersion($path)
|
||||||
|
{
|
||||||
|
return $this->version;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function applyVersion($path)
|
||||||
|
{
|
||||||
|
$versionized = sprintf($this->format, ltrim($path, '/'), $this->getVersion($path));
|
||||||
|
|
||||||
|
if ($path && '/' == $path[0]) {
|
||||||
|
return '/'.$versionized;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $versionized;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
<?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\Component\Asset\VersionStrategy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asset version strategy interface.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
interface VersionStrategyInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns the asset version for an asset.
|
||||||
|
*
|
||||||
|
* @param string $path A path
|
||||||
|
*
|
||||||
|
* @return string The version string
|
||||||
|
*/
|
||||||
|
public function getVersion($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies version to the supplied path.
|
||||||
|
*
|
||||||
|
* @param string $path A path
|
||||||
|
*
|
||||||
|
* @return string The versionized path
|
||||||
|
*/
|
||||||
|
public function applyVersion($path);
|
||||||
|
}
|
36
src/Symfony/Component/Asset/composer.json
Normal file
36
src/Symfony/Component/Asset/composer.json
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"name": "symfony/asset",
|
||||||
|
"type": "library",
|
||||||
|
"description": "Symfony Asset Component",
|
||||||
|
"keywords": [],
|
||||||
|
"homepage": "http://symfony.com",
|
||||||
|
"license": "MIT",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Fabien Potencier",
|
||||||
|
"email": "fabien@symfony.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "http://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.3"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"symfony/http-foundation": ""
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"symfony/http-foundation": "~2.4"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": { "Symfony\\Component\\Asset\\": "" }
|
||||||
|
},
|
||||||
|
"minimum-stability": "dev",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "2.7-dev"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
src/Symfony/Component/Asset/phpunit.xml.dist
Normal file
24
src/Symfony/Component/Asset/phpunit.xml.dist
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
|
||||||
|
backupGlobals="false"
|
||||||
|
colors="true"
|
||||||
|
bootstrap="vendor/autoload.php"
|
||||||
|
>
|
||||||
|
<testsuites>
|
||||||
|
<testsuite name="Symfony Asset Component Test Suite">
|
||||||
|
<directory>./Tests/</directory>
|
||||||
|
</testsuite>
|
||||||
|
</testsuites>
|
||||||
|
|
||||||
|
<filter>
|
||||||
|
<whitelist>
|
||||||
|
<directory>./</directory>
|
||||||
|
<exclude>
|
||||||
|
<directory>./vendor</directory>
|
||||||
|
<directory>./Tests</directory>
|
||||||
|
</exclude>
|
||||||
|
</whitelist>
|
||||||
|
</filter>
|
||||||
|
</phpunit>
|
@ -11,10 +11,14 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Templating\Asset;
|
namespace Symfony\Component\Templating\Asset;
|
||||||
|
|
||||||
|
trigger_error('The Symfony\Component\Templating\Asset\Package is deprecated since version 2.7 and will be removed in 3.0. Use the Asset component instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The basic package will add a version to asset URLs.
|
* The basic package will add a version to asset URLs.
|
||||||
*
|
*
|
||||||
* @author Kris Wallsmith <kris@symfony.com>
|
* @author Kris Wallsmith <kris@symfony.com>
|
||||||
|
*
|
||||||
|
* @deprecated since 2.7, will be removed in 3.0. Use the Asset component instead.
|
||||||
*/
|
*/
|
||||||
class Package implements PackageInterface
|
class Package implements PackageInterface
|
||||||
{
|
{
|
||||||
|
@ -11,10 +11,14 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Templating\Asset;
|
namespace Symfony\Component\Templating\Asset;
|
||||||
|
|
||||||
|
trigger_error('The Symfony\Component\Templating\Asset\PackageInterface is deprecated since version 2.7 and will be removed in 3.0. Use the Asset component instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asset package interface.
|
* Asset package interface.
|
||||||
*
|
*
|
||||||
* @author Kris Wallsmith <kris@symfony.com>
|
* @author Kris Wallsmith <kris@symfony.com>
|
||||||
|
*
|
||||||
|
* @deprecated since 2.7, will be removed in 3.0. Use the Asset component instead.
|
||||||
*/
|
*/
|
||||||
interface PackageInterface
|
interface PackageInterface
|
||||||
{
|
{
|
||||||
|
@ -11,10 +11,14 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Templating\Asset;
|
namespace Symfony\Component\Templating\Asset;
|
||||||
|
|
||||||
|
trigger_error('The Symfony\Component\Templating\Asset\PathPackage is deprecated since version 2.7 and will be removed in 3.0. Use the Asset component instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The path packages adds a version and a base path to asset URLs.
|
* The path packages adds a version and a base path to asset URLs.
|
||||||
*
|
*
|
||||||
* @author Kris Wallsmith <kris@symfony.com>
|
* @author Kris Wallsmith <kris@symfony.com>
|
||||||
|
*
|
||||||
|
* @deprecated since 2.7, will be removed in 3.0. Use the Asset component instead.
|
||||||
*/
|
*/
|
||||||
class PathPackage extends Package
|
class PathPackage extends Package
|
||||||
{
|
{
|
||||||
|
@ -11,10 +11,14 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Templating\Asset;
|
namespace Symfony\Component\Templating\Asset;
|
||||||
|
|
||||||
|
trigger_error('The Symfony\Component\Templating\Asset\UrlPackage is deprecated since version 2.7 and will be removed in 3.0. Use the Asset component instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The URL packages adds a version and a base URL to asset URLs.
|
* The URL packages adds a version and a base URL to asset URLs.
|
||||||
*
|
*
|
||||||
* @author Kris Wallsmith <kris@symfony.com>
|
* @author Kris Wallsmith <kris@symfony.com>
|
||||||
|
*
|
||||||
|
* @deprecated since 2.7, will be removed in 3.0. Use the Asset component instead.
|
||||||
*/
|
*/
|
||||||
class UrlPackage extends Package
|
class UrlPackage extends Package
|
||||||
{
|
{
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Templating\Helper;
|
namespace Symfony\Component\Templating\Helper;
|
||||||
|
|
||||||
|
trigger_error('The Symfony\Component\Templating\Helper\AssetsHelper is deprecated since version 2.7 and will be removed in 3.0. Use the Asset component instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
use Symfony\Component\Templating\Asset\PathPackage;
|
use Symfony\Component\Templating\Asset\PathPackage;
|
||||||
use Symfony\Component\Templating\Asset\UrlPackage;
|
use Symfony\Component\Templating\Asset\UrlPackage;
|
||||||
|
|
||||||
@ -25,6 +27,8 @@ use Symfony\Component\Templating\Asset\UrlPackage;
|
|||||||
*
|
*
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
* @author Kris Wallsmith <kris@symfony.com>
|
* @author Kris Wallsmith <kris@symfony.com>
|
||||||
|
*
|
||||||
|
* @deprecated since 2.7, will be removed in 3.0. Use the Asset component instead.
|
||||||
*/
|
*/
|
||||||
class AssetsHelper extends CoreAssetsHelper
|
class AssetsHelper extends CoreAssetsHelper
|
||||||
{
|
{
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Templating\Helper;
|
namespace Symfony\Component\Templating\Helper;
|
||||||
|
|
||||||
|
trigger_error('The Symfony\Component\Templating\Helper\CoreAssetsHelper is deprecated since version 2.7 and will be removed in 3.0. Use the Asset component instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
use Symfony\Component\Templating\Asset\PackageInterface;
|
use Symfony\Component\Templating\Asset\PackageInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,6 +26,8 @@ use Symfony\Component\Templating\Asset\PackageInterface;
|
|||||||
*
|
*
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
* @author Kris Wallsmith <kris@symfony.com>
|
* @author Kris Wallsmith <kris@symfony.com>
|
||||||
|
*
|
||||||
|
* @deprecated since 2.7, will be removed in 3.0. Use the Asset component instead.
|
||||||
*/
|
*/
|
||||||
class CoreAssetsHelper extends Helper implements PackageInterface
|
class CoreAssetsHelper extends Helper implements PackageInterface
|
||||||
{
|
{
|
||||||
|
@ -13,7 +13,7 @@ namespace Symfony\Component\Templating\Tests\Helper;
|
|||||||
|
|
||||||
use Symfony\Component\Templating\Helper\AssetsHelper;
|
use Symfony\Component\Templating\Helper\AssetsHelper;
|
||||||
|
|
||||||
class AssetsHelperTest extends \PHPUnit_Framework_TestCase
|
class LegacyAssetsHelperTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
public function testGetVersion()
|
public function testGetVersion()
|
||||||
{
|
{
|
@ -13,7 +13,7 @@ namespace Symfony\Component\Templating\Tests\Helper;
|
|||||||
|
|
||||||
use Symfony\Component\Templating\Helper\CoreAssetsHelper;
|
use Symfony\Component\Templating\Helper\CoreAssetsHelper;
|
||||||
|
|
||||||
class CoreAssetsHelperTest extends \PHPUnit_Framework_TestCase
|
class LegacyCoreAssetsHelperTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
protected $package;
|
protected $package;
|
||||||
|
|
Reference in New Issue
Block a user