Skip to content

Instantly share code, notes, and snippets.

@JoshyPHP JoshyPHP/14357.diff Secret
Created Jan 22, 2017

Embed
What would you like to do?
WIP
diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php
index 5cbf2712f..14bca2ec1 100644
--- a/phpBB/phpbb/textformatter/s9e/factory.php
+++ b/phpBB/phpbb/textformatter/s9e/factory.php
@@ -14,6 +14,7 @@
namespace phpbb\textformatter\s9e;
use s9e\TextFormatter\Configurator;
+use s9e\TextFormatter\Configurator\Helpers\TemplateHelper;
use s9e\TextFormatter\Configurator\Items\AttributeFilters\RegexpFilter;
use s9e\TextFormatter\Configurator\Items\UnsafeTemplate;
@@ -282,21 +283,11 @@ class factory implements \phpbb\textformatter\cache_interface
}
// Load custom BBCodes
- foreach ($this->data_access->get_bbcodes() as $row)
+ foreach ($this->get_custom_bbcodes() as $definition => $template)
{
- // Insert the board's URL before {LOCAL_URL} tokens
- $tpl = preg_replace_callback(
- '#\\{LOCAL_URL\\d*\\}#',
- function ($m)
- {
- return generate_board_url() . '/' . $m[0];
- },
- $row['bbcode_tpl']
- );
-
try
{
- $configurator->BBCodes->addCustom($row['bbcode_match'], new UnsafeTemplate($tpl));
+ $configurator->BBCodes->addCustom($definition, new UnsafeTemplate($template));
}
catch (\Exception $e)
{
@@ -442,6 +433,87 @@ class factory implements \phpbb\textformatter\cache_interface
}
/**
+ * Return the custom BBCodes configuration
+ *
+ * @return array Associative array of [definition => template]
+ */
+ protected function get_custom_bbcodes()
+ {
+ $definitions = array();
+ foreach ($this->data_access->get_bbcodes() as $row)
+ {
+ // Insert the board's URL before {LOCAL_URL} tokens
+ $template = preg_replace_callback(
+ '#\\{LOCAL_URL\\d*\\}#',
+ function ($m)
+ {
+ return generate_board_url() . '/' . $m[0];
+ },
+ $row['bbcode_tpl']
+ );
+
+ // Capture the BBCode name followed by an optional equal sign
+ preg_match('((\\w+)(=?))', strtolower($row['bbcode_match']), $m);
+ $definitions[$m[1]][$m[2]] = array($row['bbcode_match'], $template);
+ }
+
+ $bbcodes = array();
+ foreach ($definitions as $bbcode_name => $variants)
+ {
+ if (count($variants) === 1)
+ {
+ list($definition, $template) = end($variants);
+ }
+ else
+ {
+ // Use the definition from the variant that uses a param and replace {TOKEN} with
+ // {TOKEN;optional;useContent} because that's how duplicate definitions usually work
+ $definition = preg_replace(
+ '(=\\{\\w+)',
+ '$0;optional;useContent',
+ $variants['='][0]
+ );
+ $template = $this->generate_variant_template($bbcode_name, $variants['='][1], $variants[''][1]);
+ }
+ $bbcodes[$definition] = $template;
+ }
+
+ return $bbcodes;
+ }
+
+ /**
+ * Generate a template that accomodates both definitions of a custom BBCode
+ *
+ * phpBB 3.1 allows up to two definitions for the same BBCode if one of them has a default
+ * parameter and the other one does not, presumably to work around the lack of conditionals in
+ * templates. This method generates an XSL template that coalesce both templates and use an
+ * xsl:choose element to switch between the two.
+ *
+ * @param string $bbcode_name BBCode's name
+ * @param string $with_param Template used if the BBCode has a default parameter
+ * @param string $without_param Template used if the BBCode does not have a default parameter
+ * @return string XSL template
+ */
+ protected function generate_variant_template($bbcode_name, $with_param, $without_param)
+ {
+ // We need to normalize both templates to XSL because we cannot use HTML templates inside of
+ // an XSL template
+ $with_param = TemplateHelper::saveTemplate(TemplateHelper::loadTemplate($with_param));
+ $without_param = TemplateHelper::saveTemplate(TemplateHelper::loadTemplate($without_param));
+
+ $template = '<xsl:choose>'
+ . '<xsl:when test="@' . strtolower($bbcode_name) . '">'
+ . $with_param
+ . '</xsl:when>'
+ . '<xsl:otherwise>'
+ . $without_param
+ . '</xsl:otherwise>'
+ . '</xsl:choose>';
+
+ return $template;
+ }
+
+ /**
* Return the default BBCodes configuration
*
* @return array 2D array. Each element has a 'usage' key, a 'template' key, and an optional 'options' key
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.