Add new Strings::performWithEscapedBlocks methods
- Add new BBCode::performWithEscapedTags method - Add tests
This commit is contained in:
parent
6665eb76f9
commit
348b71d0b0
|
@ -2163,4 +2163,22 @@ class BBCode
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform a custom function on a text after having escaped blocks enclosed in the provided tag list.
|
||||||
|
*
|
||||||
|
* @param string $text
|
||||||
|
* @param array $tagList A list of tag names, e.g ['noparse', 'nobb', 'pre']
|
||||||
|
* @param callable $callback
|
||||||
|
* @return string
|
||||||
|
* @throws Exception
|
||||||
|
*@see Strings::performWithEscapedBlocks
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static function performWithEscapedTags(string $text, array $tagList, callable $callback)
|
||||||
|
{
|
||||||
|
$tagList = array_map('preg_quote', $tagList);
|
||||||
|
|
||||||
|
return Strings::performWithEscapedBlocks($text, '#\[(?:' . implode('|', $tagList) . ').*?\[/(?:' . implode('|', $tagList) . ')]#ism', $callback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -472,4 +472,52 @@ class Strings
|
||||||
|
|
||||||
return mb_substr($string, 0, $start) . $replacement . mb_substr($string, $start + $length, $string_length - $start - $length);
|
return mb_substr($string, 0, $start) . $replacement . mb_substr($string, $start + $length, $string_length - $start - $length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform a custom function on a text after having escaped blocks matched by the provided regular expressions.
|
||||||
|
* Only full matches are used, capturing group are ignored.
|
||||||
|
*
|
||||||
|
* To change the provided text, the callback function needs to return it and this function will return the modified
|
||||||
|
* version as well after having restored the escaped blocks.
|
||||||
|
*
|
||||||
|
* @param string $text
|
||||||
|
* @param string $regex
|
||||||
|
* @param callable $callback
|
||||||
|
* @return string
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public static function performWithEscapedBlocks(string $text, string $regex, callable $callback)
|
||||||
|
{
|
||||||
|
// Enables nested use
|
||||||
|
$executionId = random_int(PHP_INT_MAX / 10, PHP_INT_MAX);
|
||||||
|
|
||||||
|
$blocks = [];
|
||||||
|
|
||||||
|
$text = preg_replace_callback($regex,
|
||||||
|
function ($matches) use ($executionId, &$blocks) {
|
||||||
|
$return = '«block-' . $executionId . '-' . count($blocks) . '»';
|
||||||
|
|
||||||
|
$blocks[] = $matches[0];
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
},
|
||||||
|
$text
|
||||||
|
);
|
||||||
|
|
||||||
|
$text = $callback($text) ?? '';
|
||||||
|
|
||||||
|
// Restore code blocks
|
||||||
|
$text = preg_replace_callback('/«block-' . $executionId . '-([0-9]+)»/iU',
|
||||||
|
function ($matches) use ($blocks) {
|
||||||
|
$return = $matches[0];
|
||||||
|
if (isset($blocks[intval($matches[1])])) {
|
||||||
|
$return = $blocks[$matches[1]];
|
||||||
|
}
|
||||||
|
return $return;
|
||||||
|
},
|
||||||
|
$text
|
||||||
|
);
|
||||||
|
|
||||||
|
return $text;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,4 +194,30 @@ class StringsTest extends TestCase
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testPerformWithEscapedBlocks()
|
||||||
|
{
|
||||||
|
$originalText = '[noparse][/noparse][nobb]nobb[/nobb][noparse]noparse[/noparse]';
|
||||||
|
|
||||||
|
$text = Strings::performWithEscapedBlocks($originalText, '#[(?:noparse|nobb)].*?\[/(?:noparse|nobb)]#is', function ($text) {
|
||||||
|
return $text;
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->assertEquals($originalText, $text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPerformWithEscapedBlocksNested()
|
||||||
|
{
|
||||||
|
$originalText = '[noparse][/noparse][nobb]nobb[/nobb][noparse]noparse[/noparse]';
|
||||||
|
|
||||||
|
$text = Strings::performWithEscapedBlocks($originalText, '#[nobb].*?\[/nobb]#is', function ($text) {
|
||||||
|
$text = Strings::performWithEscapedBlocks($text, '#[noparse].*?\[/noparse]#is', function ($text) {
|
||||||
|
return $text;
|
||||||
|
});
|
||||||
|
|
||||||
|
return $text;
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->assertEquals($originalText, $text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue