Skip to content

Commit

Permalink
[Twig Hooks] Allow to define a section in the hook name that will be …
Browse files Browse the repository at this point in the history
…discarded while creating a hook name
  • Loading branch information
jakubtobiasz committed Apr 29, 2024
1 parent 37d0052 commit 6b0a93a
Show file tree
Hide file tree
Showing 14 changed files with 164 additions and 102 deletions.
23 changes: 20 additions & 3 deletions src/TwigHooks/config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Sylius\TwigHooks\Hook\NameGenerator\TemplateNameGenerator;
use Sylius\TwigHooks\Hook\Normalizer\CompositeNameNormalizer;
use Sylius\TwigHooks\Hook\Normalizer\NameNormalizerInterface;
use Sylius\TwigHooks\Hook\Normalizer\RemoveSectionPartNormalizer;
use Sylius\TwigHooks\Provider\ComponentPropsProvider;
use Sylius\TwigHooks\Provider\DefaultConfigurationProvider;
use Sylius\TwigHooks\Provider\DefaultContextProvider;
Expand Down Expand Up @@ -33,7 +35,22 @@
])
;

$services->set('twig_hooks.hook.name_generator.template', TemplateNameGenerator::class);
$services
->set('twig_hooks.hook.normalizer.composite', CompositeNameNormalizer::class)
->args([
tagged_iterator('twig_hooks.hook_normalizer'),
])
->alias(NameNormalizerInterface::class, 'twig_hooks.hook.normalizer.composite')
;

$services
->set('twig_hooks.hook.normalizer.remove_section_part', RemoveSectionPartNormalizer::class)
->args([
param('twig_hooks.hook_name_section_separator'),
])
->tag('twig_hooks.hook_normalizer')
->alias(sprintf('%s $removeSectionPartNormalizer', NameNormalizerInterface::class), 'twig_hooks.hook.normalizer.remove_section_part')
;

$services->set(HooksExtension::class)
->args([
Expand All @@ -49,7 +66,7 @@
$services->set(HooksRuntime::class)
->args([
service('twig_hooks.renderer.hook'),
service('twig_hooks.hook.name_generator.template'),
service('twig_hooks.hook.normalizer.composite'),
param('twig_hooks.enable_autoprefixing'),
])
->tag('twig.runtime')
Expand Down
1 change: 1 addition & 0 deletions src/TwigHooks/src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public function getConfigTreeBuilder(): TreeBuilder
$rootNode
->children()
->booleanNode('enable_autoprefixing')->defaultFalse()->end()
->scalarNode('hook_name_section_separator')->defaultFalse()->end()
->end()
->end();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public function load(array $configs, ContainerBuilder $container): void

$this->registerHooks($container, $config['hooks'], $config['supported_hookable_types']);
$container->setParameter('twig_hooks.enable_autoprefixing', $config['enable_autoprefixing']);
$container->setParameter('twig_hooks.hook_name_section_separator', $config['hook_name_section_separator']);
}

/**
Expand Down
10 changes: 0 additions & 10 deletions src/TwigHooks/src/Hook/NameGenerator/NameGeneratorInterface.php

This file was deleted.

39 changes: 0 additions & 39 deletions src/TwigHooks/src/Hook/NameGenerator/TemplateNameGenerator.php

This file was deleted.

30 changes: 30 additions & 0 deletions src/TwigHooks/src/Hook/Normalizer/CompositeNameNormalizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Sylius\TwigHooks\Hook\Normalizer;

final class CompositeNameNormalizer implements NameNormalizerInterface
{
/** @var array<NameNormalizerInterface> */
private readonly array $nameNormalizers;

/**
* @param iterable<NameNormalizerInterface> $nameNormalizers
*/
public function __construct(iterable $nameNormalizers)
{
$this->nameNormalizers = $nameNormalizers instanceof \Traversable ? iterator_to_array($nameNormalizers) : $nameNormalizers;
}

public function normalize(string $name): string
{
$normalizedHookName = $name;

foreach ($this->nameNormalizers as $nameNormalizer) {
$normalizedHookName = $nameNormalizer->normalize($normalizedHookName);
}

return $normalizedHookName;
}
}
10 changes: 10 additions & 0 deletions src/TwigHooks/src/Hook/Normalizer/NameNormalizerInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace Sylius\TwigHooks\Hook\Normalizer;

interface NameNormalizerInterface
{
public function normalize(string $name): string;
}
33 changes: 33 additions & 0 deletions src/TwigHooks/src/Hook/Normalizer/RemoveSectionPartNormalizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Sylius\TwigHooks\Hook\Normalizer;

