tags:

views:

33

answers:

2

Hey,

With the code below some smilies won't work (the text isn't replaced by a smiley). When I change the order of the $smileys array, the broken smileys work but others don't.

So I know the order of the $smileys array determines the replacement of the smilies, but I don't know why.

Can anybody help me to let all the smileys work properly? Thanks

public $smileys = array(
    'tongetje.gif'  => array(':p',':P'),
    'cool.gif'  => array(':8'),
    'dansen.gif'=> array('(dance)'),
    'mondje_dicht.gif' => array(':|'),
    'muur_hoofd.gif'    => array('|:('),
    'huilen.gif'    => array('(h)'),
    'loser.gif' => array('(:)'),
    'lachje.gif' => array(':)',':-)'),
    'wink.gif'  => array(';)'),
    'lach.gif'  => array(':d',':-D'),
    'lollol.gif'    => array(':#'),
    'bloos.gif' => array('(b)'),
    'stom.gif'  => array(':s'),
    'doei.gif'  => array('(d)'),
    'engeltje.gif' => array('O-)'),
    'boze_smiley.gif' => array(':('),
    '1april.gif' => array(':1)'),
    'koning.gif' => array('(koning)'),
    'offtopic.gif' => array('*-*'),
    'opgeven_verlegen.gif' => array('O+'),
     'piraat.gif' => array(':F'),
    'politie.gif' => array('(p)'),
    'reggae.gif' => array('(r)'),
    'jammie.gif' => array(':9'),
    'schamen.gif' => array(':-8'),
    'verliefd.gif' => array(':00'),
    'middelvinger.gif' => array(':--')
);      

private function ubb_smileys($string) {
    $counter = 1;
    foreach($this->smileys as $imagename => $imagetags) {
        if(is_numeric($this->smilies_enable)) {
            if($counter <= $this->smilies_enable) {
                foreach($imagetags as $int => $tag) {
                    $tag = str_replace("\\", "", $tag);
                    $src = UBB_SMILEYS_PATH.$imagename;
                    $image = UBB_SMILEYS_STRING;
                    $image = str_replace('${TAG}', $tag, $image);
                    $image = str_replace('${SRC}', $src, $image);
                    $string = str_replace($tag, $image, $string);

                }
            }
        } else {
            foreach($imagetags as $int => $tag) {
                $tag = str_replace("\\", "", $tag);
                $src = UBB_SMILEYS_PATH.$imagename;
                $image = UBB_SMILEYS_STRING;
                $image = str_replace('${TAG}', $tag, $image);
                $image = str_replace('${SRC}', $src, $image);
                $string = str_replace($tag, $image, $string);

            }
        }
        $counter++;
    }
    return $string;
}
A: 

I expect it is because some smileys are subsets of others. For example ':)' is a subset of '(:)'. So if it came before ':)', '(:)' would never be found.

Include the most complicated ones first, and then any smiley that is a subset of another smiley must come later.

This explains why the ordering is affecting your results.

That said --- I can't find a specific example of the ordering in the order you posted above (although I may not have looked for long enough). With the above-posted order, which smileys are not working for you?

EDIT:

I tested with the below. Works fine for me. What are you using as a test string?

define('UBB_SMILEYS_PATH', '/images/');
define('UBB_SMILEYS_STRING', '<img src="${SRC}" alt="${TAG}" />');

class UBB {
    public $smileys_enable;

    public function __construct() {
        $this->smilies_enable = 100;
    }

    public $smileys = array(
        'tongetje.gif'  => array(':p',':P'),
        'cool.gif'  => array(':8'),
        'dansen.gif'=> array('(dance)'),
        'mondje_dicht.gif' => array(':|'),
        'muur_hoofd.gif'    => array('|:('),
        'huilen.gif'    => array('(h)'),
        'loser.gif' => array('(:)'),
        'lachje.gif' => array(':)',':-)'),
        'wink.gif'  => array(';)'),
        'lach.gif'  => array(':d',':-D'),
        'lollol.gif'    => array(':#'),
        'bloos.gif' => array('(b)'),
        'stom.gif'  => array(':s'),
        'doei.gif'  => array('(d)'),
        'engeltje.gif' => array('O-)'),
        'boze_smiley.gif' => array(':('),
        '1april.gif' => array(':1)'),
        'koning.gif' => array('(koning)'),
        'offtopic.gif' => array('*-*'),
        'opgeven_verlegen.gif' => array('O+'),
         'piraat.gif' => array(':F'),
        'politie.gif' => array('(p)'),
        'reggae.gif' => array('(r)'),
        'jammie.gif' => array(':9'),
        'schamen.gif' => array(':-8'),
        'verliefd.gif' => array(':00'),
        'middelvinger.gif' => array(':--')
    );      

