From dff1ef04bf9f2d60266c40d52c5e04003f22dc53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Wed, 6 Mar 2024 21:00:21 +0100 Subject: [PATCH] Added placeholders filter to utilize the placeholders in twig mode Fixes #546 --- .../LabelSystem/LabelHTMLGenerator.php | 9 +++- .../LabelSystem/LabelTextReplacer.php | 13 ++++- .../LabelSystem/SandboxedTwigFactory.php | 9 +++- src/Twig/Sandbox/SandboxedLabelExtension.php | 51 +++++++++++++++++++ .../LabelSystem/SandboxedTwigFactoryTest.php | 4 ++ 5 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 src/Twig/Sandbox/SandboxedLabelExtension.php diff --git a/src/Services/LabelSystem/LabelHTMLGenerator.php b/src/Services/LabelSystem/LabelHTMLGenerator.php index 620d7746..b2df055e 100644 --- a/src/Services/LabelSystem/LabelHTMLGenerator.php +++ b/src/Services/LabelSystem/LabelHTMLGenerator.php @@ -53,7 +53,14 @@ use Twig\Error\Error; final class LabelHTMLGenerator { - public function __construct(private readonly ElementTypeNameGenerator $elementTypeNameGenerator, private readonly LabelTextReplacer $replacer, private readonly Environment $twig, private readonly LabelBarcodeGenerator $barcodeGenerator, private readonly SandboxedTwigFactory $sandboxedTwigProvider, private readonly Security $security, private readonly string $partdb_title) + public function __construct( + private readonly ElementTypeNameGenerator $elementTypeNameGenerator, + private readonly LabelTextReplacer $replacer, + private readonly Environment $twig, + private readonly LabelBarcodeGenerator $barcodeGenerator, + private readonly SandboxedTwigFactory $sandboxedTwigProvider, + private readonly Security $security, + private readonly string $partdb_title) { } diff --git a/src/Services/LabelSystem/LabelTextReplacer.php b/src/Services/LabelSystem/LabelTextReplacer.php index 034e243f..6f0a9ee8 100644 --- a/src/Services/LabelSystem/LabelTextReplacer.php +++ b/src/Services/LabelSystem/LabelTextReplacer.php @@ -64,6 +64,17 @@ final class LabelTextReplacer * @return string If the placeholder was valid, the replaced info. Otherwise the passed string. */ public function handlePlaceholder(string $placeholder, object $target): string + { + return $this->handlePlaceholderOrReturnNull($placeholder, $target) ?? $placeholder; + } + + /** + * Similar to handlePlaceholder, but returns null if the placeholder is not known (instead of the original string) + * @param string $placeholder + * @param object $target + * @return string|null + */ + public function handlePlaceholderOrReturnNull(string $placeholder, object $target): ?string { foreach ($this->providers as $provider) { /** @var PlaceholderProviderInterface $provider */ @@ -73,7 +84,7 @@ final class LabelTextReplacer } } - return $placeholder; + return null; } /** diff --git a/src/Services/LabelSystem/SandboxedTwigFactory.php b/src/Services/LabelSystem/SandboxedTwigFactory.php index 1ae5d79d..e8a3a4cf 100644 --- a/src/Services/LabelSystem/SandboxedTwigFactory.php +++ b/src/Services/LabelSystem/SandboxedTwigFactory.php @@ -64,6 +64,7 @@ use App\Twig\BarcodeExtension; use App\Twig\EntityExtension; use App\Twig\FormatExtension; use App\Twig\Sandbox\InheritanceSecurityPolicy; +use App\Twig\Sandbox\SandboxedLabelExtension; use App\Twig\TwigCoreExtension; use InvalidArgumentException; use Twig\Environment; @@ -92,6 +93,9 @@ final class SandboxedTwigFactory //FormatExtension: 'format_money', 'format_si', 'format_amount', 'format_bytes', + + //SandboxedLabelExtension + 'placeholders', ]; private const ALLOWED_FUNCTIONS = ['country_names', 'country_timezones', 'currency_names', 'cycle', @@ -103,7 +107,8 @@ final class SandboxedTwigFactory 'entity_type', 'entity_url', //BarcodeExtension: 'barcode_svg', - + //SandboxedLabelExtension + 'placeholder', ]; private const ALLOWED_METHODS = [ @@ -143,6 +148,7 @@ final class SandboxedTwigFactory private readonly BarcodeExtension $barcodeExtension, private readonly EntityExtension $entityExtension, private readonly TwigCoreExtension $twigCoreExtension, + private readonly SandboxedLabelExtension $sandboxedLabelExtension, ) { } @@ -172,6 +178,7 @@ final class SandboxedTwigFactory $twig->addExtension($this->barcodeExtension); $twig->addExtension($this->entityExtension); $twig->addExtension($this->twigCoreExtension); + $twig->addExtension($this->sandboxedLabelExtension); return $twig; } diff --git a/src/Twig/Sandbox/SandboxedLabelExtension.php b/src/Twig/Sandbox/SandboxedLabelExtension.php new file mode 100644 index 00000000..540f204f --- /dev/null +++ b/src/Twig/Sandbox/SandboxedLabelExtension.php @@ -0,0 +1,51 @@ +. + */ + +declare(strict_types=1); + + +namespace App\Twig\Sandbox; + +use App\Services\LabelSystem\LabelTextReplacer; +use Twig\Extension\AbstractExtension; +use Twig\TwigFilter; +use Twig\TwigFunction; + +class SandboxedLabelExtension extends AbstractExtension +{ + public function __construct(private readonly LabelTextReplacer $labelTextReplacer) + { + + } + + public function getFunctions() + { + return [ + new TwigFunction('placeholder', fn(string $text, object $label_target) => $this->labelTextReplacer->handlePlaceholderOrReturnNull($text, $label_target)), + ]; + } + + public function getFilters(): array + { + return [ + new TwigFilter('placeholders', fn(string $text, object $label_target) => $this->labelTextReplacer->replace($text, $label_target)), + ]; + } +} \ No newline at end of file diff --git a/tests/Services/LabelSystem/SandboxedTwigFactoryTest.php b/tests/Services/LabelSystem/SandboxedTwigFactoryTest.php index 2b9a7873..7d43db7a 100644 --- a/tests/Services/LabelSystem/SandboxedTwigFactoryTest.php +++ b/tests/Services/LabelSystem/SandboxedTwigFactoryTest.php @@ -88,6 +88,10 @@ class SandboxedTwigFactoryTest extends WebTestCase '], [' {{ entity_type(part) is object }} + '], + [' + {% apply placeholders(part) %}[[NAME]]{% endapply %}
+ {{ placeholder("[[NAME]]", part) }} '] ]; }