Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit97cff75

Browse files
committed
feature#13234 [Asset] added the component (fabpot)
This PR was merged into the 2.7 branch.Discussion----------[Asset] added the component| Q | A| ------------- | ---| Bug fix? | yes| New feature? | yes| BC breaks? | no| Deprecations? | yes| Tests pass? | yes| Fixed tickets |#10973,#11748,#11876,#4883,#12474| License | MIT| Doc PR | not yetTODO: - [ ] submit documentation PRThe current Asset sub-namespace in Templating has several (major) problems: * It does not cover all use cases (see#10973 and#4883 for some example) * It has some design issues (relies on the Request instance and so requires the request scope, very coupled with the PHP templating sub-system, see#11748 and#11876)To decouple this feature and make it reusable in Silex for instance, and to fix the design issues and make it more extensible, I've decided to extract and rework the features provided into a new Asset component.Basically, this component allows the developer to easily manage asset URLs: versioning, paths, and hosts.Both the new and the old asset management features are kept in this PR to avoid breaking BC; the old system is of course deprecated and automatically converted to the new one.Even if the features are quite similar, and besides the flexilibity of the new system, here are some differences: * `PathPackage` always prepend the path (even if the given path starts with `/`). * Usage is stricter (for instance, `PathPackage` requires a basePath to be passed and `UrlPackage` requires that at least on URL is passed). * In the configuration, named packages inherits from the version and version format of the default package by default. * It is not possible to override the version when asking for a URL (instead, you can define your own version strategy implementation -- the use cases explained in#6092 are easily implemented this way). * It's not possible to generate absolute URLs (see#13264 for a better alternative using composition; so using `absolute_url(asset_path('me.png')) should work)`.#10973 was about adding shortcuts for bundles, which is a good idea; but given that you rarely reference built-in or third-party bundle assets and because we now have a one-bundle default approach named AppBundle, the same can be achieved with just a simple piece of configuration with the new assets feature:```ymlframework: assets: packages: app: base_path: /bundles/app/ img: base_path: /bundles/app/images/```Then:```jinja{{ asset('images/me.png', 'app') }}# /bundles/app/images/me.png{{ asset('me.png', 'img') }}# /bundles/app/images/me.png```#12474 discussed the possibility to add a version for absolute URL. It's not possible to do that in a generic way as the version strategy involves both the version and the path, which obviously cannot work when the path is an absolute URL already. Instead, one should use the `asset_version` Twig function to add the version manually.Commits-------0750d02 removed usage of the deprecated forms of asset() in the core frameworkf74a1f2 renamed asset_path() to asset() and added a BC layer4d0adea [Asset] added a NullContext classd33c41d [Asset] added the component
2 parentsac389b6 +0750d02 commit97cff75

File tree

72 files changed

+2206
-147
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+2206
-147
lines changed

