Skip to content

Instantly share code, notes, and snippets.

@JoshyPHP
Created January 22, 2017 13:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoshyPHP/6d9c2f6b1102bcc22c72fad854dcc542 to your computer and use it in GitHub Desktop.
Save JoshyPHP/6d9c2f6b1102bcc22c72fad854dcc542 to your computer and use it in GitHub Desktop.
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