XF 2.2 Allowing BBCode/complex text inside BBCodes made with PHP callback

Eternity7

Member
I have the following PHP that works as intended with one line text but BBCodes and newlines inside it is parsed as HTML.

PHP:
<?php
 
    namespace custom_addons;

    class box {

        public static function box($tagChildren, $tagOption, $tag, array $options, \XF\BbCode\Renderer\AbstractRenderer $renderer)
        {
            $res = $renderer->renderSubTree($tagChildren, $options);
            $toptions = trim(strip_tags($tag['option']));
            $toptions = preg_split("|\||", $toptions, -1, PREG_SPLIT_NO_EMPTY);

            @list($style, $bd, $brad1, $brad2) = $toptions;
            if ($tmp = trim($style)) {
                $style = "$tmp";
            }
            if ($tmp = trim($bd)) {
                $bd = "$tmp";
            }
            if ($tmp = trim($brad1)) {
                $brad1 = "$tmp";
            }
            if ($tmp = trim($brad2)) {
                $brad2 = "$tmp";
            }
            
            $templater = $renderer->getTemplater();
            $customTemplate = $templater->renderTemplate('public:custom_addons_box', [
                'style' => $style,
                'bd' => $bd,
                'brad1' => $brad1,
                'brad2' => $brad2,
                'res' => $res,
            ], true);

            return $customTemplate;
        }

    }
?>

Code:
<div style="background:{$style}; border: {$bd}px solid ; border-radius: {$brad1}px {$brad2}px;">{$res}</div>

Input:
1616945955488.webp

Result:
1616945988162.webp
I'd appreciate your help for this. Thank you.
 
Use {$res|raw} in your template to render html content inside the string, otherwise XF will escape it. The BB Code renderer will already have escaped any html the user tried to insert at this point, so it'll still be escaped.
 
You're a godsend, it worked.

Although when I tried it with a custom table and it did not, {$res} is throw above of the actual template.

PHP:
<?php
 
    namespace custom_addons;

    class table2 {

        public static function table2($tagChildren, $tagOption, $tag, array $options, \XF\BbCode\Renderer\AbstractRenderer $renderer)
        {
            $res = $renderer->renderSubTree($tagChildren, $options);
            $toptions = trim(strip_tags($tag['option']));
            $toptions = preg_split("|\||", $toptions, -1, PREG_SPLIT_NO_EMPTY);

            @list($class, $id, $frame) = $toptions;
            if ($tmp = trim($class)) {
                $class = "$tmp";
            }
            if ($tmp = trim($id)) {
                $id = "$tmp";
            }
            if ($tmp = trim($frame)) {
                $frame = "$tmp";
            }
            
            $templater = $renderer->getTemplater();
            $customTemplate = $templater->renderTemplate('public:custom_addons_table2', [
                'class' => $class,
                'id' => $id,
                'frame' => $frame,
                'res' => $res,
            ], true);

            return $customTemplate;
        }

    }
?>

Code:
<div class="bbTable">
    <table class="{$class}" id="{$id}" frame="{$frame}">
        <tbody>
            <tr>
                <td>1</td>
                <td>2</td>
            </tr>
            <tr>
                <td>3</td>
                <td>4</td>
            </tr>
            {$res|raw}
        </tbody>
    </table>
</div>

1617397296351.webp

1617397311296.webp

1617397360887.webp
 
That's normal browser behavior. Anything that doesn't belong into the table syntax will be pushed to the top or bottom. If you inspect the page source you'll see it is located correctly. You'll have to parse the TR and TD elements in your code to HTML first
 
That's normal browser behavior. Anything that doesn't belong into the table syntax will be pushed to the top or bottom. If you inspect the page source you'll see it is located correctly. You'll have to parse the TR and TD elements in your code to HTML first

Sorry I don't know how to parse the TR and TD elements in my code to HTML first, do you mind pointing it out?
 
You can reference the built-in table BB code in \XF\BbCode\Renderer\Html Line 1478-1515

Unfortunately I don't understand the code.

PHP:
public function renderTagTable(array $children, $option, array $tag, array $options)
    {
        $rows = [];
        $columnCounts = [];
        $lostAndFound = [];
        foreach ($children as $child)
        {
            if (is_array($child))
            {
                if ($child['tag'] === 'tr')
                {
                    $rows[] = $this->renderTableRow($child, $options, $columnCount, $lostAndFound);
                    $columnCounts[] = $columnCount;
                }
                else
                {
                    $lostAndFound[] = $this->renderSubTree([$child], $options);
                }
            }
            else if (trim($child) !== '')
            {
                $lostAndFound[] = $this->renderSubTree([$child], $options);
            }
        }

        $maxColumnCount = max($columnCounts ?: [0]);
        foreach ($columnCounts as $i => $columnCount)
        {
            if ($columnCount < $maxColumnCount)
            {
                $td = strpos($rows[$i], '<th') !== false ? 'th' : 'td';
                $filler = str_repeat("<$td></$td>", $maxColumnCount - $columnCount);
                $rows[$i] = preg_replace('#</tr>$#', "$filler\0", $rows[$i]);
            }
        }

        return $this->renderFinalTableHtml(implode('', $rows), $option, implode("\n", $lostAndFound));
    }

Ultimately, what I'm trying to go for is a BBCode of this sort:

Rich (BB code):
[table2]
|-
|row 1 col 1
|row 1 col 2
|row 1 col 3
|-
|row 2 col 1
|row 2 col 2
|row 2 col 3
[/table2]

Rich (BB code):
[table2=!attribute !style]
|-!attribute !style]
|row 1 col 1
|row 1 col 2
|row 1 col 3
|-
|row 2 col 1
|!attribute !style]row 2 col 2
|row 2 col 3
[/table2]

where it only accepts a few specific attributes like rules, frame, colspan, rowspan, etc - for example:

Rich (BB code):
[table2=!rules=rows align=center !background: purple;]
|-
|row 1 col 1
|row 1 col 2
|row 1 col 3
|-
|row 2 col 1
|!colspan=2 ! color:green; font-size: 13px;]row 2 col 2 & col 3
[/table2]

Is it possible?
 
Top Bottom