Skip to content

Commit

Permalink
fixed differenced in shortcode name validation, added RawHandler, add…
Browse files Browse the repository at this point in the history
…ed relevant documentation, updated changelog
  • Loading branch information
thunderer committed Feb 5, 2016
1 parent 9135f56 commit 5265cb5
Show file tree
Hide file tree
Showing 10 changed files with 54 additions and 10 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

* v0.6.0 (XX.YY.2016)

* README was completely rewritten to take into account newest additions,
* 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,
Expand All @@ -15,7 +16,9 @@
* `FilterRawEventHandler` allows to automatically configure shortcodes that should not have their content processed,
* `ReplaceJoinEventHandler` discards the parent shortcode content and returns only concatenated replacements,
* fixed `HandlerContainer::addAlias()` bug that may have silently added aliases for default handler,
* added possibility to create `WordpressParser` with names from array or `HandlerContainer` to catch only those like WordPress does.
* added possibility to create `WordpressParser` with names from array or `HandlerContainer` to catch only those like WordPress does,
* fixed differences between parsers and standardized validating allowed characters in their names in `RegexBuilderUtility::buildNameRegex()`
* introduced several ready to use shortcode handlers described in dedicated section of README.

* v0.5.3 (26.01.2016)
* massive performance improvements in RegularParser,
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,12 +288,11 @@ assert($unserializedFromXml->getName() === $shortcode->getName());

## Handlers

