Skip to content

Commit

Permalink
Issue 1907 (#1908)
Browse files Browse the repository at this point in the history
* add test case and new regex #1907

* add tag sub value escapeing #1907

* add changelog #1907

* Update TagParser.php
  • Loading branch information
nadar authored Feb 19, 2019
1 parent 385f8fc commit c2b7aab
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 8 deletions.
2 changes: 1 addition & 1 deletion core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ All notable changes to this project will be documented in this file. This projec

### Fixed

+ [#1907](https://github.com/luyadev/luya/issues/1907) Tags can now have escaped sub values like `file[1](file.png \(PDF\))`.
+ [#1900](https://github.com/luyadev/luya/issues/1900) Fixed issue when attachment file name is not provided.
+ [#1902](https://github.com/luyadev/luya/pull/1902) Composition component hides alternate url lang codes when hideDefaultPrefixOnly is true and current lang code is default.
+ [#1898](https://github.com/luyadev/luya/issues/1898) Telephone link raises an exception if an invalid telephone number is provided.
+ [#1897](https://github.com/luyadev/luya/issues/1897) Yii_* constants where not available in config files as Yii entry script was loaded after config files.
+ [#1888](https://github.com/luyadev/luya/issues/1888) Fixed issue with range values which can have float values.
+ [#1876](https://github.com/luyadev/luya/issues/1876) Fixed the url generation without module context when using language switcher.

Expand Down
49 changes: 42 additions & 7 deletions core/TagParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class TagParser extends BaseObject
* @var string Base regular expression to determine function, values and value-sub informations.
* @see https://regex101.com/r/hP9nJ1/1 - Online Regex tester
*/
const REGEX = '/(?<function>[a-z]+)\[(?<value>.*?)\](\((?<sub>.*?)\))?/mi';
const REGEX = '/(?<function>[a-z]+)\[(?<value>.*?)\]((?<!\\\\)\((?<sub>.*?)(?<!\\\\)\))?/mi';

private $tags = [
'mail' => ['class' => 'luya\tag\tags\MailTag'],
Expand Down Expand Up @@ -100,6 +100,11 @@ public static function getInstantiatedTagObjects()
return $context->tags;
}

/**
* Get the TagParser object, create new if not exists
*
* @return static
*/
private static function getInstance()
{
if (self::$_instance === null) {
Expand All @@ -109,16 +114,27 @@ private static function getInstance()
return self::$_instance;
}

/**
* Internal method to add a tag into the tags array.
*/
private function addTag($identifier, $tagObjectConfig)
{
$this->tags[$identifier] = $tagObjectConfig;
}

/**
* Check if the given tag name exists.
*
* @return boolean
*/
private function hasTag($tag)
{
return isset($this->tags[$tag]);
}

/**
* Create the tag instance (object) for a given tag name.
*/
private function instantiatTag($tag)
{
if (!is_object($this->tags[$tag])) {
Expand All @@ -127,17 +143,36 @@ private function instantiatTag($tag)
}
}

private function evalTag($tag, $context)
/**
* Parse the given tag with context informations.
*
* @return string Returns the parsed tag value.
*/
private function parseTag($tag, $context)
{
// ensure tag is an object
$this->instantiatTag($tag);

// extract context
$value = isset($context['value']) ? $context['value'] : false;
$sub = isset($context['sub']) ? $context['sub'] : false;


// the sub value can contain escaped values, those values must be parsed back into the original state.
if ($sub) {
$sub = str_replace(['\)', '\('], [')', '('], $sub);
}
// run parse method inside the tag object.
return $this->tags[$tag]->parse($value, $sub);
}

/**
* Process a given text.
*
* + This will find all tag based expressions inside the text
* + instantiate the tag if the alias exists.
* + parse the tag and modify the input $text
*
* @param string $text The input text
* @return string The parsed text
*/
private function processText($text)
{
// verify if content is a string otherwhise just return the original provided content
Expand All @@ -152,10 +187,10 @@ private function processText($text)
if (empty($row['value'])) {
continue;
}

// extract tag name from regex
$tag = $row['function'];
if ($this->hasTag($tag)) {
$replace = $this->evalTag($tag, $row);
$replace = $this->parseTag($tag, $row);
$text = preg_replace('/'.preg_quote($row[0], '/').'/mi', $replace, $text, 1);
}
}
Expand Down
15 changes: 15 additions & 0 deletions tests/core/TagParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ public function parse($value, $sub)
}
}

class Test2Tag extends TestTag
{
public function parse($value, $sub)
{
return '<a href="'.$value.'">'.$sub.'</a>';
}
}

class TagParserTest extends LuyaWebTestCase
{
public function testInvalidContent()
Expand Down Expand Up @@ -70,4 +78,11 @@ public function testProcessText()
$this->assertSame('test[]', TagParser::convert('test[]'));
$this->assertSame('value|sub', TagParser::convert('test[value](sub)'));
}

public function testSubValueWithBrackets()
{
TagParser::inject('test', ['class' => Test2Tag::class]);

$this->assertSame('<a href="1">Example file (PDF)</a>', TagParser::convert('test[1](Example file \(PDF\))'));
}
}

0 comments on commit c2b7aab

Please sign in to comment.