From 8e445d8839c585cc4db039d931b8c760d8be3c13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kali=C5=84ski?= Date: Tue, 12 May 2026 09:56:23 +0200 Subject: [PATCH 1/2] Simplify callable validation in ContentParser. --- src/Twig/Parser/ContentParser.php | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/Twig/Parser/ContentParser.php b/src/Twig/Parser/ContentParser.php index 426e3f72..d02ec1e3 100644 --- a/src/Twig/Parser/ContentParser.php +++ b/src/Twig/Parser/ContentParser.php @@ -82,15 +82,9 @@ private function callFunction( array $arguments, ): string { Assert::keyExists($functions, $functionName, sprintf('Function %s does not exist!', $functionName)); - /** @var TwigFunction $function */ - $function = $functions[$functionName]; - $callable = $function->getCallable(); - Assert::isArray($callable, sprintf('Function with name "%s" is not callable', $functionName)); - $extension = $callable[0]; - $extensionMethod = $callable[1]; - $callback = [$extension, $extensionMethod]; - Assert::isCallable($callback); - - return call_user_func_array($callback, $arguments); + $callable = $functions[$functionName]->getCallable(); + Assert::isCallable($callable, sprintf('Function with name "%s" is not callable', $functionName)); + + return call_user_func_array($callable, $arguments); } } From 2ecb4c68697619b37473e6acb0e05c25b36996d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kali=C5=84ski?= Date: Tue, 12 May 2026 10:53:20 +0200 Subject: [PATCH 2/2] Add unit tests for ContentParser function handling. --- tests/Unit/Twig/Parser/ContentParserTest.php | 52 ++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/tests/Unit/Twig/Parser/ContentParserTest.php b/tests/Unit/Twig/Parser/ContentParserTest.php index bb97c63b..f8a733fa 100644 --- a/tests/Unit/Twig/Parser/ContentParserTest.php +++ b/tests/Unit/Twig/Parser/ContentParserTest.php @@ -82,4 +82,56 @@ public function testParsesStringFunctions(): void self::assertSame("Let's render! parsed\nLet's render twice! parsed2", $this->contentParser->parse($input)); } + + public function testParsesWithFirstClassCallable(): void + { + $twigEnvironment = $this->createMock(Environment::class); + $twigEnvironment + ->method('getFunctions') + ->willReturn([ + 'app_render_gallery' => new TwigFunction('app_render_gallery', $this->renderGallery(...)), + ]) + ; + + $contentParser = new ContentParser($twigEnvironment, ['app_render_gallery']); + + self::assertSame( + 'gallery: summer', + $contentParser->parse("{{ app_render_gallery('summer') }}"), + ); + } + + public function testSkipsDisabledFunction(): void + { + $this->renderBlockRuntime + ->expects(self::never()) + ->method('renderBlock') + ; + + $contentParser = new ContentParser($this->twigEnvironment, []); + $input = "{{ sylius_cms_render_block('intro') }}"; + + self::assertSame($input, $contentParser->parse($input)); + } + + public function testReplacesWithEmptyStringWhenFunctionNotRegisteredInTwig(): void + { + $twigEnvironment = $this->createMock(Environment::class); + $twigEnvironment + ->method('getFunctions') + ->willReturn([]) + ; + + $contentParser = new ContentParser($twigEnvironment, ['sylius_cms_render_block']); + + self::assertSame( + '', + $contentParser->parse("{{ sylius_cms_render_block('intro') }}"), + ); + } + + private function renderGallery(string $slug): string + { + return sprintf('gallery: %s', $slug); + } }