diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index 873f9c311..c9c5b9b16 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -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. diff --git a/core/TagParser.php b/core/TagParser.php index 4ace2d501..6592cbf7d 100644 --- a/core/TagParser.php +++ b/core/TagParser.php @@ -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 = '/(?[a-z]+)\[(?.*?)\](\((?.*?)\))?/mi'; + const REGEX = '/(?[a-z]+)\[(?.*?)\]((?.*?)(? ['class' => 'luya\tag\tags\MailTag'], @@ -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) { @@ -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])) { @@ -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 @@ -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); } } diff --git a/tests/core/TagParserTest.php b/tests/core/TagParserTest.php index 4b02c5dc6..666c7bc3d 100644 --- a/tests/core/TagParserTest.php +++ b/tests/core/TagParserTest.php @@ -34,6 +34,14 @@ public function parse($value, $sub) } } +class Test2Tag extends TestTag +{ + public function parse($value, $sub) + { + return ''.$sub.''; + } +} + class TagParserTest extends LuyaWebTestCase { public function testInvalidContent() @@ -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('Example file (PDF)', TagParser::convert('test[1](Example file \(PDF\))')); + } }