Reputation: 2079
I'm working on a bb-code replacement function when a user wants to post a smiley.
The problem is, that if someone uses a bb-code smiley that doesn't exists, it results in an empty post because the browser will not display the (non-existing) emoticon.
Here's my code so far:
// DO [:smiley:]
$convert_smiley = preg_match_all('/\[:(.*?):\]/i', $string, $matches);
if( $convert_smiley )
{
$string = preg_replace('/\[:(.*?):\]/i', "<i class='icon-smiley-$1'></i>", $string, $convert_smiley);
}
return $string;
The bb-code for a smiley usually looks like [:smile:]
or like [:sad:]
or like [:happy:]
and so on.
The code above is working well, until someone post a bb-code that doesn't exists, so what I am asking for is a fix for non existing smileys.
Is there a possibility, in example to create an array, like array('smile', 'sad', 'happy')
and only bb-code that matches one or more in this array will be converted?
So, after the fix, posting [:test:]
or just [::]
should not be converted and should be posted as original text while [:happy:]
will be converted.
Any ideas? Thanks!
Upvotes: 0
Views: 670
Reputation: 26084
Well, the first issue is you are setting $convert_smiley
to the true
/false
value of the preg_match_all()
instead of parsing the results. Here is how I reworked your code:
// Test strings.
$string = ' [:happy:] [:frown:] [:smile:] [:foobar:]';
// Set a list of valid smileys.
$valid_smileys = array('smile', 'sad', 'happy');
// Do a `preg_match_all` against the smiley’s
preg_match_all('/\[:(.*?):\]/i', $string, $matches);
// Check if there are matches.
if (count($matches) > 0) {
// Loop through the results
foreach ($matches[1] as $smiley_value) {
// Validate them against the valid smiley list.
$pattern = $replacement = '';
if (in_array($smiley_value, $valid_smileys)) {
$pattern = sprintf('/\[:%s:\]/i', $smiley_value);
$replacement = sprintf("<i class='icon-smiley-%s'></i>", $smiley_value);
$string = preg_replace($pattern, $replacement, $string);
}
}
}
echo 'Test Output:';
echo htmlentities($string);
Just note that I chose to use sprintf()
for the formatting of content & set $pattern
and $replacement
as variables. I also chose to use htmlentities()
so the HTML DOM elements can easily be read for debugging.
Upvotes: 1
Reputation: 23749
I put your possible smiley’s in non-grouping parentheses with or
symbol in a regexp:
<?php
$string = 'looks like [:smile:] or like [:sad:] or like [:happy:] [:bad-smiley:]';
$string = preg_replace('/\[:((?:smile)|(?:sad)|(?:happy)):\]/i', "<i class='icon-smiley-$1'></i>", $string);
print $string;
Output:
looks like <i class='icon-smiley-smile'></i> or like <i class='icon-smiley-sad'></i> or like <i class='icon-smiley-happy'></i> [:bad-smiley:]
[:bad-smiley:] is ignored.
Upvotes: 1
Reputation: 9577
A simple workaround:
$string ="[:clap:]";
$convert_smiley = preg_match_all('/\[:(.*?):\]/i', $string, $matches);
$emoticons = array("smile","clap","sad"); //array of supported smileys
if(in_array($matches[1][0],$emoticons)){
//smily exists
$string = preg_replace('/\[:(.*?):\]/i', "<i class='icon-smiley-$1'></i>", $string, $convert_smiley);
}
else{
//smily doesn't exist
}
Upvotes: 1