0

I recenlythave tried to convert the preg_replace() line to preg_replace_callback, but with no success. I did try the methods on Stackoverflow, but they seem to be different.

Hope I could get some help with it.

function ame_process_bbcode(&$parser, &$param1, $param2 = '')
{
    if (class_exists('vB_BbCodeParser_Wysiwyg') AND is_a($parser, 'vB_BbCodeParser_Wysiwyg'))
    {
     return $text; 
    }
    else
    {
        global $vbulletin;
        ($hook = vBulletinHook::fetch_hook('automediaembed_parse_bbcode_start')) ? eval($hook) : false;
        $ameinfo = fetch_full_ameinfo();

        $text = preg_replace($ameinfo['find'], $ameinfo['replace'], ($param2 ? $param2 : $param1), 1);

        ($hook = vBulletinHook::fetch_hook('automediaembed_parse_bbcode_end')) ? eval($hook) : false;
        return $text;   
    }
}

Updates: Thanks to @Barmar, I know now that the issue is related to the fetch_full_ameinfo function.. I will add function below. Maybe it will help others in the long run. I will also include the fix whenever I am done. Thanks to @Barmar for the help.

function &fetch_full_ameinfo($findonly = false, $refresh = false)
{

    global $db, $vbulletin, $vbphrase, $stylevar;
    static $ameinfo = array();
    static $inied, $lastfind;

    if ($refresh)
    {

        $inied = false;

    }

    if ($lastfind && !$findonly)
    {

        $inied = false;
        $ameinfo = array();

    }

    if (!$inied)
    {

        if (!$refresh AND $vbulletin->options['automediaembed_cache'])
        {

            $path = $vbulletin->options['automediaembed_cache_path'];

            if (file_exists($path . "findonly.php"));
            {

                if ($findonly)
                {

                    include($path . "findonly.php");

                }
                else
                {

                    include($path . "ameinfo.php");

                }

                $inied = true;
                $lastfind = $findonly;

                return $ameinfo;
            }

        }

        if ($vbulletin->options['automediaembed_resolve'])
        {

            $embed = ",IF(extraction=1 AND embedregexp!= '', embedregexp, '') as embedregexp, IF(extraction=1 AND validation!= '', validation, '') as validation";
            $embedwhere = " AND ((extraction = 0 AND embedregexp = '') OR (extraction = 1)) ";

        }
        else
        {

            $embedwhere = " AND embedregexp = ''";

        }


        $sql = "SELECT findcode" . (!$findonly ? ", replacecode,title,container,ameid" : ",extraction$embed") . " FROM " . TABLE_PREFIX . "automediaembed WHERE status=1 $embedwhere
                        ORDER BY displayorder, title ASC";

        $results = $db->query_read_slave($sql);

        while ($result = $db->fetch_array($results))
        {

            if ($result['findcode'])
            {

                if (!$findonly)
                {

                    $ameinfo['find'][] = "~($result[findcode])~ie";
                    $ameinfo['replace'][] = 'ame_match_bbcode($param1, $param2, \'' . $result['ameid'] . '\', \'' . ame_slasher($result['title']) . '\', ' . $result['container'] . ', \'' . ame_slasher($result['replacecode']) . '\', \'\\1\', \'\\2\', \'\\3\', \'\\4\', \'\\5\', \'\\6\')';


                }
                else
                {

                    $ameinfo['find'][] = "~(\[url\]$result[findcode]\[/url\])~ie";
                    $ameinfo['find'][] = "~(\[url=\"?$result[findcode]\"?\](.*?)\[/url\])~ie";
                    $ameinfo['replace'][] = 'ame_match("\1", "", ' . intval($result['extraction']) .', "' . ($result['embedregexp'] ? "~" . ame_slasher($result['embedregexp']) . "~sim" : "") . '", "' . ($result['validation'] ? "~" . ame_slasher($result['validation']) . "~sim" : "") . '",$ameinfo)';
                    $ameinfo['replace'][] = 'ame_match("\1", "\2", ' . intval($result['extraction']) .', "' . ($result['embedregexp'] ? "~" . ame_slasher($result['embedregexp']) . "~sim" : "") . '", "' . ($result['validation'] ? "~" . ame_slasher($result['validation']) . "~sim" : "") . '", $ameinfo)';

                }

            }

        }

        $inied = true;
    }

    $lastfind = $findonly;

    return $ameinfo;
}
Miguel
  • 68
  • 6
  • Where is your code that uses `preg_replace_callback`? – Barmar Jun 30 '17 at 22:39
  • If you tried to convert it, why haven't you shown the result of your attempt, so we could tell you what you did wrong? How do you expect to learn from your mistakes? – Barmar Jun 30 '17 at 22:41
  • Huh? You can clearly see that trying to get help with it. It doesn't matter how my attempts are made, because they were all wrong. I tried 20 different methods. You dont want me to post them all? – Miguel Jun 30 '17 at 22:44
  • We want you to post something that shows what you tried, probably the one you think should be closest to correct. Otherwise we're just writing it for you, not helping you fix your error. – Barmar Jun 30 '17 at 22:45
  • 1
    Your old code doesn't show the regexp or the replacement. How are we supposed to know what the callback function should do? – Barmar Jun 30 '17 at 22:47
  • But I've reopened the question. You're using dynamic regexp and replacement, which is different from the hard-coded replacement in the linked question. – Barmar Jun 30 '17 at 22:48
  • 1
    Where does `$ameinfo` come from? Show an example of the contents. – Barmar Jun 30 '17 at 22:49
  • Barmar thank you for making that point. I keep comparing it to the Regex methods. The function itself was too long. So I tried to shorten it, in order not to confuse any. That make sense. – Miguel Jun 30 '17 at 22:51
  • The linked question shows how to do it with a hard-coded replacement string. You just need to put a similar anonymous function into `$ameinfo['replace']`. – Barmar Jun 30 '17 at 22:53
  • The change needs to be made in the code that fills in `$ameinfo['replace']`. – Barmar Jun 30 '17 at 22:58
  • Ok, I got the whole addon which is made for vBulletin. I will definitely work on it asap. Thank you for your time and efforts. – Miguel Jun 30 '17 at 23:01
  • If this is coming from a third-party library, you might check whether there's an update that deals with this. – Barmar Jun 30 '17 at 23:02
  • About the addon itself, its actually outdated on vBulletin.org and the Developer stopped releasing other updates. Its called "AME - Auto Media Embedding". Its a great addon. The issues started when I Upgraded to PHP 5.6. But now I can see what the issues is related to. Its within the " &fetch_full_ameinfo". Thanks to you, I wouldn't have figured that out by myself. so again. Thank you Barmar. – Miguel Jun 30 '17 at 23:07
  • @Barmar, I have included the &fetch_full_ameinfo above. Hopefully it could help others in the long run. Cheers. – Miguel Jun 30 '17 at 23:12
  • Ugh, this looks really tricky. The replacement uses `$param1` and `$param2`, but they're not available in the scope of `fetch_full_ameinfo()`. – Barmar Jun 30 '17 at 23:27
  • lol right. Now you know why I was lost hahah. Thank you so much for the awesome work. – Miguel Jul 06 '17 at 20:48