‎composer.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"psr/log":"~1.0"
2323
},
2424
"replace": {
25+
"symfony/asset":"self.version",
2526
"symfony/browser-kit":"self.version",
2627
"symfony/class-loader":"self.version",
2728
"symfony/config":"self.version",

‎src/Symfony/Bridge/Twig/CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ CHANGELOG
66

77
* added LogoutUrlExtension (provides`logout_url` and`logout_path`)
88
* added an HttpFoundation extension (provides the`absolute_url` and the`relative_path` functions)
9+
* added AssetExtension (provides the`asset` and`asset_version` functions)
910

1011
2.5.0
1112
-----
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Bridge\Twig\Extension;
13+
14+
useSymfony\Component\Asset\Packages;
15+
useSymfony\Component\Asset\VersionStrategy\StaticVersionStrategy;
16+
17+
/**
18+
* Twig extension for the Symfony Asset component.
19+
*
20+
* @author Fabien Potencier <fabien@symfony.com>
21+
*/
22+
class AssetExtensionextends \Twig_Extension
23+
{
24+
private$packages;
25+
private$foundationExtension;
26+
27+
/**
28+
* Passing an HttpFoundationExtension instance as a second argument must not be relied on
29+
* as it's only there to maintain BC with older Symfony version. It will be removed in 3.0.
30+
*/
31+
publicfunction__construct(Packages$packages,HttpFoundationExtension$foundationExtension =null)
32+
{
33+
$this->packages =$packages;
34+
$this->foundationExtension =$foundationExtension;
35+
}
36+
37+
/**
38+
* {@inheritdoc}
39+
*/
40+
publicfunctiongetFunctions()
41+
{
42+
returnarray(
43+
new \Twig_SimpleFunction('asset',array($this,'getAssetUrl')),
44+
new \Twig_SimpleFunction('asset_version',array($this,'getAssetVersion')),
45+
new \Twig_SimpleFunction('assets_version',array($this,'getAssetsVersion')),
46+
);
47+
}
48+
49+
/**
50+
* Returns the public url/path of an asset.
51+
*
52+
* If the package used to generate the path is an instance of
53+
* UrlPackage, you will always get a URL and not a path.
54+
*
55+
* @param string $path A public path
56+
* @param string $packageName The name of the asset package to use
57+
*
58+
* @return string The public path of the asset
59+
*/
60+
publicfunctiongetAssetUrl($path,$packageName =null,$absolute =false,$version =null)
61+
{
62+
// BC layer to be removed in 3.0
63+
if (2 <$count =func_num_args()) {
64+
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);
65+
if (4 ===$count) {
66+
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);
67+
}
68+
69+
$args =func_get_args();
70+
71+
return$this->getLegacyAssetUrl($path,$packageName,$args[2],isset($args[3]) ?$args[3] :null);
72+
}
73+
74+
return$this->packages->getUrl($path,$packageName);
75+
}
76+
77+
/**
78+
* Returns the version of an asset.
79+
*
80+
* @param string $path A public path
81+
* @param string $packageName The name of the asset package to use
82+
*
83+
* @return string The asset version
84+
*/
85+
publicfunctiongetAssetVersion($path,$packageName =null)
86+
{
87+
return$this->packages->getVersion($path,$packageName);
88+
}
89+
90+
publicfunctiongetAssetsVersion($packageName =null)
91+
{
92+
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);
93+
94+
return$this->packages->getVersion('/',$packageName);
95+
}
96+
97+
privatefunctiongetLegacyAssetUrl($path,$packageName =null,$absolute =false,$version =null)
98+
{
99+
if ($version) {
100+
$package =$this->packages->getPackage($packageName);
101+
102+
$v =new \ReflectionProperty($package,'versionStrategy');
103+
$v->setAccessible(true);
104+
105+
$currentVersionStrategy =$v->getValue($package);
106+
107+
$f =new \ReflectionProperty($currentVersionStrategy,'format');
108+
$f->setAccessible(true);
109+
$format =$f->getValue($currentVersionStrategy);
110+
111+
$v->setValue($package,newStaticVersionStrategy($version,$format));
112+
}
113+
114+
try {
115+
$url =$this->packages->getUrl($path,$packageName);
116+
}catch (\Exception$e) {
117+
if ($version) {
118+
$v->setValue($package,$currentVersionStrategy);
119+
}
120+
121+
throw$e;
122+
}
123+
124+
if ($version) {
125+
$v->setValue($package,$currentVersionStrategy);
126+
}
127+
128+
if ($absolute) {
129+
return$this->foundationExtension->generateAbsoluteUrl($url);
130+
}
131+
132+
return$url;
133+
}
134+
135+
/**
136+
* Returns the name of the extension.
137+
*
138+
* @return string The extension name
139+
*/
140+
publicfunctiongetName()
141+
{
142+
return'asset';
143+
}
144+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Bridge\Twig\Tests\Extension;
13+
14+
useSymfony\Bridge\Twig\Extension\AssetExtension;
15+
useSymfony\Component\Asset\Package;
16+
useSymfony\Component\Asset\Packages;
17+
useSymfony\Component\Asset\VersionStrategy\StaticVersionStrategy;
18+
19+
class AssetExtensionTestextends \PHPUnit_Framework_TestCase
20+
{
21+
publicfunctiontestLegacyGetAssetUrl()
22+
{
23+
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
24+
25+
$foundationExtension =$this->getMockBuilder('Symfony\Bridge\Twig\Extension\HttpFoundationExtension')->disableOriginalConstructor()->getMock();
26+
$foundationExtension
27+
->expects($this->any())
28+
->method('generateAbsoluteUrl')
29+
->will($this->returnCallback(function ($arg) {return'http://localhost/'.$arg; }))
30+
;
31+
32+
$package =newPackage(newStaticVersionStrategy('22','%s?version=%s'));
33+
$packages =newPackages($package);
34+
$extension =newAssetExtension($packages,$foundationExtension);
35+
36+
$this->assertEquals('me.png?version=42',$extension->getAssetUrl('me.png',null,false,'42'));
37+
$this->assertEquals('http://localhost/me.png?version=22',$extension->getAssetUrl('me.png',null,true));
38+
$this->assertEquals('http://localhost/me.png?version=42',$extension->getAssetUrl('me.png',null,true,'42'));
39+
}
40+
}

