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

Issue 1907 #1908

Merged
merged 4 commits into from
Feb 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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\))'));
}
}