From 39a61068541962646ed9b799ccdc7c7d2633cc30 Mon Sep 17 00:00:00 2001 From: Sami Mazouz Date: Wed, 14 Apr 2021 11:34:49 +0100 Subject: [PATCH] Add unparse to Formatter extender (#2780) --- src/Extend/Formatter.php | 27 +++++++++++++ src/Formatter/Formatter.php | 14 ++++++- src/Post/CommentPost.php | 2 +- tests/integration/extenders/FormatterTest.php | 38 +++++++++++++++++++ 4 files changed, 79 insertions(+), 2 deletions(-) diff --git a/src/Extend/Formatter.php b/src/Extend/Formatter.php index 4e8ca7b5c..f1d742cc0 100644 --- a/src/Extend/Formatter.php +++ b/src/Extend/Formatter.php @@ -18,6 +18,7 @@ class Formatter implements ExtenderInterface, LifecycleInterface { private $configurationCallbacks = []; private $parsingCallbacks = []; + private $unparsingCallbacks = []; private $renderingCallbacks = []; /** @@ -58,6 +59,28 @@ class Formatter implements ExtenderInterface, LifecycleInterface return $this; } + /** + * Prepare the system for unparsing. This can be used to modify the text that was parsed. + * Please note that the parsed text must be returned, regardless of whether it's changed. + * + * @param callable|string $callback + * + * The callback can be a closure or invokable class, and should accept: + * - mixed $context + * - string $xml: The parsed text. + * + * The callback should return: + * - string $xml: The text to be unparsed. + * + * @return self + */ + public function unparse($callback) + { + $this->unparsingCallbacks[] = $callback; + + return $this; + } + /** * Prepare the system for rendering. This can be used to modify the xml that will be rendered, or to modify the renderer. * Please note that the xml to be rendered must be returned, regardless of whether it's changed. @@ -91,6 +114,10 @@ class Formatter implements ExtenderInterface, LifecycleInterface $formatter->addParsingCallback(ContainerUtil::wrapCallback($callback, $container)); } + foreach ($this->unparsingCallbacks as $callback) { + $formatter->addUnparsingCallback(ContainerUtil::wrapCallback($callback, $container)); + } + foreach ($this->renderingCallbacks as $callback) { $formatter->addRenderingCallback(ContainerUtil::wrapCallback($callback, $container)); } diff --git a/src/Formatter/Formatter.php b/src/Formatter/Formatter.php index 80683ff2d..44776a2ac 100644 --- a/src/Formatter/Formatter.php +++ b/src/Formatter/Formatter.php @@ -20,6 +20,8 @@ class Formatter protected $parsingCallbacks = []; + protected $unparsingCallbacks = []; + protected $renderingCallbacks = []; /** @@ -52,6 +54,11 @@ class Formatter $this->parsingCallbacks[] = $callback; } + public function addUnparsingCallback($callback) + { + $this->unparsingCallbacks[] = $callback; + } + public function addRenderingCallback($callback) { $this->renderingCallbacks[] = $callback; @@ -98,10 +105,15 @@ class Formatter * Unparse XML. * * @param string $xml + * @param mixed $context * @return string */ - public function unparse($xml) + public function unparse($xml, $context = null) { + foreach ($this->unparsingCallbacks as $callback) { + $xml = $callback($context, $xml); + } + return Unparser::unparse($xml); } diff --git a/src/Post/CommentPost.php b/src/Post/CommentPost.php index d49bed207..6e89e79ea 100644 --- a/src/Post/CommentPost.php +++ b/src/Post/CommentPost.php @@ -128,7 +128,7 @@ class CommentPost extends Post */ public function getContentAttribute($value) { - return static::$formatter->unparse($value); + return static::$formatter->unparse($value, $this); } /** diff --git a/tests/integration/extenders/FormatterTest.php b/tests/integration/extenders/FormatterTest.php index 7a4e12fdf..2dfd66554 100644 --- a/tests/integration/extenders/FormatterTest.php +++ b/tests/integration/extenders/FormatterTest.php @@ -89,6 +89,36 @@ class FormatterTest extends TestCase $this->assertEquals('ReplacedText<a>', $this->getFormatter()->parse('Text')); } + /** + * @test + */ + public function custom_formatter_unparsing_doesnt_work_by_default() + { + $this->assertEquals('Text', $this->getFormatter()->unparse('Text<a>')); + } + + /** + * @test + */ + public function custom_formatter_unparsing_works_if_added_with_closure() + { + $this->extend((new Extend\Formatter)->unparse(function ($context, $xml) { + return 'ReplacedText<a>'; + })); + + $this->assertEquals('ReplacedText', $this->getFormatter()->unparse('Text<a>')); + } + + /** + * @test + */ + public function custom_formatter_unparsing_works_if_added_with_invokable_class() + { + $this->extend((new Extend\Formatter)->unparse(InvokableUnparsing::class)); + + $this->assertEquals('ReplacedText', $this->getFormatter()->unparse('Text<a>')); + } + /** * @test */ @@ -136,6 +166,14 @@ class InvokableParsing } } +class InvokableUnparsing +{ + public function __invoke($context, $xml) + { + return 'ReplacedText<a>'; + } +} + class InvokableRendering { public function __invoke($renderer, $context, $xml, $request)