Skip to content

Commit

Permalink
Refactor rendering hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
jakubtobiasz committed Dec 19, 2023
1 parent f361f9b commit 97bd55b
Show file tree
Hide file tree
Showing 14 changed files with 161 additions and 54 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,6 @@ jobs:

- name: Run PHPUnit
run: bin/phpunit

- name: Run PHPUnit (Twig Hooks)
run: bin/phpunit -c src/TwigHooks/phpunit.xml.dist
7 changes: 7 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,16 @@
<testsuites>
<testsuite name="TwigHooks Test Suite">
<directory>src/TwigHooks/tests</directory>

</testsuite>
</testsuites>

<groups>
<exclude>
<group>kernel-required</group>
</exclude>
</groups>

<listeners>
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
</listeners>
Expand Down
5 changes: 1 addition & 4 deletions src/TwigHooks/config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,7 @@

$services->set(HooksRuntime::class)
->args([
service('twig_hooks.registry.hookables'),
service('twig_hooks.renderer.hookable'),
service('twig_hooks.profiler.profile')->nullOnInvalid(),
param('kernel.debug'),
service('twig_hooks.renderer.hook'),
])
->tag('twig.runtime')
;
Expand Down
28 changes: 24 additions & 4 deletions src/TwigHooks/config/services/debug.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

use Sylius\TwigHooks\DependencyInjection\CompilerPass\UnregisterDebugServicesPass;
use Sylius\TwigHooks\Hook\Renderer\Debug\HookDebugCommentRenderer;
use Sylius\TwigHooks\Hook\Renderer\Debug\HookProfilerRenderer;
use Sylius\TwigHooks\Hookable\Renderer\Debug\HookableDebugCommentRenderer;
use Sylius\TwigHooks\Hookable\Renderer\Debug\HookableProfilerRenderer;
use Sylius\TwigHooks\Profiler\HooksDataCollector;
use Sylius\TwigHooks\Profiler\Profile;
use Symfony\Component\DependencyInjection\ContainerBuilder;
Expand All @@ -13,17 +15,35 @@
$services = $configurator->services();
$services->defaults()->tag(UnregisterDebugServicesPass::DEBUG_TAG);

$services->set('twig_hooks.renderer.hook.debug', HookDebugCommentRenderer::class)
->decorate('twig_hooks.renderer.hook')
$services->set('twig_hooks.renderer.hook.debug_comment', HookDebugCommentRenderer::class)
->decorate('twig_hooks.renderer.hook', priority: 256)
->args([
service('.inner'),
])
;

$services->set('twig_hooks.renderer.hookable.debug', HookableDebugCommentRenderer::class)
->decorate('twig_hooks.renderer.hookable')
$services->set('twig_hooks.renderer.hook.profiler', HookProfilerRenderer::class)
->decorate('twig_hooks.renderer.hook', priority: 512)
->args([
service('.inner'),
service('twig_hooks.profiler.profile')->nullOnInvalid(),
service('debug.stopwatch')->nullOnInvalid(),
])
;

$services->set('twig_hooks.renderer.hookable.debug_comment', HookableDebugCommentRenderer::class)
->decorate('twig_hooks.renderer.hookable', priority: 256)
->args([
service('.inner'),
])
;

