From d39c687d7a9ec50ff255259e6b271a6a05ea06b5 Mon Sep 17 00:00:00 2001 From: Tomasz Kowalczyk Date: Wed, 28 Oct 2020 00:34:07 +0100 Subject: [PATCH] implemented REWRITE_REPLACEMENTS event to manipulate results of all handlers before they are applied to the original text --- src/Event/RewriteReplacementsEvent.php | 48 ++++++++++++++++++++ src/EventHandler/RewriteWrapEventHandler.php | 32 +++++++++++++ src/Events.php | 3 +- src/Processor/Processor.php | 4 ++ src/Shortcode/ReplacedShortcode.php | 13 ++++++ tests/EventsTest.php | 17 +++++++ 6 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 src/Event/RewriteReplacementsEvent.php create mode 100644 src/EventHandler/RewriteWrapEventHandler.php diff --git a/src/Event/RewriteReplacementsEvent.php b/src/Event/RewriteReplacementsEvent.php new file mode 100644 index 0000000..38d755a --- /dev/null +++ b/src/Event/RewriteReplacementsEvent.php @@ -0,0 +1,48 @@ + + */ +final class RewriteReplacementsEvent +{ + /** @var ReplacedShortcode[] */ + private $replacements; + /** @var ReplacedShortcode[] */ + private $rewritten = array(); + /** @var bool */ + private $called = false; + + /** @param ReplacedShortcode[] $replacements */ + public function __construct(array $replacements) + { + $this->replacements = $replacements; + } + + /** @return ReplacedShortcode[] */ + public function getReplacements() + { + $this->called = true; + + return $this->replacements; + } + + /** @return void */ + public function addRewritten(ReplacedShortcode $replacement) + { + $this->rewritten[] = $replacement; + } + + /** @return ReplacedShortcode[] */ + public function getRewritten() + { + return $this->called ? $this->rewritten : $this->replacements; + } +} diff --git a/src/EventHandler/RewriteWrapEventHandler.php b/src/EventHandler/RewriteWrapEventHandler.php new file mode 100644 index 0000000..78c9675 --- /dev/null +++ b/src/EventHandler/RewriteWrapEventHandler.php @@ -0,0 +1,32 @@ + + */ +final class RewriteWrapEventHandler +{ + /** @var string */ + private $prefix; + /** @var string */ + private $suffix; + + /** + * @param string $prefix + * @param string $suffix + */ + public function __construct($prefix, $suffix) + { + $this->prefix = $prefix; + $this->suffix = $suffix; + } + + public function __invoke(RewriteReplacementsEvent $event) + { + foreach($event->getReplacements() as $replacement) { + $event->addRewritten($replacement->withReplacement($this->prefix.$replacement->getReplacement().$this->suffix)); + } + } +} diff --git a/src/Events.php b/src/Events.php index 7d7bafb..8ba7e9e 100644 --- a/src/Events.php +++ b/src/Events.php @@ -8,10 +8,11 @@ final class Events { const FILTER_SHORTCODES = 'event.filter-shortcodes'; const REPLACE_SHORTCODES = 'event.replace-shortcodes'; + const REWRITE_REPLACEMENTS = 'event.rewrite-replacements'; /** @return string[] */ public static function getEvents() { - return array(static::FILTER_SHORTCODES, static::REPLACE_SHORTCODES); + return array(static::FILTER_SHORTCODES, static::REPLACE_SHORTCODES, static::REWRITE_REPLACEMENTS); } } diff --git a/src/Processor/Processor.php b/src/Processor/Processor.php index f12cd10..666ff2b 100644 --- a/src/Processor/Processor.php +++ b/src/Processor/Processor.php @@ -3,6 +3,7 @@ use Thunder\Shortcode\Event\ReplaceShortcodesEvent; use Thunder\Shortcode\Event\FilterShortcodesEvent; +use Thunder\Shortcode\Event\RewriteReplacementsEvent; use Thunder\Shortcode\EventContainer\EventContainerInterface; use Thunder\Shortcode\Events; use Thunder\Shortcode\HandlerContainer\HandlerContainerInterface as Handlers; @@ -122,6 +123,9 @@ private function processIteration($text, ProcessorContext $context, ProcessedSho $replaces[] = new ReplacedShortcode($shortcode, $replace); } + $rewriteEvent = new RewriteReplacementsEvent($replaces); + $this->dispatchEvent(Events::REWRITE_REPLACEMENTS, $rewriteEvent); + $replaces = $rewriteEvent->getRewritten(); $applyEvent = new ReplaceShortcodesEvent($text, $replaces, $parent); $this->dispatchEvent(Events::REPLACE_SHORTCODES, $applyEvent); diff --git a/src/Shortcode/ReplacedShortcode.php b/src/Shortcode/ReplacedShortcode.php index 6fa89cb..99c8d6b 100644 --- a/src/Shortcode/ReplacedShortcode.php +++ b/src/Shortcode/ReplacedShortcode.php @@ -26,6 +26,19 @@ public function __construct(ParsedShortcodeInterface $shortcode, $replacement) $this->replacement = $replacement; } + /** + * @param string $replacement + * + * @return self + */ + public function withReplacement($replacement) + { + $base = new Shortcode($this->name, $this->parameters, $this->content, $this->bbCode); + $parsed = new ParsedShortcode($base, $this->text, $this->offset); + + return new self($parsed, $replacement); + } + /** @return string */ public function getReplacement() { diff --git a/tests/EventsTest.php b/tests/EventsTest.php index a6e0cbc..742edf7 100644 --- a/tests/EventsTest.php +++ b/tests/EventsTest.php @@ -5,6 +5,7 @@ use Thunder\Shortcode\EventContainer\EventContainer; use Thunder\Shortcode\EventHandler\FilterRawEventHandler; use Thunder\Shortcode\EventHandler\ReplaceJoinEventHandler; +use Thunder\Shortcode\EventHandler\RewriteWrapEventHandler; use Thunder\Shortcode\Events; use Thunder\Shortcode\HandlerContainer\HandlerContainer; use Thunder\Shortcode\Parser\RegularParser; @@ -76,6 +77,22 @@ public function testDefaultApplier() $this->assertSame('a root[x name c name y] b', $processor->process('a [root]x [name] c[content] [name /] [/content] y[/root] b')); } + public function testRewriteReplacements() + { + $handlers = new HandlerContainer(); + $handlers->add('name', function(ShortcodeInterface $s) { return $s->getName(); }); + $handlers->add('content', function(ShortcodeInterface $s) { return $s->getContent(); }); + $handlers->add('root', function(ProcessedShortcode $s) { return 'root['.$s->getContent().']'; }); + + $events = new EventContainer(); + $events->addListener(Events::REWRITE_REPLACEMENTS, new RewriteWrapEventHandler('>', '<')); + + $processor = new Processor(new RegularParser(), $handlers); + $processor = $processor->withEventContainer($events); + + $this->assertSame('a >root[x >name< c> >name< < y]< b', $processor->process('a [root]x [name] c[content] [name /] [/content] y[/root] b')); + } + public function testExceptionOnHandlerForUnknownEvent() { $events = new EventContainer();