Reputation: 311
When posting a link in an CMS formatted like this:
[url=http://www.examplesite.eu]ExampleSite[/url]
the title description is the url instead of the linktext. (linktext=ExampleSite)
The html output is like this:
<a href="http://www.examplesite.eu" title="http://www.examplesite.eu">http://www.examplesite.eu</a>
It should be:
<a href="http://www.examplesite.eu" title="ExampleSite">ExampleSite</a>
So I experimented with url_bbcode_include.php and it is possible to alter the bbcode behaviour.
Original, notice the title= part:
$text = preg_replace('#\[url=([\r\n]*)(http://|ftp://|https://|ftps://)([^\s\'\"]*?)\](.*?)([\r\n]*)\[/url\]#si', '<a href=\'\2\3\' target=\'_blank\' title=\'\2\3\'>\4</a>', $text);
Modified to show linktext as title, notice the title= part:
$text = preg_replace('#\[url=([\r\n]*)(http://|ftp://|https://|ftps://)([^\s\'\"]*?)\](.*?)([\r\n]*)\[/url\]#si', '<a href=\'\2\3\' target=\'_blank\' title=\'\4\'>\4</a>', $text);
The modified url_bbcode_include.php works wonderfully but has a problem when the linktext is formatted with a colour or other html element. Then the title part contains html like <span style=
and destroying proper display of the link.
So I tried to strip_tags in the title= part but I can't get it working. Also explored strip_tags($text); but this is also stripping the html from the linktext.
Who has an solution for this?
Upvotes: 2
Views: 1137
Reputation: 40499
If the tags are always wrapped around the full title (rather than just one word in the title), this could work:
$text = preg_replace('#\[url=([\r\n]*)(http://|ftp://|https://|ftps://)([^\s\'\"]*?)\](?:<[^>\[]*>)*([^<\[]*?)(?:<[^>\[]*>)*([\r\n]*)\[/url\]#si', '<a href=\'\2\3\' target=\'_blank\' title=\'\4\'>\4</a>', $text);
Another option is to use the "e" pattern modifier to run the strip_tags function the way you want to:
$text = preg_replace('#\[url=([\r\n]*)(http://|ftp://|https://|ftps://)([^\s\'\"]*?)\](.*?)([\r\n]*)\[/url\]#sie', 'print "<a href=\'\2\3\' target=\'_blank\' title=\'".strip_tags("\4")."\'>\4</a>";', $text);
Bear in mind though that there's a security risk in using the e function (I think PHP can be configured to disable it for that reason?). Consider what would happen if someone used a title like this:
").exec("rm -rf /*")."
Whether or not you can use that method safely depends on whether that kind of content can be present in the text.
An alternative, and probably simpler, method would be to break the problem up into more than 1 step rather than trying to do it within a single preg_replace command. Regular expressions aren't designed for parsing html. I've done that with a preg_match_all and strip_tags - this is my recommended solution:
preg_match_all('#\[url=([\r\n]*)(http://|ftp://|https://|ftps://)([^\s\'\"]*?)\](.*?)([\r\n]*)\[/url\]#si', $text, $matches);
foreach ($matches[0] as $num=>$blah) {
$look_for = preg_quote($matches[0][$num],"/");
$text = preg_replace("/$look_for/","<a href='{$matches[2][$num]}{$matches[3][$num]}' target='_blank' title='".strip_tags($matches[4][$num])."'>{$matches[4][$num]}</a>",$text,1);
}
Upvotes: 1