• Forum
  • Doc
  • Screenshots
  • Download
  • Donate
  • Contributors
  • Contact
  • Follow @phpfreechat
  • DEMO
  • Board index ‹ Version 1.x branch ‹ General Support (v1.x)
  • Change font size
  • FAQ
  • Register
  • Login

Problems with smilies

Moderators: OldWolf, re*s.t.a.r.s.*2

Post a reply
8 posts • Page 1 of 1

Postby AdamR » Thu Nov 30, 2006 3:00 pm

Hi, first of all, thanks for a brilliant script, It works well with my phpbb forum.

I have a few issues, wondered if anyone can help.

The smilie filter has problems where you might have 2 smilies,

i.e.

foo.gif :p
bar.gif :punch

in this case, if someone sends :punch, it will be replaced with the :p smiley, and unch on the end, i.e. <img src="foo.gif">unch

Could anyone tell me how to solve this? I believe the relevent code is here in phpfreechat.class.php:

Code: Select all
  function FilterSmiley($msg)
  {
    $c =& pfcGlobalConfig::Instance();
    // build a preg_replace array
    $search = array();
    $replace = array();
    $query = "/(";
    foreach($c->smileys as $s_file => $s_strs)
    {
      foreach ($s_strs as $s_str)
      {
        $s_str = stripslashes($s_str); /* the :'( smileys needs this filter */
         $query .= preg_quote($s_str,'/')."|";
         $search[] = "/".preg_quote($s_str,'/')."/";
         $replace[] = '<img src="'.$s_file.'" alt="'.$s_str.'" title="'.$s_str.'" />';
      }
    }

...

Thanks in advance
Adam
AdamR
New member
 
Posts: 3
Joined: Thu Nov 30, 2006 2:56 pm
Top

Postby phpfreechat » Thu Nov 30, 2006 3:08 pm

Difficulte to know what is the priority when two smileys uses the same string or substring.
I suggest you to rename one smiley string.
phpfreechat
Site Admin
 
Posts: 2657
Joined: Tue Feb 07, 2006 3:35 pm
Location: France
Top

Postby AdamR » Thu Nov 30, 2006 3:19 pm

why is it difficult?

I would of thought it is just a case of finding the longest exact match first ?

I do not want to change the smiley strings, as I have written a script to export them directly from phpbb, which my users are familiar with :)
AdamR
New member
 
Posts: 3
Joined: Thu Nov 30, 2006 2:56 pm
Top

Postby phpfreechat » Thu Nov 30, 2006 4:01 pm

Ok if you are able to write a better algorithme feel free to submit it here, I will integrate your patch to the official pfc source code.
However, the smiley parsing is not done server side (in 1.0-beta7), it is done client side in src/client/pfcclient.js :
"parseMessage: function(msg)"

The current code is :
Code: Select all
 1189     // try to parse smileys
 1190     var smileys = this.res.getSmileyHash();
 1191     var sl = smileys.keys();
 1192     for(var i = 0; i < sl.length; i++)
 1193     {
 1194       rx = new RegExp(RegExp.escape(sl[i]),'g');
 1195       msg = msg.replace(rx, '<img src="'+ smileys[sl[i]] +'" alt="' + sl[i] + '" title="' + sl[i] + '" />');
 1196     }
phpfreechat
Site Admin
 
Posts: 2657
Joined: Tue Feb 07, 2006 3:35 pm
Location: France
Top

Postby AdamR » Thu Nov 30, 2006 5:03 pm

Thanks for the info, I'm slowly working out how pfc works :)

I will update this thread with the code I use.

Thanks
Adam
AdamR
New member
 
Posts: 3
Joined: Thu Nov 30, 2006 2:56 pm
Top

Postby joel558 » Mon Mar 05, 2007 2:18 am

I see this message is rather old, but no solution has been posted and the issue seems to still exist, so I'll post my solution..

in the latest beta i replaced the smilie code with

Code: Select all
    // try to parse smileys
    var smileys = this.res.getSmileyHash();
    var sl = smileys.keys();
    for(var i = 0; i < sl.length; i++)
    {
      rx = new RegExp('s*'+RegExp.escape(sl[i])+' ','gi');
      msg = msg.replace(rx, ' <img src="'+ smileys[sl[i]] +'" alt="' + sl[i] + '" title="' + sl[i] + '" /> ');
    }

and it seems to have solved the issues I had with smilies such as 'lurker2' being overridden by 'lurker'

Basically it checks for zero or more whitespace characters at the beginning, as well as a space at the end.. not sure if this would have any impact on any of the other smilies, but it does what i need.. And i think smilies are pretty much always a word on their own anyways..

*edit: edited to new code with optional whitespace at start*
Last edited by joel558 on Mon Mar 05, 2007 2:30 am, edited 1 time in total.
joel558
New member
 
Posts: 3
Joined: Mon Mar 05, 2007 2:10 am
Top

Postby joel558 » Sat Jul 07, 2007 4:49 am

I'll post a fix to my own code here.. it had issues dealing with some things like using bbcode around smilies, etc.. so heres the updated version with a few more changes going in to make it work better..

we're gonna rely on there being a space after each smilie, so if the smilie is the only thing on the line, or at the end, we need to add the space, so we add the following to the start of parseMessage function..
Code: Select all
msg = ' '+msg+' ';