‎src/Symfony/Bridge/Twig/composer.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
},
3838
"suggest": {
3939
"symfony/finder":"",
40+
"symfony/asset":"For using the AssetExtension",
4041
"symfony/form":"For using the FormExtension",
4142
"symfony/http-kernel":"For using the HttpKernelExtension",
4243
"symfony/routing":"For using the RoutingExtension",

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TemplatingAssetHelperPass.php‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@
1616
useSymfony\Component\DependencyInjection\Definition;
1717
useSymfony\Component\DependencyInjection\Reference;
1818

19+
trigger_error('The'.__NAMESPACE__.'\TemplatingAssetHelperPass class is deprecated since version 2.7 and will be removed in 3.0.',E_USER_DEPRECATED);
20+
21+
/**
22+
* @deprecated since 2.7, will be removed in 3.0
23+
*/
1924
class TemplatingAssetHelperPassimplements CompilerPassInterface
2025
{
2126
publicfunctionprocess(ContainerBuilder$container)

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php‎

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,44 @@ public function getConfigTreeBuilder()
5353
return$v;
5454
})
5555
->end()
56+
->validate()
57+
->ifTrue(function ($v) {returnisset($v['templating']); })
58+
->then(function ($v) {
59+
if ($v['templating']['assets_version']
60+
||count($v['templating']['assets_base_urls']['http'])
61+
||count($v['templating']['assets_base_urls']['ssl'])
62+
||count($v['templating']['packages'])
63+
) {
64+
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);
65+
66+
// convert the old configuration to the new one
67+
if (isset($v['assets'])) {
68+
thrownewLogicException('You cannot use assets settings under "templating.templating" and "assets" configurations in the same project.');
69+
}
70+
71+
$v['assets'] =array(
72+
'version' =>$v['templating']['assets_version'],
73+
'version_format' =>$v['templating']['assets_version_format'],
74+
'base_path' =>'',
75+
'base_urls' =>array_values(array_unique(array_merge($v['templating']['assets_base_urls']['http'],$v['templating']['assets_base_urls']['ssl']))),
76+
'packages' =>array(),
77+
);
78+
79+
foreach ($v['templating']['packages']as$name =>$config) {
80+
$v['assets']['packages'][$name] =array(
81+
'version' => (string)$config['version'],
82+
'version_format' =>$config['version_format'],
83+
'base_path' =>'',
84+
'base_urls' =>array_values(array_unique(array_merge($config['base_urls']['http'],$config['base_urls']['ssl']))),
85+
);
86+
}
87+
}
88+
89+
unset($v['templating']['assets_version'],$v['templating']['assets_version_format'],$v['templating']['assets_base_urls'],$v['templating']['packages']);
90+
91+
return$v;
92+
})
93+
->end()
5694
->children()
5795
->scalarNode('secret')->end()
5896
->scalarNode('http_method_override')
@@ -108,6 +146,7 @@ public function getConfigTreeBuilder()
108146
$this->addSessionSection($rootNode);
109147
$this->addRequestSection($rootNode);
110148
$this->addTemplatingSection($rootNode);
149+
$this->addAssetsSection($rootNode);
111150
$this->addTranslatorSection($rootNode);
112151
$this->addValidationSection($rootNode);
113152
$this->addAnnotationsSection($rootNode);
@@ -347,8 +386,8 @@ private function addTemplatingSection(ArrayNodeDefinition $rootNode)
347386
->info('templating configuration')
348387
->canBeUnset()
349388
->children()
350-
->scalarNode('assets_version')->defaultValue(null)->end()
351-
->scalarNode('assets_version_format')->defaultValue('%%s?%%s')->end()
389+
->scalarNode('assets_version')->defaultNull()->info('Deprecated since 2.7, will be removed in 3.0. Use the new assets entry instead.')->end()
390+
->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()
352391
->scalarNode('hinclude_default_template')->defaultNull()->end()
353392
->arrayNode('form')
354393
->addDefaultsIfNotSet()
@@ -370,6 +409,7 @@ private function addTemplatingSection(ArrayNodeDefinition $rootNode)
370409
->fixXmlConfig('assets_base_url')
371410
->children()
372411
->arrayNode('assets_base_urls')
412+
->info('Deprecated since 2.7, will be removed in 3.0. Use the new assets entry instead.')
373413
->performNoDeepMerging()
374414
->addDefaultsIfNotSet()
375415
->beforeNormalization()
@@ -417,6 +457,7 @@ private function addTemplatingSection(ArrayNodeDefinition $rootNode)
417457
->fixXmlConfig('package')
418458
->children()
419459
->arrayNode('packages')
460+
->info('Deprecated since 2.7, will be removed in 3.0. Use the new assets entry instead.')
420461
->useAttributeAsKey('name')
421462
->prototype('array')
422463
->fixXmlConfig('base_url')
@@ -452,6 +493,54 @@ private function addTemplatingSection(ArrayNodeDefinition $rootNode)
452493
;
453494
}
454495