    private function ubb_smileys($string) {
        $counter = 1;
        foreach($this->smileys as $imagename => $imagetags) {
            if(is_numeric($this->smilies_enable)) {
                if($counter <= $this->smilies_enable) {
                    foreach($imagetags as $int => $tag) {
                        $tag = str_replace("\\", "", $tag);
                        $src = UBB_SMILEYS_PATH.$imagename;
                        $image = UBB_SMILEYS_STRING;
                        $image = str_replace('${TAG}', $tag, $image);
                        $image = str_replace('${SRC}', $src, $image);
                        $string = str_replace($tag, $image, $string);

                    }
                }
            } else {
                foreach($imagetags as $int => $tag) {
                    $tag = str_replace("\\", "", $tag);
                    $src = UBB_SMILEYS_PATH.$imagename;
                    $image = UBB_SMILEYS_STRING;
                    $image = str_replace('${TAG}', $tag, $image);
                    $image = str_replace('${SRC}', $src, $image);
                    $string = str_replace($tag, $image, $string);

                }
            }
            $counter++;
        }
        return $string;
    }
    public function parse_smileys($str) {
        return $this->ubb_smileys($str);
    }
}

$ubb = new UBB();

$myStr = 'xxx :-) :s lalala (d) :( Some text';

echo($ubb->parse_smileys($myStr));
Jhong
For example the :s and (d) doesn't work in the code above.The ${TAG} will be replaced and isn't a variable.
Arjen
It looks like the ordering isn't affecting the working of the smileys, because :s isn't replaced anywhere but this one still doesn't work.
Arjen
Edited. :s and (d) Work for me in the above example (which is just your code with a test scaffold).
Jhong
A: 

I think you needed to short-circuit the foreach loops when you have a successful replacement. This is what I did to test it, as a complete file:

<pre>
<?php
define('UBB_SMILEYS_PATH', 'c:\\');
define('UBB_SMILEYS_STRING', '(img src="${SRC}" alt="${TAG}" /)');
class ubb {
var $smilies_enable = true;
 public $smileys = array(
    'tongetje.gif'  => array(':p',':P'),
    'cool.gif'  => array(':8'),
    'dansen.gif'=> array('(dance)'),
    'mondje_dicht.gif' => array(':|'),
    'muur_hoofd.gif'    => array('|:('),
    'huilen.gif'    => array('(h)'),
    'loser.gif' => array('(:)'),
    'lachje.gif' => array(':)',':-)'),
    'wink.gif'  => array(';)'),
    'lach.gif'  => array(':d',':-D'),
    'lollol.gif'    => array(':#'),
    'bloos.gif' => array('(b)'),
    'stom.gif'  => array(':s'),
    'doei.gif'  => array('(d)'),
    'engeltje.gif' => array('O-)'),
    'boze_smiley.gif' => array(':('),
    '1april.gif' => array(':1)'),
    'koning.gif' => array('(koning)'),
    'offtopic.gif' => array('*-*'),
    'opgeven_verlegen.gif' => array('O+'),
     'piraat.gif' => array(':F'),
    'politie.gif' => array('(p)'),
    'reggae.gif' => array('(r)'),
    'jammie.gif' => array(':9'),
    'schamen.gif' => array(':-8'),
    'verliefd.gif' => array(':00'),
    'middelvinger.gif' => array(':--')
);      

 public function ubb_smileys($string) {
    $counter = 0;
    foreach($this->smileys as $imagename => $imagetags) {
        $f = false;
        if(is_numeric($this->smilies_enable)) {
            if($counter <= $this->smilies_enable) {
                foreach($imagetags as $int => $tag) {
                    $tag = str_replace("\\", "", $tag);
                    $src = UBB_SMILEYS_PATH.$imagename;
                    $image = UBB_SMILEYS_STRING;
                    $image = str_replace('${TAG}', $tag, $image);
                    $image = str_replace('${SRC}', $src, $image);
                    if(strstr($string, $tag)) {
                        $string = str_replace($tag, $image, $string);
                        $f = true;
                        break;
                    }
                }
            }
        } else {
            foreach($imagetags as $int => $tag) {
                $tag = str_replace("\\", "", $tag);
                $src = UBB_SMILEYS_PATH.$imagename;
                $image = UBB_SMILEYS_STRING;
                $image = str_replace('${TAG}', $tag, $image);
                $image = str_replace('${SRC}', $src, $image);
                if(strstr($string, $tag)) {
                    $string = str_replace($tag, $image, $string);
                    $f = true;
                    break;
                }
            }
        }
        $counter++;
        if($f) break;
    }
    return $string;
}
}

$ubb = new ubb();
foreach($ubb->smileys as $s) {
    foreach($s as $ss) {
        $phr = "lol $ss";
        echo $phr . " -&gt; " .($ubb->ubb_smileys($phr));
        echo "<br/>";
    }
}
This won't work if you pass in a string with multiple smilies
Jhong
Reasonable; maybe repeatedly call the function until it doesn't change anything.