$services->set('twig_hooks.renderer.hookable.profiler', HookableProfilerRenderer::class)
->decorate('twig_hooks.renderer.hookable', priority: 512)
->args([
service('.inner'),
service('twig_hooks.profiler.profile')->nullOnInvalid(),
service('debug.stopwatch')->nullOnInvalid(),
])
;

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ final class UnregisterDebugServicesPass implements CompilerPassInterface
public function process(ContainerBuilder $container): void
{
$debug = !$container->hasParameter('kernel.debug') || $container->getParameter('kernel.debug');

if (true === $debug) {
return;
}
Expand Down
33 changes: 33 additions & 0 deletions src/TwigHooks/src/Hook/Renderer/Debug/HookProfilerRenderer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Sylius\TwigHooks\Hook\Renderer\Debug;

use Sylius\TwigHooks\Hook\Renderer\HookRendererInterface;
use Sylius\TwigHooks\Profiler\Profile;
use Symfony\Component\Stopwatch\Stopwatch;

final class HookProfilerRenderer implements HookRendererInterface
{
public function __construct (
private HookRendererInterface $innerRenderer,
private ?Profile $profile,
private ?Stopwatch $stopwatch,
) {
}

public function render(array $hooksNames, array $data = []): string
{
$this->profile?->registerHookStart($hooksNames);
$this->stopwatch?->start(md5(serialize($hooksNames)));

$rendered = $this->innerRenderer->render($hooksNames, $data);

$this->profile?->registerHookEnd(
$this->stopwatch?->stop(md5(serialize($hooksNames)))->getDuration(),
);

return $rendered;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace Sylius\TwigHooks\Hookable\Renderer\Debug;

use Sylius\TwigHooks\Hookable\AbstractHookable;
use Sylius\TwigHooks\Hookable\Renderer\HookableRendererInterface;
use Sylius\TwigHooks\Profiler\Profile;
use Symfony\Component\Stopwatch\Stopwatch;

final class HookableProfilerRenderer implements HookableRendererInterface
{
public function __construct (
private readonly HookableRendererInterface $innerRenderer,
private readonly ?Profile $profile,
private readonly ?Stopwatch $stopwatch,
) {
}

public function render(AbstractHookable $hookable, array $hookData = []): string
{
$this->profile?->registerHookableRenderStart($hookable);
$this->stopwatch?->start($hookable->getId());

$rendered = $this->innerRenderer->render($hookable, $hookData);

$this->profile?->registerHookableRenderEnd(
$this->stopwatch?->stop($hookable->getId())->getDuration(),
);

return $rendered;
}
}
51 changes: 6 additions & 45 deletions src/TwigHooks/src/Twig/Runtime/HooksRuntime.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@

namespace Sylius\TwigHooks\Twig\Runtime;

use Sylius\TwigHooks\Hookable\AbstractHookable;
use Sylius\TwigHooks\Hookable\Renderer\HookableRendererInterface;
use Sylius\TwigHooks\Profiler\Profile;
use Sylius\TwigHooks\Registry\HookablesRegistry;
use Symfony\Component\Stopwatch\Stopwatch;
use Sylius\TwigHooks\Hook\Renderer\HookRendererInterface;
use Twig\Extension\RuntimeExtensionInterface;

final class HooksRuntime implements RuntimeExtensionInterface
Expand All @@ -17,17 +13,9 @@ final class HooksRuntime implements RuntimeExtensionInterface

public const HOOKABLE_DATA_PARAMETER = 'hookable_data';

private ?Stopwatch $stopwatch = null;

public function __construct (
private HookablesRegistry $hookablesRegistry,
private HookableRendererInterface $compositeHookableRenderer,
private ?Profile $profile,
bool $debug,
private readonly HookRendererInterface $hookRenderer,
) {
if (class_exists(Stopwatch::class) && true === $debug) {
$this->stopwatch = new Stopwatch();
}
}

public function createHookName(string $base, string ...$parts): string
Expand Down Expand Up @@ -84,39 +72,12 @@ public function getHookableConfiguration(array $context): array
* @param array<string> $hooksNames
* @param array<string, mixed> $data
*/
public function renderHook(array $hooksNames, array $data = []): string
public function renderHook(string|array $hooksNames, array $data = []): string
{
$this->profile?->registerHookStart($hooksNames);
$this->stopwatch?->start(md5(serialize($hooksNames)));

$result = [];
$enabledHookables = $this->hookablesRegistry->getEnabledFor($hooksNames);

foreach ($enabledHookables as $hookable) {
$result[] = $this->renderHookable($hookable, $data);
if (is_string($hooksNames)) {
$hooksNames = [$hooksNames];
}

$this->profile?->registerHookEnd(
$this->stopwatch?->stop(md5(serialize($hooksNames)))->getDuration(),
);

return implode(PHP_EOL, $result);
}

/**
* @param array<string, mixed> $data
*/
public function renderHookable(AbstractHookable $hookable, array $data = []): string
{
$this->profile?->registerHookableRenderStart($hookable);
$this->stopwatch?->start($hookable->getId());

$result = $this->compositeHookableRenderer->render($hookable, $data);

$this->profile?->registerHookableRenderEnd(
$this->stopwatch?->stop($hookable->getId())->getDuration(),
);

return $result;
return $this->hookRenderer->render($hooksNames, $data);
}
}
2 changes: 1 addition & 1 deletion src/TwigHooks/src/Twig/TokenParser/HookTokenParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public function parse(Token $token): Node
{
$lineno = $token->getLine();
$stream = $this->parser->getStream();
$hookNames = $this->parser->getExpressionParser()->parseMultitargetExpression();
$hookNames = $this->parser->getExpressionParser()->parseExpression();

$variables = null;
if ($stream->nextIf(Token::NAME_TYPE, 'with')) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% hook ['some_hook', 'another_hook'] %}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% hook 'some_hook' %}
46 changes: 46 additions & 0 deletions src/TwigHooks/tests/Functional/Twig/ParsingHookTagTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace Tests\Sylius\TwigHooks\Functional\Twig;

use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Twig\Environment as Twig;

/**
* @group kernel-required
*/
final class ParsingHookTagTest extends KernelTestCase
{
public function testItRendersSingleHookName(): void
{
$this->assertSame(
<<<EXPECTED
<!-- BEGIN HOOK | name: "some_hook" -->
<!-- END HOOK | name: "some_hook" -->
EXPECTED,
$this->render('parsing_hook_tag_test/single_hook_name.html.twig'),
);
}

public function testItRendersMultipleHookNames(): void
{
$this->assertSame(
<<<EXPECTED
<!-- BEGIN HOOK | name: "some_hook, another_hook" -->
<!-- END HOOK | name: "some_hook, another_hook" -->
EXPECTED,
$this->render('parsing_hook_tag_test/multiple_hook_names.html.twig'),
);
}

private function render(string $path): string
{
/** @var Twig $twig */
$twig = $this->getContainer()->get('twig');

return $twig->render($path);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
use Sylius\TwigHooks\Twig\Runtime\HooksRuntime;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

/**
* @group kernel-required
*/
final class HooksRuntimeTest extends KernelTestCase
{
/**
Expand Down

0 comments on commit 97bd55b

Please sign in to comment.