496+
privatefunctionaddAssetsSection(ArrayNodeDefinition$rootNode)
497+
{
498+
$rootNode
499+
->children()
500+
->arrayNode('assets')
501+
->info('assets configuration')
502+
->canBeUnset()
503+
->fixXmlConfig('base_url')
504+
->children()
505+
->scalarNode('version')->defaultNull()->end()
506+
->scalarNode('version_format')->defaultValue('%%s?%%s')->end()
507+
->scalarNode('base_path')->defaultValue('')->end()
508+
->arrayNode('base_urls')
509+
->requiresAtLeastOneElement()
510+
->beforeNormalization()
511+
->ifTrue(function ($v) {return !is_array($v); })
512+
->then(function ($v) {returnarray($v); })
513+
->end()
514+
->prototype('scalar')->end()
515+
->end()
516+
->end()
517+
->fixXmlConfig('package')
518+
->children()
519+
->arrayNode('packages')
520+
->useAttributeAsKey('name')
521+
->prototype('array')
522+
->fixXmlConfig('base_url')
523+
->children()
524+
->scalarNode('version')->defaultNull()->end()
525+
->scalarNode('version_format')->defaultNull()->end()
526+
->scalarNode('base_path')->defaultValue('')->end()
527+
->arrayNode('base_urls')
528+
->requiresAtLeastOneElement()
529+
->beforeNormalization()
530+
->ifTrue(function ($v) {return !is_array($v); })
531+
->then(function ($v) {returnarray($v); })
532+
->end()
533+
->prototype('scalar')->end()
534+
->end()
535+
->end()
536+
->end()
537+
->end()
538+
->end()
539+
->end()
540+
->end()
541+
;
542+
}
543+
455544
privatefunctionaddTranslatorSection(ArrayNodeDefinition$rootNode)
456545
{
457546
$rootNode

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp