Skip to content

Commit 18ef0a2

Browse files
dunglaschalasr
authored andcommitted
[FrameworkBundle][HttpKernel][TwigBridge] Add an helper to generate fragments URL
1 parent 2e8048e commit 18ef0a2

File tree

4 files changed

+49
-1
lines changed

4 files changed

+49
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
-----
66

77
* Add a new `markAsPublic` method on `NotificationEmail` to change the `importance` context option to null after creation
8+
* Add a new `fragment_uri()` helper to generate the URI of a fragment
89

910
5.3.0
1011
-----

Extension/HttpKernelExtension.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public function getFunctions(): array
3030
return [
3131
new TwigFunction('render', [HttpKernelRuntime::class, 'renderFragment'], ['is_safe' => ['html']]),
3232
new TwigFunction('render_*', [HttpKernelRuntime::class, 'renderFragmentStrategy'], ['is_safe' => ['html']]),
33+
new TwigFunction('fragment_uri', [HttpKernelRuntime::class, 'generateFragmentUri']),
3334
new TwigFunction('controller', static::class.'::controller'),
3435
];
3536
}

Extension/HttpKernelRuntime.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\HttpKernel\Controller\ControllerReference;
1515
use Symfony\Component\HttpKernel\Fragment\FragmentHandler;
16+
use Symfony\Component\HttpKernel\Fragment\FragmentUriGeneratorInterface;
1617

1718
/**
1819
* Provides integration with the HttpKernel component.
@@ -22,10 +23,12 @@
2223
final class HttpKernelRuntime
2324
{
2425
private $handler;
26+
private $fragmentUriGenerator;
2527

26-
public function __construct(FragmentHandler $handler)
28+
public function __construct(FragmentHandler $handler, FragmentUriGeneratorInterface $fragmentUriGenerator = null)
2729
{
2830
$this->handler = $handler;
31+
$this->fragmentUriGenerator = $fragmentUriGenerator;
2932
}
3033

3134
/**
@@ -54,4 +57,13 @@ public function renderFragmentStrategy(string $strategy, $uri, array $options =
5457
{
5558
return $this->handler->render($uri, $strategy, $options);
5659
}
60+
61+
public function generateFragmentUri(ControllerReference $controller, bool $absolute = false, bool $strict = true, bool $sign = true): string
62+
{
63+
if (null === $this->fragmentUriGenerator) {
64+
throw new \LogicException(sprintf('An instance of "%s" must be provided to use "%s()".', FragmentUriGeneratorInterface::class, __METHOD__));
65+
}
66+
67+
return $this->fragmentUriGenerator->generate($controller, null, $absolute, $strict, $sign);
68+
}
5769
}

Tests/Extension/HttpKernelExtensionTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,14 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Bridge\Twig\Extension\HttpKernelExtension;
1616
use Symfony\Bridge\Twig\Extension\HttpKernelRuntime;
17+
use Symfony\Bundle\FrameworkBundle\Controller\TemplateController;
1718
use Symfony\Component\HttpFoundation\Request;
1819
use Symfony\Component\HttpFoundation\RequestStack;
1920
use Symfony\Component\HttpFoundation\Response;
2021
use Symfony\Component\HttpKernel\Fragment\FragmentHandler;
2122
use Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface;
23+
use Symfony\Component\HttpKernel\Fragment\FragmentUriGenerator;
24+
use Symfony\Component\HttpKernel\UriSigner;
2225
use Twig\Environment;
2326
use Twig\Loader\ArrayLoader;
2427
use Twig\RuntimeLoader\RuntimeLoaderInterface;
@@ -53,6 +56,37 @@ public function testUnknownFragmentRenderer()
5356
$renderer->render('/foo');
5457
}
5558

59+
public function testGenerateFragmentUri()
60+
{
61+
if (!class_exists(FragmentUriGenerator::class)) {
62+
$this->markTestSkipped('HttpKernel 5.3+ is required');
63+
}
64+
65+
$requestStack = new RequestStack();
66+
$requestStack->push(Request::create('/'));
67+
68+
$fragmentHandler = new FragmentHandler($requestStack);
69+
$fragmentUriGenerator = new FragmentUriGenerator('/_fragment', new UriSigner('s3cr3t'), $requestStack);
70+
71+
$kernelRuntime = new HttpKernelRuntime($fragmentHandler, $fragmentUriGenerator);
72+
73+
$loader = new ArrayLoader([
74+
'index' => sprintf(<<<TWIG
75+
{{ fragment_uri(controller("%s::templateAction", {template: "foo.html.twig"})) }}
76+
TWIG
77+
, TemplateController::class), ]);
78+
$twig = new Environment($loader, ['debug' => true, 'cache' => false]);
79+
$twig->addExtension(new HttpKernelExtension());
80+
81+
$loader = $this->createMock(RuntimeLoaderInterface::class);
82+
$loader->expects($this->any())->method('load')->willReturnMap([
83+
[HttpKernelRuntime::class, $kernelRuntime],
84+
]);
85+
$twig->addRuntimeLoader($loader);
86+
87+
$this->assertSame('/_fragment?_hash=PP8%2FeEbn1pr27I9wmag%2FM6jYGVwUZ0l2h0vhh2OJ6CI%3D&amp;_path=template%3Dfoo.html.twig%26_format%3Dhtml%26_locale%3Den%26_controller%3DSymfonyBundleFrameworkBundleControllerTemplateController%253A%253AtemplateAction', $twig->render('index'));
88+
}
89+
5690
protected function getFragmentHandler($return)
5791
{
5892
$strategy = $this->createMock(FragmentRendererInterface::class);

0 commit comments

Comments
 (0)