Simple Machines Community Forum

Customizing SMF => Tips and Tricks => Topic started by: nend on November 28, 2011, 07:43:29 PM

Title: [TIP/TRICK] Get Facebook and others to load a shared url.
Post by: nend on November 28, 2011, 07:43:29 PM
Well this is a tip or should I say a hack that allows Facebook and some others to load information from pages that have been shared on a SMF Forum. It also makes the link load from the social site, lol.

The main reason Facebook and SMF collide is because SMF uses ";" to separate items in the query string and well Facebook does not support semicolons in urls, sorry to say. Any url with a semicolon separator will get everything after that semicolon put in the first variable in the query string. Plus everything after that like ; and = will get converted.

The trick here is to convert them back before SMF loads. Before anyone says anything, yeah I know I could of did a http redirect but Facebook will not follow it anyways, so no use there. :(

Will here it is, put this in the beginning of your index.php

if(strstr($_SERVER["REQUEST_URI"], '%3D')) {
$fix_uri = explode('?' , $_SERVER["REQUEST_URI"]);
$_SERVER["REQUEST_URI"] = $fix_uri[0].'?'; //Might as well rebuild the URI, who knows something might need it.
$fix_uri = str_replace(';', '%3B', $fix_uri[1]);
$fix_uri = explode('%3B', $fix_uri, substr_count($fix_uri, '%3B')+1);
foreach($fix_uri as $value) {
if(strstr($value, '=')) {
$key = explode('=', $value);
$_REQUEST[$key[0]] = $_GET[$key[0]] = $_POST[$key[0]] = $key[1];
$_SERVER["REQUEST_URI"].= $key[0].'='.$key[1].';';
} else if(strstr($value, '%3D')) {
$key = explode('%3D', $value);
$_REQUEST[$key[0]] = $_GET[$key[0]] = $_POST[$key[0]] = $key[1];
$_SERVER["REQUEST_URI"].= $key[0].'='.$key[1].';';
} else {
$_REQUEST[$value] = $_GET[$value] = $_POST[$value] = true;
               $_SERVER["REQUEST_URI"].= $value.';';
}
}
}
Title: Re: [TIP/TRICK] Get Facebook and others to load a shared url.
Post by: SA™ on January 09, 2012, 01:40:22 PM
hey nend will this fix urls like this?

http://www.sa-smf.com/community/index.php?action=kb%3Barea%3Darticle%3Bcont%3D41

Title: Re: [TIP/TRICK] Get Facebook and others to load a shared url.
Post by: nend on January 09, 2012, 02:02:33 PM
That is what it is for, ;)

When the user clicks on the link in FB or G+ they get a link like the one you have above, but that doesn't work in SMF so it has to be converted and all the post information pulled from it, however SMF does not convert a url that has been encoded this way. Maybe it shoud, maybe not, however we can make it do it.

Say I have a gallery item
http://site.com/index.php?action=media%3Bsa%3Ditem%3Bin%3D120

All the script sees is this below, so it can't find anything of meaning in that mess so we end up on the board index.

var                   value
actionmedia%3Bsa%3Ditem%3Bin%3D120

With this hack it converts the values so we can actually go to the page we are meant to go to.

var                   value
actionmedia
saitem
in120
Title: Re: [TIP/TRICK] Get Facebook and others to load a shared url.
Post by: SA™ on January 09, 2012, 02:21:05 PM
thats what i fault but it doesnt seem to work

with the code added it goes to the action fine [without it goes to the boardindex]

after conversion the url still looks like this

http://www.sa-smf.com/community/index.php?action=kb%3Barea%3Darticle%3Bcont%3D41

