renamed asset_path() to asset() and added a BC layer

This commit is contained in:
Fabien Potencier 2015-01-17 08:35:04 +01:00
parent 4d0adeae16
commit f74a1f2dc3
34 changed files with 613 additions and 180 deletions

View File

@ -6,7 +6,7 @@ CHANGELOG
* added LogoutUrlExtension (provides `logout_url` and `logout_path`)
* added an HttpFoundation extension (provides the `absolute_url` and the `relative_path` functions)
* added AssetExtension (provides the `asset_path` function)
* added AssetExtension (provides the `asset` and `asset_version` functions)
2.5.0
-----

View File

@ -12,6 +12,7 @@
namespace Symfony\Bridge\Twig\Extension;
use Symfony\Component\Asset\Packages;
use Symfony\Component\Asset\VersionStrategy\StaticVersionStrategy;
/**
* Twig extension for the Symfony Asset component.
@ -21,10 +22,16 @@ use Symfony\Component\Asset\Packages;
class AssetExtension extends \Twig_Extension
{
private $packages;
private $foundationExtension;
public function __construct(Packages $packages)
/**
* Passing an HttpFoundationExtension instance as a second argument must not be relied on
* as it's only there to maintain BC with older Symfony version. It will be removed in 3.0.
*/
public function __construct(Packages $packages, HttpFoundationExtension $foundationExtension = null)
{
$this->packages = $packages;
$this->foundationExtension = $foundationExtension;
}
/**
@ -33,13 +40,14 @@ class AssetExtension extends \Twig_Extension
public function getFunctions()
{
return array(
new \Twig_SimpleFunction('asset_path', array($this, 'getAssetPath')),
new \Twig_SimpleFunction('asset', array($this, 'getAssetUrl')),
new \Twig_SimpleFunction('asset_version', array($this, 'getAssetVersion')),
new \Twig_SimpleFunction('assets_version', array($this, 'getAssetsVersion')),
);
}
/**
* Returns the public path of an asset.
* Returns the public url/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.
@ -49,8 +57,20 @@ class AssetExtension extends \Twig_Extension
*
* @return string The public path of the asset
*/
public function getAssetPath($path, $packageName = null)
public function getAssetUrl($path, $packageName = null, $absolute = false, $version = null)
{
// BC layer to be removed in 3.0
if (2 < $count = func_num_args()) {
trigger_error('Generating absolute URLs with the Twig asset() function was deprecated in 2.7 and will be removed in 3.0. Please use absolute_url() instead.', E_USER_DEPRECATED);
if (4 === $count) {
trigger_error('Forcing a version with the Twig asset() function was deprecated in 2.7 and will be removed in 3.0.', E_USER_DEPRECATED);
}
$args = func_get_args();
return $this->getLegacyAssetUrl($path, $packageName, $args[2], isset($args[3]) ? $args[3] : null);
}
return $this->packages->getUrl($path, $packageName);
}
@ -67,6 +87,51 @@ class AssetExtension extends \Twig_Extension
return $this->packages->getVersion($path, $packageName);
}
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->packages->getVersion('/', $packageName);
}
private function getLegacyAssetUrl($path, $packageName = null, $absolute = false, $version = null)
{
if ($version) {
$package = $this->packages->getPackage($packageName);
$v = new \ReflectionProperty($package, 'versionStrategy');
$v->setAccessible(true);
$currentVersionStrategy = $v->getValue($package);
$f = new \ReflectionProperty($currentVersionStrategy, 'format');
$f->setAccessible(true);
$format = $f->getValue($currentVersionStrategy);
$v->setValue($package, new StaticVersionStrategy($version, $format));
}
try {
$url = $this->packages->getUrl($path, $packageName);
} catch (\Exception $e) {
if ($version) {
$v->setValue($package, $currentVersionStrategy);
}
throw $e;
}
if ($version) {
$v->setValue($package, $currentVersionStrategy);
}
if ($absolute) {
return $this->foundationExtension->generateAbsoluteUrl($url);
}
return $url;
}
/**
* Returns the name of the extension.
*

View File

@ -0,0 +1,40 @@
<?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\Tests\Extension;
use Symfony\Bridge\Twig\Extension\AssetExtension;
use Symfony\Component\Asset\Package;
use Symfony\Component\Asset\Packages;
use Symfony\Component\Asset\VersionStrategy\StaticVersionStrategy;
class AssetExtensionTest extends \PHPUnit_Framework_TestCase
{
public function testLegacyGetAssetUrl()
{
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
$foundationExtension = $this->getMockBuilder('Symfony\Bridge\Twig\Extension\HttpFoundationExtension')->disableOriginalConstructor()->getMock();
$foundationExtension
->expects($this->any())
->method('generateAbsoluteUrl')
->will($this->returnCallback(function ($arg) { return 'http://localhost/'.$arg; }))
;
$package = new Package(new StaticVersionStrategy('22', '%s?version=%s'));
$packages = new Packages($package);
$extension = new AssetExtension($packages, $foundationExtension);
$this->assertEquals('me.png?version=42', $extension->getAssetUrl('me.png', null, false, '42'));
$this->assertEquals('http://localhost/me.png?version=22', $extension->getAssetUrl('me.png', null, true));
$this->assertEquals('http://localhost/me.png?version=42', $extension->getAssetUrl('me.png', null, true, '42'));
}
}

View File

@ -16,6 +16,8 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
trigger_error('The '.__NAMESPACE__.'\TemplatingAssetHelperPass class is deprecated since version 2.7 and will be removed in 3.0.', E_USER_DEPRECATED);
/**
* @deprecated since 2.7, will be removed in 3.0
*/

