offline
- Pridružio: 02 Mar 2008
- Poruke: 202
|
<?php
/**
* phpfreechat.class.php
*
* Copyright © 2006 Stephane Gully <stephane.gully@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
require_once dirname(__FILE__).'/pfccommand.class.php';
require_once dirname(__FILE__).'/pfcglobalconfig.class.php';
require_once dirname(__FILE__).'/pfcuserconfig.class.php';
require_once dirname(__FILE__).'/pfctemplate.class.php';
require_once dirname(__FILE__).'/../lib/utf8/utf8_substr.php';
require_once dirname(__FILE__).'/pfcresponse.class.php';
/**
* phpFreeChat is the entry point for developpers
*
* @example ../demo/demo1_simple.php
* @author Stephane Gully <stephane.gully@gmail.com>
*/
class phpFreeChat
{
function phpFreeChat( &$params )
{
if (!is_array($params))
die('phpFreeChat parameters must be an array');
// initialize the global config object
$c =& pfcGlobalConfig::Instance( $params );
// need to initiate the user config object here because it uses sessions
$u =& pfcUserConfig::Instance();
// this code is used to handle the AJAX call and build the response
if (isset($_REQUEST['pfc_ajax']))
{
$function = isset($_REQUEST['f']) ? $_REQUEST['f'] : '';
$cmd = isset($_REQUEST['cmd']) ? stripslashes($_REQUEST['cmd']) : '';
$r = null;
if ($function && method_exists($this,$function))
{
require_once dirname(__FILE__).'/pfcresponse.class.php';
$r =& $this->$function($cmd);
}
echo $r->getOutput();
die();
}
}
/**
* depreciated
*/
function printJavaScript( $return = false )
{
$output = '';
if ($return)
return $output;
else
echo $output;
}
/**
* depreciated
*/
function printStyle( $return = false )
{
$output = '';
if($return)
return $output;
else
echo $output;
}
/**
* printChat must be called somewhere in the page
* it inserts necessary html which will receive chat's data
* usage:
* <code>
* <?php $chat->printChat(); ?>
* </code>
*/
function printChat( $return = false )
{
$c =& pfcGlobalConfig::Instance();
$u =& pfcUserConfig::Instance();
$output = '';
if (count($c->getErrors()) > 0)
{
$output .= "<p>phpFreeChat cannot be initialized, please correct these errors:</p><ul>";
foreach( $c->getErrors() as $e ) $output .= "<li>".$e."</li>"; $output .= "</ul>";
}
else
{
pfcI18N::SwitchOutputEncoding($c->output_encoding);
$path = $c->getFilePathFromTheme('chat.js.tpl.php');
$t = new pfcTemplate($path);
$t->assignObject($u,"u");
$t->assignObject($c,"c");
$output .= $t->getOutput();
pfcI18N::SwitchOutputEncoding();
}
if($return)
return $output;
else
echo $output;
}
/**
* Encode special caracteres and remove extra slashes
*/
function FilterSpecialChar($str)
{
//$str = stripslashes($str);
// $str = addslashes($str);
$str = htmlspecialchars($str);
return $str;
}
/**
* Just check the nicknames doesn't start with spaces and is not longer than the max_nick_len
*/
function FilterNickname($nickname)
{
$c =& pfcGlobalConfig::Instance();
//$nickname = str_replace("\\", "", $nickname); // '\' is a forbidden charactere for nicknames
$nickname = trim($nickname);
$nickname = utf8_substr($nickname, 0, $c->max_nick_len);
return $nickname;
}
/**
* search/replace smileys
*/
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.'" />';
}
}
$query = substr($query, 0, strlen($query)-1);
$query .= ")/i";
$split_words = preg_split($query, $msg, -1, PREG_SPLIT_DELIM_CAPTURE);
$msg = "";
foreach($split_words as $word)
$msg .= preg_replace($search, $replace, $word);
return $msg;
}
/**
* Filter messages before they are sent to container
*/
function PreFilterMsg($msg)
{
$c =& pfcGlobalConfig::Instance();
if (preg_match("/^\[/i",$msg))
// add 25 characteres if the message starts with [ : means there is a bbcode
$msg = utf8_substr($msg, 0, $c->max_text_len+25);
else
$msg = utf8_substr($msg, 0, $c->max_text_len);
$msg = phpFreeChat::FilterSpecialChar($msg);
// $msg = phpFreeChat::FilterSmiley($msg);
/* if ($msg[0] == "\n") $msg = substr($msg, 1); */ // delete the first \n generated by FF
/* if (strpos($msg,"\n") > 0) $msg = "<br/>".$msg;
$msg = str_replace("\r\n", "<br/>", $msg);
$msg = str_replace("\n", "<br/>", $msg);
$msg = str_replace("\t", " ", $msg);*/
//$msg = str_replace(" ", " ", $msg);
// $msg = preg_replace('/(http\:\/\/[^\s]*)/i', "<a href=\"$1\">$1</a>", $msg );
return $msg;
}
/**
* Filter messages when they are recived from container
*/
function PostFilterMsg($msg)
{
//$c =& pfcGlobalConfig::Instance();
// $msg = preg_replace('/('.preg_quote($c->nick,'/').')/i', "<strong>$1</strong>", $msg );
$msg = preg_replace('/\n/i', "", $msg );
return $msg;
}
function &handleRequest($request)
{
$c =& pfcGlobalConfig::Instance();
$u =& pfcUserConfig::Instance();
if ($c->debug) ob_start(); // capture output
$xml_reponse =& new pfcResponse();
// check the command
$cmdstr = "";
$cmdname = "";
$clientid = "";
$recipient = "";
$recipientid = "";
$param = "";
$sender = "";
$res = pfcCommand::ParseCommand($request);
$cmdstr = isset($res['cmdstr']) ? $res['cmdstr'] : $request;
$cmdname = strtolower(isset($res['cmdname']) ? $res['cmdname'] : '');
$clientid = isset($res['params'][0]) ? $res['params'][0] : '';
$recipientid = isset($res['params'][1]) ? $res['params'][1] : "";
$params = array_slice(is_array($res['params']) ? $res['params'] : array() ,2);
$param = implode(" ",$params); // to keep compatibility (will be removed)
$sender = $u->getNickname();
// translate the recipientid to the channel name
if (isset($u->channels[$recipientid]))
{
$recipient = $u->channels[$recipientid]["recipient"];
}
if (isset($u->privmsg[$recipientid]))
{
$recipient = $u->privmsg[$recipientid]["recipient"];
// @todo: move this code in a proxy
if ($cmdname != "update" &&
$cmdname != "leave" && // do not open the pv tab when other user close the tab
$cmdname != "quit" &&
$cmdname != "privmsg2")
{
// alert the other from the new pv
// (warn other user that someone talk to him)
$ct =& pfcContainer::Instance();
$nickidtopv = $u->privmsg[$recipientid]["pvnickid"];
$cmdstr = 'privmsg2';
$cmdp = array();
$cmdp['param'] = $u->nickid;//$sender;
$cmdp['params'][] = $u->nickid;//$sender;
pfcCommand::AppendCmdToPlay($nickidtopv, $cmdstr, $cmdp);
}
}
$cmdp = array();
$cmdp["clientid"] = $clientid;
$cmdp["sender"] = $sender;
$cmdp["recipient"] = $recipient;
$cmdp["recipientid"] = $recipientid;
// before playing the wanted command
// play the found commands into the meta 'cmdtoplay'
pfcCommand::RunPendingCmdToPlay($u->nickid, $cmdp, $xml_reponse);
// play the wanted command
$cmd =& pfcCommand::Factory($cmdname);
$cmdp["param"] = $param;
$cmdp["params"] = $params;
if ($cmd != NULL)
{
// call the command
if ($c->debug)
$cmd->run($xml_reponse, $cmdp);
else
@$cmd->run($xml_reponse, $cmdp);
}
else
{
$cmd =& pfcCommand::Factory("error");
$cmdp = array();
$cmdp["clientid"] = $clientid;
$cmdp["param"] = _pfc("Unknown command [%s]",stripslashes("/".$cmdname." ".$param));
$cmdp["sender"] = $sender;
$cmdp["recipient"] = $recipient;
$cmdp["recipientid"] = $recipientid;
if ($c->debug)
$cmd->run($xml_reponse, $cmdp);
else
@$cmd->run($xml_reponse, $cmdp);
}
// do not update twice
// do not update when the user just quit
if ($cmdname != "update" &&
$cmdname != "quit" &&
$u->nickid != '')
{
// force an update just after a command is sent
// thus the message user just poster is really fastly displayed
$cmd =& pfcCommand::Factory("update");
$cmdp = array();
$cmdp["clientid"] = $clientid;
$cmdp["param"] = $param;
$cmdp["sender"] = $sender;
$cmdp["recipient"] = $recipient;
$cmdp["recipientid"] = $recipientid;
if ($c->debug)
$cmd->run($xml_reponse, $cmdp);
else
@$cmd->run($xml_reponse, $cmdp);
}
if ($c->debug)
{
// capture echoed content
// if a content not empty is captured it is a php error in the code
$data = ob_get_contents();
if ($data != "")
{
// todo : display the $data somewhere to warn the user
}
ob_end_clean();
}
// do nothing else if the xml response is empty in order to save bandwidth
if ($xml_reponse->getCommandCount() == 0) die();
return $xml_reponse;
}
function &loadStyles($theme = 'default', &$xml_reponse)
{
if ($xml_reponse == null) $xml_reponse =& new pfcResponse();
$c =& pfcGlobalConfig::Instance();
// do not overload the theme parameter as long as
// the ajax request do not give the correct one
// $c->theme = $theme;
$u =& pfcUserConfig::Instance();
$js = '';//file_get_contents(dirname(__FILE__).'/client/createstylerule.js');
$js .= 'var c = $H();';
$path = $c->getFilePathFromTheme('style.css.php');
require_once dirname(__FILE__).'/../lib/ctype/ctype.php'; // to keep compatibility for php without ctype support
require_once dirname(__FILE__).'/../lib/csstidy-1.2/class.csstidy.php';
$css = new csstidy();
$css->set_cfg('preserve_css',false);
$css_code = '';
$t = new pfcTemplate();
$t->assignObject($u,"u");
$t->assignObject($c,"c");
if (!$c->isDefaultFile('style.css.php'))
{
$t->setTemplate($c->theme_default_path.'/default/style.css.php');
$css_code .= $t->getOutput();
}
$t->setTemplate($c->getFilePathFromTheme('style.css.php'));
$css_code .= $t->getOutput();
$css->parse($css_code);
foreach($css->css as $k => $v)
{
foreach($v as $k2 => $v2)
{
$rules = '';
foreach($v2 as $k3 => $v3)
$rules .= $k3.':'.$v3.';';
$js .= "c.set('".$k2."', '".str_replace("\n", "", $rules)."');\n";
}
}
$js .= "var pfccss = new pfcCSS(); var k = c.keys(); c.each(function (a) { pfccss.applyRule(a[0],a[1]); });";
$xml_reponse->script($js);
return $xml_reponse;
}
function &loadScripts($theme, &$xml_reponse)
{
if ($xml_reponse == null) $xml_reponse =& new pfcResponse();
$c =& pfcGlobalConfig::Instance();
$js = '';
// load customize.js.php
$path = $c->getFilePathFromTheme('customize.js.php');
$t = new pfcTemplate($path);
$t->assignObject($c,"c");
$js .= $t->getOutput();
// load translations
require_once dirname(__FILE__).'/pfcjson.class.php';
$json = new pfcJSON();
$labels_to_load =
array( "Do you really want to leave this room ?", // _pfc
"Are you sure you want to close this tab ?", // _pfc
"Hide nickname marker", // _pfc
"Show nickname marker", // _pfc
"Hide dates and hours", // _pfc
"Show dates and hours", // _pfc
"Disconnect", // _pfc
"Connect", // _pfc
"Magnify", // _pfc
"Cut down", // _pfc
"Hide smiley box", // _pfc
"Show smiley box", // _pfc
"Hide online users box", // _pfc
"Show online users box", // _pfc
"Please enter your nickname", // _pfc
"Private message", // _pfc
"Close this tab", // _pfc
"Enter your message here", // _pfc
"Enter your nickname here", // _pfc
"Bold", // _pfc
"Italics", // _pfc
"Underline", // _pfc
"Delete", // _pfc
"Mail", // _pfc
"Color", // _pfc
"PHP FREE CHAT [powered by phpFreeChat-%s]", // _pfc
"Enter the text to format", // _pfc
"Configuration has been rehashed", // _pfc
"A problem occurs during rehash", // _pfc
"Chosen nickname is already used", // _pfc
"phpfreechat current version is %s", // _pfc
"Maximum number of joined channels has been reached", // _pfc
"Maximum number of private chat has been reached", // _pfc
"Click here to send your message", // _pfc
"Send", // _pfc
"You are not allowed to speak to yourself", // _pfc
"Close", // _pfc
"Chosen nickname is not allowed", // _pfc
"Enable sound notifications", // _pfc
"Disable sound notifications", // _pfc
"Input Required", // _pfc
"OK", // _pfc
"Cancel", // _pfc
"You are trying to speak to a unknown (or not connected) user", // _pfc
);
foreach($labels_to_load as $l)
{
$js .= "pfc.res.setLabel(".$json->encode($l).",".$json->encode(_pfc2($l)).");\n";
}
// load ressources
$fileurl_to_load =
array( 'images/ch.gif',
'images/pv.gif',
'images/tab_remove.gif',
'images/ch-active.gif',
'images/pv-active.gif',
'images/user.gif',
'images/user-me.gif',
'images/user_female.gif',
'images/user_female-me.gif',
'images/color-on.gif',
'images/color-off.gif',
'images/clock-on.gif',
'images/clock-off.gif',
'images/logout.gif',
'images/login.gif',
'images/maximize.gif',
'images/minimize.gif',
'images/smiley-on.gif',
'images/smiley-off.gif',
'images/online-on.gif',
'images/online-off.gif',
'images/bt_strong.gif',
'images/bt_em.gif',
'images/bt_ins.gif',
'images/bt_del.gif',
'images/bt_mail.gif',
'images/bt_color.gif',
'images/color_transparent.gif',
'images/close-whoisbox.gif',
'images/openpv.gif',
'images/user-admin.gif',
'images/sound-on.gif',
'images/sound-off.gif',
'sound.swf',
);
foreach($fileurl_to_load as $f)
{
$js .= "pfc.res.setFileUrl(".$json->encode($f).",\"".$c->getFileUrlFromTheme($f)."\");\n";
}
foreach($c->smileys as $s_file => $s_str) {
for($j = 0; $j<count($s_str) ; $j++) {
$js .= "pfc.res.setSmiley(".$json->encode($s_str[$j]).",\"".$c->getFileUrlFromTheme($s_file)."\");\n";
}
}
$js .= '
pfc.gui.loadSmileyBox();
pfc.gui.loadBBCodeColorList();
pfc.connectListener();
pfc.refreshGUI();
if (pfc_connect_at_startup) pfc.connect_disconnect();
';
$xml_reponse->script($js);
return $xml_reponse;
}
function loadInterface($theme = 'default', &$xml_reponse)
{
if ($xml_reponse == null) $xml_reponse =& new pfcResponse();
$c =& pfcGlobalConfig::Instance();
// do not overload the theme parameter as long as
// the ajax request do not give the correct one
// $c->theme = $theme;
$u =& pfcUserConfig::Instance();
$html = '';
// pfcI18N::SwitchOutputEncoding($c->output_encoding);
$path = $c->getFilePathFromTheme('chat.html.tpl.php');
$t = new pfcTemplate($path);
$t->assignObject($u,"u");
$t->assignObject($c,"c");
$html .= $t->getOutput();
// pfcI18N::SwitchOutputEncoding();
$xml_reponse->remove('pfc_loader'); // to hide the loading box
$xml_reponse->update('pfc_container', $html);
return $xml_reponse;
}
function &loadChat($theme = 'default')
{
$xml_reponse =& new pfcResponse();
$this->loadInterface($theme,$xml_reponse);
$this->loadStyles($theme,$xml_reponse);
$this->loadScripts($theme,$xml_reponse);
return $xml_reponse;
}
}
?>
|