View Full Version : Using str_replace in MEMBERINFO
Digital Jedi
12-23-2010, 04:56 AM
I've been searching for a few days, and I can't find anything to suggest why str_replace isn't working in MEMBERINFO for me. I've tried using both a custom template and simply putting the replacement code in a variable. I can' tell if I'm using the wrong hook, using outdated code or what.
For example, using a custome template
$find= '<li class=\"thead\"><a href=\"moderator.php?$session[sessionurl]do=useroptions&u=$userinfo[userid]\">$vbphrase[edit_user_profile]</a></li>';
$vbulletin->templatecache['MEMBERINFO'] = str_replace($find, fetch_template(djs_delete_link) . $find, $vbulletin->templatecache['MEMBERINFO']);
I'm looking at some other plugins, but none of them look right around the Edit Profile link, which is where I'm looking. Does it have to do with the if condition the block of code sits in? I recall reading that str_replace doesn't play nice with if conditionals, but I thought that was if you were searching for them, not searching for a string inside of one. This seems like it should be working.
Boofo
12-23-2010, 05:20 AM
You don't escape double quotes when they are used between single quotes. Only single quotes get escaped between single quotes. That is why it is not working for you.
And this I have never seen before:
fetch_template(djs_delete_link)
Digital Jedi
12-23-2010, 05:37 AM
You don't escape double quotes when they are used between single quotes. Only single quotes get escaped between single quotes. That is why it is not working for you.
I tried with and without. There's an article here on vB.org that stresses that you have to escape double quotes because that's the way the code is stored in memory:
$find = '<table class=\"tborder\" cellpadding=\"$stylevar[cellpadding]\" cellspacing=\"$stylevar[cellspacing]\" border=\"0\" width=\"100%\" align=\"center\" id=\"woltable\">';This is what we are going to look for, we've stored it in a variable called $find to make it easier to handle. Did you notice something? We've changed things slightly. Every time we have a double quote we need to "escape (http://en.wikipedia.org/wiki/Escape_character)" it. We do this by adding a backslash character to tell PHP that we really do want a double quote stored in the variable, rather than having PHP think that we are ending or beginning a string using the double quote character. We've also enclosed our string in single quotes. Now you might be saying that at this point "But single quotes mean I don't have to escape double quotes". This is true, but not in this case. If we actually looked inside the template, as it is stored in memory, we'd find those backslash characters. If we want our search to match, we have to put them in. We could have also used the addslashes() (http://www.php.net/addslashes) function to do this, but we are keeping this example simple, so we put them in by hand. Remember what you see when editing the template via the style manager is not always the same as what is actually stored in memory!
Nevertheless, I'm always game, especially since the article is a few years old and I tried the code you sent me. In fact, I tried this same method (with and without quotes) before I tried using a template.
$find = '<li class="thead"><a href="moderator.php?$session[sessionurl]do=useroptions&u=$userinfo[userid]">$vbphrase[edit_user_profile]</a></li>';
$add_before = '<li class="thead"><a href="admincp/user.php?do=remove&u=$userinfo[userid]" style="color:red; font-face:bold">Delete User Profile</a></li>';
$vbulletin->templatecache['MEMBERINFO'] = str_replace($find, $add_before . $find, $vbulletin->templatecache['MEMBERINFO']);
I keep picking different hooks, but nothing seems to work, and it seems like it should.
And this I have never seen before:fetch_template(djs_delete_link)
Is there a more current way to fetch a template? That article is from 2007, but I've not been able to find anything more current. At least not for vB3.
Boofo
12-23-2010, 05:53 AM
I meant you can't fetch a template in the middle of a str_replace, AFAIK. Also, this is one of the lines I have in one of my mods for a str_replace:
$find2 = '<input type="checkbox" name="cookieuser" id="cb_cookieuser" value="1" tabindex="1" />';
I don't escape the double quotes and it works fine.
Digital Jedi
12-23-2010, 06:32 AM
I meant you can't fetch a template in the middle of a str_replace, AFAIK. Also, this is one of the lines I have in one of my mods for a str_replace:
$find2 = '<input type="checkbox" name="cookieuser" id="cb_cookieuser" value="1" tabindex="1" />';
I don't escape the double quotes and it works fine.
Ah, I see what you mean. For the life of me, I can't find the article where I learned to do that. I know I can't be that crazy. But I could be crazy and a little sleepy.
Boofo
12-23-2010, 09:25 AM
I believe you. You're not crazy. ;)
I read the first post and also thought for sure it was the backslashes. Anyway, to see what was going on I put this code in a plugin using member_complete:
$fp = fopen('some path/out.txt', 'w');
fwrite($fp, $vbulletin->templatecache['MEMBERINFO']);
fclose($fp);
then I searched the output file for your string and found this:
.(($show['edit_profile']) ? ("
<li class=\"thead\"><a href=\"moderator.php?" . $GLOBALS['vbulletin']->session->vars['sessionurl'] . "do=useroptions&u=$userinfo[userid]\">$vbphrase[edit_user_profile]</a></li>
") : (""))."
So I guess that explains it. And I notice that the $userinfo and $vbphrase variables didn't get treated like that, so it seems it's only certain special variables that you can't match in a str_replace like that.
It also looks like you should need the backslashes, but then I can't explain why Boofo's example works, so :confused:.
Anyway, I guess you could probably make the $find be only the part before $session (or match something before that line instead if that doesn't narrow it down). Maybe you could put an html comment in the right place just to have something to match.
ETA: ...or maybe you could just copy the line as it appears above and use that.
Boofo
12-23-2010, 12:11 PM
Then he would also have to do the replace line parsed. The only way to know what that is is to manually add the code to the template first and then go to the db and look at the template code for that after it is parsed and use that for the replacement. I used to do it that way at one time.
The escaped backslashes are there after it is the db, not before. Look at the Delete User Link in Profile mod I just did and see how I had to do it for vb 4. vb 3 was a lot easier to str_replace.
Digital Jedi
12-23-2010, 05:08 PM
That would explain a lot. Just tried adding it to the template and it looks like this:
".(($show['edit_profile']) ? ("
<li class=\"thead\"><a href=\"moderator.php?" . $GLOBALS['vbulletin']->session->vars['sessionurl'] . "do=useroptions&u=$userinfo[userid]\">$vbphrase[edit_user_profile]</a></li>
<li class=\"thead\"><a href=\"admincp/user.php?do=remove&u=$userinfo[userid]\" style=\"color:red; font-face:bold\">Delete User Profile</a></li>
") : (""))."
I'm not familiar with finding matches with variables in them. What's the syntax for that, as I get a parse error if I try it as is?
BirdOPrey5
12-23-2010, 10:27 PM
The 1 character causing the whole thing not to match is the ? after "moderator.php" - everything before it and everything after it (with kh99's code) matches.. and all the double quotes must be escaped as well, I tried it and it didn't work without escaping them, though I agree with Boofo it's not logical this needs to be done.
But anyway the code I have the replacement working on is on hook member_start.
This code works fine:
$find= '<li class=\"thead\"><a href=\"moderator.php';
$find3 = "xxx.php";
$vbulletin->templatecache['MEMBERINFO'] = str_replace($find, $find3, $vbulletin->templatecache['MEMBERINFO']);
As does this:
$find= $GLOBALS['vbulletin']->session->vars['sessionurl'] . 'do=useroptions&u=$userinfo[userid]\">$vbphrase[edit_user_profile]</a></li>';
$find3 = "xxx.php";
$vbulletin->templatecache['MEMBERINFO'] = str_replace($find, $find3, $vbulletin->templatecache['MEMBERINFO']);
It's only the ? screwing everything up... I tried escaping it just for the hell of it- no help.
Boofo
12-23-2010, 10:58 PM
Here is an example I found from something I did for vb 3 a while back:
$find_fh = 'accesskey=\"c\" />$vbphrase[remember_me]</label>';
$replace_fh = 'accesskey=\"c\" checked=\"checked\" /> $vbphrase[remember_me]</label>';
$vbulletin->templatecache['navbar'] = str_replace($find_fh, $replace_fh, $vbulletin->templatecache['navbar']);
And another one:
$find = '<strong>" . construct_phrase("$vbphrase[welcome_x_link_y]", "" . $GLOBALS[\'vbulletin\']->userinfo[\'username\'] . "", "member.php?" . $GLOBALS[\'vbulletin\']->session->vars[\'sessionurl\'] . "u=" . $GLOBALS[\'vbulletin\']->userinfo[\'userid\'] . "") . "</strong><br />';
$replace = '<strong>" . construct_phrase("$vbphrase[ung_greeting]", "$vbphrase[ung_line]", "member.php?" . $GLOBALS[\'vbulletin\']->session->vars[\'sessionurl\'] . "u=" . $GLOBALS[\'vbulletin\']->userinfo[\'userid\'] . "", "$vbphrase[realname]", "$vbphrase[ung_punctuation]") . "</strong><br />';
$vbulletin->templatecache['navbar'] = str_replace($find, $replace, $vbulletin->templatecache['navbar']);
Since I don't have vb 3 anymore, I can't look in the db and help you guys figure it out, sorry.
BirdOPrey5
12-23-2010, 11:44 PM
From the database itself the exact code is:
".(($show['edit_profile']) ? ("
<li class=\"thead\"><a href=\"moderator.php?" . $GLOBALS['vbulletin']->session->vars['sessionurl'] . "do=useroptions&u=$userinfo[userid]\">$vbphrase[edit_user_profile]</a></li>
") : (""))."
--------------- Added 1293155414 at 1293155414 ---------------
Maybe this is a bug in the template code... if you look at the double quote following the ? it's not escaped, but every other double quote in that situation is...
<a href=\"moderator.php?"
Boofo
12-24-2010, 12:00 AM
Try this:
$find = '".(($show[\'edit_profile\']) ? ("
<li class=\"thead\"><a href=\"moderator.php?" . $GLOBALS[\'vbulletin\']->session->vars[\'sessionurl\'] . "do=useroptions&u=$userinfo[userid]\">$vbphrase[edit_user_profile]</a></li>
") : (""))."';
BirdOPrey5
12-24-2010, 12:57 AM
I got this working, kind of... saw we didn't need anything after the ? anyway so this code will add "xxxx" to the link...
$find= '<li class=\"thead\"><a href=\"moderator.php';
$vbulletin->templatecache['MEMBERINFO'] = str_replace($find, "xxxx" . $find, $vbulletin->templatecache['MEMBERINFO']);
You should have no problem calling your template function.
Boofo
12-24-2010, 02:58 AM
Did you try the code I gave you above a a test?
Digital Jedi
12-24-2010, 03:47 AM
I got this working, kind of... saw we didn't need anything after the ? anyway so this code will add "xxxx" to the link...
$find= '<li class=\"thead\"><a href=\"moderator.php';
$vbulletin->templatecache['MEMBERINFO'] = str_replace($find, "xxxx" . $find, $vbulletin->templatecache['MEMBERINFO']);
You should have no problem calling your template function.
Ah, indeed that worked. For a minute there I was forgetting to change the hook to member_start.
$find= '$vbphrase[edit_user_profile]</a></li>';
$vbulletin->templatecache['MEMBERINFO'] = str_replace($find, $find . fetch_template(djs_delete_link), $vbulletin->templatecache['MEMBERINFO']);
Template inserted fine. Er, when I remembered to put in the correct template code.
So, that's how many names I've got to put into the Contributors field? :p
--------------- Added 1293169854 at 1293169854 ---------------
Did you try the code I gave you above a a test?
I did try that, too, with no luck. But I also read that line breaks can cause a problem. Also, when I did the manual template edit, the ") : (""))." wrapped my line of code, I presume because it was included in the show edit profile <if> condition.
BirdOPrey5
12-24-2010, 04:16 AM
I need no such official recognition... but I would really like an answer why a question mark killed str_replace in that instance... I tried 20 things probably and nothing was working. :mad:
I need no such official recognition...
Ditto here - I don't expect anyone to give me credit on any mod just for helping with a question.
vBulletin® v3.8.12 by vBS, Copyright ©2000-2025, vBulletin Solutions Inc.