Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Runtime events #32

Merged
merged 11 commits into from
Jan 29, 2016
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,27 @@

## Version 0.*

* v0.6.0 (XX.YY.2016)

* introduced `FilterShortcodesEvent` for modifying set of parsed shortcodes before processing them,
* introduced `ReplaceShortcodesEvent` to alter the way shortcode replacements are applied to source text at each processing level,
* introduced `EventContainerInterface` with default implementation `EventContainer` to store event handlers,
* introduced events handling in `Processor` with events above,
* added `Processor::withEventContainer()` to configure event handlers,
* added `ProcessedShortcode::hasAncestor()` to detect if shortcode has any parent with given name,
* introduced `ReplacedShortcode` which represents parsed shortcode data with replacement returned from its handler,
* introduced ready to use event handlers classes:
* `FilterRawEventHandler` allows to automatically configure shortcodes that should not have their content processed,
* `ReplaceJoinEventHandler` discards the parent shortcode content and returns only concatenated replacements.

* v0.5.3 (26.01.2016)
* massive performance improvements in RegularParser,
* fixed problem with multibyte characters in parsed texts,
* fixed matching shortcodes with invalid names.

* v0.5.2 (20.01.2016)
* fixed bug with subsequent string tokens in RegularParser.

* v0.5.1 (12.11.2015)

* fixed bug leaving part of shortcode text when it contained multibyte characters.
Expand Down
50 changes: 50 additions & 0 deletions src/Event/FilterShortcodesEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php
namespace Thunder\Shortcode\Event;

use Thunder\Shortcode\Shortcode\ParsedShortcodeInterface;
use Thunder\Shortcode\Shortcode\ProcessedShortcode;

/**
* This event is salled immediately after receiving shortcodes from parser to
* make changes before processing with registered handler. Result of this event
* is used directly in processor.
*
* @author Tomasz Kowalczyk <tomasz@kowalczyk.cc>
*/
class FilterShortcodesEvent
{
private $parent;
private $shortcodes;

public function __construct(array $shortcodes, ProcessedShortcode $parent = null)
{
$this->parent = $parent;
$this->setShortcodes($shortcodes);
}

/**
* @return ParsedShortcodeInterface[]
*/
public function getShortcodes()
{
return $this->shortcodes;
}

public function getParent()
{
return $this->parent;
}

public function setShortcodes(array $shortcodes)
{
$this->shortcodes = array();
foreach($shortcodes as $shortcode) {
$this->addShortcode($shortcode);
}
}

private function addShortcode(ParsedShortcodeInterface $shortcode)
{
$this->shortcodes[] = $shortcode;
}
}
72 changes: 72 additions & 0 deletions src/Event/ReplaceShortcodesEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php
namespace Thunder\Shortcode\Event;

use Thunder\Shortcode\Shortcode\ReplacedShortcode;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;

/**
* This event is called just before returning processed text result at each
* processing level to alter the way shortcodes are replaced with their handlers
* results in the source text.
*
* @author Tomasz Kowalczyk <tomasz@kowalczyk.cc>
*/
class ReplaceShortcodesEvent
{
private $shortcode;
private $text;
/** @var ReplacedShortcode[] */
private $replacements;
private $result;

public function __construct($text, array $replacements, ShortcodeInterface $shortcode = null)
{
$this->shortcode = $shortcode;
$this->text = $text;
$this->result = null;

$this->setReplacements($replacements);
}

private function setReplacements(array $replacements)
{
foreach($replacements as $replacement) {
$this->addReplacement($replacement);
}
}

private function addReplacement(ReplacedShortcode $replacement)
{
$this->replacements[] = $replacement;
}

public function getText()
{
return $this->text;
}

public function getReplacements()
{
return $this->replacements;
}

public function getShortcode()
{
return $this->shortcode;
}

public function setResult($result)
{
$this->result = $result;
}

public function getResult()
{
return $this->result;
}

public function hasResult()
{
return null !== $this->result;
}
}
39 changes: 39 additions & 0 deletions src/EventContainer/EventContainer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php
namespace Thunder\Shortcode\EventContainer;

use Thunder\Shortcode\Events;

/**
* @author Tomasz Kowalczyk <tomasz@kowalczyk.cc>
*/
final class EventContainer implements EventContainerInterface
{
private $listeners = array();

public function __construct()
{
}

public function addListener($event, $handler)
{
if(!in_array($event, Events::getEvents())) {
throw new \InvalidArgumentException(sprintf('Unsupported event %s!', $event));
}

if(!array_key_exists($event, $this->listeners)) {
$this->listeners[$event] = array();
}

$this->listeners[$event][] = $handler;
}

public function getListeners($event)
{
return $this->hasEvent($event) ? $this->listeners[$event] : array();
}

private function hasEvent($name)
{
return array_key_exists($name, $this->listeners);
}
}
10 changes: 10 additions & 0 deletions src/EventContainer/EventContainerInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php
namespace Thunder\Shortcode\EventContainer;

/**
* @author Tomasz Kowalczyk <tomasz@kowalczyk.cc>
*/
interface EventContainerInterface
{
public function getListeners($event);
}
34 changes: 34 additions & 0 deletions src/EventHandler/FilterRawEventHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php
namespace Thunder\Shortcode\EventHandler;

use Thunder\Shortcode\Event\FilterShortcodesEvent;

/**
* @author Tomasz Kowalczyk <tomasz@kowalczyk.cc>
*/
final class FilterRawEventHandler
{
/** @var string[] */
private $names = array();

public function __construct(array $names)
{
foreach($names as $name) {
if(false === is_string($name)) {
throw new \InvalidArgumentException('Expected array of strings!');
}

$this->names[] = $name;
}
}

public function __invoke(FilterShortcodesEvent $event)
{
$parent = $event->getParent();
if($parent && in_array($parent->getName(), $this->names)) {
$event->setShortcodes(array());

return;
}
}
}
36 changes: 36 additions & 0 deletions src/EventHandler/ReplaceJoinEventHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php
namespace Thunder\Shortcode\EventHandler;

use Thunder\Shortcode\Event\ReplaceShortcodesEvent;

/**
* @author Tomasz Kowalczyk <tomasz@kowalczyk.cc>
*/
final class ReplaceJoinEventHandler
{
/** @var string[] */
private $names = array();

public function __construct(array $names)
{
foreach($names as $name) {
if(false === is_string($name)) {
throw new \InvalidArgumentException('Expected array of strings!');
}

$this->names[] = $name;
}
}

public function __invoke(ReplaceShortcodesEvent $event)
{
if($event->getShortcode() && in_array($event->getShortcode()->getName(), $this->names)) {
$replaces = array();
foreach($event->getReplacements() as $r) {
$replaces[] = $r->getReplacement();
}

$event->setResult(implode('', $replaces));
}
}
}
16 changes: 16 additions & 0 deletions src/Events.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php
namespace Thunder\Shortcode;

/**
* @author Tomasz Kowalczyk <tomasz@kowalczyk.cc>
*/
final class Events
{
const FILTER_SHORTCODES = 'event.filter-shortcodes';
const REPLACE_SHORTCODES = 'event.replace-shortcodes';

public static function getEvents()
{
return array(static::FILTER_SHORTCODES, static::REPLACE_SHORTCODES);
}
}
Loading