try the url above and your see what i mean
Title: Re: [TIP/TRICK] Get Facebook and others to load a shared url.
Post by: nend on January 09, 2012, 02:24:11 PM
I just checked my sources, I changed the script a little, not much though. I remember having the same problem you where.
// Lets just fix the URI early if it is screwed up from services like Facebook and such.
if(strstr($_SERVER["REQUEST_URI"], '%3D')) {
$fix_uri = explode('?' , $_SERVER["REQUEST_URI"]);
$_SERVER["REQUEST_URI"] = $fix_uri[0].'?'; //Might as well rebuild the URI, who knows something might need it.
$fix_uri = str_replace(';', '%3B', $fix_uri[1]);
$fix_uri = explode('%3B', $fix_uri);
foreach($fix_uri as $value) {
if(strstr($value, '=')) {
$key = explode('=', $value);
$_REQUEST[$key[0]] = $_GET[$key[0]] = $_POST[$key[0]] = $key[1];
$_SERVER["REQUEST_URI"].= $key[0].'='.$key[1].';';
} else if(strstr($value, '%3D')) {
$key = explode('%3D', $value);
$_REQUEST[$key[0]] = $_GET[$key[0]] = $_POST[$key[0]] = $key[1];
$_SERVER["REQUEST_URI"].= $key[0].'='.$key[1].';';
} else {
$_REQUEST[$value] = $_GET[$value] = $_POST[$value] = true;
               $_SERVER["REQUEST_URI"].= $value.';';
}
}
}
Title: Re: [TIP/TRICK] Get Facebook and others to load a shared url.
Post by: SA™ on January 09, 2012, 02:27:13 PM
that still does the same
Title: Re: [TIP/TRICK] Get Facebook and others to load a shared url.
Post by: nend on January 09, 2012, 02:43:47 PM
Ahh, I see the problem, I only exploded the uri string once. I need to explode each instance, So that script can only do up to two values. Try this, I will update the script to count instances at the top, this one only does 10 instances. It should do the trick to test though.

// Lets just fix the URI early if it is screwed up from services like Facebook and such.
if(strstr($_SERVER["REQUEST_URI"], '%3D')) {
$fix_uri = explode('?' , $_SERVER["REQUEST_URI"]);
$_SERVER["REQUEST_URI"] = $fix_uri[0].'?'; //Might as well rebuild the URI, who knows something might need it.
$fix_uri = str_replace(';', '%3B', $fix_uri[1]);
$fix_uri = explode('%3B', $fix_uri, 10);
foreach($fix_uri as $value) {
if(strstr($value, '=')) {
$key = explode('=', $value);
$_REQUEST[$key[0]] = $_GET[$key[0]] = $_POST[$key[0]] = $key[1];
$_SERVER["REQUEST_URI"].= $key[0].'='.$key[1].';';
} else if(strstr($value, '%3D')) {
$key = explode('%3D', $value);
$_REQUEST[$key[0]] = $_GET[$key[0]] = $_POST[$key[0]] = $key[1];
$_SERVER["REQUEST_URI"].= $key[0].'='.$key[1].';';
} else {
$_REQUEST[$value] = $_GET[$value] = $_POST[$value] = true;
               $_SERVER["REQUEST_URI"].= $value.';';
}
}
}
Title: Re: [TIP/TRICK] Get Facebook and others to load a shared url.
Post by: SA™ on January 09, 2012, 03:31:20 PM
still does the same  ???
Title: Re: [TIP/TRICK] Get Facebook and others to load a shared url.
Post by: nend on January 09, 2012, 09:49:50 PM
I can't produce the same results, every url works.

http://wrestletopia.2-si.net/n/index.php?action=media%3Bsa%3Ditem%3Bin%3D120
http://wrestletopia.2-si.net/n/index.php?action%3Dmedia%3Bsa%3Ditem%3Bin%3D120
http://wrestletopia.2-si.net/n/media/?sa%3Ditem%3Bin%3D120
http://wrestletopia.2-si.net/n/media/?sa=item%3Bin%3D120

Can you get the output of $_SERVER["REQUEST_URI"] at the end of the script, I doubt this would be different though.
Maybe the variable type isn't set as a integer, if you consider it in the beginning it is a string, maybe it stays as a string and then later on there is a check to see if the value is a integer for security reasons and then the script is haulted on a error.

Try
// Lets just fix the URI early if it is screwed up from services like Facebook and such.
if(strstr($_SERVER["REQUEST_URI"], '%3D')) {
$fix_uri = explode('?' , $_SERVER["REQUEST_URI"]);
$_SERVER["REQUEST_URI"] = $fix_uri[0].'?'; //Might as well rebuild the URI, who knows something might need it.
$fix_uri = str_replace(';', '%3B', $fix_uri[1]);
$fix_uri = explode('%3B', $fix_uri, substr_count($fix_uri, '%3B')+1);
foreach($fix_uri as $value) {
if(strstr($value, '=')) {
$key = explode('=', $value);
$_REQUEST[$key[0]] = $_GET[$key[0]] = $_POST[$key[0]] = is_numeric($key[1]) ? (int)$key[1] : $key[1];
$_SERVER["REQUEST_URI"].= $key[0].'='.$key[1].';';
} else if(strstr($value, '%3D')) {
$key = explode('%3D', $value);
$_REQUEST[$key[0]] = $_GET[$key[0]] = $_POST[$key[0]] =  is_numeric($key[1]) ? (int)$key[1] : $key[1];
$_SERVER["REQUEST_URI"].= $key[0].'='.$key[1].';';
} else {
$_REQUEST[$value] = $_GET[$value] = $_POST[$value] = true;
               $_SERVER["REQUEST_URI"].= $value.';';
}
}
}


I haven't tested this, it looks typo free though, lol.
Title: Re: [TIP/TRICK] Get Facebook and others to load a shared url.
Post by: Oldiesmann on January 10, 2012, 08:50:49 AM
Wouldn't it just be simpler to pass the URL through PHP's urldecode() function?
Title: Re: [TIP/TRICK] Get Facebook and others to load a shared url.
Post by: nend on January 10, 2012, 09:16:15 AM
Quote from: Oldiesmann on January 10, 2012, 08:50:49 AM
Wouldn't it just be simpler to pass the URL through PHP's urldecode() function?
It will decode the url ok, but we still need the values from it. Since these sites encode the url the values are not passed. I actually did it the way you suggested at first and did a redirect and FB did not follow. As easy as I thought it was at the beginning in the end it was no easy fix, lol. ;)
Title: Re: [TIP/TRICK] Get Facebook and others to load a shared url.
Post by: SA™ on January 10, 2012, 09:19:06 AM
tryed the new code it still didnt work correct nend :/
Title: Re: [TIP/TRICK] Get Facebook and others to load a shared url.
Post by: nend on January 10, 2012, 09:58:41 AM
Well I am stumped about your site, I tried the simple way like suggested used urldecode and then tried a redirect then I seen the problem.

When you have a url like this urldecode doesn't work because it consider it as a value of action and it is right. But this is one of the common malformed urls that FB and G+ spits out.
site.com/index.php?action=media%3Bsa%3Ditem%3Bin%3D120

So try this we are redirecting on this one, but not using urldecode. Shouldn't be too much of a problem unless a mod submits data in the url with the "=" sign then it would be a problem. We have to disable for this or something, haven't ran into compatibility issues yet though.

if(strstr($_SERVER["REQUEST_URI"], '%3D')) {
$fix_uri = explode('?' , $_SERVER["REQUEST_URI"]);
$_SERVER["REQUEST_URI"] = $fix_uri[0].'?'; //Might as well rebuild the URI, who knows something might need it.
$fix_uri = str_replace(';', '%3B', $fix_uri[1]);
$fix_uri = explode('%3B', $fix_uri, substr_count($fix_uri, '%3B')+1);
foreach($fix_uri as $value) {
if(strstr($value, '=')) {
$key = explode('=', $value);
$_SERVER["REQUEST_URI"].= $key[0].'='.$key[1].';';
} else if(strstr($value, '%3D')) {
$key = explode('%3D', $value);
$_SERVER["REQUEST_URI"].= $key[0].'='.$key[1].';';
} else {
               $_SERVER["REQUEST_URI"].= $value.';';
}
}
Header( "HTTP/1.1 301 Moved Permanently" );
Header( "Location: ".$_SERVER["REQUEST_URI"]);
}
Title: Re: [TIP/TRICK] Get Facebook and others to load a shared url.
Post by: SA™ on January 10, 2012, 10:05:45 AM
now this works thanks for this nend
Title: Re: [TIP/TRICK] Get Facebook and others to load a shared url.
Post by: spcx on April 25, 2012, 02:52:59 PM
Hey nend, used your trick to solve my linking prob on FB. But a quick question, how can I make my link on FB:

becomes
http://triggerinc.net/index.php?action=classifieds&sa=view&id=32

instead of ;

Reason why is that you can try both & and ; on the same URL, but it brings different results on FB. If I use & it displays the link with the pic and body copy of the link which is what I want!

Is there a way to work around this?
Title: Re: [TIP/TRICK] Get Facebook and others to load a shared url.
Post by: petb on May 19, 2012, 10:32:41 AM
There where much more Users with this Problem,..
http://www.simplemachines.org/community/index.php?topic=474432.msg3316966#msg3316966
http://www.simplemachines.org/community/index.php?topic=471506.msg3295593#msg3295593

My Question was:
Why did smf changed this ?
Because older Versions havent any Problem with the %3B and %3D in the Query String.
Title: Re: [TIP/TRICK] Get Facebook and others to load a shared url.
Post by: nend on May 19, 2012, 01:41:05 PM
Quote from: spcx on April 25, 2012, 02:52:59 PM
Hey nend, used your trick to solve my linking prob on FB. But a quick question, how can I make my link on FB:

becomes
http://triggerinc.net/index.php?action=classifieds&sa=view&id=32

instead of ;

Reason why is that you can try both & and ; on the same URL, but it brings different results on FB. If I use & it displays the link with the pic and body copy of the link which is what I want!

Is there a way to work around this?

Maybe with quite a bit of work, what you have is a disagreement here. SMF prefers ; in urls and Facebook hates them and prefers & to separate the arguments. So if you want SMF to support & instead of ; you might want to search the entire code base or edit the output buffer. If your going to miss with the buffer though you might as well just install one of these SEO url mods like PrettyURLs or SimpleSEF.

Quote from: petb on May 19, 2012, 10:32:41 AM
There where much more Users with this Problem,..
http://www.simplemachines.org/community/index.php?topic=474432.msg3316966#msg3316966
http://www.simplemachines.org/community/index.php?topic=471506.msg3295593#msg3295593

My Question was:
Why did smf changed this ?
Because older Versions havent any Problem with the %3B and %3D in the Query String.

I think the changes in SMF was due to a anticipated HTML standard that still isn't accepted, I however doubt it will ever be accepted. This standard will say you have to use ; instead of &.
Title: Re: [TIP/TRICK] Get Facebook and others to load a shared url.
Post by: demlak on January 04, 2013, 12:53:40 PM
Quote from: nend on November 28, 2011, 07:43:29 PM
if(strstr($_SERVER["REQUEST_URI"], '%3D')) {
$fix_uri = explode('?' , $_SERVER["REQUEST_URI"]);
$_SERVER["REQUEST_URI"] = $fix_uri[0].'?'; //Might as well rebuild the URI, who knows something might need it.
$fix_uri = str_replace(';', '%3B', $fix_uri[1]);
$fix_uri = explode('%3B', $fix_uri, substr_count($fix_uri, '%3B')+1);
foreach($fix_uri as $value) {
if(strstr($value, '=')) {
$key = explode('=', $value);
$_REQUEST[$key[0]] = $_GET[$key[0]] = $_POST[$key[0]] = $key[1];
$_SERVER["REQUEST_URI"].= $key[0].'='.$key[1].';';
} else if(strstr($value, '%3D')) {
$key = explode('%3D', $value);
$_REQUEST[$key[0]] = $_GET[$key[0]] = $_POST[$key[0]] = $key[1];
$_SERVER["REQUEST_URI"].= $key[0].'='.$key[1].';';
} else {
$_REQUEST[$value] = $_GET[$value] = $_POST[$value] = true;
               $_SERVER["REQUEST_URI"].= $value.';';
}
}
}

i would like to make a mod of this code..
(just change the %3D in first line to %3B)

since im not using FB and also my board is not working for non-logged-in users..  this FB thing is not relevant for us.. but it is relevant for activation links on webmailers like gmx, gmail, web.de, and so on.. webmailers got many problems on those links in activation mails.. but some interpret "=" correct.. but it seems no webmailer interprets the semicolon correct.

if it´s ok for you.. i will submit this as a mod to SMF... since i don´t want to steal code.. i need your permission =) and you will be named in there...
Title: Re: [TIP/TRICK] Get Facebook and others to load a shared url.
Post by: nend on January 04, 2013, 11:53:33 PM
No problem, don't have any problems with sharing.  ;D
Title: Re: [TIP/TRICK] Get Facebook and others to load a shared url.
Post by: rodelio.lagahit on January 15, 2013, 12:54:04 AM
and this mod killed my forum :(
any idea how to remove this for my site to be accessible again?
Title: Re: [TIP/TRICK] Get Facebook and others to load a shared url.
Post by: rodelio.lagahit on January 15, 2013, 01:10:24 AM
Quote from: rodelio.lagahit on January 15, 2013, 12:54:04 AM
and this mod killed my forum :(
any idea how to remove this for my site to be accessible again?

fixed!

just look for the index.php. this mode added a few lines of codes at the beginning of that file. just delete it and don't forget to add <?php code after so that your file won't get any error.
Title: Re: [TIP/TRICK] Get Facebook and others to load a shared url.
Post by: demlak on January 15, 2013, 11:10:37 AM
im sorry that the mod mades problems.. but it should not.. i can´t see any problem..

if you want to help to fix this.. please post detailed infos