To be implemented (PR #33). See the current state on `builtin-handlers` branch.

There are several builtin shortcode handlers available in `Thunder\Shortcode\Handler` namespace. Description below assumes that given handler was registered with `xyz` name:

- `NameHandler` always returns shortcode's name. `[xyz arg=val]content[/xyz]` becomes `sample`,
- `ContentHandler` always returns shortcode's content. It discards its opening and closing tag. `[xyz]code[/xyz]` becomes `code`,
- `RawHandler` returns unprocessed shortcode content. Its behavior is different than `FilterRawEventHandler` because if content auto processing is turned on, then nested shortcodes handlers were called, just their result was discarded,
- `NullHandler` completely removes shortcode with all nested shortcodes,
- `DeclareHandler` allows to dynamically create shortcode handler with name as first parameter that will also replace all placeholders in text passed as arguments. Example: `[declare xyz]Your age is %age%.[/declare]` created handler for shortcode `xyz` and when used like `[xyz age=18]` the result is `Your age is 18.`,
- `EmailHandler` replaces the email address or shortcode content as clickable `mailto:` link:
Expand Down
26 changes: 26 additions & 0 deletions src/Handler/RawHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php
namespace Thunder\Shortcode\Handler;

use Thunder\Shortcode\Shortcode\ProcessedShortcode;

/**
* @author Tomasz Kowalczyk <tomasz@kowalczyk.cc>
*/
final class RawHandler
{
public function __construct()
{
}

/**
* [raw]any content [with] or [without /] shortcodes[/raw]
*
* @param ProcessedShortcode $shortcode
*
* @return string
*/
public function __invoke(ProcessedShortcode $shortcode)
{
return $shortcode->getTextContent();
}
}
2 changes: 1 addition & 1 deletion src/Parser/RegexParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ private function parseSingle($text, $offset)
preg_match($this->singleShortcodeRegex, $text, $matches, PREG_OFFSET_CAPTURE);

$name = $matches['name'][0];
if(!preg_match('/^[a-zA-Z0-9-]+$/', $name)) {
if(!preg_match('~^'.RegexBuilderUtility::buildNameRegex().'$~us', $name)) {
return null;
}
$parameters = isset($matches['parameters'][0]) ? $this->parseParameters($matches['parameters'][0]) : array();
Expand Down
3 changes: 2 additions & 1 deletion src/Parser/RegularParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Thunder\Shortcode\Shortcode\Shortcode;
use Thunder\Shortcode\Syntax\CommonSyntax;
use Thunder\Shortcode\Syntax\SyntaxInterface;
use Thunder\Shortcode\Utility\RegexBuilderUtility;

/**
* @author Tomasz Kowalczyk <tomasz@kowalczyk.cc>
Expand Down Expand Up @@ -78,7 +79,7 @@ private function shortcode(array &$names)
if(!$this->match(self::TOKEN_OPEN, $setOffset, true)) { return false; }
if(!$this->match(self::TOKEN_STRING, $setName, false)) { return false; }
if($this->lookahead(self::TOKEN_STRING, null)) { return false; }
if(!preg_match_all('/^[a-zA-Z0-9-]+$/', $name, $matches)) { return false; }
if(!preg_match_all('~^'.RegexBuilderUtility::buildNameRegex().'$~us', $name, $matches)) { return false; }
$this->match(self::TOKEN_WS);
if(false === ($bbCode = $this->bbCode())) { return false; }
if(false === ($parameters = $this->parameters())) { return false; }
Expand Down
3 changes: 2 additions & 1 deletion src/Parser/WordpressParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use Thunder\Shortcode\HandlerContainer\HandlerContainer;
use Thunder\Shortcode\Shortcode\ParsedShortcode;
use Thunder\Shortcode\Shortcode\Shortcode;
use Thunder\Shortcode\Utility\RegexBuilderUtility;

/**
* IMPORTANT NOTE: USE THIS PARSER **ONLY** IF YOU WANT THE FULL COMPATIBILITY
Expand Down Expand Up @@ -58,7 +59,7 @@ public function parse($text)
{
$names = $this->names
? implode('|', array_map('preg_quote', $this->names))
: '[a-zA-Z0-9-]+';
: RegexBuilderUtility::buildNameRegex();
$regex = str_replace('<NAMES>', $names, static::$shortcodeRegex);
preg_match_all($regex, $text, $matches, PREG_OFFSET_CAPTURE);

Expand Down
1 change: 0 additions & 1 deletion src/Shortcode/ProcessedShortcode.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<?php
namespace Thunder\Shortcode\Shortcode;

use Thunder\Shortcode\Parser\ParserInterface;
use Thunder\Shortcode\Processor\ProcessorContext;
use Thunder\Shortcode\Processor\ProcessorInterface;

Expand Down
7 changes: 6 additions & 1 deletion src/Utility/RegexBuilderUtility.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
*/
final class RegexBuilderUtility
{
public static function buildNameRegex()
{
return '[a-zA-Z0-9-_]+';
}

public static function buildShortcodeRegex(SyntaxInterface $syntax)
{
return '~('.self::createShortcodeRegexContent($syntax).')~us';
Expand Down Expand Up @@ -58,7 +63,7 @@ private static function createShortcodeRegexContent(SyntaxInterface $syntax)
$bbCode = '(?:'.$equals.$space.'(?<bbCode>'.$complex.'|'.$simple.'))?';

// alphanumeric characters and dash
$name = '(?<name>[\w-]+)';
$name = '(?<name>'.static::buildNameRegex().')';
// non-greedy match for any characters
$content = '(?<content>.*?)';

Expand Down
9 changes: 8 additions & 1 deletion tests/ParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,14 @@ public function provideShortcodes()
new ParsedShortcode(new Shortcode('2', array(), null), '[2]', 6),
new ParsedShortcode(new Shortcode('3', array(), null), '[3]', 9),
)),
array($s, '[_][na_me][_name][name_][n_am_e][_n_]', array()),
array($s, '[_][na_me][_name][name_][n_am_e][_n_]', array(
new ParsedShortcode(new Shortcode('_', array(), null), '[_]', 0),
new ParsedShortcode(new Shortcode('na_me', array(), null), '[na_me]', 3),
new ParsedShortcode(new Shortcode('_name', array(), null), '[_name]', 10),
new ParsedShortcode(new Shortcode('name_', array(), null), '[name_]', 17),
new ParsedShortcode(new Shortcode('n_am_e', array(), null), '[n_am_e]', 24),
new ParsedShortcode(new Shortcode('_n_', array(), null), '[_n_]', 32),
)),
);

/**
Expand Down
5 changes: 4 additions & 1 deletion tests/ProcessorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Thunder\Shortcode\Handler\NameHandler;
use Thunder\Shortcode\Handler\NullHandler;
use Thunder\Shortcode\Handler\PlaceholderHandler;
use Thunder\Shortcode\Handler\RawHandler;
use Thunder\Shortcode\Handler\SerializerHandler;
use Thunder\Shortcode\Handler\UrlHandler;
use Thunder\Shortcode\Handler\WrapHandler;
Expand Down Expand Up @@ -167,7 +168,8 @@ public function testBuiltInHandlers($text, $result)
->add('bb', WrapHandler::createBold())
->add('declare', new DeclareHandler($handlers))
->add('url', new UrlHandler())
->add('email', new EmailHandler());
->add('email', new EmailHandler())
->add('raw', new RawHandler());
$processor = new Processor(new RegexParser(), $handlers);

$this->assertSame($result, $processor->process($text));
Expand All @@ -193,6 +195,7 @@ public function provideBuiltInTests()
array('[content]cnt[/content]', 'cnt'),
array('[placeholder param=val]%param%[/placeholder]', 'val'),
array('[placeholder param=val]%param%[/placeholder]', 'val'),
array('[raw][null][content]cnt[/content][name /][/raw]', '[null][content]cnt[/content][name /]'),
);
}

Expand Down

0 comments on commit 5265cb5

Please sign in to comment.