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

Appearance settings

Commit 76b8851

Browse filesBrowse files
committed
[TwigBundle] Add possibility to generate absolute assets urls
1 parent b7c158a commit 76b8851
Copy full SHA for 76b8851

File tree

Expand file treeCollapse file tree

4 files changed

+154
-6
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+154
-6
lines changed

‎src/Symfony/Bundle/TwigBundle/Extension/AssetsExtension.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/TwigBundle/Extension/AssetsExtension.php
+44-5Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Bundle\TwigBundle\Extension;
1313

1414
use Symfony\Component\DependencyInjection\ContainerInterface;
15+
use Symfony\Component\Routing\RequestContext;
1516

1617
/**
1718
* Twig extension for Symfony assets helper
@@ -21,10 +22,12 @@
2122
class AssetsExtension extends \Twig_Extension
2223
{
2324
private $container;
25+
private $context;
2426

25-
public function __construct(ContainerInterface $container)
27+
public function __construct(ContainerInterface $container, RequestContext $requestContext)
2628
{
2729
$this->container = $container;
30+
$this->context = $requestContext;
2831
}
2932

3033
/**
@@ -45,14 +48,21 @@ public function getFunctions()
4548
*
4649
* Absolute paths (i.e. http://...) are returned unmodified.
4750
*
48-
* @param string $path A public path
49-
* @param string $packageName The name of the asset package to use
51+
* @param string $path A public path
52+
* @param string $packageName The name of the asset package to use
53+
* @param Boolean $absolute Whether to return an absolute URL or a relative one
5054
*
5155
* @return string A public path which takes into account the base path and URL path
5256
*/
53-
public function getAssetUrl($path, $packageName = null)
57+
public function getAssetUrl($path, $packageName = null, $absolute = false)
5458
{
55-
return $this->container->get('templating.helper.assets')->getUrl($path, $packageName);
59+
$url = $this->container->get('templating.helper.assets')->getUrl($path, $packageName);
60+
61+
if (!$absolute) {
62+
return $url;
63+
}
64+
65+
return $this->ensureUrlIsAbsolute($url);
5666
}
5767

5868
/**
@@ -76,4 +86,33 @@ public function getName()
7686
{
7787
return 'assets';
7888
}
89+
90+
/**
91+
* Ensures an URL is absolute, if possible.
92+
*
93+
* @param string $url The URL that has to be absolute
94+
*
95+
* @return string The absolute URL
96+
*/
97+
private function ensureUrlIsAbsolute($url)
98+
{
99+
if (false !== strpos($url, '://') || 0 === strpos($url, '//')) {
100+
return $url;
101+
}
102+
103+
if ('' === $host = $this->context->getHost()) {
104+
return $url;
105+
}
106+
107+
$scheme = $this->context->getScheme();
108+
$port = '';
109+
110+
if ('http' === $scheme && 80 != $this->context->getHttpPort()) {
111+
$port = ':'.$this->context->getHttpPort();
112+
} elseif ('https' === $scheme && 443 != $this->context->getHttpsPort()) {
113+
$port = ':'.$this->context->getHttpsPort();
114+
}
115+
116+
return $scheme.'://'.$host.$port.$url;
117+
}
79118
}

‎src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
<service id="twig.extension.assets" class="%twig.extension.assets.class%" public="false">
6767
<tag name="twig.extension" />
6868
<argument type="service" id="service_container" />
69+
<argument type="service" id="router.request_context" />
6970
</service>
7071

