Skip to content

Navigation Menu

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 0141b44

Browse filesBrowse files
committed
[HttpKernel] Add a class to generate fragment URLs
1 parent 2dcf313 commit 0141b44
Copy full SHA for 0141b44

File tree

6 files changed

+125
-53
lines changed
Filter options

6 files changed

+125
-53
lines changed

‎src/Symfony/Bridge/Twig/Extension/HttpKernelExtension.php

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Twig/Extension/HttpKernelExtension.php
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,6 @@ public static function controller(string $controller, array $attributes = [], ar
3838
{
3939
return new ControllerReference($controller, $attributes, $query);
4040
}
41+
42+
public static function fragment()
4143
}

‎src/Symfony/Component/HttpKernel/Fragment/AbstractSurrogateFragmentRenderer.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpKernel/Fragment/AbstractSurrogateFragmentRenderer.php
+1-8Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,7 @@ public function render($uri, Request $request, array $options = [])
8383

8484
private function generateSignedFragmentUri(ControllerReference $uri, Request $request): string
8585
{
86-
if (null === $this->signer) {
87-
throw new \LogicException('You must use a URI when using the ESI rendering strategy or set a URL signer.');
88-
}
89-
90-
// we need to sign the absolute URI, but want to return the path only.
91-
$fragmentUri = $this->signer->sign($this->generateFragmentUri($uri, $request, true));
92-
93-
return substr($fragmentUri, \strlen($request->getSchemeAndHttpHost()));
86+
return (new FragmentUriGenerator($this->fragmentPath, $this->signer))->generate($uri, $request);
9487
}
9588

9689
private function containsNonScalars(array $values): bool
+85Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
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\Component\HttpKernel\Fragment;
13+
14+
use Symfony\Component\HttpFoundation\Request;
15+
use Symfony\Component\HttpKernel\UriSigner;
16+
17+
/**
18+
* Generates a fragment URI.
19+
*
20+
* @author Kévin Dunglas <kevin@dunglas.fr>
21+
* @author Fabien Potencier <fabien@symfony.com>
22+
*/
23+
final class FragmentUriGenerator implements FragmentUriGeneratorInterface
24+
{
25+
private $fragmentPath;
26+
private $signer;
27+
28+
public function __construct(string $fragmentPath, UriSigner $signer = null)
29+
{
30+
$this->fragmentPath = $fragmentPath;
31+
$this->signer = $signer;
32+
}
33+
34+
/**
35+
* {@inheritDoc}
36+
*/
37+
public function generate($controller, Request $request, bool $absolute = false, bool $strict = true, bool $sign = true): string
38+
{
39+
if ($sign && null === $this->signer) {
40+
throw new \LogicException('You must use a URI when using the ESI rendering strategy or set a URL signer.');
41+
}
42+
43+
if ($strict) {
44+
$this->checkNonScalar($controller->attributes);
45+
}
46+
47+
// We need to forward the current _format and _locale values as we don't have
48+
// a proper routing pattern to do the job for us.
49+
// This makes things inconsistent if you switch from rendering a controller
50+
// to rendering a route if the route pattern does not contain the special
51+
// _format and _locale placeholders.
52+
if (!isset($controller->attributes['_format'])) {
53+
$controller->attributes['_format'] = $request->getRequestFormat();
54+
}
55+
if (!isset($controller->attributes['_locale'])) {
56+
$controller->attributes['_locale'] = $request->getLocale();
57+
}
58+
59+
$controller->attributes['_controller'] = $controller->controller;
60+
$controller->query['_path'] = http_build_query($controller->attributes, '', '&');
61+
$path = $this->fragmentPath.'?'.http_build_query($controller->query, '', '&');
62+
63+
// we need to sign the absolute URI, but want to return the path only.
64+
$fragmentUri = $sign || $absolute ? $request->getUriForPath($path) : $request->getBaseUrl().$path;
65+
66+
if (!$sign) {
67+
return $fragmentUri;
68+
}
69+
70+
$fragmentUri = $this->signer->sign($fragmentUri);
71+
72+
return $absolute ? $fragmentUri : substr($fragmentUri, \strlen($request->getSchemeAndHttpHost()));
73+
}
74+
75+
private function checkNonScalar(array $values): void
76+
{
77+
foreach ($values as $key => $value) {
78+
if (\is_array($value)) {
79+
$this->checkNonScalar($value);
80+
} elseif (!is_scalar($value) && null !== $value) {
81+
throw new \LogicException(sprintf('Controller attributes cannot contain non-scalar/non-null values (value for key "%s" is not a scalar or null).', $key));
82+
}
83+
}
84+
}
85+
}
+34Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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\Component\HttpKernel\Fragment;
13+
14+
use Symfony\Component\HttpFoundation\Request;
15+
use Symfony\Component\HttpKernel\Controller\ControllerReference;
16+
17+
/**
18+
* Interface implemented by rendering strategies able to generate an URL for a fragment.
19+
*
20+
* @author Kévin Dunglas <kevin@dunglas.fr>
21+
*/
22+
interface FragmentUriGeneratorInterface
23+
{
24+
/**
25+
* Generates a fragment URI for a given controller.
26+
*
27+
* @param string|ControllerReference $controller The name of a controller as a string or a ControllerReference instance
28+
* @param bool $absolute Whether to generate an absolute URL or not
29+
* @param bool $strict Whether to allow non-scalar attributes or not
30+
*
31+
* @return string A fragment URI
32+
*/
33+
public function generate($controller, Request $request, bool $absolute = false, bool $strict = true, bool $sign = true): string;
34+
}