replacing the smilie parsing code to look for spaces after smilie..
Code: Select all
    // try to parse smileys
    var smileys = this.res.getSmileyHash();
    var sl = smileys.keys();
    for(var i = 0; i < sl.length; i++)
    {
      rx = new RegExp(RegExp.escape(sl[i])+'\s','gi');
      msg = msg.replace(rx, '<img src="'+ smileys[sl[i]] +'" alt="' + sl[i] + '" title="' + sl[i] + '" />');
    }

move the following from just before the smilie parsing to just after so we don't eat up the spaces the smilies need
Code: Select all
   
     // replace double spaces by   entity
    rx = new RegExp('  ','g');
    msg = msg.replace(rx, '  ');

we also need to allow for the smilies to be in bbcode, and we need spaces around them, so we change the bbcode parsing to add spaces inside the tags:
Code: Select all
    // try to parse bbcode
    rx = new RegExp('\[b\](.+?)\[/b\]','ig');
    msg = msg.replace(rx, '<span style="font-weight: bold"> $1 </span>');
    rx = new RegExp('\[i\](.+?)\[/i\]','ig');
    msg = msg.replace(rx, '<span style="font-style: italic"> $1 </span>');
    rx = new RegExp('\[u\](.+?)\[/u\]','ig');
    msg = msg.replace(rx, '<span style="text-decoration: underline"> $1 </span>');
    rx = new RegExp('\[s\](.+?)\[/s\]','ig');
    msg = msg.replace(rx, '<span style="text-decoration: line-through"> $1 </span>');
    //    rx = new RegExp('\[pre\](.+?)\[/pre\]','ig');
    // msg = msg.replace(rx, '<pre>$1</pre>');
    rx = new RegExp('\[email\]([A-z0-9][\w.-]*@[A-z0-9][\w\-\.]+\.[A-z0-9]{2,6})\[/email\]','ig');
    msg = msg.replace(rx, '<a href="mailto: $1">$1</a>');
    rx = new RegExp('\[email=([A-z0-9][\w.-]*@[A-z0-9][\w\-\.]+\.[A-z0-9]{2,6})\](.+?)\[/email\]','ig');
    msg = msg.replace(rx, '<a href="mailto: $1">$2</a>');
    rx = new RegExp('\[color=([a-zA-Z]+|\#?[0-9a-fA-F]{6}|\#?[0-9a-fA-F]{3})](.+?)\[/color\]','ig');
    msg = msg.replace(rx, '<span style="color: $1"> $2 </span>');
    // parse bbcode colors twice because the current_text_color is a bbcolor
    // so it's possible to have a bbcode color imbrication
    rx = new RegExp('\[color=([a-zA-Z]+|\#?[0-9a-fA-F]{6}|\#?[0-9a-fA-F]{3})](.+?)\[/color\]','ig');
    msg = msg.replace(rx, '<span style="color: $1"> $2 </span>');

and since we're relying on spaces after a smilie, we'll change the insertSmiley code to add a space when someone clicks on a smiie in the smilie box below chat:
Code: Select all
  insertSmiley: function(s)
  {
    this.el_words.value += s+' ';
    this.el_words.focus();
  },

and from the testing i've done this seems to work with everything!
joel558
New member
 
Posts: 3
Joined: Mon Mar 05, 2007 2:10 am
Top

Postby King Moonraiser » Fri Sep 07, 2007 5:36 pm

I haven't tried to implement your changes, but from what I'm gathering, you're solving the problem by ensuring smileys always have whitespace. It makes sense since smileys can be very destructive on strings. However, people's expectation on smileys is that they don't expect them to be separated by spaces. Most forum software programs allow a string of smileys with no breaks.

AdamR was on the right track. The smileys are stored in a hash table, so there's no guarantee on the order they will be processed. The solution is to sort the smileys by length so ":punch" gets processed before ":p" does. The other "gotcha" is that the smileys are already converted to escaped html, so smileys with special characters would get yield erroneous string sizes.

I resolved the issue by creating an ordered array of all the smiley hash keys (i.e., this.smileyskeys). It gets sorted after the smiles are loaded:

Code: Select all
  sortSmileyKeys: function()
  {
    // Sort keys by longest to shortest. This prevents a smiley like :) from being used on >:)
    return this.smileyskeys.sort(
        function (a,b)
        {
          var x = a.unescapeHTML();
          var y = b.unescapeHTML();

          // Replace " with " for IE and Webkit browsers.
          // The prototype.js version 1.5.1.1 unescapeHTML() function does not do this.
          if (is_ie || is_webkit)
          {
            x = x.replace(/"/g,'"');
            y = y.replace(/"/g,'"');
          }   
   
          return (y.length - x.length);
        }
    );
  }
King Moonraiser
Member
 
Posts: 98
Joined: Fri Jun 22, 2007 9:42 pm
  • Website
Top


Post a reply
8 posts • Page 1 of 1

Return to General Support (v1.x)

Who is online

Users browsing this forum: No registered users and 3 guests

  • Board index
  • The team • Delete all board cookies • All times are UTC + 1 hour
Powered by phpBB® Forum Software © phpBB Group
Sign in
Wrong credentials
Sign up I forgot my password
.
jeu-gratuit.net | more partners
Fork me on GitHub