1 Answers1

2

You can't put the replacement function in fetch_full_ameinfo(), because it needs to refer to the $param1 and $param2 variables, which are local to this function.

This means it needs to use eval() in the current function (this is essentially what preg_replace() does internally when it processes the /e flag).

You need to change the replacement string that fetch_full_ameinfo() creates so that it uses a variable instead of \1, \2, etc. to refer to the capture groups, because the callback function receives the captured matches as an array. So replace the block beginning with if (!$findonly) with this:

if (!$findonly)
    {

        $ameinfo['find'][] = "~($result[findcode])~i";
        $ameinfo['replace'][] = 'ame_match_bbcode($param1, $param2, \'' . $result['ameid'] . '\', \'' . ame_slasher($result['title']) . '\', ' . $result['container'] . ', \'' . ame_slasher($result['replacecode']) . '\', \'$match[1]\', \'$match[2]\', \'$match[3]\', \'$match[4]\', \'$match[5]\', \'$match[6]\')';


    }
else
    {

        $ameinfo['find'][] = "~(\[url\]$result[findcode]\[/url\])~i";
        $ameinfo['find'][] = "~(\[url=\"?$result[findcode]\"?\](.*?)\[/url\])~i";
        $ameinfo['replace'][] = 'ame_match("$match[1]", "", ' . intval($result['extraction']) .', "' . ($result['embedregexp'] ? "~" . ame_slasher($result['embedregexp']) . "~sim" : "") . '", "' . ($result['validation'] ? "~" . ame_slasher($result['validation']) . "~sim" : "") . '",$ameinfo)';
        $ameinfo['replace'][] = 'ame_match("$match[1]", "$match[2]", ' . intval($result['extraction']) .', "' . ($result['embedregexp'] ? "~" . ame_slasher($result['embedregexp']) . "~sim" : "") . '", "' . ($result['validation'] ? "~" . ame_slasher($result['validation']) . "~sim" : "") . '", $ameinfo)';

    }

Then change your code to:

    $text = preg_replace_callback($ameinfo['find'], function($match) use (&$param1, &$param2, &$ameinfo) {
        return eval($ameinfo['replace']);
    }, ($param2 ? $param2 : $param1), 1);
Barmar
  • 741,623
  • 53
  • 500
  • 612