3

I used to have this block of code to simulate some sort of BBCode:

$pattern = array(
    '/\\n/',
    '/\\r/',
    '/\[list\](.*?)\[\/list\]/ise',
    '/\[b\](.*?)\[\/b\]/is',
    '/\[strong\](.*?)\[\/strong\]/is',
    '/\[i\](.*?)\[\/i\]/is',
    '/\[u\](.*?)\[\/u\]/is',
    '/\[s\](.*?)\[\/s\]/is',
    '/\[del\](.*?)\[\/del\]/is',
    '/\[url=(.*?)\](.*?)\[\/url\]/ise',
    '/\[email=(.*?)\](.*?)\[\/email\]/is',
    '/\[img](.*?)\[\/img\]/ise',
    '/\[color=(.*?)\](.*?)\[\/color\]/is',
    '/\[font=(.*?)\](.*?)\[\/font\]/ise',
    '/\[bg=(.*?)\](.*?)\[\/bg\]/ise',
    '/\[size=(.*?)\](.*?)\[\/size\]/ise'
);

$replace = array(
    '<br/>',
    '',
    '$this->sList(\'\\1\')',
    '<b>\1</b>',
    '<strong>\1</strong>',
    '<i>\1</i>',
    '<span style="text-decoration: underline;">\1</span>',
    '<span style="text-decoration: line-through;">\1</span>',
    '<span style="text-decoration: line-through;">\1</span>',
    '$this->urlfix(\'\\1\',\'\\2\')',
    '<a href="mailto:\1" title="\1">\2</a>',
    '$this->imagefix(\'\\1\')',
    '<span style="color: \1;">\2</span>',
    '$this->fontfix(\'\\1\',\'\\2\')',
    '$this->bgfix(\'\\1\',\'\\2\')',
    '$this->sizefix(\'\\1\',\'\\2\')'
);

return preg_replace($pattern, $replace, nl2br(stripslashes($string)));

But I'm moving to PHP 5.5 and I'm getting errors here, it used to work perfectly, this is the erros I'm getting:

Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in

I tried several stuff but nothing worked so far.

This is the code I tried so far:

return preg_replace_callback(
    $pattern,
    function($matches) use ($replace) {
        return ((isset($replace[$matches[0]])) ? $replace[$matches[0]] : '');
    },
    nl2br(stripslashes($string))
);

I have been reading around but most examples are related to basic replacements, here I have two arrays.

Please notice that there are some methods that are being called from the $replace area.

How can I solve this? Is this the right approach?

Lucas
  • 383
  • 1
  • 5
  • 17
  • go to http://stackoverflow.com/questions/21334934/deprecated-preg-replace-the-e-modifier-is-deprecated-use-preg-replace-call link – Domain Jan 30 '16 at 14:18
  • I'm having a little trouble understanding what it is that you are trying to do. Is is that you are trying to pass two arrays in the `use` part? – Quixrick Jan 30 '16 at 15:14
  • No, it is just one array. I'm just expecting the same result as before. – Lucas Jan 30 '16 at 16:11
  • @Lucas please give this library a try, it'll solve all your BBCode related problems: https://github.com/thunderer/Shortcode . I'm an author, so if you have any problems, let me know and I'll help. – Tomasz Kowalczyk Feb 03 '16 at 19:43

1 Answers1

0

After a lot of work and testings and reading I came out with a solution for this, I hope it can help someone else.

Here is my solution to replace bbcode:

$bbcodes    = [
    '/\\n/' => '$this->setLineJump()',
    '/\\r/' => '$this->setReturn()',
    '/\[list\](.*?)\[\/list\]/is' => '$this->setList(\'\\1\')',
    '/\[b\](.*?)\[\/b\]/is' => '$this->setBold(\'\\1\')',
    '/\[strong\](.*?)\[\/strong\]/is' => '$this->setBold(\'\\1\')',
    '/\[i\](.*?)\[\/i\]/is' => '$this->setItalic(\'\\1\')',
    '/\[u\](.*?)\[\/u\]/is' => '$this->setUnderline(\'\\1\')',
    '/\[s\](.*?)\[\/s\]/is' => '$this->setStrike(\'\\1\')',
    '/\[del\](.*?)\[\/del\]/is' => '$this->setStrike(\'\\1\')',
    '/\[url=(.*?)\](.*?)\[\/url\]/is' => '$this->setUrl(\'\\1\',\'\\2\')',
    '/\[email=(.*?)\](.*?)\[\/email\]/is' => '$this->setEmail(\'\\1\',\'\\2\')',
    '/\[img](.*?)\[\/img\]/is' => '$this->setImage(\'\\1\')',
    '/\[color=(.*?)\](.*?)\[\/color\]/is' => '$this->setFontColor(\'\\1\',\'\\2\')',
    '/\[font=(.*?)\](.*?)\[\/font\]/is' => '$this->setFontFamiliy(\'\\1\',\'\\2\')',
    '/\[bg=(.*?)\](.*?)\[\/bg\]/is' => '$this->setBackgroundColor(\'\\1\',\'\\2\')',
    '/\[size=(.*?)\](.*?)\[\/size\]/is' => '$this->setFontSize(\'\\1\',\'\\2\')'
];

$string = stripslashes($string);

foreach ($bbcodes as $bbcode => $html) {
    $string = preg_replace_callback(
        $bbcode,
        function($matches) use($html) {
            return $this->getBbCode($matches, $html);
        },
        $string
    );
}

private function getBbCode($matches, $replace)
{
    if (isset($matches[1])) {

        $replacements   = [
            '\1' => isset($matches[1]) ? $matches[1] : '',
            '\2' => isset($matches[2]) ? $matches[2] : ''
        ];

        return eval('return ' . strtr($replace, $replacements) . ';');   
    } else {

        return eval('return ' . $replace . ';');   
    }
}

As you can see I'm using objects but you can replace them by your own functions. What really matters here is that you can replace element by element, just making some changes in your arrays.

Lucas
  • 383
  • 1
  • 5
  • 17