‎src/Symfony/Component/HttpKernel/Fragment/HIncludeFragmentRenderer.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpKernel/Fragment/HIncludeFragmentRenderer.php
+1-6Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,7 @@ public function hasTemplating()
6262
public function render($uri, Request $request, array $options = [])
6363
{
6464
if ($uri instanceof ControllerReference) {
65-
if (null === $this->signer) {
66-
throw new \LogicException('You must use a proper URI when using the Hinclude rendering strategy or set a URL signer.');
67-
}
68-
69-
// we need to sign the absolute URI, but want to return the path only.
70-
$uri = substr($this->signer->sign($this->generateFragmentUri($uri, $request, true)), \strlen($request->getSchemeAndHttpHost()));
65+
$uri = (new FragmentUriGenerator($this->fragmentPath, $this->signer))->generate($uri, $request);
7166
}
7267

7368
// We need to replace ampersands in the URI with the encoded form in order to return valid html/xml content.

‎src/Symfony/Component/HttpKernel/Fragment/RoutableFragmentRenderer.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpKernel/Fragment/RoutableFragmentRenderer.php
+2-39Lines changed: 2 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
*/
2323
abstract class RoutableFragmentRenderer implements FragmentRendererInterface
2424
{
25-
private $fragmentPath = '/_fragment';
25+
protected $fragmentPath = '/_fragment';
2626

2727
/**
2828
* Sets the fragment path that triggers the fragment listener.
@@ -44,43 +44,6 @@ public function setFragmentPath(string $path)
4444
*/
4545
protected function generateFragmentUri(ControllerReference $reference, Request $request, bool $absolute = false, bool $strict = true)
4646
{
47-
if ($strict) {
48-
$this->checkNonScalar($reference->attributes);
49-
}
50-
51-
// We need to forward the current _format and _locale values as we don't have
52-
// a proper routing pattern to do the job for us.
53-
// This makes things inconsistent if you switch from rendering a controller
54-
// to rendering a route if the route pattern does not contain the special
55-
// _format and _locale placeholders.
56-
if (!isset($reference->attributes['_format'])) {
57-
$reference->attributes['_format'] = $request->getRequestFormat();
58-
}
59-
if (!isset($reference->attributes['_locale'])) {
60-
$reference->attributes['_locale'] = $request->getLocale();
61-
}
62-
63-
$reference->attributes['_controller'] = $reference->controller;
64-
65-
$reference->query['_path'] = http_build_query($reference->attributes, '', '&');
66-
67-
$path = $this->fragmentPath.'?'.http_build_query($reference->query, '', '&');
68-
69-
if ($absolute) {
70-
return $request->getUriForPath($path);
71-
}
72-
73-
return $request->getBaseUrl().$path;
74-
}
75-
76-
private function checkNonScalar(array $values)
77-
{
78-
foreach ($values as $key => $value) {
79-
if (\is_array($value)) {
80-
$this->checkNonScalar($value);
81-
} elseif (!is_scalar($value) && null !== $value) {
82-
throw new \LogicException(sprintf('Controller attributes cannot contain non-scalar/non-null values (value for key "%s" is not a scalar or null).', $key));
83-
}
84-
}
47+
return (new FragmentUriGenerator($this->fragmentPath))->generate($reference, $request, $absolute, $strict, false);
8548
}
8649
}

0 commit comments

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