View File

@ -53,6 +53,44 @@ class Configuration implements ConfigurationInterface
return $v;
})
->end()
->validate()
->ifTrue(function ($v) { return isset($v['templating']); })
->then(function ($v) {
if ($v['templating']['assets_version']
|| count($v['templating']['assets_base_urls']['http'])
|| count($v['templating']['assets_base_urls']['ssl'])
|| count($v['templating']['packages'])
) {
trigger_error('The assets settings under framework.templating are deprecated since version 2.7 and will be removed in 3.0. Use the framework.assets configuration key instead', E_USER_DEPRECATED);
// convert the old configuration to the new one
if (isset($v['assets'])) {
throw new LogicException('You cannot use assets settings under "templating.templating" and "assets" configurations in the same project.');
}
$v['assets'] = array(
'version' => $v['templating']['assets_version'],
'version_format' => $v['templating']['assets_version_format'],
'base_path' => '',
'base_urls' => array_values(array_unique(array_merge($v['templating']['assets_base_urls']['http'], $v['templating']['assets_base_urls']['ssl']))),
'packages' => array(),
);
foreach ($v['templating']['packages'] as $name => $config) {
$v['assets']['packages'][$name] = array(
'version' => (string) $config['version'],
'version_format' => $config['version_format'],
'base_path' => '',
'base_urls' => array_values(array_unique(array_merge($config['base_urls']['http'], $config['base_urls']['ssl']))),
);
}
}
unset($v['templating']['assets_version'], $v['templating']['assets_version_format'], $v['templating']['assets_base_urls'], $v['templating']['packages']);
return $v;
})
->end()
->children()
->scalarNode('secret')->end()
->scalarNode('http_method_override')

View File