final class RemoveSectionPartNormalizer implements NameNormalizerInterface
{
/**
* @param non-empty-string|false $separator
*/
public function __construct(private readonly string|false $separator)
{
}

public function normalize(string $name): string
{
if (false === $this->separator) {
return $name;
}

$parts = explode('.', $name);
$result = [];

foreach ($parts as $part) {
$hookNameExplodedBySectionSeparator = explode($this->separator, $part);

$result[] = current($hookNameExplodedBySectionSeparator);
}

return implode('.', $result);
}
}
2 changes: 0 additions & 2 deletions src/TwigHooks/src/Twig/HooksExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ final class HooksExtension extends AbstractExtension
public function getFunctions(): array
{
return [
new TwigFunction('hook_name', [HooksRuntime::class, 'createHookName']),
new TwigFunction('create_hook_name', [HooksRuntime::class, 'createHookName']),
new TwigFunction('get_hookable_metadata', [HooksRuntime::class, 'getHookableMetadata'], ['needs_context' => true]),
new TwigFunction('get_hookable_context', [HooksRuntime::class, 'getHookableContext'], ['needs_context' => true]),
new TwigFunction('get_hookable_configuration', [HooksRuntime::class, 'getHookableConfiguration'], ['needs_context' => true]),
Expand Down
13 changes: 5 additions & 8 deletions src/TwigHooks/src/Twig/Runtime/HooksRuntime.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Sylius\TwigHooks\Twig\Runtime;

use Sylius\TwigHooks\Bag\DataBagInterface;
use Sylius\TwigHooks\Hook\NameGenerator\NameGeneratorInterface;
use Sylius\TwigHooks\Hook\Normalizer\NameNormalizerInterface;
use Sylius\TwigHooks\Hook\Renderer\HookRendererInterface;
use Sylius\TwigHooks\Hookable\Metadata\HookableMetadata;
use Twig\Error\RuntimeError;
Expand All @@ -17,16 +17,11 @@ final class HooksRuntime implements RuntimeExtensionInterface

public function __construct (
private readonly HookRendererInterface $hookRenderer,
private readonly NameGeneratorInterface $nameGenerator,
private readonly NameNormalizerInterface $nameNormalizer,
private readonly bool $enableAutoprefixing,
) {
}

public function createHookName(string $base, string ...$parts): string
{
return $this->nameGenerator->generate($base, ...$parts);
}

/**
* @param array<string, mixed> $context
* @throws RuntimeError
Expand Down Expand Up @@ -72,6 +67,7 @@ public function renderHook(
): string
{
$hookNames = is_string($hookNames) ? [$hookNames] : $hookNames;
$hookNames = array_map([$this->nameNormalizer, 'normalize'], $hookNames);

$context = $this->getContext($hookContext, $hookableMetadata, $only);
$prefixes = $this->getPrefixes($hookContext, $hookableMetadata);
Expand All @@ -84,7 +80,8 @@ public function renderHook(

foreach ($hookNames as $hookName) {
foreach ($prefixes as $prefix) {
$prefixedHookNames[] = $this->nameGenerator->generate($prefix, $hookName);
$normalizedPrefix = $this->nameNormalizer->normalize($prefix);
$prefixedHookNames[] = implode('.', [$normalizedPrefix, $hookName]);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public function testItReturnsDefaultConfiguration(): void
'component' => HookableComponent::class,
'disabled' => DisabledHookable::class,
],
'hook_name_section_separator' => '#',
],
);
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Tests\Sylius\TwigHooks\Unit\Hook\Normalizer;

use PHPUnit\Framework\TestCase;
use Sylius\TwigHooks\Hook\Normalizer\CompositeNameNormalizer;
use Sylius\TwigHooks\Hook\Normalizer\NameNormalizerInterface;

final class CompositeNameNormalizerTest extends TestCase
{
public function testItNormalizesNameUsingPassedNormalizers(): void
{
$dummyNormalizer = $this->createMock(NameNormalizerInterface::class);
$dummyNormalizer->expects($this->once())->method('normalize')->with('hook_name')->willReturn('hook_name_normalized');
$zummyNormalizer = $this->createMock(NameNormalizerInterface::class);
$zummyNormalizer->expects($this->once())->method('normalize')->with('hook_name_normalized')->willReturn('hook_name_normalized_normalized');

$compositeNameNormalizer = new CompositeNameNormalizer([$dummyNormalizer, $zummyNormalizer]);
$normalizedHookName = $compositeNameNormalizer->normalize('hook_name');

$this->assertSame('hook_name_normalized_normalized', $normalizedHookName);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

namespace Tests\Sylius\TwigHooks\Unit\Hook\Normalizer;

use PHPUnit\Framework\TestCase;
use Sylius\TwigHooks\Hook\Normalizer\RemoveSectionPartNormalizer;

final class RemoveSectionPartNormalizerTest extends TestCase
{
public function testItRemovesSectionPartFromName(): void
{
$removeSectionPartNormalizer = new RemoveSectionPartNormalizer(separator: '#');

$this->assertSame('hook_name_section', $removeSectionPartNormalizer->normalize('hook_name_section'));
$this->assertSame('hook_name', $removeSectionPartNormalizer->normalize('hook_name#section'));
$this->assertSame('hook_name.section', $removeSectionPartNormalizer->normalize('hook_name.section'));
}

public function testItRemovesSectionPartFromNameWithUsingOtherSeparatorThanHash(): void
{
$removeSectionPartNormalizer = new RemoveSectionPartNormalizer(separator: '|');

$this->assertSame('hook_name_section', $removeSectionPartNormalizer->normalize('hook_name_section'));
$this->assertSame('hook_name', $removeSectionPartNormalizer->normalize('hook_name|section'));
$this->assertSame('hook_name.section', $removeSectionPartNormalizer->normalize('hook_name.section'));
}

public function testItSkipsRemovingSectionPartIfSeparatorIsFalse(): void
{
$removeSectionPartNormalizer = new RemoveSectionPartNormalizer(separator: false);

$this->assertSame('hook_name_section', $removeSectionPartNormalizer->normalize('hook_name_section'));
$this->assertSame('hook_name#section', $removeSectionPartNormalizer->normalize('hook_name#section'));
$this->assertSame('hook_name.section', $removeSectionPartNormalizer->normalize('hook_name.section'));
}
}

0 comments on commit 6b0a93a

Please sign in to comment.