[Routing] add support for path-relative and scheme-relative URL generation
This commit is contained in:
parent
18c520a5e8
commit
75f59ebe01
@ -40,14 +40,14 @@ class RoutingExtension extends \Twig_Extension
|
||||
);
|
||||
}
|
||||
|
||||
public function getPath($name, $parameters = array())
|
||||
public function getPath($name, $parameters = array(), $relative = false)
|
||||
{
|
||||
return $this->generator->generate($name, $parameters, false);
|
||||
return $this->generator->generate($name, $parameters, $relative ? UrlGeneratorInterface::RELATIVE_PATH : UrlGeneratorInterface::ABSOLUTE_PATH);
|
||||
}
|
||||
|
||||
public function getUrl($name, $parameters = array())
|
||||
public function getUrl($name, $parameters = array(), $schemeRelative = false)
|
||||
{
|
||||
return $this->generator->generate($name, $parameters, true);
|
||||
return $this->generator->generate($name, $parameters, $schemeRelative ? UrlGeneratorInterface::NETWORK_PATH : UrlGeneratorInterface::ABSOLUTE_URL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\Controller;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
@ -19,8 +20,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\Form\FormTypeInterface;
|
||||
use Symfony\Component\Form\Form;
|
||||
use Symfony\Component\Form\FormBuilder;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Doctrine\Bundle\DoctrineBundle\Registry;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Controller is a simple implementation of a Controller.
|
||||
@ -34,15 +35,15 @@ class Controller extends ContainerAware
|
||||
/**
|
||||
* Generates a URL from the given parameters.
|
||||
*
|
||||
* @param string $route The name of the route
|
||||
* @param mixed $parameters An array of parameters
|
||||
* @param Boolean $absolute Whether to generate an absolute URL
|
||||
* @param string $route The name of the route
|
||||
* @param mixed $parameters An array of parameters
|
||||
* @param string $referenceType The type of reference (see UrlGeneratorInterface)
|
||||
*
|
||||
* @return string The generated URL
|
||||
*/
|
||||
public function generateUrl($route, $parameters = array(), $absolute = false)
|
||||
public function generateUrl($route, $parameters = array(), $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH)
|
||||
{
|
||||
return $this->container->get('router')->generate($route, $parameters, $absolute);
|
||||
return $this->container->get('router')->generate($route, $parameters, $referenceType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -12,8 +12,9 @@
|
||||
namespace Symfony\Bundle\FrameworkBundle\Controller;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerAware;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
|
||||
/**
|
||||
* Redirects a request to another URL.
|
||||
@ -45,7 +46,7 @@ class RedirectController extends ContainerAware
|
||||
$attributes = $this->container->get('request')->attributes->get('_route_params');
|
||||
unset($attributes['route'], $attributes['permanent']);
|
||||
|
||||
return new RedirectResponse($this->container->get('router')->generate($route, $attributes, true), $permanent ? 301 : 302);
|
||||
return new RedirectResponse($this->container->get('router')->generate($route, $attributes, UrlGeneratorInterface::ABSOLUTE_URL), $permanent ? 301 : 302);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -36,15 +36,15 @@ class RouterHelper extends Helper
|
||||
/**
|
||||
* Generates a URL from the given parameters.
|
||||
*
|
||||
* @param string $name The name of the route
|
||||
* @param mixed $parameters An array of parameters
|
||||
* @param Boolean $absolute Whether to generate an absolute URL
|
||||
* @param string $name The name of the route
|
||||
* @param mixed $parameters An array of parameters
|
||||
* @param string $referenceType The type of reference (see UrlGeneratorInterface)
|
||||
*
|
||||
* @return string The generated URL
|
||||
*/
|
||||
public function generate($name, $parameters = array(), $absolute = false)
|
||||
public function generate($name, $parameters = array(), $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH)
|
||||
{
|
||||
return $this->generator->generate($name, $parameters, $absolute);
|
||||
return $this->generator->generate($name, $parameters, $referenceType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -55,36 +55,40 @@ class LogoutUrlHelper extends Helper
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the relative logout URL for the firewall.
|
||||
* Generates the absolute logout path for the firewall.
|
||||
*
|
||||
* @param string $key The firewall key
|
||||
* @return string The relative logout URL
|
||||
*
|
||||
* @return string The logout path
|
||||
*/
|
||||
public function getLogoutPath($key)
|
||||
{
|
||||
return $this->generateLogoutUrl($key, false);
|
||||
return $this->generateLogoutUrl($key, UrlGeneratorInterface::ABSOLUTE_PATH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the absolute logout URL for the firewall.
|
||||
* Generates the absolute logout URL for the firewall.
|
||||
*
|
||||
* @param string $key The firewall key
|
||||
* @return string The absolute logout URL
|
||||
*
|
||||
* @return string The logout URL
|
||||
*/
|
||||
public function getLogoutUrl($key)
|
||||
{
|
||||
return $this->generateLogoutUrl($key, true);
|
||||
return $this->generateLogoutUrl($key, UrlGeneratorInterface::ABSOLUTE_URL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the logout URL for the firewall.
|
||||
* Generates the logout URL for the firewall.
|
||||
*
|
||||
* @param string $key The firewall key
|
||||
* @param string $referenceType The type of reference (see UrlGeneratorInterface)
|
||||
*
|
||||
* @param string $key The firewall key
|
||||
* @param Boolean $absolute Whether to generate an absolute URL
|
||||
* @return string The logout URL
|
||||
*
|
||||
* @throws \InvalidArgumentException if no LogoutListener is registered for the key
|
||||
*/
|
||||
private function generateLogoutUrl($key, $absolute)
|
||||
private function generateLogoutUrl($key, $referenceType)
|
||||
{
|
||||
if (!array_key_exists($key, $this->listeners)) {
|
||||
throw new \InvalidArgumentException(sprintf('No LogoutListener found for firewall key "%s".', $key));
|
||||
@ -97,13 +101,13 @@ class LogoutUrlHelper extends Helper
|
||||
if ('/' === $logoutPath[0]) {
|
||||
$request = $this->container->get('request');
|
||||
|
||||
$url = ($absolute ? $request->getUriForPath($logoutPath) : $request->getBasePath() . $logoutPath);
|
||||
$url = UrlGeneratorInterface::ABSOLUTE_URL === $referenceType ? $request->getUriForPath($logoutPath) : $request->getBasePath() . $logoutPath;
|
||||
|
||||
if (!empty($parameters)) {
|
||||
$url .= '?' . http_build_query($parameters);
|
||||
}
|
||||
} else {
|
||||
$url = $this->router->generate($logoutPath, $parameters, $absolute);
|
||||
$url = $this->router->generate($logoutPath, $parameters, $referenceType);
|
||||
}
|
||||
|
||||
return $url;
|
||||
|
@ -12,9 +12,10 @@
|
||||
namespace Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\FormLoginBundle\Security;
|
||||
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
|
||||
|
||||
class LocalizedFormFailureHandler implements AuthenticationFailureHandlerInterface
|
||||
@ -28,6 +29,6 @@ class LocalizedFormFailureHandler implements AuthenticationFailureHandlerInterfa
|
||||
|
||||
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
|
||||
{
|
||||
return new RedirectResponse($this->router->generate('localized_login_path', array(), true));
|
||||
return new RedirectResponse($this->router->generate('localized_login_path', array(), UrlGeneratorInterface::ABSOLUTE_URL));
|
||||
}
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ EOF;
|
||||
private function generateGenerateMethod()
|
||||
{
|
||||
return <<<EOF
|
||||
public function generate(\$name, \$parameters = array(), \$absolute = false)
|
||||
public function generate(\$name, \$parameters = array(), \$referenceType = self::ABSOLUTE_PATH)
|
||||
{
|
||||
if (!isset(self::\$declaredRoutes[\$name])) {
|
||||
throw new RouteNotFoundException(sprintf('Route "%s" does not exist.', \$name));
|
||||
@ -116,7 +116,7 @@ EOF;
|
||||
|
||||
list(\$variables, \$defaults, \$requirements, \$tokens, \$hostnameTokens) = self::\$declaredRoutes[\$name];
|
||||
|
||||
return \$this->doGenerate(\$variables, \$defaults, \$requirements, \$tokens, \$parameters, \$name, \$absolute, \$hostnameTokens);
|
||||
return \$this->doGenerate(\$variables, \$defaults, \$requirements, \$tokens, \$parameters, \$name, \$referenceType, \$hostnameTokens);
|
||||
}
|
||||
EOF;
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function generate($name, $parameters = array(), $absolute = false)
|
||||
public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
|
||||
{
|
||||
if (null === $route = $this->routes->get($name)) {
|
||||
throw new RouteNotFoundException(sprintf('Route "%s" does not exist.', $name));
|
||||
@ -136,15 +136,40 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
|
||||
// the Route has a cache of its own and is not recompiled as long as it does not get modified
|
||||
$compiledRoute = $route->compile();
|
||||
|
||||
return $this->doGenerate($compiledRoute->getVariables(), $route->getDefaults(), $route->getRequirements(), $compiledRoute->getTokens(), $parameters, $name, $absolute, $compiledRoute->getHostnameTokens());
|
||||
return $this->doGenerate($compiledRoute->getVariables(), $route->getDefaults(), $route->getRequirements(), $compiledRoute->getTokens(), $parameters, $name, $referenceType, $compiledRoute->getHostnameTokens());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method converts the reference type to the new value introduced in Symfony 2.2. It can be used by
|
||||
* other UrlGenerator implementations to be BC with Symfony 2.1. Reference type was a Boolean called
|
||||
* $absolute in Symfony 2.1 and only supported two reference types.
|
||||
*
|
||||
* @param Boolean $absolute Whether to generate an absolute URL
|
||||
*
|
||||
* @return string The new reference type
|
||||
*
|
||||
* @deprecated Deprecated since version 2.2, to be removed in 2.3.
|
||||
*/
|
||||
public static function convertReferenceType($absolute)
|
||||
{
|
||||
if (false === $absolute) {
|
||||
return self::ABSOLUTE_PATH;
|
||||
}
|
||||
if (true === $absolute) {
|
||||
return self::ABSOLUTE_URL;
|
||||
}
|
||||
|
||||
return $absolute;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws MissingMandatoryParametersException When route has some missing mandatory parameters
|
||||
* @throws InvalidParameterException When a parameter value is not correct
|
||||
*/
|
||||
protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $absolute, $hostnameTokens)
|
||||
protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostnameTokens)
|
||||
{
|
||||
$referenceType = self::convertReferenceType($referenceType);
|
||||
|
||||
$variables = array_flip($variables);
|
||||
$mergedParams = array_replace($defaults, $this->context->getParameters(), $parameters);
|
||||
|
||||
@ -186,8 +211,8 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
|
||||
$url = '/';
|
||||
}
|
||||
|
||||
// do not encode the contexts base url as it is already encoded (see Symfony\Component\HttpFoundation\Request)
|
||||
$url = $this->context->getBaseUrl().strtr(rawurlencode($url), $this->decodedChars);
|
||||
// the contexts base url is already encoded (see Symfony\Component\HttpFoundation\Request)
|
||||
$url = strtr(rawurlencode($url), $this->decodedChars);
|
||||
|
||||
// the path segments "." and ".." are interpreted as relative reference when resolving a URI; see http://tools.ietf.org/html/rfc3986#section-3.3
|
||||
// so we need to encode them as they are not used for this purpose here
|
||||
@ -199,16 +224,11 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
|
||||
$url = substr($url, 0, -1) . '%2E';
|
||||
}
|
||||
|
||||
// add a query string if needed
|
||||
$extra = array_diff_key($parameters, $variables);
|
||||
if ($extra && $query = http_build_query($extra, '', '&')) {
|
||||
$url .= '?'.$query;
|
||||
}
|
||||
|
||||
$schemeAuthority = '';
|
||||
if ($host = $this->context->getHost()) {
|
||||
$scheme = $this->context->getScheme();
|
||||
if (isset($requirements['_scheme']) && ($req = strtolower($requirements['_scheme'])) && $scheme != $req) {
|
||||
$absolute = true;
|
||||
if (isset($requirements['_scheme']) && ($req = strtolower($requirements['_scheme'])) && $scheme !== $req) {
|
||||
$referenceType = self::ABSOLUTE_URL;
|
||||
$scheme = $req;
|
||||
}
|
||||
|
||||
@ -231,18 +251,20 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
|
||||
}
|
||||
|
||||
$routeHost = $token[1].$mergedParams[$token[3]].$routeHost;
|
||||
} elseif ('text' === $token[0]) {
|
||||
} else {
|
||||
$routeHost = $token[1].$routeHost;
|
||||
}
|
||||
}
|
||||
|
||||
if ($routeHost != $host) {
|
||||
if ($routeHost !== $host) {
|
||||
$host = $routeHost;
|
||||
$absolute = true;
|
||||
if (self::ABSOLUTE_URL !== $referenceType) {
|
||||
$referenceType = self::NETWORK_PATH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($absolute) {
|
||||
if (self::ABSOLUTE_URL === $referenceType || self::NETWORK_PATH === $referenceType) {
|
||||
$port = '';
|
||||
if ('http' === $scheme && 80 != $this->context->getHttpPort()) {
|
||||
$port = ':'.$this->context->getHttpPort();
|
||||
@ -250,10 +272,74 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
|
||||
$port = ':'.$this->context->getHttpsPort();
|
||||
}
|
||||
|
||||
$url = $scheme.'://'.$host.$port.$url;
|
||||
$schemeAuthority = self::NETWORK_PATH === $referenceType ? '//' : "$scheme://";
|
||||
$schemeAuthority .= $host.$port;
|
||||
}
|
||||
}
|
||||
|
||||
if (self::RELATIVE_PATH === $referenceType) {
|
||||
$url = self::getRelativePath($this->context->getPathInfo(), $url);
|
||||
} else {
|
||||
$url = $schemeAuthority.$this->context->getBaseUrl().$url;
|
||||
}
|
||||
|
||||
// add a query string if needed
|
||||
$extra = array_diff_key($parameters, $variables);
|
||||
if ($extra && $query = http_build_query($extra, '', '&')) {
|
||||
$url .= '?'.$query;
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the target path as relative reference from the base path.
|
||||
*
|
||||
* Only the URIs path component (no schema, hostname etc.) is relevant and must be given, starting with a slash.
|
||||
* Both paths must be absolute and not contain relative parts.
|
||||
* Relative URLs from one resource to another are useful when generating self-contained downloadable document archives.
|
||||
* Furthermore, they can be used to reduce the link size in documents.
|
||||
*
|
||||
* Example target paths, given a base path of "/a/b/c/d":
|
||||
* - "/a/b/c/d" -> ""
|
||||
* - "/a/b/c/" -> "./"
|
||||
* - "/a/b/" -> "../"
|
||||
* - "/a/b/c/other" -> "other"
|
||||
* - "/a/x/y" -> "../../x/y"
|
||||
*
|
||||
* @param string $basePath The base path
|
||||
* @param string $targetPath The target path
|
||||
*
|
||||
* @return string The relative target path
|
||||
*/
|
||||
public static function getRelativePath($basePath, $targetPath)
|
||||
{
|
||||
if ($basePath === $targetPath) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$sourceDirs = explode('/', isset($basePath[0]) && '/' === $basePath[0] ? substr($basePath, 1) : $basePath);
|
||||
$targetDirs = explode('/', isset($targetPath[0]) && '/' === $targetPath[0] ? substr($targetPath, 1) : $targetPath);
|
||||
array_pop($sourceDirs);
|
||||
$targetFile = array_pop($targetDirs);
|
||||
|
||||
foreach ($sourceDirs as $i => $dir) {
|
||||
if (isset($targetDirs[$i]) && $dir === $targetDirs[$i]) {
|
||||
unset($sourceDirs[$i], $targetDirs[$i]);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$targetDirs[] = $targetFile;
|
||||
$path = str_repeat('../', count($sourceDirs)) . implode('/', $targetDirs);
|
||||
|
||||
// A reference to the same base directory or an empty subdirectory must be prefixed with "./".
|
||||
// This also applies to a segment with a colon character (e.g., "file:colon") that cannot be used
|
||||
// as the first segment of a relative-path reference, as it would be mistaken for a scheme name
|
||||
// (see http://tools.ietf.org/html/rfc3986#section-4.2).
|
||||
return '' === $path || '/' === $path[0]
|
||||
|| false !== ($colonPos = strpos($path, ':')) && ($colonPos < ($slashPos = strpos($path, '/')) || false === $slashPos)
|
||||
? "./$path" : $path;
|
||||
}
|
||||
}
|
||||
|
@ -18,20 +18,34 @@ use Symfony\Component\Routing\Exception\RouteNotFoundException;
|
||||
* UrlGeneratorInterface is the interface that all URL generator classes must implement.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Tobias Schultze <http://tobion.de>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
interface UrlGeneratorInterface extends RequestContextAwareInterface
|
||||
{
|
||||
/**
|
||||
* These constants define the different types of resource references that are declared
|
||||
* in RFC 3986: http://tools.ietf.org/html/rfc3986
|
||||
* We are using the term "URL" instead of "URI" as this is more common in web applications
|
||||
* and we do not need to distinguish them as the difference is mostly semantical and
|
||||
* less technical. Generating URIs, i.e. representation-independent resource identifiers,
|
||||
* is still possible.
|
||||
*/
|
||||
const ABSOLUTE_URL = 'url';
|
||||
const ABSOLUTE_PATH = 'path';
|
||||
const RELATIVE_PATH = 'relative';
|
||||
const NETWORK_PATH = 'network';
|
||||
|
||||
/**
|
||||
* Generates a URL from the given parameters.
|
||||
*
|
||||
* If the generator is not able to generate the url, it must throw the RouteNotFoundException
|
||||
* as documented below.
|
||||
*
|
||||
* @param string $name The name of the route
|
||||
* @param mixed $parameters An array of parameters
|
||||
* @param Boolean $absolute Whether to generate an absolute URL
|
||||
* @param string $name The name of the route
|
||||
* @param mixed $parameters An array of parameters
|
||||
* @param string $referenceType The type of reference to be generated (see defined constants)
|
||||
*
|
||||
* @return string The generated URL
|
||||
*
|
||||
@ -39,5 +53,5 @@ interface UrlGeneratorInterface extends RequestContextAwareInterface
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function generate($name, $parameters = array(), $absolute = false);
|
||||
public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH);
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ use Symfony\Component\HttpFoundation\Request;
|
||||
class RequestContext
|
||||
{
|
||||
private $baseUrl;
|
||||
private $pathInfo;
|
||||
private $method;
|
||||
private $host;
|
||||
private $scheme;
|
||||
@ -46,7 +47,7 @@ class RequestContext
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function __construct($baseUrl = '', $method = 'GET', $host = 'localhost', $scheme = 'http', $httpPort = 80, $httpsPort = 443)
|
||||
public function __construct($baseUrl = '', $method = 'GET', $host = 'localhost', $scheme = 'http', $httpPort = 80, $httpsPort = 443, $path = '/')
|
||||
{
|
||||
$this->baseUrl = $baseUrl;
|
||||
$this->method = strtoupper($method);
|
||||
@ -54,11 +55,13 @@ class RequestContext
|
||||
$this->scheme = strtolower($scheme);
|
||||
$this->httpPort = $httpPort;
|
||||
$this->httpsPort = $httpsPort;
|
||||
$this->pathInfo = $path;
|
||||
}
|
||||
|
||||
public function fromRequest(Request $request)
|
||||
{
|
||||
$this->setBaseUrl($request->getBaseUrl());
|
||||
$this->setPathInfo($request->getPathInfo());
|
||||
$this->setMethod($request->getMethod());
|
||||
$this->setHost($request->getHost());
|
||||
$this->setScheme($request->getScheme());
|
||||
@ -88,6 +91,26 @@ class RequestContext
|
||||
$this->baseUrl = $baseUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the path info.
|
||||
*
|
||||
* @return string The path info
|
||||
*/
|
||||
public function getPathInfo()
|
||||
{
|
||||
return $this->pathInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the path info.
|
||||
*
|
||||
* @param string $pathInfo The path info
|
||||
*/
|
||||
public function setPathInfo($pathInfo)
|
||||
{
|
||||
$this->pathInfo = $pathInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the HTTP method.
|
||||
*
|
||||
|
@ -202,9 +202,9 @@ class Router implements RouterInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function generate($name, $parameters = array(), $absolute = false)
|
||||
public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
|
||||
{
|
||||
return $this->getGenerator()->generate($name, $parameters, $absolute);
|
||||
return $this->getGenerator()->generate($name, $parameters, $referenceType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -379,7 +379,6 @@ class UrlGeneratorTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testDefaultRequirementOfVariableDisallowsNextSeparator()
|
||||
{
|
||||
|
||||
$routes = $this->getRoutes('test', new Route('/{page}.{_format}'));
|
||||
$this->getGenerator($routes)->generate('test', array('page' => 'do.t', '_format' => 'html'));
|
||||
}
|
||||
@ -388,7 +387,7 @@ class UrlGeneratorTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$routes = $this->getRoutes('test', new Route('/{name}', array(), array(), array(), '{locale}.example.com'));
|
||||
|
||||
$this->assertEquals('http://fr.example.com/app.php/Fabien', $this->getGenerator($routes)->generate('test', array('name' =>'Fabien', 'locale' => 'fr')));
|
||||
$this->assertEquals('//fr.example.com/app.php/Fabien', $this->getGenerator($routes)->generate('test', array('name' =>'Fabien', 'locale' => 'fr')));
|
||||
}
|
||||
|
||||
public function testWithHostnameSameAsContext()
|
||||
@ -440,6 +439,120 @@ class UrlGeneratorTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertNull($generator->generate('test', array('foo' => 'baz'), false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideRelativePaths
|
||||
*/
|
||||
public function testGetRelativePath($sourcePath, $targetPath, $expectedPath)
|
||||
{
|
||||
$this->assertSame($expectedPath, UrlGenerator::getRelativePath($sourcePath, $targetPath));
|
||||
}
|
||||
|
||||
public function provideRelativePaths()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
'/same/dir/',
|
||||
'/same/dir/',
|
||||
''
|
||||
),
|
||||
array(
|
||||
'/same/file',
|
||||
'/same/file',
|
||||
''
|
||||
),
|
||||
array(
|
||||
'/',
|
||||
'/file',
|
||||
'file'
|
||||
),
|
||||
array(
|
||||
'/',
|
||||
'/dir/file',
|
||||
'dir/file'
|
||||
),
|
||||
array(
|
||||
'/dir/file.html',
|
||||
'/dir/different-file.html',
|
||||
'different-file.html'
|
||||
),
|
||||
array(
|
||||
'/same/dir/extra-file',
|
||||
'/same/dir/',
|
||||
'./'
|
||||
),
|
||||
array(
|
||||
'/parent/dir/',
|
||||
'/parent/',
|
||||
'../'
|
||||
),
|
||||
array(
|
||||
'/parent/dir/extra-file',
|
||||
'/parent/',
|
||||
'../'
|
||||
),
|
||||
array(
|
||||
'/a/b/',
|
||||
'/x/y/z/',
|
||||
'../../x/y/z/'
|
||||
),
|
||||
array(
|
||||
'/a/b/c/d/e',
|
||||
'/a/c/d',
|
||||
'../../../c/d'
|
||||
),
|
||||
array(
|
||||
'/a/b/c//',
|
||||
'/a/b/c/',
|
||||
'../'
|
||||
),
|
||||
array(
|
||||
'/a/b/c/',
|
||||
'/a/b/c//',
|
||||
'.//'
|
||||
),
|
||||
array(
|
||||
'/root/a/b/c/',
|
||||
'/root/x/b/c/',
|
||||
'../../../x/b/c/'
|
||||
),
|
||||
array(
|
||||
'/a/b/c/d/',
|
||||
'/a',
|
||||
'../../../../a'
|
||||
),
|
||||
array(
|
||||
'/special-chars/sp%20ce/1€/mäh/e=mc²',
|
||||
'/special-chars/sp%20ce/1€/<µ>/e=mc²',
|
||||
'../<µ>/e=mc²'
|
||||
),
|
||||
array(
|
||||
'not-rooted',
|
||||
'dir/file',
|
||||
'dir/file'
|
||||
),
|
||||
array(
|
||||
'//dir/',
|
||||
'',
|
||||
'../../'
|
||||
),
|
||||
array(
|
||||
'/dir/',
|
||||
'/dir/file:with-colon',
|
||||
'./file:with-colon'
|
||||
),
|
||||
array(
|
||||
'/dir/',
|
||||
'/dir/subdir/file:with-colon',
|
||||
'subdir/file:with-colon'
|
||||
),
|
||||
array(
|
||||
'/dir/',
|
||||
'/dir/:subdir/',
|
||||
'./:subdir/'
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
protected function getGenerator(RouteCollection $routes, array $parameters = array(), $logger = null)
|
||||
{
|
||||
$context = new RequestContext('/app.php');
|
||||
|
@ -67,8 +67,8 @@ class HttpUtils
|
||||
public function createRequest(Request $request, $path)
|
||||
{
|
||||
$newRequest = Request::create($this->generateUri($request, $path), 'get', array(), $request->cookies->all(), array(), $request->server->all());
|
||||
if ($session = $request->getSession()) {
|
||||
$newRequest->setSession($session);
|
||||
if ($request->hasSession()) {
|
||||
$newRequest->setSession($request->getSession());
|
||||
}
|
||||
|
||||
if ($request->attributes->has(SecurityContextInterface::AUTHENTICATION_ERROR)) {
|
||||
@ -127,15 +127,10 @@ class HttpUtils
|
||||
return $request->getUriForPath($path);
|
||||
}
|
||||
|
||||
return $this->generateUrl($path, true);
|
||||
}
|
||||
|
||||
private function generateUrl($route, $absolute = false)
|
||||
{
|
||||
if (null === $this->urlGenerator) {
|
||||
throw new \LogicException('You must provide a UrlGeneratorInterface instance to be able to use routes.');
|
||||
}
|
||||
|
||||
return $this->urlGenerator->generate($route, array(), $absolute);
|
||||
return $this->urlGenerator->generate($path, array(), UrlGeneratorInterface::ABSOLUTE_URL);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user