@ -49,6 +49,7 @@ class FrameworkExtension extends Extension
$loader->load('web.xml');
$loader->load('services.xml');
$loader->load('fragment_renderer.xml');
$loader->load('assets.xml');
// A translator must always be registered (as support is included by
// default in the Form component). If disabled, an identity translator
@ -473,23 +474,6 @@ class FrameworkExtension extends Extension
$container->setParameter('templating.helper.code.file_link_format', isset($links[$ide]) ? $links[$ide] : $ide);
$container->setParameter('fragment.renderer.hinclude.global_template', $config['hinclude_default_template']);
$loader->load('old_assets.xml');
// create package definitions and add them to the assets helper
$defaultPackage = $this->createTemplatingPackageDefinition($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) {
$namedPackage = $this->createTemplatingPackageDefinition($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->getDefinition('templating.helper.assets')->setArguments(array(
new Reference('templating.asset.default_package'),
$namedPackages,
));
if ($container->getParameter('kernel.debug')) {
$logger = new Reference('logger', ContainerInterface::IGNORE_ON_INVALID_REFERENCE);
@ -569,73 +553,6 @@ class FrameworkExtension extends Extension
}
}
/**
* Returns a definition for an asset package.
*/
private function createTemplatingPackageDefinition(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 assets configuration.
*
@ -645,9 +562,7 @@ class FrameworkExtension extends Extension
*/
private function registerAssetsConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader)
{
$loader->load('assets.xml');
$defaultVersion = $this->createVersion($container, $config['version'], $config['version_format']);
$defaultVersion = $this->createVersion($container, $config['version'], $config['version_format'], '_default');
$defaultPackage = $this->createPackageDefinition($config['base_path'], $config['base_urls'], $defaultVersion);
$container->setDefinition('assets._default_package', $defaultPackage);
@ -658,7 +573,6 @@ class FrameworkExtension extends Extension
$version = $defaultVersion;
} else {
$format = $package['version_format'] ?: $config['version_format'];
$version = $this->createVersion($container, $package['version'], $format, $name);
}
@ -700,9 +614,9 @@ class FrameworkExtension extends Extension
;
}
private function createVersion(ContainerBuilder $container, $version, $format, $name = null)
private function createVersion(ContainerBuilder $container, $version, $format, $name)
{
if (!$version) {
if (null === $version) {
return new Reference('assets.empty_version_strategy');
}

View File

@ -16,7 +16,6 @@ use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddValidatorInit
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConsoleCommandPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\FormPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TemplatingPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TemplatingAssetHelperPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\RoutingResolverPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ProfilerPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslatorPass;
@ -76,7 +75,6 @@ class FrameworkBundle extends Bundle
// but as late as possible to get resolved parameters
$container->addCompilerPass(new RegisterListenersPass(), PassConfig::TYPE_BEFORE_REMOVING);
$container->addCompilerPass(new TemplatingPass());
$container->addCompilerPass(new TemplatingAssetHelperPass());
$container->addCompilerPass(new AddConstraintValidatorsPass());
$container->addCompilerPass(new AddValidatorInitializersPass());
$container->addCompilerPass(new AddConsoleCommandPass());

View File

@ -7,10 +7,14 @@
<services>
<service id="assets.packages" class="Symfony\Component\Asset\Packages">
<argument /> <!-- default package -->
<argument type="service" id="assets.empty_package" /> <!-- default package -->
<argument type="collection" /> <!-- named packages -->
</service>
<service id="assets.empty_package" class="Symfony\Component\Asset\Package" public="false">
<argument type="service" id="assets.empty_version_strategy" />
</service>
<service id="assets.context" class="Symfony\Component\Asset\Context\RequestStackContext">
<argument type="service" id="request_stack" />
</service>

View File

@ -18,6 +18,7 @@
<xsd:complexType name="config">
<xsd:all>
<xsd:element name="assets" type="assets" minOccurs="0" maxOccurs="1" />
<xsd:element name="form" type="form" minOccurs="0" maxOccurs="1" />
<xsd:element name="csrf-protection" type="csrf_protection" minOccurs="0" maxOccurs="1" />
<xsd:element name="esi" type="esi" minOccurs="0" maxOccurs="1" />
@ -125,12 +126,34 @@
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="assets">
<xsd:sequence>
<xsd:element name="base-url" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="package" type="package" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="base-path" type="xsd:string" />
<xsd:attribute name="version" type="xsd:string" />
<xsd:attribute name="version-format" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="package">
<xsd:sequence>
<xsd:element name="base-url" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
<xsd:attribute name="base-path" type="xsd:string" />
<xsd:attribute name="version" type="xsd:string" />
<xsd:attribute name="version-format" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="templating">
<xsd:sequence>
<xsd:element name="loader" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="engine" type="xsd:string" minOccurs="1" maxOccurs="unbounded" />
<xsd:element name="assets-base-url" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="package" type="package" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="package" type="old-package" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="form" type="form-resources" minOccurs="0" maxOccurs="1" />
</xsd:sequence>
@ -146,7 +169,7 @@
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="package">
<xsd:complexType name="old-package">
<xsd:sequence>
<xsd:element name="base-url" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>

View File

@ -14,7 +14,6 @@
<parameter key="templating.loader.cache.class">Symfony\Component\Templating\Loader\CacheLoader</parameter>
<parameter key="templating.loader.chain.class">Symfony\Component\Templating\Loader\ChainLoader</parameter>
<parameter key="templating.finder.class">Symfony\Bundle\FrameworkBundle\CacheWarmer\TemplateFinder</parameter>
<parameter key="templating.helper.assets.class">Symfony\Component\Templating\Helper\CoreAssetsHelper</parameter>
</parameters>
<services>
@ -59,15 +58,5 @@
</service>
<service id="templating.loader" alias="templating.loader.filesystem" />
<!--
This should be in templating_php.xml but unfortunately, Twig depends on this helper.
As the Twig extension depending on this service is deprecated, this will be removed in 3.0.
-->
<service id="templating.helper.assets" class="%templating.helper.assets.class%">
<tag name="templating.helper" alias="assets" />
<argument /> <!-- default package -->
<argument type="collection" /> <!-- named packages -->
</service>
</services>
</container>

View File

@ -15,6 +15,7 @@
<parameter key="templating.helper.translator.class">Symfony\Bundle\FrameworkBundle\Templating\Helper\TranslatorHelper</parameter>
<parameter key="templating.helper.form.class">Symfony\Bundle\FrameworkBundle\Templating\Helper\FormHelper</parameter>
<parameter key="templating.helper.stopwatch.class">Symfony\Bundle\FrameworkBundle\Templating\Helper\StopwatchHelper</parameter>
<parameter key="templating.helper.assets.class">Symfony\Bundle\FrameworkBundle\Templating\Helper\AssetsHelper</parameter>
<parameter key="templating.form.engine.class">Symfony\Component\Form\Extension\Templating\TemplatingRendererEngine</parameter>
<parameter key="templating.form.renderer.class">Symfony\Component\Form\FormRenderer</parameter>
<parameter key="templating.globals.class">Symfony\Bundle\FrameworkBundle\Templating\GlobalVariables</parameter>
@ -65,6 +66,12 @@
<argument type="service" id="translator" />
</service>
<service id="templating.helper.assets" class="%templating.helper.assets.class%">
<tag name="templating.helper" alias="assets" />
<argument /> <!-- default package -->
<argument type="collection" /> <!-- named packages -->
</service>
<service id="templating.helper.form" class="%templating.helper.form.class%">
<tag name="templating.helper" alias="form" />
<argument type="service" id="templating.form.renderer" />

View File

@ -0,0 +1,126 @@
<?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\Bundle\FrameworkBundle\Templating\Helper;
use Symfony\Component\Asset\Packages;
use Symfony\Component\Asset\VersionStrategy\StaticVersionStrategy;
use Symfony\Component\Templating\Helper\Helper;
/**
* AssetsHelper helps manage asset URLs.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class AssetsHelper extends Helper
{
private $packages;
public function __construct(Packages $packages)
{
$this->packages = $packages;
}
/**
* Returns the public url/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 getUrl($path, $packageName = null, $version = null)
{
// BC layer to be removed in 3.0
if (3 === $count = func_num_args()) {
trigger_error('Forcing a version for an asset was deprecated in 2.7 and will be removed in 3.0.', E_USER_DEPRECATED);
$args = func_get_args();
return $this->getLegacyAssetUrl($path, $packageName, $args[2]);
}
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 getVersion($path = null, $packageName = null)
{
// no arguments means old getVersion() for default package
if (null === $path) {
trigger_error('The getVersion() method requires a path as a first argument since 2.7 and will be enforced as of 3.0.', E_USER_DEPRECATED);
return $this->packages->getVersion('/', $packageName);
}
// path and packageName can only be for the new version
if (null !== $packageName) {
return $this->packages->getVersion($path, $packageName);
}
// packageName is null and path not, so path is a path or a packageName
try {
$package = $this->packages->getPackage($path);
} catch (\InvalidArgumentException $e) {
// path is not a package, so it should be a path
return $this->packages->getVersion($path);
}
// path is a packageName, old version
trigger_error('The getVersion() method requires a path as a first argument since 2.7 and will be enforced as of 3.0.', E_USER_DEPRECATED);
return $this->packages->getVersion('/', $path);
}
private function getLegacyAssetUrl($path, $packageName = null, $version = null)
{
if ($version) {
$package = $this->packages->getPackage($packageName);
$v = new \ReflectionProperty($package, 'versionStrategy');
$v->setAccessible(true);
$currentVersionStrategy = $v->getValue($package);
$f = new \ReflectionProperty($currentVersionStrategy, 'format');
$f->setAccessible(true);
$format = $f->getValue($currentVersionStrategy);
$v->setValue($package, new StaticVersionStrategy($version, $format));
}
$url = $this->packages->getUrl($path, $packageName);
if ($version) {
$v->setValue($package, $currentVersionStrategy);
}
return $url;
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'assets';
}
}

View File

@ -16,7 +16,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
class TemplatingAssetHelperPassTest extends \PHPUnit_Framework_TestCase
class LegacyTemplatingAssetHelperPassTest extends \PHPUnit_Framework_TestCase
{
public function getScopesTests()
{

View File

@ -0,0 +1,25 @@
<?php
$container->loadFromExtension('framework', array(
'assets' => array(
'version' => 'SomeVersionScheme',
'base_urls' => 'http://cdn.example.com',
'version_format' => '%%s?version=%%s',
'packages' => array(
'images_path' => array(
'base_path' => '/foo',
),
'images' => array(
'version' => '1.0.0',
'base_urls' => array('http://images1.example.com', 'http://images2.example.com'),
),
'foo' => array(
'version' => '1.0.0',
'version_format' => '%%s-%%s',
),
'bar' => array(
'base_urls' => array('https://bar2.example.com'),
),
),
),
));

View File

@ -39,23 +39,9 @@ $container->loadFromExtension('framework', array(
'save_path' => '/path/to/sessions',
),
'templating' => array(
'assets_version' => 'SomeVersionScheme',
'assets_base_urls' => 'http://cdn.example.com',
'cache' => '/path/to/cache',
'engines' => array('php', 'twig'),
'loader' => array('loader.foo', 'loader.bar'),
'packages' => array(
'images' => array(
'version' => '1.0.0',
'base_urls' => array('http://images1.example.com', 'http://images2.example.com'),
),
'foo' => array(
'version' => '1.0.0',
),
'bar' => array(
'base_urls' => array('http://bar1.example.com', 'http://bar2.example.com'),
),
),
'form' => array(
'resources' => array('theme1', 'theme2'),
),

View File

@ -0,0 +1,23 @@
<?php
$container->loadFromExtension('framework', array(
'templating' => array(
'engines' => array('php'),
'assets_version' => 'SomeVersionScheme',
'assets_base_urls' => 'http://cdn.example.com',
'assets_version_format' => '%%s?version=%%s',
'packages' => array(
'images' => array(
'version' => '1.0.0',
'base_urls' => array('http://images1.example.com', 'http://images2.example.com'),
),
'foo' => array(
'version' => '1.0.0',
'version_format' => '%%s-%%s',
),
'bar' => array(
'base_urls' => array('https://bar2.example.com'),
),
),
),
));

View File

@ -0,0 +1,23 @@
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:framework="http://symfony.com/schema/dic/symfony"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
<framework:config>
<framework:assets version="SomeVersionScheme" version-format="%%s?version=%%s">
<framework:base-url>http://cdn.example.com</framework:base-url>
<framework:package name="images_path" base-path="/foo" version-format="%%s-%%s" />
<framework:package name="images" version="1.0.0">
<framework:base-url>http://images1.example.com</framework:base-url>
<framework:base-url>http://images2.example.com</framework:base-url>
</framework:package>
<framework:package name="foo" version="1.0.0" version-format="%%s-%%s" />
<framework:package name="bar">
<framework:base-url>https://bar2.example.com</framework:base-url>
</framework:package>
</framework:assets>
</framework:config>
</container>

View File

@ -24,21 +24,11 @@
<framework:mime-type>application/pdf</framework:mime-type>
</framework:format>
</framework:request>
<framework:templating assets-version="SomeVersionScheme" cache="/path/to/cache" hinclude-default-template="global_hinclude_template">
<framework:templating cache="/path/to/cache" hinclude-default-template="global_hinclude_template">
<framework:loader>loader.foo</framework:loader>
<framework:loader>loader.bar</framework:loader>
<framework:engine>php</framework:engine>
<framework:engine>twig</framework:engine>
<framework:assets-base-url>http://cdn.example.com</framework:assets-base-url>
<framework:package name="images" version="1.0.0">
<framework:base-url>http://images1.example.com</framework:base-url>
<framework:base-url>http://images2.example.com</framework:base-url>
</framework:package>
<framework:package name="foo" version="1.0.0" />
<framework:package name="bar">
<framework:base-url>http://bar1.example.com</framework:base-url>
<framework:base-url>http://bar2.example.com</framework:base-url>
</framework:package>
<framework:form>
<framework:resource>theme1</framework:resource>
<framework:resource>theme2</framework:resource>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:framework="http://symfony.com/schema/dic/symfony"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
<framework:config>
<framework:templating assets-version="SomeVersionScheme" assets-version-format="%%s?version=%%s">
<framework:engine>php</framework:engine>
<framework:assets-base-url>http://cdn.example.com</framework:assets-base-url>
<framework:package name="images" version="1.0.0">
<framework:base-url>http://images1.example.com</framework:base-url>
<framework:base-url>http://images2.example.com</framework:base-url>
</framework:package>
<framework:package name="foo" version="1.0.0" version-format="%%s-%%s" />
<framework:package name="bar">
<framework:base-url>https://bar2.example.com</framework:base-url>
</framework:package>
</framework:templating>
</framework:config>
</container>

View File

@ -0,0 +1,16 @@
framework:
assets:
version: SomeVersionScheme
version_format: %%s?version=%%s
base_urls: http://cdn.example.com
packages:
images_path:
base_path: '/foo'
images:
version: 1.0.0
base_urls: ["http://images1.example.com", "http://images2.example.com"]
foo:
version: 1.0.0
version_format: %%s-%%s
bar:
base_urls: ["https://bar2.example.com"]

View File

@ -30,19 +30,9 @@ framework:
gc_maxlifetime: 90000
save_path: /path/to/sessions
templating:
assets_version: SomeVersionScheme
assets_base_urls: http://cdn.example.com
engines: [php, twig]
loader: [loader.foo, loader.bar]
cache: /path/to/cache
packages:
images:
version: 1.0.0
base_urls: ["http://images1.example.com", "http://images2.example.com"]
foo:
version: 1.0.0
bar:
base_urls: ["http://images1.example.com", "http://images2.example.com"]
form:
resources: [theme1, theme2]
hinclude_default_template: global_hinclude_template

View File

@ -0,0 +1,15 @@
framework:
templating:
engines: [php]
assets_version: SomeVersionScheme
assets_version_format: %%s?version=%%s
assets_base_urls: http://cdn.example.com
packages:
images:
version: 1.0.0
base_urls: ["http://images1.example.com", "http://images2.example.com"]
foo:
version: 1.0.0
version_format: %%s-%%s
bar:
base_urls: "https://bar2.example.com"

View File

@ -14,6 +14,8 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection;
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\FrameworkExtension;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\Validator\Validation;
@ -186,21 +188,6 @@ abstract class FrameworkExtensionTest extends TestCase
$this->assertTrue($container->hasDefinition('templating.name_parser'), '->registerTemplatingConfiguration() loads templating.xml');
// 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->assertEquals('%%s?%%s', $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->assertEquals('templating.engine.delegating', (string) $container->getAlias('templating'), '->registerTemplatingConfiguration() configures delegating loader if multiple engines are provided');
$this->assertEquals($container->getDefinition('templating.loader.chain'), $container->getDefinition('templating.loader.wrapped'), '->registerTemplatingConfiguration() configures loader chain if multiple loaders are provided');
@ -216,11 +203,16 @@ abstract class FrameworkExtensionTest extends TestCase
$this->assertEquals('global_hinclude_template', $container->getParameter('fragment.renderer.hinclude.global_template'), '->registerTemplatingConfiguration() registers the global hinclude.js template');
}
public function testTemplatingAssetsHelperScopeDependsOnPackageArgumentScopes()
public function testLegacyTemplatingAssets()
{
$container = $this->createContainerFromFile('templating_url_package');
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
$this->assertNotEquals('request', $container->getDefinition('templating.helper.assets')->getScope(), '->registerTemplatingConfiguration() does not set request scope on assets helper if no packages are request-scoped');
$this->checkAssetsPackages($this->createContainerFromFile('legacy_templating_assets'), true);
}
public function testAssets()
{
$this->checkAssetsPackages($this->createContainerFromFile('assets'));
}
public function testTranslator()
@ -528,4 +520,71 @@ abstract class FrameworkExtensionTest extends TestCase
return $container;
}
protected function createContainerFromClosure($closure, $data = array())
{
$container = $this->createContainer($data);
$container->registerExtension(new FrameworkExtension());
$loader = new ClosureLoader($container);
$loader->load($closure);
$container->getCompilerPassConfig()->setOptimizationPasses(array());
$container->getCompilerPassConfig()->setRemovingPasses(array());
$container->compile();
return $container;
}
private function checkAssetsPackages(ContainerBuilder $container, $legacy = false)
{
$packages = $container->getDefinition('assets.packages');
// default package
$defaultPackage = $container->getDefinition($packages->getArgument(0));
$this->assertUrlPackage($container, $defaultPackage, array('http://cdn.example.com'), 'SomeVersionScheme', '%%s?version=%%s');
// packages
$packages = $packages->getArgument(1);
$this->assertCount($legacy ? 3 : 4, $packages);
if (!$legacy) {
$package = $container->getDefinition($packages['images_path']);
$this->assertPathPackage($container, $package, '/foo', 'SomeVersionScheme', '%%s?version=%%s');
}
$package = $container->getDefinition($packages['images']);
$this->assertUrlPackage($container, $package, array('http://images1.example.com', 'http://images2.example.com'), '1.0.0', $legacy ? '%%s?%%s' : '%%s?version=%%s');
$package = $container->getDefinition($packages['foo']);
$this->assertPathPackage($container, $package, '', '1.0.0', '%%s-%%s');
$package = $container->getDefinition($packages['bar']);
$this->assertUrlPackage($container, $package, array('https://bar2.example.com'), $legacy ? '' : 'SomeVersionScheme', $legacy ? '%%s?%%s' : '%%s?version=%%s');
}
private function assertPathPackage(ContainerBuilder $container, Definition $package, $basePath, $version, $format)
{
$this->assertEquals('assets.path_package', $package->getParent());
$this->assertEquals($basePath, $package->getArgument(0));
$this->assertVersionStrategy($container, $package->getArgument(1), $version, $format);
}
private function assertUrlPackage(ContainerBuilder $container, Definition $package, $baseUrls, $version, $format)
{
$this->assertEquals('assets.url_package', $package->getParent());
$this->assertEquals($baseUrls, $package->getArgument(0));
$this->assertVersionStrategy($container, $package->getArgument(1), $version, $format);
}
private function assertVersionStrategy(ContainerBuilder $container, Reference $reference, $version, $format)
{
$versionStrategy = $container->getDefinition($reference);
if (null === $version) {
$this->assertEquals('assets.empty_version_strategy', (string) $reference);
} else {
$this->assertEquals('assets.static_version_strategy', $versionStrategy->getParent());
$this->assertEquals($version, $versionStrategy->getArgument(0));
$this->assertEquals($format, $versionStrategy->getArgument(1));
}
}
}

View File

@ -22,4 +22,38 @@ class PhpFrameworkExtensionTest extends FrameworkExtensionTest
$loader = new PhpFileLoader($container, new FileLocator(__DIR__.'/Fixtures/php'));
$loader->load($file.'.php');
}
/**
* @expectedException \LogicException
*/
public function testAssetsCannotHavePathAndUrl()
{
$container = $this->createContainerFromClosure(function ($container) {
$container->loadFromExtension('framework', array(
'assets' => array(
'base_urls' => 'http://cdn.example.com',
'base_path' => '/foo',
),
));
});
}
/**
* @expectedException \LogicException
*/
public function testAssetPackageCannotHavePathAndUrl()
{
$container = $this->createContainerFromClosure(function ($container) {
$container->loadFromExtension('framework', array(
'assets' => array(
'packages' => array(
'impossible' => array(
'base_urls' => 'http://cdn.example.com',
'base_path' => '/foo',
),
),
),
));
});
}
}

View File

@ -0,0 +1,46 @@
<?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\Bundle\FrameworkBundle\Tests\Templating\Helper;
use Symfony\Bundle\FrameworkBundle\Templating\Helper\AssetsHelper;
use Symfony\Component\Asset\Package;
use Symfony\Component\Asset\Packages;
use Symfony\Component\Asset\VersionStrategy\StaticVersionStrategy;
class AssetsHelperTest extends \PHPUnit_Framework_TestCase
{
public function testLegacyGetUrl()
{
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
$package = new Package(new StaticVersionStrategy('22', '%s?version=%s'));
$packages = new Packages($package);
$helper = new AssetsHelper($packages);
$this->assertEquals('me.png?version=42', $helper->getUrl('me.png', null, '42'));
}
public function testLegacyGetVersion()
{
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
$package = new Package(new StaticVersionStrategy('22'));
$imagePackage = new Package(new StaticVersionStrategy('42'));
$packages = new Packages($package, array('images' => $imagePackage));
$helper = new AssetsHelper($packages);
$this->assertEquals('22', $helper->getVersion());
$this->assertEquals('22', $helper->getVersion('/foo'));
$this->assertEquals('42', $helper->getVersion('images'));
$this->assertEquals('42', $helper->getVersion('/foo', 'images'));
}
}

View File

@ -48,6 +48,7 @@
"symfony/yaml": "~2.0,>=2.0.5|~3.0.0"
},
"suggest": {
"symfony/asset": "",
"symfony/console": "For using the console commands",
"symfony/finder": "For using the translation loader and cache warmer",
"symfony/form": "For using forms",

View File

@ -82,9 +82,5 @@ class ExtensionPass implements CompilerPassInterface
// we are on Symfony <3.0, where the setContainer method exists
$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');
}
}
}

