Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6d79a56

Browse files
committed
[Routing] adds _fragment special option to url generation for document fragment
1 parent fa01e84 commit 6d79a56

File tree

5 files changed

+53
-4
lines changed

5 files changed

+53
-4
lines changed

src/Symfony/Component/Routing/Generator/UrlGenerator.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,14 +257,24 @@ protected function doGenerate($variables, $defaults, $requirements, $tokens, $pa
257257
$url = $schemeAuthority.$this->context->getBaseUrl().$url;
258258
}
259259

260-
// add a query string if needed
260+
// extract unused parameters
261261
$extra = array_diff_key($parameters, $variables, $defaults);
262+
263+
// extract fragment
264+
$fragment = isset($extra['_fragment']) ? $extra['_fragment'] : '';
265+
unset($extra['_fragment']);
266+
267+
// add a query string if needed
262268
if ($extra && $query = http_build_query($extra, '', '&')) {
263269
// "/" and "?" can be left decoded for better user experience, see
264270
// http://tools.ietf.org/html/rfc3986#section-3.4
265271
$url .= '?'.strtr($query, array('%2F' => '/'));
266272
}
267273

274+
if ('' !== $fragment) {
275+
$url .= '#'.strtr(rawurlencode($fragment), array('%2F' => '/', '%3F' => '?'));
276+
}
277+
268278
return $url;
269279
}
270280

src/Symfony/Component/Routing/Generator/UrlGeneratorInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ interface UrlGeneratorInterface extends RequestContextAwareInterface
6969
*
7070
* If there is no route with the given name, the generator must throw the RouteNotFoundException.
7171
*
72+
* The special parameter _fragment will be used as the document fragment suffixed to the final URL.
73+
*
7274
* @param string $name The name of the route
7375
* @param mixed $parameters An array of parameters
7476
* @param int $referenceType The type of reference to be generated (one of the constants)

src/Symfony/Component/Routing/RouteCompiler.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,10 @@ class RouteCompiler implements RouteCompilerInterface
3131
/**
3232
* {@inheritdoc}
3333
*
34-
* @throws \LogicException If a variable is referenced more than once
35-
* @throws \DomainException If a variable name is numeric because PHP raises an error for such
36-
* subpatterns in PCRE and thus would break matching, e.g. "(?P<123>.+)".
34+
* @throws \InvalidArgumentException If a path variable is named _fragment
35+
* @throws \LogicException If a variable is referenced more than once
36+
* @throws \DomainException If a variable name is numeric because PHP raises an error for such
37+
* subpatterns in PCRE and thus would break matching, e.g. "(?P<123>.+)".
3738
*/
3839
public static function compile(Route $route)
3940
{
@@ -59,6 +60,13 @@ public static function compile(Route $route)
5960
$staticPrefix = $result['staticPrefix'];
6061

6162
$pathVariables = $result['variables'];
63+
64+
foreach ($pathVariables as $pathParam) {
65+
if ('_fragment' === $pathParam) {
66+
throw new \InvalidArgumentException(sprintf('Route pattern "%s" cannot contain "_fragment" as a path parameter.', $route->getPath()));
67+
}
68+
}
69+
6270
$variables = array_merge($variables, $pathVariables);
6371

6472
$tokens = $result['tokens'];

src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,25 @@ public function provideRelativePaths()
622622
);
623623
}
624624

625+
public function testFragmentsCanBeAppendedToUrls()
626+
{
627+
$routes = $this->getRoutes('test', new Route('/testing'));
628+
629+
$url = $this->getGenerator($routes)->generate('test', array('_fragment' => 'frag ment'), true);
630+
$this->assertEquals('/app.php/testing#frag%20ment', $url);
631+
632+
$url = $this->getGenerator($routes)->generate('test', array('_fragment' => '0'), true);
633+
$this->assertEquals('/app.php/testing#0', $url);
634+
}
635+
636+
public function testFragmentsDoNotEscapeValidCharacters()
637+
{
638+
$routes = $this->getRoutes('test', new Route('/testing'));
639+
$url = $this->getGenerator($routes)->generate('test', array('_fragment' => '?/'), true);
640+
641+
$this->assertEquals('/app.php/testing#?/', $url);
642+
}
643+
625644
protected function getGenerator(RouteCollection $routes, array $parameters = array(), $logger = null)
626645
{
627646
$context = new RequestContext('/app.php');

src/Symfony/Component/Routing/Tests/RouteCompilerTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,16 @@ public function testRouteWithSameVariableTwice()
175175
$compiled = $route->compile();
176176
}
177177

178+
/**
179+
* @expectedException \InvalidArgumentException
180+
*/
181+
public function testRouteWithFragmentAsPathParameter()
182+
{
183+
$route = new Route('/{_fragment}');
184+
185+
$compiled = $route->compile();
186+
}
187+
178188
/**
179189
* @dataProvider getNumericVariableNames
180190
* @expectedException \DomainException

0 commit comments

Comments
 (0)