<?php
/*################################################
* Omsnplus class 1.0
* Done by : Saanina
* My Name : Abdulrahman Muhammad Alshawaiee
* From KSA
* You can Find Me At :
* - moffed.com
* - issc.ws
* My email : hide@address.com
*
* Class Description:
* emulator of Messenger Plus But for web pages :)
*
*Class license :
* - GPL for Non-Commerical
* - You can call me at my email if you want to use it in any thing commerical ..
###############################################*/
class Omsnplus
{
//folder of msn smiles
//Download all the emoticons (*.gif and don't rename) from http://messenger.msn.com/Resource/Emoticons.aspx
var $smiles_folder = 'smiles/';
//pre-definded colors
//source : http://www.emesene.org
//emesene is a linux program for msn in python
var $dirty_colors = array(
'ffffff','000000','00007F','009300','FF0000','7F0000','9C009C','FC7F00',
'FFFF00','00FC00','009393','00FFFF','0000FC','FF00FF','7F7F7F','D2D2D2',
'E7E6E4','CFCDD0','FFDEA4','FFAEB9','FFA8FF','B4B4FC','BAFBE5','C1FFA3',
'FAFDA2','B6B4B7','A2A0A1','F9C152','FF6D66','FF62FF','6C6CFF','68FFC3',
'8EFF67','F9FF57','858482','6E6D7B','FFA01E','F92611','FF20FF','202BFF',
'1EFFA5','60F913','FFF813','5E6464','4B494C','D98812','EB0505','DE00DE',
'0000D3','03CC88','59D80D','D4C804','333335','18171C','944E00','9B0008',
'980299','01038C','01885F','389600','9A9E15','473400','4D0000','5F0162',
'000047','06502F','1C5300','544D05'
);
//all copyrights of these smiles and thier shorts return to microzoft.
//but with time those smiles were very popular, so we have some of the copyrights :)
//if you hate microsoft remove this codes, if microzoft hate you, you can leave it.
//Download all the emoticons (*.gif and don't rename) from http://messenger.msn.com/Resource/Emoticons.aspx
var $msn_smiles = array(
':-( :(' => 'sad_smile.gif',
':-) :)' => 'regular_smile.gif',
':-O :o' => 'omg_smile.gif',
':-D :d' => 'teeth_smile.gif',
':-P :p' => 'tongue_smile.gif',
';-) ;)' => 'wink_smile.gif',
':-S :s' => 'confused_smile.gif',
':\'(' => 'cry_smile.gif',
'(H) (h)' => 'shades_smile.gif',
'(A) (a)' => 'angel_smile.gif',
'(C) (c)' => 'coffee.gif',
'(Y) (y)' => 'thumbs_up.gif',
'(N) (n)' => 'thumbs_down.gif',
'(L) (l)' => 'heart.gif',
'(U) (u)' => 'broken_heart.gif',
'(K) (k)' => 'kiss.gif',
'(G) (g)' => 'present.gif',
'(F) (f)' => 'rose.gif',
'(W) (w)' => 'wilted_rose.gif',
'(P) (p)' => 'camera.gif',
'(T) (t)' => 'phone.gif',
'(I) (i)' => 'lightbulb.gif',
'(E) (e)' => 'envelope.gif',
'(O) (o)' => 'clock.gif',
'(M) (m)' => 'messenger.gif',
'(~)' => 'film.gif',
'(B) (b)' => 'beer_mug.gif',//bad smile
'(D) (d)' => 'martini.gif',//bad smile
'(X) (x)' => 'girl.gif',//I beileive that girls not like
'(Z) (z)' => 'guy.gif',//Boys and Boys not like girls, X:horizotanl axis Y:vertiacl axis
'({}' => 'guy_hug.gif',
'())' => 'girl_hug.gif',
':-#' => '47_47.gif',
':-| :|' => 'what_smile.gif',
':-$ :$' => 'red_smile.gif',
':-@ :@' => 'angry_smile.gif',
'(6)' => 'devil_smile.gif',
'8o|' => '48_48.gif',
'8-|' => '49_49.gif',
'^o)' => '50_50.gif',
':-*' => '51_51.gif',
'+o(' => '52_52.gif',
':^)' => '71_71.gif',
'*-)' => '72_72.gif',
'<:o)' => '74_74.gif',
'8-)' => '75_75.gif',
'|-)' => '77_77.gif',
'|-)' => '77_77.gif',
':-[ :[' => 'bat.gif',
'(^)' => 'cake.gif',
'(@)' => 'cat.gif',
'(&)' => 'dog.gif',
'(8)' => 'note.gif',
'(S)' => 'moon.gif',
'(*)' => 'star.gif',
'(sn)' => '53_53.gif',
'(bah)' => '70_70.gif',
'(pl)' => '55_55.gif',
'(||)' => '56_56.gif',
'(pi)' => '57_57.gif',
'(so)' => '58_58.gif',
'(au)' => '59_59.gif',
'(ap)' => '60_60.gif',
'(um)' => '61_61.gif',
'(ip)' => '62_62.gif',
'(co)' => '63_63.gif',
'(mp)' => '64_64.gif',
'(st)' => '66_66.gif',
'(li)' => '73_73.gif',
'(mo)' => '69_69.gif',
//additional smiles , and you can add more as item from the external variable : $this->msn_smiles['short'] = 'img path';
//bla bla bla
);
//the codes for msn. plus
var $codes = array(
//solve some thing in begining
//text decoration
'!\[(\/|)(b||u|s|i)\]!is' => '<$1$2>',
//'!\[\/(b||u|s|i)\]!is' => '</$1>',
'!\·\#(.*?)\·\#!s' => '<span style="font-weight:bold">$1</span>',
'!\·\#!s' => '<span style="font-weight:bold">',
'!\·\&(.*?)\·\&!s' => '<span style="font-style:italic">$1</span>',
'!\·\&!s' => '<span style="font-style:italic">',
'!\·\'(.*?)\·\'!s' => '<span style="text-decoration: line-through">$1</span>',
'!\·\'!s' => '<span style="text-decoration: line-through">',
'!\·\@(.*?)\·\@!s' => '<span style="text-decoration:underline">$1</span>',
'!\·\@!s' => '<span style="text-decoration:underline">',
'!\·0!s' => '</span>',//idont know what the porpuse of terminate till now , but i will try to know
'!\[\/[a|c]\]!is' => '</span>',
//colors for all methods
//predefined number
//hex
'!\·\$(\#[0-9A-Fa-f]{2,6}|[a-z]+)(?: |)\,(?: |)(\#[0-9A-Fa-f]{2,6}|[a-z]+)!' => '<span style="color:$1;background-color:$2">',
'!\·\$(?: |)\,(?: |)([0-9]{1,3})!e' => '"<span style=\"background-color:#" . $this->dirty_colors[$1] . "\">"',
'!\·\$(?: |)\,(?: |)(\#[0-9A-Fa-f]{2,6}|[a-z]+)!' => '<span style="background-color:$1">',
'!\·\$([0-9]{1,3})(?: |),(?: |)([0-9]{1,3})!e' => '"<span style=\"color:#" . $this->dirty_colors[$1] . ";background-color:#" . $this->dirty_colors[$2] . "\">"',
'!\·\$([0-9]{1,3})!e' => '"<span style=\"color:" . $this->dirty_colors[$1] . "\">"',
'!\·\$(\#[0-9A-Fa-f]{2,6}|[a-z]+)!' => '<span style="color:$1">',
//rgb , not hex ·$(255,000,128) alone ...
'!\·\$(?: |),(?: |)(\([0-9]{1,3}\,[0-9]{1,3}\,[0-9]{1,3}\))!' => '<span style="background-color:rgb$1">',
'!\·\$(\([0-9]{1,3}\,[0-9]{1,3}\,[0-9]{1,3}\))(?: |),(?: |)(\([0-9]{1,3}\,[0-9]{1,3}\,[0-9]{1,3}\))!' => '<span style="color:rgb$1;background-color:rgb$2">',
'!\·\$(?: |)(\([0-9]{1,3}\,[0-9]{1,3}\,[0-9]{1,3}\))!' => '<span style="color:rgb$1">',
//at end , dirty solutions
'!\<span(.*?)\>(\s+)\<!ie' => '$this->clean_spaces(\'$2\', "$1")',
'!\<span(.*?)\>\s(\w)!i' => '<span$1> $2',
'!(\w)\s\<\/span\>!i' => '$1 </span>',
'!\·\$!' => '</span></span></span></span>', // ·$
);
/*
* clean_spaces
* for correct if nothing in span tag except spaces
* */
function clean_spaces($text, $style)
{
return '<span'.$style.'>' . str_replace(' ', ' ', $text).'<';
}
/*This function will complie codes and output it
*as msn. plus format ..
* */
function ps($text)
{
//nobody chalenge saanina !
//convert some chars to html
$text = str_replace('&', '&', htmlspecialchars($text,ENT_QUOTES));
//$text = str_replace(array('·','ε','σ','&'), array('·','ε','σ','&'),htmlentities($text, ENT_NOQUOTES)); // support only latin letters :( and with ( .., "UTF-8") also dosnt work
//smiles
$text = $this->replace_smiles($text);
//plus codes
$text = preg_replace('!\·\$([0-9]{1,3})(?: |)\,(?: |)\#!e', '"·$#" . $this->dirty_colors[$1] . ",#"', $text);//fixs
$text = preg_replace('!\·\$(\#[0-9A-Fa-f]{2,6})\,(?: |)([0-9]{1,3})!e', '"·$$1,#" . $this->dirty_colors[$2] . ""', $text);//fixs
$text = preg_replace_callback('!\[c\=(.*?)\](.*?)\[\/c\=(.*?)\]!is', array(&$this,"apply_color") , $text);
$text = preg_replace_callback('!\[c\=(.*?)\]!is', array(&$this,"apply_color") , $text);
$text = preg_replace_callback('!\[a\=(.*?)\](.*?)\[\/a\=(.*?)\]!is', array(&$this,"apply_background") , $text);
$text = preg_replace_callback('!\[a\=(.*?)\]!is', array(&$this,"apply_background") , $text);
$text = preg_replace(array_keys($this->codes), array_values($this->codes), $text);
return $this->close_dangling_tags($text);
}
/*Replace short text of smiles by images
*the default msn smiles
* */
function replace_smiles($text)
{
//smiles at last .. i m using loop for my specail reasons !
$smiles_match = $smiles_rep = array();
foreach($this->msn_smiles as $txt=>$img)
{
//space ! there, ok, do u know 'strpos' better than 'explode'
if(strpos($txt, ' ') !== false)
{
$txts = explode(' ', $txt);
foreach($txts as $t)
{
$smiles_match[] = "#" . preg_quote($t, '#') . "#m";
$smiles_rep[] = '<img src="' . $this->smiles_folder . $img . '" alt="' . str_replace('.gif', '', $img) . '" />';
}
}
else
{
$smiles_match[] = "#" . preg_quote($txt, '#') . "#m";
$smiles_rep[] = '<img src="' . $this->smiles_folder . $img . '" alt="' . str_replace('.gif', '', $img) . '" />';
}
}
//preg_replace faster as they said than str_replace !
return preg_replace($smiles_match, $smiles_rep, $text);
}
/*clean color and return it as hex one
* this function its not that fully one ...
* */
function return_good_color($color)
{
$color_is = '';
if(is_numeric($color) && strlen($color) < 5)
$color_is = '' . (!$this->dirty_colors[$color] ? $color : $this->dirty_colors[$color]);
else
$color_is = htmlspecialchars(str_replace('#', '',$color));
return $color_is;
}
/*The color of text in Plus done by many format ..
* this fucntion will know what color will be
* */
function apply_color($match)
{
$color1 = $this->return_good_color($match[1]);
$color2 = ($match[3]) ? $this->return_good_color($match[3]) : false;
if($color2 == false)
return '<span style="color:#' . $color1 .'">' . ($match[2] ? $match[2] . '</span>' : '');
else
return $this->grad($color1, $color2, $match[2]);
}
/*As color function but for backgrounds
* style css will change only !
* */
function apply_background($match)
{
$color1 = $this->return_good_color($match[1]);
$color2 = ($match[3]) ? $this->return_good_color($match[3]) : false;
if($color2 == false)
return '<span style="background-color:#' . $color1 .'">' . ($match[2] ? $match[2] . '</span>' : '');
else
return $this->grad($color1, $color2, $match[2], 'background-color');
}
/*Make grardient for text, i know its complicated feature but
*this function is the simplest way to know why i hate PLUS
* */
function grad($first_color, $second_color, $text, $span_style='color')
{
$text = str_replace(array(' '), array(' '), $text);//fix
$texts = $this->str_split_php4_utf8($text);
$text_length = sizeof($texts);
$r1 = hexdec(substr($first_color, 0, 2));
$g1 = hexdec(substr($first_color, 2, 2));
$b1 = hexdec(substr($first_color, 4, 2));
$res_r = ($r1 - hexdec(substr($second_color, 0, 2))) / ($text_length - 1);
$res_g = ($g1 - hexdec(substr($second_color, 2, 2))) / ($text_length - 1);
$res_b = ($b1 - hexdec(substr($second_color, 4, 2))) / ($text_length - 1);
$colors = array();
$return_text = '';
$h = $w = false;
foreach(range(0, $text_length) as $i)
{
//open tags
if(in_array($texts[$i], array('[','<')))
{
if($texts[$i] == '[')
{
$pos_h = strpos($text, ']');
if($pos_h === false && $pos_h-$i > 10 && $pos_h-$i < 1)
$h = false;
else
$h = true;
}
else
{
$pos_w = strpos($text, '>');
if($pos_w === false && $pos_w-$i > 10 && $pos_w-$i < 1)
$w = false;
else
$w = true;
}
}
//close tags
if($h == true && $texts[$i] != ']')
$return_text .= $texts[$i] == ' ' ? ' ' : $texts[$i];
else if($w == true && $texts[$i] != '>')
$return_text .= $texts[$i] == ' ' ? ' ' : $texts[$i];
else
{
if(in_array($texts[$i],array(']','>')))
{
$return_text .= $texts[$i] == ' ' ? ' ' : $texts[$i];
($texts[$i] == ']' ? $h = false : $w = false);
}
else
{
$colors['r'] = sprintf('%02x', floor($r1 - ($res_r*$i)));
$colors['g'] = sprintf('%02x', floor($g1 - ($res_g*$i)));
$colors['b'] = sprintf('%02x', floor($b1 - ($res_b*$i)));
$return_text .= $texts[$i] == ' ' ? ' ' : '<span style="' . $span_style . ':#' . implode(null,$colors) . '">' . $texts[$i] . '</span>';
}
}
}
return $return_text;
}
/*split text to letters in array !
* but in utf8 !
* code by :saeedco
* */
function str_split_php4_utf8($str)
{
$split=1;
$array = array();
for ($i=0; $i < strlen($str); )
{
$value = ord($str[$i]);
if($value > 127)
{
if($value >= 192 && $value <= 223)
$split=2;
elseif($value >= 224 && $value <= 239)
$split=3;
elseif($value >= 240 && $value <= 247)
$split=4;
}
else
{
$split=1;
}
$key = NULL;
for ($j = 0; $j < $split; $j++, $i++)
{
$key .= $str[$i];
}
array_push( $array, $key );
}
return $array;
}
/*
* Colse opened html tags .. before output it
* @code by jamiew , link : http://codesnippets.joyent.com/posts/show/959
*/
function close_dangling_tags($html)
{
#put all opened tags into an array
preg_match_all("#<([a-z]+)( .*)?(?!/)>#iU",$html,$result);
$openedtags=$result[1];
#put all closed tags into an array
preg_match_all("#</([a-z]+)>#iU",$html,$result);
$closedtags=$result[1];
$len_opened = count($openedtags);
# all tags are closed
if(count($closedtags) == $len_opened)
return $html;
$openedtags = array_reverse($openedtags);
# close tags
for($i=0;$i < $len_opened;$i++)
{
if (!in_array($openedtags[$i],$closedtags))
$html .= '</' . $openedtags[$i] . '>';
else
unset($closedtags[array_search($openedtags[$i], $closedtags)]);
}
return $html;
}
}
?>