View File

@ -14,6 +14,8 @@ namespace Symfony\Bundle\TwigBundle\Extension;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Routing\RequestContext;
trigger_error('The '.__NAMESPACE__.'\AssetsExtension class is deprecated since version 2.7 and will be removed in 3.0. Use the Symfony\Bridge\Twig\Extension\AssetExtension class instead.', E_USER_DEPRECATED);
/**
* Twig extension for Symfony assets helper.
*
@ -59,8 +61,6 @@ class AssetsExtension extends \Twig_Extension
*/
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);
if (!$absolute) {
@ -79,8 +79,6 @@ class AssetsExtension extends \Twig_Extension
*/
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);
}

View File

@ -11,7 +11,6 @@
<parameter key="templating.engine.twig.class">Symfony\Bundle\TwigBundle\TwigEngine</parameter>
<parameter key="twig.cache_warmer.class">Symfony\Bundle\TwigBundle\CacheWarmer\TemplateCacheCacheWarmer</parameter>
<parameter key="twig.extension.trans.class">Symfony\Bridge\Twig\Extension\TranslationExtension</parameter>
<parameter key="twig.extension.assets.class">Symfony\Bundle\TwigBundle\Extension\AssetsExtension</parameter>
<parameter key="twig.extension.actions.class">Symfony\Bundle\TwigBundle\Extension\ActionsExtension</parameter>
<parameter key="twig.extension.code.class">Symfony\Bridge\Twig\Extension\CodeExtension</parameter>
<parameter key="twig.extension.routing.class">Symfony\Bridge\Twig\Extension\RoutingExtension</parameter>
@ -86,14 +85,10 @@
<argument type="service" id="translator" />
</service>
<service id="twig.extension.assets" class="%twig.extension.assets.class%" public="false">
<service id="twig.extension.assets" class="Symfony\Bridge\Twig\Extension\AssetExtension" public="false">
<tag name="twig.extension" />
<argument type="service" id="service_container" />
<argument type="service" id="router.request_context" on-invalid="null" />
</service>
<service id="twig.extension.new_assets" class="Symfony\Bridge\Twig\Extension\AssetExtension" public="false">
<argument type="service" id="assets.packages" />
<argument type="service" id="twig.extension.httpfoundation" />
</service>
<service id="twig.extension.actions" class="%twig.extension.actions.class%" public="false">

View File

@ -15,6 +15,11 @@ use Symfony\Component\Templating\Helper\AssetsHelper;
class LegacyAssetsHelperTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
}
public function testGetVersion()
{
$helper = new AssetsHelper(null, array(), 'foo');

View File

@ -19,6 +19,8 @@ class LegacyCoreAssetsHelperTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
$this->package = $this->getMock('Symfony\Component\Templating\Asset\PackageInterface');
}