7172
<service id="twig.extension.actions" class="%twig.extension.actions.class%" public="false">
+106Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
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+
namespace Symfony\Bundle\TwigBundle\Tests\Extension;
13+
14+
use Symfony\Bundle\TwigBundle\Extension\AssetsExtension;
15+
use Symfony\Bundle\TwigBundle\Tests\TestCase;
16+
use Symfony\Component\Routing\RequestContext;
17+
18+
class AssetsExtensionTest extends TestCase
19+
{
20+
/**
21+
* @dataProvider provideGetGetAssetUrlArguments
22+
*/
23+
public function testGetAssetUrl($path, $packageName, $absolute, $relativeUrl, $expectedUrl, $scheme, $host, $httpPort, $httpsPort)
24+
{
25+
$helper = $this->createHelperMock($path, $packageName, $relativeUrl);
26+
$container = $this->createContainerMock($helper);
27+
28+
$context = $this->createRequestContextMock($scheme, $host, $httpPort, $httpsPort);
29+
30+
$extension = new AssetsExtension($container, $context);
31+
$this->assertEquals($expectedUrl, $extension->getAssetUrl($path, $packageName, $absolute));
32+
}
33+
34+
public function testGetAssetWithtoutHost()
35+
{
36+
$path = '/path/to/asset';
37+
$packageName = null;
38+
$relativeUrl = '/bundle-name/path/to/asset';
39+
40+
$helper = $this->createHelperMock($path, $packageName, $relativeUrl);
41+
$container = $this->createContainerMock($helper);
42+
43+
$context = $this->createRequestContextMock('http', '', 80, 443);
44+
45+
$extension = new AssetsExtension($container, $context);
46+
$this->assertEquals($relativeUrl, $extension->getAssetUrl($path, $packageName, true));
47+
}
48+
49+
public function provideGetGetAssetUrlArguments()
50+
{
51+
return array(
52+
array('/path/to/asset', 'package-name', false, '/bundle-name/path/to/asset', '/bundle-name/path/to/asset', 'http', 'symfony.com', 80, null),
53+
array('/path/to/asset', 'package-name', false, 'http://subdomain.symfony.com/bundle-name/path/to/asset', 'http://subdomain.symfony.com/bundle-name/path/to/asset', 'http', 'symfony.com', 80, null),
54+
array('/path/to/asset', null, false, '/bundle-name/path/to/asset', '/bundle-name/path/to/asset', 'http', 'symfony.com', 80, null),
55+
array('/path/to/asset', 'package-name', true, '/bundle-name/path/to/asset', 'http://symfony.com/bundle-name/path/to/asset', 'http', 'symfony.com', 80, null),
56+
array('/path/to/asset', 'package-name', true, 'http://subdomain.symfony.com/bundle-name/path/to/asset', 'http://subdomain.symfony.com/bundle-name/path/to/asset', 'http', 'symfony.com', 80, null),
57+
array('/path/to/asset', null, true, '/bundle-name/path/to/asset', 'https://symfony.com:92/bundle-name/path/to/asset', 'https', 'symfony.com', null, 92),
58+
array('/path/to/asset', null, true, '/bundle-name/path/to/asset', 'http://symfony.com:660/bundle-name/path/to/asset', 'http', 'symfony.com', 660, null),
59+
);
60+
}
61+
62+
private function createRequestContextMock($scheme, $host, $httpPort, $httpsPort)
63+
{
64+
$context = $this->getMockBuilder('Symfony\Component\Routing\RequestContext')
65+
->disableOriginalConstructor()
66+
->getMock();
67+
$context->expects($this->any())
68+
->method('getScheme')
69+
->will($this->returnValue($scheme));
70+
$context->expects($this->any())
71+
->method('getHost')
72+
->will($this->returnValue($host));
73+
$context->expects($this->any())
74+
->method('getHttpPort')
75+
->will($this->returnValue($httpPort));
76+
$context->expects($this->any())
77+
->method('getHttpsPort')
78+
->will($this->returnValue($httpsPort));
79+
80+
return $context;
81+
}
82+
83+
private function createContainerMock($helper)
84+
{
85+
$container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
86+
$container->expects($this->any())
87+
->method('get')
88+
->with('templating.helper.assets')
89+
->will($this->returnValue($helper));
90+
91+
return $container;
92+
}
93+
94+
private function createHelperMock($path, $packageName, $returnValue)
95+
{
96+
$helper = $this->getMockBuilder('Symfony\Component\Templating\Helper\CoreAssetsHelper')
97+
->disableOriginalConstructor()
98+
->getMock();
99+
$helper->expects($this->any())
100+
->method('getUrl')
101+
->with($path, $packageName)
102+
->will($this->returnValue($returnValue));
103+
104+
return $helper;
105+
}
106+
}

‎src/Symfony/Bundle/TwigBundle/composer.json

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/TwigBundle/composer.json
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
"require-dev": {
2424
"symfony/stopwatch": "~2.2",
2525
"symfony/dependency-injection": "~2.0",
26-
"symfony/config": "~2.2"
26+
"symfony/config": "~2.2",
27+
"symfony/routing": "~2.1",
28+
"symfony/templating": "~2.1"
2729
},
2830
"autoload": {
2931
"psr-0": { "Symfony\\Bundle\\TwigBundle\\": "" }

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.