feature #10451 [TwigBundle] Add possibility to generate absolute assets urls (romainneutron)
This PR was merged into the 2.5-dev branch.
Discussion
----------
[TwigBundle] Add possibility to generate absolute assets urls
| Q | A
| ------------- | ---
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| License | MIT
| Doc PR | https://github.com/symfony/symfony-docs/pull/3683
This is another approach of #7722
- [x] Add unit tests
- [x] Update doc
Commits
-------
76b8851
[TwigBundle] Add possibility to generate absolute assets urls
This commit is contained in:
commit
48c9985e73
@ -12,6 +12,7 @@
|
||||
namespace Symfony\Bundle\TwigBundle\Extension;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\Routing\RequestContext;
|
||||
|
||||
/**
|
||||
* Twig extension for Symfony assets helper
|
||||
@ -21,10 +22,12 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
class AssetsExtension extends \Twig_Extension
|
||||
{
|
||||
private $container;
|
||||
private $context;
|
||||
|
||||
public function __construct(ContainerInterface $container)
|
||||
public function __construct(ContainerInterface $container, RequestContext $requestContext)
|
||||
{
|
||||
$this->container = $container;
|
||||
$this->context = $requestContext;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,12 +50,19 @@ class AssetsExtension extends \Twig_Extension
|
||||
*
|
||||
* @param string $path A public path
|
||||
* @param string $packageName The name of the asset package to use
|
||||
* @param Boolean $absolute Whether to return an absolute URL or a relative one
|
||||
*
|
||||
* @return string A public path which takes into account the base path and URL path
|
||||
*/
|
||||
public function getAssetUrl($path, $packageName = null)
|
||||
public function getAssetUrl($path, $packageName = null, $absolute = false)
|
||||
{
|
||||
return $this->container->get('templating.helper.assets')->getUrl($path, $packageName);
|
||||
$url = $this->container->get('templating.helper.assets')->getUrl($path, $packageName);
|
||||
|
||||
if (!$absolute) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
return $this->ensureUrlIsAbsolute($url);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -76,4 +86,33 @@ class AssetsExtension extends \Twig_Extension
|
||||
{
|
||||
return 'assets';
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures an URL is absolute, if possible.
|
||||
*
|
||||
* @param string $url The URL that has to be absolute
|
||||
*
|
||||
* @return string The absolute URL
|
||||
*/
|
||||
private function ensureUrlIsAbsolute($url)
|
||||
{
|
||||
if (false !== strpos($url, '://') || 0 === strpos($url, '//')) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
if ('' === $host = $this->context->getHost()) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
$scheme = $this->context->getScheme();
|
||||
$port = '';
|
||||
|
||||
if ('http' === $scheme && 80 != $this->context->getHttpPort()) {
|
||||
$port = ':'.$this->context->getHttpPort();
|
||||
} elseif ('https' === $scheme && 443 != $this->context->getHttpsPort()) {
|
||||
$port = ':'.$this->context->getHttpsPort();
|
||||
}
|
||||
|
||||
return $scheme.'://'.$host.$port.$url;
|
||||
}
|
||||
}
|
||||
|
@ -66,6 +66,7 @@
|
||||
<service id="twig.extension.assets" class="%twig.extension.assets.class%" public="false">
|
||||
<tag name="twig.extension" />
|
||||
<argument type="service" id="service_container" />
|
||||
<argument type="service" id="router.request_context" />
|
||||
</service>
|
||||
|
||||
<service id="twig.extension.actions" class="%twig.extension.actions.class%" public="false">
|
||||
|
@ -0,0 +1,106 @@
|
||||
<?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\TwigBundle\Tests\Extension;
|
||||
|
||||
use Symfony\Bundle\TwigBundle\Extension\AssetsExtension;
|
||||
use Symfony\Bundle\TwigBundle\Tests\TestCase;
|
||||
use Symfony\Component\Routing\RequestContext;
|
||||
|
||||
class AssetsExtensionTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideGetGetAssetUrlArguments
|
||||
*/
|
||||
public function testGetAssetUrl($path, $packageName, $absolute, $relativeUrl, $expectedUrl, $scheme, $host, $httpPort, $httpsPort)
|
||||
{
|
||||
$helper = $this->createHelperMock($path, $packageName, $relativeUrl);
|
||||
$container = $this->createContainerMock($helper);
|
||||
|
||||
$context = $this->createRequestContextMock($scheme, $host, $httpPort, $httpsPort);
|
||||
|
||||
$extension = new AssetsExtension($container, $context);
|
||||
$this->assertEquals($expectedUrl, $extension->getAssetUrl($path, $packageName, $absolute));
|
||||
}
|
||||
|
||||
public function testGetAssetWithtoutHost()
|
||||
{
|
||||
$path = '/path/to/asset';
|
||||
$packageName = null;
|
||||
$relativeUrl = '/bundle-name/path/to/asset';
|
||||
|
||||
$helper = $this->createHelperMock($path, $packageName, $relativeUrl);
|
||||
$container = $this->createContainerMock($helper);
|
||||
|
||||
$context = $this->createRequestContextMock('http', '', 80, 443);
|
||||
|
||||
$extension = new AssetsExtension($container, $context);
|
||||
$this->assertEquals($relativeUrl, $extension->getAssetUrl($path, $packageName, true));
|
||||
}
|
||||
|
||||
public function provideGetGetAssetUrlArguments()
|
||||
{
|
||||
return array(
|
||||
array('/path/to/asset', 'package-name', false, '/bundle-name/path/to/asset', '/bundle-name/path/to/asset', 'http', 'symfony.com', 80, null),
|
||||
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),
|
||||
array('/path/to/asset', null, false, '/bundle-name/path/to/asset', '/bundle-name/path/to/asset', 'http', 'symfony.com', 80, null),
|
||||
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),
|
||||
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),
|
||||
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),
|
||||
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),
|
||||
);
|
||||
}
|
||||
|
||||
private function createRequestContextMock($scheme, $host, $httpPort, $httpsPort)
|
||||
{
|
||||
$context = $this->getMockBuilder('Symfony\Component\Routing\RequestContext')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$context->expects($this->any())
|
||||
->method('getScheme')
|
||||
->will($this->returnValue($scheme));
|
||||
$context->expects($this->any())
|
||||
->method('getHost')
|
||||
->will($this->returnValue($host));
|
||||
$context->expects($this->any())
|
||||
->method('getHttpPort')
|
||||
->will($this->returnValue($httpPort));
|
||||
$context->expects($this->any())
|
||||
->method('getHttpsPort')
|
||||
->will($this->returnValue($httpsPort));
|
||||
|
||||
return $context;
|
||||
}
|
||||
|
||||
private function createContainerMock($helper)
|
||||
{
|
||||
$container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
|
||||
$container->expects($this->any())
|
||||
->method('get')
|
||||
->with('templating.helper.assets')
|
||||
->will($this->returnValue($helper));
|
||||
|
||||
return $container;
|
||||
}
|
||||
|
||||
private function createHelperMock($path, $packageName, $returnValue)
|
||||
{
|
||||
$helper = $this->getMockBuilder('Symfony\Component\Templating\Helper\CoreAssetsHelper')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$helper->expects($this->any())
|
||||
->method('getUrl')
|
||||
->with($path, $packageName)
|
||||
->will($this->returnValue($returnValue));
|
||||
|
||||
return $helper;
|
||||
}
|
||||
}
|
@ -23,7 +23,9 @@
|
||||
"require-dev": {
|
||||
"symfony/stopwatch": "~2.2",
|
||||
"symfony/dependency-injection": "~2.0",
|
||||
"symfony/config": "~2.2"
|
||||
"symfony/config": "~2.2",
|
||||
"symfony/routing": "~2.1",
|
||||
"symfony/templating": "~2.1"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": { "Symfony\\Bundle\\TwigBundle\\": "" }
|
||||
|
Reference in New Issue
Block a user