diff --git a/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php b/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php
index ad7949dfaa682..69d6d326f4d08 100644
--- a/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php
+++ b/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php
@@ -13,6 +13,7 @@
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\RequestContext;
/**
* Twig extension for the Symfony HttpFoundation component.
@@ -22,10 +23,12 @@
class HttpFoundationExtension extends \Twig_Extension
{
private $requestStack;
+ private $requestContext;
- public function __construct(RequestStack $requestStack)
+ public function __construct(RequestStack $requestStack, RequestContext $requestContext = null)
{
$this->requestStack = $requestStack;
+ $this->requestContext = $requestContext;
}
/**
@@ -57,6 +60,23 @@ public function generateAbsoluteUrl($path)
}
if (!$request = $this->requestStack->getMasterRequest()) {
+ if (null !== $this->requestContext && '' !== $host = $this->requestContext->getHost()) {
+ $scheme = $this->requestContext->getScheme();
+ $port = '';
+
+ if ('http' === $scheme && 80 != $this->requestContext->getHttpPort()) {
+ $port = ':'.$this->requestContext->getHttpPort();
+ } elseif ('https' === $scheme && 443 != $this->requestContext->getHttpsPort()) {
+ $port = ':'.$this->requestContext->getHttpsPort();
+ }
+
+ if ('/' !== $path[0]) {
+ $path = rtrim($this->requestContext->getBaseUrl(), '/').'/'.$path;
+ }
+
+ return $scheme.'://'.$host.$port.$path;
+ }
+
return $path;
}
diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/HttpFoundationExtensionTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/HttpFoundationExtensionTest.php
index 91f978a909381..339d43d7c6bd1 100644
--- a/src/Symfony/Bridge/Twig/Tests/Extension/HttpFoundationExtensionTest.php
+++ b/src/Symfony/Bridge/Twig/Tests/Extension/HttpFoundationExtensionTest.php
@@ -14,6 +14,7 @@
use Symfony\Bridge\Twig\Extension\HttpFoundationExtension;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\RequestContext;
class HttpFoundationExtensionTest extends \PHPUnit_Framework_TestCase
{
@@ -43,6 +44,49 @@ public function getGenerateAbsoluteUrlData()
);
}
+ /**
+ * @dataProvider getGenerateAbsoluteUrlRequestContextData
+ */
+ public function testGenerateAbsoluteUrlWithRequestContext($path, $baseUrl, $host, $scheme, $httpPort, $httpsPort, $expected)
+ {
+ if (!class_exists('Symfony\Component\Routing\RequestContext')) {
+ $this->markTestSkipped('The Routing component is needed to run tests that depend on its request context.');
+ }
+
+ $requestContext = new RequestContext($baseUrl, 'GET', $host, $scheme, $httpPort, $httpsPort, $path);
+ $extension = new HttpFoundationExtension(new RequestStack(), $requestContext);
+
+ $this->assertEquals($expected, $extension->generateAbsoluteUrl($path));
+ }
+
+ /**
+ * @dataProvider getGenerateAbsoluteUrlRequestContextData
+ */
+ public function testGenerateAbsoluteUrlWithoutRequestAndRequestContext($path)
+ {
+ if (!class_exists('Symfony\Component\Routing\RequestContext')) {
+ $this->markTestSkipped('The Routing component is needed to run tests that depend on its request context.');
+ }
+
+ $extension = new HttpFoundationExtension(new RequestStack());
+
+ $this->assertEquals($path, $extension->generateAbsoluteUrl($path));
+ }
+
+ public function getGenerateAbsoluteUrlRequestContextData()
+ {
+ return array(
+ array('/foo.png', '/foo', 'localhost', 'http', 80, 443, 'http://localhost/foo.png'),
+ array('foo.png', '/foo', 'localhost', 'http', 80, 443, 'http://localhost/foo/foo.png'),
+ array('foo.png', '/foo/bar/', 'localhost', 'http', 80, 443, 'http://localhost/foo/bar/foo.png'),
+ array('/foo.png', '/foo', 'localhost', 'https', 80, 443, 'https://localhost/foo.png'),
+ array('foo.png', '/foo', 'localhost', 'https', 80, 443, 'https://localhost/foo/foo.png'),
+ array('foo.png', '/foo/bar/', 'localhost', 'https', 80, 443, 'https://localhost/foo/bar/foo.png'),
+ array('/foo.png', '/foo', 'localhost', 'http', 443, 80, 'http://localhost:443/foo.png'),
+ array('/foo.png', '/foo', 'localhost', 'https', 443, 80, 'https://localhost:80/foo.png'),
+ );
+ }
+
public function testGenerateAbsoluteUrlWithScriptFileName()
{
$request = Request::create('http://localhost/app/web/app_dev.php');
diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
index 6a13980fcd048..f2c2a4cee007c 100644
--- a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
+++ b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
@@ -127,6 +127,7 @@
+