Apply new codding style

This commit is contained in:
Dmitriy Simushev 2014-01-28 14:02:58 +00:00
parent 41f1e0a3bc
commit 42ff39f4d9
119 changed files with 10773 additions and 10241 deletions

View File

@ -24,43 +24,48 @@ require_once(dirname(__FILE__).'/libs/init.php');
require_once(MIBEW_FS_ROOT . '/libs/chat.php'); require_once(MIBEW_FS_ROOT . '/libs/chat.php');
require_once(MIBEW_FS_ROOT . '/libs/operator.php'); require_once(MIBEW_FS_ROOT . '/libs/operator.php');
require_once(MIBEW_FS_ROOT . '/libs/groups.php'); require_once(MIBEW_FS_ROOT . '/libs/groups.php');
require_once(MIBEW_FS_ROOT . '/libs/track.php');
$referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ""; $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : "";
if ($referer && isset($_SESSION['threadid'])) { if ($referer && isset($_SESSION['threadid'])) {
$thread = Thread::load($_SESSION['threadid']); $thread = Thread::load($_SESSION['threadid']);
if ($thread && $thread->state != Thread::STATE_CLOSED) { if ($thread && $thread->state != Thread::STATE_CLOSED) {
$msg = getstring2_("chat.client.visited.page", array($referer), $thread->locale); $msg = getstring2_(
"chat.client.visited.page",
array($referer),
$thread->locale
);
$thread->postMessage(Thread::KIND_FOR_AGENT, $msg); $thread->postMessage(Thread::KIND_FOR_AGENT, $msg);
} }
} }
$image = verifyparam(isset($_GET['image']) ? "image" : "i", "/^\w+$/", "mibew"); $image = verify_param(isset($_GET['image']) ? "image" : "i", "/^\w+$/", "mibew");
$lang = verifyparam(isset($_GET['language']) ? "language" : "lang", "/^[\w-]{2,5}$/", ""); $lang = verify_param(isset($_GET['language']) ? "language" : "lang", "/^[\w-]{2,5}$/", "");
if (!$lang || !locale_exists($lang)) { if (!$lang || !locale_exists($lang)) {
$lang = CURRENT_LOCALE; $lang = CURRENT_LOCALE;
} }
$groupid = verifyparam( "group", "/^\d{1,8}$/", ""); $group_id = verify_param("group", "/^\d{1,8}$/", "");
if($groupid) { if ($group_id) {
if (Settings::get('enablegroups') == '1') { if (Settings::get('enablegroups') == '1') {
$group = group_by_id($groupid); $group = group_by_id($group_id);
if (!$group) { if (!$group) {
$groupid = ""; $group_id = "";
} }
} else { } else {
$groupid = ""; $group_id = "";
} }
} }
$image_postfix = has_online_operators($groupid) ? "on" : "off"; $image_postfix = has_online_operators($group_id) ? "on" : "off";
$filename = "locales/${lang}/button/${image}_${image_postfix}.gif"; $file_name = "locales/${lang}/button/${image}_${image_postfix}.gif";
$fp = fopen($filename, 'rb') or die("no image"); $fp = fopen($file_name, 'rb') or die("no image");
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: no-store, no-cache, must-revalidate");
header("Pragma: no-cache"); header("Pragma: no-cache");
header("Content-Type: image/gif"); header("Content-Type: image/gif");
header("Content-Length: ".filesize($filename)); header("Content-Length: " . filesize($file_name));
if (function_exists('fpassthru')) { if (function_exists('fpassthru')) {
@fpassthru($fp); @fpassthru($fp);
} else { } else {
@ -70,5 +75,3 @@ if(function_exists('fpassthru')){
} }
fclose($fp); fclose($fp);
} }
exit;
?>

View File

@ -16,5 +16,3 @@
*/ */
require_once(dirname(__FILE__) . '/b.php'); require_once(dirname(__FILE__) . '/b.php');
exit;
?>

View File

@ -18,9 +18,6 @@
require_once(dirname(__FILE__) . '/libs/init.php'); require_once(dirname(__FILE__) . '/libs/init.php');
require_once(MIBEW_FS_ROOT . '/libs/captcha.php'); require_once(MIBEW_FS_ROOT . '/libs/captcha.php');
$captchaCode = gen_captcha(); $captcha_code = gen_captcha();
$_SESSION["mibew_captcha"] = $captchaCode; $_SESSION["mibew_captcha"] = $captcha_code;
draw_captcha($captchaCode); draw_captcha($captcha_code);
exit;
?>

View File

@ -54,7 +54,7 @@ if (get_remote_level($_SERVER['HTTP_USER_AGENT']) == 'old') {
exit; exit;
} }
$action = verifyparam("act", "/^(invitation|mailthread)$/", "default"); $action = verify_param("act", "/^(invitation|mailthread)$/", "default");
if ($action == 'invitation' && Settings::get('enabletracking')) { if ($action == 'invitation' && Settings::get('enabletracking')) {
// Check if user invited to chat // Check if user invited to chat
@ -76,7 +76,7 @@ if ($action == 'invitation' && Settings::get('enabletracking')) {
if (!isset($_GET['token']) || !isset($_GET['thread'])) { if (!isset($_GET['token']) || !isset($_GET['thread'])) {
$thread = NULL; $thread = null;
if (isset($_SESSION['threadid'])) { if (isset($_SESSION['threadid'])) {
$thread = Thread::reopen($_SESSION['threadid']); $thread = Thread::reopen($_SESSION['threadid']);
} }
@ -84,33 +84,31 @@ if( !isset($_GET['token']) || !isset($_GET['thread']) ) {
if (!$thread) { if (!$thread) {
// Load group info // Load group info
$groupid = ""; $group_id = "";
$groupname = ""; $group_name = "";
$group = NULL; $group = null;
if (Settings::get('enablegroups') == '1') { if (Settings::get('enablegroups') == '1') {
$groupid = verifyparam( "group", "/^\d{1,8}$/", ""); $group_id = verify_param("group", "/^\d{1,8}$/", "");
if($groupid) { if ($group_id) {
$group = group_by_id($groupid); $group = group_by_id($group_id);
if (!$group) { if (!$group) {
$groupid = ""; $group_id = "";
} else { } else {
$groupname = get_group_name($group); $group_name = get_group_name($group);
} }
} }
} }
// Get operator code // Get operator code
$operator_code = empty($_GET['operator_code']) $operator_code = empty($_GET['operator_code']) ? '' : $_GET['operator_code'];
? ''
: $_GET['operator_code'];
if (!preg_match("/^[A-z0-9_]+$/", $operator_code)) { if (!preg_match("/^[A-z0-9_]+$/", $operator_code)) {
$operator_code = false; $operator_code = false;
} }
// Get visitor info // Get visitor info
$visitor = visitor_from_request(); $visitor = visitor_from_request();
$info = getgetparam('info'); $info = get_get_param('info');
$email = getgetparam('email'); $email = get_get_param('email');
// Get referrer // Get referrer
$referrer = isset($_GET['url']) $referrer = isset($_GET['url'])
@ -122,14 +120,14 @@ if( !isset($_GET['token']) || !isset($_GET['thread']) ) {
} }
// Check if there are online operators // Check if there are online operators
if(!has_online_operators($groupid)) { if (!has_online_operators($group_id)) {
// Display leave message page // Display leave message page
$page = array_merge_recursive( $page = array_merge_recursive(
setup_logo($group), setup_logo($group),
setup_leavemessage( setup_leavemessage(
$visitor['name'], $visitor['name'],
$email, $email,
$groupid, $group_id,
$info, $info,
$referrer $referrer
) )
@ -154,14 +152,17 @@ if( !isset($_GET['token']) || !isset($_GET['thread']) ) {
} }
// Check if survey should be displayed // Check if survey should be displayed
if(Settings::get('enablepresurvey') == '1' if (Settings::get('enablepresurvey') == '1' && !$visitor_is_invited && !$requested_operator) {
&& !$visitor_is_invited
&& !$requested_operator
) {
// Display prechat survey // Display prechat survey
$page = array_merge_recursive( $page = array_merge_recursive(
setup_logo($group), setup_logo($group),
setup_survey($visitor['name'], $email, $groupid, $info, $referrer) setup_survey(
$visitor['name'],
$email,
$group_id,
$info,
$referrer
)
); );
$page['surveyOptions'] = json_encode($page['survey']); $page['surveyOptions'] = json_encode($page['survey']);
$chat_style->render('chat', $page); $chat_style->render('chat', $page);
@ -169,19 +170,29 @@ if( !isset($_GET['token']) || !isset($_GET['thread']) ) {
} }
// Start chat thread // Start chat thread
$thread = chat_start_for_user($groupid, $requested_operator, $visitor['id'], $visitor['name'], $referrer, $info); $thread = chat_start_for_user(
$group_id,
$requested_operator,
$visitor['id'],
$visitor['name'],
$referrer,
$info
);
} }
$threadid = $thread->id; $thread_id = $thread->id;
$token = $thread->lastToken; $token = $thread->lastToken;
$chatstyle = verifyparam( "style", "/^\w+$/", ""); $chat_style_name = verify_param("style", "/^\w+$/", "");
header("Location: " . MIBEW_WEB_ROOT . "/client.php?thread=" . intval($threadid) . "&token=" . urlencode($token) . ($chatstyle ? "&style=" . urlencode($chatstyle) : "")); $redirect_to = MIBEW_WEB_ROOT . "/client.php?thread=" . intval($thread_id)
. "&token=" . urlencode($token)
. ($chat_style_name ? "&style=" . urlencode($chat_style_name) : "");
header("Location: " . $redirect_to);
exit; exit;
} }
$token = verifyparam( "token", "/^\d{1,8}$/"); $token = verify_param("token", "/^\d{1,8}$/");
$threadid = verifyparam( "thread", "/^\d{1,8}$/"); $thread_id = verify_param("thread", "/^\d{1,8}$/");
$thread = Thread::load($threadid, $token); $thread = Thread::load($thread_id, $token);
if (!$thread) { if (!$thread) {
die("wrong thread"); die("wrong thread");
} }
@ -196,5 +207,3 @@ if($action == "mailthread") {
// Expand page // Expand page
$chat_style->render('chat', $page); $chat_style->render('chat', $page);
} }
?>

View File

@ -22,6 +22,7 @@ use Mibew\Settings;
// Initialize libraries // Initialize libraries
require_once(dirname(__FILE__) . '/libs/init.php'); require_once(dirname(__FILE__) . '/libs/init.php');
require_once(MIBEW_FS_ROOT . '/libs/track.php'); require_once(MIBEW_FS_ROOT . '/libs/track.php');
require_once(MIBEW_FS_ROOT . '/libs/chat.php');
require_once(MIBEW_FS_ROOT . '/libs/statistics.php'); require_once(MIBEW_FS_ROOT . '/libs/statistics.php');
require_once(MIBEW_FS_ROOT . '/libs/cron.php'); require_once(MIBEW_FS_ROOT . '/libs/cron.php');
@ -54,5 +55,3 @@ if (! $quiet) {
// TODO: May be localize it // TODO: May be localize it
echo('All cron jobs done.'); echo('All cron jobs done.');
} }
?>

View File

@ -16,6 +16,3 @@
*/ */
header("Location: operator/index.php"); header("Location: operator/index.php");
exit;
?>

View File

@ -36,6 +36,8 @@ define('MIBEW_WEB_ROOT', $mibewroot);
// Include common functions // Include common functions
require_once(MIBEW_FS_ROOT.'/libs/common/constants.php'); require_once(MIBEW_FS_ROOT.'/libs/common/constants.php');
require_once(MIBEW_FS_ROOT.'/libs/common/verification.php');
require_once(MIBEW_FS_ROOT.'/libs/common/converter.php');
require_once(MIBEW_FS_ROOT.'/libs/common/locale.php'); require_once(MIBEW_FS_ROOT.'/libs/common/locale.php');
require_once(MIBEW_FS_ROOT.'/libs/common/misc.php'); require_once(MIBEW_FS_ROOT.'/libs/common/misc.php');
require_once(MIBEW_FS_ROOT.'/libs/common/response.php'); require_once(MIBEW_FS_ROOT.'/libs/common/response.php');
@ -48,7 +50,7 @@ function runsql($query, $link)
return $res; return $res;
} }
$act = verifyparam("act", "/^(silentcreateall|createdb|ct|dt|addcolumns)$/"); $act = verify_param("act", "/^(silentcreateall|createdb|ct|dt|addcolumns)$/");
$link = @mysql_connect($mysqlhost, $mysqllogin, $mysqlpass) $link = @mysql_connect($mysqlhost, $mysqllogin, $mysqlpass)
or show_install_err('Could not connect: ' . mysql_error()); or show_install_err('Could not connect: ' . mysql_error());

View File

@ -48,6 +48,8 @@ define('MIBEW_WEB_ROOT', $base_url);
// Include common functions // Include common functions
require_once(MIBEW_FS_ROOT.'/libs/common/constants.php'); require_once(MIBEW_FS_ROOT.'/libs/common/constants.php');
require_once(MIBEW_FS_ROOT.'/libs/common/verification.php');
require_once(MIBEW_FS_ROOT.'/libs/common/converter.php');
require_once(MIBEW_FS_ROOT.'/libs/common/locale.php'); require_once(MIBEW_FS_ROOT.'/libs/common/locale.php');
require_once(MIBEW_FS_ROOT.'/libs/common/misc.php'); require_once(MIBEW_FS_ROOT.'/libs/common/misc.php');
require_once(MIBEW_FS_ROOT.'/libs/common/response.php'); require_once(MIBEW_FS_ROOT.'/libs/common/response.php');
@ -307,7 +309,7 @@ function add_canned_messages($link){
foreach (get_available_locales() as $locale) { foreach (get_available_locales() as $locale) {
if (! in_array($locale, $existlocales)) { if (! in_array($locale, $existlocales)) {
foreach (explode("\n", getstring_('chat.predefined_answers', $locale)) as $answer) { foreach (explode("\n", getstring_('chat.predefined_answers', $locale)) as $answer) {
$result[] = array('locale' => $locale, 'vctitle' => cutstring($answer, 97, '...'), 'vcvalue' => $answer); $result[] = array('locale' => $locale, 'vctitle' => cut_string($answer, 97, '...'), 'vcvalue' => $answer);
} }
} }
} }

View File

@ -18,18 +18,19 @@
// Import namespaces and classes of the core // Import namespaces and classes of the core
use Mibew\Database; use Mibew\Database;
function load_canned_messages($locale, $groupid) function load_canned_messages($locale, $group_id)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
$values = array(':locale' => $locale); $values = array(':locale' => $locale);
if ($groupid) { if ($group_id) {
$values[':groupid'] = $groupid; $values[':groupid'] = $group_id;
} }
return $db->query( return $db->query(
"select id, vctitle, vcvalue from {chatresponses} " . ("SELECT id, vctitle, vcvalue FROM {chatresponses} "
"where locale = :locale AND (" . . "WHERE locale = :locale AND ("
($groupid ? "groupid = :groupid" : "groupid is NULL OR groupid = 0") . . ($group_id ? "groupid = :groupid" : "groupid is NULL OR groupid = 0")
") order by vcvalue", . ") ORDER BY vcvalue"),
$values, $values,
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
@ -39,10 +40,11 @@ function load_canned_message($key)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
$result = $db->query( $result = $db->query(
"select vctitle, vcvalue from {chatresponses} where id = ?", "SELECT vctitle, vcvalue FROM {chatresponses} WHERE id = ?",
array($key), array($key),
array('return_rows' => Database::RETURN_ONE_ROW) array('return_rows' => Database::RETURN_ONE_ROW)
); );
return $result ? $result : null; return $result ? $result : null;
} }
@ -50,24 +52,22 @@ function save_canned_message($key, $title, $message)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
$db->query( $db->query(
"update {chatresponses} set vcvalue = ?, vctitle = ? where id = ?", "UPDATE {chatresponses} SET vcvalue = ?, vctitle = ? WHERE id = ?",
array($message, $title, $key) array($message, $title, $key)
); );
} }
function add_canned_message($locale, $groupid, $title, $message) function add_canned_message($locale, $group_id, $title, $message)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
$db->query( $db->query(
"insert into {chatresponses} (locale,groupid,vctitle,vcvalue) " . ("INSERT INTO {chatresponses} (locale,groupid,vctitle,vcvalue) "
"values (?, ?, ?, ?)", . "VALUES (?, ?, ?, ?)"),
array( array(
$locale, $locale,
($groupid ? $groupid : "null"), ($group_id ? $group_id : "null"),
$title, $title,
$message $message,
) )
); );
} }
?>

View File

@ -27,12 +27,12 @@ function gen_captcha()
for ($i = 0; $i < 5; $i++) { for ($i = 0; $i < 5; $i++) {
$string .= substr($symbols, mt_rand(0, strlen($symbols)), 1); $string .= substr($symbols, mt_rand(0, strlen($symbols)), 1);
} }
return $string; return $string;
} }
function draw_captcha($security_code) function draw_captcha($security_code)
{ {
//Set the image width and height //Set the image width and height
$width = 100; $width = 100;
$height = 25; $height = 25;
@ -71,5 +71,3 @@ function draw_captcha($security_code)
//Free up resources //Free up resources
ImageDestroy($image); ImageDestroy($image);
} }
?>

View File

@ -22,13 +22,9 @@ use Mibew\Thread;
use Mibew\Style\ChatStyle; use Mibew\Style\ChatStyle;
use Mibew\Style\PageStyle; use Mibew\Style\PageStyle;
// Initialize libraries
require_once(MIBEW_FS_ROOT.'/libs/track.php');
/** /**
* Names for chat-related cookies * Names for chat-related cookies
*/ */
define('USERID_COOKIE_NAME', 'MIBEW_UserID'); define('USERID_COOKIE_NAME', 'MIBEW_UserID');
define('USERNAME_COOKIE_NAME', 'MIBEW_Data'); define('USERNAME_COOKIE_NAME', 'MIBEW_Data');
@ -36,10 +32,11 @@ function message_to_text($msg)
{ {
$message_time = date("H:i:s ", $msg['created']); $message_time = date("H:i:s ", $msg['created']);
if ($msg['kind'] == Thread::KIND_USER || $msg['kind'] == Thread::KIND_AGENT) { if ($msg['kind'] == Thread::KIND_USER || $msg['kind'] == Thread::KIND_AGENT) {
if ($msg['name']) if ($msg['name']) {
return $message_time . $msg['name'] . ": " . $msg['message'] . "\n"; return $message_time . $msg['name'] . ": " . $msg['message'] . "\n";
else } else {
return $message_time . $msg['message'] . "\n"; return $message_time . $msg['message'] . "\n";
}
} elseif ($msg['kind'] == Thread::KIND_INFO) { } elseif ($msg['kind'] == Thread::KIND_INFO) {
return $message_time . $msg['message'] . "\n"; return $message_time . $msg['message'] . "\n";
} else { } else {
@ -47,55 +44,64 @@ function message_to_text($msg)
} }
} }
function get_user_name($username, $addr, $id) function get_user_name($user_name, $addr, $id)
{ {
return str_replace( return str_replace(
"{addr}", $addr, "{addr}",
$addr,
str_replace( str_replace(
"{id}", $id, "{id}",
str_replace("{name}", $username, Settings::get('usernamepattern')) $id,
str_replace("{name}", $user_name, Settings::get('usernamepattern'))
) )
); );
} }
function is_ajax_browser($browserid, $ver, $useragent) function is_ajax_browser($browser_id, $ver, $user_agent)
{ {
if ($browserid == "opera") if ($browser_id == "opera") {
return $ver >= 8.02; return $ver >= 8.02;
if ($browserid == "safari") }
if ($browser_id == "safari") {
return $ver >= 125; return $ver >= 125;
if ($browserid == "msie") }
return $ver >= 5.5 && !strstr($useragent, "powerpc"); if ($browser_id == "msie") {
if ($browserid == "netscape") return $ver >= 5.5 && !strstr($user_agent, "powerpc");
}
if ($browser_id == "netscape") {
return $ver >= 7.1; return $ver >= 7.1;
if ($browserid == "mozilla") }
if ($browser_id == "mozilla") {
return $ver >= 1.4; return $ver >= 1.4;
if ($browserid == "firefox") }
if ($browser_id == "firefox") {
return $ver >= 1.0; return $ver >= 1.0;
if ($browserid == "chrome") }
if ($browser_id == "chrome") {
return true; return true;
}
return false; return false;
} }
function get_remote_level($useragent) function get_remote_level($user_agent)
{ {
$known_agents = get_known_user_agents(); $known_agents = get_known_user_agents();
$useragent = strtolower($useragent); $user_agent = strtolower($user_agent);
foreach ($known_agents as $agent) { foreach ($known_agents as $agent) {
if (strstr($useragent, $agent)) { if (strstr($user_agent, $agent)) {
if (preg_match("/" . $agent . "[\\s\/]?(\\d+(\\.\\d+)?)/", $useragent, $matches)) { if (preg_match("/" . $agent . "[\\s\/]?(\\d+(\\.\\d+)?)/", $user_agent, $matches)) {
$ver = $matches[1]; $ver = $matches[1];
if (is_ajax_browser($agent, $ver, $useragent)) { if (is_ajax_browser($agent, $ver, $user_agent)) {
return "ajaxed"; return "ajaxed";
} else { } else {
return "old"; return "old";
} }
}
}
}
}
}
}
return "ajaxed"; return "ajaxed";
} }
@ -104,7 +110,8 @@ function get_remote_level($useragent)
* *
* @return array List of known user agents * @return array List of known user agents
*/ */
function get_known_user_agents() { function get_known_user_agents()
{
return array( return array(
"opera", "opera",
"msie", "msie",
@ -112,34 +119,38 @@ function get_known_user_agents() {
"safari", "safari",
"firefox", "firefox",
"netscape", "netscape",
"mozilla" "mozilla",
); );
} }
function is_agent_opera95() function is_agent_opera95()
{ {
$useragent = strtolower($_SERVER['HTTP_USER_AGENT']); $user_agent = strtolower($_SERVER['HTTP_USER_AGENT']);
if (strstr($useragent, "opera")) { if (strstr($user_agent, "opera")) {
if (preg_match("/opera[\\s\/]?(\\d+(\\.\\d+)?)/", $useragent, $matches)) { if (preg_match("/opera[\\s\/]?(\\d+(\\.\\d+)?)/", $user_agent, $matches)) {
$ver = $matches[1]; $ver = $matches[1];
if ($ver >= "9.5") if ($ver >= "9.5") {
return true; return true;
} }
} }
}
return false; return false;
} }
function is_mac_opera() function is_mac_opera()
{ {
$useragent = strtolower($_SERVER['HTTP_USER_AGENT']); $user_agent = strtolower($_SERVER['HTTP_USER_AGENT']);
return strstr($useragent, "opera") && strstr($useragent, "mac");
return strstr($user_agent, "opera") && strstr($user_agent, "mac");
} }
function needsFramesrc() function needs_frame_src()
{ {
$useragent = strtolower($_SERVER['HTTP_USER_AGENT']); $user_agent = strtolower($_SERVER['HTTP_USER_AGENT']);
return strstr($useragent, "safari/");
return strstr($user_agent, "safari/");
} }
/** /**
@ -148,24 +159,28 @@ function needsFramesrc()
* @param array $group Group info * @param array $group Group info
* @return array Array of logo data * @return array Array of logo data
*/ */
function setup_logo($group = NULL) { function setup_logo($group = null)
{
$data = array(); $data = array();
$top_level_group = (!$group) ? array() : get_top_level_group($group);
$toplevelgroup = (!$group)?array():get_top_level_group($group); $group_name = empty($top_level_group['vctitle'])
? Settings::get('title')
: $top_level_group['vctitle'];
$logo = empty($top_level_group['vclogo'])
? Settings::get('logo')
: $top_level_group['vclogo'];
$mibew_host = empty($top_level_group['vchosturl'])
? Settings::get('hosturl')
: $top_level_group['vchosturl'];
$data['company'] = array( $data['company'] = array(
'name' => topage(empty($toplevelgroup['vctitle']) 'name' => to_page($group_name),
? Settings::get('title') 'chatLogoURL' => to_page($logo),
: $toplevelgroup['vctitle']),
'chatLogoURL' => topage(empty($toplevelgroup['vclogo'])
? Settings::get('logo')
: $toplevelgroup['vclogo'])
); );
$data['mibewHost'] = to_page($mibew_host);
$data['mibewHost'] = topage(empty($toplevelgroup['vchosturl'])
? Settings::get('hosturl')
: $toplevelgroup['vchosturl']);
return $data; return $data;
} }
@ -174,16 +189,15 @@ function setup_logo($group = NULL) {
* Prepare values common for chat, prechat survey form and leave message form. * Prepare values common for chat, prechat survey form and leave message form.
* @return array * @return array
*/ */
function prepare_chat_app_data() { function prepare_chat_app_data()
{
$data = array(); $data = array();
// Set enter key shortcut // Set enter key shortcut
if (Settings::get('sendmessagekey') == 'enter') { if (Settings::get('sendmessagekey') == 'enter') {
$data['send_shortcut'] = "Enter"; $data['send_shortcut'] = "Enter";
} else { } else {
$data['send_shortcut'] = is_mac_opera() $data['send_shortcut'] = is_mac_opera() ? "&#8984;-Enter" : "Ctrl-Enter";
? "&#8984;-Enter"
: "Ctrl-Enter";
} }
// Set refresh frequency // Set refresh frequency
@ -194,7 +208,7 @@ function prepare_chat_app_data() {
'email.required' => no_field("form.field.email"), 'email.required' => no_field("form.field.email"),
'name.required' => no_field("form.field.name"), 'name.required' => no_field("form.field.name"),
'message.required' => no_field("form.field.message"), 'message.required' => no_field("form.field.message"),
'wrong.email' => wrong_field("form.field.email") 'wrong.email' => wrong_field("form.field.email"),
); );
return $data; return $data;
@ -210,7 +224,8 @@ function prepare_chat_app_data() {
* @param string $referrer URL of referrer page * @param string $referrer URL of referrer page
* @return array Array of leave message form data * @return array Array of leave message form data
*/ */
function setup_leavemessage($name, $email, $group_id, $info, $referrer) { function setup_leavemessage($name, $email, $group_id, $info, $referrer)
{
$data = prepare_chat_app_data(); $data = prepare_chat_app_data();
// Load JavaScript plugins and JavaScripts, CSS files required by them // Load JavaScript plugins and JavaScripts, CSS files required by them
@ -226,14 +241,13 @@ function setup_leavemessage($name, $email, $group_id, $info, $referrer) {
} }
$data['leaveMessage']['leaveMessageForm'] = array( $data['leaveMessage']['leaveMessageForm'] = array(
'name' => topage($name), 'name' => to_page($name),
'email' => topage($email), 'email' => to_page($email),
'groupId' => $group_id, 'groupId' => $group_id,
'groupName' => $group_name, 'groupName' => $group_name,
'info' => topage($info), 'info' => to_page($info),
'referrer' => topage($referrer), 'referrer' => to_page($referrer),
'showCaptcha' => (bool)(Settings::get("enablecaptcha") == "1" 'showCaptcha' => (bool) (Settings::get("enablecaptcha") == "1" && can_show_captcha()),
&& can_show_captcha())
); );
$data['page.title'] = (empty($group_name) ? '' : $group_name . ': ') $data['page.title'] = (empty($group_name) ? '' : $group_name . ': ')
@ -262,7 +276,8 @@ function setup_leavemessage($name, $email, $group_id, $info, $referrer) {
* @param string $referrer URL of referrer page * @param string $referrer URL of referrer page
* @return array Array of survey data * @return array Array of survey data
*/ */
function setup_survey($name, $email, $group_id, $info, $referrer) { function setup_survey($name, $email, $group_id, $info, $referrer)
{
$data = prepare_chat_app_data(); $data = prepare_chat_app_data();
// Load JavaScript plugins and JavaScripts, CSS files required by them // Load JavaScript plugins and JavaScripts, CSS files required by them
@ -272,14 +287,14 @@ function setup_survey($name, $email, $group_id, $info, $referrer) {
$data['survey'] = array(); $data['survey'] = array();
$data['survey']['surveyForm'] = array( $data['survey']['surveyForm'] = array(
'name' => topage($name), 'name' => to_page($name),
'groupId' => $group_id, 'groupId' => $group_id,
'email' => topage($email), 'email' => to_page($email),
'info' => topage($info), 'info' => to_page($info),
'referrer' => topage($referrer), 'referrer' => to_page($referrer),
'showEmail' => (bool) (Settings::get("surveyaskmail") == "1"), 'showEmail' => (bool) (Settings::get("surveyaskmail") == "1"),
'showMessage' => (bool) (Settings::get("surveyaskmessage") == "1"), 'showMessage' => (bool) (Settings::get("surveyaskmessage") == "1"),
'canChangeName' => (bool)(Settings::get('usercanchangename') == "1") 'canChangeName' => (bool) (Settings::get('usercanchangename') == "1"),
); );
$data['page.title'] = getlocal('presurvey.title'); $data['page.title'] = getlocal('presurvey.title');
@ -287,8 +302,7 @@ function setup_survey($name, $email, $group_id, $info, $referrer) {
'title' => $data['page.title'] 'title' => $data['page.title']
); );
if (Settings::get('enablegroups') == '1' if (Settings::get('enablegroups') == '1' && Settings::get('surveyaskgroup') == '1') {
&& Settings::get('surveyaskgroup') == '1') {
$data['survey']['surveyForm']['groups'] $data['survey']['surveyForm']['groups']
= prepare_groups_select($group_id); = prepare_groups_select($group_id);
} }
@ -314,10 +328,9 @@ function setup_survey($name, $email, $group_id, $info, $referrer) {
* - 'online': boolean, indicates if group online; * - 'online': boolean, indicates if group online;
* - 'selected': boolean, indicates if group selected by default. * - 'selected': boolean, indicates if group selected by default.
*/ */
function prepare_groups_select($group_id) { function prepare_groups_select($group_id)
$show_groups = ($group_id == '') {
? true $show_groups = ($group_id == '') ? true : group_has_children($group_id);
: group_has_children($group_id);
if (!$show_groups) { if (!$show_groups) {
return false; return false;
@ -334,9 +347,9 @@ function prepare_groups_select($group_id) {
foreach ($all_groups as $group) { foreach ($all_groups as $group) {
$group_is_empty = (bool) ($group['inumofagents'] == 0); $group_is_empty = (bool) ($group['inumofagents'] == 0);
$group_related_with_specified = (empty($group_id) $group_related_with_specified = empty($group_id)
|| $group['parent'] == $group_id || $group['parent'] == $group_id
|| $group['groupid'] == $group_id); || $group['groupid'] == $group_id;
if ($group_is_empty || !$group_related_with_specified) { if ($group_is_empty || !$group_related_with_specified) {
continue; continue;
@ -351,7 +364,7 @@ function prepare_groups_select($group_id) {
'name' => get_group_name($group), 'name' => get_group_name($group),
'description' => get_group_description($group), 'description' => get_group_description($group),
'online' => group_is_online($group), 'online' => group_is_online($group),
'selected' => (bool)($group['groupid'] == $selected_group_id) 'selected' => (bool) ($group['groupid'] == $selected_group_id),
); );
} }
@ -381,7 +394,8 @@ function prepare_groups_select($group_id) {
* @param Thread $thread thread object * @param Thread $thread thread object
* @return array Array of chat view data * @return array Array of chat view data
*/ */
function setup_chatview(Thread $thread) { function setup_chatview(Thread $thread)
{
$data = prepare_chat_app_data(); $data = prepare_chat_app_data();
// Get group info // Get group info
@ -396,7 +410,7 @@ function setup_chatview(Thread $thread) {
$data['chat'] = array( $data['chat'] = array(
'messageForm' => array(), 'messageForm' => array(),
'links' => array(), 'links' => array(),
'windowsParams' => array() 'windowsParams' => array(),
); );
// Set thread params // Set thread params
@ -405,20 +419,15 @@ function setup_chatview(Thread $thread) {
'token' => $thread->lastToken 'token' => $thread->lastToken
); );
$data['page.title'] = topage( $data['page.title'] = to_page(
empty($group['vcchattitle']) empty($group['vcchattitle']) ? Settings::get('chattitle') : $group['vcchattitle']
? Settings::get('chattitle')
: $group['vcchattitle']
); );
$data['chat']['page'] = array( $data['chat']['page'] = array(
'title' => $data['page.title'] 'title' => $data['page.title']
); );
// Setup logo // Setup logo
$data = array_merge_recursive( $data = array_merge_recursive($data, setup_logo($group));
$data,
setup_logo($group)
);
// Set enter key shortcut // Set enter key shortcut
if (Settings::get('sendmessagekey') == 'enter') { if (Settings::get('sendmessagekey') == 'enter') {
@ -429,7 +438,7 @@ function setup_chatview(Thread $thread) {
// Set some browser info // Set some browser info
$data['isOpera95'] = is_agent_opera95(); $data['isOpera95'] = is_agent_opera95();
$data['neediframesrc'] = needsFramesrc(); $data['neediframesrc'] = needs_frame_src();
// Load dialogs style options // Load dialogs style options
$chat_style = new ChatStyle(ChatStyle::currentStyle()); $chat_style = new ChatStyle(ChatStyle::currentStyle());
@ -451,11 +460,11 @@ function setup_chatview(Thread $thread) {
/** /**
* Prepare some data for chat for user * Prepare some data for chat for user
* *
* @param Thread $thread thread object * @param Thread $thread thread object that will be used
* be used
* @return array Array of chat view data * @return array Array of chat view data
*/ */
function setup_chatview_for_user(Thread $thread) { function setup_chatview_for_user(Thread $thread)
{
$data = setup_chatview($thread); $data = setup_chatview($thread);
// Load JavaScript plugins and JavaScripts, CSS files required by them // Load JavaScript plugins and JavaScripts, CSS files required by them
@ -463,12 +472,11 @@ function setup_chatview_for_user(Thread $thread) {
// Set user info // Set user info
$data['chat']['user'] = array( $data['chat']['user'] = array(
'name' => htmlspecialchars(topage($thread->userName)), 'name' => htmlspecialchars(to_page($thread->userName)),
'canChangeName' => (bool) (Settings::get('usercanchangename') == "1"), 'canChangeName' => (bool) (Settings::get('usercanchangename') == "1"),
'defaultName' => (bool)(getstring("chat.default.username") 'defaultName' => (bool) (getstring("chat.default.username") != $thread->userName),
!= $thread->userName),
'canPost' => true, 'canPost' => true,
'isAgent' => false 'isAgent' => false,
); );
$params = "thread=" . $thread->id . "&amp;token=" . $thread->lastToken; $params = "thread=" . $thread->id . "&amp;token=" . $thread->lastToken;
@ -494,7 +502,8 @@ function setup_chatview_for_user(Thread $thread) {
* @param Thread $thread thread object * @param Thread $thread thread object
* @return array Array of chat view data * @return array Array of chat view data
*/ */
function setup_chatview_for_operator(Thread $thread, $operator) { function setup_chatview_for_operator(Thread $thread, $operator)
{
$data = setup_chatview($thread); $data = setup_chatview($thread);
// Load JavaScript plugins and JavaScripts, CSS files required by them // Load JavaScript plugins and JavaScripts, CSS files required by them
@ -503,7 +512,7 @@ function setup_chatview_for_operator(Thread $thread, $operator) {
// Set operator info // Set operator info
$data['chat']['user'] = array( $data['chat']['user'] = array(
'name' => htmlspecialchars( 'name' => htmlspecialchars(
topage( to_page(
get_user_name( get_user_name(
$thread->userName, $thread->userName,
$thread->remote, $thread->remote,
@ -512,7 +521,7 @@ function setup_chatview_for_operator(Thread $thread, $operator) {
) )
), ),
'canPost' => (bool) ($thread->agentId == $operator['operatorid']), 'canPost' => (bool) ($thread->agentId == $operator['operatorid']),
'isAgent' => true 'isAgent' => true,
); );
// Set SSL link // Set SSL link
@ -533,7 +542,7 @@ function setup_chatview_for_operator(Thread $thread, $operator) {
// Set tracking params // Set tracking params
if (Settings::get('enabletracking')) { if (Settings::get('enabletracking')) {
$visitor = track_get_visitor_by_threadid($thread->id); $visitor = track_get_visitor_by_thread_id($thread->id);
$tracked_link_params = array("visitor" => "" . $visitor['visitorid']); $tracked_link_params = array("visitor" => "" . $visitor['visitorid']);
$data['chat']['links']['tracked'] = add_params( $data['chat']['links']['tracked'] = add_params(
MIBEW_WEB_ROOT . "/operator/tracked.php", MIBEW_WEB_ROOT . "/operator/tracked.php",
@ -556,9 +565,7 @@ function setup_chatview_for_operator(Thread $thread, $operator) {
foreach ($canned_messages as $answer) { foreach ($canned_messages as $answer) {
$predefined_answers[] = array( $predefined_answers[] = array(
'short' => htmlspecialchars( 'short' => htmlspecialchars(
topage($answer['vctitle'] to_page($answer['vctitle'] ? $answer['vctitle'] : cut_string($answer['vcvalue'], 97, '...'))
? $answer['vctitle']
: cutstring($answer['vcvalue'], 97, '...'))
), ),
'full' => myiconv( 'full' => myiconv(
MIBEW_ENCODING, MIBEW_ENCODING,
@ -584,11 +591,10 @@ function ban_for_addr($addr)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
return $db->query( return $db->query(
"select banid,comment from {chatban} " . "SELECT banid,comment FROM {chatban} WHERE dtmtill > :now AND address = :addr",
"where dtmtill > :now AND address = :addr",
array( array(
':addr' => $addr, ':addr' => $addr,
':now' => time() ':now' => time(),
), ),
array('return_rows' => Database::RETURN_ONE_ROW) array('return_rows' => Database::RETURN_ONE_ROW)
); );
@ -596,36 +602,39 @@ function ban_for_addr($addr)
function visitor_from_request() function visitor_from_request()
{ {
$defaultName = getstring("chat.default.username"); $default_name = getstring("chat.default.username");
$userName = $defaultName; $user_name = $default_name;
if (isset($_COOKIE[USERNAME_COOKIE_NAME])) { if (isset($_COOKIE[USERNAME_COOKIE_NAME])) {
$data = base64_decode(strtr($_COOKIE[USERNAME_COOKIE_NAME], '-_,', '+/=')); $data = base64_decode(strtr($_COOKIE[USERNAME_COOKIE_NAME], '-_,', '+/='));
if (strlen($data) > 0) { if (strlen($data) > 0) {
$userName = myiconv("utf-8", MIBEW_ENCODING, $data); $user_name = myiconv("utf-8", MIBEW_ENCODING, $data);
} }
} }
if ($userName == $defaultName) { if ($user_name == $default_name) {
$userName = getgetparam('name', $userName); $user_name = get_get_param('name', $user_name);
} }
if (isset($_COOKIE[USERID_COOKIE_NAME])) { if (isset($_COOKIE[USERID_COOKIE_NAME])) {
$userId = $_COOKIE[USERID_COOKIE_NAME]; $user_id = $_COOKIE[USERID_COOKIE_NAME];
} else { } else {
$userId = uniqid('', TRUE); $user_id = uniqid('', true);
setcookie(USERID_COOKIE_NAME, $userId, time() + 60 * 60 * 24 * 365); setcookie(USERID_COOKIE_NAME, $user_id, time() + 60 * 60 * 24 * 365);
} }
return array('id' => $userId, 'name' => $userName);
return array('id' => $user_id, 'name' => $user_name);
} }
function get_remote_host() function get_remote_host()
{ {
$extAddr = $_SERVER['REMOTE_ADDR']; $ext_addr = $_SERVER['REMOTE_ADDR'];
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $has_proxy = isset($_SERVER['HTTP_X_FORWARDED_FOR'])
$_SERVER['HTTP_X_FORWARDED_FOR'] != $_SERVER['REMOTE_ADDR']) { && $_SERVER['HTTP_X_FORWARDED_FOR'] != $_SERVER['REMOTE_ADDR'];
$extAddr = $_SERVER['REMOTE_ADDR'] . ' (' . $_SERVER['HTTP_X_FORWARDED_FOR'] . ')'; if ($has_proxy) {
$ext_addr = $_SERVER['REMOTE_ADDR'] . ' (' . $_SERVER['HTTP_X_FORWARDED_FOR'] . ')';
} }
return isset($_SERVER['REMOTE_HOST']) ? $_SERVER['REMOTE_HOST'] : $extAddr;
return isset($_SERVER['REMOTE_HOST']) ? $_SERVER['REMOTE_HOST'] : $ext_addr;
} }
/** /**
@ -638,7 +647,14 @@ function get_remote_host()
* @param string $referrer Page user came from * @param string $referrer Page user came from
* @param string $info User info * @param string $info User info
*/ */
function chat_start_for_user($group_id, $requested_operator, $visitor_id, $visitor_name, $referrer, $info) { function chat_start_for_user(
$group_id,
$requested_operator,
$visitor_id,
$visitor_name,
$referrer,
$info
) {
// Get user info // Get user info
$remote_host = get_remote_host(); $remote_host = get_remote_host();
$user_browser = $_SERVER['HTTP_USER_AGENT']; $user_browser = $_SERVER['HTTP_USER_AGENT'];
@ -740,5 +756,3 @@ function chat_start_for_user($group_id, $requested_operator, $visitor_id, $visit
return $thread; return $thread;
} }
?>

View File

@ -22,8 +22,8 @@ namespace Mibew\API;
* *
* @todo May be use regular methods instead of static one * @todo May be use regular methods instead of static one
*/ */
class API { class API
{
/** /**
* Version of the MIBEW API protocol implemented by the class * Version of the MIBEW API protocol implemented by the class
*/ */
@ -31,6 +31,7 @@ class API {
/** /**
* Array of \Mibew\API\API objects * Array of \Mibew\API\API objects
*
* @var array * @var array
*/ */
protected static $interactions = array(); protected static $interactions = array();
@ -40,7 +41,7 @@ class API {
* *
* @var \Mibew\API\Interaction * @var \Mibew\API\Interaction
*/ */
protected $interaction = NULL; protected $interaction = null;
/** /**
* Returns \Mibew\API\API object * Returns \Mibew\API\API object
@ -49,7 +50,8 @@ class API {
* @return MibeAPI object * @return MibeAPI object
* @throws \Mibew\API\APIException * @throws \Mibew\API\APIException
*/ */
public static function getAPI($class_name) { public static function getAPI($class_name)
{
if (!class_exists($class_name)) { if (!class_exists($class_name)) {
throw new APIException( throw new APIException(
"Wrong interaction type", "Wrong interaction type",
@ -59,16 +61,8 @@ class API {
if (empty(self::$interactions[$class_name])) { if (empty(self::$interactions[$class_name])) {
self::$interactions[$class_name] = new self(new $class_name()); self::$interactions[$class_name] = new self(new $class_name());
} }
return self::$interactions[$class_name];
}
/** return self::$interactions[$class_name];
* Class constructor
*
* @param \Mibew\API\Interaction $interaction Interaction type object
*/
protected function __construct(Interaction\Interaction $interaction) {
$this->interaction = $interaction;
} }
/** /**
@ -78,7 +72,8 @@ class API {
* @param array $trusted_signatures Array of trusted signatures. * @param array $trusted_signatures Array of trusted signatures.
* @throws \Mibew\API\APIException * @throws \Mibew\API\APIException
*/ */
public function checkPackage($package, $trusted_signatures) { public function checkPackage($package, $trusted_signatures)
{
// Check signature // Check signature
if (!isset($package['signature'])) { if (!isset($package['signature'])) {
throw new APIException( throw new APIException(
@ -140,7 +135,8 @@ class API {
* @param array $request Request array. See Mibew API for details. * @param array $request Request array. See Mibew API for details.
* @throws \Mibew\API\APIException * @throws \Mibew\API\APIException
*/ */
public function checkRequest($request) { public function checkRequest($request)
{
// Check token // Check token
if (empty($request['token'])) { if (empty($request['token'])) {
throw new APIException( throw new APIException(
@ -165,11 +161,12 @@ class API {
* Validate function * Validate function
* *
* @param array $function Function array. See Mibew API for details. * @param array $function Function array. See Mibew API for details.
* @param boolean $filter_reserved_functions Determine if function name must not be in * @param boolean $filter_reserved_functions Determine if function name must
* reserved list * not be in reserved list
* @throws \Mibew\API\APIException * @throws \Mibew\API\APIException
*/ */
public function checkFunction($function, $filter_reserved_functions = false) { public function checkFunction($function, $filter_reserved_functions = false)
{
// Check function name // Check function name
if (empty($function['function'])) { if (empty($function['function'])) {
throw new APIException( throw new APIException(
@ -178,10 +175,7 @@ class API {
); );
} }
if ($filter_reserved_functions) { if ($filter_reserved_functions) {
if (in_array( if (in_array($function['function'], $this->interaction->reservedFunctionNames)) {
$function['function'],
$this->interaction->reservedFunctionNames
)) {
throw new APIException( throw new APIException(
"'{$function['function']}' is reserved function name", "'{$function['function']}' is reserved function name",
APIException::FUNCTION_NAME_RESERVED APIException::FUNCTION_NAME_RESERVED
@ -218,15 +212,18 @@ class API {
* *
* @param array $requests Requests array. See Mibew API for details. * @param array $requests Requests array. See Mibew API for details.
* @param string $signature Sender signature. * @param string $signature Sender signature.
* @param boolean $async true for asynchronous request and false for synchronous request * @param boolean $async true for asynchronous request and false for
* synchronous request
* @return string Ready for transfer encoded package * @return string Ready for transfer encoded package
*/ */
public function encodePackage($requests, $signature, $async) { public function encodePackage($requests, $signature, $async)
{
$package = array(); $package = array();
$package['signature'] = $signature; $package['signature'] = $signature;
$package['proto'] = self::PROTOCOL_VERSION; $package['proto'] = self::PROTOCOL_VERSION;
$package['async'] = $async; $package['async'] = $async;
$package['requests'] = $requests; $package['requests'] = $requests;
return urlencode(json_encode($package)); return urlencode(json_encode($package));
} }
@ -238,7 +235,8 @@ class API {
* @return array Decoded package array. See Mibew API for details. * @return array Decoded package array. See Mibew API for details.
* @throws \Mibew\API\APIException * @throws \Mibew\API\APIException
*/ */
public function decodePackage($package, $trusted_signatures) { public function decodePackage($package, $trusted_signatures)
{
// Try to decode package // Try to decode package
$decoded_package = urldecode($package); $decoded_package = urldecode($package);
$decoded_package = json_decode($decoded_package, true); $decoded_package = json_decode($decoded_package, true);
@ -248,8 +246,7 @@ class API {
if ($json_error_code != JSON_ERROR_NONE) { if ($json_error_code != JSON_ERROR_NONE) {
// Not valid JSON // Not valid JSON
throw new APIException( throw new APIException(
"Package have invalid json structure. " . "Package have invalid json structure. JSON error code is '" . $json_error_code . "'",
"JSON error code is '" . $json_error_code . "'",
APIException::NOT_VALID_JSON APIException::NOT_VALID_JSON
); );
} }
@ -265,33 +262,39 @@ class API {
* @param array $result_arguments Arguments of result function * @param array $result_arguments Arguments of result function
* @return array Result package * @return array Result package
*/ */
public function buildResult($token, $result_arguments) { public function buildResult($token, $result_arguments)
{
$arguments = $result_arguments + $this->interaction->getObligatoryArgumentsDefaults('result'); $arguments = $result_arguments + $this->interaction->getObligatoryArgumentsDefaults('result');
$package = array( $package = array(
'token' => $token, 'token' => $token,
'functions' => array( 'functions' => array(
array( array(
'function' => 'result', 'function' => 'result',
'arguments' => $arguments 'arguments' => $arguments,
) ),
) ),
); );
return $package; return $package;
} }
/** /**
* Search 'result' function in $function_list. If request contains more than one result * Search 'result' function in $function_list.
* functions throws an \Mibew\API\APIException
* *
* @param array $functions_list Array of functions. See Mibew API specification * If request contains more than one result the functions throws
* for function structure details * an \Mibew\API\APIException.
* @param mixed $existance Control existance of the 'result' function in request. *
* Use boolean true if 'result' function must exists in request, boolean false if must not * @param array $functions_list Array of functions. See Mibew API
* and null if it doesn't matter. * specification for function structure details.
* @return mixed Function array if 'result' function found and NULL otherwise * @param mixed $existance Control existance of the 'result' function in
* request. Use boolean true if 'result' function must exists in request,
* boolean false if must not and null if it doesn't matter.
* @return mixed Function array if 'result' function found and NULL
* otherwise
* @throws \Mibew\API\APIException * @throws \Mibew\API\APIException
*/ */
public function getResultFunction ($functions_list, $existence = null) { public function getResultFunction($functions_list, $existence = null)
{
$result_function = null; $result_function = null;
// Try to find 'result' function // Try to find 'result' function
foreach ($functions_list as $function) { foreach ($functions_list as $function) {
@ -321,8 +324,17 @@ class API {
APIException::RESULT_FUNCTION_EXISTS APIException::RESULT_FUNCTION_EXISTS
); );
} }
return $result_function; return $result_function;
} }
}
?> /**
* Class constructor
*
* @param \Mibew\API\Interaction $interaction Interaction type object
*/
protected function __construct(Interaction\Interaction $interaction)
{
$this->interaction = $interaction;
}
}

View File

@ -20,7 +20,8 @@ namespace Mibew\API;
/** /**
* Mibew API Exception class. * Mibew API Exception class.
*/ */
class APIException extends \Exception { class APIException extends \Exception
{
/** /**
* Async flag is missed. * Async flag is missed.
*/ */
@ -114,5 +115,3 @@ class APIException extends \Exception {
*/ */
const WRONG_PROTOCOL_VERSION = 23; const WRONG_PROTOCOL_VERSION = 23;
} }
?>

View File

@ -20,18 +20,21 @@ namespace Mibew\API;
/** /**
* Implements functions execution context * Implements functions execution context
*/ */
class ExecutionContext { class ExecutionContext
{
/** /**
* Values which returns after execution of all functions in request * Values which returns after execution of all functions in request
*
* @var array * @var array
*/ */
protected $return = array(); protected $return = array();
/** /**
* Results of execution of all function in request * Results of execution of all function in request
*
* @var array * @var array
*/ */
protected $functions_results = array(); protected $functionsResults = array();
/** /**
* Returns requets results * Returns requets results
@ -39,27 +42,35 @@ class ExecutionContext {
* @return array Request results * @return array Request results
* @see \Mibew\API\ExecutionContext::$return * @see \Mibew\API\ExecutionContext::$return
*/ */
public function getResults () { public function getResults()
{
return $this->return; return $this->return;
} }
/** /**
* Build arguments list by replace all references by values of execution context * Build arguments list by replace all references by values of execution
* context.
* *
* @param array $function Function array. See MibewAPI for details. * @param array $function Function array. See MibewAPI for details.
* @return array Arguments list * @return array Arguments list
* @throws \Mibew\API\APIException * @throws \Mibew\API\APIException
*/ */
public function getArgumentsList ($function) { public function getArgumentsList($function)
{
$arguments = $function['arguments']; $arguments = $function['arguments'];
$references = $function['arguments']['references']; $references = $function['arguments']['references'];
foreach ($references as $variable => $func_num) { foreach ($references as $variable => $func_num) {
// Check target function in context // Check target function in context
if (! isset($this->functions_results[$func_num - 1])) { if (!isset($this->functionsResults[$func_num - 1])) {
// Wrong function num // Wrong function num
$message = "Wrong reference in '%s' function. "
. "Function #%s does not call yet.";
throw new APIException( throw new APIException(
"Wrong reference in '{$function['function']}' function. " . sprintf(
"Function #{$func_num} does not call yet.", $message,
$function['function'],
$func_num
),
APIException::WRONG_FUNCTION_NUM_IN_REFERENCE APIException::WRONG_FUNCTION_NUM_IN_REFERENCE
); );
} }
@ -68,47 +79,63 @@ class ExecutionContext {
if (empty($arguments[$variable])) { if (empty($arguments[$variable])) {
// Empty argument that should contains reference // Empty argument that should contains reference
throw new APIException( throw new APIException(
"Wrong reference in '{$function['function']}' function. " . sprintf(
"Empty {$variable} argument.", "Wrong reference in '%s' function. Empty %s argument.",
$function['function'],
$variable
),
APIException::EMPTY_VARIABLE_IN_REFERENCE APIException::EMPTY_VARIABLE_IN_REFERENCE
); );
} }
$reference_to = $arguments[$variable]; $reference_to = $arguments[$variable];
// Check target value // Check target value
if (! isset($this->functions_results[$func_num - 1][$reference_to])) { if (!isset($this->functionsResults[$func_num - 1][$reference_to])) {
// Undefined target value // Undefined target value
$message = "Wrong reference in '%s' function. "
. "There is no '%s' argument in #%s function results";
throw new APIException( throw new APIException(
"Wrong reference in '{$function['function']}' function. " . sprintf(
"There is no '{$reference_to}' argument in #{$func_num} " . $message,
"function results", $function['function'],
$reference_to,
$func_num
),
APIException::VARIABLE_IS_UNDEFINED_IN_REFERENCE APIException::VARIABLE_IS_UNDEFINED_IN_REFERENCE
); );
} }
// Replace reference by target value // Replace reference by target value
$arguments[$variable] = $this->functions_results[$func_num - 1][$reference_to]; $arguments[$variable] = $this->functionsResults[$func_num - 1][$reference_to];
} }
return $arguments; return $arguments;
} }
/** /**
* Stores functions results in execution context and add values to request result * Stores functions results in execution context and add values to request
* result.
* *
* @param array $function Function array. See MibewAPI for details. * @param array $function Function array. See MibewAPI for details.
* @param array $results Associative array of the function results. * @param array $results Associative array of the function results.
* @throws \Mibew\API\APIException * @throws \Mibew\API\APIException
*/ */
public function storeFunctionResults ($function, $results) { public function storeFunctionResults($function, $results)
{
// Check if function return correct results // Check if function return correct results
if (empty($results['errorCode'])) { if (empty($results['errorCode'])) {
// Add value to request results // Add value to request results
foreach ($function['arguments']['return'] as $name => $alias) { foreach ($function['arguments']['return'] as $name => $alias) {
if (!isset($results[$name])) { if (!isset($results[$name])) {
// Value that defined in 'return' argument is undefined // Value that defined in 'return' argument is undefined
$message = "Variable with name '%s' is undefined "
. "in the results of the '%s' function";
throw new APIException( throw new APIException(
"Variable with name '{$name}' is undefined in the " . sprintf(
"results of the '{$function['function']}' function", $message,
$name,
$function['function']
),
APIException::VARIABLE_IS_UNDEFINED_IN_RESULT APIException::VARIABLE_IS_UNDEFINED_IN_RESULT
); );
} }
@ -124,9 +151,6 @@ class ExecutionContext {
} }
// Store function results in execution context // Store function results in execution context
$this->functions_results[] = $results; $this->functionsResults[] = $results;
} }
} }
?>

View File

@ -20,7 +20,17 @@ namespace Mibew\API\Interaction;
/** /**
* Implements Mibew Core - Mibew Chat Window interaction * Implements Mibew Core - Mibew Chat Window interaction
*/ */
class ChatInteraction extends Interaction { class ChatInteraction extends Interaction
{
/**
* Reserved function's names
* @var array
* @see \Mibew\API\Interaction\Interaction::$reservedFunctionNames
*/
public $reservedFunctionNames = array(
'result',
);
/** /**
* Defines obligatory arguments and default values for them * Defines obligatory arguments and default values for them
* @var array * @var array
@ -31,21 +41,10 @@ class ChatInteraction extends Interaction {
'threadId' => null, 'threadId' => null,
'token' => null, 'token' => null,
'references' => array(), 'references' => array(),
'return' => array() 'return' => array(),
), ),
'result' => array( 'result' => array(
'errorCode' => 0 'errorCode' => 0,
) ),
);
/**
* Reserved function's names
* @var array
* @see \Mibew\API\Interaction\Interaction::$reservedFunctionNames
*/
public $reservedFunctionNames = array(
'result'
); );
} }
?>

View File

@ -20,28 +20,8 @@ namespace Mibew\API\Interaction;
/** /**
* Encapsulates interaction type * Encapsulates interaction type
*/ */
abstract class Interaction { abstract class Interaction
/** {
* Defines obligatory arguments and default values for them
*
* @var array Keys of the array are function names ('*' for all functions). Values are arrays of obligatory
* arguments with key for name of an argument and value for default value.
*
* For example:
* <code>
* protected $obligatoryArguments = array(
* '*' => array( // Obligatory arguments for all functions are
* 'return' => array(), // 'return' with array() by default and
* 'references' => array() // 'references' with array() by default
* ),
* 'result' => array( // There is an additional argument for the result function
* 'errorCode' => 0 // This is 'error_code' with 0 by default
* )
* );
* </code>
*/
protected $obligatoryArguments = array();
/** /**
* Reserved function's names * Reserved function's names
* *
@ -50,13 +30,39 @@ abstract class Interaction {
*/ */
public $reservedFunctionNames = array(); public $reservedFunctionNames = array();
/**
* Defines obligatory arguments and default values for them
*
* @var array Keys of the array are function names ('*' for all functions).
* Values are arrays of obligatory arguments with key for name of an
* argument and value for default value.
*
* For example:
* <code>
* protected $obligatoryArguments = array(
* '*' => array(
* // Obligatory arguments for all functions are:
* 'return' => array(), // 'return' with array() by default and
* 'references' => array() // 'references' with array() by default
* ),
*
* 'result' => array(
* // There is an additional argument for the result function
* 'errorCode' => 0 // This is 'error_code' with 0 by default
* )
* );
* </code>
*/
protected $obligatoryArguments = array();
/** /**
* Returns obligatory arguments for the $function_name function * Returns obligatory arguments for the $function_name function
* *
* @param string $function_name Function name * @param string $function_name Function name
* @return array An array of obligatory arguments * @return array An array of obligatory arguments
*/ */
public function getObligatoryArguments($function_name) { public function getObligatoryArguments($function_name)
{
$obligatory_arguments = array(); $obligatory_arguments = array();
// Add obligatory for all functions arguments // Add obligatory for all functions arguments
if (!empty($this->obligatoryArguments['*'])) { if (!empty($this->obligatoryArguments['*'])) {
@ -72,28 +78,36 @@ abstract class Interaction {
array_keys($this->obligatoryArguments[$function_name]) array_keys($this->obligatoryArguments[$function_name])
); );
} }
return array_unique($obligatory_arguments); return array_unique($obligatory_arguments);
} }
/** /**
* Returns default values of obligatory arguments for the $function_name function * Returns default values of obligatory arguments for the $function_name
* function
* *
* @param string $function_name Function name * @param string $function_name Function name
* @return array Associative array with keys are obligatory arguments and values are default * @return array Associative array with keys are obligatory arguments and
* values of them * values are default values of them
*/ */
public function getObligatoryArgumentsDefaults($function_name) { public function getObligatoryArgumentsDefaults($function_name)
{
$obligatory_arguments = array(); $obligatory_arguments = array();
// Add obligatory for all functions arguments // Add obligatory for all functions arguments
if (!empty($this->obligatoryArguments['*'])) { if (!empty($this->obligatoryArguments['*'])) {
$obligatory_arguments = array_merge($obligatory_arguments, $this->obligatoryArguments['*']); $obligatory_arguments = array_merge(
$obligatory_arguments,
$this->obligatoryArguments['*']
);
} }
// Add obligatory arguments for given function // Add obligatory arguments for given function
if (!empty($this->obligatoryArguments[$function_name])) { if (!empty($this->obligatoryArguments[$function_name])) {
$obligatory_arguments = array_merge($obligatory_arguments, $this->obligatoryArguments[$function_name]); $obligatory_arguments = array_merge(
$obligatory_arguments,
$this->obligatoryArguments[$function_name]
);
} }
return $obligatory_arguments; return $obligatory_arguments;
} }
} }
?>

View File

@ -20,7 +20,17 @@ namespace Mibew\API\Interaction;
/** /**
* Implements Mibew Core - Mibew invitation waiting window interaction * Implements Mibew Core - Mibew invitation waiting window interaction
*/ */
class InviteInteraction extends Interaction { class InviteInteraction extends Interaction
{
/**
* Reserved function's names
* @var array
* @see \Mibew\API\Interaction\Interaction::$reservedFunctionNames
*/
public $reservedFunctionNames = array(
'result',
);
/** /**
* Defines obligatory arguments and default values for them * Defines obligatory arguments and default values for them
* @var array * @var array
@ -30,21 +40,10 @@ class InviteInteraction extends Interaction {
'*' => array( '*' => array(
'references' => array(), 'references' => array(),
'return' => array(), 'return' => array(),
'visitorId' => null 'visitorId' => null,
), ),
'result' => array( 'result' => array(
'errorCode' => 0 'errorCode' => 0,
) ),
);
/**
* Reserved function's names
* @var array
* @see \Mibew\API\Interaction\Interaction::$reservedFunctionNames
*/
public $reservedFunctionNames = array(
'result'
); );
} }
?>

View File

@ -20,7 +20,17 @@ namespace Mibew\API\Interaction;
/** /**
* Implements Mibew Core - Mibew Users list interaction * Implements Mibew Core - Mibew Users list interaction
*/ */
class UsersInteraction extends Interaction { class UsersInteraction extends Interaction
{
/**
* Reserved function's names
* @var array
* @see \Mibew\API\Interaction\Interaction::$reservedFunctionNames
*/
public $reservedFunctionNames = array(
'result',
);
/** /**
* Defines obligatory arguments and default values for them * Defines obligatory arguments and default values for them
* @var array * @var array
@ -30,24 +40,13 @@ class UsersInteraction extends Interaction {
'*' => array( '*' => array(
'agentId' => null, 'agentId' => null,
'references' => array(), 'references' => array(),
'return' => array() 'return' => array(),
), ),
'updateThreads' => array( 'updateThreads' => array(
'revision' => 0 'revision' => 0,
), ),
'result' => array( 'result' => array(
'errorCode' => 0 'errorCode' => 0,
) ),
);
/**
* Reserved function's names
* @var array
* @see \Mibew\API\Interaction\Interaction::$reservedFunctionNames
*/
public $reservedFunctionNames = array(
'result'
); );
} }
?>

View File

@ -21,8 +21,8 @@ namespace Mibew;
* Encapsulates work with database. Implenets singleton pattern to provide only * Encapsulates work with database. Implenets singleton pattern to provide only
* one instance. * one instance.
*/ */
Class Database{ class Database
{
const FETCH_ASSOC = 1; const FETCH_ASSOC = 1;
const FETCH_NUM = 2; const FETCH_NUM = 2;
const FETCH_BOTH = 4; const FETCH_BOTH = 4;
@ -33,13 +33,13 @@ Class Database{
* An instance of Database class * An instance of Database class
* @var Database * @var Database
*/ */
protected static $instance = NULL; protected static $instance = null;
/** /**
* PDO object * PDO object
* @var \PDO * @var \PDO
*/ */
protected $dbh = NULL; protected $dbh = null;
/** /**
* Database host * Database host
@ -72,7 +72,8 @@ Class Database{
protected $tablesPrefix = ''; protected $tablesPrefix = '';
/** /**
* Database connection encoding. Use only if Database::$forceCharsetInConnection set to true * Database connection encoding. Is used only if
* Database::$forceCharsetInConnection is set to true.
* @var string * @var string
* *
* @see Database::$forceCharsetInConnection * @see Database::$forceCharsetInConnection
@ -104,7 +105,7 @@ Class Database{
* Id of the last query * Id of the last query
* @var type * @var type
*/ */
protected $lastQuery = NULL; protected $lastQuery = null;
/** /**
* Controls if exception must be processed into class or thrown * Controls if exception must be processed into class or thrown
@ -116,45 +117,59 @@ Class Database{
* Get instance of Database class. * Get instance of Database class.
* *
* If no instance exists, creates new instance. * If no instance exists, creates new instance.
* Use Database::initialize() before try to get an instance. If database was not initilize coorectly triggers an * Use Database::initialize() before try to get an instance. If database
* error with E_USER_ERROR level. * was not initilize coorectly triggers an error with E_USER_ERROR level.
* *
* @return Database * @return Database
* @see Database::initialize() * @see Database::initialize()
*/ */
public static function getInstance(){ public static function getInstance()
{
if (is_null(self::$instance)) { if (is_null(self::$instance)) {
trigger_error('Database was not initialized correctly', E_USER_ERROR); trigger_error('Database was not initialized correctly', E_USER_ERROR);
} }
return self::$instance; return self::$instance;
} }
/** /**
* Destroy internal database object * Destroy internal database object
*/ */
public static function destroy(){ public static function destroy()
{
if (!is_null(self::$instance)) { if (!is_null(self::$instance)) {
self::$instance->__destruct(); self::$instance->__destruct();
self::$instance = NULL; self::$instance = null;
} }
} }
/** /**
* Initialize database. * Initialize database.
* *
* Set internal database and connectionproperties. Create Database object. Create PDO object and store it in the * Set internal database and connectionproperties. Create Database object.
* Database object. * Create PDO object and store it in the Database object.
* *
* @param string $host Database host. * @param string $host Database host.
* @param string $user Database user name. * @param string $user Database user name.
* @param string $pass Database for user with $name password. * @param string $pass Database for user with $name password.
* @param boolean $use_pconn Control use persistent connection to the database or not. * @param boolean $use_pconn Control use persistent connection to the
* database or not.
* @param string $db Database name. * @param string $db Database name.
* @param string $prefix Database tables prefix * @param string $prefix Database tables prefix
* @param boolean $force_charset Control force charset in conection or not. * @param boolean $force_charset Control force charset in conection or not.
* @param string $encoding Contains connection encoding. Using only if $force_charset = true. * @param string $encoding Contains connection encoding. Is used only if
* $force_charset is equals to TRUE.
*/ */
public static function initialize($host, $user, $pass, $use_pconn, $db, $prefix, $force_charset = false, $encoding = 'utf8') { public static function initialize(
$host,
$user,
$pass,
$use_pconn,
$db,
$prefix,
$force_charset = false,
$encoding = 'utf8'
) {
// Check PDO // Check PDO
if (!extension_loaded('PDO')) { if (!extension_loaded('PDO')) {
throw new \Exception('PDO extension is not loaded'); throw new \Exception('PDO extension is not loaded');
@ -198,27 +213,6 @@ Class Database{
self::$instance = $instance; self::$instance = $instance;
} }
/**
* Forbid clone objects
*/
private final function __clone() {}
/**
* Forbid external object creation
*/
protected function __construct() {}
/**
* Handles errors
* @param \Exception $e
*/
protected function handleError(\Exception $e){
if ($this->throwExceptions) {
throw $e;
}
die($e->getMessage());
}
/** /**
* Set if exceptions must be process into the class or thrown and return * Set if exceptions must be process into the class or thrown and return
* previous value. * previous value.
@ -229,52 +223,55 @@ Class Database{
* @param boolean $value Value that should be set. This argument is optional * @param boolean $value Value that should be set. This argument is optional
* @return bool Previous value * @return bool Previous value
*/ */
public function throwExeptions(){ public function throwExeptions()
{
$last_value = $this->throwExceptions; $last_value = $this->throwExceptions;
if (func_num_args() > 0) { if (func_num_args() > 0) {
$this->throwExceptions = func_get_arg(0); $this->throwExceptions = func_get_arg(0);
} }
return $last_value; return $last_value;
} }
/** /**
* Database class destructor. * Database class destructor.
*/ */
public function __destruct(){ public function __destruct()
{
foreach ($this->preparedStatements as $key => $statement) { foreach ($this->preparedStatements as $key => $statement) {
$this->preparedStatements[$key] = NULL; $this->preparedStatements[$key] = null;
} }
$this->dbh = NULL; $this->dbh = null;
self::$instance = NULL; self::$instance = null;
} }
/** /**
* Executes SQL query. * Executes SQL query.
*
* In SQL query can be used PDO style placeholders: * In SQL query can be used PDO style placeholders:
* unnamed placeholders (question marks '?') and named placeholders (like * unnamed placeholders (question marks '?') and named placeholders (like
* ':name'). * ':name'). If unnamed placeholders are used, $values array must have
* If unnamed placeholders are used, $values array must have numeric indexes. * numeric indexes. If named placeholders are used, $values param must be an
* If named placeholders are used, $values param must be an associative array * associative array with keys corresponding to the placeholders names
* with keys corresponding to the placeholders names
* *
* Table prefix automatically substitute if table name puts in curly braces * Table prefix automatically substitute if table name puts in curly braces
* *
* @param string $query SQL query * @param string $query SQL query
* @param array $values Values, that must be substitute instead of * @param array $values Values, that must be substitute instead of
* placeholders in SQL query. * placeholders in SQL query.
* @param array $params Array of query parameters. It can contains values with * @param array $params Array of query parameters. It can contains values
* following keys: * with following keys:
* - 'return_rows' control if rows must be returned and how many rows must * - 'return_rows' control if rows must be returned and how many rows must
* be returnd. The value can be Database::RETURN_ONE_ROW for olny one row * be returnd. The value can be Database::RETURN_ONE_ROW for olny one
* or Database::RETURN_ALL_ROWS for all rows. If this key not specified, * row or Database::RETURN_ALL_ROWS for all rows. If this key not
* the function will not return any rows. * specified, the function will not return any rows.
* - 'fetch_type' control indexes in resulting rows. The value can be * - 'fetch_type' control indexes in resulting rows. The value can be
* Database::FETCH_ASSOC for associative array, Database::FETCH_NUM for * Database::FETCH_ASSOC for associative array, Database::FETCH_NUM for
* array with numeric indexes and Database::FETCH_BOTH for both indexes. * array with numeric indexes and Database::FETCH_BOTH for both indexes.
* Default value is Database::FETCH_ASSOC. * Default value is Database::FETCH_ASSOC.
* @return mixed If 'return_rows' key of the $params array is specified, * @return mixed If 'return_rows' key of the $params array is specified,
* returns one or several rows (depending on $params['return_rows'] value) or * returns one or several rows (depending on $params['return_rows'] value)
* boolean false on fail. * or boolean false on fail.
* If 'return_rows' key of the $params array is not specified, returns * If 'return_rows' key of the $params array is not specified, returns
* boolean true on success or false on fail. * boolean true on success or false on fail.
* *
@ -284,7 +281,8 @@ Class Database{
* @see Database::FETCH_NUM * @see Database::FETCH_NUM
* @see Database::FETCH_BOTH * @see Database::FETCH_BOTH
*/ */
public function query($query, $values = NULL, $params = array()){ public function query($query, $values = null, $params = array())
{
try { try {
$query = preg_replace("/\{(\w+)\}/", $this->tablesPrefix . "$1", $query); $query = preg_replace("/\{(\w+)\}/", $this->tablesPrefix . "$1", $query);
@ -310,7 +308,6 @@ Class Database{
} }
// Some rows must be returned // Some rows must be returned
// Get indexes type // Get indexes type
if (!array_key_exists('fetch_type', $params)) { if (!array_key_exists('fetch_type', $params)) {
$params['fetch_type'] = Database::FETCH_ASSOC; $params['fetch_type'] = Database::FETCH_ASSOC;
@ -347,21 +344,23 @@ Class Database{
} }
/** /**
* Returns value of PDOStatement::$errorInfo property for last query * Returns value of PDOStatement::$errorInfo property for last query.
* @return string Error info array
* *
* @return string Error info array
* @see \PDOStatement::$erorrInfo * @see \PDOStatement::$erorrInfo
*/ */
public function errorInfo(){ public function errorInfo()
{
if (is_null($this->lastQuery)) { if (is_null($this->lastQuery)) {
return false; return false;
} }
try { try {
$errorInfo = $this->preparedStatements[$this->lastQuery]->errorInfo(); $error_info = $this->preparedStatements[$this->lastQuery]->errorInfo();
} catch (\Exception $e) { } catch (\Exception $e) {
$this->handleError($e); $this->handleError($e);
} }
return $errorInfo;
return $error_info;
} }
/** /**
@ -369,13 +368,15 @@ Class Database{
* *
* @return int The ID * @return int The ID
*/ */
public function insertedId(){ public function insertedId()
{
try { try {
$lastInsertedId = $this->dbh->lastInsertId(); $last_inserted_id = $this->dbh->lastInsertId();
} catch (\Exception $e) { } catch (\Exception $e) {
$this->handleError($e); $this->handleError($e);
} }
return $lastInsertedId;
return $last_inserted_id;
} }
/** /**
@ -383,7 +384,8 @@ Class Database{
* *
* @return int Affected rows count * @return int Affected rows count
*/ */
public function affectedRows(){ public function affectedRows()
{
if (is_null($this->lastQuery)) { if (is_null($this->lastQuery)) {
return false; return false;
} }
@ -392,9 +394,33 @@ Class Database{
} catch (\Exception $e) { } catch (\Exception $e) {
$this->handleError($e); $this->handleError($e);
} }
return $affected_rows; return $affected_rows;
} }
/**
* Forbid external object creation
*/
protected function __construct()
{
} }
?> /**
* Handles errors
* @param \Exception $e
*/
protected function handleError(\Exception $e)
{
if ($this->throwExceptions) {
throw $e;
}
die($e->getMessage());
}
/**
* Forbid clone objects
*/
final private function __clone()
{
}
}

View File

@ -21,23 +21,26 @@ namespace Mibew;
* Provide event-related functionality. * Provide event-related functionality.
* Implements singleton pattern. * Implements singleton pattern.
*/ */
Class EventDispatcher { class EventDispatcher
{
/** /**
* An instance of EventDispatcher class. * An instance of EventDispatcher class.
*
* @var EventDispatcher * @var EventDispatcher
*/ */
protected static $instance = null; protected static $instance = null;
/** /**
* Events and listeners array. * Events and listeners array.
*
* @var array * @var array
*/ */
protected $events = array(); protected $events = array();
/** /**
* Increments any time when plugin adds. Use for determine plugins order for plugins with * Increments any time when plugin adds. Is used for determine plugins order
* equal priority. * for plugins with equal priority.
*
* @var int * @var int
*/ */
protected $offset = 0; protected $offset = 0;
@ -47,18 +50,15 @@ Class EventDispatcher {
* *
* @return EventDispatcher * @return EventDispatcher
*/ */
public static function getInstance(){ public static function getInstance()
{
if (self::$instance === null) { if (self::$instance === null) {
self::$instance = new self(); self::$instance = new self();
} }
return self::$instance; return self::$instance;
} }
/**
* Make constructor unavailable for client code
*/
protected function __constructor() {}
/** /**
* Attaches listener function to event. * Attaches listener function to event.
* *
@ -67,16 +67,18 @@ Class EventDispatcher {
* @param string $event_name Event's name * @param string $event_name Event's name
* @param \Mibew\Plugin $plugin Plugin object, that handles the event * @param \Mibew\Plugin $plugin Plugin object, that handles the event
* @param string $listener Plugins method, that handles the event * @param string $listener Plugins method, that handles the event
* @param int $priority Priority of listener. If $priority = null, the plugin weight will * @param int $priority Priority of listener. If $priority = null, the
* use instead. * plugin weight will use instead.
* @return boolean true on success or false on failure. * @return boolean true on success or false on failure.
* *
* @see \Mibew\Plugin::getWeight() * @see \Mibew\Plugin::getWeight()
*/ */
public function attachListener($event_name, Plugin $plugin, $listener, $priority = null){ public function attachListener($event_name, Plugin $plugin, $listener, $priority = null)
{
// Check method is callable // Check method is callable
if (!is_callable(array($plugin, $listener))) { if (!is_callable(array($plugin, $listener))) {
trigger_error("Method '{$listener}' is not callable!", E_USER_WARNING); trigger_error("Method '{$listener}' is not callable!", E_USER_WARNING);
return false; return false;
} }
// Create empty array for event listener if it not exists // Create empty array for event listener if it not exists
@ -90,9 +92,10 @@ Class EventDispatcher {
// Attach listener // Attach listener
$this->events[$event_name][$priority . "_" . $this->offset] = array( $this->events[$event_name][$priority . "_" . $this->offset] = array(
'plugin' => $plugin, 'plugin' => $plugin,
'listener' => $listener 'listener' => $listener,
); );
$this->offset++; $this->offset++;
return true; return true;
} }
@ -104,7 +107,8 @@ Class EventDispatcher {
* @param string $listener Plugins method, that handles the event * @param string $listener Plugins method, that handles the event
* @return boolean true on success or false on failure. * @return boolean true on success or false on failure.
*/ */
public function detachListener($event_name, Plugin $plugin, $listener){ public function detachListener($event_name, Plugin $plugin, $listener)
{
// Check event exists // Check event exists
if (!array_key_exists($event_name, $this->events)) { if (!array_key_exists($event_name, $this->events)) {
return false; return false;
@ -114,9 +118,11 @@ Class EventDispatcher {
if ($event['plugin'] === $plugin && $event['listener'] == $listener) { if ($event['plugin'] === $plugin && $event['listener'] == $listener) {
// Detach listener // Detach listener
unset($this->events[$event_name][$index]); unset($this->events[$event_name][$index]);
return true; return true;
} }
} }
return false; return false;
} }
@ -127,7 +133,8 @@ Class EventDispatcher {
* @param array &$arguments Arguments passed to listener * @param array &$arguments Arguments passed to listener
* @return boolean true on success or false on failure * @return boolean true on success or false on failure
*/ */
public function triggerEvent($event_name, &$arguments = array()){ public function triggerEvent($event_name, &$arguments = array())
{
// Check event listeners exists // Check event listeners exists
if (!array_key_exists($event_name, $this->events)) { if (!array_key_exists($event_name, $this->events)) {
return true; return true;
@ -140,9 +147,14 @@ Class EventDispatcher {
$listener = $event['listener']; $listener = $event['listener'];
$plugin->$listener($arguments); $plugin->$listener($arguments);
} }
return true; return true;
} }
/**
* Make constructor unavailable for client code
*/
protected function __constructor()
{
}
} }
?>

View File

@ -20,8 +20,8 @@ namespace Mibew;
/** /**
* Base plugin class * Base plugin class
*/ */
abstract Class Plugin { abstract class Plugin
{
/** /**
* Constructor must set this value to true after successful initialization * Constructor must set this value to true after successful initialization
* failures * failures
@ -36,8 +36,8 @@ abstract Class Plugin {
protected $config = array(); protected $config = array();
/** /**
* Returns plugin weight. Weight is used for determine loading order and as default * Returns plugin weight. Weight is used for determine loading order and as
* listner priority. * default listner priority.
* *
* @return int Plugin weight * @return int Plugin weight
*/ */
@ -63,9 +63,8 @@ abstract Class Plugin {
* *
* @return array List of plugin's dependences. * @return array List of plugin's dependences.
*/ */
public static function getDependences() { public static function getDependences()
{
return array(); return array();
} }
} }
?>

View File

@ -20,13 +20,14 @@ namespace Mibew;
/** /**
* Manage plugins * Manage plugins
*/ */
Class PluginManager { class PluginManager
{
/** /**
* Contains all loaded plugins * Contains all loaded plugins
*
* @var array * @var array
*/ */
protected static $loaded_plugins = array(); protected static $loadedPlugins = array();
/** /**
* Returns plugin object * Returns plugin object
@ -34,14 +35,16 @@ Class PluginManager {
* @param string $plugin_name * @param string $plugin_name
* @return \Mibew\Plugin * @return \Mibew\Plugin
*/ */
public static function getPlugin($plugin_name) { public static function getPlugin($plugin_name)
if (empty(self::$loaded_plugins[$plugin_name])) { {
if (empty(self::$loadedPlugins[$plugin_name])) {
trigger_error( trigger_error(
"Plugin '{$plugin_name}' does not initialized!", "Plugin '{$plugin_name}' does not initialized!",
E_USER_WARNING E_USER_WARNING
); );
} }
return self::$loaded_plugins[$plugin_name];
return self::$loadedPlugins[$plugin_name];
} }
/** /**
@ -51,8 +54,9 @@ Class PluginManager {
* *
* @return array * @return array
*/ */
public static function getAllPlugins() { public static function getAllPlugins()
return self::$loaded_plugins; {
return self::$loadedPlugins;
} }
/** /**
@ -76,7 +80,8 @@ Class PluginManager {
* *
* @see Plugin::registerListeners() * @see Plugin::registerListeners()
*/ */
public static function loadPlugins($plugins_list){ public static function loadPlugins($plugins_list)
{
// Add include path // Add include path
$include_path = get_include_path(); $include_path = get_include_path();
$include_path .= empty($include_path) ? '' : PATH_SEPARATOR; $include_path .= empty($include_path) ? '' : PATH_SEPARATOR;
@ -112,26 +117,22 @@ Class PluginManager {
} }
// Check if plugin extends abstract 'Plugin' class // Check if plugin extends abstract 'Plugin' class
if ('Mibew\\Plugin' != get_parent_class($plugin_classname)) { if ('Mibew\\Plugin' != get_parent_class($plugin_classname)) {
trigger_error( $error_essage = "Plugin class '{$plugin_classname}' does not "
"Plugin class '{$plugin_classname}' does not extend " . . "extend abstract '\\Mibew\\Plugin' class!";
"abstract '\\Mibew\\Plugin' class!", trigger_error($error_essage, E_USER_WARNING);
E_USER_WARNING
);
continue; continue;
} }
// Check plugin dependences // Check plugin dependences
$plugin_dependences = call_user_func(array( $plugin_dependences = call_user_func(array(
$plugin_classname, $plugin_classname,
'getDependences' 'getDependences',
)); ));
foreach ($plugin_dependences as $dependence) { foreach ($plugin_dependences as $dependence) {
if (empty(self::$loaded_plugins[$dependence])) { if (empty(self::$loadedPlugins[$dependence])) {
trigger_error( $error_essage = "Plugin '{$dependence}' was not loaded "
"Plugin '{$dependence}' was not loaded yet, but " . . "yet, but exists in '{$plugin_name}' dependences list!";
"exists in '{$plugin_name}' dependences list!", trigger_error($error_essage, E_USER_WARNING);
E_USER_WARNING
);
continue 2; continue 2;
} }
} }
@ -140,7 +141,7 @@ Class PluginManager {
$plugin_instance = new $plugin_classname($plugin_config); $plugin_instance = new $plugin_classname($plugin_config);
if ($plugin_instance->initialized) { if ($plugin_instance->initialized) {
// Store plugin instance // Store plugin instance
self::$loaded_plugins[$plugin_name] = $plugin_instance; self::$loadedPlugins[$plugin_name] = $plugin_instance;
$loading_queue[$plugin_instance->getWeight() . "_" . $offset] = $plugin_instance; $loading_queue[$plugin_instance->getWeight() . "_" . $offset] = $plugin_instance;
$offset++; $offset++;
} else { } else {
@ -158,5 +159,3 @@ Class PluginManager {
} }
} }
} }
?>

View File

@ -24,7 +24,8 @@ use Mibew\Database;
* Base class for all request processors that interact with JavaScript * Base class for all request processors that interact with JavaScript
* applications at the client side. * applications at the client side.
*/ */
abstract class ClientSideProcessor extends Processor { abstract class ClientSideProcessor extends Processor
{
/** /**
* Call function at client side * Call function at client side
@ -34,7 +35,8 @@ abstract class ClientSideProcessor extends Processor {
* @param array|null $callback callback array for synchronous requests. * @param array|null $callback callback array for synchronous requests.
* @return mixed request result or boolean false on failure. * @return mixed request result or boolean false on failure.
*/ */
public function call($functions, $callback = null) { public function call($functions, $callback = null)
{
return parent::call($functions, true, $callback); return parent::call($functions, true, $callback);
} }
@ -44,7 +46,8 @@ abstract class ClientSideProcessor extends Processor {
* @param array $responses An array of the 'Request' arrays. See Mibew API * @param array $responses An array of the 'Request' arrays. See Mibew API
* for details * for details
*/ */
protected function sendAsyncResponses($responses) { protected function sendAsyncResponses($responses)
{
header("Content-type: text/plain; charset=UTF-8"); header("Content-type: text/plain; charset=UTF-8");
echo($this->mibewAPI->encodePackage( echo($this->mibewAPI->encodePackage(
$responses, $responses,
@ -60,7 +63,8 @@ abstract class ClientSideProcessor extends Processor {
* @param String $key Request key. Use to load request from buffer. * @param String $key Request key. Use to load request from buffer.
* @param $request Request array. * @param $request Request array.
*/ */
protected function addRequestToBuffer($key, $request) { protected function addRequestToBuffer($key, $request)
{
// Save request to database // Save request to database
$db = Database::getInstance(); $db = Database::getInstance();
$db->query( $db->query(
@ -75,7 +79,8 @@ abstract class ClientSideProcessor extends Processor {
* @param String $key Request key * @param String $key Request key
* @return array Array of requests with given key * @return array Array of requests with given key
*/ */
protected function getRequestsFromBuffer($key) { protected function getRequestsFromBuffer($key)
{
$db = Database::getInstance(); $db = Database::getInstance();
$key = md5($key); $key = md5($key);
@ -96,9 +101,7 @@ abstract class ClientSideProcessor extends Processor {
foreach ($requests as $request_info) { foreach ($requests as $request_info) {
$result[] = unserialize($request_info['request']); $result[] = unserialize($request_info['request']);
} }
return $result; return $result;
} }
} }
?>

View File

@ -20,11 +20,10 @@ namespace Mibew\RequestProcessor\Exception;
/** /**
* Class for {@link \Mibew\RequestProcessor\InviteRequestProcessor} exceptions * Class for {@link \Mibew\RequestProcessor\InviteRequestProcessor} exceptions
*/ */
class InviteProcessorException extends ProcessorException { class InviteProcessorException extends ProcessorException
{
/** /**
* Operator is not logged in * Operator is not logged in
*/ */
const ERROR_AGENT_NOT_LOGGED_IN = 1; const ERROR_AGENT_NOT_LOGGED_IN = 1;
} }
?>

View File

@ -20,11 +20,10 @@ namespace Mibew\RequestProcessor\Exception;
/** /**
* Class for {@link \Mibew\RequestProcessor\Processor} exceptions. * Class for {@link \Mibew\RequestProcessor\Processor} exceptions.
*/ */
class ProcessorException extends \Exception { class ProcessorException extends \Exception
{
/** /**
* Wrong function arguments * Wrong function arguments
*/ */
const WRONG_ARGUMENTS = 1; const WRONG_ARGUMENTS = 1;
} }
?>

View File

@ -20,7 +20,8 @@ namespace Mibew\RequestProcessor\Exception;
/** /**
* Class for {@link \Mibew\RequestProcessor\ThreadProcessor} exceptions. * Class for {@link \Mibew\RequestProcessor\ThreadProcessor} exceptions.
*/ */
class ThreadProcessorException extends ProcessorException { class ThreadProcessorException extends ProcessorException
{
/** /**
* 'recipient' argument is not set * 'recipient' argument is not set
*/ */
@ -66,5 +67,3 @@ class ThreadProcessorException extends ProcessorException {
*/ */
const ERROR_WRONG_EMAIL = 11; const ERROR_WRONG_EMAIL = 11;
} }
?>

View File

@ -20,7 +20,8 @@ namespace Mibew\RequestProcessor\Exception;
/** /**
* Class for {@link \Mibew\RequestProcessor\UsersProcessor} exceptions * Class for {@link \Mibew\RequestProcessor\UsersProcessor} exceptions
*/ */
class UsersProcessorException extends ProcessorException { class UsersProcessorException extends ProcessorException
{
/** /**
* Operator is not logged in * Operator is not logged in
*/ */
@ -34,5 +35,3 @@ class UsersProcessorException extends ProcessorException {
*/ */
const VARIOUS_AGENT_ID = 3; const VARIOUS_AGENT_ID = 3;
} }
?>

View File

@ -33,22 +33,26 @@ use Mibew\RequestProcessor\Exception\InviteProcessorException;
* *
* Implements Singleton pattern * Implements Singleton pattern
*/ */
class InviteProcessor extends ClientSideProcessor { class InviteProcessor extends ClientSideProcessor
{
/** /**
* An instance of the InviteProcessor class * An instance of the InviteProcessor class
*
* @var \Mibew\RequestProcessor\InviteProcessor * @var \Mibew\RequestProcessor\InviteProcessor
*/ */
protected static $instance = null; protected static $instance = null;
/** /**
* Return an instance of the InviteProcessor class. * Return an instance of the InviteProcessor class.
*
* @return \Mibew\RequestProcessor\InviteProcessor * @return \Mibew\RequestProcessor\InviteProcessor
*/ */
public static function getInstance() { public static function getInstance()
{
if (is_null(self::$instance)) { if (is_null(self::$instance)) {
self::$instance = new self(); self::$instance = new self();
} }
return self::$instance; return self::$instance;
} }
@ -57,9 +61,11 @@ class InviteProcessor extends ClientSideProcessor {
* *
* Do not use directly __construct method! Use * Do not use directly __construct method! Use
* \Mibew\RequestProcessor\InviteProcessor::getInstance() instead! * \Mibew\RequestProcessor\InviteProcessor::getInstance() instead!
*
* @todo Think about why the method is not protected * @todo Think about why the method is not protected
*/ */
public function __construct() { public function __construct()
{
parent::__construct(array( parent::__construct(array(
'signature' => '', 'signature' => '',
'trusted_signatures' => array(''), 'trusted_signatures' => array(''),
@ -72,7 +78,8 @@ class InviteProcessor extends ClientSideProcessor {
* *
* @return \Mibew\API\API * @return \Mibew\API\API
*/ */
protected function getMibewAPIInstance() { protected function getMibewAPIInstance()
{
return MibewAPI::getAPI('\\Mibew\\API\\Interaction\\InviteInteraction'); return MibewAPI::getAPI('\\Mibew\\API\\Interaction\\InviteInteraction');
} }
@ -80,9 +87,11 @@ class InviteProcessor extends ClientSideProcessor {
* Stub for sendAsyncRequest method. * Stub for sendAsyncRequest method.
* *
* Actually request not send to client side. This method is ONLY STUB. * Actually request not send to client side. This method is ONLY STUB.
*
* @return boolean Always true * @return boolean Always true
*/ */
protected function sendAsyncRequest() { protected function sendAsyncRequest()
{
return true; return true;
} }
@ -90,9 +99,11 @@ class InviteProcessor extends ClientSideProcessor {
* Stub for call method. * Stub for call method.
* *
* Actually nothing can be called at client side. This method is ONLY STUB. * Actually nothing can be called at client side. This method is ONLY STUB.
*
* @return boolean Always false. * @return boolean Always false.
*/ */
public function call() { public function call()
{
return false; return false;
} }
@ -104,9 +115,11 @@ class InviteProcessor extends ClientSideProcessor {
* - 'visitorId': Id of the invited visitor * - 'visitorId': Id of the invited visitor
* @return array Array of results. It contains following keys: * @return array Array of results. It contains following keys:
* - 'invited': boolean, indicates if visitor is invited * - 'invited': boolean, indicates if visitor is invited
* - 'threadId': thread id related to visitor or false if there is no thread * - 'threadId': thread id related to visitor or false if there is no
* thread
*/ */
protected function apiInvitationState($args) { protected function apiInvitationState($args)
{
$operator = get_logged_in(); $operator = get_logged_in();
if (!$operator) { if (!$operator) {
throw new InviteProcessorException( throw new InviteProcessorException(
@ -116,11 +129,10 @@ class InviteProcessor extends ClientSideProcessor {
} }
$invitation = invitation_state($args['visitorId']); $invitation = invitation_state($args['visitorId']);
return array( return array(
'invited' => (bool) $invitation['invited'], 'invited' => (bool) $invitation['invited'],
'threadId' => ($invitation['threadid'] ? $invitation['threadid'] : false) 'threadId' => ($invitation['threadid'] ? $invitation['threadid'] : false),
); );
} }
} }
?>

View File

@ -92,28 +92,32 @@ use Mibew\RequestProcessor\Exception\ProcessorException;
* *
* @see \Mibew\RequestProcessor\Processor::__construct() * @see \Mibew\RequestProcessor\Processor::__construct()
*/ */
abstract class Processor { abstract class Processor
{
/** /**
* Instance of the MibewAPI class * Instance of the MibewAPI class
*
* @var \Mibew\API\API * @var \Mibew\API\API
*/ */
protected $mibewAPI = null; protected $mibewAPI = null;
/** /**
* Prefix that uses for all events triggered by the class. * Prefix that uses for all events triggered by the class.
*
* @var string * @var string
*/ */
protected $eventPrefix = ''; protected $eventPrefix = '';
/** /**
* Array of the responses packages * Array of the responses packages
*
* @var array * @var array
*/ */
protected $responses = array(); protected $responses = array();
/** /**
* Array of configurations * Array of configurations
*
* @var array * @var array
*/ */
protected $config = array(); protected $config = array();
@ -124,14 +128,15 @@ abstract class Processor {
* @param type $config Configuration data. * @param type $config Configuration data.
* It must contains following keys: * It must contains following keys:
* - 'signature': Use for verification sender * - 'signature': Use for verification sender
* - 'trusted_signatures': array of trusted signatures. Uses for identify another * - 'trusted_signatures': array of trusted signatures. Uses for identify
* side of interaction. * another side of interaction.
* And may contains following (if not default values will be used) * And may contains following (if not default values will be used)
* - 'event_prefix': prefix that uses for all events triggered by the * - 'event_prefix': prefix that uses for all events triggered by the
* class. The default value is the class name with first character in * class. The default value is the class name with first character in
* lower case * lower case
*/ */
public function __construct($config) { public function __construct($config)
{
// Check signature // Check signature
if (!isset($config['signature'])) { if (!isset($config['signature'])) {
trigger_error("Signature is not specified", E_USER_ERROR); trigger_error("Signature is not specified", E_USER_ERROR);
@ -159,13 +164,15 @@ abstract class Processor {
/** /**
* Proccess received packages * Proccess received packages
* *
* On any error function returns only boolean false. To handle error add listener to the * On any error function returns only boolean false. To handle error add
* "<eventPrefix>RequestError" event. * listener to the "<eventPrefix>RequestError" event.
* *
* @param string $package Encoded package * @param string $package Encoded package
* @return boolean true if request processed succussfully or false on failure * @return boolean true if request processed succussfully or false on
* failure
*/ */
public function receiveRequest($package){ public function receiveRequest($package)
{
$dispatcher = EventDispatcher::getInstance(); $dispatcher = EventDispatcher::getInstance();
// Try to handle request // Try to handle request
try { try {
@ -245,23 +252,27 @@ abstract class Processor {
// Something went wrong. Trigger error event // Something went wrong. Trigger error event
$vars = array('exception' => $e); $vars = array('exception' => $e);
$dispatcher->triggerEvent($this->eventPrefix . 'RequestError', $vars); $dispatcher->triggerEvent($this->eventPrefix . 'RequestError', $vars);
return false; return false;
} }
return true; return true;
} }
/** /**
* Call functions at the other side * Call functions at the other side
* *
* On any error function returns only boolean false. To handle error add listener to the * On any error function returns only boolean false. To handle error add
* "<eventPrefix>CallError" event. * listener to the "<eventPrefix>CallError" event.
* *
* @param array $functions Array of functions. See Mibew API for details. * @param array $functions Array of functions. See Mibew API for details.
* @param boolean $async True for asynchronous requests and false for synchronous request * @param boolean $async True for asynchronous requests and false for
* synchronous request
* @param mixed $callback callback array or null for synchronous requests. * @param mixed $callback callback array or null for synchronous requests.
* @return mixed request result or boolean false on failure. * @return mixed request result or boolean false on failure.
*/ */
public function call($functions, $async, $callback = null) { public function call($functions, $async, $callback = null)
{
// Get an instance of the \Mibew\EventDispatcher class // Get an instance of the \Mibew\EventDispatcher class
$dispatcher = EventDispatcher::getInstance(); $dispatcher = EventDispatcher::getInstance();
// Try to call function at Other side // Try to call function at Other side
@ -279,7 +290,8 @@ abstract class Processor {
} }
// Create request // Create request
// TODO: evaluate a possibility of using more secure method of the generation of token // TODO: evaluate a possibility of using more secure method of the
// generation of token
$token = md5(microtime() . rand()); $token = md5(microtime() . rand());
$request = array( $request = array(
'token' => $token, 'token' => $token,
@ -317,8 +329,10 @@ abstract class Processor {
// Trigger error event // Trigger error event
$vars = array('exception' => $e); $vars = array('exception' => $e);
$dispatcher->triggerEvent($this->eventPrefix . "CallError", $vars); $dispatcher->triggerEvent($this->eventPrefix . "CallError", $vars);
return false; return false;
} }
return $result; return $result;
} }
@ -326,12 +340,13 @@ abstract class Processor {
* Process request * Process request
* *
* @param array $request 'Requests' array. See Mibew API for details. * @param array $request 'Requests' array. See Mibew API for details.
* @param mixed $result_function Control existance of the 'result' function in request. * @param mixed $result_function Control existance of the 'result' function
* Use boolean true if 'result' function must exists in request, boolean false if must not * in request. Use boolean true if 'result' function must exists in
* and null if it doesn't matter. * request, boolean false if must not and null if it doesn't matter.
* @return array Array of requests results. * @return array Array of requests results.
*/ */
protected function processRequest($request, $result_function = null) { protected function processRequest($request, $result_function = null)
{
$context = new \Mibew\API\ExecutionContext(); $context = new \Mibew\API\ExecutionContext();
// Get result functions // Get result functions
@ -356,6 +371,7 @@ abstract class Processor {
break; break;
} }
} }
return $context->getResults(); return $context->getResults();
} else { } else {
// Return result // Return result
@ -368,16 +384,18 @@ abstract class Processor {
* *
* @param array $function 'Function' array. See Mibew API for details * @param array $function 'Function' array. See Mibew API for details
* @param \Mibew\API\ExecutionContext &$context Execution context * @param \Mibew\API\ExecutionContext &$context Execution context
* @return boolean lase if function returns errorCode and errorCode differs from 0. * @return boolean lase if function returns errorCode and errorCode differs
* from 0.
*/ */
protected function processFunction($function, \Mibew\API\ExecutionContext &$context) { protected function processFunction($function, \Mibew\API\ExecutionContext &$context)
{
// Get function arguments with replaced references // Get function arguments with replaced references
$arguments = $context->getArgumentsList($function); $arguments = $context->getArgumentsList($function);
$call_vars = array( $call_vars = array(
'function' => $function['function'], 'function' => $function['function'],
'arguments' => $arguments, 'arguments' => $arguments,
'results' => array() 'results' => array(),
); );
// Call processor function // Call processor function
@ -401,25 +419,30 @@ abstract class Processor {
* Stores callback function * Stores callback function
* *
* Callback is an associative array with following keys * Callback is an associative array with following keys
* - 'function': function name to call * - 'function': function name to call.
* - 'arguments': additional arguments, that passed to the callback function * - 'arguments': additional arguments, that passed to the callback
* function.
* *
* @param string $token Request token * @param string $token Request token
* @param array $callback Callback function array * @param array $callback Callback function array
* @todo Create some unit tests * @todo Create some unit tests
*/ */
protected function saveCallback($token, $callback) { protected function saveCallback($token, $callback)
{
$db = Database::getInstance(); $db = Database::getInstance();
$query = "INSERT INTO {requestcallback} ( "
. "token, function, arguments "
. ") VALUES ( "
. ":token, :function, :arguments"
. ")";
$db->query( $db->query(
"INSERT INTO {requestcallback} ( ". $query,
"token, function, arguments ".
") VALUES ( " .
":token, :function, :arguments" .
")",
array( array(
':token' => $token, ':token' => $token,
':function' => $callback['function'], ':function' => $callback['function'],
':arguments' => serialize($callback['arguments']) ':arguments' => serialize($callback['arguments']),
) )
); );
} }
@ -428,14 +451,17 @@ abstract class Processor {
* Loads callback function * Loads callback function
* *
* Callback is an associative array with following keys * Callback is an associative array with following keys
* - 'function': function name to call * - 'function': function name to call.
* - 'arguments': additional arguments, that passed to the callback function * - 'arguments': additional arguments, that passed to the callback
* function.
* *
* @param string $token Token of the request related to callback function * @param string $token Token of the request related to callback function
* @return mixed callback function array or null if callback function not exists * @return mixed callback function array or null if callback function not
* exists
* @todo Create some unit tests * @todo Create some unit tests
*/ */
protected function loadCallback($token) { protected function loadCallback($token)
{
$db = Database::getInstance(); $db = Database::getInstance();
$callback = $db->query( $callback = $db->query(
"SELECT * FROM {requestcallback} WHERE token = :token", "SELECT * FROM {requestcallback} WHERE token = :token",
@ -445,22 +471,26 @@ abstract class Processor {
if (!$callback) { if (!$callback) {
return null; return null;
} }
return array( return array(
'function' => $callback['function'], 'function' => $callback['function'],
'arguments' => unserialize($callback['arguments']) 'arguments' => unserialize($callback['arguments']),
); );
} }
/** /**
* Dispatcher of the functions, provided by the RequestProcessor (or inherited) classes as an external API. * Dispatcher of the functions, provided by the RequestProcessor
* (or inherited) classes as an external API.
* *
* All API methods names starts with 'api' prefix. * All API methods names starts with 'api' prefix.
* It calls before '<eventPrefix>FunctionCall' event triggers. * It calls before '<eventPrefix>FunctionCall' event triggers.
* *
* @param array &$func Function array equals to array, passed to the '<eventPrefix>FunctionCall' event. * @param array &$func Function array equals to array, passed to the
* '<eventPrefix>FunctionCall' event.
* @todo Create some unit tests * @todo Create some unit tests
*/ */
protected function processorCall(&$func) { protected function processorCall(&$func)
{
$method_name = 'api' . ucfirst($func['function']); $method_name = 'api' . ucfirst($func['function']);
if (is_callable(array($this, $method_name))) { if (is_callable(array($this, $method_name))) {
try { try {
@ -468,7 +498,7 @@ abstract class Processor {
} catch (ProcessorException $e) { } catch (ProcessorException $e) {
$func['results'] = array( $func['results'] = array(
'errorCode' => $e->getCode(), 'errorCode' => $e->getCode(),
'errorMessage' => $e->getMessage() 'errorMessage' => $e->getMessage(),
); );
} }
} }
@ -480,7 +510,8 @@ abstract class Processor {
* @param array $request The 'request' array. See Mibew API for details * @param array $request The 'request' array. See Mibew API for details
* @return mixed response array or boolean false on failure * @return mixed response array or boolean false on failure
*/ */
protected function sendSyncRequest($request) { protected function sendSyncRequest($request)
{
trigger_error('Method sendSyncRequest does not implement!', E_USER_WARNING); trigger_error('Method sendSyncRequest does not implement!', E_USER_WARNING);
} }
@ -490,25 +521,30 @@ abstract class Processor {
* @param array $request The 'request' array. See Mibew API for details * @param array $request The 'request' array. See Mibew API for details
* @return boolean true on success or false on failure * @return boolean true on success or false on failure
*/ */
protected function sendAsyncRequest($request) { protected function sendAsyncRequest($request)
{
trigger_error('Method sendAsyncRequest does not implement!', E_USER_WARNING); trigger_error('Method sendAsyncRequest does not implement!', E_USER_WARNING);
} }
/** /**
* Sends synchronous responses * Sends synchronous responses
* *
* @param array $responses An array of the 'Request' arrays. See Mibew API for details * @param array $responses An array of the 'Request' arrays. See Mibew API
* for details
*/ */
protected function sendSyncResponses($responses) { protected function sendSyncResponses($responses)
{
trigger_error('Method sendSyncResponses does not implement!', E_USER_WARNING); trigger_error('Method sendSyncResponses does not implement!', E_USER_WARNING);
} }
/** /**
* Sends asynchronous responses * Sends asynchronous responses
* *
* @param array $responses An array of the 'Request' arrays. See Mibew API for details * @param array $responses An array of the 'Request' arrays. See Mibew API
* for details
*/ */
protected function sendAsyncResponses($responses) { protected function sendAsyncResponses($responses)
{
trigger_error('Method sendAsyncResponses does not implement!', E_USER_WARNING); trigger_error('Method sendAsyncResponses does not implement!', E_USER_WARNING);
} }
@ -519,14 +555,14 @@ abstract class Processor {
* *
* @param Array $function A Function array * @param Array $function A Function array
*/ */
protected function checkFunction($function) {} protected function checkFunction($function)
{
}
/** /**
* Creates and returns an instance of the \Mibew\API\API class. * Creates and returns an instance of the \Mibew\API\API class.
* *
* @return \Mibew\API\API * @return \Mibew\API\API
*/ */
protected abstract function getMibewAPIInstance(); abstract protected function getMibewAPIInstance();
} }
?>

View File

@ -39,22 +39,26 @@ use Mibew\RequestProcessor\Exception\ThreadProcessorException;
* *
* Implements Singleton pattern * Implements Singleton pattern
*/ */
class ThreadProcessor extends ClientSideProcessor { class ThreadProcessor extends ClientSideProcessor
{
/** /**
* An instance of the ThreadProcessor class * An instance of the ThreadProcessor class
*
* @var \Mibew\RequestProcessor\ThreadProcessor * @var \Mibew\RequestProcessor\ThreadProcessor
*/ */
protected static $instance = null; protected static $instance = null;
/** /**
* Return an instance of the ThreadProcessor class. * Return an instance of the ThreadProcessor class.
*
* @return \Mibew\RequestProcessor\ThreadProcessor * @return \Mibew\RequestProcessor\ThreadProcessor
*/ */
public static function getInstance() { public static function getInstance()
{
if (is_null(self::$instance)) { if (is_null(self::$instance)) {
self::$instance = new self(); self::$instance = new self();
} }
return self::$instance; return self::$instance;
} }
@ -66,7 +70,8 @@ class ThreadProcessor extends ClientSideProcessor {
* @return \Mibew\Thread * @return \Mibew\Thread
* @throws \Mibew\RequestProcessor\ThreadProcessorException * @throws \Mibew\RequestProcessor\ThreadProcessorException
*/ */
public static function getThread($thread_id, $last_token) { public static function getThread($thread_id, $last_token)
{
// Load thread // Load thread
$thread = Thread::load($thread_id, $last_token); $thread = Thread::load($thread_id, $last_token);
// Check thread // Check thread
@ -76,6 +81,7 @@ class ThreadProcessor extends ClientSideProcessor {
ThreadProcessorException::ERROR_WRONG_THREAD ThreadProcessorException::ERROR_WRONG_THREAD
); );
} }
// Return thread // Return thread
return $thread; return $thread;
} }
@ -87,7 +93,8 @@ class ThreadProcessor extends ClientSideProcessor {
* @param array $vars Array of arguments names that must be checked * @param array $vars Array of arguments names that must be checked
* @throws \Mibew\RequestProcessor\ThreadProcessorException * @throws \Mibew\RequestProcessor\ThreadProcessorException
*/ */
public static function checkParams($args, $vars) { public static function checkParams($args, $vars)
{
if (empty($vars)) { if (empty($vars)) {
return; return;
} }
@ -109,27 +116,31 @@ class ThreadProcessor extends ClientSideProcessor {
* @throws \Mibew\RequestProcessor\ThreadProcessorException If operator is * @throws \Mibew\RequestProcessor\ThreadProcessorException If operator is
* not logged in. * not logged in.
*/ */
public static function checkOperator() { public static function checkOperator()
{
$operator = get_logged_in(); $operator = get_logged_in();
if (!$operator) { if (!$operator) {
throw new ThreadProcessorException( throw new ThreadProcessorException(
"Operator not logged in!", "Operator is not logged in!",
ThreadProcessorException::ERROR_AGENT_NOT_LOGGED_IN ThreadProcessorException::ERROR_AGENT_NOT_LOGGED_IN
); );
} }
return $operator; return $operator;
} }
/** /**
* Class constructor * Class constructor
* *
* Do not use directly __construct method! Use ThreadProcessor::getInstance() instead! * Do not use directly __construct method! Use
* \Mibew\RequestProcessor\ThreadProcessor::getInstance() instead!
*/ */
public function __construct() { public function __construct()
{
parent::__construct(array( parent::__construct(array(
'signature' => '', 'signature' => '',
'trusted_signatures' => array(''), 'trusted_signatures' => array(''),
'event_prefix' => 'thread' 'event_prefix' => 'thread',
)); ));
} }
@ -138,7 +149,8 @@ class ThreadProcessor extends ClientSideProcessor {
* *
* @return \Mibew\API\API * @return \Mibew\API\API
*/ */
protected function getMibewAPIInstance() { protected function getMibewAPIInstance()
{
return MibewAPI::getAPI('\\Mibew\\API\\Interaction\\ChatInteraction'); return MibewAPI::getAPI('\\Mibew\\API\\Interaction\\ChatInteraction');
} }
@ -148,7 +160,8 @@ class ThreadProcessor extends ClientSideProcessor {
* @param array $request The 'request' array. See Mibew API for details * @param array $request The 'request' array. See Mibew API for details
* @return boolean true on success or false on failure * @return boolean true on success or false on failure
*/ */
protected function sendAsyncRequest($request) { protected function sendAsyncRequest($request)
{
// Define empty thread id and thread token // Define empty thread id and thread token
$thread_id = null; $thread_id = null;
$token = null; $token = null;
@ -162,8 +175,9 @@ class ThreadProcessor extends ClientSideProcessor {
continue; continue;
} }
// Check thread id and thread token for the remaining functions // Check thread id and thread token for the remaining functions
if ($thread_id != $function['arguments']['threadId'] $wrong_thread_id = $thread_id != $function['arguments']['threadId'];
|| $token != $function['arguments']['token']) { $wrong_token = $token != $function['arguments']['token'];
if ($wrong_thread_id || $wrong_token) {
throw new ThreadProcessorException( throw new ThreadProcessorException(
'Various thread id or thread token in different functions in one package!', 'Various thread id or thread token in different functions in one package!',
ThreadProcessorException::VARIOUS_THREAD_ID ThreadProcessorException::VARIOUS_THREAD_ID
@ -184,6 +198,7 @@ class ThreadProcessor extends ClientSideProcessor {
if ($recipient == 'user' || $recipient == 'both') { if ($recipient == 'user' || $recipient == 'both') {
$this->addRequestToBuffer('thread_user_' . $thread_id, $request); $this->addRequestToBuffer('thread_user_' . $thread_id, $request);
} }
return true; return true;
} }
@ -192,19 +207,18 @@ class ThreadProcessor extends ClientSideProcessor {
* *
* @param Array $function A Function array * @param Array $function A Function array
*/ */
protected function checkFunction($function) { protected function checkFunction($function)
{
// Check recipient argument existance // Check recipient argument existance
if (!array_key_exists('recipient', $function['arguments'])) { if (!array_key_exists('recipient', $function['arguments'])) {
throw new ThreadProcessorException( throw new ThreadProcessorException(
"'recipient' argument is not set in function '{function['function]}'!", "'recipient' argument is not set in function '{$function['function']}'!",
ThreadProcessorException::EMPTY_RECIPIENT ThreadProcessorException::EMPTY_RECIPIENT
); );
} }
$recipient = $function['arguments']['recipient']; $recipient = $function['arguments']['recipient'];
// Check recipient value // Check recipient value
if ($recipient != 'agent' if ($recipient != 'agent' && $recipient != 'both' && $recipient != 'user') {
&& $recipient != 'both'
&& $recipient != 'user') {
throw new ThreadProcessorException( throw new ThreadProcessorException(
"Wrong recipient value '{$recipient}'! It should be one of 'agent', 'user', 'both'", "Wrong recipient value '{$recipient}'! It should be one of 'agent', 'user', 'both'",
ThreadProcessorException::WRONG_RECIPIENT_VALUE ThreadProcessorException::WRONG_RECIPIENT_VALUE
@ -216,17 +230,21 @@ class ThreadProcessor extends ClientSideProcessor {
* Update chat window state. API function * Update chat window state. API function
* *
* Call periodically by chat window * Call periodically by chat window
* @param array $args Associative array of arguments. It must contains following keys: * @param array $args Associative array of arguments. It must contains
* following keys:
* - 'threadId': Id of the thread related to chat window * - 'threadId': Id of the thread related to chat window
* - 'token': last thread token * - 'token': last thread token
* - 'user': TRUE if window used by user and FALSE otherwise * - 'user': TRUE if window used by user and FALSE otherwise
* - 'typed': indicates if user(or agent) typed * - 'typed': indicates if user(or agent) typed
* - 'lastId': id of the last sent to message * - 'lastId': id of the last sent to message
* @return array Array of results. It contains following keys: * @return array Array of results. It contains following keys:
* - 'typing': indicates if another side of the conversation is typing message * - 'typing': indicates if another side of the conversation is typing
* - 'canPost': indicates if agent(user can post message all the time) can post the message * message
* - 'canPost': indicates if agent(user can post message all the time)
* can post the message
*/ */
protected function apiUpdate($args) { protected function apiUpdate($args)
{
// Load thread // Load thread
$thread = self::getThread($args['threadId'], $args['token']); $thread = self::getThread($args['threadId'], $args['token']);
@ -260,28 +278,32 @@ class ThreadProcessor extends ClientSideProcessor {
// Get status values // Get status values
if ($args['user']) { if ($args['user']) {
$is_typing = abs($thread->lastPingAgent - time()) < Thread::CONNECTION_TIMEOUT && $thread->agentTyping; $is_typing = abs($thread->lastPingAgent - time()) < Thread::CONNECTION_TIMEOUT
&& $thread->agentTyping;
} else { } else {
$is_typing = abs($thread->lastPingUser - time()) < Thread::CONNECTION_TIMEOUT && $thread->userTyping; $is_typing = abs($thread->lastPingUser - time()) < Thread::CONNECTION_TIMEOUT
&& $thread->userTyping;
} }
$can_post = $args['user'] || $operator['operatorid'] == $thread->agentId; $can_post = $args['user'] || $operator['operatorid'] == $thread->agentId;
return array( return array(
'typing' => $is_typing, 'typing' => $is_typing,
'canPost' => $can_post 'canPost' => $can_post,
); );
} }
/** /**
* Send new messages to window. API function * Send new messages to window. API function
* *
* @param array $args Associative array of arguments. It must contains following keys: * @param array $args Associative array of arguments. It must contains the
* following keys:
* - 'threadId': Id of the thread related to chat window * - 'threadId': Id of the thread related to chat window
* - 'token': last thread token * - 'token': last thread token
* - 'user': TRUE if window used by user and FALSE otherwise * - 'user': TRUE if window used by user and FALSE otherwise
* - 'lastId': last sent message id * - 'lastId': last sent message id
*/ */
protected function apiUpdateMessages($args) { protected function apiUpdateMessages($args)
{
// Load thread // Load thread
$thread = self::getThread($args['threadId'], $args['token']); $thread = self::getThread($args['threadId'], $args['token']);
@ -302,21 +324,23 @@ class ThreadProcessor extends ClientSideProcessor {
return array( return array(
'messages' => $messages, 'messages' => $messages,
'lastId' => $last_message_id 'lastId' => $last_message_id,
); );
} }
/** /**
* Post message to thread. API function * Post message to thread. API function
* *
* @param array $args Associative array of arguments. It must contains following keys: * @param array $args Associative array of arguments. It must contains the
* following keys:
* - 'threadId': Id of the thread related to chat window * - 'threadId': Id of the thread related to chat window
* - 'token': last thread token * - 'token': last thread token
* - 'user': TRUE if window used by user and FALSE otherwise * - 'user': TRUE if window used by user and FALSE otherwise
* - 'message': posted message * - 'message': posted message
* @throws ThreadProcessorException * @throws ThreadProcessorException
*/ */
protected function apiPost($args) { protected function apiPost($args)
{
// Load thread // Load thread
$thread = self::getThread($args['threadId'], $args['token']); $thread = self::getThread($args['threadId'], $args['token']);
@ -330,7 +354,10 @@ class ThreadProcessor extends ClientSideProcessor {
// Check message can be sent // Check message can be sent
if (!$args['user'] && $operator['operatorid'] != $thread->agentId) { if (!$args['user'] && $operator['operatorid'] != $thread->agentId) {
throw new ThreadProcessorException("Cannot send", ThreadProcessorException::ERROR_CANNOT_SEND); throw new ThreadProcessorException(
"Cannot send",
ThreadProcessorException::ERROR_CANNOT_SEND
);
} }
// Set fields // Set fields
@ -340,7 +367,7 @@ class ThreadProcessor extends ClientSideProcessor {
} else { } else {
$msg_options = array( $msg_options = array(
'name' => $thread->agentName, 'name' => $thread->agentName,
'operator_id' => $operator['operatorid'] 'operator_id' => $operator['operatorid'],
); );
} }
@ -357,13 +384,15 @@ class ThreadProcessor extends ClientSideProcessor {
/** /**
* Rename user in the chat. API function * Rename user in the chat. API function
* *
* @param array $args Associative array of arguments. It must contains following keys: * @param array $args Associative array of arguments. It must contains the
* following keys:
* - 'threadId': Id of the thread related to chat window * - 'threadId': Id of the thread related to chat window
* - 'token': last thread token * - 'token': last thread token
* - 'name': new user name * - 'name': new user name
* @throws \Mibew\RequestProcessor\ThreadProcessorException * @throws \Mibew\RequestProcessor\ThreadProcessorException
*/ */
protected function apiRename($args) { protected function apiRename($args)
{
// Check rename possibility // Check rename possibility
if (Settings::get('usercanchangename') != "1") { if (Settings::get('usercanchangename') != "1") {
throw new ThreadProcessorException( throw new ThreadProcessorException(
@ -388,14 +417,16 @@ class ThreadProcessor extends ClientSideProcessor {
/** /**
* Close chat thread. API function * Close chat thread. API function
* *
* @param array $args Associative array of arguments. It must contains following keys: * @param array $args Associative array of arguments. It must contains the
* following keys:
* - 'threadId': Id of the thread related to chat window * - 'threadId': Id of the thread related to chat window
* - 'token': last thread token * - 'token': last thread token
* - 'user': TRUE if window used by user and FALSE otherwise * - 'user': TRUE if window used by user and FALSE otherwise
* @return array Array of results. It contains following keys: * @return array Array of results. It contains following keys:
* - 'closed': indicates if thread can be closed * - 'closed': indicates if thread can be closed
*/ */
protected function apiClose($args) { protected function apiClose($args)
{
// Load thread and check thread's last token // Load thread and check thread's last token
$thread = self::getThread($args['threadId'], $args['token']); $thread = self::getThread($args['threadId'], $args['token']);
@ -413,14 +444,14 @@ class ThreadProcessor extends ClientSideProcessor {
} }
return array( return array(
'closed' => true 'closed' => true,
); );
} }
/** /**
* Process submitted prechat survey. * Process submitted prechat survey.
* *
* @param array $args Associative array of arguments. It must contains * @param array $args Associative array of arguments. It must contains the
* following keys: * following keys:
* - 'threadId': for this function this param equals to null; * - 'threadId': for this function this param equals to null;
* - 'token': for this function this param equals to null; * - 'token': for this function this param equals to null;
@ -434,8 +465,8 @@ class ThreadProcessor extends ClientSideProcessor {
* - 'next': string, indicates what module run next; * - 'next': string, indicates what module run next;
* - 'options': options array for next module. * - 'options': options array for next module.
*/ */
protected function apiProcessSurvey($args) { protected function apiProcessSurvey($args)
{
$visitor = visitor_from_request(); $visitor = visitor_from_request();
// Get form values // Get form values
@ -446,7 +477,7 @@ class ThreadProcessor extends ClientSideProcessor {
// Verify group id // Verify group id
$group_id = ''; $group_id = '';
$group = NULL; $group = null;
if (Settings::get('enablegroups') == '1') { if (Settings::get('enablegroups') == '1') {
if (preg_match("/^\d{1,8}$/", $args['groupId']) != 0) { if (preg_match("/^\d{1,8}$/", $args['groupId']) != 0) {
$group = group_by_id($args['groupId']); $group = group_by_id($args['groupId']);
@ -481,9 +512,10 @@ class ThreadProcessor extends ClientSideProcessor {
); );
$options = $client_data['leaveMessage']; $options = $client_data['leaveMessage'];
$options['page'] += setup_logo($group); $options['page'] += setup_logo($group);
return array( return array(
'next' => 'leaveMessage', 'next' => 'leaveMessage',
'options' => $options 'options' => $options,
); );
} }
@ -522,7 +554,7 @@ class ThreadProcessor extends ClientSideProcessor {
return array( return array(
'next' => 'chat', 'next' => 'chat',
'options' => $options 'options' => $options,
); );
} }
@ -530,7 +562,7 @@ class ThreadProcessor extends ClientSideProcessor {
* Process submitted leave message form. * Process submitted leave message form.
* *
* Send message to operator email and create special meil thread. * Send message to operator email and create special meil thread.
* @param array $args Associative array of arguments. It must contains * @param array $args Associative array of arguments. It must contains the
* following keys: * following keys:
* - 'threadId': for this function this param equals to null; * - 'threadId': for this function this param equals to null;
* - 'token': for this function this param equals to null; * - 'token': for this function this param equals to null;
@ -545,7 +577,8 @@ class ThreadProcessor extends ClientSideProcessor {
* @throws \Mibew\RequestProcessor\ThreadProcessorException Can throw an * @throws \Mibew\RequestProcessor\ThreadProcessorException Can throw an
* exception if captcha or email is wrong. * exception if captcha or email is wrong.
*/ */
protected function apiProcessLeaveMessage($args) { protected function apiProcessLeaveMessage($args)
{
// Check captcha // Check captcha
if (Settings::get('enablecaptcha') == '1' && can_show_captcha()) { if (Settings::get('enablecaptcha') == '1' && can_show_captcha()) {
$captcha = $args['captcha']; $captcha = $args['captcha'];
@ -641,7 +674,8 @@ class ThreadProcessor extends ClientSideProcessor {
// Send email // Send email
if ($inbox_mail) { if ($inbox_mail) {
// Prepare message to send by email // Prepare message to send by email
$subject = getstring2_("leavemail.subject", $subject = getstring2_(
"leavemail.subject",
array($args['name']), array($args['name']),
$message_locale $message_locale
); );
@ -661,5 +695,3 @@ class ThreadProcessor extends ClientSideProcessor {
} }
} }
} }
?>

View File

@ -41,22 +41,26 @@ use Mibew\RequestProcessor\Exception\UsersProcessorException;
* *
* Implements Singleton pattern * Implements Singleton pattern
*/ */
class UsersProcessor extends ClientSideProcessor { class UsersProcessor extends ClientSideProcessor
{
/** /**
* An instance of the UsersProcessor class * An instance of the UsersProcessor class
*
* @var \Mibew\RequestProcessor\UsersProcessor * @var \Mibew\RequestProcessor\UsersProcessor
*/ */
protected static $instance = null; protected static $instance = null;
/** /**
* Return an instance of the UsersProcessor class. * Return an instance of the UsersProcessor class.
*
* @return \Mibew\RequestProcessor\UsersProcessor * @return \Mibew\RequestProcessor\UsersProcessor
*/ */
public static function getInstance() { public static function getInstance()
{
if (is_null(self::$instance)) { if (is_null(self::$instance)) {
self::$instance = new self(); self::$instance = new self();
} }
return self::$instance; return self::$instance;
} }
@ -65,9 +69,11 @@ class UsersProcessor extends ClientSideProcessor {
* *
* Do not use directly __construct method! Use * Do not use directly __construct method! Use
* \Mibew\RequestProcessor\UsersProcessor::getInstance() instead! * \Mibew\RequestProcessor\UsersProcessor::getInstance() instead!
*
* @todo Think about why the method is not protected * @todo Think about why the method is not protected
*/ */
public function __construct() { public function __construct()
{
parent::__construct(array( parent::__construct(array(
'signature' => '', 'signature' => '',
'trusted_signatures' => array(''), 'trusted_signatures' => array(''),
@ -80,7 +86,8 @@ class UsersProcessor extends ClientSideProcessor {
* *
* @return \Mibew\API\API * @return \Mibew\API\API
*/ */
protected function getMibewAPIInstance() { protected function getMibewAPIInstance()
{
return MibewAPI::getAPI('\\Mibew\\API\\Interaction\\UsersInteraction'); return MibewAPI::getAPI('\\Mibew\\API\\Interaction\\UsersInteraction');
} }
@ -90,7 +97,8 @@ class UsersProcessor extends ClientSideProcessor {
* @param array $request The 'request' array. See Mibew API for details * @param array $request The 'request' array. See Mibew API for details
* @return boolean true on success or false on failure * @return boolean true on success or false on failure
*/ */
protected function sendAsyncRequest($request) { protected function sendAsyncRequest($request)
{
// Define empty agent id // Define empty agent id
$agent_id = null; $agent_id = null;
foreach ($request['functions'] as $function) { foreach ($request['functions'] as $function) {
@ -109,19 +117,21 @@ class UsersProcessor extends ClientSideProcessor {
} }
// Store request in buffer // Store request in buffer
$this->addRequestToBuffer('users_' . $agent_id, $request); $this->addRequestToBuffer('users_' . $agent_id, $request);
return true; return true;
} }
/** /**
* Check operator id equals to $operatorId is current logged in operator * Check operator id equals to $operator_id for current logged in operator
* *
* @param int $operatorId Operator id to check * @param int $operator_id Operator id to check
* @return array Operators info array * @return array Operators info array
* *
* @throws UsersProcessorException If operators not logged in or if * @throws UsersProcessorException If operators not logged in or if
* $operatorId varies from current logged in operator. * $operator_id varies from current logged in operator.
*/ */
protected static function checkOperator($operatorId) { protected static function checkOperator($operator_id)
{
$operator = get_logged_in(); $operator = get_logged_in();
if (!$operator) { if (!$operator) {
throw new UsersProcessorException( throw new UsersProcessorException(
@ -129,23 +139,25 @@ class UsersProcessor extends ClientSideProcessor {
UsersProcessorException::ERROR_AGENT_NOT_LOGGED_IN UsersProcessorException::ERROR_AGENT_NOT_LOGGED_IN
); );
} }
if ($operatorId != $operator['operatorid']) { if ($operator_id != $operator['operatorid']) {
throw new UsersProcessorException( throw new UsersProcessorException(
"Wrong agent id: '{$operatorId}' instead of {$operator['operatorid']}", "Wrong agent id: '{$operator_id}' instead of {$operator['operatorid']}",
UsersProcessorException::ERROR_WRONG_AGENT_ID UsersProcessorException::ERROR_WRONG_AGENT_ID
); );
} }
return $operator; return $operator;
} }
/** /**
* Mark operator as away. API function * Mark operator as away. API function
* *
* @param array $args Associative array of arguments. It must contains * @param array $args Associative array of arguments. It must contains the
* following keys: * following keys:
* - 'agentId': Id of the agent related to users window * - 'agentId': Id of the agent related to users window
*/ */
protected function apiAway($args) { protected function apiAway($args)
{
$operator = self::checkOperator($args['agentId']); $operator = self::checkOperator($args['agentId']);
notify_operator_alive($operator['operatorid'], 1); notify_operator_alive($operator['operatorid'], 1);
} }
@ -153,11 +165,12 @@ class UsersProcessor extends ClientSideProcessor {
/** /**
* Mark operator as available. API function * Mark operator as available. API function
* *
* @param array $args Associative array of arguments. It must contains * @param array $args Associative array of arguments. It must contains the
* following keys: * following keys:
* - 'agentId': Id of the agent related to users window * - 'agentId': Id of the agent related to users window
*/ */
protected function apiAvailable($args) { protected function apiAvailable($args)
{
$operator = self::checkOperator($args['agentId']); $operator = self::checkOperator($args['agentId']);
notify_operator_alive($operator['operatorid'], 0); notify_operator_alive($operator['operatorid'], 0);
} }
@ -165,53 +178,52 @@ class UsersProcessor extends ClientSideProcessor {
/** /**
* Return updated threads list. API function * Return updated threads list. API function
* *
* @param array $args Associative array of arguments. It must contains * @param array $args Associative array of arguments. It must contains the
* following keys: * following keys:
* - 'agentId': Id of the agent related to users window * - 'agentId': Id of the agent related to users window
* - 'revision': last revision number at client side * - 'revision': last revision number at client side
* @return array Array of results. It contains following keys: * @return array Array of results. It contains the following keys:
* - 'threads': array of threads changes * - 'threads': array of threads changes
*/ */
protected function apiUpdateThreads($args) { protected function apiUpdateThreads($args)
{
$operator = self::checkOperator($args['agentId']); $operator = self::checkOperator($args['agentId']);
$since = $args['revision']; $since = $args['revision'];
// Get operator groups // Get operator groups
if (!isset($_SESSION[SESSION_PREFIX . "operatorgroups"])) { if (!isset($_SESSION[SESSION_PREFIX . "operatorgroups"])) {
$_SESSION[SESSION_PREFIX . "operatorgroups"] $_SESSION[SESSION_PREFIX . "operatorgroups"]
= get_operator_groupslist($operator['operatorid']); = get_operator_groups_list($operator['operatorid']);
} }
$groupids = $_SESSION[SESSION_PREFIX."operatorgroups"]; $group_ids = $_SESSION[SESSION_PREFIX . "operatorgroups"];
$db = Database::getInstance(); $db = Database::getInstance();
$query = "select t.*, " . $query = "SELECT t.*, "
" g.vclocalname as group_localname, " . . " g.vclocalname AS group_localname, "
" g.vccommonname as group_commonname " . . " g.vccommonname AS group_commonname "
" from {chatthread} t left outer join {chatgroup} g on " . . " FROM {chatthread} t LEFT OUTER JOIN {chatgroup} g ON "
" t.groupid = g.groupid " . . " t.groupid = g.groupid "
" where t.lrevision > :since " . . " WHERE t.lrevision > :since "
" AND t.istate <> " . Thread::STATE_INVITED . . " AND t.istate <> " . Thread::STATE_INVITED
($since == 0 . ($since == 0
// Select only active threads at first time when lrevision = 0 // Select only active threads at first time when lrevision = 0
? " AND t.istate <> " . Thread::STATE_CLOSED . ? " AND t.istate <> " . Thread::STATE_CLOSED
" AND t.istate <> " . Thread::STATE_LEFT . " AND t.istate <> " . Thread::STATE_LEFT
// Select all threads at when lrevision > 0. It provides the // Select all threads at when lrevision > 0. It provides the
// ability to update(and probably hide) closed threads at the // ability to update(and probably hide) closed threads at the
// clien side. // clien side.
: "" : ""
) . )
(Settings::get('enablegroups') == '1' . (Settings::get('enablegroups') == '1'
// If groups are enabled select only threads with empty groupid // If groups are enabled select only threads with empty groupid
// or groups related to current operator // or groups related to current operator
? " AND (g.groupid is NULL" . ($groupids ? " AND (g.groupid is NULL" . ($group_ids ? " OR g.groupid IN ($group_ids) OR g.groupid IN "
? " OR g.groupid IN ($groupids) OR g.groupid IN " . . "(SELECT parent FROM {chatgroup} "
"(SELECT parent FROM {chatgroup} " . . "WHERE groupid IN ($group_ids)) " : "")
"WHERE groupid IN ($groupids)) " . ") "
: "") .
") "
: "" : ""
) . )
" ORDER BY t.threadid"; . " ORDER BY t.threadid";
$rows = $db->query( $rows = $db->query(
$query, $query,
array(':since' => $since), array(':since' => $since),
@ -243,7 +255,7 @@ class UsersProcessor extends ClientSideProcessor {
if ($ban_info !== false) { if ($ban_info !== false) {
$ban = array( $ban = array(
'id' => $ban_info['banid'], 'id' => $ban_info['banid'],
'reason' => $ban_info['comment'] 'reason' => $ban_info['comment'],
); );
} else { } else {
$ban = false; $ban = false;
@ -264,18 +276,18 @@ class UsersProcessor extends ClientSideProcessor {
} }
// Get thread operartor name // Get thread operartor name
$nextagent = $thread->nextAgent != 0 $next_agent = $thread->nextAgent != 0
? operator_by_id($thread->nextAgent) ? operator_by_id($thread->nextAgent)
: false; : false;
if ($nextagent) { if ($next_agent) {
$agent_name = get_operator_name($nextagent); $agent_name = get_operator_name($next_agent);
} else { } else {
if ($thread->agentName) { if ($thread->agentName) {
$agent_name = $thread->agentName; $agent_name = $thread->agentName;
} else { } else {
$group_name = get_group_name(array( $group_name = get_group_name(array(
'vccommonname' => $row['group_commonname'], 'vccommonname' => $row['group_commonname'],
'vclocalname' => $row['group_localname'] 'vclocalname' => $row['group_localname'],
)); ));
if ($group_name) { if ($group_name) {
$agent_name = '-' . $group_name . '-'; $agent_name = '-' . $group_name . '-';
@ -289,8 +301,7 @@ class UsersProcessor extends ClientSideProcessor {
$first_message = null; $first_message = null;
if ($thread->shownMessageId != 0) { if ($thread->shownMessageId != 0) {
$line = $db->query( $line = $db->query(
"select tmessage from {chatmessage} " . "SELECT tmessage FROM {chatmessage} WHERE messageid = ? LIMIT 1",
" where messageid = ? limit 1",
array($thread->shownMessageId), array($thread->shownMessageId),
array('return_rows' => Database::RETURN_ONE_ROW) array('return_rows' => Database::RETURN_ONE_ROW)
); );
@ -309,7 +320,7 @@ class UsersProcessor extends ClientSideProcessor {
'userName' => $user_name, 'userName' => $user_name,
'userIp' => $user_ip, 'userIp' => $user_ip,
'remote' => $thread->remote, 'remote' => $thread->remote,
'userAgent' => get_useragent_version($thread->userAgent), 'userAgent' => get_user_agent_version($thread->userAgent),
'agentName' => $agent_name, 'agentName' => $agent_name,
'canOpen' => $can_open, 'canOpen' => $can_open,
'canView' => $can_view, 'canView' => $can_view,
@ -318,7 +329,7 @@ class UsersProcessor extends ClientSideProcessor {
'state' => $thread->state, 'state' => $thread->state,
'totalTime' => $thread->created, 'totalTime' => $thread->created,
'waitingTime' => $thread->modified, 'waitingTime' => $thread->modified,
'firstMessage' => $first_message 'firstMessage' => $first_message,
); );
// Get max revision // Get max revision
@ -333,7 +344,7 @@ class UsersProcessor extends ClientSideProcessor {
// Send results back to the client // Send results back to the client
return array( return array(
'threads' => $threads, 'threads' => $threads,
'lastRevision' => $revision 'lastRevision' => $revision,
); );
} }
@ -354,14 +365,15 @@ class UsersProcessor extends ClientSideProcessor {
* list. Associative array pass to event lister have following keys: * list. Associative array pass to event lister have following keys:
* - 'visitors': array of visitors arrays. * - 'visitors': array of visitors arrays.
* *
* @param array $args Associative array of arguments. It must contains * @param array $args Associative array of arguments. It must contains the
* following keys: * following keys:
* - 'agentId': Id of the agent related to users window * - 'agentId': Id of the agent related to users window
* *
* @return array Array of results. It contains following keys: * @return array Array of results. It contains the following keys:
* - 'visitors': array of visitors on the site * - 'visitors': array of visitors on the site
*/ */
protected function apiUpdateVisitors($args) { protected function apiUpdateVisitors($args)
{
// Check access // Check access
self::checkOperator($args['agentId']); self::checkOperator($args['agentId']);
@ -385,25 +397,25 @@ class UsersProcessor extends ClientSideProcessor {
// Load visitors list // Load visitors list
$db = Database::getInstance(); $db = Database::getInstance();
// Load visitors // Load visitors
$query = "SELECT v.visitorid, " . $query = "SELECT v.visitorid, "
"v.userid, " . . "v.userid, "
"v.username, " . . "v.username, "
"v.firsttime, " . . "v.firsttime, "
"v.lasttime, " . . "v.lasttime, "
"v.entry, " . . "v.entry, "
"v.details, " . . "v.details, "
"t.invitationstate, " . . "t.invitationstate, "
"t.dtmcreated AS invitationtime, " . . "t.dtmcreated AS invitationtime, "
"t.agentId AS invitedby, " . . "t.agentId AS invitedby, "
"v.invitations, " . . "v.invitations, "
"v.chats " . . "v.chats "
"FROM {chatsitevisitor} v " . . "FROM {chatsitevisitor} v "
"LEFT OUTER JOIN {chatthread} t " . . "LEFT OUTER JOIN {chatthread} t "
"ON t.threadid = v.threadid " . . "ON t.threadid = v.threadid "
"WHERE v.threadid IS NULL " . . "WHERE v.threadid IS NULL "
"OR (t.istate = :state_invited " . . "OR (t.istate = :state_invited "
"AND t.invitationstate = :invitation_wait)" . . "AND t.invitationstate = :invitation_wait)"
"ORDER BY t.invitationstate, v.lasttime DESC, v.invitations"; . "ORDER BY t.invitationstate, v.lasttime DESC, v.invitations";
$query .= (Settings::get('visitors_limit') == '0') $query .= (Settings::get('visitors_limit') == '0')
? "" ? ""
: " LIMIT " . Settings::get('visitors_limit'); : " LIMIT " . Settings::get('visitors_limit');
@ -412,7 +424,7 @@ class UsersProcessor extends ClientSideProcessor {
$query, $query,
array( array(
':state_invited' => Thread::STATE_INVITED, ':state_invited' => Thread::STATE_INVITED,
':invitation_wait' => Thread::INVITATION_WAIT ':invitation_wait' => Thread::INVITATION_WAIT,
), ),
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
@ -424,7 +436,7 @@ class UsersProcessor extends ClientSideProcessor {
$details = track_retrieve_details($row); $details = track_retrieve_details($row);
// Get user agent // Get user agent
$user_agent = get_useragent_version($details['user_agent']); $user_agent = get_user_agent_version($details['user_agent']);
// Get user ip // Get user ip
if (preg_match("/(\\d+\\.\\d+\\.\\d+\\.\\d+)/", $details['remote_host'], $matches) != 0) { if (preg_match("/(\\d+\\.\\d+\\.\\d+\\.\\d+)/", $details['remote_host'], $matches) != 0) {
@ -441,7 +453,7 @@ class UsersProcessor extends ClientSideProcessor {
); );
$invitation_info = array( $invitation_info = array(
'time' => $row['invitationtime'], 'time' => $row['invitationtime'],
'agentName' => $agent_name 'agentName' => $agent_name,
); );
} else { } else {
$invitation_info = false; $invitation_info = false;
@ -459,7 +471,7 @@ class UsersProcessor extends ClientSideProcessor {
'lastTime' => $row['lasttime'], 'lastTime' => $row['lasttime'],
'invitations' => (int) $row['invitations'], 'invitations' => (int) $row['invitations'],
'chats' => (int) $row['chats'], 'chats' => (int) $row['chats'],
'invitationInfo' => $invitation_info 'invitationInfo' => $invitation_info,
); );
} }
} else { } else {
@ -468,26 +480,27 @@ class UsersProcessor extends ClientSideProcessor {
// Provide ability to alter visitors list // Provide ability to alter visitors list
$arguments = array( $arguments = array(
'visitors' => $visitors 'visitors' => $visitors,
); );
$dispatcher->triggerEvent('usersUpdateVisitorsAlter', $arguments); $dispatcher->triggerEvent('usersUpdateVisitorsAlter', $arguments);
return array( return array(
'visitors' => $arguments['visitors'] 'visitors' => $arguments['visitors'],
); );
} }
/** /**
* Return updated operators list. API function * Return updated operators list. API function
* *
* @param array $args Associative array of arguments. It must contains * @param array $args Associative array of arguments. It must contains the
* following keys: * following keys:
* - 'agentId': Id of the agent related to users window * - 'agentId': Id of the agent related to users window
* *
* @return array Array of results. It contains following keys: * @return array Array of results. It contains the following keys:
* - 'operators': array of online operators * - 'operators': array of online operators
*/ */
protected function apiUpdateOperators($args) { protected function apiUpdateOperators($args)
{
// Check access and get operators info // Check access and get operators info
$operator = self::checkOperator($args['agentId']); $operator = self::checkOperator($args['agentId']);
@ -527,7 +540,7 @@ class UsersProcessor extends ClientSideProcessor {
// Send operators list to the client side // Send operators list to the client side
return array( return array(
'operators' => $result_list 'operators' => $result_list,
); );
} }
@ -535,11 +548,12 @@ class UsersProcessor extends ClientSideProcessor {
* Update chat window state. API function * Update chat window state. API function
* Call periodically by chat window. * Call periodically by chat window.
* *
* @param array $args Associative array of arguments. It must contains * @param array $args Associative array of arguments. It must contains the
* following keys: * following keys:
* - 'agentId': Id of the agent related to users window * - 'agentId': Id of the agent related to users window
*/ */
protected function apiUpdate($args) { protected function apiUpdate($args)
{
// Check access and get operator array // Check access and get operator array
$operator = self::checkOperator($args['agentId']); $operator = self::checkOperator($args['agentId']);
@ -559,22 +573,21 @@ class UsersProcessor extends ClientSideProcessor {
/** /**
* Returns current server time. API function * Returns current server time. API function
* *
* @param array $args Associative array of arguments. It must contains * @param array $args Associative array of arguments. It must contains the
* following keys: * following keys:
* - 'agentId': Id of the agent related to users window * - 'agentId': Id of the agent related to users window
* *
* @return array Array of results. It contains following keys: * @return array Array of results. It contains the following keys:
* - 'time': current server time * - 'time': current server time
*/ */
protected function apiCurrentTime($args) { protected function apiCurrentTime($args)
{
// Check access // Check access
self::checkOperator($args['agentId']); self::checkOperator($args['agentId']);
// Return time // Return time
return array( return array(
'time' => time() 'time' => time(),
); );
} }
} }
?>

View File

@ -20,41 +20,49 @@ namespace Mibew;
/** /**
* Encapsulates work with system settings. * Encapsulates work with system settings.
*/ */
Class Settings { class Settings
{
/** /**
* An instance of Settings class * An instance of Settings class
*
* @var Settings * @var Settings
*/ */
protected static $instance = null; protected static $instance = null;
/** /**
* Array of settings * Array of settings
*
* @var array * @var array
*/ */
protected $settings = array(); protected $settings = array();
/** /**
* Array of settings stored in database * Array of settings stored in database
*
* @var array * @var array
*/ */
protected $settingsInDb = array(); protected $settingsInDb = array();
/** /**
* Returns an instance of Settings class * Returns an instance of Settings class
*
* @return Settings * @return Settings
*/ */
protected static function getInstance(){ protected static function getInstance()
{
if (self::$instance === null) { if (self::$instance === null) {
self::$instance = new self(); self::$instance = new self();
} }
return self::$instance; return self::$instance;
} }
/** /**
* Settings class constructor. Set default values and load setting from database. * Settings class constructor. Set default values and load setting from
* database.
*/ */
protected function __construct() { protected function __construct()
{
// Set default values // Set default values
$this->settings = array( $this->settings = array(
'dbversion' => 0, 'dbversion' => 0,
@ -72,11 +80,9 @@ Class Settings {
'max_uploaded_file_size' => 100000, 'max_uploaded_file_size' => 100000,
'max_connections_from_one_host' => 10, 'max_connections_from_one_host' => 10,
'thread_lifetime' => 600, 'thread_lifetime' => 600,
'email' => '', /* inbox for left messages */ 'email' => '', /* inbox for left messages */
'left_messages_locale' => HOME_LOCALE, 'left_messages_locale' => HOME_LOCALE,
'sendmessagekey' => 'center', 'sendmessagekey' => 'center',
'enableban' => '0', 'enableban' => '0',
'enablessl' => '0', 'enablessl' => '0',
'forcessl' => '0', 'forcessl' => '0',
@ -92,33 +98,27 @@ Class Settings {
'enablepopupnotification' => '0', 'enablepopupnotification' => '0',
'showonlineoperators' => '0', 'showonlineoperators' => '0',
'enablecaptcha' => '0', 'enablecaptcha' => '0',
'online_timeout' => 30, /* Timeout (in seconds) when online operator becomes offline */ 'online_timeout' => 30, /* Timeout (in seconds) when online operator becomes offline */
'updatefrequency_operator' => 2, 'updatefrequency_operator' => 2,
'updatefrequency_chat' => 2, 'updatefrequency_chat' => 2,
'statistics_aggregation_interval' => 24 * 60 * 60, 'statistics_aggregation_interval' => 24 * 60 * 60,
'updatefrequency_tracking' => 10, 'updatefrequency_tracking' => 10,
'visitors_limit' => 20, /* Number of visitors to look over */ 'visitors_limit' => 20, /* Number of visitors to look over */
'invitation_lifetime' => 60, /* Lifetime for invitation to chat */ 'invitation_lifetime' => 60, /* Lifetime for invitation to chat */
'tracking_lifetime' => 600, /* Time to store tracked old visitors' data */ 'tracking_lifetime' => 600, /* Time to store tracked old visitors' data */
'cron_key' => DEFAULT_CRON_KEY, 'cron_key' => DEFAULT_CRON_KEY,
// System values are listed below. They cannot be changed via // System values are listed below. They cannot be changed via
// administrative interface. Start names for these values from // administrative interface. Start names for these values from
// underscore sign(_). // underscore sign(_).
// Unix timestamp when cron job ran last time. // Unix timestamp when cron job ran last time.
'_last_cron_run' => 0 '_last_cron_run' => 0,
); );
// Load values from database // Load values from database
$db = Database::getInstance(); $db = Database::getInstance();
$rows = $db->query( $rows = $db->query(
"select vckey,vcvalue from {chatconfig}", "SELECT vckey, vcvalue FROM {chatconfig}",
NULL, null,
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
@ -135,8 +135,10 @@ Class Settings {
* @param string $name Variable's name * @param string $name Variable's name
* @return mixed * @return mixed
*/ */
public static function get($name) { public static function get($name)
{
$instance = self::getInstance(); $instance = self::getInstance();
return $instance->settings[$name]; return $instance->settings[$name];
} }
@ -146,7 +148,8 @@ Class Settings {
* @param string $name Variables's name * @param string $name Variables's name
* @param mixed $value Variable's value * @param mixed $value Variable's value
*/ */
public static function set($name, $value) { public static function set($name, $value)
{
$instance = self::getInstance(); $instance = self::getInstance();
$instance->settings[$name] = $value; $instance->settings[$name] = $value;
} }
@ -154,18 +157,19 @@ Class Settings {
/** /**
* Updates settings in database. * Updates settings in database.
*/ */
public static function update() { public static function update()
{
$instance = self::getInstance(); $instance = self::getInstance();
$db = Database::getInstance(); $db = Database::getInstance();
foreach ($instance->settings as $key => $value) { foreach ($instance->settings as $key => $value) {
if (!isset($instance->settingsInDb[$key])) { if (!isset($instance->settingsInDb[$key])) {
$db->query( $db->query(
"insert into {chatconfig} (vckey) values (?)", "INSERT INTO {chatconfig} (vckey) VALUES (?)",
array($key) array($key)
); );
} }
$db->query( $db->query(
"update {chatconfig} set vcvalue=? where vckey=?", "UPDATE {chatconfig} SET vcvalue=? WHERE vckey=?",
array($value, $key) array($value, $key)
); );
} }
@ -174,7 +178,7 @@ Class Settings {
/** /**
* Implementation of destructor * Implementation of destructor
*/ */
public function __destruct() {} public function __destruct()
{
}
} }
?>

View File

@ -24,10 +24,11 @@ use Mibew\TemplateEngine\ChatTemplateEngine;
/** /**
* Represents a chat style * Represents a chat style
*/ */
class ChatStyle extends Style implements StyleInterface { class ChatStyle extends Style implements StyleInterface
{
/** /**
* Template engine for chat templates. * Template engine for chat templates.
*
* @var \Mibew\TemplateEngine\ChatTemplateEngine * @var \Mibew\TemplateEngine\ChatTemplateEngine
*/ */
protected $templateEngine; protected $templateEngine;
@ -37,7 +38,8 @@ class ChatStyle extends Style implements StyleInterface {
* *
* @param string $style_name Name of the style * @param string $style_name Name of the style
*/ */
public function __construct($style_name) { public function __construct($style_name)
{
parent::__construct($style_name); parent::__construct($style_name);
$this->templateEngine = new ChatTemplateEngine( $this->templateEngine = new ChatTemplateEngine(
@ -46,14 +48,14 @@ class ChatStyle extends Style implements StyleInterface {
); );
} }
/** /**
* Builds base path for style files. This path is relative Mibew root and * Builds base path for style files. This path is relative Mibew root and
* does not contain neither leading nor trailing slash. * does not contain neither leading nor trailing slash.
* *
* @return string Base path for style files * @return string Base path for style files
*/ */
public function filesPath() { public function filesPath()
{
return 'styles/dialogs/' . $this->name(); return 'styles/dialogs/' . $this->name();
} }
@ -65,7 +67,8 @@ class ChatStyle extends Style implements StyleInterface {
* @param array $data Associative array of values that should be used for * @param array $data Associative array of values that should be used for
* substitutions in a template. * substitutions in a template.
*/ */
public function render($template_name, $data = array()) { public function render($template_name, $data = array())
{
start_html_output(); start_html_output();
echo($this->templateEngine->render($template_name, $data)); echo($this->templateEngine->render($template_name, $data));
} }
@ -79,9 +82,10 @@ class ChatStyle extends Style implements StyleInterface {
* @return string Name of a style * @return string Name of a style
* @throws \RuntimeException * @throws \RuntimeException
*/ */
public static function currentStyle() { public static function currentStyle()
{
// Ceck if request contains chat style // Ceck if request contains chat style
$style_name = verifyparam("style", "/^\w+$/", ""); $style_name = verify_param("style", "/^\w+$/", "");
if (!$style_name) { if (!$style_name) {
// Use the default style // Use the default style
$style_name = self::defaultStyle(); $style_name = self::defaultStyle();
@ -110,7 +114,8 @@ class ChatStyle extends Style implements StyleInterface {
* *
* @return string Name of a style * @return string Name of a style
*/ */
public static function defaultStyle() { public static function defaultStyle()
{
// Load value from system settings // Load value from system settings
return Settings::get('chat_style'); return Settings::get('chat_style');
} }
@ -120,7 +125,8 @@ class ChatStyle extends Style implements StyleInterface {
* *
* @param string $style_name Name of a style * @param string $style_name Name of a style
*/ */
public static function setDefaultStyle($style_name) { public static function setDefaultStyle($style_name)
{
Settings::set('chat_style', $style_name); Settings::set('chat_style', $style_name);
Settings::update(); Settings::update();
} }
@ -130,7 +136,8 @@ class ChatStyle extends Style implements StyleInterface {
* *
* @param array List of styles names * @param array List of styles names
*/ */
public static function availableStyles() { public static function availableStyles()
{
$styles_root = MIBEW_FS_ROOT . '/styles/dialogs'; $styles_root = MIBEW_FS_ROOT . '/styles/dialogs';
return self::getStyleList($styles_root); return self::getStyleList($styles_root);
@ -142,28 +149,27 @@ class ChatStyle extends Style implements StyleInterface {
* *
* @return array Default configurations of the style * @return array Default configurations of the style
*/ */
protected function defaultConfigurations() { protected function defaultConfigurations()
{
return array( return array(
'history' => array( 'history' => array(
'window_params' => '' 'window_params' => '',
), ),
'users' => array( 'users' => array(
'thread_tag' => 'div', 'thread_tag' => 'div',
'visitor_tag' => 'div' 'visitor_tag' => 'div',
), ),
'tracked' => array( 'tracked' => array(
'user_window_params' => '', 'user_window_params' => '',
'visitor_window_params' => '' 'visitor_window_params' => '',
), ),
'invitation' => array( 'invitation' => array(
'window_params' => '' 'window_params' => '',
), ),
'ban' => array( 'ban' => array(
'window_params' => '' 'window_params' => '',
), ),
'screenshots' => array() 'screenshots' => array(),
); );
} }
} }
?>

View File

@ -23,14 +23,16 @@ use Mibew\Settings;
/** /**
* Represents a style for invitations * Represents a style for invitations
*/ */
class InvitationStyle extends Style implements StyleInterface { class InvitationStyle extends Style implements StyleInterface
{
/** /**
* Builds base path for style files. This path is relative Mibew root and * Builds base path for style files. This path is relative Mibew root and
* does not contain neither leading nor trailing slash. * does not contain neither leading nor trailing slash.
* *
* @return string Base path for style files * @return string Base path for style files
*/ */
public function filesPath() { public function filesPath()
{
return 'styles/invitations/' . $this->name(); return 'styles/invitations/' . $this->name();
} }
@ -39,7 +41,8 @@ class InvitationStyle extends Style implements StyleInterface {
* *
* @return array Style configurations * @return array Style configurations
*/ */
public function configurations() { public function configurations()
{
return array(); return array();
} }
@ -49,8 +52,9 @@ class InvitationStyle extends Style implements StyleInterface {
* The method does not contain actual code because inviation styles are not * The method does not contain actual code because inviation styles are not
* renderable now. * renderable now.
*/ */
public function render($template_name, $data = array()) { public function render($template_name, $data = array())
return FALSE; {
return false;
} }
/** /**
@ -61,7 +65,8 @@ class InvitationStyle extends Style implements StyleInterface {
* *
* @return string Name of a style * @return string Name of a style
*/ */
public static function currentStyle() { public static function currentStyle()
{
// Just use the default style // Just use the default style
return self::defaultStyle(); return self::defaultStyle();
} }
@ -71,7 +76,8 @@ class InvitationStyle extends Style implements StyleInterface {
* *
* @return string Name of a style * @return string Name of a style
*/ */
public static function defaultStyle() { public static function defaultStyle()
{
// Load value from system settings // Load value from system settings
return Settings::get('invitation_style'); return Settings::get('invitation_style');
} }
@ -81,7 +87,8 @@ class InvitationStyle extends Style implements StyleInterface {
* *
* @param string $style_name Name of a style * @param string $style_name Name of a style
*/ */
public static function setDefaultStyle($style_name) { public static function setDefaultStyle($style_name)
{
Settings::set('invitation_style', $style_name); Settings::set('invitation_style', $style_name);
Settings::update(); Settings::update();
} }
@ -91,7 +98,8 @@ class InvitationStyle extends Style implements StyleInterface {
* *
* @param array List of styles names * @param array List of styles names
*/ */
public static function availableStyles() { public static function availableStyles()
{
$styles_root = MIBEW_FS_ROOT . '/styles/invitations'; $styles_root = MIBEW_FS_ROOT . '/styles/invitations';
return self::getStyleList($styles_root); return self::getStyleList($styles_root);
@ -103,9 +111,8 @@ class InvitationStyle extends Style implements StyleInterface {
* *
* @return array Default configurations of the style * @return array Default configurations of the style
*/ */
protected function defaultConfigurations() { protected function defaultConfigurations()
{
return array(); return array();
} }
} }
?>

View File

@ -23,14 +23,16 @@ use Mibew\Settings;
/** /**
* Represents a style for operator pages * Represents a style for operator pages
*/ */
class PageStyle extends Style implements StyleInterface { class PageStyle extends Style implements StyleInterface
{
/** /**
* Builds base path for style files. This path is relative Mibew root and * Builds base path for style files. This path is relative Mibew root and
* does not contain neither leading nor trailing slash. * does not contain neither leading nor trailing slash.
* *
* @return string Base path for style files * @return string Base path for style files
*/ */
public function filesPath() { public function filesPath()
{
return 'styles/pages/' . $this->name(); return 'styles/pages/' . $this->name();
} }
@ -42,7 +44,8 @@ class PageStyle extends Style implements StyleInterface {
* @param array $data Associative array of values that should be used for * @param array $data Associative array of values that should be used for
* substitutions in a template. * substitutions in a template.
*/ */
public function render($template_name, $data = array()) { public function render($template_name, $data = array())
{
// Add template root value to page variables // Add template root value to page variables
$page['stylepath'] = MIBEW_WEB_ROOT . '/' . $this->filesPath(); $page['stylepath'] = MIBEW_WEB_ROOT . '/' . $this->filesPath();
@ -51,8 +54,8 @@ class PageStyle extends Style implements StyleInterface {
// Build full view name. Remove '\' and '/' characters form the // Build full view name. Remove '\' and '/' characters form the
// specified view name // specified view name
$full_view_name = MIBEW_FS_ROOT . '/' . $this->filesPath() . '/views/' . $full_view_name = MIBEW_FS_ROOT . '/' . $this->filesPath() . '/views/'
str_replace("/\\", '', $template_name) . '.php'; . str_replace("/\\", '', $template_name) . '.php';
// $page variable is used in included views files, so we need to create // $page variable is used in included views files, so we need to create
// it as an alias of $data argument. // it as an alias of $data argument.
@ -70,7 +73,8 @@ class PageStyle extends Style implements StyleInterface {
* *
* @return string Name of a style * @return string Name of a style
*/ */
public static function currentStyle() { public static function currentStyle()
{
// Just use the default style // Just use the default style
return self::defaultStyle(); return self::defaultStyle();
} }
@ -80,7 +84,8 @@ class PageStyle extends Style implements StyleInterface {
* *
* @return string Name of a style * @return string Name of a style
*/ */
public static function defaultStyle() { public static function defaultStyle()
{
// Load value from system settings // Load value from system settings
return Settings::get('page_style'); return Settings::get('page_style');
} }
@ -90,7 +95,8 @@ class PageStyle extends Style implements StyleInterface {
* *
* @param string $style_name Name of a style * @param string $style_name Name of a style
*/ */
public static function setDefaultStyle($style_name) { public static function setDefaultStyle($style_name)
{
Settings::set('page_style', $style_name); Settings::set('page_style', $style_name);
Settings::update(); Settings::update();
} }
@ -100,7 +106,8 @@ class PageStyle extends Style implements StyleInterface {
* *
* @param array List of styles names * @param array List of styles names
*/ */
public static function availableStyles() { public static function availableStyles()
{
$styles_root = MIBEW_FS_ROOT . '/styles/pages'; $styles_root = MIBEW_FS_ROOT . '/styles/pages';
return self::getStyleList($styles_root); return self::getStyleList($styles_root);
@ -112,7 +119,8 @@ class PageStyle extends Style implements StyleInterface {
* *
* @return array Default configurations of the style * @return array Default configurations of the style
*/ */
protected function defaultConfigurations() { protected function defaultConfigurations()
{
return array( return array(
'chat' => array( 'chat' => array(
'window_params' => '' 'window_params' => ''
@ -120,9 +128,7 @@ class PageStyle extends Style implements StyleInterface {
'mail' => array( 'mail' => array(
'window_params' => '' 'window_params' => ''
), ),
'screenshots' => array() 'screenshots' => array(),
); );
} }
} }
?>

View File

@ -20,15 +20,18 @@ namespace Mibew\Style;
/** /**
* Base class for styles * Base class for styles
*/ */
abstract class Style { abstract class Style
{
/** /**
* Styles configuration array or NULL by default * Styles configuration array or NULL by default
*
* @var array|NULL * @var array|NULL
*/ */
protected $cachedConfigurations = NULL; protected $cachedConfigurations = null;
/** /**
* This value is used to store name of a style * This value is used to store name of a style
*
* @var string * @var string
*/ */
protected $styleName; protected $styleName;
@ -36,6 +39,7 @@ abstract class Style {
/** /**
* Contains cached results of the \Mibew\Style\StyleInterface::getStyleList * Contains cached results of the \Mibew\Style\StyleInterface::getStyleList
* method. The lists are keyed by the $root_dir argument of the method. * method. The lists are keyed by the $root_dir argument of the method.
*
* @var array * @var array
* @see \Mibew\Style\StyleInterface::getStyleList * @see \Mibew\Style\StyleInterface::getStyleList
*/ */
@ -46,7 +50,8 @@ abstract class Style {
* *
* @param string $style_name Name of the style * @param string $style_name Name of the style
*/ */
public function __construct($style_name) { public function __construct($style_name)
{
$this->styleName = $style_name; $this->styleName = $style_name;
} }
@ -55,7 +60,8 @@ abstract class Style {
* *
* @return string Name of the style * @return string Name of the style
*/ */
public function name() { public function name()
{
return $this->styleName; return $this->styleName;
} }
@ -66,7 +72,8 @@ abstract class Style {
* @return array Style configurations * @return array Style configurations
* @throws \RuntimeException * @throws \RuntimeException
*/ */
public function configurations() { public function configurations()
{
$config_file = MIBEW_FS_ROOT . '/' . $this->filesPath() . '/config.ini'; $config_file = MIBEW_FS_ROOT . '/' . $this->filesPath() . '/config.ini';
// Check if configurations already loaded. Do not do the job twice. // Check if configurations already loaded. Do not do the job twice.
@ -89,13 +96,22 @@ abstract class Style {
return $this->cachedConfigurations; return $this->cachedConfigurations;
} }
/**
* Builds base path for style files. This path is relative Mibew root and
* does not contain neither leading nor trailing slash.
*
* @return string Base path for style files
*/
abstract public function filesPath();
/** /**
* Gets names of styles which are located in the $root_dir. * Gets names of styles which are located in the $root_dir.
* *
* @param string $root_dir Root styles directory * @param string $root_dir Root styles directory
* @return array List of styles' names * @return array List of styles' names
*/ */
protected static function getStyleList($root_dir) { protected static function getStyleList($root_dir)
{
// Check if styles list is already stored in the cache // Check if styles list is already stored in the cache
if (!isset(self::$cachedStyleLists[$root_dir])) { if (!isset(self::$cachedStyleLists[$root_dir])) {
// Build list of styles for the specified root directory. // Build list of styles for the specified root directory.
@ -116,21 +132,11 @@ abstract class Style {
return self::$cachedStyleLists[$root_dir]; return self::$cachedStyleLists[$root_dir];
} }
/**
* Builds base path for style files. This path is relative Mibew root and
* does not contain neither leading nor trailing slash.
*
* @return string Base path for style files
*/
public abstract function filesPath();
/** /**
* Returns array of default configurations for concrete style object. This * Returns array of default configurations for concrete style object. This
* method uses "Template method" design pattern. * method uses "Template method" design pattern.
* *
* @return array Default configurations of the style * @return array Default configurations of the style
*/ */
protected abstract function defaultConfigurations(); abstract protected function defaultConfigurations();
} }
?>

View File

@ -20,7 +20,9 @@ namespace Mibew\Style;
/** /**
* Determine interface for specific style class. * Determine interface for specific style class.
*/ */
interface StyleInterface { interface StyleInterface
{
/** /**
* Returns name of the style which shoud be used for the current request. * Returns name of the style which shoud be used for the current request.
* *
@ -84,5 +86,3 @@ interface StyleInterface {
*/ */
public function render($template_name, $data = array()); public function render($template_name, $data = array());
} }
?>

View File

@ -20,13 +20,12 @@ namespace Mibew\TemplateEngine;
/** /**
* Simple template engine for chat templates * Simple template engine for chat templates
*/ */
class ChatTemplateEngine { class ChatTemplateEngine
{
/** /**
* Regular expression for conditional blocks in templates * Regular expression for conditional blocks in templates
*/ */
const IF_REGEXP = "/\\\${(if|ifnot):([\w\.]+)}(.*?)(\\\${else:\\2}.*?)?\\\${endif:\\2}/s"; const IF_REGEXP = "/\\\${(if|ifnot):([\w\.]+)}(.*?)(\\\${else:\\2}.*?)?\\\${endif:\\2}/s";
/** /**
* Path to teplates relative to MIBEW_FS_ROOT. * Path to teplates relative to MIBEW_FS_ROOT.
* @var string * @var string
@ -58,7 +57,8 @@ class ChatTemplateEngine {
* @param string $style_path Path to the style relative to MIBEW_FS_ROOT. * @param string $style_path Path to the style relative to MIBEW_FS_ROOT.
* @param string $style_name Machine name of the templates style. * @param string $style_name Machine name of the templates style.
*/ */
public function __construct($style_path, $style_name) { public function __construct($style_path, $style_name)
{
$this->stylePath = $style_path; $this->stylePath = $style_path;
$this->styleName = $style_name; $this->styleName = $style_name;
} }
@ -71,10 +71,12 @@ class ChatTemplateEngine {
* @param array $data Data for substitutions. * @param array $data Data for substitutions.
* @return string Rendered HTML markup. * @return string Rendered HTML markup.
*/ */
public function render($template_name, $data) { public function render($template_name, $data)
{
$this->flattenTemplateData = array_flatten_recursive($data); $this->flattenTemplateData = array_flatten_recursive($data);
$this->templateData = $data; $this->templateData = $data;
$contents = $this->getTemplateFileContent($template_name); $contents = $this->getTemplateFileContent($template_name);
return $this->expandText($contents); return $this->expandText($contents);
} }
@ -84,11 +86,13 @@ class ChatTemplateEngine {
* @param string $condition Condition name. Can be any element name of the * @param string $condition Condition name. Can be any element name of the
* template data array. * template data array.
*/ */
public function checkCondition($condition) { public function checkCondition($condition)
{
if ($condition == 'errors') { if ($condition == 'errors') {
return !empty($this->templateData['errors']) return !empty($this->templateData['errors'])
&& is_array($this->templateData['errors']); && is_array($this->templateData['errors']);
} }
return !empty($this->flattenTemplateData[$condition]); return !empty($this->flattenTemplateData[$condition]);
} }
@ -100,7 +104,8 @@ class ChatTemplateEngine {
* function. * function.
* @return string One of conditional blocks depending of conditional value. * @return string One of conditional blocks depending of conditional value.
*/ */
public function expandCondition($matches) { public function expandCondition($matches)
{
$value = $this->checkCondition($matches[2]) ^ ($matches[1] != 'if'); $value = $this->checkCondition($matches[2]) ^ ($matches[1] != 'if');
if ($value) { if ($value) {
@ -129,7 +134,8 @@ class ChatTemplateEngine {
* @return string Value of the variable or empty string if the value was not * @return string Value of the variable or empty string if the value was not
* passed in with template data. * passed in with template data.
*/ */
public function expandVar($matches) { public function expandVar($matches)
{
$prefix = $matches[1]; $prefix = $matches[1];
$var = $matches[2]; $var = $matches[2];
@ -146,10 +152,9 @@ class ChatTemplateEngine {
$this->templateData['pagination'] $this->templateData['pagination']
); );
} elseif ($var == 'errors' || $var == 'harderrors') { } elseif ($var == 'errors' || $var == 'harderrors') {
if ( $errors_data_exists = !empty($this->templateData['errors'])
!empty($this->templateData['errors']) && is_array($this->templateData['errors']);
&& is_array($this->templateData['errors']) if ($errors_data_exists) {
) {
$result = getlocal("$var.header"); $result = getlocal("$var.header");
foreach ($this->templateData['errors'] as $e) { foreach ($this->templateData['errors'] as $e) {
$result .= getlocal("errors.prefix") $result .= getlocal("errors.prefix")
@ -157,10 +162,10 @@ class ChatTemplateEngine {
. getlocal("errors.suffix"); . getlocal("errors.suffix");
} }
$result .= getlocal("errors.footer"); $result .= getlocal("errors.footer");
return $result; return $result;
} }
} }
} elseif ($prefix == 'msg:' || $prefix == 'msgjs:' || $prefix == 'url:') { } elseif ($prefix == 'msg:' || $prefix == 'msgjs:' || $prefix == 'url:') {
$message = ''; $message = '';
if (strpos($var, ",") !== false) { if (strpos($var, ",") !== false) {
@ -181,6 +186,7 @@ class ChatTemplateEngine {
$message = isset($this->flattenTemplateData[$var]) $message = isset($this->flattenTemplateData[$var])
? $this->flattenTemplateData[$var] ? $this->flattenTemplateData[$var]
: ""; : "";
return ($prefix == 'pagejs:') ? json_encode($message) : $message; return ($prefix == 'pagejs:') ? json_encode($message) : $message;
} elseif ($prefix == 'if:' || $prefix == 'else:' || $prefix == 'endif:' || $prefix == 'ifnot:') { } elseif ($prefix == 'if:' || $prefix == 'else:' || $prefix == 'endif:' || $prefix == 'ifnot:') {
return "<!-- wrong $prefix:$var -->"; return "<!-- wrong $prefix:$var -->";
@ -197,8 +203,10 @@ class ChatTemplateEngine {
* function. * function.
* @return string Contents of including file * @return string Contents of including file
*/ */
public function expandInclude($matches) { public function expandInclude($matches)
{
$template_name = $matches[1]; $template_name = $matches[1];
return $this->getTemplateFileContent($template_name); return $this->getTemplateFileContent($template_name);
} }
@ -208,7 +216,8 @@ class ChatTemplateEngine {
* @param string $text Source text * @param string $text Source text
* @return string Markup with no control structures * @return string Markup with no control structures
*/ */
public function expandText($text) { public function expandText($text)
{
$text = preg_replace_callback( $text = preg_replace_callback(
"/\\\${include:([\w\.]+)}/", "/\\\${include:([\w\.]+)}/",
array($this, "expandInclude"), array($this, "expandInclude"),
@ -237,9 +246,10 @@ class ChatTemplateEngine {
* @throws \RuntimeException If there is no such template file or the file * @throws \RuntimeException If there is no such template file or the file
* is not readable. * is not readable.
*/ */
protected function getTemplateFileContent($template_name) { protected function getTemplateFileContent($template_name)
$full_file_path = MIBEW_FS_ROOT . '/' . $this->stylePath . {
'/templates/' . $template_name . '.tpl'; $full_file_path = MIBEW_FS_ROOT . '/' . $this->stylePath
. '/templates/' . $template_name . '.tpl';
if (!is_readable($full_file_path)) { if (!is_readable($full_file_path)) {
throw new \RuntimeException( throw new \RuntimeException(
@ -250,5 +260,3 @@ class ChatTemplateEngine {
return file_get_contents($full_file_path); return file_get_contents($full_file_path);
} }
} }
?>

View File

@ -40,8 +40,8 @@ use Mibew\RequestProcessor\ThreadProcessor;
* @todo Think about STATE_* and KIND_* constant systems and may be simplifies * @todo Think about STATE_* and KIND_* constant systems and may be simplifies
* them. * them.
*/ */
Class Thread { class Thread
{
/** /**
* User in the users queue * User in the users queue
*/ */
@ -129,8 +129,9 @@ Class Thread {
/** /**
* Contain mapping of thread object properties to fields in database. * Contain mapping of thread object properties to fields in database.
* *
* Keys are object properties and vlues are {chatthread} table fields. Properties are available via magic __get * Keys are object properties and vlues are {chatthread} table fields.
* and __set methods. Real values are stored in the Thread::$threadInfo array. * Properties are available via magic __get and __set methods. Real values
* are stored in the Thread::$threadInfo array.
* *
* Thread object have following properties: * Thread object have following properties:
* - 'id': id of the thread * - 'id': id of the thread
@ -139,7 +140,8 @@ Class Thread {
* - 'invitationState': state of invitation. See INVITATION_* constants, * - 'invitationState': state of invitation. See INVITATION_* constants,
* defined in libs/invitation.php * defined in libs/invitation.php
* - 'lastToken': last chat token * - 'lastToken': last chat token
* - 'nextAgent': id of the next agent(agent that change current agent in the chat) * - 'nextAgent': id of the next agent(agent that change current agent in
* the chat)
* - 'groupId': id of the group related to the thread * - 'groupId': id of the group related to the thread
* - 'shownMessageId': last id of shown message * - 'shownMessageId': last id of shown message
* - 'messageCount': count of user's messages related to the thread * - 'messageCount': count of user's messages related to the thread
@ -149,7 +151,8 @@ Class Thread {
* - 'chatStarted': unix timestamp of related to thread chat started * - 'chatStarted': unix timestamp of related to thread chat started
* - 'agentId': id of an operator who take part in the chat * - 'agentId': id of an operator who take part in the chat
* - 'agentName': name of an operator who take part in the chat * - 'agentName': name of an operator who take part in the chat
* - 'agentTyping': "1" if operator typing at last ping time and "0" otherwise * - 'agentTyping': "1" if operator typing at last ping time and "0"
* otherwise
* - 'lastPingAgent': unix timestamp of last operator ping * - 'lastPingAgent': unix timestamp of last operator ping
* - 'locale': locale code of the chat related to thread * - 'locale': locale code of the chat related to thread
* - 'userId': id of an user who take part in the chat * - 'userId': id of an user who take part in the chat
@ -168,44 +171,37 @@ Class Thread {
*/ */
protected $propertyMap = array( protected $propertyMap = array(
'id' => 'threadid', 'id' => 'threadid',
'lastRevision' => 'lrevision', 'lastRevision' => 'lrevision',
'state' => 'istate', 'state' => 'istate',
'invitationState' => 'invitationstate', 'invitationState' => 'invitationstate',
'lastToken' => 'ltoken', 'lastToken' => 'ltoken',
'nextAgent' => 'nextagent', 'nextAgent' => 'nextagent',
'groupId' => 'groupid', 'groupId' => 'groupid',
'shownMessageId' => 'shownmessageid', 'shownMessageId' => 'shownmessageid',
'messageCount' => 'messageCount', 'messageCount' => 'messageCount',
'created' => 'dtmcreated', 'created' => 'dtmcreated',
'modified' => 'dtmmodified', 'modified' => 'dtmmodified',
'chatStarted' => 'dtmchatstarted', 'chatStarted' => 'dtmchatstarted',
'closed' => 'dtmclosed', 'closed' => 'dtmclosed',
'agentId' => 'agentId', 'agentId' => 'agentId',
'agentName' => 'agentName', 'agentName' => 'agentName',
'agentTyping' => 'agentTyping', 'agentTyping' => 'agentTyping',
'lastPingAgent' => 'lastpingagent', 'lastPingAgent' => 'lastpingagent',
'locale' => 'locale', 'locale' => 'locale',
'userId' => 'userid', 'userId' => 'userid',
'userName' => 'userName', 'userName' => 'userName',
'userTyping' => 'userTyping', 'userTyping' => 'userTyping',
'lastPingUser' => 'lastpinguser', 'lastPingUser' => 'lastpinguser',
'remote' => 'remote', 'remote' => 'remote',
'referer' => 'referer', 'referer' => 'referer',
'userAgent' => 'userAgent' 'userAgent' => 'userAgent',
); );
/** /**
* Contain loaded from database information about thread * Contain loaded from database information about thread
* *
* Do not use this property manually! * Do not use this property manually!
*
* @var array * @var array
*/ */
protected $threadInfo; protected $threadInfo;
@ -214,22 +210,19 @@ Class Thread {
* List of modified fields. * List of modified fields.
* *
* Do not use this property manually! * Do not use this property manually!
*
* @var array * @var array
*/ */
protected $changedFields = array(); protected $changedFields = array();
/**
* Forbid create instance from outside of the class
*/
protected function __construct() {}
/** /**
* Create new empty thread in database * Create new empty thread in database
* *
* @return boolean|Thread Returns an object of the Thread class or boolean * @return boolean|Thread Returns an object of the Thread class or boolean
* false on failure * false on failure
*/ */
public static function create() { public static function create()
{
// Get database object // Get database object
$db = Database::getInstance(); $db = Database::getInstance();
@ -252,6 +245,7 @@ Class Thread {
// Set initial values // Set initial values
$thread->lastToken = self::nextToken(); $thread->lastToken = self::nextToken();
$thread->created = time(); $thread->created = time();
return $thread; return $thread;
} }
@ -264,7 +258,8 @@ Class Thread {
* @return boolean|Thread Returns an object of the Thread class or boolean * @return boolean|Thread Returns an object of the Thread class or boolean
* false on failure * false on failure
*/ */
public static function createFromDbInfo($thread_info) { public static function createFromDbInfo($thread_info)
{
// Create new empty thread // Create new empty thread
$thread = new self(); $thread = new self();
@ -279,6 +274,7 @@ Class Thread {
// Copy field to Thread object // Copy field to Thread object
$thread->threadInfo[$field] = $thread_info[$field]; $thread->threadInfo[$field] = $thread_info[$field];
} }
return $thread; return $thread;
} }
@ -289,7 +285,8 @@ Class Thread {
* @return boolean|Thread Returns an object of the Thread class or boolean * @return boolean|Thread Returns an object of the Thread class or boolean
* false on failure * false on failure
*/ */
public static function load($id, $last_token = null) { public static function load($id, $last_token = null)
{
// Check $id // Check $id
if (empty($id)) { if (empty($id)) {
return false; return false;
@ -303,10 +300,8 @@ Class Thread {
// Load thread // Load thread
$thread_info = $db->query( $thread_info = $db->query(
"select * from {chatthread} where threadid = :threadid", "SELECT * FROM {chatthread} WHERE threadid = :threadid",
array( array(':threadid' => $id),
':threadid' => $id
),
array('return_rows' => Database::RETURN_ONE_ROW) array('return_rows' => Database::RETURN_ONE_ROW)
); );
@ -329,28 +324,34 @@ Class Thread {
return false; return false;
} }
} }
return $thread; return $thread;
} }
/** /**
* Reopen thread and send message about it * Reopen thread and send message about it
* *
* @return boolean|Thread Boolean FALSE on failure or thread object on success * @return boolean|Thread Boolean FALSE on failure or thread object on
* success
*/ */
public static function reopen($id) { public static function reopen($id)
{
// Load thread // Load thread
$thread = self::load($id); $thread = self::load($id);
// Check if user and agent gone // Check if user and agent gone
if (Settings::get('thread_lifetime') != 0 && $user_gone = abs($thread->lastPingUser - time()) > Settings::get('thread_lifetime');
abs($thread->lastPingUser - time()) > Settings::get('thread_lifetime') && $agent_gone = abs($thread->lastPingAgent - time()) > Settings::get('thread_lifetime');
abs($thread->lastPingAgent - time()) > Settings::get('thread_lifetime')) { if (Settings::get('thread_lifetime') != 0 && $user_gone && $agent_gone) {
unset($thread); unset($thread);
return false; return false;
} }
// Check if thread closed // Check if thread closed
if ($thread->state == self::STATE_CLOSED || $thread->state == self::STATE_LEFT) { if ($thread->state == self::STATE_CLOSED || $thread->state == self::STATE_LEFT) {
unset($thread); unset($thread);
return false; return false;
} }
@ -361,57 +362,62 @@ Class Thread {
} }
// Send message // Send message
$thread->postMessage(self::KIND_EVENTS, getstring_("chat.status.user.reopenedthread", $thread->locale)); $thread->postMessage(
self::KIND_EVENTS,
getstring_("chat.status.user.reopenedthread", $thread->locale)
);
return $thread; return $thread;
} }
/** /**
* Close all old threads that were not closed by some reasons * Close all old threads that were not closed by some reasons
*/ */
public static function closeOldThreads() { public static function closeOldThreads()
{
if (Settings::get('thread_lifetime') == 0) { if (Settings::get('thread_lifetime') == 0) {
return; return;
} }
$db = Database::getInstance(); $db = Database::getInstance();
$query = "UPDATE {chatthread} SET " . $query = "UPDATE {chatthread} SET "
"lrevision = :next_revision, " . . "lrevision = :next_revision, "
"dtmmodified = :now, " . . "dtmmodified = :now, "
"dtmclosed = :now, " . . "dtmclosed = :now, "
"istate = :state_closed " . . "istate = :state_closed "
"WHERE istate <> :state_closed " . . "WHERE istate <> :state_closed "
"AND istate <> :state_left " . . "AND istate <> :state_left "
// Check created timestamp // Check created timestamp
"AND ABS(:now - dtmcreated) > :thread_lifetime " . . "AND ABS(:now - dtmcreated) > :thread_lifetime "
// Check pings // Check pings
"AND ( " . . "AND ( "
"( " . . "( "
// Both user and operator have no connection problems. // Both user and operator have no connection problems.
// Check all pings. // Check all pings.
"lastpingagent <> 0 " . . "lastpingagent <> 0 "
"AND lastpinguser <> 0 " . . "AND lastpinguser <> 0 "
"AND ABS(:now - lastpinguser) > :thread_lifetime " . . "AND ABS(:now - lastpinguser) > :thread_lifetime "
"AND ABS(:now - lastpingagent) > :thread_lifetime " . . "AND ABS(:now - lastpingagent) > :thread_lifetime "
") OR ( " . . ") OR ( "
// Only operator have connection problems. // Only operator have connection problems.
// Check user's ping. // Check user's ping.
"lastpingagent = 0 " . . "lastpingagent = 0 "
"AND lastpinguser <> 0 " . . "AND lastpinguser <> 0 "
"AND ABS(:now - lastpinguser) > :thread_lifetime " . . "AND ABS(:now - lastpinguser) > :thread_lifetime "
") OR ( " . . ") OR ( "
// Only user have connection problems. // Only user have connection problems.
// Check operator's ping. // Check operator's ping.
"lastpinguser = 0 " . . "lastpinguser = 0 "
"AND lastpingagent <> 0 " . . "AND lastpingagent <> 0 "
"AND ABS(:now - lastpingagent) > :thread_lifetime " . . "AND ABS(:now - lastpingagent) > :thread_lifetime "
") OR ( " . . ") OR ( "
// Both user and operator have connection problems. // Both user and operator have connection problems.
// Just close thread. // Just close thread.
"lastpinguser = 0 " . . "lastpinguser = 0 "
"AND lastpingagent = 0 " . . "AND lastpingagent = 0 "
") " . . ") "
")"; . ")";
$db->query( $db->query(
$query, $query,
@ -420,7 +426,7 @@ Class Thread {
':now' => time(), ':now' => time(),
':state_closed' => self::STATE_CLOSED, ':state_closed' => self::STATE_CLOSED,
':state_left' => self::STATE_LEFT, ':state_left' => self::STATE_LEFT,
':thread_lifetime' => Settings::get('thread_lifetime') ':thread_lifetime' => Settings::get('thread_lifetime'),
) )
); );
} }
@ -431,71 +437,52 @@ Class Thread {
* @param string $remote User IP * @param string $remote User IP
* @return boolean TRUE if connection limit reached and FALSE otherwise * @return boolean TRUE if connection limit reached and FALSE otherwise
*/ */
public static function connectionLimitReached($remote) { public static function connectionLimitReached($remote)
{
if (Settings::get('max_connections_from_one_host') == 0) { if (Settings::get('max_connections_from_one_host') == 0) {
return false; return false;
} }
$db = Database::getInstance(); $db = Database::getInstance();
$result = $db->query( $result = $db->query(
"select count(*) as opened from {chatthread} " . "SELECT COUNT(*) AS opened FROM {chatthread} WHERE remote = ? AND istate <> ? AND istate <> ?",
"where remote = ? AND istate <> ? AND istate <> ?", array(
array($remote, Thread::STATE_CLOSED, Thread::STATE_LEFT), $remote,
Thread::STATE_CLOSED,
Thread::STATE_LEFT,
),
array('return_rows' => Database::RETURN_ONE_ROW) array('return_rows' => Database::RETURN_ONE_ROW)
); );
if ($result && isset($result['opened'])) { if ($result && isset($result['opened'])) {
return $result['opened'] >= Settings::get('max_connections_from_one_host'); return $result['opened'] >= Settings::get('max_connections_from_one_host');
} }
return false; return false;
} }
/**
* Return next revision number (last revision number plus one)
*
* @return int revision number
*/
protected static function nextRevision() {
$db = Database::getInstance();
$db->query("update {chatrevision} set id=LAST_INSERT_ID(id+1)");
$val = $db->insertedId();
return $val;
}
/**
* Create thread token
*
* @return int Thread token
*/
protected static function nextToken() {
if (function_exists('openssl_random_pseudo_bytes')) {
$token_arr = unpack('N', "\x0" . openssl_random_pseudo_bytes(3));
$token = $token_arr[1];
}
else {
$token = mt_rand(99999, 99999999);
}
return $token;
}
/** /**
* Implementation of the magic __get method * Implementation of the magic __get method
* *
* Check if variable with name $name exists in the Thread::$propertyMap array. * Check if variable with name $name exists in the Thread::$propertyMap
* If it does not exist triggers an error with E_USER_NOTICE level and returns false. * array. If it does not exist triggers an error with E_USER_NOTICE level
* and returns false.
* *
* @param string $name property name * @param string $name property name
* @return mixed * @return mixed
* @see Thread::$propertyMap * @see Thread::$propertyMap
*/ */
public function __get($name) { public function __get($name)
{
// Check property existance // Check property existance
if (!array_key_exists($name, $this->propertyMap)) { if (!array_key_exists($name, $this->propertyMap)) {
trigger_error("Undefined property '{$name}'", E_USER_NOTICE); trigger_error("Undefined property '{$name}'", E_USER_NOTICE);
return NULL;
return null;
} }
$field_name = $this->propertyMap[$name]; $field_name = $this->propertyMap[$name];
return $this->threadInfo[$field_name]; return $this->threadInfo[$field_name];
} }
@ -513,16 +500,17 @@ Class Thread {
* @return mixed * @return mixed
* @see Thread::$propertyMap * @see Thread::$propertyMap
*/ */
public function __set($name, $value) { public function __set($name, $value)
{
if (empty($this->propertyMap[$name])) { if (empty($this->propertyMap[$name])) {
trigger_error("Undefined property '{$name}'", E_USER_NOTICE); trigger_error("Undefined property '{$name}'", E_USER_NOTICE);
return; return;
} }
$field_name = $this->propertyMap[$name]; $field_name = $this->propertyMap[$name];
if (array_key_exists($field_name, $this->threadInfo) if (array_key_exists($field_name, $this->threadInfo) && ($this->threadInfo[$field_name] === $value)) {
&& ($this->threadInfo[$field_name] === $value)) {
return; return;
} }
@ -541,19 +529,22 @@ Class Thread {
* param string $name Variable name * param string $name Variable name
* return boolean True if variable exists and false otherwise * return boolean True if variable exists and false otherwise
*/ */
public function __isset($name) { public function __isset($name)
{
if (!array_key_exists($name, $this->propertyMap)) { if (!array_key_exists($name, $this->propertyMap)) {
return false; return false;
} }
$property_name = $this->propertyMap[$name]; $property_name = $this->propertyMap[$name];
return isset($this->threadInfo[$property_name]); return isset($this->threadInfo[$property_name]);
} }
/** /**
* Remove thread from database * Remove thread from database
*/ */
public function delete() { public function delete()
{
$db = Database::getInstance(); $db = Database::getInstance();
$db->query( $db->query(
"DELETE FROM {chatthread} WHERE threadid = :id LIMIT 1", "DELETE FROM {chatthread} WHERE threadid = :id LIMIT 1",
@ -564,13 +555,16 @@ Class Thread {
/** /**
* Ping the thread. * Ping the thread.
* *
* Updates ping time for conversation members and sends messages about connection problems. * Updates ping time for conversation members and sends messages about
* connection problems.
* *
* @param boolean $is_user Indicates user or operator pings thread. Boolean true for user and boolean false * @param boolean $is_user Indicates user or operator pings thread. Boolean
* otherwise. * true for user and boolean false otherwise.
* @param boolean $is_typing Indicates if user or operator is typing a message. * @param boolean $is_typing Indicates if user or operator is typing a
* message.
*/ */
public function ping($is_user, $is_typing) { public function ping($is_user, $is_typing)
{
// Indicates if revision ID of the thread should be updated on save. // Indicates if revision ID of the thread should be updated on save.
// Update revision leads to rerender thread in threads list at client // Update revision leads to rerender thread in threads list at client
// side. Do it on every ping is too costly. // side. Do it on every ping is too costly.
@ -606,14 +600,14 @@ Class Thread {
// Check if user chatting at the moment // Check if user chatting at the moment
if ($this->state == self::STATE_CHATTING) { if ($this->state == self::STATE_CHATTING) {
// Send message to user // Send message to user
$message_to_post = getstring_("chat.status.operator.dead", $this->locale); $message_to_post = getstring_(
"chat.status.operator.dead",
$this->locale
);
$this->postMessage( $this->postMessage(
self::KIND_CONN, self::KIND_CONN,
$message_to_post, $message_to_post,
array( array('created' => $last_ping_other_side + self::CONNECTION_TIMEOUT)
'created' => $last_ping_other_side
+ self::CONNECTION_TIMEOUT
)
); );
// And update thread // And update thread
@ -630,14 +624,14 @@ Class Thread {
$this->lastPingUser = 0; $this->lastPingUser = 0;
// And send a message to operator // And send a message to operator
$message_to_post = getstring_("chat.status.user.dead", $this->locale); $message_to_post = getstring_(
"chat.status.user.dead",
$this->locale
);
$this->postMessage( $this->postMessage(
self::KIND_FOR_AGENT, self::KIND_FOR_AGENT,
$message_to_post, $message_to_post,
array( array('created' => $last_ping_other_side + self::CONNECTION_TIMEOUT)
'created' => $last_ping_other_side
+ self::CONNECTION_TIMEOUT
)
); );
} }
} }
@ -648,9 +642,11 @@ Class Thread {
/** /**
* Save the thread to the database * Save the thread to the database
* *
* @param boolean $update_revision Indicates if last modified time and last revision should be updated * @param boolean $update_revision Indicates if last modified time and last
* revision should be updated.
*/ */
public function save($update_revision = true){ public function save($update_revision = true)
{
$db = Database::getInstance(); $db = Database::getInstance();
// Update modified time and last revision if need // Update modified time and last revision if need
@ -672,14 +668,15 @@ Class Thread {
$values[] = $this->threadInfo[$field_db_name]; $values[] = $this->threadInfo[$field_db_name];
} }
$query = "update {chatthread} t set " . implode(', ', $set_clause) . " where threadid = ?"; $query = "UPDATE {chatthread} t SET " . implode(', ', $set_clause)
. " WHERE threadid = ?";
$values[] = $this->id; $values[] = $this->id;
$db->query($query, $values); $db->query($query, $values);
// Trigger thread changed event // Trigger thread changed event
$args = array( $args = array(
'thread' => $this, 'thread' => $this,
'changed_fields' => $this->changedFields 'changed_fields' => $this->changedFields,
); );
$dispatcher = EventDispatcher::getInstance(); $dispatcher = EventDispatcher::getInstance();
$dispatcher->triggerEvent('threadChanged', $args); $dispatcher->triggerEvent('threadChanged', $args);
@ -691,14 +688,20 @@ Class Thread {
/** /**
* Check if thread is reassigned for another operator * Check if thread is reassigned for another operator
* *
* Updates thread info, send events messages and avatar message to user * Updates thread info, send events messages and avatar message to user.
*
* @param array $operator Operator for test * @param array $operator Operator for test
*/ */
public function checkForReassign($operator) { public function checkForReassign($operator)
$operator_name = ($this->locale == HOME_LOCALE) ? $operator['vclocalename'] : $operator['vccommonname']; {
$operator_name = ($this->locale == HOME_LOCALE)
? $operator['vclocalename']
: $operator['vccommonname'];
if ($this->state == self::STATE_WAITING && $is_operator_correct = $this->nextAgent == $operator['operatorid']
($this->nextAgent == $operator['operatorid'] || $this->agentId == $operator['operatorid'])) { || $this->agentId == $operator['operatorid'];
if ($this->state == self::STATE_WAITING && $is_operator_correct) {
// Prepare message // Prepare message
if ($this->nextAgent == $operator['operatorid']) { if ($this->nextAgent == $operator['operatorid']) {
@ -708,7 +711,11 @@ Class Thread {
$this->locale $this->locale
); );
} else { } else {
$message_to_post = getstring2_("chat.status.operator.returned", array($operator_name), $this->locale); $message_to_post = getstring2_(
"chat.status.operator.returned",
array($operator_name),
$this->locale
);
} }
// Update thread info // Update thread info
@ -745,20 +752,23 @@ Class Thread {
* - 'data' array, arbitrary data attached to the message * - 'data' array, arbitrary data attached to the message
* @see Thread::postMessage() * @see Thread::postMessage()
*/ */
public function getMessages($is_user, &$last_id) { public function getMessages($is_user, &$last_id)
{
$db = Database::getInstance(); $db = Database::getInstance();
// Load messages // Load messages
$query = "SELECT messageid AS id, ikind AS kind, dtmcreated AS created, "
. " tname AS name, tmessage AS message, plugin, data "
. "FROM {chatmessage} "
. "WHERE threadid = :threadid AND messageid > :lastid "
. ($is_user ? "AND ikind <> " . self::KIND_FOR_AGENT : "")
. " ORDER BY messageid";
$messages = $db->query( $messages = $db->query(
"select messageid as id, ikind as kind, dtmcreated as created, " . $query,
" tname as name, tmessage as message, plugin, data " .
"from {chatmessage} " .
"where threadid = :threadid and messageid > :lastid " .
($is_user ? "and ikind <> " . self::KIND_FOR_AGENT : "") .
" order by messageid",
array( array(
':threadid' => $this->id, ':threadid' => $this->id,
':lastid' => $last_id ':lastid' => $last_id,
), ),
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
@ -819,8 +829,8 @@ Class Thread {
* - 'plugin': string, name of the plugin which sent the message. If * - 'plugin': string, name of the plugin which sent the message. If
* message was not sent by a plugin do not set this field. * message was not sent by a plugin do not set this field.
* - 'data': array with arbitrary data related with message. This value * - 'data': array with arbitrary data related with message. This value
* will be converted to array and serialized before save. If there is no * will be converted to array and serialized before save. If there is
* such data do not set this field. * no such data do not set this field.
* *
* @return int Message ID * @return int Message ID
* *
@ -834,90 +844,22 @@ Class Thread {
* @see Thread::getMessages() * @see Thread::getMessages()
* @see Thread::postPluginMessage() * @see Thread::postPluginMessage()
*/ */
public function postMessage($kind, $message, $options = array()) { public function postMessage($kind, $message, $options = array())
{
$options = is_array($options) ? $options : array(); $options = is_array($options) ? $options : array();
// Send message // Send message
return $this->saveMessage($kind, $message, $options); return $this->saveMessage($kind, $message, $options);
} }
/**
* Save the messsage in database
*
* @param int $kind Message kind. One of the Thread::KIND_*
* @param string $message Message body
* @param array $options List of additional options. It may contain
* following items:
* - 'name': string, name of the message sender.
* - 'operator_id': int, ID of the operator who sent the message. For
* system messages do not set this field.
* - 'created': int, unix timestamp of the send time. If you want to set
* current time do not set this field.
* - 'plugin': string, name of the plugin which sent the message. If
* message was not sent by a plugin do not set this field.
* - 'data': array with arbitrary data related with message. This value
* will be converted to array and serialized before save. If there is no
* such data do not set this field.
*
* @return int Message ID
*
* @see Thread::KIND_USER
* @see Thread::KIND_AGENT
* @see Thread::KIND_FOR_AGENT
* @see Thread::KIND_INFO
* @see Thread::KIND_CONN
* @see Thread::KIND_EVENTS
* @see Thread::KIND_PLUGIN
* @see Thread::getMessages()
*/
protected function saveMessage($kind, $message, $options = array()) {
$db = Database::getInstance();
// TODO: check incoming message (it should be non-empty string)
// Add default values to options
$options += array(
'name' => null,
'operator_id' => 0,
'created' => time(),
'plugin' => '',
'data' => array()
);
// Prepare message data
$options['data'] = serialize((array)$options['data']);
// Prepare query
$query = "INSERT INTO {chatmessage} (" .
"threadid, ikind, tmessage, tname, agentId, " .
"dtmcreated, plugin, data" .
") VALUES (" .
":threadid, :kind, :message, :name, :agentid, " .
":created, :plugin, :data" .
")";
$values = array(
':threadid' => $this->id,
':kind' => $kind,
':message' => $message,
':name' => $options['name'],
':agentid' => $options['operator_id'],
':created' => $options['created'],
':plugin' => $options['plugin'],
':data' => $options['data']
);
// Execute query
$db->query($query, $values);
return $db->insertedId();
}
/** /**
* Close thread and send closing messages to the conversation members * Close thread and send closing messages to the conversation members
* *
* @param boolean $is_user Boolean TRUE if user initiate thread closing or boolean FALSE otherwise * @param boolean $is_user Boolean TRUE if user initiate thread closing or
* boolean FALSE otherwise
*/ */
public function close($is_user) { public function close($is_user)
{
// Send message about closing // Send message about closing
if ($is_user) { if ($is_user) {
$this->postMessage( $this->postMessage(
@ -953,14 +895,15 @@ Class Thread {
$db = Database::getInstance(); $db = Database::getInstance();
list($message_count) = $db->query( list($message_count) = $db->query(
"SELECT COUNT(*) FROM {chatmessage} WHERE {chatmessage}.threadid = :threadid AND ikind = :kind_user", ("SELECT COUNT(*) FROM {chatmessage} "
. "WHERE {chatmessage}.threadid = :threadid AND ikind = :kind_user"),
array( array(
':threadid' => $this->id, ':threadid' => $this->id,
':kind_user' => Thread::KIND_USER ':kind_user' => Thread::KIND_USER,
), ),
array( array(
'return_rows' => Database::RETURN_ONE_ROW, 'return_rows' => Database::RETURN_ONE_ROW,
'fetch_type' => Database::FETCH_NUM 'fetch_type' => Database::FETCH_NUM,
) )
); );
@ -979,12 +922,19 @@ Class Thread {
* @param array $operator Operator who try to take thread * @param array $operator Operator who try to take thread
* @return boolean Boolean TRUE on success or FALSE on failure * @return boolean Boolean TRUE on success or FALSE on failure
*/ */
public function take($operator) { public function take($operator)
{
$take_thread = false; $take_thread = false;
$message = ''; $message = '';
$operator_name = ($this->locale == HOME_LOCALE) ? $operator['vclocalename'] : $operator['vccommonname']; $operator_name = ($this->locale == HOME_LOCALE)
? $operator['vclocalename']
: $operator['vccommonname'];
if ($this->state == self::STATE_QUEUE || $this->state == self::STATE_WAITING || $this->state == self::STATE_LOADING) { $no_operator_in_chat = self::STATE_QUEUE
|| self::STATE_WAITING
|| self::STATE_LOADING;
if ($no_operator_in_chat) {
// User waiting // User waiting
$take_thread = true; $take_thread = true;
if ($this->state == self::STATE_WAITING) { if ($this->state == self::STATE_WAITING) {
@ -995,10 +945,18 @@ Class Thread {
$this->locale $this->locale
); );
} else { } else {
$message = getstring2_("chat.status.operator.returned", array($operator_name), $this->locale); $message = getstring2_(
"chat.status.operator.returned",
array($operator_name),
$this->locale
);
} }
} else { } else {
$message = getstring2_("chat.status.operator.joined", array($operator_name), $this->locale); $message = getstring2_(
"chat.status.operator.joined",
array($operator_name),
$this->locale
);
} }
} elseif ($this->state == self::STATE_CHATTING) { } elseif ($this->state == self::STATE_CHATTING) {
// User chatting // User chatting
@ -1034,6 +992,7 @@ Class Thread {
$operator['vcavatar'] ? $operator['vcavatar'] : "" $operator['vcavatar'] ? $operator['vcavatar'] : ""
); );
} }
return true; return true;
} }
@ -1042,7 +1001,8 @@ Class Thread {
* *
* @param string $new_name New user name * @param string $new_name New user name
*/ */
public function renameUser($new_name) { public function renameUser($new_name)
{
// Rename only if a new name is realy new // Rename only if a new name is realy new
if ($this->userName != $new_name) { if ($this->userName != $new_name) {
// Save old name // Save old name
@ -1061,11 +1021,123 @@ Class Thread {
} }
} }
/**
* Forbid create instance from outside of the class
*/
protected function __construct()
{
}
/**
* Save the messsage in database
*
* @param int $kind Message kind. One of the Thread::KIND_*
* @param string $message Message body
* @param array $options List of additional options. It may contain
* following items:
* - 'name': string, name of the message sender.
* - 'operator_id': int, ID of the operator who sent the message. For
* system messages do not set this field.
* - 'created': int, unix timestamp of the send time. If you want to set
* current time do not set this field.
* - 'plugin': string, name of the plugin which sent the message. If
* message was not sent by a plugin do not set this field.
* - 'data': array with arbitrary data related with message. This value
* will be converted to array and serialized before save. If there is no
* such data do not set this field.
*
* @return int Message ID
*
* @see Thread::KIND_USER
* @see Thread::KIND_AGENT
* @see Thread::KIND_FOR_AGENT
* @see Thread::KIND_INFO
* @see Thread::KIND_CONN
* @see Thread::KIND_EVENTS
* @see Thread::KIND_PLUGIN
* @see Thread::getMessages()
*/
protected function saveMessage($kind, $message, $options = array())
{
$db = Database::getInstance();
// TODO: check incoming message (it should be non-empty string)
// Add default values to options
$options += array(
'name' => null,
'operator_id' => 0,
'created' => time(),
'plugin' => '',
'data' => array(),
);
// Prepare message data
$options['data'] = serialize((array) $options['data']);
// Prepare query
$query = "INSERT INTO {chatmessage} ("
. "threadid, ikind, tmessage, tname, agentId, "
. "dtmcreated, plugin, data"
. ") VALUES ("
. ":threadid, :kind, :message, :name, :agentid, "
. ":created, :plugin, :data"
. ")";
$values = array(
':threadid' => $this->id,
':kind' => $kind,
':message' => $message,
':name' => $options['name'],
':agentid' => $options['operator_id'],
':created' => $options['created'],
':plugin' => $options['plugin'],
':data' => $options['data'],
);
// Execute query
$db->query($query, $values);
return $db->insertedId();
}
/**
* Return next revision number (last revision number plus one)
*
* @return int revision number
*/
protected static function nextRevision()
{
$db = Database::getInstance();
$db->query("UPDATE {chatrevision} SET id=LAST_INSERT_ID(id+1)");
$val = $db->insertedId();
return $val;
}
/**
* Create thread token
*
* @return int Thread token
*/
protected static function nextToken()
{
if (function_exists('openssl_random_pseudo_bytes')) {
$token_arr = unpack('N', "\x0" . openssl_random_pseudo_bytes(3));
$token = $token_arr[1];
} else {
$token = mt_rand(99999, 99999999);
}
return $token;
}
/** /**
* Set operator avatar in the user's chat window * Set operator avatar in the user's chat window
*
* @param string $link URL of the new operator avatar * @param string $link URL of the new operator avatar
*/ */
protected function setupAvatar($link) { protected function setupAvatar($link)
{
$processor = ThreadProcessor::getInstance(); $processor = ThreadProcessor::getInstance();
$processor->call(array( $processor->call(array(
array( array(
@ -1076,11 +1148,9 @@ Class Thread {
'return' => array(), 'return' => array(),
'references' => array(), 'references' => array(),
'recipient' => 'user', 'recipient' => 'user',
'imageLink' => $link 'imageLink' => $link,
) ),
) ),
)); ));
} }
} }
?>

View File

@ -17,9 +17,11 @@
/** /**
* Autoloader for classes which implements PSR-0 standard. * Autoloader for classes which implements PSR-0 standard.
*
* @param string $class_name Fully qualified name of the class * @param string $class_name Fully qualified name of the class
*/ */
function class_autoload($class_name) { function class_autoload($class_name)
{
$base_dir = MIBEW_FS_ROOT . DIRECTORY_SEPARATOR . 'libs' . $base_dir = MIBEW_FS_ROOT . DIRECTORY_SEPARATOR . 'libs' .
DIRECTORY_SEPARATOR . 'classes'; DIRECTORY_SEPARATOR . 'classes';
@ -35,5 +37,3 @@ function class_autoload($class_name) {
require $base_dir . DIRECTORY_SEPARATOR . $file_name; require $base_dir . DIRECTORY_SEPARATOR . $file_name;
} }
?>

View File

@ -22,11 +22,11 @@
* @return boolean|array Array of configurations or boolean false if file can * @return boolean|array Array of configurations or boolean false if file can
* not be read. * not be read.
*/ */
function read_config_file($file) { function read_config_file($file)
{
if (!is_readable($file)) { if (!is_readable($file)) {
return false; return false;
} }
return parse_ini_file($file, true); return parse_ini_file($file, true);
} }
?>

View File

@ -41,8 +41,8 @@ define('SESSION_PREFIX', md5($mysqlhost.'##'.$mysqldb.'##'.$mysqlprefix) . '_');
* Another value can be set at operator/settings.php page. * Another value can be set at operator/settings.php page.
*/ */
define('DEFAULT_CRON_KEY', md5( define('DEFAULT_CRON_KEY', md5(
$mysqlhost . '##' . $mysqldb . '##' . $mysqllogin. '##' . $mysqlhost . '##' . $mysqldb . '##' . $mysqllogin . '##'
$mysqlpass . '##' . $mysqlprefix . '##' . $mysqlpass . '##' . $mysqlprefix . '##'
)); ));
/** /**
@ -54,5 +54,3 @@ define('VISITOR_COOKIE_NAME', 'MIBEW_VisitorID');
* Internal system encoding * Internal system encoding
*/ */
define('MIBEW_ENCODING', $mibew_encoding); define('MIBEW_ENCODING', $mibew_encoding);
?>

View File

@ -47,5 +47,3 @@ $_win1251utf8 = array(
"\xF6" => "\xD1\x86", "\xF7" => "\xD1\x87", "\xF8" => "\xD1\x88", "\xF9" => "\xD1\x89", "\xFA" => "\xD1\x8A", "\xF6" => "\xD1\x86", "\xF7" => "\xD1\x87", "\xF8" => "\xD1\x88", "\xF9" => "\xD1\x89", "\xFA" => "\xD1\x8A",
"\xFB" => "\xD1\x8B", "\xFC" => "\xD1\x8C", "\xFD" => "\xD1\x8D", "\xFE" => "\xD1\x8E", "\xFF" => "\xD1\x8F", "\xFB" => "\xD1\x8B", "\xFC" => "\xD1\x8C", "\xFD" => "\xD1\x8D", "\xFE" => "\xD1\x8E", "\xFF" => "\xD1\x8F",
"\xB3" => "\xD1\x96", "\xBF" => "\xD1\x97", "\xBA" => "\xD1\x94", "\xA2" => "\xD1\x9E"); "\xB3" => "\xD1\x96", "\xBF" => "\xD1\x97", "\xBA" => "\xD1\x94", "\xA2" => "\xD1\x9E");
?>

View File

@ -16,20 +16,18 @@
*/ */
/* authorization token check for CSRF attack */ /* authorization token check for CSRF attack */
function csrfchecktoken() function csrf_check_token()
{ {
setcsrftoken(); set_csrf_token();
// check the turing code for post requests and del requests // Check the turing code for post requests and del requests
if ($_SERVER['REQUEST_METHOD'] == 'POST') { if ($_SERVER['REQUEST_METHOD'] == 'POST') {
//if token match // If token match
if (!isset($_POST['csrf_token']) || ($_POST['csrf_token'] != $_SESSION['csrf_token'])) { if (!isset($_POST['csrf_token']) || ($_POST['csrf_token'] != $_SESSION['csrf_token'])) {
die("CSRF failure"); die("CSRF failure");
} }
} elseif (isset($_GET['act'])) { } elseif (isset($_GET['act'])) {
if (($_GET['act'] == 'del' || $_GET['act'] == 'delete') && $_GET['csrf_token'] != $_SESSION['csrf_token']) { if (($_GET['act'] == 'del' || $_GET['act'] == 'delete') && $_GET['csrf_token'] != $_SESSION['csrf_token']) {
die("CSRF failure"); die("CSRF failure");
} }
} }
@ -38,7 +36,7 @@ function csrfchecktoken()
/* print csrf token as a hidden field */ /* print csrf token as a hidden field */
function print_csrf_token_input() function print_csrf_token_input()
{ {
setcsrftoken(); set_csrf_token();
echo "<input name='csrf_token' type='hidden' value='" . $_SESSION['csrf_token'] . "' />"; echo "<input name='csrf_token' type='hidden' value='" . $_SESSION['csrf_token'] . "' />";
} }
@ -46,17 +44,17 @@ function print_csrf_token_input()
/* print csrf token in url format */ /* print csrf token in url format */
function print_csrf_token_in_url() function print_csrf_token_in_url()
{ {
setcsrftoken(); set_csrf_token();
echo "&amp;csrf_token=" . $_SESSION['csrf_token']; echo "&amp;csrf_token=" . $_SESSION['csrf_token'];
} }
/* set csrf token */ /* set csrf token */
function setcsrftoken() function set_csrf_token()
{ {
if (!isset($_SESSION['csrf_token'])) { if (!isset($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = sha1(session_id() . (function_exists('openssl_random_pseudo_bytes') ? openssl_random_pseudo_bytes(32) : (time() + microtime()) . mt_rand(0, 99999999))); $_SESSION['csrf_token'] = sha1(session_id() . (function_exists('openssl_random_pseudo_bytes')
? openssl_random_pseudo_bytes(32)
: (time() + microtime()) . mt_rand(0, 99999999)));
} }
} }
?>

View File

@ -15,8 +15,6 @@
* limitations under the License. * limitations under the License.
*/ */
require_once(MIBEW_FS_ROOT.'/libs/common/locale.php');
function date_diff_to_text($seconds) function date_diff_to_text($seconds)
{ {
$minutes = div($seconds, 60); $minutes = div($seconds, 60);
@ -26,13 +24,14 @@ function date_diff_to_text($seconds)
} else { } else {
$hours = div($minutes, 60); $hours = div($minutes, 60);
$minutes = $minutes % 60; $minutes = $minutes % 60;
return sprintf("%02d:%02d:%02d", $hours, $minutes, $seconds); return sprintf("%02d:%02d:%02d", $hours, $minutes, $seconds);
} }
} }
function get_month_selection($fromtime, $totime) function get_month_selection($from_time, $to_time)
{ {
$start = getdate($fromtime); $start = getdate($from_time);
$month = $start['mon']; $month = $start['mon'];
$year = $start['year']; $year = $start['year'];
$result = array(); $result = array();
@ -44,7 +43,8 @@ function get_month_selection($fromtime, $totime)
$month = 1; $month = 1;
$year++; $year++;
} }
} while ($current < $totime); } while ($current < $to_time);
return $result; return $result;
} }
@ -53,20 +53,23 @@ function get_form_date($day, $month)
if (preg_match('/^(\d{2}).(\d{2})$/', $month, $matches)) { if (preg_match('/^(\d{2}).(\d{2})$/', $month, $matches)) {
return mktime(0, 0, 0, $matches[1], $day, $matches[2]); return mktime(0, 0, 0, $matches[1], $day, $matches[2]);
} }
return 0; return 0;
} }
function set_form_date($utime, $prefix) { function set_form_date($utime, $prefix)
{
return array( return array(
"form${prefix}day" => date("d", $utime), "form${prefix}day" => date("d", $utime),
"form${prefix}month" => date("m.y", $utime) "form${prefix}month" => date("m.y", $utime),
); );
} }
function date_to_text($unixtime) function date_to_text($unixtime)
{ {
if ($unixtime < 60 * 60 * 24 * 30) if ($unixtime < 60 * 60 * 24 * 30) {
return getlocal("time.never"); return getlocal("time.never");
}
$then = getdate($unixtime); $then = getdate($unixtime);
$now = getdate(); $now = getdate();
@ -81,5 +84,3 @@ function date_to_text($unixtime)
return strftime($date_format . " " . getlocal("time.timeformat"), $unixtime); return strftime($date_format . " " . getlocal("time.timeformat"), $unixtime);
} }
?>

View File

@ -23,9 +23,12 @@
* @param string $name Form variable name. * @param string $name Form variable name.
* @return string Value of a form variable. * @return string Value of a form variable.
*/ */
function form_value($page, $name) { function form_value($page, $name)
if (!empty($page) && isset($page["form$name"])) {
if (!empty($page) && isset($page["form$name"])) {
return htmlspecialchars($page["form$name"]); return htmlspecialchars($page["form$name"]);
}
return ""; return "";
} }
@ -35,15 +38,17 @@ function form_value($page, $name) {
* @param array $page The page array. All form variables are prefixed with * @param array $page The page array. All form variables are prefixed with
* "form" string. * "form" string.
* @param string $name Form variable name. * @param string $name Form variable name.
* @return boolean Returns TRUE only if specified form variable is set, has boolean type * @return boolean Returns TRUE only if specified form variable is set, has
* and equals to TRUE. In all other cases returns FALSE. * boolean type and equals to TRUE. In all other cases returns FALSE.
*/ */
function form_value_cb($page, $name) { function form_value_cb($page, $name)
if (!empty($page) && isset($page["form$name"])) {
if (!empty($page) && isset($page["form$name"])) {
return $page["form$name"] === true; return $page["form$name"] === true;
return false;
} }
return false;
}
/** /**
* Checks if form variable is array and has element with specified key. * Checks if form variable is array and has element with specified key.
@ -55,11 +60,11 @@ function form_value_cb($page, $name) {
* @return boolean Returns TRUE only if specified form variable is set, is an * @return boolean Returns TRUE only if specified form variable is set, is an
* array has element with the specified key. In all other cases returns FALSE. * array has element with the specified key. In all other cases returns FALSE.
*/ */
function form_value_mb($page, $name, $key) { function form_value_mb($page, $name, $key)
{
if (!empty($page) && isset($page["form$name"]) && is_array($page["form$name"])) { if (!empty($page) && isset($page["form$name"]) && is_array($page["form$name"])) {
return in_array($key, $page["form$name"]); return in_array($key, $page["form$name"]);
} }
return false; return false;
} }
?>

View File

@ -18,10 +18,6 @@
// Import namespaces and classes of the core // Import namespaces and classes of the core
use Mibew\PluginManager; use Mibew\PluginManager;
// Initialize libraries
require_once(MIBEW_FS_ROOT.'/libs/common/converter.php');
require_once(MIBEW_FS_ROOT.'/libs/common/verification.php');
/** /**
* Name for the cookie to store locale code in use * Name for the cookie to store locale code in use
*/ */
@ -33,13 +29,19 @@ define('LOCALE_COOKIE_NAME', 'mibew_locale');
* Verified value of the $default_locale configuration parameter (see * Verified value of the $default_locale configuration parameter (see
* "libs/default_config.php" for details) * "libs/default_config.php" for details)
*/ */
define('DEFAULT_LOCALE', locale_pattern_check($default_locale) && locale_exists($default_locale) ? $default_locale : 'en'); define(
'DEFAULT_LOCALE',
locale_pattern_check($default_locale) && locale_exists($default_locale) ? $default_locale : 'en'
);
/** /**
* Verified value of the $home_locale configuration parameter (see * Verified value of the $home_locale configuration parameter (see
* "libs/default_config.php" for details) * "libs/default_config.php" for details)
*/ */
define('HOME_LOCALE', locale_pattern_check($home_locale) && locale_exists($home_locale) ? $home_locale : 'en'); define(
'HOME_LOCALE',
locale_pattern_check($home_locale) && locale_exists($home_locale) ? $home_locale : 'en'
);
/** /**
* Code of the current system locale * Code of the current system locale
@ -54,14 +56,16 @@ function myiconv($in_enc, $out_enc, $string)
} }
if (function_exists('iconv')) { if (function_exists('iconv')) {
$converted = @iconv($in_enc, $out_enc, $string); $converted = @iconv($in_enc, $out_enc, $string);
if ($converted !== FALSE) { if ($converted !== false) {
return $converted; return $converted;
} }
} }
if ($in_enc == "cp1251" && $out_enc == "utf-8") if ($in_enc == "cp1251" && $out_enc == "utf-8") {
return strtr($string, $_win1251utf8); return strtr($string, $_win1251utf8);
if ($in_enc == "utf-8" && $out_enc == "cp1251") }
if ($in_enc == "utf-8" && $out_enc == "cp1251") {
return strtr($string, $_utf8win1251); return strtr($string, $_utf8win1251);
}
return $string; // do not know how to convert return $string; // do not know how to convert
} }
@ -74,6 +78,7 @@ function locale_exists($locale)
function locale_pattern_check($locale) function locale_pattern_check($locale)
{ {
$locale_pattern = "/^[\w-]{2,5}$/"; $locale_pattern = "/^[\w-]{2,5}$/";
return preg_match($locale_pattern, $locale) && $locale != 'names'; return preg_match($locale_pattern, $locale) && $locale != 'names';
} }
@ -90,6 +95,7 @@ function get_available_locales()
closedir($handle); closedir($handle);
} }
sort($list); sort($list);
return $list; return $list;
} }
@ -97,56 +103,70 @@ function get_user_locale()
{ {
if (isset($_COOKIE[LOCALE_COOKIE_NAME])) { if (isset($_COOKIE[LOCALE_COOKIE_NAME])) {
$requested_lang = $_COOKIE[LOCALE_COOKIE_NAME]; $requested_lang = $_COOKIE[LOCALE_COOKIE_NAME];
if (locale_pattern_check($requested_lang) && locale_exists($requested_lang)) if (locale_pattern_check($requested_lang) && locale_exists($requested_lang)) {
return $requested_lang; return $requested_lang;
} }
}
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
$requested_langs = explode(",", $_SERVER['HTTP_ACCEPT_LANGUAGE']); $requested_langs = explode(",", $_SERVER['HTTP_ACCEPT_LANGUAGE']);
foreach ($requested_langs as $requested_lang) { foreach ($requested_langs as $requested_lang) {
if (strlen($requested_lang) > 2) if (strlen($requested_lang) > 2) {
$requested_lang = substr($requested_lang, 0, 2); $requested_lang = substr($requested_lang, 0, 2);
}
if (locale_pattern_check($requested_lang) && locale_exists($requested_lang)) if (locale_pattern_check($requested_lang) && locale_exists($requested_lang)) {
return $requested_lang; return $requested_lang;
} }
} }
}
if (locale_pattern_check(DEFAULT_LOCALE) && locale_exists(DEFAULT_LOCALE)) if (locale_pattern_check(DEFAULT_LOCALE) && locale_exists(DEFAULT_LOCALE)) {
return DEFAULT_LOCALE; return DEFAULT_LOCALE;
}
return 'en'; return 'en';
} }
function get_locale() function get_locale()
{ {
$locale = verifyparam("locale", "/./", ""); $locale = verify_param("locale", "/./", "");
if ($locale && locale_pattern_check($locale) && locale_exists($locale)) { // Check if locale code passed in as a param is valid
$locale_param_valid = $locale
&& locale_pattern_check($locale)
&& locale_exists($locale);
// Check if locale code stored in session data is valid
$session_locale_valid = isset($_SESSION['locale'])
&& locale_pattern_check($_SESSION['locale'])
&& locale_exists($_SESSION['locale']);
if ($locale_param_valid) {
$_SESSION['locale'] = $locale; $_SESSION['locale'] = $locale;
} } elseif ($session_locale_valid) {
else if (isset($_SESSION['locale']) && locale_pattern_check($_SESSION['locale']) && locale_exists($_SESSION['locale'])) {
$locale = $_SESSION['locale']; $locale = $_SESSION['locale'];
} } else {
else {
$locale = get_user_locale(); $locale = get_user_locale();
} }
setcookie(LOCALE_COOKIE_NAME, $locale, time() + 60 * 60 * 24 * 1000, MIBEW_WEB_ROOT . "/"); setcookie(LOCALE_COOKIE_NAME, $locale, time() + 60 * 60 * 24 * 1000, MIBEW_WEB_ROOT . "/");
return $locale; return $locale;
} }
function get_locale_links($href) function get_locale_links($href)
{ {
$localeLinks = array(); $locale_links = array();
$allLocales = get_available_locales(); $all_locales = get_available_locales();
if (count($allLocales) < 2) { if (count($all_locales) < 2) {
return null; return null;
} }
foreach ($allLocales as $k) { foreach ($all_locales as $k) {
$localeLinks[$k] = getlocal_($k, "names"); $locale_links[$k] = getlocal_($k, "names");
} }
return $localeLinks;
return $locale_links;
} }
/** /**
@ -157,7 +177,8 @@ function get_locale_links($href)
* *
* @param string $locale Name of a locale whose messages should be loaded. * @param string $locale Name of a locale whose messages should be loaded.
*/ */
function load_messages($locale) { function load_messages($locale)
{
global $messages, $output_encoding; global $messages, $output_encoding;
// Load core localization // Load core localization
@ -210,14 +231,15 @@ function load_messages($locale) {
* All localized strings have internal Mibew encoding(see $mibew_encoding * All localized strings have internal Mibew encoding(see $mibew_encoding
* value in libs/config.php). * value in libs/config.php).
*/ */
function read_locale_file($path) { function read_locale_file($path)
{
// Set default values // Set default values
$current_encoding = MIBEW_ENCODING; $current_encoding = MIBEW_ENCODING;
$output_encoding = null; $output_encoding = null;
$messages = array(); $messages = array();
$fp = fopen($path, "r"); $fp = fopen($path, "r");
if ($fp === FALSE) { if ($fp === false) {
die("unable to read locale file $path"); die("unable to read locale file $path");
} }
while (!feof($fp)) { while (!feof($fp)) {
@ -256,20 +278,26 @@ function read_locale_file($path) {
function getoutputenc() function getoutputenc()
{ {
global $output_encoding, $messages; global $output_encoding, $messages;
if (!isset($messages[CURRENT_LOCALE])) if (!isset($messages[CURRENT_LOCALE])) {
load_messages(CURRENT_LOCALE); load_messages(CURRENT_LOCALE);
return isset($output_encoding[CURRENT_LOCALE]) ? $output_encoding[CURRENT_LOCALE] : MIBEW_ENCODING; }
return isset($output_encoding[CURRENT_LOCALE])
? $output_encoding[CURRENT_LOCALE]
: MIBEW_ENCODING;
} }
function getstring_($text, $locale) function getstring_($text, $locale)
{ {
global $messages; global $messages;
if (!isset($messages[$locale])) if (!isset($messages[$locale])) {
load_messages($locale); load_messages($locale);
}
$localized = $messages[$locale]; $localized = $messages[$locale];
if (isset($localized[$text])) if (isset($localized[$text])) {
return $localized[$text]; return $localized[$text];
}
if ($locale != 'en') { if ($locale != 'en') {
return getstring_($text, 'en'); return getstring_($text, 'en');
} }
@ -298,6 +326,7 @@ function getstring2_($text, $params, $locale)
for ($i = 0; $i < count($params); $i++) { for ($i = 0; $i < count($params); $i++) {
$string = str_replace("{" . $i . "}", $params[$i], $string); $string = str_replace("{" . $i . "}", $params[$i], $string);
} }
return $string; return $string;
} }
@ -312,25 +341,27 @@ function getlocal2($text, $params)
for ($i = 0; $i < count($params); $i++) { for ($i = 0; $i < count($params); $i++) {
$string = str_replace("{" . $i . "}", $params[$i], $string); $string = str_replace("{" . $i . "}", $params[$i], $string);
} }
return $string; return $string;
} }
/* prepares for Javascript string */ /* prepares for Javascript string */
function getlocalforJS($text, $params) function get_local_for_js($text, $params)
{ {
$string = myiconv(MIBEW_ENCODING, getoutputenc(), getstring_($text, CURRENT_LOCALE)); $string = myiconv(MIBEW_ENCODING, getoutputenc(), getstring_($text, CURRENT_LOCALE));
$string = str_replace("\"", "\\\"", str_replace("\n", "\\n", $string)); $string = str_replace("\"", "\\\"", str_replace("\n", "\\n", $string));
for ($i = 0; $i < count($params); $i++) { for ($i = 0; $i < count($params); $i++) {
$string = str_replace("{" . $i . "}", $params[$i], $string); $string = str_replace("{" . $i . "}", $params[$i], $string);
} }
return $string; return $string;
} }
function locale_load_idlist($name) function locale_load_id_list($name)
{ {
$result = array(); $result = array();
$fp = @fopen(MIBEW_FS_ROOT . "/locales/names/$name", "r"); $fp = @fopen(MIBEW_FS_ROOT . "/locales/names/$name", "r");
if ($fp !== FALSE) { if ($fp !== false) {
while (!feof($fp)) { while (!feof($fp)) {
$line = trim(fgets($fp, 4096)); $line = trim(fgets($fp, 4096));
if ($line && preg_match("/^[\w_\.]+$/", $line)) { if ($line && preg_match("/^[\w_\.]+$/", $line)) {
@ -339,6 +370,7 @@ function locale_load_idlist($name)
} }
fclose($fp); fclose($fp);
} }
return $result; return $result;
} }
@ -348,17 +380,22 @@ function save_message($locale, $key, $value)
$added = false; $added = false;
$current_encoding = MIBEW_ENCODING; $current_encoding = MIBEW_ENCODING;
$fp = fopen(MIBEW_FS_ROOT . "/locales/$locale/properties", "r"); $fp = fopen(MIBEW_FS_ROOT . "/locales/$locale/properties", "r");
if ($fp === FALSE) { if ($fp === false) {
die("unable to open properties for locale $locale"); die("unable to open properties for locale $locale");
} }
while (!feof($fp)) { while (!feof($fp)) {
$line = fgets($fp, 4096); $line = fgets($fp, 4096);
$keyval = preg_split("/=/", $line, 2); $key_val = preg_split("/=/", $line, 2);
if (isset($keyval[1])) { if (isset($key_val[1])) {
if ($keyval[0] == 'encoding') { if ($key_val[0] == 'encoding') {
$current_encoding = trim($keyval[1]); $current_encoding = trim($key_val[1]);
} else if (!$added && $keyval[0] == $key) { } elseif (!$added && $key_val[0] == $key) {
$line = "$key=" . myiconv(MIBEW_ENCODING, $current_encoding, str_replace("\r", "", str_replace("\n", "\\n", trim($value)))) . "\n"; $line = "$key="
. myiconv(
MIBEW_ENCODING,
$current_encoding,
str_replace("\r", "", str_replace("\n", "\\n", trim($value)))
) . "\n";
$added = true; $added = true;
} }
} }
@ -366,32 +403,44 @@ function save_message($locale, $key, $value)
} }
fclose($fp); fclose($fp);
if (!$added) { if (!$added) {
$result .= "$key=" . myiconv(MIBEW_ENCODING, $current_encoding, str_replace("\r", "", str_replace("\n", "\\n", trim($value)))) . "\n"; $result .= "$key="
. myiconv(
MIBEW_ENCODING,
$current_encoding,
str_replace("\r", "", str_replace("\n", "\\n", trim($value)))
) . "\n";
} }
$fp = @fopen(MIBEW_FS_ROOT . "/locales/$locale/properties", "w"); $fp = @fopen(MIBEW_FS_ROOT . "/locales/$locale/properties", "w");
if ($fp !== FALSE) { if ($fp !== false) {
fwrite($fp, $result); fwrite($fp, $result);
fclose($fp); fclose($fp);
} else { } else {
die("cannot write /locales/$locale/properties, please check file permissions on your server"); die("cannot write /locales/$locale/properties, please check file permissions on your server");
} }
$fp = @fopen(MIBEW_FS_ROOT . "/locales/$locale/properties.log", "a"); $fp = @fopen(MIBEW_FS_ROOT . "/locales/$locale/properties.log", "a");
if ($fp !== FALSE) { if ($fp !== false) {
$extAddr = $_SERVER['REMOTE_ADDR']; $ext_addr = $_SERVER['REMOTE_ADDR'];
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) &&
$_SERVER['HTTP_X_FORWARDED_FOR'] != $_SERVER['REMOTE_ADDR']) { $_SERVER['HTTP_X_FORWARDED_FOR'] != $_SERVER['REMOTE_ADDR']) {
$extAddr = $_SERVER['REMOTE_ADDR'] . ' (' . $_SERVER['HTTP_X_FORWARDED_FOR'] . ')'; $ext_addr = $_SERVER['REMOTE_ADDR'] . ' (' . $_SERVER['HTTP_X_FORWARDED_FOR'] . ')';
} }
$userbrowser = $_SERVER['HTTP_USER_AGENT']; $user_browser = $_SERVER['HTTP_USER_AGENT'];
$remoteHost = isset($_SERVER['REMOTE_HOST']) ? $_SERVER['REMOTE_HOST'] : $extAddr; $remote_host = isset($_SERVER['REMOTE_HOST']) ? $_SERVER['REMOTE_HOST'] : $ext_addr;
fwrite($fp, "# " . date(DATE_RFC822) . " by $remoteHost using $userbrowser\n"); fwrite($fp, "# " . date(DATE_RFC822) . " by $remote_host using $user_browser\n");
fwrite($fp, "$key=" . myiconv(MIBEW_ENCODING, $current_encoding, str_replace("\r", "", str_replace("\n", "\\n", trim($value)))) . "\n"); fwrite(
$fp,
("$key="
. myiconv(
MIBEW_ENCODING,
$current_encoding,
str_replace("\r", "", str_replace("\n", "\\n", trim($value)))
)
. "\n")
);
fclose($fp); fclose($fp);
} }
} }
$messages = array(); $messages = array();
$output_encoding = array(); $output_encoding = array();
?>

View File

@ -15,8 +15,6 @@
* limitations under the License. * limitations under the License.
*/ */
require_once(MIBEW_FS_ROOT.'/libs/common/constants.php');
function debugexit_print($var) function debugexit_print($var)
{ {
echo "<html><body><pre>"; echo "<html><body><pre>";
@ -35,15 +33,16 @@ function get_gifimage_size($filename)
$height = imagesy($img); $height = imagesy($img);
$width = imagesx($img); $width = imagesx($img);
imagedestroy($img); imagedestroy($img);
return array($width, $height); return array($width, $height);
} }
} }
} }
return array(0, 0); return array(0, 0);
} }
function js_path()
function jspath()
{ {
return "js/compiled"; return "js/compiled";
} }
@ -88,7 +87,8 @@ function div($a, $b)
* @param array $arr Array to flatten * @param array $arr Array to flatten
* @return array * @return array
*/ */
function array_flatten_recursive($arr) { function array_flatten_recursive($arr)
{
$result = array(); $result = array();
foreach ($arr as $key => $value) { foreach ($arr as $key => $value) {
if (is_array($value)) { if (is_array($value)) {
@ -102,6 +102,7 @@ function array_flatten_recursive($arr) {
$result[$key] = $value; $result[$key] = $value;
} }
} }
return $result; return $result;
} }
@ -110,12 +111,11 @@ function array_flatten_recursive($arr) {
* *
* @return boolean * @return boolean
*/ */
function installation_in_progress() { function installation_in_progress()
{
if (!defined('INSTALLATION_IN_PROGRESS')) { if (!defined('INSTALLATION_IN_PROGRESS')) {
return FALSE; return false;
} }
return INSTALLATION_IN_PROGRESS; return INSTALLATION_IN_PROGRESS;
} }
?>

View File

@ -18,36 +18,35 @@
// Import namespaces and classes of the core // Import namespaces and classes of the core
use Mibew\Settings; use Mibew\Settings;
// Initialize libraries
require_once(MIBEW_FS_ROOT.'/libs/common/locale.php');
/* ajax server actions use utf-8 */ /* ajax server actions use utf-8 */
function getrawparam($name) function get_raw_param($name)
{ {
if (isset($_POST[$name])) { if (isset($_POST[$name])) {
$value = myiconv("utf-8", MIBEW_ENCODING, $_POST[$name]); $value = myiconv("utf-8", MIBEW_ENCODING, $_POST[$name]);
if (get_magic_quotes_gpc()) { if (get_magic_quotes_gpc()) {
$value = stripslashes($value); $value = stripslashes($value);
} }
return $value; return $value;
} }
die("no " . $name . " parameter"); die("no " . $name . " parameter");
} }
/* form processors use current Output encoding */ /* form processors use current Output encoding */
function getparam($name)
function get_param($name)
{ {
if (isset($_POST[$name])) { if (isset($_POST[$name])) {
$value = myiconv(getoutputenc(), MIBEW_ENCODING, $_POST[$name]); $value = myiconv(getoutputenc(), MIBEW_ENCODING, $_POST[$name]);
if (get_magic_quotes_gpc()) { if (get_magic_quotes_gpc()) {
$value = stripslashes($value); $value = stripslashes($value);
} }
return $value; return $value;
} }
die("no " . $name . " parameter"); die("no " . $name . " parameter");
} }
function getgetparam($name, $default = '') function get_get_param($name, $default = '')
{ {
if (!isset($_GET[$name]) || !$_GET[$name]) { if (!isset($_GET[$name]) || !$_GET[$name]) {
return $default; return $default;
@ -56,13 +55,14 @@ function getgetparam($name, $default = '')
if (get_magic_quotes_gpc()) { if (get_magic_quotes_gpc()) {
$value = stripslashes($value); $value = stripslashes($value);
} }
return $value; return $value;
} }
function get_app_location($showhost, $issecure) function get_app_location($show_host, $is_secure)
{ {
if ($showhost) { if ($show_host) {
return ($issecure ? "https://" : "http://") . $_SERVER['HTTP_HOST'] . MIBEW_WEB_ROOT; return ($is_secure ? "https://" : "http://") . $_SERVER['HTTP_HOST'] . MIBEW_WEB_ROOT;
} else { } else {
return MIBEW_WEB_ROOT; return MIBEW_WEB_ROOT;
} }
@ -70,10 +70,9 @@ function get_app_location($showhost, $issecure)
function is_secure_request() function is_secure_request()
{ {
return return (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443')
isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443' || (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == "on")
|| isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == "on" || (isset($_SERVER["HTTP_HTTPS"]) && $_SERVER["HTTP_HTTPS"] == "on");
|| isset($_SERVER["HTTP_HTTPS"]) && $_SERVER["HTTP_HTTPS"] == "on";
} }
/** /**
@ -81,8 +80,7 @@ function is_secure_request()
* *
* @return string * @return string
*/ */
function get_page_style() { function get_page_style()
{
return Settings::get('page_style'); return Settings::get('page_style');
} }
?>

View File

@ -15,25 +15,28 @@
* limitations under the License. * limitations under the License.
*/ */
// Import namespaces and classes of the core // Import namespaces and classes of the core
use Mibew\EventDispatcher; use Mibew\EventDispatcher;
// Initialize libraries function get_popup($href, $js_href, $message, $title, $wnd_name, $options)
require_once(MIBEW_FS_ROOT.'/libs/common/locale.php');
function get_popup($href, $jshref, $message, $title, $wndName, $options)
{ {
if (!$jshref) { if (!$js_href) {
$jshref = "'$href'"; $js_href = "'$href'";
} }
return "<a href=\"$href\" target=\"_blank\" " . ($title ? "title=\"$title\" " : "") . "onclick=\"if(navigator.userAgent.toLowerCase().indexOf('opera') != -1 &amp;&amp; window.event.preventDefault) window.event.preventDefault();this.newWindow = window.open($jshref, '$wndName', '$options');this.newWindow.focus();this.newWindow.opener=window;return false;\">$message</a>"; return "<a href=\"$href\" target=\"_blank\" "
. ($title ? "title=\"$title\" " : "")
. "onclick=\"if(navigator.userAgent.toLowerCase().indexOf('opera') != -1 "
. "&amp;&amp; window.event.preventDefault) window.event.preventDefault();"
. "this.newWindow = window.open($js_href, '$wnd_name', '$options');"
. "this.newWindow.focus();this.newWindow.opener=window;return false;\">$message</a>";
} }
function get_image($href, $width, $height) function get_image($href, $width, $height)
{ {
if ($width != 0 && $height != 0) if ($width != 0 && $height != 0) {
return "<img src=\"$href\" border=\"0\" width=\"$width\" height=\"$height\" alt=\"\"/>"; return "<img src=\"$href\" border=\"0\" width=\"$width\" height=\"$height\" alt=\"\"/>";
}
return "<img src=\"$href\" border=\"0\" alt=\"\"/>"; return "<img src=\"$href\" border=\"0\" alt=\"\"/>";
} }
@ -55,7 +58,8 @@ function start_html_output()
header("Content-type: text/html" . (isset($charset) ? "; charset=" . $charset : "")); header("Content-type: text/html" . (isset($charset) ? "; charset=" . $charset : ""));
} }
function start_js_output(){ function start_js_output()
{
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: no-store, no-cache, must-revalidate");
header("Pragma: no-cache"); header("Pragma: no-cache");
@ -63,7 +67,7 @@ function start_js_output(){
header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"'); header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');
} }
function topage($text) function to_page($text)
{ {
return myiconv(MIBEW_ENCODING, getoutputenc(), $text); return myiconv(MIBEW_ENCODING, getoutputenc(), $text);
} }
@ -81,11 +85,12 @@ function topage($text)
* @param string $page_name CSS files load to this page * @param string $page_name CSS files load to this page
* @return string HTML block of 'link' tags * @return string HTML block of 'link' tags
*/ */
function get_additional_css($page_name) { function get_additional_css($page_name)
{
// Prepare event arguments array // Prepare event arguments array
$args = array( $args = array(
'page' => $page_name, 'page' => $page_name,
'css' => array() 'css' => array(),
); );
// Trigger event // Trigger event
@ -114,7 +119,8 @@ function get_additional_css($page_name) {
* @param string $page_name JavaScript files load to this page * @param string $page_name JavaScript files load to this page
* @return string HTML block of 'script' tags * @return string HTML block of 'script' tags
*/ */
function get_additional_js($page_name) { function get_additional_js($page_name)
{
// Prepare event arguments array // Prepare event arguments array
$args = array( $args = array(
'page' => $page_name, 'page' => $page_name,
@ -145,11 +151,12 @@ function get_additional_js($page_name) {
* @param string $page_name Localized strings add to this page * @param string $page_name Localized strings add to this page
* @return string JSON encoded localized strings * @return string JSON encoded localized strings
*/ */
function get_additional_localized_strings($page_name) { function get_additional_localized_strings($page_name)
{
// Prepare event arguments array // Prepare event arguments array
$args = array( $args = array(
'page' => $page_name, 'page' => $page_name,
'localized_strings' => array() 'localized_strings' => array(),
); );
// Trigger event // Trigger event
@ -158,8 +165,7 @@ function get_additional_localized_strings($page_name) {
// Build result // Build result
$result = array(); $result = array();
if (! empty($args['localized_strings']) if (!empty($args['localized_strings']) && is_array($args['localized_strings'])) {
&& is_array($args['localized_strings'])) {
$result = $args['localized_strings']; $result = $args['localized_strings'];
} }
@ -179,7 +185,8 @@ function get_additional_localized_strings($page_name) {
* @param string $page_name Plugins initialize at this page * @param string $page_name Plugins initialize at this page
* @return string JavaScript options block * @return string JavaScript options block
*/ */
function get_js_plugin_options($page_name) { function get_js_plugin_options($page_name)
{
// Prepare event arguments array // Prepare event arguments array
$args = array( $args = array(
'page' => $page_name, 'page' => $page_name,
@ -206,7 +213,8 @@ function get_js_plugin_options($page_name) {
* - 'js_plugin_options': contains results of the 'get_js_plugin_options' * - 'js_plugin_options': contains results of the 'get_js_plugin_options'
* function * function
*/ */
function get_plugins_data($page_name) { function get_plugins_data($page_name)
{
return array( return array(
'additional_css' => get_additional_css($page_name), 'additional_css' => get_additional_css($page_name),
'additional_js' => get_additional_js($page_name), 'additional_js' => get_additional_js($page_name),
@ -222,8 +230,7 @@ function no_field($key)
function failed_uploading_file($filename, $key) function failed_uploading_file($filename, $key)
{ {
return getlocal2("errors.failed.uploading.file", return getlocal2("errors.failed.uploading.file", array($filename, getlocal($key)));
array($filename, getlocal($key)));
} }
function wrong_field($key) function wrong_field($key)
@ -234,12 +241,14 @@ function wrong_field($key)
function add_params($servlet, $params) function add_params($servlet, $params)
{ {
$infix = '?'; $infix = '?';
if (strstr($servlet, $infix) !== FALSE) if (strstr($servlet, $infix) !== false) {
$infix = '&amp;'; $infix = '&amp;';
}
foreach ($params as $k => $v) { foreach ($params as $k => $v) {
$servlet .= $infix . $k . "=" . $v; $servlet .= $infix . $k . "=" . $v;
$infix = '&amp;'; $infix = '&amp;';
} }
return $servlet; return $servlet;
} }
@ -259,14 +268,14 @@ function add_params($servlet, $params)
* functions, specified in 'handlers' item. * functions, specified in 'handlers' item.
* @return string JSONP response that ready to send to the widget * @return string JSONP response that ready to send to the widget
*/ */
function build_widget_response($response) { function build_widget_response($response)
{
$result = $response + array( $result = $response + array(
'load' => array(), 'load' => array(),
'handlers' => array(), 'handlers' => array(),
'dependences' => array(), 'dependences' => array(),
'data' => array() 'data' => array(),
); );
return "Mibew.Objects.widget.onResponse(" . json_encode($result) . ");"; return "Mibew.Objects.widget.onResponse(" . json_encode($result) . ");";
} }
?>

View File

@ -38,7 +38,7 @@ function unicode_urldecode($url)
return urldecode($url); return urldecode($url);
} }
function cutstring($string, $length = 75, $ellipsis = '') function cut_string($string, $length = 75, $ellipsis = '')
{ {
$result = ''; $result = '';
if (strlen($string) > $length) { if (strlen($string) > $length) {
@ -54,5 +54,3 @@ function escape_with_cdata($text)
{ {
return "<![CDATA[" . str_replace("]]>", "]]>]]&gt;<![CDATA[", $text) . "]]>"; return "<![CDATA[" . str_replace("]]>", "]]>]]&gt;<![CDATA[", $text) . "]]>";
} }
?>

View File

@ -15,22 +15,23 @@
* limitations under the License. * limitations under the License.
*/ */
function verifyparam($name, $regexp, $default = null) function verify_param($name, $reg_exp, $default = null)
{ {
if (isset($_GET[$name]) && is_scalar($_GET[$name])) { if (isset($_GET[$name]) && is_scalar($_GET[$name])) {
$val = $_GET[$name]; $val = $_GET[$name];
if (preg_match($regexp, $val)) if (preg_match($reg_exp, $val)) {
return $val; return $val;
}
} elseif (isset($_POST[$name]) && is_scalar($_POST[$name])) { } elseif (isset($_POST[$name]) && is_scalar($_POST[$name])) {
$val = $_POST[$name]; $val = $_POST[$name];
if (preg_match($regexp, $val)) if (preg_match($reg_exp, $val)) {
return $val; return $val;
}
} else { } else {
if (isset($default)) if (isset($default)) {
return $default; return $default;
} }
}
echo "<html><head></head><body>Wrong parameter used or absent: " . $name . "</body></html>"; echo "<html><head></head><body>Wrong parameter used or absent: " . $name . "</body></html>";
exit; exit;
} }
@ -39,5 +40,3 @@ function is_valid_email($email)
{ {
return preg_match("/^[^@]+@[^\.]+(\.[^\.]+)*$/", $email); return preg_match("/^[^@]+@[^\.]+(\.[^\.]+)*$/", $email);
} }
?>

View File

@ -21,12 +21,10 @@
* @param string $cron_key Cron security key * @param string $cron_key Cron security key
* @return string Cron URI * @return string Cron URI
*/ */
function cron_get_uri($cron_key) { function cron_get_uri($cron_key)
{
$path = get_app_location(true, is_secure_request()) . '/cron.php'; $path = get_app_location(true, is_secure_request()) . '/cron.php';
$path .= empty($cron_key) $path .= empty($cron_key) ? '' : '?cron_key=' . $cron_key;
? ''
: '?cron_key='.$cron_key;
return $path; return $path;
} }
?>

View File

@ -62,6 +62,7 @@ $default_locale = "en"; /* if user does not provide known lang */
* Plugins * Plugins
*/ */
$plugins_list = array(); $plugins_list = array();
/* Exapmle of plugins configuration /* Exapmle of plugins configuration
$plugins_list[] = array( $plugins_list[] = array(
'name' => 'plugin_name', 'name' => 'plugin_name',
@ -71,5 +72,3 @@ $plugins_list[] = array(
) )
) )
*/ */
?>

View File

@ -19,36 +19,52 @@
use Mibew\Settings; use Mibew\Settings;
use Mibew\Style\InvitationStyle; use Mibew\Style\InvitationStyle;
function generate_button($title, $locale, $style, $invitation_style_name, $group, $inner, $showhost, $forcesecure, $modsecurity, $operator_code) function generate_button(
{ $title,
$app_location = get_app_location($showhost, $forcesecure); $locale,
$style,
$invitation_style_name,
$group,
$inner,
$show_host,
$force_secure,
$mod_security,
$operator_code
) {
$app_location = get_app_location($show_host, $force_secure);
$link = $app_location . "/client.php"; $link = $app_location . "/client.php";
if ($locale) if ($locale) {
$link = append_query($link, "locale=$locale"); $link = append_query($link, "locale=$locale");
if ($style) }
if ($style) {
$link = append_query($link, "style=$style"); $link = append_query($link, "style=$style");
if ($group) }
if ($group) {
$link = append_query($link, "group=$group"); $link = append_query($link, "group=$group");
}
$modsecfix = $modsecurity ? ".replace('http://','').replace('https://','')" : ""; $modsecfix = $mod_security ? ".replace('http://','').replace('https://','')" : "";
$jslink = append_query("'" . $link, "url='+escape(document.location.href$modsecfix)+'&amp;referrer='+escape(document.referrer$modsecfix)"); $js_link = append_query(
"'" . $link,
"url='+escape(document.location.href$modsecfix)+'&amp;referrer='+escape(document.referrer$modsecfix)"
);
$popup_options = "toolbar=0,scrollbars=0,location=0,status=1,menubar=0,width=640,height=480,resizable=1"; $popup_options = "toolbar=0,scrollbars=0,location=0,status=1,menubar=0,width=640,height=480,resizable=1";
// Generate operator code field // Generate operator code field
if ($operator_code) { if ($operator_code) {
$form_on_submit = "if(navigator.userAgent.toLowerCase().indexOf('opera') != -1 " . $form_on_submit = "if(navigator.userAgent.toLowerCase().indexOf('opera') != -1 "
"&amp;&amp; window.event.preventDefault) window.event.preventDefault();" . . "&amp;&amp; window.event.preventDefault) window.event.preventDefault();"
"this.newWindow = window.open({$jslink} + '&amp;operator_code=' + document.getElementById('mibewOperatorCodeField').value, 'mibew', '{$popup_options}');" . . "this.newWindow = window.open({$js_link} + '&amp;operator_code=' "
"this.newWindow.focus();this.newWindow.opener=window;return false;"; . "+ document.getElementById('mibewOperatorCodeField').value, 'mibew', '{$popup_options}');"
$temp = '<form action="" onsubmit="' . $form_on_submit . '" id="mibewOperatorCodeForm">' . . "this.newWindow.focus();this.newWindow.opener=window;return false;";
'<input type="text" id="mibewOperatorCodeField" />' . $temp = '<form action="" onsubmit="' . $form_on_submit . '" id="mibewOperatorCodeForm">'
'</form>'; . '<input type="text" id="mibewOperatorCodeField" />'
. '</form>';
return "<!-- mibew operator code field -->" . $temp . "<!-- / mibew operator code field -->"; return "<!-- mibew operator code field -->" . $temp . "<!-- / mibew operator code field -->";
} }
// Generate button // Generate button
$temp = get_popup($link, "$jslink", $temp = get_popup($link, "$js_link", $inner, $title, "mibew", $popup_options);
$inner, $title, "mibew", $popup_options);
if (Settings::get('enabletracking')) { if (Settings::get('enabletracking')) {
$widget_data = array(); $widget_data = array();
@ -64,8 +80,7 @@ function generate_button($title, $locale, $style, $invitation_style_name, $group
'/invite.css'; '/invite.css';
// Time between requests to the server in milliseconds // Time between requests to the server in milliseconds
$widget_data['requestTimeout'] = Settings::get('updatefrequency_tracking') $widget_data['requestTimeout'] = Settings::get('updatefrequency_tracking') * 1000;
* 1000;
// URL for requests // URL for requests
$widget_data['requestURL'] = $app_location . '/widget.php'; $widget_data['requestURL'] = $app_location . '/widget.php';
@ -77,63 +92,70 @@ function generate_button($title, $locale, $style, $invitation_style_name, $group
$widget_data['visitorCookieName'] = VISITOR_COOKIE_NAME; $widget_data['visitorCookieName'] = VISITOR_COOKIE_NAME;
// Build additional button code // Build additional button code
$temp = preg_replace('/^(<a )/', '\1id="mibewAgentButton" ', $temp) . $temp = preg_replace('/^(<a )/', '\1id="mibewAgentButton" ', $temp)
'<div id="mibewinvitation"></div>' . . '<div id="mibewinvitation"></div>'
'<script type="text/javascript" src="' . . '<script type="text/javascript" src="'
$app_location . '/js/compiled/widget.js' . . $app_location . '/js/compiled/widget.js'
'"></script>' . . '"></script>'
'<script type="text/javascript">' . . '<script type="text/javascript">'
'Mibew.Widget.init('.json_encode($widget_data).')' . . 'Mibew.Widget.init(' . json_encode($widget_data) . ')'
'</script>'; . '</script>';
} }
return "<!-- mibew button -->" . $temp . "<!-- / mibew button -->"; return "<!-- mibew button -->" . $temp . "<!-- / mibew button -->";
} }
function verifyparam_groupid($paramid, &$errors) { function verifyparam_groupid($param_id, &$errors)
$groupid = ""; {
$groupid = verifyparam($paramid, "/^\d{0,8}$/", ""); $group_id = verify_param($param_id, "/^\d{0,8}$/", "");
if ($groupid) { if ($group_id) {
$group = group_by_id($groupid); $group = group_by_id($group_id);
if (!$group) { if (!$group) {
$errors[] = getlocal("page.group.no_such"); $errors[] = getlocal("page.group.no_such");
$groupid = ""; $group_id = "";
} }
} }
return $groupid;
return $group_id;
} }
function get_groups_list() function get_groups_list()
{ {
$result = array(); $result = array();
$allgroups = get_all_groups(); $all_groups = get_all_groups();
$result[] = array('groupid' => '', 'vclocalname' => getlocal("page.gen_button.default_group"), 'level' => 0); $result[] = array(
foreach ($allgroups as $g) { 'groupid' => '',
'vclocalname' => getlocal("page.gen_button.default_group"),
'level' => 0,
);
foreach ($all_groups as $g) {
$result[] = $g; $result[] = $g;
} }
return $result; return $result;
} }
function get_image_locales_map($localesdir) function get_image_locales_map($locales_dir)
{ {
$imageLocales = array(); $image_locales = array();
$allLocales = get_available_locales(); $all_locales = get_available_locales();
foreach ($allLocales as $curr) { foreach ($all_locales as $curr) {
$imagesDir = "$localesdir/$curr/button"; $images_dir = "$locales_dir/$curr/button";
if ($handle = @opendir($imagesDir)) { if ($handle = @opendir($images_dir)) {
while (false !== ($file = readdir($handle))) { while (false !== ($file = readdir($handle))) {
if (preg_match("/^(\w+)_on.gif$/", $file, $matches) $both_files_exist = preg_match("/^(\w+)_on.gif$/", $file, $matches)
&& is_file("$imagesDir/" . $matches[1] . "_off.gif")) { && is_file("$images_dir/" . $matches[1] . "_off.gif");
if ($both_files_exist) {
$image = $matches[1]; $image = $matches[1];
if (!isset($imageLocales[$image])) { if (!isset($image_locales[$image])) {
$imageLocales[$image] = array(); $image_locales[$image] = array();
} }
$imageLocales[$image][] = $curr; $image_locales[$image][] = $curr;
} }
} }
closedir($handle); closedir($handle);
} }
} }
return $imageLocales;
}
?> return $image_locales;
}

View File

@ -23,10 +23,11 @@ function group_by_id($id)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
$group = $db->query( $group = $db->query(
"select * from {chatgroup} where groupid = ?", "SELECT * FROM {chatgroup} WHERE groupid = ?",
array($id), array($id),
array('return_rows' => Database::RETURN_ONE_ROW) array('return_rows' => Database::RETURN_ONE_ROW)
); );
return $group; return $group;
} }
@ -34,20 +35,22 @@ function group_by_name($name)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
$group = $db->query( $group = $db->query(
"select * from {chatgroup} where vclocalname = ?", "SELECT * FROM {chatgroup} WHERE vclocalname = ?",
array($name), array($name),
array('return_rows' => Database::RETURN_ONE_ROW) array('return_rows' => Database::RETURN_ONE_ROW)
); );
return $group; return $group;
} }
function get_group_name($group) function get_group_name($group)
{ {
if (HOME_LOCALE == CURRENT_LOCALE || !isset($group['vccommonname']) || !$group['vccommonname']) if (HOME_LOCALE == CURRENT_LOCALE || !isset($group['vccommonname']) || !$group['vccommonname']) {
return $group['vclocalname']; return $group['vclocalname'];
else } else {
return $group['vccommonname']; return $group['vccommonname'];
} }
}
/** /**
* Builds list of group settings tabs. The keys are tabs titles and the values * Builds list of group settings tabs. The keys are tabs titles and the values
@ -57,67 +60,82 @@ function get_group_name($group)
* @param int $active Number of the active tab. The count starts from 0. * @param int $active Number of the active tab. The count starts from 0.
* @return array Tabs list * @return array Tabs list
*/ */
function setup_group_settings_tabs($gid, $active) { function setup_group_settings_tabs($gid, $active)
{
$tabs = array(); $tabs = array();
if ($gid) { if ($gid) {
$tabs = array( $tabs = array(
getlocal("page_group.tab.main") => $active != 0 ? (MIBEW_WEB_ROOT . "/operator/group.php?gid=$gid") : "", getlocal("page_group.tab.main") => ($active != 0
getlocal("page_group.tab.members") => $active != 1 ? (MIBEW_WEB_ROOT . "/operator/groupmembers.php?gid=$gid") : "", ? (MIBEW_WEB_ROOT . "/operator/group.php?gid=$gid")
: ""),
getlocal("page_group.tab.members") => ($active != 1
? (MIBEW_WEB_ROOT . "/operator/groupmembers.php?gid=$gid")
: ""),
); );
} }
return $tabs; return $tabs;
} }
function get_operator_groupslist($operatorid) function get_operator_groups_list($operator_id)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
if (Settings::get('enablegroups') == '1') { if (Settings::get('enablegroups') == '1') {
$groupids = array(0); $group_ids = array(0);
$allgroups = $db->query( $all_groups = $db->query(
"select groupid from {chatgroupoperator} where operatorid = ? order by groupid", "SELECT groupid FROM {chatgroupoperator} WHERE operatorid = ? ORDER BY groupid",
array($operatorid), array($operator_id),
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
foreach ($allgroups as $g) { foreach ($all_groups as $g) {
$groupids[] = $g['groupid']; $group_ids[] = $g['groupid'];
} }
return implode(",", $groupids);
return implode(",", $group_ids);
} else { } else {
return ""; return "";
} }
} }
function get_available_parent_groups($skipgroup) function get_available_parent_groups($skip_group)
{ {
$result = array();
$result[] = array(
'groupid' => '',
'level' => '',
'vclocalname' => getlocal("form.field.groupparent.root"),
);
$db = Database::getInstance(); $db = Database::getInstance();
$groupslist = $db->query( $groups_list = $db->query(
"select {chatgroup}.groupid as groupid, parent, vclocalname " . ("SELECT {chatgroup}.groupid AS groupid, parent, vclocalname "
"from {chatgroup} order by vclocalname", . "FROM {chatgroup} ORDER BY vclocalname"),
NULL, null,
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
$result = array(array('groupid' => '', 'level' => '', 'vclocalname' => getlocal("form.field.groupparent.root")));
if ($skipgroup) { if ($skip_group) {
$skipgroup = (array)$skipgroup; $skip_group = (array) $skip_group;
} else { } else {
$skipgroup = array(); $skip_group = array();
} }
$result = array_merge($result, get_sorted_child_groups_($groupslist, $skipgroup, 0) ); $result = array_merge($result, get_sorted_child_groups_($groups_list, $skip_group, 0));
return $result; return $result;
} }
function group_has_children($groupid) function group_has_children($group_id)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
$children = $db->query( $children = $db->query(
"select COUNT(*) as count from {chatgroup} where parent = ?", "SELECT COUNT(*) AS count FROM {chatgroup} WHERE parent = ?",
array($groupid), array($group_id),
array('return_rows' => Database::RETURN_ONE_ROW) array('return_rows' => Database::RETURN_ONE_ROW)
); );
return ($children['count'] > 0); return ($children['count'] > 0);
} }
@ -128,10 +146,12 @@ function get_top_level_group($group)
/** /**
* Try to load email for specified group or for its parent. * Try to load email for specified group or for its parent.
*
* @param int $group_id Group id * @param int $group_id Group id
* @return string|boolean Email address or false if there is no email * @return string|boolean Email address or false if there is no email
*/ */
function get_group_email($group_id) { function get_group_email($group_id)
{
// Try to get group email // Try to get group email
$group = group_by_id($group_id); $group = group_by_id($group_id);
if ($group && !empty($group['vcemail'])) { if ($group && !empty($group['vcemail'])) {
@ -156,9 +176,10 @@ function get_group_email($group_id) {
* @param array $group Associative group array. Should contain 'ilastseen' key. * @param array $group Associative group array. Should contain 'ilastseen' key.
* @return bool * @return bool
*/ */
function group_is_online($group) { function group_is_online($group)
return ($group['ilastseen'] !== NULL {
&& $group['ilastseen'] < Settings::get('online_timeout')); return $group['ilastseen'] !== null
&& $group['ilastseen'] < Settings::get('online_timeout');
} }
/** /**
@ -168,8 +189,9 @@ function group_is_online($group) {
* key. * key.
* @return bool * @return bool
*/ */
function group_is_away($group) { function group_is_away($group)
return $group['ilastseenaway'] !== NULL {
return $group['ilastseenaway'] !== null
&& $group['ilastseenaway'] < Settings::get('online_timeout'); && $group['ilastseenaway'] < Settings::get('online_timeout');
} }
@ -181,17 +203,20 @@ function group_is_away($group) {
* - 'vclocaldescription': string, contain local description of the group. * - 'vclocaldescription': string, contain local description of the group.
* @return string Group description * @return string Group description
*/ */
function get_group_description($group) { function get_group_description($group)
if (HOME_LOCALE == CURRENT_LOCALE {
$use_local_description = HOME_LOCALE == CURRENT_LOCALE
|| !isset($group['vccommondescription']) || !isset($group['vccommondescription'])
|| !$group['vccommondescription']) { || !$group['vccommondescription'];
if ($use_local_description) {
return $group['vclocaldescription']; return $group['vclocaldescription'];
} else { } else {
return $group['vccommondescription']; return $group['vccommondescription'];
} }
} }
function check_group_params($group, $extra_params = NULL) function check_group_params($group, $extra_params = null)
{ {
$obligatory_params = array( $obligatory_params = array(
'name', 'name',
@ -203,8 +228,13 @@ function check_group_params($group, $extra_params = NULL)
'parent', 'parent',
'chattitle', 'chattitle',
'hosturl', 'hosturl',
'logo'); 'logo',
$params = is_null($extra_params)?$obligatory_params:array_merge($obligatory_params,$extra_params); );
$params = is_null($extra_params)
? $obligatory_params
: array_merge($obligatory_params, $extra_params);
if (count(array_diff($params, array_keys($group))) != 0) { if (count(array_diff($params, array_keys($group))) != 0) {
die('Wrong parameters set!'); die('Wrong parameters set!');
} }
@ -213,22 +243,34 @@ function check_group_params($group, $extra_params = NULL)
/** /**
* Creates group * Creates group
* *
* @param array $group Operators' group. * @param array $group Operators' group. The $group array must contains the
* The $group array must contains following keys: * following keys:
* name, description, commonname, commondescription, * - name,
* email, weight, parent, title, chattitle, hosturl, logo * - description,
* - commonname,
* - commondescription,
* - email,
* - weight,
* - parent,
* - title,
* - chattitle,
* - hosturl,
* - logo
* @return array Created group * @return array Created group
*/ */
function create_group($group) function create_group($group)
{ {
$db = Database::getInstance();
check_group_params($group); check_group_params($group);
$db = Database::getInstance();
$db->query( $db->query(
"insert into {chatgroup} (parent, vclocalname,vclocaldescription,vccommonname, " . ("INSERT INTO {chatgroup} ("
"vccommondescription,vcemail,vctitle,vcchattitle,vchosturl,vclogo,iweight) " . . "parent, vclocalname, vclocaldescription, vccommonname, "
"values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", . "vccommondescription, vcemail, vctitle, vcchattitle, vchosturl, "
. "vclogo, iweight"
. ") values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"),
array( array(
($group['parent'] ? (int)$group['parent'] : NULL), ($group['parent'] ? (int) $group['parent'] : null),
$group['name'], $group['name'],
$group['description'], $group['description'],
$group['commonname'], $group['commonname'],
@ -238,37 +280,52 @@ function create_group($group)
$group['chattitle'], $group['chattitle'],
$group['hosturl'], $group['hosturl'],
$group['logo'], $group['logo'],
$group['weight'] $group['weight'],
) )
); );
$id = $db->insertedId(); $id = $db->insertedId();
$newdep = $db->query( $new_group = $db->query(
"select * from {chatgroup} where groupid = ?", "SELECT * FROM {chatgroup} WHERE groupid = ?",
array($id), array($id),
array('return_rows' => Database::RETURN_ONE_ROW) array('return_rows' => Database::RETURN_ONE_ROW)
); );
return $newdep;
return $new_group;
} }
/** /**
* Updates group info * Updates group info
* *
* @param array $group Operators' group. * @param array $group Operators' group. The $group array must contains the
* The $group array must contains following keys: * following keys:
* id, name, description, commonname, commondescription, * - id,
* email, weight, parent, title, chattitle, hosturl, logo * - name,
* - description,
* - commonname,
* - commondescription,
* - email,
* - weight,
* - parent,
* - title,
* - chattitle,
* - hosturl,
* - logo
*/ */
function update_group($group) function update_group($group)
{ {
$db = Database::getInstance();
check_group_params($group, array('id')); check_group_params($group, array('id'));
$db = Database::getInstance();
$db->query( $db->query(
"update {chatgroup} set parent = ?, vclocalname = ?, vclocaldescription = ?, " . ("UPDATE {chatgroup} SET "
"vccommonname = ?, vccommondescription = ?, vcemail = ?, vctitle = ?, " . . "parent = ?, vclocalname = ?, vclocaldescription = ?, "
"vcchattitle = ?, vchosturl = ?, vclogo = ?, iweight = ? where groupid = ?", . "vccommonname = ?, vccommondescription = ?, "
. "vcemail = ?, vctitle = ?, vcchattitle = ?, "
. "vchosturl = ?, vclogo = ?, iweight = ? "
. "where groupid = ?"),
array( array(
($group['parent'] ? (int)$group['parent'] : NULL), ($group['parent'] ? (int) $group['parent'] : null),
$group['name'], $group['name'],
$group['description'], $group['description'],
$group['commonname'], $group['commonname'],
@ -285,33 +342,34 @@ function update_group($group)
if ($group['parent']) { if ($group['parent']) {
$db->query( $db->query(
"update {chatgroup} set parent = NULL where parent = ?", "UPDATE {chatgroup} SET parent = NULL WHERE parent = ?",
array($group['id']) array($group['id'])
); );
} }
} }
function get_group_members($groupid) function get_group_members($group_id)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
return $db->query( return $db->query(
"select operatorid from {chatgroupoperator} where groupid = ?", "SELECT operatorid FROM {chatgroupoperator} WHERE groupid = ?",
array($groupid), array($group_id),
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
} }
function update_group_members($groupid, $newvalue) function update_group_members($group_id, $new_value)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
$db->query("delete from {chatgroupoperator} where groupid = ?", array($groupid));
foreach ($newvalue as $opid) {
$db->query( $db->query(
"insert into {chatgroupoperator} (groupid, operatorid) values (?, ?)", "DELETE FROM {chatgroupoperator} WHERE groupid = ?",
array($groupid,$opid) array($group_id)
);
foreach ($new_value as $operator_id) {
$db->query(
"INSERT INTO {chatgroupoperator} (groupid, operatorid) VALUES (?, ?)",
array($group_id, $operator_id)
); );
} }
} }
?>

View File

@ -27,7 +27,13 @@ define('MIBEW_FS_ROOT', dirname(dirname(__FILE__)));
require_once(MIBEW_FS_ROOT . '/libs/config.php'); require_once(MIBEW_FS_ROOT . '/libs/config.php');
// Sanitize path to application and remove extra slashes // Sanitize path to application and remove extra slashes
$mibewroot = join("/", array_map("urlencode", preg_split('/\//', preg_replace('/\/+$/', '', preg_replace('/\/{2,}/', '/', '/' . $mibewroot))))); $mibewroot = join(
"/",
array_map(
"urlencode",
preg_split('/\//', preg_replace('/\/+$/', '', preg_replace('/\/{2,}/', '/', '/' . $mibewroot)))
)
);
/** /**
* Base URL of the Mibew installation * Base URL of the Mibew installation
@ -43,20 +49,21 @@ spl_autoload_register('class_autoload');
// Include common libs // Include common libs
require_once(MIBEW_FS_ROOT . '/libs/common/configurations.php'); require_once(MIBEW_FS_ROOT . '/libs/common/configurations.php');
require_once(MIBEW_FS_ROOT . '/libs/common/verification.php');
require_once(MIBEW_FS_ROOT . '/libs/common/converter.php');
require_once(MIBEW_FS_ROOT . '/libs/common/locale.php');
require_once(MIBEW_FS_ROOT . '/libs/common/csrf.php'); require_once(MIBEW_FS_ROOT . '/libs/common/csrf.php');
require_once(MIBEW_FS_ROOT . '/libs/common/datetime.php'); require_once(MIBEW_FS_ROOT . '/libs/common/datetime.php');
require_once(MIBEW_FS_ROOT . '/libs/common/forms.php'); require_once(MIBEW_FS_ROOT . '/libs/common/forms.php');
require_once(MIBEW_FS_ROOT.'/libs/common/verification.php');
require_once(MIBEW_FS_ROOT.'/libs/common/locale.php');
require_once(MIBEW_FS_ROOT . '/libs/common/misc.php'); require_once(MIBEW_FS_ROOT . '/libs/common/misc.php');
require_once(MIBEW_FS_ROOT . '/libs/common/request.php'); require_once(MIBEW_FS_ROOT . '/libs/common/request.php');
require_once(MIBEW_FS_ROOT . '/libs/common/response.php'); require_once(MIBEW_FS_ROOT . '/libs/common/response.php');
require_once(MIBEW_FS_ROOT . '/libs/common/string.php'); require_once(MIBEW_FS_ROOT . '/libs/common/string.php');
// Make session cookie more secure // Make session cookie more secure
@ini_set('session.cookie_httponly', TRUE); @ini_set('session.cookie_httponly', true);
if (is_secure_request()) { if (is_secure_request()) {
@ini_set('session.cookie_secure', TRUE); @ini_set('session.cookie_secure', true);
} }
@ini_set('session.cookie_path', MIBEW_WEB_ROOT . "/"); @ini_set('session.cookie_path', MIBEW_WEB_ROOT . "/");
@ini_set('session.name', 'MibewSessionID'); @ini_set('session.name', 'MibewSessionID');
@ -86,5 +93,3 @@ if (! empty($plugins_list)) {
// Variable $plugins_config defined in libs/config.php // Variable $plugins_config defined in libs/config.php
\Mibew\PluginManager::loadPlugins($plugins_list); \Mibew\PluginManager::loadPlugins($plugins_list);
} }
?>

View File

@ -29,13 +29,14 @@ use Mibew\Thread;
* - 'threadid': int, ID of the thread, related with visitor or boolean false * - 'threadid': int, ID of the thread, related with visitor or boolean false
* if visitor with specfied ID does not exist. * if visitor with specfied ID does not exist.
*/ */
function invitation_state($visitor_id) { function invitation_state($visitor_id)
{
$db = Database::getInstance(); $db = Database::getInstance();
$db_result = $db->query( $db_result = $db->query(
"SELECT t.threadid, t.invitationstate, t.istate " . ("SELECT t.threadid, t.invitationstate, t.istate "
"FROM {chatsitevisitor} v, {chatthread} t " . . "FROM {chatsitevisitor} v, {chatthread} t "
"WHERE visitorid = ? " . . "WHERE visitorid = ? "
"AND t.threadid = v.threadid", . "AND t.threadid = v.threadid"),
array($visitor_id), array($visitor_id),
array('return_rows' => Database::RETURN_ONE_ROW) array('return_rows' => Database::RETURN_ONE_ROW)
); );
@ -49,6 +50,7 @@ function invitation_state($visitor_id) {
&& ($db_result['invitationstate'] == Thread::INVITATION_WAIT); && ($db_result['invitationstate'] == Thread::INVITATION_WAIT);
$ret['threadid'] = $db_result['threadid']; $ret['threadid'] = $db_result['threadid'];
} }
return $ret; return $ret;
} }
@ -60,7 +62,8 @@ function invitation_state($visitor_id) {
* @return Thread|boolean Thread object related with invitation or boolean * @return Thread|boolean Thread object related with invitation or boolean
* false on failure * false on failure
*/ */
function invitation_invite($visitor_id, $operator) { function invitation_invite($visitor_id, $operator)
{
// Check if visitor already invited // Check if visitor already invited
$invitation_state = invitation_state($visitor_id); $invitation_state = invitation_state($visitor_id);
if ($invitation_state['invited']) { if ($invitation_state['invited']) {
@ -103,13 +106,13 @@ function invitation_invite($visitor_id, $operator) {
$db = Database::getInstance(); $db = Database::getInstance();
$db->query( $db->query(
"UPDATE {chatsitevisitor} set " . ("UPDATE {chatsitevisitor} set "
"invitations = invitations + 1, " . . "invitations = invitations + 1, "
"threadid = :thread_id " . . "threadid = :thread_id "
"WHERE visitorid = :visitor_id", . "WHERE visitorid = :visitor_id"),
array( array(
':thread_id' => $thread->id, ':thread_id' => $thread->id,
':visitor_id' => $visitor_id ':visitor_id' => $visitor_id,
) )
); );
@ -126,7 +129,7 @@ function invitation_invite($visitor_id, $operator) {
getlocal("invitation.message"), getlocal("invitation.message"),
array( array(
'name' => $operator_name, 'name' => $operator_name,
'operator_id' => $operator['operatorid'] 'operator_id' => $operator['operatorid'],
) )
); );
@ -139,7 +142,8 @@ function invitation_invite($visitor_id, $operator) {
* @param int $visitor_id ID of the visitor who accept invitation * @param int $visitor_id ID of the visitor who accept invitation
* @return Thread|boolean Thread object or boolean false on failure * @return Thread|boolean Thread object or boolean false on failure
*/ */
function invitation_accept($visitor_id) { function invitation_accept($visitor_id)
{
// Check if visitor was invited // Check if visitor was invited
$invitation_state = invitation_state($visitor_id); $invitation_state = invitation_state($visitor_id);
if (!$invitation_state['invited']) { if (!$invitation_state['invited']) {
@ -174,8 +178,8 @@ function invitation_accept($visitor_id) {
// Update visitor info // Update visitor info
$db->query( $db->query(
"UPDATE {chatsitevisitor} SET chats = chats + 1 " . ("UPDATE {chatsitevisitor} SET chats = chats + 1 "
"WHERE visitorid = :visitor_id", . "WHERE visitorid = :visitor_id"),
array(':visitor_id' => $visitor_id) array(':visitor_id' => $visitor_id)
); );
@ -187,7 +191,8 @@ function invitation_accept($visitor_id) {
* *
* @param int $visitor_id ID of the visitor * @param int $visitor_id ID of the visitor
*/ */
function invitation_reject($visitor_id) { function invitation_reject($visitor_id)
{
$visitor = track_get_visitor_by_id($visitor_id); $visitor = track_get_visitor_by_id($visitor_id);
// Send message to operator // Send message to operator
@ -201,18 +206,18 @@ function invitation_reject($visitor_id) {
$db = Database::getInstance(); $db = Database::getInstance();
$db->query( $db->query(
"UPDATE {chatsitevisitor} v, {chatthread} t SET " . ("UPDATE {chatsitevisitor} v, {chatthread} t SET "
"v.threadid = NULL, " . . "v.threadid = NULL, "
"t.invitationstate = :invitation_rejected, " . . "t.invitationstate = :invitation_rejected, "
"t.istate = :state_closed, " . . "t.istate = :state_closed, "
"t.dtmclosed = :now " . . "t.dtmclosed = :now "
"WHERE t.threadid = v.threadid " . . "WHERE t.threadid = v.threadid "
"AND visitorid = :visitor_id", . "AND visitorid = :visitor_id"),
array( array(
':invitation_rejected' => Thread::INVITATION_REJECTED, ':invitation_rejected' => Thread::INVITATION_REJECTED,
':state_closed' => Thread::STATE_CLOSED, ':state_closed' => Thread::STATE_CLOSED,
':visitor_id' => $visitor_id, ':visitor_id' => $visitor_id,
':now' => time() ':now' => time(),
) )
); );
} }
@ -220,41 +225,42 @@ function invitation_reject($visitor_id) {
/** /**
* Close old invitations * Close old invitations
*/ */
function invitation_close_old() { function invitation_close_old()
{
$db = Database::getInstance(); $db = Database::getInstance();
// Get all threads to close // Get all threads to close
$threads = $db->query( $threads = $db->query(
"SELECT * FROM {chatthread} " . ("SELECT * FROM {chatthread} "
"WHERE istate = :state_invited " . . "WHERE istate = :state_invited "
"AND invitationstate = :invitation_wait " . . "AND invitationstate = :invitation_wait "
"AND (:now - dtmcreated) > :lifetime", . "AND (:now - dtmcreated) > :lifetime"),
array( array(
':invitation_wait' => Thread::INVITATION_WAIT, ':invitation_wait' => Thread::INVITATION_WAIT,
':state_invited' => Thread::STATE_INVITED, ':state_invited' => Thread::STATE_INVITED,
':lifetime' => Settings::get('invitation_lifetime'), ':lifetime' => Settings::get('invitation_lifetime'),
':now' => time() ':now' => time(),
), ),
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
// Remove old invitations // Remove old invitations
$db->query( $db->query(
"UPDATE {chatsitevisitor} v, {chatthread} t SET " . ("UPDATE {chatsitevisitor} v, {chatthread} t SET "
"t.invitationstate = :invitation_ignored, " . . "t.invitationstate = :invitation_ignored, "
"t.istate = :state_closed, " . . "t.istate = :state_closed, "
"t.dtmclosed = :now, " . . "t.dtmclosed = :now, "
"v.threadid = NULL " . . "v.threadid = NULL "
"WHERE t.istate = :state_invited " . . "WHERE t.istate = :state_invited "
"AND t.invitationstate = :invitation_wait " . . "AND t.invitationstate = :invitation_wait "
"AND (:now - t.dtmcreated) > :lifetime", . "AND (:now - t.dtmcreated) > :lifetime"),
array( array(
':invitation_ignored' => Thread::INVITATION_IGNORED, ':invitation_ignored' => Thread::INVITATION_IGNORED,
':invitation_wait' => Thread::INVITATION_WAIT, ':invitation_wait' => Thread::INVITATION_WAIT,
':state_closed' => Thread::STATE_CLOSED, ':state_closed' => Thread::STATE_CLOSED,
':state_invited' => Thread::STATE_INVITED, ':state_invited' => Thread::STATE_INVITED,
':lifetime' => Settings::get('invitation_lifetime'), ':lifetime' => Settings::get('invitation_lifetime'),
':now' => time() ':now' => time(),
) )
); );
@ -276,7 +282,8 @@ function invitation_close_old() {
* @param Thread $thread Thread object related with invitation * @param Thread $thread Thread object related with invitation
* @return array Array of invitation data * @return array Array of invitation data
*/ */
function setup_invitation_view(Thread $thread) { function setup_invitation_view(Thread $thread)
{
$data = prepare_chat_app_data(); $data = prepare_chat_app_data();
// Set refresh frequency // Set refresh frequency
@ -290,18 +297,16 @@ function setup_invitation_view(Thread $thread) {
$data['invitation']['thread'] = array( $data['invitation']['thread'] = array(
'id' => $thread->id, 'id' => $thread->id,
'token' => $thread->lastToken 'token' => $thread->lastToken,
); );
$data['invitation']['user'] = array( $data['invitation']['user'] = array(
'name' => htmlspecialchars(topage($thread->userName)), 'name' => htmlspecialchars(to_page($thread->userName)),
'canChangeName' => false, 'canChangeName' => false,
'isAgent' => false 'isAgent' => false,
); );
$data['startFrom'] = 'invitation'; $data['startFrom'] = 'invitation';
return $data; return $data;
} }
?>

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
function mibew_mail($toaddr, $reply_to, $subject, $body) function mibew_mail($to_addr, $reply_to, $subject, $body)
{ {
global $mibew_mailbox, $mail_encoding; global $mibew_mailbox, $mail_encoding;
@ -24,16 +24,20 @@ function mibew_mail($toaddr, $reply_to, $subject, $body)
. "Content-Type: text/plain; charset=$mail_encoding\r\n" . "Content-Type: text/plain; charset=$mail_encoding\r\n"
. 'X-Mailer: PHP/' . phpversion(); . 'X-Mailer: PHP/' . phpversion();
$real_subject = "=?" . $mail_encoding . "?B?" . base64_encode(myiconv(MIBEW_ENCODING, $mail_encoding, $subject)) . "?="; $real_subject = "=?" . $mail_encoding . "?B?"
. base64_encode(myiconv(MIBEW_ENCODING, $mail_encoding, $subject)) . "?=";
$body = preg_replace("/\n/", "\r\n", $body); $body = preg_replace("/\n/", "\r\n", $body);
$old_from = ini_get('sendmail_from'); $old_from = ini_get('sendmail_from');
@ini_set('sendmail_from', $mibew_mailbox); @ini_set('sendmail_from', $mibew_mailbox);
@mail($toaddr, $real_subject, wordwrap(myiconv(MIBEW_ENCODING, $mail_encoding, $body), 70), $headers); @mail(
$to_addr,
$real_subject,
wordwrap(myiconv(MIBEW_ENCODING, $mail_encoding, $body), 70),
$headers
);
if (isset($old_from)) { if (isset($old_from)) {
@ini_set('sendmail_from', $old_from); @ini_set('sendmail_from', $old_from);
} }
} }
?>

View File

@ -54,12 +54,13 @@ define('CAN_MODIFYPROFILE', 3);
* @return array Associativa array whose keys are numerical permission ids and * @return array Associativa array whose keys are numerical permission ids and
* values are string permission names. * values are string permission names.
*/ */
function permission_ids() { function permission_ids()
{
return array( return array(
CAN_ADMINISTRATE => "admin", CAN_ADMINISTRATE => "admin",
CAN_TAKEOVER => "takeover", CAN_TAKEOVER => "takeover",
CAN_VIEWTHREADS => "viewthreads", CAN_VIEWTHREADS => "viewthreads",
CAN_MODIFYPROFILE => "modifyprofile" CAN_MODIFYPROFILE => "modifyprofile",
); );
} }
@ -68,10 +69,11 @@ function permission_ids() {
* @param int $operator_id Operator ID * @param int $operator_id Operator ID
* @param int $perm New permissions value * @param int $perm New permissions value
*/ */
function update_operator_permissions($operator_id, $perm) { function update_operator_permissions($operator_id, $perm)
{
$db = Database::getInstance(); $db = Database::getInstance();
$db->query( $db->query(
"update {chatoperator} set iperm = ? where operatorid = ?", "UPDATE {chatoperator} SET iperm = ? WHERE operatorid = ?",
array($perm, $operator_id) array($perm, $operator_id)
); );
} }
@ -79,8 +81,9 @@ function update_operator_permissions($operator_id, $perm) {
function operator_by_login($login) function operator_by_login($login)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
return $db->query( return $db->query(
"select * from {chatoperator} where vclogin = ?", "SELECT * FROM {chatoperator} WHERE vclogin = ?",
array($login), array($login),
array('return_rows' => Database::RETURN_ONE_ROW) array('return_rows' => Database::RETURN_ONE_ROW)
); );
@ -89,8 +92,9 @@ function operator_by_login($login)
function operator_by_email($mail) function operator_by_email($mail)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
return $db->query( return $db->query(
"select * from {chatoperator} where vcemail = ?", "SELECT * FROM {chatoperator} WHERE vcemail = ?",
array($mail), array($mail),
array('return_rows' => Database::RETURN_ONE_ROW) array('return_rows' => Database::RETURN_ONE_ROW)
); );
@ -99,8 +103,9 @@ function operator_by_email($mail)
function operator_by_id($id) function operator_by_id($id)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
return $db->query( return $db->query(
"select * from {chatoperator} where operatorid = ?", "SELECT * FROM {chatoperator} WHERE operatorid = ?",
array($id), array($id),
array('return_rows' => Database::RETURN_ONE_ROW) array('return_rows' => Database::RETURN_ONE_ROW)
); );
@ -108,14 +113,17 @@ function operator_by_id($id)
/** /**
* Load operator info by specified operators code * Load operator info by specified operators code
*
* @param string $code Operators code * @param string $code Operators code
* @return array|boolean Operators info array or boolean false if there is no * @return array|boolean Operators info array or boolean false if there is no
* operator with specified code. * operator with specified code.
*/ */
function operator_by_code($code) { function operator_by_code($code)
{
$db = Database::getInstance(); $db = Database::getInstance();
return $db->query( return $db->query(
"select * from {chatoperator} where code = ?", "SELECT * FROM {chatoperator} WHERE code = ?",
array($code), array($code),
array('return_rows' => Database::RETURN_ONE_ROW) array('return_rows' => Database::RETURN_ONE_ROW)
); );
@ -123,16 +131,17 @@ function operator_by_code($code) {
/** /**
* Get list of operators taking into account $options * Get list of operators taking into account $options
* @param array $options Associative array of options. It can contains following keys: * @param array $options Associative array of options. It can contains following
* keys:
* - 'sort': an associative array of sorting options. * - 'sort': an associative array of sorting options.
* - 'isolated_operator_id': id of current operators. If it set - function would return * - 'isolated_operator_id': id of current operators. If it set - function
* only operators from adjacent groups. * would return only operators from adjacent groups.
* *
* 'sort' array must contains two keys: 'by' and 'desc'. * 'sort' array must contains two keys: 'by' and 'desc'.
* 'by' means the field by which operators would be sort and can take following * 'by' means the field by which operators would be sort and can take
* values: 'commonname', 'localename', 'login', 'lastseen'. 'desc' means order in which operators would * following values: 'commonname', 'localename', 'login', 'lastseen'. 'desc'
* be sort. If it's 'true' operators would be sort in descending order and in * means order in which operators would be sort. If it's 'true' operators
* ascending order overwise. * would be sort in descending order and in ascending order overwise.
* *
*/ */
function get_operators_list($options) function get_operators_list($options)
@ -159,22 +168,31 @@ function get_operators_list($options)
$orderby = "vclogin"; $orderby = "vclogin";
} }
$query = "select distinct {chatoperator}.operatorid, vclogin, vclocalename, vccommonname, code, istatus, idisabled, (:now - dtmlastvisited) as time " . $query = "SELECT DISTINCT "
"from {chatoperator}" . . "{chatoperator}.operatorid, "
( . "vclogin, "
empty($options['isolated_operator_id']) ? "" : . "vclocalename, "
", {chatgroupoperator} " . . "vccommonname, "
" where {chatoperator}.operatorid = {chatgroupoperator}.operatorid and {chatgroupoperator}.groupid in " . . "code, "
"(select g.groupid from {chatgroup} g, " . . "istatus, "
"(select distinct parent from {chatgroup}, {chatgroupoperator} " . . "idisabled, "
"where {chatgroup}.groupid = {chatgroupoperator}.groupid and {chatgroupoperator}.operatorid = :operatorid) i " . . "(:now - dtmlastvisited) AS time "
"where g.groupid = i.parent or g.parent = i.parent " . . "FROM {chatoperator}"
")" . (empty($options['isolated_operator_id'])
) . ? ""
" order by " . $orderby; : ", {chatgroupoperator} "
. "WHERE {chatoperator}.operatorid = {chatgroupoperator}.operatorid "
. "AND {chatgroupoperator}.groupid IN ("
. "SELECT g.groupid FROM {chatgroup} g, "
. "(SELECT DISTINCT parent FROM {chatgroup}, {chatgroupoperator} "
. "WHERE {chatgroup}.groupid = {chatgroupoperator}.groupid "
. "AND {chatgroupoperator}.operatorid = :operatorid) i "
. "WHERE g.groupid = i.parent OR g.parent = i.parent "
. ")")
. " ORDER BY " . $orderby;
$values = array( $values = array(
':now' => time() ':now' => time(),
); );
if (!empty($options['isolated_operator_id'])) { if (!empty($options['isolated_operator_id'])) {
@ -190,12 +208,14 @@ function get_operators_list($options)
return $operators; return $operators;
} }
function operator_get_all() { function operator_get_all()
{
$db = Database::getInstance(); $db = Database::getInstance();
return $operators = $db->query( return $operators = $db->query(
"select operatorid, vclogin, vclocalename, vccommonname, istatus, code, idisabled, " . ("SELECT operatorid, vclogin, vclocalename, vccommonname, istatus, "
"(:now - dtmlastvisited) as time " . . "code, idisabled, (:now - dtmlastvisited) AS time "
"from {chatoperator} order by vclogin", . "FROM {chatoperator} ORDER BY vclogin"),
array(':now' => time()), array(':now' => time()),
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
@ -204,25 +224,25 @@ function operator_get_all() {
function get_operators_from_adjacent_groups($operator) function get_operators_from_adjacent_groups($operator)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
$query = "select distinct {chatoperator}.operatorid, vclogin, vclocalename,vccommonname, " . $query = "SELECT DISTINCT {chatoperator}.operatorid, vclogin, "
"istatus, idisabled, code, " . . "vclocalename,vccommonname, "
"(:now - dtmlastvisited) as time " . . "istatus, idisabled, code, "
"from {chatoperator}, {chatgroupoperator} " . . "(:now - dtmlastvisited) AS time "
"where {chatoperator}.operatorid = {chatgroupoperator}.operatorid " . . "FROM {chatoperator}, {chatgroupoperator} "
"and {chatgroupoperator}.groupid in " . . "WHERE {chatoperator}.operatorid = {chatgroupoperator}.operatorid "
"(select g.groupid from {chatgroup} g, " . . "AND {chatgroupoperator}.groupid IN ("
"(select distinct parent from {chatgroup}, {chatgroupoperator} " . . "SELECT g.groupid from {chatgroup} g, "
"where {chatgroup}.groupid = {chatgroupoperator}.groupid " . . "(SELECT DISTINCT parent FROM {chatgroup}, {chatgroupoperator} "
"and {chatgroupoperator}.operatorid = :operatorid) i " . . "WHERE {chatgroup}.groupid = {chatgroupoperator}.groupid "
"where g.groupid = i.parent or g.parent = i.parent " . . "AND {chatgroupoperator}.operatorid = :operatorid) i "
") order by vclogin"; . "WHERE g.groupid = i.parent OR g.parent = i.parent "
. ") ORDER BY vclogin";
return $db->query( return $db->query(
$query, $query,
array( array(
':operatorid' => $operator['operatorid'], ':operatorid' => $operator['operatorid'],
':now' => time() ':now' => time(),
), ),
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
@ -235,12 +255,16 @@ function operator_is_online($operator)
function operator_is_available($operator) function operator_is_available($operator)
{ {
return $operator['istatus'] == 0 && $operator['time'] < Settings::get('online_timeout') ? "1" : ""; return ($operator['istatus'] == 0 && $operator['time'] < Settings::get('online_timeout'))
? "1"
: "";
} }
function operator_is_away($operator) function operator_is_away($operator)
{ {
return $operator['istatus'] != 0 && $operator['time'] < Settings::get('online_timeout') ? "1" : ""; return ($operator['istatus'] != 0 && $operator['time'] < Settings::get('online_timeout'))
? "1"
: "";
} }
function operator_is_disabled($operator) function operator_is_disabled($operator)
@ -253,46 +277,53 @@ function operator_is_disabled($operator)
* *
* If $password argument is empty operators password will not be changed. * If $password argument is empty operators password will not be changed.
* *
* @param int $operatorid ID of operator to update * @param int $operator_id ID of operator to update
* @param string $login Operator's login * @param string $login Operator's login
* @param string $email Operator's * @param string $email Operator's
* @param string $password Operator's password * @param string $password Operator's password
* @param string $localename Operator's local name * @param string $locale_name Operator's local name
* @param string $commonname Operator's international name * @param string $common_name Operator's international name
* @param string $code Operator's code which use to start chat with specified * @param string $code Operator's code which use to start chat with specified
* operator * operator
*/ */
function update_operator($operatorid, $login, $email, $password, $localename, $commonname, $code) { function update_operator(
$operator_id,
$login,
$email,
$password,
$locale_name,
$common_name,
$code
) {
$db = Database::getInstance(); $db = Database::getInstance();
$values = array( $values = array(
':login' => $login, ':login' => $login,
':localname' => $localename, ':localname' => $locale_name,
':commonname' => $commonname, ':commonname' => $common_name,
':email' => $email, ':email' => $email,
':jabbername' => '', ':jabbername' => '',
':operatorid' => $operatorid, ':operatorid' => $operator_id,
':code' => $code ':code' => $code,
); );
if ($password) { if ($password) {
$values[':password'] = calculate_password_hash($login, $password); $values[':password'] = calculate_password_hash($login, $password);
} }
$db->query( $db->query(
"update {chatoperator} set vclogin = :login, " . ("UPDATE {chatoperator} SET vclogin = :login, "
($password ? " vcpassword=:password, " : "") . . ($password ? " vcpassword=:password, " : "")
"vclocalename = :localname, vccommonname = :commonname, " . . "vclocalename = :localname, vccommonname = :commonname, "
"vcemail = :email, code = :code, vcjabbername= :jabbername " . . "vcemail = :email, code = :code, vcjabbername= :jabbername "
"where operatorid = :operatorid", . "WHERE operatorid = :operatorid"),
$values $values
); );
} }
function update_operator_avatar($operatorid, $avatar) function update_operator_avatar($operator_id, $avatar)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
$db->query( $db->query(
"update {chatoperator} set vcavatar = ? where operatorid = ?", "UPDATE {chatoperator} SET vcavatar = ? WHERE operatorid = ?",
array($avatar, $operatorid) array($avatar, $operator_id)
); );
} }
@ -302,39 +333,47 @@ function update_operator_avatar($operatorid, $avatar)
* @param string $login Operator's login * @param string $login Operator's login
* @param string $email Operator's * @param string $email Operator's
* @param string $password Operator's password * @param string $password Operator's password
* @param string $localename Operator's local name * @param string $locale_name Operator's local name
* @param string $commonname Operator's international name * @param string $common_name Operator's international name
* @param string $avatar Operator's avatar * @param string $avatar Operator's avatar
* @param string $code Operator's code which use to start chat with specified * @param string $code Operator's code which use to start chat with specified
* operator * operator
* @return array Operator's array * @return array Operator's array
*/ */
function create_operator($login, $email, $password, $localename, $commonname, $avatar, $code) { function create_operator(
$login,
$email,
$password,
$locale_name,
$common_name,
$avatar,
$code
) {
$db = Database::getInstance(); $db = Database::getInstance();
$db->query( $db->query(
"INSERT INTO {chatoperator} (" . ("INSERT INTO {chatoperator} ("
"vclogin, vcpassword, vclocalename, vccommonname, vcavatar, " . . "vclogin, vcpassword, vclocalename, vccommonname, vcavatar, "
"vcemail, code, vcjabbername " . . "vcemail, code, vcjabbername "
") VALUES (" . . ") VALUES ("
":login, :pass, :localename, :commonname, :avatar, " . . ":login, :pass, :localename, :commonname, :avatar, "
":email, :code, :jabber". . ":email, :code, :jabber"
")", . ")"),
array( array(
':login' => $login, ':login' => $login,
':pass' => calculate_password_hash($login, $password), ':pass' => calculate_password_hash($login, $password),
':localename' => $localename, ':localename' => $locale_name,
':commonname' => $commonname, ':commonname' => $common_name,
':avatar' => $avatar, ':avatar' => $avatar,
':email' => $email, ':email' => $email,
':code' => $code, ':code' => $code,
':jabber' => '' ':jabber' => '',
) )
); );
$id = $db->insertedId(); $id = $db->insertedId();
return $db->query( return $db->query(
"select * from {chatoperator} where operatorid = ?", "SELECT * FROM {chatoperator} WHERE operatorid = ?",
array($id), array($id),
array('return_rows' => Database::RETURN_ONE_ROW) array('return_rows' => Database::RETURN_ONE_ROW)
); );
@ -345,20 +384,21 @@ function create_operator($login, $email, $password, $localename, $commonname, $a
* *
* This function remove operator and associations with groups for this operator * This function remove operator and associations with groups for this operator
* from datatabse. * from datatabse.
* It trigger 'operatorDelete' event and pass to event listeners associative * It triggers 'operatorDelete' event and pass to event listeners associative
* array with following keys: * array with following keys:
* - 'id': int, deleted operator ID. * - 'id': int, deleted operator ID.
* *
* @param int $operator_id Operator ID * @param int $operator_id Operator ID
*/ */
function delete_operator($operator_id) { function delete_operator($operator_id)
{
$db = Database::getInstance(); $db = Database::getInstance();
$db->query( $db->query(
"delete from {chatgroupoperator} where operatorid = ?", "DELETE FROM {chatgroupoperator} WHERE operatorid = ?",
array($operator_id) array($operator_id)
); );
$db->query( $db->query(
"delete from {chatoperator} where operatorid = ?", "DELETE FROM {chatoperator} WHERE operatorid = ?",
array($operator_id) array($operator_id)
); );
@ -375,20 +415,20 @@ function delete_operator($operator_id) {
* @param int $istatus Operator status: '0' means 'available' and '1' means * @param int $istatus Operator status: '0' means 'available' and '1' means
* 'away' * 'away'
*/ */
function notify_operator_alive($operatorid, $istatus) function notify_operator_alive($operator_id, $istatus)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
$db->query( $db->query(
"update {chatoperator} set istatus = :istatus, dtmlastvisited = :now " . ("UPDATE {chatoperator} SET istatus = :istatus, dtmlastvisited = :now "
"where operatorid = :operatorid", . "WHERE operatorid = :operatorid"),
array( array(
':istatus' => $istatus, ':istatus' => $istatus,
':now' => time(), ':now' => time(),
':operatorid' => $operatorid ':operatorid' => $operator_id,
) )
); );
if (isset($_SESSION[SESSION_PREFIX . "operator"])) { if (isset($_SESSION[SESSION_PREFIX . "operator"])) {
if ($_SESSION[SESSION_PREFIX."operator"]['operatorid'] == $operatorid) { if ($_SESSION[SESSION_PREFIX . "operator"]['operatorid'] == $operator_id) {
$_SESSION[SESSION_PREFIX . "operator"]['istatus'] = $istatus; $_SESSION[SESSION_PREFIX . "operator"]['istatus'] = $istatus;
} }
} }
@ -396,26 +436,30 @@ function notify_operator_alive($operatorid, $istatus)
/** /**
* Indicates if at least one operator of the group is online * Indicates if at least one operator of the group is online
* @param int $groupid Id of the group * @param int $group_id Id of the group
* @return boolean true if the group have online operators and false otherwise * @return boolean true if the group have online operators and false otherwise
*/ */
function has_online_operators($groupid = "") function has_online_operators($group_id = "")
{ {
$db = Database::getInstance(); $db = Database::getInstance();
$query = "select count(*) as total, min(:now - dtmlastvisited) as time from {chatoperator}"; $query = "SELECT count(*) AS total, MIN(:now - dtmlastvisited) AS time "
. "FROM {chatoperator}";
$values = array(':now' => time()); $values = array(':now' => time());
if ($groupid) { if ($group_id) {
$query .= ", {chatgroupoperator}, {chatgroup} where {chatgroup}.groupid = {chatgroupoperator}.groupid and " . $query .= ", {chatgroupoperator}, {chatgroup} "
"({chatgroup}.groupid = :groupid or {chatgroup}.parent = :groupid) and {chatoperator}.operatorid = " . . "WHERE {chatgroup}.groupid = {chatgroupoperator}.groupid "
"{chatgroupoperator}.operatorid and istatus = 0"; . "AND ({chatgroup}.groupid = :groupid OR {chatgroup}.parent = :groupid) "
$values[':groupid'] = $groupid; . "AND {chatoperator}.operatorid = {chatgroupoperator}.operatorid "
. "AND istatus = 0";
$values[':groupid'] = $group_id;
} else { } else {
if (Settings::get('enablegroups') == 1) { if (Settings::get('enablegroups') == 1) {
$query .= ", {chatgroupoperator} where {chatoperator}.operatorid = " . $query .= ", {chatgroupoperator} "
"{chatgroupoperator}.operatorid and istatus = 0"; . "WHERE {chatoperator}.operatorid = {chatgroupoperator}.operatorid "
. "AND istatus = 0";
} else { } else {
$query .= " where istatus = 0"; $query .= " WHERE istatus = 0";
} }
} }
@ -424,30 +468,31 @@ function has_online_operators($groupid = "")
$values, $values,
array('return_rows' => Database::RETURN_ONE_ROW) array('return_rows' => Database::RETURN_ONE_ROW)
); );
return $row['time'] < Settings::get('online_timeout') && $row['total'] > 0;
return ($row['time'] < Settings::get('online_timeout')) && ($row['total'] > 0);
} }
/** /**
* Indicates if operator online or not * Indicates if operator online or not
* *
* @param int $operatorid Id of the operator * @param int $operator_id Id of the operator
* @return boolean true if operator is online and false otherwise * @return boolean true if operator is online and false otherwise
*/ */
function is_operator_online($operatorid) function is_operator_online($operator_id)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
$row = $db->query( $row = $db->query(
"select count(*) as total, " . ("SELECT count(*) AS total, "
"min(:now - dtmlastvisited) as time " . . "MIN(:now - dtmlastvisited) AS time "
"from {chatoperator} where operatorid = :operatorid", . "FROM {chatoperator} WHERE operatorid = :operatorid"),
array( array(
':now' => time(), ':now' => time(),
':operatorid' => $operatorid ':operatorid' => $operator_id,
), ),
array('return_rows' => Database::RETURN_ONE_ROW) array('return_rows' => Database::RETURN_ONE_ROW)
); );
return $row['time'] < Settings::get('online_timeout') && $row['total'] == 1; return ($row['time'] < Settings::get('online_timeout')) && ($row['total'] == 1);
} }
/** /**
@ -458,17 +503,20 @@ function is_operator_online($operatorid)
*/ */
function get_operator_name($operator) function get_operator_name($operator)
{ {
if (HOME_LOCALE == CURRENT_LOCALE) if (HOME_LOCALE == CURRENT_LOCALE) {
return $operator['vclocalename']; return $operator['vclocalename'];
else } else {
return $operator['vccommonname']; return $operator['vccommonname'];
} }
}
function append_query($link, $pv) function append_query($link, $pv)
{ {
$infix = '?'; $infix = '?';
if (strstr($link, $infix) !== FALSE) if (strstr($link, $infix) !== false) {
$infix = '&amp;'; $infix = '&amp;';
}
return "$link$infix$pv"; return "$link$infix$pv";
} }
@ -485,13 +533,20 @@ function append_query($link, $pv)
* @return null|array Array with operator info if operator is logged in and * @return null|array Array with operator info if operator is logged in and
* null otherwise. * null otherwise.
*/ */
function check_login($redirect = true) { function check_login($redirect = true)
{
if (!isset($_SESSION[SESSION_PREFIX . "operator"])) { if (!isset($_SESSION[SESSION_PREFIX . "operator"])) {
if (isset($_COOKIE[REMEMBER_OPERATOR_COOKIE_NAME])) { if (isset($_COOKIE[REMEMBER_OPERATOR_COOKIE_NAME])) {
list($login, $pwd) = preg_split('/\x0/', base64_decode($_COOKIE[REMEMBER_OPERATOR_COOKIE_NAME]), 2); list($login, $pwd) = preg_split('/\x0/', base64_decode($_COOKIE[REMEMBER_OPERATOR_COOKIE_NAME]), 2);
$op = operator_by_login($login); $op = operator_by_login($login);
if ($op && isset($pwd) && isset($op['vcpassword']) && calculate_password_hash($op['vclogin'], $op['vcpassword']) == $pwd && !operator_is_disabled($op)) { $can_login = $op
&& isset($pwd)
&& isset($op['vcpassword'])
&& calculate_password_hash($op['vclogin'], $op['vcpassword']) == $pwd
&& !operator_is_disabled($op);
if ($can_login) {
$_SESSION[SESSION_PREFIX . "operator"] = $op; $_SESSION[SESSION_PREFIX . "operator"] = $op;
return $op; return $op;
} }
} }
@ -516,6 +571,7 @@ function check_login($redirect = true) {
return null; return null;
} }
} }
return $_SESSION[SESSION_PREFIX . "operator"]; return $_SESSION[SESSION_PREFIX . "operator"];
} }
@ -530,7 +586,9 @@ function force_password($operator)
function get_logged_in() function get_logged_in()
{ {
return isset($_SESSION[SESSION_PREFIX."operator"]) ? $_SESSION[SESSION_PREFIX."operator"] : FALSE; return isset($_SESSION[SESSION_PREFIX . "operator"])
? $_SESSION[SESSION_PREFIX . "operator"]
: false;
} }
/** /**
@ -545,12 +603,20 @@ function get_logged_in()
* @param boolean $remember Indicates if system should remember operator * @param boolean $remember Indicates if system should remember operator
* @param boolean $https Indicates if cookie should be flagged as a secure one * @param boolean $https Indicates if cookie should be flagged as a secure one
*/ */
function login_operator($operator, $remember, $https = FALSE) { function login_operator($operator, $remember, $https = false)
{
$_SESSION[SESSION_PREFIX . "operator"] = $operator; $_SESSION[SESSION_PREFIX . "operator"] = $operator;
if ($remember) { if ($remember) {
$value = base64_encode($operator['vclogin'] . "\x0" . calculate_password_hash($operator['vclogin'], $operator['vcpassword'])); $password_hash = calculate_password_hash($operator['vclogin'], $operator['vcpassword']);
setcookie(REMEMBER_OPERATOR_COOKIE_NAME, $value, time() + 60 * 60 * 24 * 1000, MIBEW_WEB_ROOT . "/", NULL, $https, TRUE); setcookie(
REMEMBER_OPERATOR_COOKIE_NAME,
base64_encode($operator['vclogin'] . "\x0" . $password_hash),
time() + 60 * 60 * 24 * 1000,
MIBEW_WEB_ROOT . "/",
null,
$https,
true
);
} elseif (isset($_COOKIE[REMEMBER_OPERATOR_COOKIE_NAME])) { } elseif (isset($_COOKIE[REMEMBER_OPERATOR_COOKIE_NAME])) {
setcookie(REMEMBER_OPERATOR_COOKIE_NAME, '', time() - 3600, MIBEW_WEB_ROOT . "/"); setcookie(REMEMBER_OPERATOR_COOKIE_NAME, '', time() - 3600, MIBEW_WEB_ROOT . "/");
} }
@ -558,7 +624,7 @@ function login_operator($operator, $remember, $https = FALSE) {
// Trigger login event // Trigger login event
$args = array( $args = array(
'operator' => $operator, 'operator' => $operator,
'remember' => $remember 'remember' => $remember,
); );
$dispatcher = EventDispatcher::getInstance(); $dispatcher = EventDispatcher::getInstance();
$dispatcher->triggerEvent('operatorLogin', $args); $dispatcher->triggerEvent('operatorLogin', $args);
@ -569,7 +635,8 @@ function login_operator($operator, $remember, $https = FALSE) {
* *
* Triggers 'operatorLogout' event after operator logged out. * Triggers 'operatorLogout' event after operator logged out.
*/ */
function logout_operator() { function logout_operator()
{
unset($_SESSION[SESSION_PREFIX . "operator"]); unset($_SESSION[SESSION_PREFIX . "operator"]);
unset($_SESSION['backpath']); unset($_SESSION['backpath']);
if (isset($_COOKIE[REMEMBER_OPERATOR_COOKIE_NAME])) { if (isset($_COOKIE[REMEMBER_OPERATOR_COOKIE_NAME])) {
@ -581,29 +648,34 @@ function logout_operator() {
$dispatcher->triggerEvent('operatorLogout'); $dispatcher->triggerEvent('operatorLogout');
} }
function setup_redirect_links($threadid, $operator, $token) { function setup_redirect_links($threadid, $operator, $token)
{
$result = array(); $result = array();
$operator_in_isolation = in_isolation($operator); $operator_in_isolation = in_isolation($operator);
$list_options = $operator_in_isolation?array('isolated_operator_id' => $operator['operatorid']):array(); $list_options = $operator_in_isolation
? array('isolated_operator_id' => $operator['operatorid'])
: array();
$operators = get_operators_list($list_options); $operators = get_operators_list($list_options);
$operatorscount = count($operators); $operators_count = count($operators);
$groupscount = 0; $groups_count = 0;
$groups = array(); $groups = array();
if (Settings::get('enablegroups') == "1") { if (Settings::get('enablegroups') == "1") {
$groupslist = $operator_in_isolation?get_groups_for_operator($operator, true):get_groups(true); $groupslist = $operator_in_isolation
? get_groups_for_operator($operator, true)
: get_groups(true);
foreach ($groupslist as $group) { foreach ($groupslist as $group) {
if ($group['inumofagents'] == 0) { if ($group['inumofagents'] == 0) {
continue; continue;
} }
$groups[] = $group; $groups[] = $group;
} }
$groupscount = count($groups); $groups_count = count($groups);
} }
$p = pagination_info(max($operatorscount, $groupscount), 8); $p = pagination_info(max($operators_count, $groups_count), 8);
$result['pagination'] = $p; $result['pagination'] = $p;
$operators = array_slice($operators, $p['start'], $p['end'] - $p['start']); $operators = array_slice($operators, $p['start'], $p['end'] - $p['start']);
@ -616,13 +688,12 @@ function setup_redirect_links($threadid, $operator, $token) {
$status = $agent['time'] < Settings::get('online_timeout') $status = $agent['time'] < Settings::get('online_timeout')
? ($agent['istatus'] == 0 ? ($agent['istatus'] == 0
? getlocal("char.redirect.operator.online_suff") ? getlocal("char.redirect.operator.online_suff")
: getlocal("char.redirect.operator.away_suff") : getlocal("char.redirect.operator.away_suff"))
)
: ""; : "";
$agent_list .= "<li><a href=\"" . add_params(MIBEW_WEB_ROOT . "/operator/redirect.php", $params) . $agent_list .= "<li><a href=\"" . add_params(MIBEW_WEB_ROOT . "/operator/redirect.php", $params)
"\" title=\"" . topage(get_operator_name($agent)) . "\">" . . "\" title=\"" . to_page(get_operator_name($agent)) . "\">"
topage(get_operator_name($agent)) . . to_page(get_operator_name($agent))
"</a> $status</li>"; . "</a> $status</li>";
} }
$result['redirectToAgent'] = $agent_list; $result['redirectToAgent'] = $agent_list;
@ -631,15 +702,13 @@ function setup_redirect_links($threadid, $operator, $token) {
$params = array('thread' => $threadid, 'token' => $token); $params = array('thread' => $threadid, 'token' => $token);
foreach ($groups as $group) { foreach ($groups as $group) {
$params['nextGroup'] = $group['groupid']; $params['nextGroup'] = $group['groupid'];
$status = $group['ilastseen'] !== NULL && $group['ilastseen'] < Settings::get('online_timeout') $status = group_is_online($group)
? getlocal("char.redirect.operator.online_suff") ? getlocal("char.redirect.operator.online_suff")
: ($group['ilastseenaway'] !== NULL && $group['ilastseenaway'] < Settings::get('online_timeout') : (group_is_away($group) ? getlocal("char.redirect.operator.away_suff") : "");
? getlocal("char.redirect.operator.away_suff") $group_list .= "<li><a href=\"" . add_params(MIBEW_WEB_ROOT . "/operator/redirect.php", $params)
: ""); . "\" title=\"" . to_page(get_group_name($group)) . "\">"
$group_list .= "<li><a href=\"" . add_params(MIBEW_WEB_ROOT . "/operator/redirect.php", $params) . . to_page(get_group_name($group))
"\" title=\"" . topage(get_group_name($group)) . "\">" . . "</a> $status</li>";
topage(get_group_name($group)) .
"</a> $status</li>";
} }
} }
$result['redirectToGroup'] = $group_list; $result['redirectToGroup'] = $group_list;
@ -650,26 +719,31 @@ function setup_redirect_links($threadid, $operator, $token) {
function get_permission_list() function get_permission_list()
{ {
static $permission_list = array(); static $permission_list = array();
if (count($permission_list) == 0) { if (count($permission_list) == 0) {
foreach (permission_ids() as $permid) { foreach (permission_ids() as $perm_id) {
$permission_list[] = array( $permission_list[] = array(
'id' => $permid, 'id' => $perm_id,
'descr' => getlocal("permission.$permid") 'descr' => getlocal("permission.$perm_id"),
); );
} }
} }
return $permission_list; return $permission_list;
} }
function is_capable($perm, $operator) function is_capable($perm, $operator)
{ {
$permissions = $operator && isset($operator['iperm']) ? $operator['iperm'] : 0; $permissions = $operator && isset($operator['iperm']) ? $operator['iperm'] : 0;
return $perm >= 0 && $perm < 32 && ($permissions & (1 << $perm)) != 0; return $perm >= 0 && $perm < 32 && ($permissions & (1 << $perm)) != 0;
} }
function in_isolation($operator) function in_isolation($operator)
{ {
return (!is_capable(CAN_ADMINISTRATE, $operator) && Settings::get('enablegroups') && Settings::get('enablegroupsisolation')); return !is_capable(CAN_ADMINISTRATE, $operator)
&& Settings::get('enablegroups')
&& Settings::get('enablegroupsisolation');
} }
/** /**
@ -682,11 +756,12 @@ function in_isolation($operator)
* Default value is TRUE. * Default value is TRUE.
* @return array * @return array
*/ */
function prepare_menu($operator, $hasright = true) { function prepare_menu($operator, $has_right = true)
{
$result = array(); $result = array();
$result['operator'] = topage(get_operator_name($operator)); $result['operator'] = to_page(get_operator_name($operator));
if ($hasright) { if ($has_right) {
$result['showban'] = Settings::get('enableban') == "1"; $result['showban'] = Settings::get('enableban') == "1";
$result['showstat'] = Settings::get('enablestatistics') == "1"; $result['showstat'] = Settings::get('enablestatistics') == "1";
$result['showadmin'] = is_capable(CAN_ADMINISTRATE, $operator); $result['showadmin'] = is_capable(CAN_ADMINISTRATE, $operator);
@ -700,49 +775,67 @@ function get_all_groups()
{ {
$db = Database::getInstance(); $db = Database::getInstance();
$groups = $db->query( $groups = $db->query(
"select {chatgroup}.groupid as groupid, parent, vclocalname, vclocaldescription " . ("SELECT {chatgroup}.groupid AS groupid, parent, "
"from {chatgroup} order by vclocalname", . "vclocalname, vclocaldescription "
NULL, . "FROM {chatgroup} ORDER BY vclocalname"),
null,
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
return get_sorted_child_groups_($groups); return get_sorted_child_groups_($groups);
} }
function get_all_groups_for_operator($operator) function get_all_groups_for_operator($operator)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
$query = "select g.groupid as groupid, g.parent, g.vclocalname, g.vclocaldescription " . $query = "SELECT g.groupid AS groupid, g.parent, g.vclocalname, g.vclocaldescription "
"from {chatgroup} g, " . . "FROM {chatgroup} g, "
"(select distinct parent from {chatgroup}, {chatgroupoperator} " . . "(SELECT DISTINCT parent FROM {chatgroup}, {chatgroupoperator} "
"where {chatgroup}.groupid = {chatgroupoperator}.groupid " . . "WHERE {chatgroup}.groupid = {chatgroupoperator}.groupid "
"and {chatgroupoperator}.operatorid = ?) i " . . "AND {chatgroupoperator}.operatorid = ?) i "
"where g.groupid = i.parent or g.parent = i.parent " . . "WHERE g.groupid = i.parent OR g.parent = i.parent "
"order by vclocalname"; . "ORDER BY vclocalname";
$groups = $db->query( $groups = $db->query(
$query, $query,
array($operator['operatorid']), array($operator['operatorid']),
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
return get_sorted_child_groups_($groups); return get_sorted_child_groups_($groups);
} }
function get_sorted_child_groups_($groupslist, $skipgroups = array(), $maxlevel = -1, $groupid = NULL, $level = 0) function get_sorted_child_groups_(
{ $groups_list,
$skip_groups = array(),
$max_level = -1,
$group_id = null,
$level = 0
) {
$child_groups = array(); $child_groups = array();
foreach ($groupslist as $index => $group) { foreach ($groups_list as $index => $group) {
if ($group['parent'] == $groupid && !in_array($group['groupid'], $skipgroups)) { if ($group['parent'] == $group_id && !in_array($group['groupid'], $skip_groups)) {
$group['level'] = $level; $group['level'] = $level;
$child_groups[] = $group; $child_groups[] = $group;
if ($maxlevel == -1 || $level < $maxlevel) { if ($max_level == -1 || $level < $max_level) {
$child_groups = array_merge($child_groups, get_sorted_child_groups_($groupslist, $skipgroups, $maxlevel, $group['groupid'], $level+1)); $child_groups = array_merge(
$child_groups,
get_sorted_child_groups_(
$groups_list,
$skip_groups,
$max_level,
$group['groupid'],
$level + 1
)
);
} }
} }
} }
return $child_groups; return $child_groups;
} }
function get_groups_($checkaway, $operator, $order = NULL) function get_groups_($check_away, $operator, $order = null)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
if ($order) { if ($order) {
@ -756,69 +849,83 @@ function get_groups_($checkaway, $operator, $order = NULL)
default: default:
$orderby = "{chatgroup}.vclocalname"; $orderby = "{chatgroup}.vclocalname";
} }
$orderby = sprintf(" IF(ISNULL({chatgroup}.parent),CONCAT('_',%s),'') %s, {chatgroup}.iweight ", $orderby = sprintf(
" IF(ISNULL({chatgroup}.parent),CONCAT('_',%s),'') %s, {chatgroup}.iweight ",
$orderby, $orderby,
($order['desc']?'DESC':'ASC')); ($order['desc'] ? 'DESC' : 'ASC')
);
} else { } else {
$orderby = "iweight, vclocalname"; $orderby = "iweight, vclocalname";
} }
$values = array( $values = array(
':now' => time() ':now' => time(),
); );
$query = "select {chatgroup}.groupid as groupid, {chatgroup}.parent as parent, vclocalname, vclocaldescription, iweight" . $query = "SELECT {chatgroup}.groupid AS groupid, "
", (SELECT count(*) from {chatgroupoperator} where {chatgroup}.groupid = " . . "{chatgroup}.parent AS parent, "
"{chatgroupoperator}.groupid) as inumofagents" . . "vclocalname, vclocaldescription, iweight, "
", (SELECT min(:now - dtmlastvisited) as time " . . "(SELECT count(*) "
"from {chatgroupoperator}, {chatoperator} where istatus = 0 and " . . "FROM {chatgroupoperator} "
"{chatgroup}.groupid = {chatgroupoperator}.groupid " . . "WHERE {chatgroup}.groupid = {chatgroupoperator}.groupid"
"and {chatgroupoperator}.operatorid = {chatoperator}.operatorid) as ilastseen" . . ") AS inumofagents, "
($checkaway . "(SELECT MIN(:now - dtmlastvisited) AS time "
? ", (SELECT min(:now - dtmlastvisited) as time " . . "FROM {chatgroupoperator}, {chatoperator} "
"from {chatgroupoperator}, {chatoperator} where istatus <> 0 and " . . "WHERE istatus = 0 "
"{chatgroup}.groupid = {chatgroupoperator}.groupid " . . "AND {chatgroup}.groupid = {chatgroupoperator}.groupid "
"and {chatgroupoperator}.operatorid = {chatoperator}.operatorid) as ilastseenaway" . "AND {chatgroupoperator}.operatorid = {chatoperator}.operatorid" .
: "" ") AS ilastseen"
) . . ($check_away
" from {chatgroup} "; ? ", (SELECT MIN(:now - dtmlastvisited) AS time "
. "FROM {chatgroupoperator}, {chatoperator} "
. "WHERE istatus <> 0 "
. "AND {chatgroup}.groupid = {chatgroupoperator}.groupid "
. "AND {chatgroupoperator}.operatorid = {chatoperator}.operatorid"
. ") AS ilastseenaway"
: "")
. " FROM {chatgroup} ";
if ($operator) { if ($operator) {
$query .= ", (select distinct parent from {chatgroup}, {chatgroupoperator} " . $query .= ", (SELECT DISTINCT parent "
"where {chatgroup}.groupid = {chatgroupoperator}.groupid and {chatgroupoperator}.operatorid = :operatorid) i " . . "FROM {chatgroup}, {chatgroupoperator} "
"where {chatgroup}.groupid = i.parent or {chatgroup}.parent = i.parent "; . "WHERE {chatgroup}.groupid = {chatgroupoperator}.groupid "
. "AND {chatgroupoperator}.operatorid = :operatorid) i "
. "WHERE {chatgroup}.groupid = i.parent OR {chatgroup}.parent = i.parent ";
$values[':operatorid'] = $operator['operatorid']; $values[':operatorid'] = $operator['operatorid'];
} }
$query .= " order by " . $orderby; $query .= " ORDER BY " . $orderby;
$groups = $db->query( $groups = $db->query(
$query, $query,
$values, $values,
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
return get_sorted_child_groups_($groups); return get_sorted_child_groups_($groups);
} }
function get_groups($checkaway) function get_groups($check_away)
{ {
return get_groups_($checkaway, NULL); return get_groups_($check_away, null);
} }
function get_groups_for_operator($operator, $checkaway) function get_groups_for_operator($operator, $check_away)
{ {
return get_groups_($checkaway, $operator); return get_groups_($check_away, $operator);
} }
function get_sorted_groups($order) function get_sorted_groups($order)
{ {
return get_groups_(true, NULL, $order); return get_groups_(true, null, $order);
} }
function get_operator_groupids($operatorid) function get_operator_group_ids($operator_id)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
return $db->query( return $db->query(
"select groupid from {chatgroupoperator} where operatorid = ?", "SELECT groupid FROM {chatgroupoperator} WHERE operatorid = ?",
array($operatorid), array($operator_id),
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
} }
@ -841,8 +948,7 @@ function calculate_password_hash($login, $password)
if (CRYPT_BLOWFISH == 1) { if (CRYPT_BLOWFISH == 1) {
if (defined('PHP_VERSION_ID') && (PHP_VERSION_ID > 50306)) { if (defined('PHP_VERSION_ID') && (PHP_VERSION_ID > 50306)) {
$hash = crypt($password, '$2y$08$' . $login); $hash = crypt($password, '$2y$08$' . $login);
} } else {
else {
$hash = crypt($password, '$2a$08$' . $login); $hash = crypt($password, '$2a$08$' . $login);
} }
} }
@ -868,26 +974,23 @@ function check_password_hash($login, $password, $hash)
{ {
if (preg_match('/^\$/', $hash)) { if (preg_match('/^\$/', $hash)) {
return !strcmp(calculate_password_hash($login, $password), $hash); return !strcmp(calculate_password_hash($login, $password), $hash);
} } else {
else {
return !strcmp(md5($password), $hash); return !strcmp(md5($password), $hash);
} }
} }
function update_operator_groups($operatorid, $newvalue) function update_operator_groups($operator_id, $new_value)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
$db->query( $db->query(
"delete from {chatgroupoperator} where operatorid = ?", "DELETE FROM {chatgroupoperator} WHERE operatorid = ?",
array($operatorid) array($operator_id)
); );
foreach ($newvalue as $groupid) { foreach ($new_value as $group_id) {
$db->query( $db->query(
"insert into {chatgroupoperator} (groupid, operatorid) values (?,?)", "INSERT INTO {chatgroupoperator} (groupid, operatorid) VALUES (?,?)",
array($groupid, $operatorid) array($group_id, $operator_id)
); );
} }
} }
?>

View File

@ -15,7 +15,6 @@
* limitations under the License. * limitations under the License.
*/ */
/** /**
* Builds list of operator settings tabs. The keys of the resulting array are * Builds list of operator settings tabs. The keys of the resulting array are
* tabs titles and the values are tabs URLs. * tabs titles and the values are tabs URLs.
@ -24,19 +23,26 @@
* @param int $active Number of the active tab. The count starts from 0. * @param int $active Number of the active tab. The count starts from 0.
* @return array Tabs list * @return array Tabs list
*/ */
function setup_operator_settings_tabs($operator_id, $active) { function setup_operator_settings_tabs($operator_id, $active)
{
$tabs = array(); $tabs = array();
if ($operator_id) { if ($operator_id) {
$tabs = array( $tabs = array(
getlocal("page_agent.tab.main") => $active != 0 ? (MIBEW_WEB_ROOT . "/operator/operator.php?op=" . $operator_id) : "", getlocal("page_agent.tab.main") => ($active != 0
getlocal("page_agent.tab.avatar") => $active != 1 ? (MIBEW_WEB_ROOT . "/operator/avatar.php?op=" . $operator_id) : "", ? (MIBEW_WEB_ROOT . "/operator/operator.php?op=" . $operator_id)
getlocal("page_agent.tab.groups") => $active != 2 ? (MIBEW_WEB_ROOT . "/operator/opgroups.php?op=" . $operator_id) : "", : ""),
getlocal("page_agent.tab.permissions") => $active != 3 ? (MIBEW_WEB_ROOT . "/operator/permissions.php?op=" . $operator_id) : "" getlocal("page_agent.tab.avatar") => ($active != 1
? (MIBEW_WEB_ROOT . "/operator/avatar.php?op=" . $operator_id)
: ""),
getlocal("page_agent.tab.groups") => ($active != 2
? (MIBEW_WEB_ROOT . "/operator/opgroups.php?op=" . $operator_id)
: ""),
getlocal("page_agent.tab.permissions") => ($active != 3
? (MIBEW_WEB_ROOT . "/operator/permissions.php?op=" . $operator_id)
: ""),
); );
} }
return $tabs; return $tabs;
} }
?>

View File

@ -32,10 +32,12 @@ define('PAGINATION_LINKS_ON_PAGE', 5);
* @param string $title Link title * @param string $title Link title
* @return string HTML markup * @return string HTML markup
*/ */
function generate_pagination_link($page, $title) { function generate_pagination_link($page, $title)
{
$lnk = $_SERVER['REQUEST_URI']; $lnk = $_SERVER['REQUEST_URI'];
$href = preg_replace("/\?page=\d+\&/", "?", preg_replace("/\&page=\d+/", "", $lnk)); $href = preg_replace("/\?page=\d+\&/", "?", preg_replace("/\&page=\d+/", "", $lnk));
$href .= strstr($href, "?") ? "&page=$page" : "?page=$page"; $href .= strstr($href, "?") ? "&page=$page" : "?page=$page";
return "<a href=\"" . htmlspecialchars($href) . "\" class=\"pagelink\">$title</a>"; return "<a href=\"" . htmlspecialchars($href) . "\" class=\"pagelink\">$title</a>";
} }
@ -47,7 +49,8 @@ function generate_pagination_link($page, $title) {
* @param string $alt Value of an 'alt' atribute of the image tag. * @param string $alt Value of an 'alt' atribute of the image tag.
* @return string HTML markup * @return string HTML markup
*/ */
function generate_pagination_image($style_path, $id, $alt) { function generate_pagination_image($style_path, $id, $alt)
{
return "<img src=\"" . $style_path . "/images/$id.gif\" border=\"0\" alt=\"" . htmlspecialchars($alt) . "\"/>"; return "<img src=\"" . $style_path . "/images/$id.gif\" border=\"0\" alt=\"" . htmlspecialchars($alt) . "\"/>";
} }
@ -65,15 +68,16 @@ function generate_pagination_image($style_path, $id, $alt) {
* - start: int, index of item to start from. * - start: int, index of item to start from.
* - end: int, index of item to end at. * - end: int, index of item to end at.
*/ */
function pagination_info($items_count, $default_items_per_page = 15) { function pagination_info($items_count, $default_items_per_page = 15)
{
if ($items_count) { if ($items_count) {
$items_per_page = verifyparam("items", "/^\d{1,3}$/", $default_items_per_page); $items_per_page = verify_param("items", "/^\d{1,3}$/", $default_items_per_page);
if ($items_per_page < 2) { if ($items_per_page < 2) {
$items_per_page = 2; $items_per_page = 2;
} }
$total_pages = div($items_count + $items_per_page - 1, $items_per_page); $total_pages = div($items_count + $items_per_page - 1, $items_per_page);
$curr_page = verifyparam("page", "/^\d{1,6}$/", 1); $curr_page = verify_param("page", "/^\d{1,6}$/", 1);
if ($curr_page < 1) { if ($curr_page < 1) {
$curr_page = 1; $curr_page = 1;
@ -108,7 +112,8 @@ function pagination_info($items_count, $default_items_per_page = 15) {
* pagination_info function for details. * pagination_info function for details.
* - items: slice of items to display. * - items: slice of items to display.
*/ */
function setup_pagination($items, $default_items_per_page = 15) { function setup_pagination($items, $default_items_per_page = 15)
{
if (count($items) > 0) { if (count($items) > 0) {
$info = pagination_info(count($items), $default_items_per_page); $info = pagination_info(count($items), $default_items_per_page);
if ($info) { if ($info) {
@ -117,6 +122,7 @@ function setup_pagination($items, $default_items_per_page = 15) {
$info['start'], $info['start'],
$info['end'] - $info['start'] $info['end'] - $info['start']
); );
return array( return array(
'info' => $info, 'info' => $info,
'items' => $items_slice, 'items' => $items_slice,
@ -140,7 +146,8 @@ function setup_pagination($items, $default_items_per_page = 15) {
* page. * page.
* @return string HTML markup * @return string HTML markup
*/ */
function generate_pagination($style_path, $pagination, $bottom = true) { function generate_pagination($style_path, $pagination, $bottom = true)
{
$result = getlocal2( $result = getlocal2(
"tag.pagination.info", "tag.pagination.info",
array( array(
@ -148,7 +155,7 @@ function generate_pagination($style_path, $pagination, $bottom = true) {
$pagination['total'], $pagination['total'],
$pagination['start'] + 1, $pagination['start'] + 1,
$pagination['end'], $pagination['end'],
$pagination['count'] $pagination['count'],
) )
) . "<br/>"; ) . "<br/>";
@ -161,8 +168,8 @@ function generate_pagination($style_path, $pagination, $bottom = true) {
$result .= "<div class='pagination'>"; $result .= "<div class='pagination'>";
$curr_page = $pagination['page']; $curr_page = $pagination['page'];
$minPage = max($curr_page - PAGINATION_LINKS_ON_PAGE, 1); $min_page = max($curr_page - PAGINATION_LINKS_ON_PAGE, 1);
$maxPage = min($curr_page + PAGINATION_LINKS_ON_PAGE, $pagination['total']); $max_page = min($curr_page + PAGINATION_LINKS_ON_PAGE, $pagination['total']);
if ($curr_page > 1) { if ($curr_page > 1) {
$result .= generate_pagination_link( $result .= generate_pagination_link(
@ -175,15 +182,17 @@ function generate_pagination($style_path, $pagination, $bottom = true) {
) . PAGINATION_SPACING; ) . PAGINATION_SPACING;
} }
for ($i = $minPage; $i <= $maxPage; $i++) { for ($i = $min_page; $i <= $max_page; $i++) {
$title = abs($curr_page - $i) >= PAGINATION_LINKS_ON_PAGE && $i != 1 ? "..." : $i; $title = (abs($curr_page - $i) >= PAGINATION_LINKS_ON_PAGE && $i != 1) ? "..." : $i;
if ($i != $curr_page) if ($i != $curr_page) {
$result .= generate_pagination_link($i, $title); $result .= generate_pagination_link($i, $title);
else } else {
$result .= "<span class=\"pagecurrent\">$title</span>"; $result .= "<span class=\"pagecurrent\">$title</span>";
if ($i < $maxPage) }
if ($i < $max_page) {
$result .= PAGINATION_SPACING; $result .= PAGINATION_SPACING;
} }
}
if ($curr_page < $pagination['total']) { if ($curr_page < $pagination['total']) {
$result .= PAGINATION_SPACING . generate_pagination_link( $result .= PAGINATION_SPACING . generate_pagination_link(
@ -197,7 +206,6 @@ function generate_pagination($style_path, $pagination, $bottom = true) {
} }
$result .= "</div>"; $result .= "</div>";
} }
return $result; return $result;
} }
?>

View File

@ -25,20 +25,31 @@ use Mibew\Settings;
* @param int $active Number of the active tab. The count starts from 0. * @param int $active Number of the active tab. The count starts from 0.
* @return array Tabs list * @return array Tabs list
*/ */
function setup_settings_tabs($active) { function setup_settings_tabs($active)
{
$tabs = array( $tabs = array(
getlocal("page_settings.tab.main") => $active != 0 ? (MIBEW_WEB_ROOT . "/operator/settings.php") : "", getlocal("page_settings.tab.main") => ($active != 0
getlocal("page_settings.tab.features") => $active != 1 ? (MIBEW_WEB_ROOT . "/operator/features.php") : "", ? (MIBEW_WEB_ROOT . "/operator/settings.php")
getlocal("page_settings.tab.performance") => $active != 2 ? (MIBEW_WEB_ROOT . "/operator/performance.php") : "", : ""),
getlocal("page_settings.tab.page_themes") => $active != 3 ? (MIBEW_WEB_ROOT . "/operator/page_themes.php") : "", getlocal("page_settings.tab.features") => ($active != 1
getlocal("page_settings.tab.themes") => $active != 4 ? (MIBEW_WEB_ROOT . "/operator/themes.php") : "", ? (MIBEW_WEB_ROOT . "/operator/features.php")
: ""),
getlocal("page_settings.tab.performance") => ($active != 2
? (MIBEW_WEB_ROOT . "/operator/performance.php")
: ""),
getlocal("page_settings.tab.page_themes") => ($active != 3
? (MIBEW_WEB_ROOT . "/operator/page_themes.php")
: ""),
getlocal("page_settings.tab.themes") => ($active != 4
? (MIBEW_WEB_ROOT . "/operator/themes.php")
: ""),
); );
if (Settings::get('enabletracking')) { if (Settings::get('enabletracking')) {
$tabs[getlocal("page_settings.tab.invitationthemes")] = ($active != 5 ? (MIBEW_WEB_ROOT . "/operator/invitationthemes.php") : ""); $tabs[getlocal("page_settings.tab.invitationthemes")] = ($active != 5
? (MIBEW_WEB_ROOT . "/operator/invitationthemes.php")
: "");
} }
return $tabs; return $tabs;
} }
?>

View File

@ -29,6 +29,7 @@ function get_statistics_query($type)
$query = preg_replace("/(\?|\&)type=\w+/", "", $query); $query = preg_replace("/(\?|\&)type=\w+/", "", $query);
} }
$query .= strstr($query, "?") ? "&type=$type" : "?type=$type"; $query .= strstr($query, "?") ? "&type=$type" : "?type=$type";
return $query; return $query;
} }
@ -39,14 +40,21 @@ function get_statistics_query($type)
* @param int $active Number of the active tab. The count starts from 0. * @param int $active Number of the active tab. The count starts from 0.
* @return array Tabs list * @return array Tabs list
*/ */
function setup_statistics_tabs($active) { function setup_statistics_tabs($active)
{
$tabs = array( $tabs = array(
getlocal("report.bydate.title") => $active != 0 ? (MIBEW_WEB_ROOT . "/operator/statistics.php".get_statistics_query('bydate')) : "", getlocal("report.bydate.title") => ($active != 0
getlocal("report.byoperator.title") => $active != 1 ? (MIBEW_WEB_ROOT . "/operator/statistics.php".get_statistics_query('byagent')) : "" ? (MIBEW_WEB_ROOT . "/operator/statistics.php" . get_statistics_query('bydate'))
: ""),
getlocal("report.byoperator.title") => ($active != 1
? (MIBEW_WEB_ROOT . "/operator/statistics.php" . get_statistics_query('byagent'))
: "")
); );
if (Settings::get('enabletracking')) { if (Settings::get('enabletracking')) {
$tabs[getlocal("report.bypage.title")] = ($active != 2 ? (MIBEW_WEB_ROOT . "/operator/statistics.php".get_statistics_query('bypage')) : ""); $tabs[getlocal("report.bypage.title")] = ($active != 2
? (MIBEW_WEB_ROOT . "/operator/statistics.php" . get_statistics_query('bypage'))
: "");
} }
return $tabs; return $tabs;
@ -55,7 +63,8 @@ function setup_statistics_tabs($active) {
/** /**
* Calculate aggregated 'by thread' statistics * Calculate aggregated 'by thread' statistics
*/ */
function calculate_thread_statistics() { function calculate_thread_statistics()
{
// Prepare database // Prepare database
$db = Database::getInstance(); $db = Database::getInstance();
$db_throw_exceptions = $db->throwExeptions(true); $db_throw_exceptions = $db->throwExeptions(true);
@ -79,40 +88,40 @@ function calculate_thread_statistics() {
// Calculate statistics // Calculate statistics
// Get base threads info // Get base threads info
$db_results = $db->query( $db_results = $db->query(
"SELECT (FLOOR(t.dtmcreated / :interval) * :interval) AS date, " . ("SELECT (FLOOR(t.dtmcreated / :interval) * :interval) AS date, "
"COUNT(t.threadid) AS threads, " . . "COUNT(t.threadid) AS threads, "
"SUM(tmp.operator_msgs) AS operator_msgs, " . . "SUM(tmp.operator_msgs) AS operator_msgs, "
"SUM(tmp.user_msgs) AS user_msgs, " . . "SUM(tmp.user_msgs) AS user_msgs, "
// Prevent negative values of avgchattime field. // Prevent negative values of avgchattime field.
// If avgchattime < 0 it becomes to zero. // If avgchattime < 0 it becomes to zero.
// For random value 'a' result of expression ((abs(a) + a) / 2) // For random value 'a' result of expression ((abs(a) + a) / 2)
// equals to 'a' if 'a' more than zero // equals to 'a' if 'a' more than zero
// and equals to zero otherwise // and equals to zero otherwise
"ROUND(AVG( " . . "ROUND(AVG( "
"ABS(tmp.last_msg_time - t.dtmchatstarted) + " . . "ABS(tmp.last_msg_time - t.dtmchatstarted) + "
"(tmp.last_msg_time - t.dtmchatstarted) " . . "(tmp.last_msg_time - t.dtmchatstarted) "
")/2,1) as avg_chat_time " . . ")/2,1) AS avg_chat_time "
"FROM {chatthread} t, " . . "FROM {chatthread} t, "
"(SELECT SUM(m.ikind = :kind_agent) AS operator_msgs, " . . "(SELECT SUM(m.ikind = :kind_agent) AS operator_msgs, "
"SUM(m.ikind = :kind_user) AS user_msgs, " . . "SUM(m.ikind = :kind_user) AS user_msgs, "
"MAX(m.dtmcreated) as last_msg_time, " . . "MAX(m.dtmcreated) as last_msg_time, "
"threadid " . . "threadid "
"FROM {chatmessage} m " . . "FROM {chatmessage} m "
// Calculate only users' and operators' messages // Calculate only users' and operators' messages
"WHERE m.ikind = :kind_user " . . "WHERE m.ikind = :kind_user "
"OR m.ikind = :kind_agent " . . "OR m.ikind = :kind_agent "
"GROUP BY m.threadid) tmp " . . "GROUP BY m.threadid) tmp "
"WHERE t.threadid = tmp.threadid " . . "WHERE t.threadid = tmp.threadid "
"AND (t.dtmcreated - :start) > :interval " . . "AND (t.dtmcreated - :start) > :interval "
// Calculate statistics only for threads that older than // Calculate statistics only for threads that older than
// statistics_aggregation_interval // statistics_aggregation_interval
"AND (:today - t.dtmcreated) > :interval " . . "AND (:today - t.dtmcreated) > :interval "
// Ignore threads when operator does not start chat // Ignore threads when operator does not start chat
"AND t.dtmchatstarted <> 0 " . . "AND t.dtmchatstarted <> 0 "
// Ignore not accepted invitations // Ignore not accepted invitations
"AND (t.invitationstate = :not_invited " . . "AND (t.invitationstate = :not_invited "
"OR t.invitationstate = :invitation_accepted) " . . "OR t.invitationstate = :invitation_accepted) "
"GROUP BY date", . "GROUP BY date"),
array( array(
':start' => $start, ':start' => $start,
':today' => $today, ':today' => $today,
@ -120,7 +129,7 @@ function calculate_thread_statistics() {
':not_invited' => Thread::INVITATION_NOT_INVITED, ':not_invited' => Thread::INVITATION_NOT_INVITED,
':invitation_accepted' => Thread::INVITATION_ACCEPTED, ':invitation_accepted' => Thread::INVITATION_ACCEPTED,
':kind_agent' => Thread::KIND_AGENT, ':kind_agent' => Thread::KIND_AGENT,
':kind_user' => Thread::KIND_USER ':kind_user' => Thread::KIND_USER,
), ),
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
@ -134,23 +143,23 @@ function calculate_thread_statistics() {
// Get info about missed threads // Get info about missed threads
$db_results = $db->query( $db_results = $db->query(
"SELECT (FLOOR(dtmcreated / :interval) * :interval) AS date, " . ("SELECT (FLOOR(dtmcreated / :interval) * :interval) AS date, "
"COUNT(*) as missed_threads " . . "COUNT(*) as missed_threads "
"FROM {chatthread} " . . "FROM {chatthread} "
"WHERE (dtmcreated - :start) > :interval " . . "WHERE (dtmcreated - :start) > :interval "
// Calculate statistics only for threads that older than // Calculate statistics only for threads that older than
// statistics_aggregation_interval // statistics_aggregation_interval
"AND (:today - dtmcreated) > :interval " . . "AND (:today - dtmcreated) > :interval "
// Ignore threads when operator does not start chat // Ignore threads when operator does not start chat
"AND dtmchatstarted = 0 " . . "AND dtmchatstarted = 0 "
// Ignore not accepted invitations // Ignore not accepted invitations
"AND invitationstate = :not_invited " . . "AND invitationstate = :not_invited "
"GROUP BY date ORDER BY date DESC", . "GROUP BY date ORDER BY date DESC"),
array( array(
':start' => $start, ':start' => $start,
':today' => $today, ':today' => $today,
':interval' => $interval, ':interval' => $interval,
':not_invited' => Thread::INVITATION_NOT_INVITED ':not_invited' => Thread::INVITATION_NOT_INVITED,
), ),
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
@ -164,23 +173,23 @@ function calculate_thread_statistics() {
// Get info about average waiting time. // Get info about average waiting time.
$db_results = $db->query( $db_results = $db->query(
"SELECT (FLOOR(dtmcreated / :interval) * :interval) AS date, " . ("SELECT (FLOOR(dtmcreated / :interval) * :interval) AS date, "
"ROUND(AVG(dtmchatstarted-dtmcreated),1) AS avg_waiting_time " . . "ROUND(AVG(dtmchatstarted-dtmcreated),1) AS avg_waiting_time "
"FROM {chatthread} " . . "FROM {chatthread} "
"WHERE (dtmcreated - :start) > :interval " . . "WHERE (dtmcreated - :start) > :interval "
// Calculate statistics only for threads that older than // Calculate statistics only for threads that older than
// statistics_aggregation_interval // statistics_aggregation_interval
"AND (:today - dtmcreated) > :interval " . . "AND (:today - dtmcreated) > :interval "
// Ignore threads when operator does not start chat // Ignore threads when operator does not start chat
"AND dtmchatstarted <> 0 " . . "AND dtmchatstarted <> 0 "
// Ignore all invitations // Ignore all invitations
"AND invitationstate = :not_invited " . . "AND invitationstate = :not_invited "
"GROUP BY date", . "GROUP BY date"),
array( array(
':start' => $start, ':start' => $start,
':today' => $today, ':today' => $today,
':interval' => $interval, ':interval' => $interval,
':not_invited' => Thread::INVITATION_NOT_INVITED ':not_invited' => Thread::INVITATION_NOT_INVITED,
), ),
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
@ -194,27 +203,27 @@ function calculate_thread_statistics() {
// Get invitation info // Get invitation info
$db_results = $db->query( $db_results = $db->query(
"SELECT (FLOOR(dtmcreated / :interval) * :interval) AS date, " . ("SELECT (FLOOR(dtmcreated / :interval) * :interval) AS date, "
"COUNT(*) AS invitations_sent, " . . "COUNT(*) AS invitations_sent, "
"SUM(invitationstate = :invitation_accepted) AS invitations_accepted, " . . "SUM(invitationstate = :invitation_accepted) AS invitations_accepted, "
"SUM(invitationstate = :invitation_rejected) AS invitations_rejected, " . . "SUM(invitationstate = :invitation_rejected) AS invitations_rejected, "
"SUM(invitationstate = :invitation_ignored) AS invitations_ignored " . . "SUM(invitationstate = :invitation_ignored) AS invitations_ignored "
"FROM {chatthread} " . . "FROM {chatthread} "
"WHERE (dtmcreated - :start) > :interval " . . "WHERE (dtmcreated - :start) > :interval "
// Calculate statistics only for threads that older than // Calculate statistics only for threads that older than
// statistics_aggregation_interval // statistics_aggregation_interval
"AND (:today - dtmcreated) > :interval " . . "AND (:today - dtmcreated) > :interval "
"AND (invitationstate = :invitation_accepted " . . "AND (invitationstate = :invitation_accepted "
"OR invitationstate = :invitation_rejected " . . "OR invitationstate = :invitation_rejected "
"OR invitationstate = :invitation_ignored) " . . "OR invitationstate = :invitation_ignored) "
"GROUP BY date", . "GROUP BY date"),
array( array(
':start' => $start, ':start' => $start,
':today' => $today, ':today' => $today,
':interval' => $interval, ':interval' => $interval,
':invitation_accepted' => Thread::INVITATION_ACCEPTED, ':invitation_accepted' => Thread::INVITATION_ACCEPTED,
':invitation_rejected' => Thread::INVITATION_REJECTED, ':invitation_rejected' => Thread::INVITATION_REJECTED,
':invitation_ignored' => Thread::INVITATION_IGNORED ':invitation_ignored' => Thread::INVITATION_IGNORED,
), ),
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
@ -241,7 +250,7 @@ function calculate_thread_statistics() {
'invitations_sent' => 0, 'invitations_sent' => 0,
'invitations_accepted' => 0, 'invitations_accepted' => 0,
'invitations_rejected' => 0, 'invitations_rejected' => 0,
'invitations_ignored' => 0 'invitations_ignored' => 0,
); );
// Prepare data for insert // Prepare data for insert
@ -252,17 +261,17 @@ function calculate_thread_statistics() {
// Store data in database // Store data in database
$db->query( $db->query(
"INSERT INTO {chatthreadstatistics} (" . ("INSERT INTO {chatthreadstatistics} ("
"date, threads, missedthreads, sentinvitations, " . . "date, threads, missedthreads, sentinvitations, "
"acceptedinvitations, rejectedinvitations, " . . "acceptedinvitations, rejectedinvitations, "
"ignoredinvitations, operatormessages, usermessages, " . . "ignoredinvitations, operatormessages, usermessages, "
"averagewaitingtime, averagechattime " . . "averagewaitingtime, averagechattime "
") VALUES (" . . ") VALUES ("
":date, :threads, :missed_threads, :invitations_sent, " . . ":date, :threads, :missed_threads, :invitations_sent, "
":invitations_accepted, :invitations_rejected, " . . ":invitations_accepted, :invitations_rejected, "
":invitations_ignored, :operator_msgs, :user_msgs, " . . ":invitations_ignored, :operator_msgs, :user_msgs, "
":avg_waiting_time, :avg_chat_time " . . ":avg_waiting_time, :avg_chat_time "
")", . ")"),
$insert_data $insert_data
); );
} }
@ -276,6 +285,7 @@ function calculate_thread_statistics() {
// Set throw exceptions back // Set throw exceptions back
$db->throwExeptions($db_throw_exceptions); $db->throwExeptions($db_throw_exceptions);
return; return;
} }
@ -289,7 +299,8 @@ function calculate_thread_statistics() {
/** /**
* Calculate aggregated 'by operator' statistics * Calculate aggregated 'by operator' statistics
*/ */
function calculate_operator_statistics() { function calculate_operator_statistics()
{
// Prepare database // Prepare database
$db = Database::getInstance(); $db = Database::getInstance();
$db_throw_exceptions = $db->throwExeptions(true); $db_throw_exceptions = $db->throwExeptions(true);
@ -313,32 +324,32 @@ function calculate_operator_statistics() {
// Caclculate statistics // Caclculate statistics
// Get base operator's info // Get base operator's info
$db_results = $db->query( $db_results = $db->query(
"SELECT (FLOOR(m.dtmcreated / :interval) * :interval) AS date, " . ("SELECT (FLOOR(m.dtmcreated / :interval) * :interval) AS date, "
"m.agentId AS operator_id, " . . "m.agentId AS operator_id, "
"COUNT(distinct m.threadid) AS threads, " . . "COUNT(distinct m.threadid) AS threads, "
"COUNT(m.messageid) AS messages, " . . "COUNT(m.messageid) AS messages, "
"AVG(CHAR_LENGTH(m.tmessage)) AS avg_msg_length " . . "AVG(CHAR_LENGTH(m.tmessage)) AS avg_msg_length "
// Use {chatmessage} as base table because of one thread can // Use {chatmessage} as base table because of one thread can
// be related with more than one operator (they can change each // be related with more than one operator (they can change each
// other during conversation). // other during conversation).
"FROM {chatmessage} m, {chatthread} t " . . "FROM {chatmessage} m, {chatthread} t "
"WHERE m.ikind = :kind_agent " . . "WHERE m.ikind = :kind_agent "
"AND m.threadid = t.threadid " . . "AND m.threadid = t.threadid "
"AND (m.dtmcreated - :start) > :interval " . . "AND (m.dtmcreated - :start) > :interval "
// Calculate statistics only for messages that older // Calculate statistics only for messages that older
// statistics_aggregation_interval // statistics_aggregation_interval
"AND (:today - m.dtmcreated) > :interval " . . "AND (:today - m.dtmcreated) > :interval "
// Ignore not accepted invitations // Ignore not accepted invitations
"AND (t.invitationstate = :not_invited " . . "AND (t.invitationstate = :not_invited "
"OR t.invitationstate = :invitation_accepted) " . . "OR t.invitationstate = :invitation_accepted) "
"GROUP BY date, operator_id", . "GROUP BY date, operator_id"),
array( array(
':start' => $start, ':start' => $start,
':today' => $today, ':today' => $today,
':interval' => $interval, ':interval' => $interval,
':not_invited' => Thread::INVITATION_NOT_INVITED, ':not_invited' => Thread::INVITATION_NOT_INVITED,
':invitation_accepted' => Thread::INVITATION_ACCEPTED, ':invitation_accepted' => Thread::INVITATION_ACCEPTED,
':kind_agent' => Thread::KIND_AGENT ':kind_agent' => Thread::KIND_AGENT,
), ),
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
@ -352,31 +363,31 @@ function calculate_operator_statistics() {
// Get info about invitations // Get info about invitations
$db_results = $db->query( $db_results = $db->query(
"SELECT (FLOOR(dtmcreated / :interval) * :interval) AS date, " . ("SELECT (FLOOR(dtmcreated / :interval) * :interval) AS date, "
"agentId as operator_id, " . . "agentId AS operator_id, "
"COUNT(threadid) AS invitations_sent, " . . "COUNT(threadid) AS invitations_sent, "
"SUM(invitationstate = :invitation_accepted) AS invitations_accepted, " . . "SUM(invitationstate = :invitation_accepted) AS invitations_accepted, "
"SUM(invitationstate = :invitation_rejected) AS invitations_rejected, " . . "SUM(invitationstate = :invitation_rejected) AS invitations_rejected, "
"SUM(invitationstate = :invitation_ignored) AS invitations_ignored " . . "SUM(invitationstate = :invitation_ignored) AS invitations_ignored "
"FROM {chatthread} " . . "FROM {chatthread} "
"WHERE (dtmcreated - :start) > :interval " . . "WHERE (dtmcreated - :start) > :interval "
// Calculate statistics only for threads that older than // Calculate statistics only for threads that older than
// statistics_aggregation_interval // statistics_aggregation_interval
"AND (:today - dtmcreated) > :interval " . . "AND (:today - dtmcreated) > :interval "
// Check if thread has related operator // Check if thread has related operator
"AND agentId != 0 " . . "AND agentId != 0 "
// Ignore not accepted invitations // Ignore not accepted invitations
"AND (invitationstate = :invitation_accepted " . . "AND (invitationstate = :invitation_accepted "
"OR invitationstate = :invitation_rejected " . . "OR invitationstate = :invitation_rejected "
"OR invitationstate = :invitation_ignored) " . . "OR invitationstate = :invitation_ignored) "
"GROUP BY date, operator_id", . "GROUP BY date, operator_id"),
array( array(
':start' => $start, ':start' => $start,
':today' => $today, ':today' => $today,
':interval' => $interval, ':interval' => $interval,
':invitation_accepted' => Thread::INVITATION_ACCEPTED, ':invitation_accepted' => Thread::INVITATION_ACCEPTED,
':invitation_rejected' => Thread::INVITATION_REJECTED, ':invitation_rejected' => Thread::INVITATION_REJECTED,
':invitation_ignored' => Thread::INVITATION_IGNORED ':invitation_ignored' => Thread::INVITATION_IGNORED,
), ),
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
@ -400,7 +411,7 @@ function calculate_operator_statistics() {
'invitations_sent' => 0, 'invitations_sent' => 0,
'invitations_accepted' => 0, 'invitations_accepted' => 0,
'invitations_rejected' => 0, 'invitations_rejected' => 0,
'invitations_ignored' => 0 'invitations_ignored' => 0,
); );
// Prepare data for insert // Prepare data for insert
@ -410,16 +421,16 @@ function calculate_operator_statistics() {
} }
$db->query( $db->query(
"INSERT INTO {chatoperatorstatistics} (" . ("INSERT INTO {chatoperatorstatistics} ("
"date, operatorid, threads, messages, averagelength, " . . "date, operatorid, threads, messages, averagelength, "
"sentinvitations, acceptedinvitations, " . . "sentinvitations, acceptedinvitations, "
"rejectedinvitations, ignoredinvitations " . . "rejectedinvitations, ignoredinvitations "
") VALUES (". . ") VALUES ("
":date, :operator_id, :threads, :messages, " . . ":date, :operator_id, :threads, :messages, "
":avg_msg_length, :invitations_sent, " . . ":avg_msg_length, :invitations_sent, "
":invitations_accepted, :invitations_rejected, " . . ":invitations_accepted, :invitations_rejected, "
":invitations_ignored " . . ":invitations_ignored "
")", . ")"),
$insert_data $insert_data
); );
} }
@ -433,6 +444,7 @@ function calculate_operator_statistics() {
// Set throw exceptions back // Set throw exceptions back
$db->throwExeptions($db_throw_exceptions); $db->throwExeptions($db_throw_exceptions);
return; return;
} }
@ -446,7 +458,8 @@ function calculate_operator_statistics() {
/** /**
* Calculate aggregated 'by page' statistics * Calculate aggregated 'by page' statistics
*/ */
function calculate_page_statistics() { function calculate_page_statistics()
{
// Prepare database // Prepare database
$db = Database::getInstance(); $db = Database::getInstance();
$db_throw_exceptions = $db->throwExeptions(true); $db_throw_exceptions = $db->throwExeptions(true);
@ -472,18 +485,18 @@ function calculate_page_statistics() {
// Calculate statistics // Calculate statistics
// Get main pages info // Get main pages info
$db_results = $db->query( $db_results = $db->query(
"SELECT FLOOR(visittime / :interval) * :interval AS date, " . ("SELECT FLOOR(visittime / :interval) * :interval AS date, "
"address, " . . "address, "
"COUNT(DISTINCT pageid) AS visits " . . "COUNT(DISTINCT pageid) AS visits "
"FROM {visitedpage} ". . "FROM {visitedpage} "
"WHERE calculated = 0 " . . "WHERE calculated = 0 "
"AND (visittime - :start) > :interval " . . "AND (visittime - :start) > :interval "
"AND (:today - visittime) > :interval " . . "AND (:today - visittime) > :interval "
"GROUP BY date, address", . "GROUP BY date, address"),
array( array(
':start' => $start, ':start' => $start,
':today' => $today, ':today' => $today,
':interval' => $interval ':interval' => $interval,
), ),
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
@ -497,28 +510,28 @@ function calculate_page_statistics() {
// Get total chats count // Get total chats count
$db_results = $db->query( $db_results = $db->query(
"SELECT FLOOR(p.visittime / :interval) * :interval AS date, " . ("SELECT FLOOR(p.visittime / :interval) * :interval AS date, "
"p.address AS address, " . . "p.address AS address, "
"COUNT(DISTINCT t.threadid) AS chats " . . "COUNT(DISTINCT t.threadid) AS chats "
"FROM {visitedpage} p, {chatthread} t, " . . "FROM {visitedpage} p, {chatthread} t, "
"(SELECT " . . "(SELECT "
"COUNT(*) AS msgs, " . . "COUNT(*) AS msgs, "
"m.threadid " . . "m.threadid "
"FROM {chatmessage} m " . . "FROM {chatmessage} m "
"WHERE m.ikind = :kind_user OR m.ikind = :kind_agent " . . "WHERE m.ikind = :kind_user OR m.ikind = :kind_agent "
"GROUP BY m.threadid) tmp " . . "GROUP BY m.threadid) tmp "
"WHERE t.referer = p.address " . . "WHERE t.referer = p.address "
"AND p.calculated = 0 " . . "AND p.calculated = 0 "
"AND t.threadid = tmp.threadid " . . "AND t.threadid = tmp.threadid "
"AND tmp.msgs > 0 " . . "AND tmp.msgs > 0 "
"AND t.dtmchatstarted <> 0 " . . "AND t.dtmchatstarted <> 0 "
"AND (p.visittime - :start) > :interval " . . "AND (p.visittime - :start) > :interval "
"AND (:today - p.visittime) > :interval " . . "AND (:today - p.visittime) > :interval "
"AND DATE(FROM_UNIXTIME(p.visittime)) " . . "AND DATE(FROM_UNIXTIME(p.visittime)) "
"= DATE(FROM_UNIXTIME(t.dtmcreated)) " . . "= DATE(FROM_UNIXTIME(t.dtmcreated)) "
"AND (t.invitationstate = :not_invited " . . "AND (t.invitationstate = :not_invited "
"OR t.invitationstate = :invitation_accepted) " . . "OR t.invitationstate = :invitation_accepted) "
"GROUP BY date, address", . "GROUP BY date, address"),
array( array(
':start' => $start, ':start' => $start,
':today' => $today, ':today' => $today,
@ -526,7 +539,7 @@ function calculate_page_statistics() {
':not_invited' => Thread::INVITATION_NOT_INVITED, ':not_invited' => Thread::INVITATION_NOT_INVITED,
':invitation_accepted' => Thread::INVITATION_ACCEPTED, ':invitation_accepted' => Thread::INVITATION_ACCEPTED,
':kind_agent' => Thread::KIND_AGENT, ':kind_agent' => Thread::KIND_AGENT,
':kind_user' => Thread::KIND_USER ':kind_user' => Thread::KIND_USER,
), ),
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
@ -540,23 +553,23 @@ function calculate_page_statistics() {
// Get info about accepted invitations // Get info about accepted invitations
$db_results = $db->query( $db_results = $db->query(
"SELECT FLOOR(p.visittime / :interval) * :interval AS date, " . ("SELECT FLOOR(p.visittime / :interval) * :interval AS date, "
"p.address AS address, " . . "p.address AS address, "
"COUNT(DISTINCT t.threadid) AS invitations_accepted " . . "COUNT(DISTINCT t.threadid) AS invitations_accepted "
"FROM {visitedpage} p, {chatthread} t " . . "FROM {visitedpage} p, {chatthread} t "
"WHERE t.referer = p.address " . . "WHERE t.referer = p.address "
"AND p.calculated = 0 " . . "AND p.calculated = 0 "
"AND (p.visittime - :start) > :interval " . . "AND (p.visittime - :start) > :interval "
"AND (:today - p.visittime) > :interval " . . "AND (:today - p.visittime) > :interval "
"AND DATE(FROM_UNIXTIME(p.visittime)) " . . "AND DATE(FROM_UNIXTIME(p.visittime)) "
"= DATE(FROM_UNIXTIME(t.dtmcreated)) " . . "= DATE(FROM_UNIXTIME(t.dtmcreated)) "
"AND t.invitationstate = :invitation_accepted " . . "AND t.invitationstate = :invitation_accepted "
"GROUP BY date, address", . "GROUP BY date, address"),
array( array(
':start' => $start, ':start' => $start,
':today' => $today, ':today' => $today,
':interval' => $interval, ':interval' => $interval,
':invitation_accepted' => Thread::INVITATION_ACCEPTED ':invitation_accepted' => Thread::INVITATION_ACCEPTED,
), ),
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
@ -570,23 +583,23 @@ function calculate_page_statistics() {
// Get info about rejected invitations // Get info about rejected invitations
$db_results = $db->query( $db_results = $db->query(
"SELECT FLOOR(p.visittime / :interval) * :interval AS date, " . ("SELECT FLOOR(p.visittime / :interval) * :interval AS date, "
"p.address AS address, " . . "p.address AS address, "
"COUNT(DISTINCT t.threadid) AS invitations_rejected " . . "COUNT(DISTINCT t.threadid) AS invitations_rejected "
"FROM {visitedpage} p, {chatthread} t " . . "FROM {visitedpage} p, {chatthread} t "
"WHERE t.referer = p.address " . . "WHERE t.referer = p.address "
"AND p.calculated = 0 " . . "AND p.calculated = 0 "
"AND (p.visittime - :start) > :interval " . . "AND (p.visittime - :start) > :interval "
"AND (:today - p.visittime) > :interval " . . "AND (:today - p.visittime) > :interval "
"AND DATE(FROM_UNIXTIME(p.visittime)) " . . "AND DATE(FROM_UNIXTIME(p.visittime)) "
"= DATE(FROM_UNIXTIME(t.dtmcreated)) " . . "= DATE(FROM_UNIXTIME(t.dtmcreated)) "
"AND t.invitationstate = :invitation_rejected " . . "AND t.invitationstate = :invitation_rejected "
"GROUP BY date, address", . "GROUP BY date, address"),
array( array(
':start' => $start, ':start' => $start,
':today' => $today, ':today' => $today,
':interval' => $interval, ':interval' => $interval,
':invitation_rejected' => Thread::INVITATION_REJECTED ':invitation_rejected' => Thread::INVITATION_REJECTED,
), ),
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
@ -600,23 +613,23 @@ function calculate_page_statistics() {
// Get info about ignored invitations // Get info about ignored invitations
$db_results = $db->query( $db_results = $db->query(
"SELECT FLOOR(p.visittime / :interval) * :interval AS date, " . ("SELECT FLOOR(p.visittime / :interval) * :interval AS date, "
"p.address AS address, " . . "p.address AS address, "
"COUNT(DISTINCT t.threadid) AS invitations_ignored " . . "COUNT(DISTINCT t.threadid) AS invitations_ignored "
"FROM {visitedpage} p, {chatthread} t " . . "FROM {visitedpage} p, {chatthread} t "
"WHERE t.referer = p.address " . . "WHERE t.referer = p.address "
"AND p.calculated = 0 " . . "AND p.calculated = 0 "
"AND (p.visittime - :start) > :interval " . . "AND (p.visittime - :start) > :interval "
"AND (:today - p.visittime) > :interval " . . "AND (:today - p.visittime) > :interval "
"AND DATE(FROM_UNIXTIME(p.visittime)) " . . "AND DATE(FROM_UNIXTIME(p.visittime)) "
"= DATE(FROM_UNIXTIME(t.dtmcreated)) " . . "= DATE(FROM_UNIXTIME(t.dtmcreated)) "
"AND t.invitationstate = :invitation_ignored " . . "AND t.invitationstate = :invitation_ignored "
"GROUP BY date, address", . "GROUP BY date, address"),
array( array(
':start' => $start, ':start' => $start,
':today' => $today, ':today' => $today,
':interval' => $interval, ':interval' => $interval,
':invitation_ignored' => Thread::INVITATION_IGNORED ':invitation_ignored' => Thread::INVITATION_IGNORED,
), ),
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
@ -638,7 +651,7 @@ function calculate_page_statistics() {
'chats' => 0, 'chats' => 0,
'invitations_accepted' => 0, 'invitations_accepted' => 0,
'invitations_rejected' => 0, 'invitations_rejected' => 0,
'invitations_ignored' => 0 'invitations_ignored' => 0,
); );
$row['invitations_sent'] = $row['invitations_accepted'] $row['invitations_sent'] = $row['invitations_accepted']
@ -652,27 +665,27 @@ function calculate_page_statistics() {
} }
$db->query( $db->query(
"INSERT INTO {visitedpagestatistics} (" . ("INSERT INTO {visitedpagestatistics} ("
"date, address, visits, chats, " . . "date, address, visits, chats, "
"sentinvitations, acceptedinvitations, " . . "sentinvitations, acceptedinvitations, "
"rejectedinvitations, ignoredinvitations " . . "rejectedinvitations, ignoredinvitations "
") VALUES (". . ") VALUES ("
":date, :address, :visits, :chats, :invitations_sent, " . . ":date, :address, :visits, :chats, :invitations_sent, "
":invitations_accepted, :invitations_rejected, " . . ":invitations_accepted, :invitations_rejected, "
":invitations_ignored " . . ":invitations_ignored "
")", . ")"),
$insert_data $insert_data
); );
} }
// Mark all visited pages as 'calculated' // Mark all visited pages as 'calculated'
$db->query( $db->query(
"UPDATE {visitedpage} SET calculated = 1 " . ("UPDATE {visitedpage} SET calculated = 1 "
"WHERE (:today - visittime) > :interval " . . "WHERE (:today - visittime) > :interval "
"AND calculated = 0", . "AND calculated = 0"),
array( array(
':today' => $today, ':today' => $today,
':interval' => $interval ':interval' => $interval,
) )
); );
@ -688,6 +701,7 @@ function calculate_page_statistics() {
// Set throw exceptions back // Set throw exceptions back
$db->throwExeptions($db_throw_exceptions); $db->throwExeptions($db_throw_exceptions);
return; return;
} }
@ -708,7 +722,8 @@ function calculate_page_statistics() {
* @param array $keys List of keys. * @param array $keys List of keys.
* @return array|boolean Extended statistics info or boolean false on failure * @return array|boolean Extended statistics info or boolean false on failure
*/ */
function extend_statistics_info($stat_info, $additional_info, $keys) { function extend_statistics_info($stat_info, $additional_info, $keys)
{
$result = $stat_info; $result = $stat_info;
foreach ($additional_info as $row) { foreach ($additional_info as $row) {
// Build key field // Build key field
@ -719,6 +734,7 @@ function extend_statistics_info($stat_info, $additional_info, $keys) {
"There is no '{$key}' key in additional_info row!", "There is no '{$key}' key in additional_info row!",
E_USER_WARNING E_USER_WARNING
); );
return false; return false;
} }
$key_field[] = $row[$key]; $key_field[] = $row[$key];
@ -733,7 +749,6 @@ function extend_statistics_info($stat_info, $additional_info, $keys) {
// Extend info // Extend info
$result[$key_field] += $row; $result[$key_field] += $row;
} }
return $result; return $result;
} }
?>

View File

@ -20,27 +20,25 @@ use Mibew\Database;
use Mibew\Settings; use Mibew\Settings;
use Mibew\Thread; use Mibew\Thread;
// Initialize libraries function track_visitor($visitor_id, $entry, $referer)
require_once(MIBEW_FS_ROOT.'/libs/chat.php');
function track_visitor($visitorid, $entry, $referer)
{ {
$visitor = track_get_visitor_by_id($visitorid); $visitor = track_get_visitor_by_id($visitor_id);
if (FALSE === $visitor) { if (false === $visitor) {
$visitor = track_visitor_start($entry, $referer); $visitor = track_visitor_start($entry, $referer);
return $visitor; return $visitor;
} else { } else {
$db = Database::getInstance(); $db = Database::getInstance();
$db->query( $db->query(
"update {chatsitevisitor} set lasttime = :now " . "UPDATE {chatsitevisitor} SET lasttime = :now WHERE visitorid = :visitorid",
"where visitorid = :visitorid",
array( array(
':visitorid' => $visitor['visitorid'], ':visitorid' => $visitor['visitorid'],
':now' => time() ':now' => time(),
) )
); );
track_visit_page($visitor['visitorid'], $referer); track_visit_page($visitor['visitorid'], $referer);
return $visitor['visitorid']; return $visitor['visitorid'];
} }
} }
@ -51,14 +49,17 @@ function track_visitor_start($entry, $referer)
$db = Database::getInstance(); $db = Database::getInstance();
$db->query( $db->query(
"insert into {chatsitevisitor} (userid,username,firsttime,lasttime,entry,details) ". ("INSERT INTO {chatsitevisitor} ( "
"values (:userid, :username, :now, :now, :entry, :details)", . "userid, username, firsttime, lasttime, entry,details "
. ") VALUES ( "
. ":userid, :username, :now, :now, :entry, :details "
. ")"),
array( array(
':userid' => $visitor['id'], ':userid' => $visitor['id'],
':username' => $visitor['name'], ':username' => $visitor['name'],
':now' => time(), ':now' => time(),
':entry' => $entry, ':entry' => $entry,
':details' => track_build_details() ':details' => track_build_details(),
) )
); );
@ -71,22 +72,24 @@ function track_visitor_start($entry, $referer)
return $id ? $id : 0; return $id ? $id : 0;
} }
function track_get_visitor_by_id($visitorid) function track_get_visitor_by_id($visitor_id)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
return $db->query( return $db->query(
"select * from {chatsitevisitor} where visitorid = ?", "SELECT * FROM {chatsitevisitor} WHERE visitorid = ?",
array($visitorid), array($visitor_id),
array('return_rows' => Database::RETURN_ONE_ROW) array('return_rows' => Database::RETURN_ONE_ROW)
); );
} }
function track_get_visitor_by_threadid($threadid) function track_get_visitor_by_thread_id($thread_id)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
return $db->query( return $db->query(
"select * from {chatsitevisitor} where threadid = ?", "SELECT * FROM {chatsitevisitor} WHERE threadid = ?",
array($threadid), array($thread_id),
array('return_rows' => Database::RETURN_ONE_ROW) array('return_rows' => Database::RETURN_ONE_ROW)
); );
} }
@ -97,36 +100,44 @@ function track_get_visitor_by_threadid($threadid)
* @param string $user_id User id * @param string $user_id User id
* @return boolean|array Visitor array or boolean false if visitor not exists * @return boolean|array Visitor array or boolean false if visitor not exists
*/ */
function track_get_visitor_by_user_id($user_id) { function track_get_visitor_by_user_id($user_id)
{
$db = Database::getInstance(); $db = Database::getInstance();
return $db->query( return $db->query(
"select * from {chatsitevisitor} where userid = ?", "SELECT * FROM {chatsitevisitor} WHERE userid = ?",
array($user_id), array($user_id),
array('return_rows' => Database::RETURN_ONE_ROW) array('return_rows' => Database::RETURN_ONE_ROW)
); );
} }
function track_visit_page($visitorid, $page) function track_visit_page($visitor_id, $page)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
if (empty($page)) { if (empty($page)) {
return; return;
} }
$lastpage = $db->query( $last_page = $db->query(
"select address from {visitedpage} where visitorid = ? " . ("SELECT address "
"order by visittime desc limit 1", . "FROM {visitedpage} "
array($visitorid), . "WHERE visitorid = ? "
. "ORDER BY visittime DESC "
. "LIMIT 1"),
array($visitor_id),
array('return_rows' => Database::RETURN_ONE_ROW) array('return_rows' => Database::RETURN_ONE_ROW)
); );
if ( $lastpage['address'] != $page ) { if ($last_page['address'] != $page) {
$db->query( $db->query(
"insert into {visitedpage} (visitorid, address, visittime) " . ("INSERT INTO {visitedpage} ("
"values (:visitorid, :page, :now)", . "visitorid, address, visittime "
. ") VALUES ( "
. ":visitorid, :page, :now "
.")"),
array( array(
':visitorid' => $visitorid, ':visitorid' => $visitor_id,
':page' => $page, ':page' => $page,
':now' => time() ':now' => time(),
) )
); );
} }
@ -136,8 +147,7 @@ function track_get_path($visitor)
{ {
$db = Database::getInstance(); $db = Database::getInstance();
$query_result = $db->query( $query_result = $db->query(
"select address, visittime from {visitedpage} " . "SELECT address, visittime FROM {visitedpage} WHERE visitorid = ?",
"where visitorid = ?",
array($visitor['visitorid']), array($visitor['visitorid']),
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
@ -145,6 +155,7 @@ function track_get_path($visitor)
foreach ($query_result as $page) { foreach ($query_result as $page) {
$result[$page['visittime']] = $page['address']; $result[$page['visittime']] = $page['address'];
} }
return $result; return $result;
} }
@ -152,11 +163,10 @@ function track_build_details()
{ {
$result = array( $result = array(
'user_agent' => $_SERVER['HTTP_USER_AGENT'], 'user_agent' => $_SERVER['HTTP_USER_AGENT'],
'remote_host' => get_remote_host() 'remote_host' => get_remote_host(),
); );
return serialize($result); return serialize($result);
} }
function track_retrieve_details($visitor) function track_retrieve_details($visitor)
@ -167,27 +177,28 @@ function track_retrieve_details($visitor)
/** /**
* Remove old visitors * Remove old visitors
*/ */
function track_remove_old_visitors() { function track_remove_old_visitors()
{
$db = Database::getInstance(); $db = Database::getInstance();
// Remove associations of visitors with closed threads // Remove associations of visitors with closed threads
$db->query( $db->query(
"UPDATE {chatsitevisitor} SET threadid = NULL " . "UPDATE {chatsitevisitor} SET threadid = NULL "
"WHERE threadid IS NOT NULL AND " . . "WHERE threadid IS NOT NULL AND "
" (SELECT count(*) FROM {chatthread} " . . "(SELECT count(*) FROM {chatthread} "
"WHERE threadid = {chatsitevisitor}.threadid" . . "WHERE threadid = {chatsitevisitor}.threadid "
" AND istate <> " . Thread::STATE_CLOSED . " " . . "AND istate <> " . Thread::STATE_CLOSED . " "
" AND istate <> " . Thread::STATE_LEFT . ") = 0" . "AND istate <> " . Thread::STATE_LEFT . ") = 0 "
); );
// Remove old visitors // Remove old visitors
$db->query( $db->query(
"DELETE FROM {chatsitevisitor} " . ("DELETE FROM {chatsitevisitor} "
"WHERE (:now - lasttime) > :lifetime ". . "WHERE (:now - lasttime) > :lifetime "
"AND threadid IS NULL", . "AND threadid IS NULL"),
array( array(
':lifetime' => Settings::get('tracking_lifetime'), ':lifetime' => Settings::get('tracking_lifetime'),
':now' => time() ':now' => time(),
) )
); );
} }
@ -195,19 +206,20 @@ function track_remove_old_visitors() {
/** /**
* Remove old tracks * Remove old tracks
*/ */
function track_remove_old_tracks() { function track_remove_old_tracks()
{
$db = Database::getInstance(); $db = Database::getInstance();
// Remove old visitors' tracks // Remove old visitors' tracks
$db->query( $db->query(
"DELETE FROM {visitedpage} " . ("DELETE FROM {visitedpage} "
"WHERE (:now - visittime) > :lifetime " . . "WHERE (:now - visittime) > :lifetime "
// Remove only tracks that are included in statistics // Remove only tracks that are included in statistics
"AND calculated = 1 " . . "AND calculated = 1 "
"AND visitorid NOT IN (SELECT visitorid FROM {chatsitevisitor}) ", . "AND visitorid NOT IN (SELECT visitorid FROM {chatsitevisitor}) "),
array( array(
':lifetime' => Settings::get('tracking_lifetime'), ':lifetime' => Settings::get('tracking_lifetime'),
':now' => time() ':now' => time(),
) )
); );
} }
@ -215,15 +227,17 @@ function track_remove_old_tracks() {
/** /**
* Return user id by visitor id. * Return user id by visitor id.
* *
* @param int $visitorid Id of the visitor * @param int $visitor_id Id of the visitor
* @return string|boolean user id or boolean false if there is no visitor with * @return string|boolean user id or boolean false if there is no visitor with
* specified visitor id * specified visitor id
*/ */
function track_get_user_id($visitorid) { function track_get_user_id($visitor_id)
$visitor = track_get_visitor_by_id($visitorid); {
$visitor = track_get_visitor_by_id($visitor_id);
if (!$visitor) { if (!$visitor) {
return false; return false;
} }
return $visitor['userid']; return $visitor['userid'];
} }
@ -234,17 +248,16 @@ function track_get_user_id($visitorid) {
* visitor. * visitor.
* @param Thread $thread Chat thread object * @param Thread $thread Chat thread object
*/ */
function track_visitor_bind_thread($user_id, $thread) { function track_visitor_bind_thread($user_id, $thread)
{
$db = Database::getInstance(); $db = Database::getInstance();
$db->query( $db->query(
'UPDATE {chatsitevisitor} ' . ('UPDATE {chatsitevisitor} '
'SET threadid = :thread_id ' . . 'SET threadid = :thread_id '
'WHERE userid = :user_id', . 'WHERE userid = :user_id'),
array( array(
':thread_id' => $thread->id, ':thread_id' => $thread->id,
':user_id' => $user_id ':user_id' => $user_id,
) )
); );
} }
?>

View File

@ -18,50 +18,50 @@
// Import namespaces and classes of the core // Import namespaces and classes of the core
use Mibew\Settings; use Mibew\Settings;
function get_useragent_version($userAgent) function get_user_agent_version($user_agent)
{ {
$known_agents = get_known_user_agents(); $known_agents = get_known_user_agents();
if (is_array($known_agents)) { if (is_array($known_agents)) {
$userAgent = strtolower($userAgent); $user_agent = strtolower($user_agent);
foreach ($known_agents as $agent) { foreach ($known_agents as $agent) {
if (strstr($userAgent, $agent)) { if (strstr($user_agent, $agent)) {
if (preg_match("/" . $agent . "[\\s\/]?(\\d+(\\.\\d+(\\.\\d+(\\.\\d+)?)?)?)/", $userAgent, $matches)) { if (preg_match("/" . $agent . "[\\s\/]?(\\d+(\\.\\d+(\\.\\d+(\\.\\d+)?)?)?)/", $user_agent, $matches)) {
$ver = $matches[1]; $ver = $matches[1];
if ($agent == 'safari') { if ($agent == 'safari') {
if (preg_match("/version\/(\\d+(\\.\\d+(\\.\\d+)?)?)/", $userAgent, $matches)) { if (preg_match("/version\/(\\d+(\\.\\d+(\\.\\d+)?)?)/", $user_agent, $matches)) {
$ver = $matches[1]; $ver = $matches[1];
} else { } else {
$ver = "1 or 2 (build " . $ver . ")"; $ver = "1 or 2 (build " . $ver . ")";
} }
if (preg_match("/mobile\/(\\d+(\\.\\d+(\\.\\d+)?)?)/", $userAgent, $matches)) { if (preg_match("/mobile\/(\\d+(\\.\\d+(\\.\\d+)?)?)/", $user_agent, $matches)) {
$userAgent = "iPhone " . $matches[1] . " ($agent $ver)"; $user_agent = "iPhone " . $matches[1] . " ($agent $ver)";
break; break;
} }
} }
$userAgent = ucfirst($agent) . " " . $ver; $user_agent = ucfirst($agent) . " " . $ver;
break; break;
} }
} }
} }
} }
return $userAgent;
return $user_agent;
} }
function get_user_addr($addr) function get_user_addr($addr)
{ {
if (Settings::get('geolink') && preg_match("/(\\d+\\.\\d+\\.\\d+\\.\\d+)/", $addr, $matches)) { if (Settings::get('geolink') && preg_match("/(\\d+\\.\\d+\\.\\d+\\.\\d+)/", $addr, $matches)) {
$userip = $matches[1]; $user_ip = $matches[1];
return get_popup( return get_popup(
str_replace("{ip}", $userip, Settings::get('geolink')), str_replace("{ip}", $user_ip, Settings::get('geolink')),
'', '',
htmlspecialchars($addr), htmlspecialchars($addr),
"GeoLocation", "GeoLocation",
"ip$userip", "ip$user_ip",
Settings::get('geolinkparams') Settings::get('geolinkparams')
); );
} }
return htmlspecialchars($addr); return htmlspecialchars($addr);
} }
?>

View File

@ -28,5 +28,3 @@ $page['fixedwrap'] = true;
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('license', $page); $page_style->render('license', $page);
?>

View File

@ -25,15 +25,16 @@ require_once(dirname(__FILE__).'/libs/init.php');
require_once(MIBEW_FS_ROOT . '/libs/chat.php'); require_once(MIBEW_FS_ROOT . '/libs/chat.php');
require_once(MIBEW_FS_ROOT . '/libs/groups.php'); require_once(MIBEW_FS_ROOT . '/libs/groups.php');
require_once(MIBEW_FS_ROOT . '/libs/notify.php'); require_once(MIBEW_FS_ROOT . '/libs/notify.php');
require_once(MIBEW_FS_ROOT . '/libs/track.php');
$page = array( $page = array(
'errors' =>array() 'errors' => array(),
); );
$token = verifyparam( "token", "/^\d{1,8}$/"); $token = verify_param("token", "/^\d{1,8}$/");
$threadid = verifyparam( "thread", "/^\d{1,8}$/"); $thread_id = verify_param("thread", "/^\d{1,8}$/");
$thread = Thread::load($threadid, $token); $thread = Thread::load($thread_id, $token);
if (!$thread) { if (!$thread) {
die("wrong thread"); die("wrong thread");
} }
@ -41,9 +42,9 @@ if (! $thread) {
// Initialize chat style which is currently used in system // Initialize chat style which is currently used in system
$chat_style = new ChatStyle(ChatStyle::currentStyle()); $chat_style = new ChatStyle(ChatStyle::currentStyle());
$email = getparam('email'); $email = get_param('email');
$page['email'] = $email; $page['email'] = $email;
$group = is_null($thread->groupId)?NULL:group_by_id($thread->groupId); $group = is_null($thread->groupId) ? null : group_by_id($thread->groupId);
if (!$email) { if (!$email) {
$page['errors'][] = no_field("form.field.email"); $page['errors'][] = no_field("form.field.email");
} elseif (!is_valid_email($email)) { } elseif (!is_valid_email($email)) {
@ -73,16 +74,15 @@ foreach ($messages as $msg) {
$subject = getstring("mail.user.history.subject"); $subject = getstring("mail.user.history.subject");
$body = getstring2( $body = getstring2(
"mail.user.history.body", "mail.user.history.body",
array($thread->userName, $history, Settings::get('title'), Settings::get('hosturl')) array($thread->userName,
$history,
Settings::get('title'),
Settings::get('hosturl')
)
); );
mibew_mail($email, $mibew_mailbox, $subject, $body); mibew_mail($email, $mibew_mailbox, $subject, $body);
$page = array_merge_recursive( $page = array_merge_recursive($page, setup_logo($group));
$page,
setup_logo($group)
);
$chat_style->render('mailsent', $page); $chat_style->render('mailsent', $page);
exit;
?>

View File

@ -28,6 +28,7 @@ require_once(MIBEW_FS_ROOT.'/libs/chat.php');
require_once(MIBEW_FS_ROOT . '/libs/groups.php'); require_once(MIBEW_FS_ROOT . '/libs/groups.php');
require_once(MIBEW_FS_ROOT . '/libs/operator.php'); require_once(MIBEW_FS_ROOT . '/libs/operator.php');
require_once(MIBEW_FS_ROOT . '/libs/pagination.php'); require_once(MIBEW_FS_ROOT . '/libs/pagination.php');
require_once(MIBEW_FS_ROOT . '/libs/track.php');
$operator = check_login(); $operator = check_login();
@ -43,9 +44,9 @@ if (Settings::get('enablessl') == "1" && Settings::get('forcessl') == "1") {
} }
} }
$threadid = verifyparam("thread", "/^\d{1,8}$/"); $thread_id = verify_param("thread", "/^\d{1,8}$/");
$page = array( $page = array(
'errors' => array() 'errors' => array(),
); );
// Initialize chat style which is currently used in system // Initialize chat style which is currently used in system
@ -62,17 +63,17 @@ if (!isset($_GET['token'])) {
exit; exit;
} }
$thread = Thread::load($threadid); $thread = Thread::load($thread_id);
if (!$thread || !isset($thread->lastToken)) { if (!$thread || !isset($thread->lastToken)) {
$page['errors'][] = getlocal("thread.error.wrong_thread"); $page['errors'][] = getlocal("thread.error.wrong_thread");
$chat_style->render('error', $page); $chat_style->render('error', $page);
exit; exit;
} }
$viewonly = verifyparam("viewonly", "/^true$/", false); $view_only = verify_param("viewonly", "/^true$/", false);
$forcetake = verifyparam("force", "/^true$/", false); $force_take = verify_param("force", "/^true$/", false);
if (!$viewonly && $thread->state == Thread::STATE_CHATTING && $operator['operatorid'] != $thread->agentId) { if (!$view_only && $thread->state == Thread::STATE_CHATTING && $operator['operatorid'] != $thread->agentId) {
if (!is_capable(CAN_TAKEOVER, $operator)) { if (!is_capable(CAN_TAKEOVER, $operator)) {
$page['errors'][] = getlocal("thread.error.cannot_take_over"); $page['errors'][] = getlocal("thread.error.cannot_take_over");
@ -80,11 +81,11 @@ if (!isset($_GET['token'])) {
exit; exit;
} }
if ($forcetake == false) { if ($force_take == false) {
$page = array( $page = array(
'user' => topage($thread->userName), 'user' => to_page($thread->userName),
'agent' => topage($thread->agentName), 'agent' => to_page($thread->agentName),
'link' => $_SERVER['PHP_SELF'] . "?thread=$threadid&amp;force=true", 'link' => $_SERVER['PHP_SELF'] . "?thread=$thread_id&amp;force=true",
'title' => getlocal("confirm.take.head"), 'title' => getlocal("confirm.take.head"),
); );
$page_style->render('confirm', $page); $page_style->render('confirm', $page);
@ -92,7 +93,7 @@ if (!isset($_GET['token'])) {
} }
} }
if (!$viewonly) { if (!$view_only) {
if (!$thread->take($operator)) { if (!$thread->take($operator)) {
$page['errors'][] = getlocal("thread.error.cannot_take"); $page['errors'][] = getlocal("thread.error.cannot_take");
$chat_style->render('error', $page); $chat_style->render('error', $page);
@ -105,13 +106,15 @@ if (!isset($_GET['token'])) {
} }
$token = $thread->lastToken; $token = $thread->lastToken;
header("Location: " . MIBEW_WEB_ROOT . "/operator/agent.php?thread=" . intval($threadid) . "&token=" . urlencode($token)); $redirect_to = MIBEW_WEB_ROOT . "/operator/agent.php?thread="
. intval($thread_id) . "&token=" . urlencode($token);
header("Location: " . $redirect_to);
exit; exit;
} }
$token = verifyparam("token", "/^\d{1,8}$/"); $token = verify_param("token", "/^\d{1,8}$/");
$thread = Thread::load($threadid, $token); $thread = Thread::load($thread_id, $token);
if (!$thread) { if (!$thread) {
die("wrong thread"); die("wrong thread");
} }
@ -129,11 +132,11 @@ $page = array_merge_recursive(
start_html_output(); start_html_output();
$pparam = verifyparam("act", "/^(redirect)$/", "default"); $pparam = verify_param("act", "/^(redirect)$/", "default");
if ($pparam == "redirect") { if ($pparam == "redirect") {
$page = array_merge_recursive( $page = array_merge_recursive(
$page, $page,
setup_redirect_links($threadid, $operator, $token) setup_redirect_links($thread_id, $operator, $token)
); );
$chat_style->render('redirect', $page); $chat_style->render('redirect', $page);
} else { } else {
@ -142,5 +145,3 @@ if ($pparam == "redirect") {
// Render the page // Render the page
$chat_style->render('chat', $page); $chat_style->render('chat', $page);
} }
?>

View File

@ -25,29 +25,27 @@ require_once(MIBEW_FS_ROOT.'/libs/operator.php');
require_once(MIBEW_FS_ROOT . '/libs/operator_settings.php'); require_once(MIBEW_FS_ROOT . '/libs/operator_settings.php');
$operator = check_login(); $operator = check_login();
csrfchecktoken(); csrf_check_token();
$opId = verifyparam("op", "/^\d{1,9}$/"); $op_id = verify_param("op", "/^\d{1,9}$/");
$page = array( $page = array(
'opid' => $opId, 'opid' => $op_id,
'avatar' => '', 'avatar' => '',
'errors' => array(), 'errors' => array(),
); );
$canmodify = ($opId == $operator['operatorid'] && is_capable(CAN_MODIFYPROFILE, $operator)) $can_modify = ($op_id == $operator['operatorid'] && is_capable(CAN_MODIFYPROFILE, $operator))
|| is_capable(CAN_ADMINISTRATE, $operator); || is_capable(CAN_ADMINISTRATE, $operator);
$op = operator_by_id($opId); $op = operator_by_id($op_id);
if (!$op) { if (!$op) {
$page['errors'][] = getlocal("no_such_operator"); $page['errors'][] = getlocal("no_such_operator");
} elseif (isset($_POST['op'])) { } elseif (isset($_POST['op'])) {
$avatar = $op['vcavatar']; $avatar = $op['vcavatar'];
if (!$canmodify) { if (!$can_modify) {
$page['errors'][] = getlocal('page_agent.cannot_modify'); $page['errors'][] = getlocal('page_agent.cannot_modify');
} elseif (isset($_FILES['avatarFile']) && $_FILES['avatarFile']['name']) { } elseif (isset($_FILES['avatarFile']) && $_FILES['avatarFile']['name']) {
$valid_types = array("gif", "jpg", "png", "tif", "jpeg"); $valid_types = array("gif", "jpg", "png", "tif", "jpeg");
@ -55,7 +53,7 @@ if (!$op) {
$tmp_file_name = $_FILES['avatarFile']['tmp_name']; $tmp_file_name = $_FILES['avatarFile']['tmp_name'];
$ext = preg_replace('/\//', '', strtolower(substr($orig_filename, 1 + strrpos($orig_filename, ".")))); $ext = preg_replace('/\//', '', strtolower(substr($orig_filename, 1 + strrpos($orig_filename, "."))));
$new_file_name = intval($opId). ".$ext"; $new_file_name = intval($op_id) . ".$ext";
$file_size = $_FILES['avatarFile']['size']; $file_size = $_FILES['avatarFile']['size'];
if ($file_size == 0 || $file_size > Settings::get('max_uploaded_file_size')) { if ($file_size == 0 || $file_size > Settings::get('max_uploaded_file_size')) {
@ -81,36 +79,30 @@ if (!$op) {
if (count($page['errors']) == 0) { if (count($page['errors']) == 0) {
update_operator_avatar($op['operatorid'], $avatar); update_operator_avatar($op['operatorid'], $avatar);
if ($opId && $avatar && $_SESSION[SESSION_PREFIX."operator"] && $operator['operatorid'] == $opId) { if ($op_id && $avatar && $_SESSION[SESSION_PREFIX . "operator"] && $operator['operatorid'] == $op_id) {
$_SESSION[SESSION_PREFIX . "operator"]['vcavatar'] = $avatar; $_SESSION[SESSION_PREFIX . "operator"]['vcavatar'] = $avatar;
} }
header("Location: " . MIBEW_WEB_ROOT . "/operator/avatar.php?op=" . intval($opId)); header("Location: " . MIBEW_WEB_ROOT . "/operator/avatar.php?op=" . intval($op_id));
exit; exit;
} else { } else {
$page['avatar'] = topage($op['vcavatar']); $page['avatar'] = to_page($op['vcavatar']);
} }
} else { } else {
if (isset($_GET['delete']) && $_GET['delete'] == "true" && $canmodify) { if (isset($_GET['delete']) && $_GET['delete'] == "true" && $can_modify) {
update_operator_avatar($op['operatorid'], ''); update_operator_avatar($op['operatorid'], '');
header("Location: " . MIBEW_WEB_ROOT . "/operator/avatar.php?op=" . intval($opId)); header("Location: " . MIBEW_WEB_ROOT . "/operator/avatar.php?op=" . intval($op_id));
exit; exit;
} }
$page['avatar'] = topage($op['vcavatar']); $page['avatar'] = to_page($op['vcavatar']);
} }
$page['currentop'] = $op ? topage(get_operator_name($op)) . " (" . $op['vclogin'] . ")" : getlocal("not_found"); $page['currentop'] = $op ? to_page(get_operator_name($op)) . " (" . $op['vclogin'] . ")" : getlocal("not_found");
$page['canmodify'] = $canmodify ? "1" : ""; $page['canmodify'] = $can_modify ? "1" : "";
$page['title'] = getlocal("page_avatar.title"); $page['title'] = getlocal("page_avatar.title");
$page['menuid'] = ($operator['operatorid'] == $opId) ? "profile" : "operators"; $page['menuid'] = ($operator['operatorid'] == $op_id) ? "profile" : "operators";
$page = array_merge( $page = array_merge($page, prepare_menu($operator));
$page, $page['tabs'] = setup_operator_settings_tabs($op_id, 1);
prepare_menu($operator)
);
$page['tabs'] = setup_operator_settings_tabs($opId, 1);
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('avatar', $page); $page_style->render('avatar', $page);
?>

View File

@ -25,9 +25,10 @@ require_once(dirname(dirname(__FILE__)).'/libs/init.php');
require_once(MIBEW_FS_ROOT . '/libs/chat.php'); require_once(MIBEW_FS_ROOT . '/libs/chat.php');
require_once(MIBEW_FS_ROOT . '/libs/operator.php'); require_once(MIBEW_FS_ROOT . '/libs/operator.php');
require_once(MIBEW_FS_ROOT . '/libs/pagination.php'); require_once(MIBEW_FS_ROOT . '/libs/pagination.php');
require_once(MIBEW_FS_ROOT . '/libs/track.php');
$operator = check_login(); $operator = check_login();
csrfchecktoken(); csrf_check_token();
$page = array('banId' => ''); $page = array('banId' => '');
$page['saved'] = false; $page['saved'] = false;
$page['thread'] = ''; $page['thread'] = '';
@ -35,11 +36,11 @@ $page['threadid'] = '';
$page['errors'] = array(); $page['errors'] = array();
if (isset($_POST['address'])) { if (isset($_POST['address'])) {
$banId = verifyparam("banId", "/^(\d{1,9})?$/", ""); $ban_id = verify_param("banId", "/^(\d{1,9})?$/", "");
$address = getparam("address"); $address = get_param("address");
$days = getparam("days"); $days = get_param("days");
$comment = getparam('comment'); $comment = get_param('comment');
$threadid = isset($_POST['threadid']) ? getparam('threadid') : ""; $thread_id = isset($_POST['threadid']) ? get_param('threadid') : "";
if (!$address) { if (!$address) {
$page['errors'][] = no_field("form.field.address"); $page['errors'][] = no_field("form.field.address");
@ -55,8 +56,8 @@ if (isset($_POST['address'])) {
$existing_ban = ban_for_addr($address); $existing_ban = ban_for_addr($address);
if ((!$banId && $existing_ban) || if ((!$ban_id && $existing_ban) ||
($banId && $existing_ban && $banId != $existing_ban['banid'])) { ($ban_id && $existing_ban && $ban_id != $existing_ban['banid'])) {
$page['errors'][] = getlocal2("ban.error.duplicate", array($address, $existing_ban['banid'])); $page['errors'][] = getlocal2("ban.error.duplicate", array($address, $existing_ban['banid']));
} }
@ -64,80 +65,74 @@ if (isset($_POST['address'])) {
$db = Database::getInstance(); $db = Database::getInstance();
$now = time(); $now = time();
$till_time = $now + $days * 24 * 60 * 60; $till_time = $now + $days * 24 * 60 * 60;
if (!$banId) { if (!$ban_id) {
$db->query( $db->query(
"insert into {chatban} (dtmcreated,dtmtill,address,comment) " . ("INSERT INTO {chatban} (dtmcreated, dtmtill, address, comment) "
"values (:now,:till,:address,:comment)", . "VALUES (:now,:till,:address,:comment)"),
array( array(
':now' => $now, ':now' => $now,
':till' => $till_time, ':till' => $till_time,
':address' => $address, ':address' => $address,
':comment' => $comment ':comment' => $comment,
) )
); );
} else { } else {
$db->query( $db->query(
"update {chatban} set dtmtill = :till,address = :address, " . ("UPDATE {chatban} SET dtmtill = :till, address = :address, "
"comment = :comment where banid = :banid", . "comment = :comment WHERE banid = :banid"),
array( array(
':till' => $till_time, ':till' => $till_time,
':address' => $address, ':address' => $address,
':comment' => $comment, ':comment' => $comment,
':banid' => $banId ':banid' => $ban_id,
) )
); );
} }
$page['saved'] = true; $page['saved'] = true;
$page['address'] = $address; $page['address'] = $address;
} else { } else {
$page['banId'] = topage($banId); $page['banId'] = to_page($ban_id);
$page['formaddress'] = topage($address); $page['formaddress'] = to_page($address);
$page['formdays'] = topage($days); $page['formdays'] = to_page($days);
$page['formcomment'] = topage($comment); $page['formcomment'] = to_page($comment);
$page['threadid'] = $threadid; $page['threadid'] = $thread_id;
} }
} elseif (isset($_GET['id'])) { } elseif (isset($_GET['id'])) {
$banId = verifyparam('id', "/^\d{1,9}$/"); $ban_id = verify_param('id', "/^\d{1,9}$/");
$db = Database::getInstance(); $db = Database::getInstance();
$ban = $db->query( $ban = $db->query(
"select banid,(dtmtill - :now)" . ("SELECT banid, (dtmtill - :now) AS days, address, comment "
" as days,address,comment from {chatban} where banid = :banid", . "FROM {chatban} WHERE banid = :banid"),
array( array(
':banid' => $banId, ':banid' => $ban_id,
':now' => time() ':now' => time(),
), ),
array('return_rows' => Database::RETURN_ONE_ROW) array('return_rows' => Database::RETURN_ONE_ROW)
); );
if ($ban) { if ($ban) {
$page['banId'] = topage($ban['banid']); $page['banId'] = to_page($ban['banid']);
$page['formaddress'] = topage($ban['address']); $page['formaddress'] = to_page($ban['address']);
$page['formdays'] = topage(round($ban['days'] / 86400)); $page['formdays'] = to_page(round($ban['days'] / 86400));
$page['formcomment'] = topage($ban['comment']); $page['formcomment'] = to_page($ban['comment']);
} else { } else {
$page['errors'][] = "Wrong id"; $page['errors'][] = "Wrong id";
} }
} elseif (isset($_GET['thread'])) { } elseif (isset($_GET['thread'])) {
$threadid = verifyparam('thread', "/^\d{1,9}$/"); $thread_id = verify_param('thread', "/^\d{1,9}$/");
$thread = Thread::load($threadid); $thread = Thread::load($thread_id);
if ($thread) { if ($thread) {
$page['thread'] = topage($thread->userName); $page['thread'] = to_page($thread->userName);
$page['threadid'] = $threadid; $page['threadid'] = $thread_id;
$page['formaddress'] = topage($thread->remote); $page['formaddress'] = to_page($thread->remote);
$page['formdays'] = 15; $page['formdays'] = 15;
} }
} }
$page['title'] = getlocal("page_ban.title"); $page['title'] = getlocal("page_ban.title");
$page = array_merge( $page = array_merge($page, prepare_menu($operator, false));
$page,
prepare_menu($operator, false)
);
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('ban', $page); $page_style->render('ban', $page);
?>

View File

@ -24,9 +24,10 @@ require_once(dirname(dirname(__FILE__)).'/libs/init.php');
require_once(MIBEW_FS_ROOT . '/libs/chat.php'); require_once(MIBEW_FS_ROOT . '/libs/chat.php');
require_once(MIBEW_FS_ROOT . '/libs/operator.php'); require_once(MIBEW_FS_ROOT . '/libs/operator.php');
require_once(MIBEW_FS_ROOT . '/libs/pagination.php'); require_once(MIBEW_FS_ROOT . '/libs/pagination.php');
require_once(MIBEW_FS_ROOT . '/libs/track.php');
$operator = check_login(); $operator = check_login();
csrfchecktoken(); csrf_check_token();
$page = array( $page = array(
'errors' => array(), 'errors' => array(),
@ -37,38 +38,33 @@ setlocale(LC_TIME, getstring("time.locale"));
$db = Database::getInstance(); $db = Database::getInstance();
if (isset($_GET['act']) && $_GET['act'] == 'del') { if (isset($_GET['act']) && $_GET['act'] == 'del') {
$banId = isset($_GET['id']) ? $_GET['id'] : ""; $ban_id = isset($_GET['id']) ? $_GET['id'] : "";
if (!preg_match("/^\d+$/", $banId)) { if (!preg_match("/^\d+$/", $ban_id)) {
$page['errors'][] = "Cannot delete: wrong argument"; $page['errors'][] = "Cannot delete: wrong argument";
} }
if (count($page['errors']) == 0) { if (count($page['errors']) == 0) {
$db->query("delete from {chatban} where banid = ?", array($banId)); $db->query("DELETE FROM {chatban} WHERE banid = ?", array($ban_id));
header("Location: " . MIBEW_WEB_ROOT . "/operator/blocked.php"); header("Location: " . MIBEW_WEB_ROOT . "/operator/blocked.php");
exit; exit;
} }
} }
$blockedList = $db->query( $blocked_list = $db->query(
"select banid, dtmtill as till,address,comment from {chatban}", "SELECT banid, dtmtill AS till,address,comment FROM {chatban}",
NULL, null,
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
$page['title'] = getlocal("page_bans.title"); $page['title'] = getlocal("page_bans.title");
$page['menuid'] = "blocked"; $page['menuid'] = "blocked";
$pagination = setup_pagination($blockedList); $pagination = setup_pagination($blocked_list);
$page['pagination'] = $pagination['info']; $page['pagination'] = $pagination['info'];
$page['pagination.items'] = $pagination['items']; $page['pagination.items'] = $pagination['items'];
$page = array_merge( $page = array_merge($page, prepare_menu($operator));
$page,
prepare_menu($operator)
);
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('blocked_visitors', $page); $page_style->render('blocked_visitors', $page);
?>

View File

@ -29,7 +29,7 @@ require_once(MIBEW_FS_ROOT.'/libs/pagination.php');
$operator = check_login(); $operator = check_login();
force_password($operator); force_password($operator);
csrfchecktoken(); csrf_check_token();
$page = array( $page = array(
'errors' => array(), 'errors' => array(),
@ -44,31 +44,30 @@ foreach ($all_locales as $id) {
} }
$page['locales'] = $locales_with_label; $page['locales'] = $locales_with_label;
$lang = verifyparam("lang", "/^[\w-]{2,5}$/", ""); $lang = verify_param("lang", "/^[\w-]{2,5}$/", "");
if (!$lang || !in_array($lang, $all_locales)) { if (!$lang || !in_array($lang, $all_locales)) {
$lang = in_array(CURRENT_LOCALE, $all_locales) ? CURRENT_LOCALE : $all_locales[0]; $lang = in_array(CURRENT_LOCALE, $all_locales) ? CURRENT_LOCALE : $all_locales[0];
} }
# groups # groups
$groupid = ""; $group_id = verify_param("group", "/^\d{0,8}$/", "");
$groupid = verifyparam("group", "/^\d{0,8}$/", ""); if ($group_id) {
if ($groupid) { $group = group_by_id($group_id);
$group = group_by_id($groupid);
if (!$group) { if (!$group) {
$page['errors'][] = getlocal("page.group.no_such"); $page['errors'][] = getlocal("page.group.no_such");
$groupid = ""; $group_id = "";
} }
} }
$allgroups = in_isolation($operator)?get_all_groups_for_operator($operator):get_all_groups(); $all_groups = in_isolation($operator) ? get_all_groups_for_operator($operator) : get_all_groups();
$page['groups'] = array(); $page['groups'] = array();
$page['groups'][] = array( $page['groups'][] = array(
'groupid' => '', 'groupid' => '',
'vclocalname' => getlocal("page.gen_button.default_group"), 'vclocalname' => getlocal("page.gen_button.default_group"),
'level' => 0 'level' => 0,
); );
foreach ($allgroups as $g) { foreach ($all_groups as $g) {
$page['groups'][] = $g; $page['groups'][] = $g;
} }
@ -83,15 +82,17 @@ if (isset($_GET['act']) && $_GET['act'] == 'delete') {
if (count($page['errors']) == 0) { if (count($page['errors']) == 0) {
$db = Database::getInstance(); $db = Database::getInstance();
$db->query("delete from {chatresponses} where id = ?", array($key)); $db->query("DELETE FROM {chatresponses} WHERE id = ?", array($key));
header("Location: " . MIBEW_WEB_ROOT . "/operator/canned.php?lang=" . urlencode($lang) . "&group=" . intval($groupid)); $redirect_to = MIBEW_WEB_ROOT . "/operator/canned.php?lang="
. urlencode($lang) . "&group=" . intval($group_id);
header("Location: " . $redirect_to);
exit; exit;
} }
} }
// Get messages and setup pagination // Get messages and setup pagination
$messages = load_canned_messages($lang, $groupid); $messages = load_canned_messages($lang, $group_id);
$pagination = setup_pagination($messages); $pagination = setup_pagination($messages);
$page['pagination'] = $pagination['info']; $page['pagination'] = $pagination['info'];
$page['pagination.items'] = $pagination['items']; $page['pagination.items'] = $pagination['items'];
@ -99,16 +100,11 @@ $page['pagination.items'] = $pagination['items'];
# form values # form values
$page['formlang'] = $lang; $page['formlang'] = $lang;
$page['formgroup'] = $groupid; $page['formgroup'] = $group_id;
$page['title'] = getlocal("canned.title"); $page['title'] = getlocal("canned.title");
$page['menuid'] = "canned"; $page['menuid'] = "canned";
$page = array_merge( $page = array_merge($page, prepare_menu($operator));
$page,
prepare_menu($operator)
);
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('canned', $page); $page_style->render('canned', $page);
?>

View File

@ -25,9 +25,9 @@ require_once(MIBEW_FS_ROOT.'/libs/operator.php');
require_once(MIBEW_FS_ROOT . '/libs/pagination.php'); require_once(MIBEW_FS_ROOT . '/libs/pagination.php');
$operator = check_login(); $operator = check_login();
csrfchecktoken(); csrf_check_token();
$stringid = verifyparam("key", "/^\d{0,9}$/", ""); $string_id = verify_param("key", "/^\d{0,9}$/", "");
$page = array( $page = array(
'errors' => array(), 'errors' => array(),
@ -35,11 +35,11 @@ $page = array(
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
if ($stringid) { if ($string_id) {
$canned_message = load_canned_message($stringid); $canned_message = load_canned_message($string_id);
if (!$canned_message) { if (!$canned_message) {
$page['errors'][] = getlocal("cannededit.no_such"); $page['errors'][] = getlocal("cannededit.no_such");
$stringid = ""; $string_id = "";
} else { } else {
$title = $canned_message['vctitle']; $title = $canned_message['vctitle'];
$message = $canned_message['vcvalue']; $message = $canned_message['vcvalue'];
@ -47,49 +47,41 @@ if ($stringid) {
} else { } else {
$message = ''; $message = '';
$title = ''; $title = '';
$page['locale'] = verifyparam("lang", "/^[\w-]{2,5}$/", ""); $page['locale'] = verify_param("lang", "/^[\w-]{2,5}$/", "");
$page['groupid'] = ""; $page['groupid'] = "";
$page['groupid'] = verifyparam("group", "/^\d{0,8}$/"); $page['groupid'] = verify_param("group", "/^\d{0,8}$/");
} }
if (isset($_POST['message']) && isset($_POST['title'])) { if (isset($_POST['message']) && isset($_POST['title'])) {
$title = getparam('title'); $title = get_param('title');
if (!$title) { if (!$title) {
$page['errors'][] = no_field("form.field.title"); $page['errors'][] = no_field("form.field.title");
} }
$message = getparam('message'); $message = get_param('message');
if (!$message) { if (!$message) {
$page['errors'][] = no_field("form.field.message"); $page['errors'][] = no_field("form.field.message");
} }
if (count($page['errors']) == 0) { if (count($page['errors']) == 0) {
if ($stringid) { if ($string_id) {
save_canned_message($stringid, $title, $message); save_canned_message($string_id, $title, $message);
} else { } else {
add_canned_message($page['locale'], $page['groupid'], $title, $message); add_canned_message($page['locale'], $page['groupid'], $title, $message);
} }
$page['saved'] = true; $page['saved'] = true;
$page = array_merge( $page = array_merge($page, prepare_menu($operator, false));
$page,
prepare_menu($operator, false)
);
$page_style->render('cannededit', $page); $page_style->render('cannededit', $page);
exit; exit;
} }
} }
$page['saved'] = false; $page['saved'] = false;
$page['key'] = $stringid; $page['key'] = $string_id;
$page['formtitle'] = topage($title); $page['formtitle'] = to_page($title);
$page['formmessage'] = topage($message); $page['formmessage'] = to_page($message);
$page['title'] = empty($stringid) ? getlocal("cannednew.title") : getlocal("cannededit.title"); $page['title'] = empty($string_id) ? getlocal("cannednew.title") : getlocal("cannededit.title");
$page = array_merge( $page = array_merge($page, prepare_menu($operator, false));
$page,
prepare_menu($operator, false)
);
$page_style->render('cannededit', $page); $page_style->render('cannededit', $page);
?>

View File

@ -25,7 +25,7 @@ require_once(MIBEW_FS_ROOT.'/libs/operator.php');
require_once(MIBEW_FS_ROOT . '/libs/settings.php'); require_once(MIBEW_FS_ROOT . '/libs/settings.php');
$operator = check_login(); $operator = check_login();
csrfchecktoken(); csrf_check_token();
$page = array( $page = array(
'agentId' => '', 'agentId' => '',
@ -33,13 +33,22 @@ $page = array(
); );
$options = array( $options = array(
'enableban', 'usercanchangename', 'enableban',
'enablegroups', 'enablegroupsisolation', 'usercanchangename',
'enablestatistics', 'enabletracking', 'enablegroups',
'enablessl', 'forcessl', 'enablegroupsisolation',
'enablepresurvey', 'surveyaskmail', 'surveyaskgroup', 'surveyaskmessage', 'enablestatistics',
'enablepopupnotification', 'showonlineoperators', 'enabletracking',
'enablecaptcha'); 'enablessl',
'forcessl',
'enablepresurvey',
'surveyaskmail',
'surveyaskgroup',
'surveyaskmessage',
'enablepopupnotification',
'showonlineoperators',
'enablecaptcha',
);
if (Settings::get('featuresversion') != FEATURES_VERSION) { if (Settings::get('featuresversion') != FEATURES_VERSION) {
Settings::set('featuresversion', FEATURES_VERSION); Settings::set('featuresversion', FEATURES_VERSION);
@ -53,7 +62,7 @@ foreach ($options as $opt) {
if (isset($_POST['sent'])) { if (isset($_POST['sent'])) {
if (is_capable(CAN_ADMINISTRATE, $operator)) { if (is_capable(CAN_ADMINISTRATE, $operator)) {
foreach ($options as $opt) { foreach ($options as $opt) {
Settings::set($opt,(verifyparam($opt, "/^on$/", "") == "on" ? "1" : "0")); Settings::set($opt, (verify_param($opt, "/^on$/", "") == "on" ? "1" : "0"));
} }
Settings::update(); Settings::update();
header("Location: " . MIBEW_WEB_ROOT . "/operator/features.php?stored"); header("Location: " . MIBEW_WEB_ROOT . "/operator/features.php?stored");
@ -72,14 +81,9 @@ foreach ($options as $opt) {
$page['title'] = getlocal("settings.title"); $page['title'] = getlocal("settings.title");
$page['menuid'] = "settings"; $page['menuid'] = "settings";
$page = array_merge( $page = array_merge($page, prepare_menu($operator));
$page,
prepare_menu($operator)
);
$page['tabs'] = setup_settings_tabs(1); $page['tabs'] = setup_settings_tabs(1);
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('features', $page); $page_style->render('features', $page);
?>

View File

@ -34,55 +34,67 @@ $page = array(
'errors' => array(), 'errors' => array(),
); );
$imageLocales = get_image_locales_map(MIBEW_FS_ROOT.'/locales'); $image_locales_map = get_image_locales_map(MIBEW_FS_ROOT . '/locales');
$image = verifyparam(isset($_GET['image']) ? "image" : "i", "/^\w+$/", "mibew"); $image = verify_param(isset($_GET['image']) ? "image" : "i", "/^\w+$/", "mibew");
if (!isset($imageLocales[$image])) { if (!isset($image_locales_map[$image])) {
$page['errors'][] = "Unknown image: $image"; $page['errors'][] = "Unknown image: $image";
$avail = array_keys($imageLocales); $avail = array_keys($image_locales_map);
$image = $avail[0]; $image = $avail[0];
} }
$image_locales = $imageLocales[$image]; $image_locales = $image_locales_map[$image];
$stylelist = ChatStyle::availableStyles(); $style_list = ChatStyle::availableStyles();
$stylelist[""] = getlocal("page.preview.style_default"); $style_list[""] = getlocal("page.preview.style_default");
$style = verifyparam("style", "/^\w*$/", ""); $style = verify_param("style", "/^\w*$/", "");
if ($style && !in_array($style, $stylelist)) { if ($style && !in_array($style, $style_list)) {
$style = ""; $style = "";
} }
$invitationstylelist = InvitationStyle::availableStyles(); $invitation_style_list = InvitationStyle::availableStyles();
$invitationstylelist[""] = getlocal("page.preview.style_default"); $invitation_style_list[""] = getlocal("page.preview.style_default");
$invitationstyle = verifyparam("invitationstyle", "/^\w*$/", ""); $invitation_style = verify_param("invitationstyle", "/^\w*$/", "");
if ($invitationstyle && !in_array($invitationstyle, $invitationstylelist)) { if ($invitation_style && !in_array($invitation_style, $invitation_style_list)) {
$invitationstyle = ""; $invitation_style = "";
} }
$groupid = verifyparam_groupid("group", $page['errors']); $group_id = verifyparam_groupid("group", $page['errors']);
$showhost = verifyparam("hostname", "/^on$/", "") == "on"; $show_host = verify_param("hostname", "/^on$/", "") == "on";
$forcesecure = verifyparam("secure", "/^on$/", "") == "on"; $force_secure = verify_param("secure", "/^on$/", "") == "on";
$modsecurity = verifyparam("modsecurity", "/^on$/", "") == "on"; $mod_security = verify_param("modsecurity", "/^on$/", "") == "on";
$code_type = verifyparam("codetype", "/^(button|operator_code)$/", "button"); $code_type = verify_param("codetype", "/^(button|operator_code)$/", "button");
$operator_code = ($code_type == "operator_code"); $operator_code = ($code_type == "operator_code");
$lang = verifyparam("lang", "/^[\w-]{2,5}$/", ""); $lang = verify_param("lang", "/^[\w-]{2,5}$/", "");
if (!$lang || !in_array($lang, $image_locales)) if (!$lang || !in_array($lang, $image_locales)) {
$lang = in_array(CURRENT_LOCALE, $image_locales) ? CURRENT_LOCALE : $image_locales[0]; $lang = in_array(CURRENT_LOCALE, $image_locales) ? CURRENT_LOCALE : $image_locales[0];
}
$file = MIBEW_FS_ROOT . '/locales/${lang}/button/${image}_on.gif'; $file = MIBEW_FS_ROOT . '/locales/${lang}/button/${image}_on.gif';
$size = get_gifimage_size($file); $size = get_gifimage_size($file);
$imagehref = get_app_location($showhost, $forcesecure) . "/b.php?i=$image&amp;lang=$lang"; $image_href = get_app_location($show_host, $force_secure) . "/b.php?i=$image&amp;lang=$lang";
if ($groupid) { if ($group_id) {
$imagehref .= "&amp;group=$groupid"; $image_href .= "&amp;group=$group_id";
} }
$message = get_image($imagehref, $size[0], $size[1]); $message = get_image($image_href, $size[0], $size[1]);
$page['buttonCode'] = generate_button("", $lang, $style, $invitationstyle, $groupid, $message, $showhost, $forcesecure, $modsecurity, $operator_code); $page['buttonCode'] = generate_button(
$page['availableImages'] = array_keys($imageLocales); "",
$lang,
$style,
$invitation_style,
$group_id,
$message,
$show_host,
$force_secure,
$mod_security,
$operator_code
);
$page['availableImages'] = array_keys($image_locales_map);
$page['availableLocales'] = $image_locales; $page['availableLocales'] = $image_locales;
$page['availableChatStyles'] = $stylelist; $page['availableChatStyles'] = $style_list;
$page['availableInvitationStyles'] = $invitationstylelist; $page['availableInvitationStyles'] = $invitation_style_list;
$page['groups'] = get_groups_list(); $page['groups'] = get_groups_list();
$page['availableCodeTypes'] = array( $page['availableCodeTypes'] = array(
@ -90,14 +102,14 @@ $page['availableCodeTypes'] = array(
'operator_code' => getlocal('page.gen_button.operator_code') 'operator_code' => getlocal('page.gen_button.operator_code')
); );
$page['formgroup'] = $groupid; $page['formgroup'] = $group_id;
$page['formstyle'] = $style; $page['formstyle'] = $style;
$page['forminvitationstyle'] = $invitationstyle; $page['forminvitationstyle'] = $invitation_style;
$page['formimage'] = $image; $page['formimage'] = $image;
$page['formlang'] = $lang; $page['formlang'] = $lang;
$page['formhostname'] = $showhost; $page['formhostname'] = $show_host;
$page['formsecure'] = $forcesecure; $page['formsecure'] = $force_secure;
$page['formmodsecurity'] = $modsecurity; $page['formmodsecurity'] = $mod_security;
$page['formcodetype'] = $code_type; $page['formcodetype'] = $code_type;
$page['enabletracking'] = Settings::get('enabletracking'); $page['enabletracking'] = Settings::get('enabletracking');
@ -106,12 +118,7 @@ $page['operator_code'] = $operator_code;
$page['title'] = getlocal("page.gen_button.title"); $page['title'] = getlocal("page.gen_button.title");
$page['menuid'] = "getcode"; $page['menuid'] = "getcode";
$page = array_merge( $page = array_merge($page, prepare_menu($operator));
$page,
prepare_menu($operator)
);
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('gen_button', $page); $page_style->render('gen_button', $page);
?>

View File

@ -24,133 +24,137 @@ require_once(MIBEW_FS_ROOT.'/libs/operator.php');
require_once(MIBEW_FS_ROOT . '/libs/groups.php'); require_once(MIBEW_FS_ROOT . '/libs/groups.php');
$operator = check_login(); $operator = check_login();
csrfchecktoken(); csrf_check_token();
$page = array( $page = array(
'grid' => '', 'grid' => '',
'errors' => array(), 'errors' => array(),
); );
$groupid = ''; $group_id = '';
if (isset($_POST['name'])) { if (isset($_POST['name'])) {
$groupid = verifyparam("gid", "/^(\d{1,9})?$/", ""); $group_id = verify_param("gid", "/^(\d{1,9})?$/", "");
$name = getparam('name'); $name = get_param('name');
$description = getparam('description'); $description = get_param('description');
$commonname = getparam('commonname'); $common_name = get_param('commonname');
$commondescription = getparam('commondescription'); $common_description = get_param('commondescription');
$email = getparam('email'); $email = get_param('email');
$weight = getparam('weight'); $weight = get_param('weight');
$parentgroup = verifyparam("parentgroup", "/^(\d{1,9})?$/", ""); $parent_group = verify_param("parentgroup", "/^(\d{1,9})?$/", "");
$title = getparam('title'); $title = get_param('title');
$chattitle = getparam('chattitle'); $chat_title = get_param('chattitle');
$hosturl = getparam('hosturl'); $host_url = get_param('hosturl');
$logo = getparam('logo'); $logo = get_param('logo');
if (!$name) if (!$name) {
$page['errors'][] = no_field("form.field.groupname"); $page['errors'][] = no_field("form.field.groupname");
}
if ($email != '' && !is_valid_email($email)) if ($email != '' && !is_valid_email($email)) {
$page['errors'][] = wrong_field("form.field.mail"); $page['errors'][] = wrong_field("form.field.mail");
}
if (! preg_match("/^(\d{1,9})?$/", $weight)) if (!preg_match("/^(\d{1,9})?$/", $weight)) {
$page['errors'][] = wrong_field("form.field.groupweight"); $page['errors'][] = wrong_field("form.field.groupweight");
}
if ($weight == '') if ($weight == '') {
$weight = 0; $weight = 0;
}
if (! $parentgroup) if (!$parent_group) {
$parentgroup = NULL; $parent_group = null;
}
$existing_group = group_by_name($name); $existing_group = group_by_name($name);
if ((!$groupid && $existing_group) || $duplicate_name = (!$group_id && $existing_group)
($groupid && $existing_group && $groupid != $existing_group['groupid'])) || ($group_id
&& $existing_group
&& $group_id != $existing_group['groupid']);
if ($duplicate_name) {
$page['errors'][] = getlocal("page.group.duplicate_name"); $page['errors'][] = getlocal("page.group.duplicate_name");
}
if (count($page['errors']) == 0) { if (count($page['errors']) == 0) {
if (!$groupid) { if (!$group_id) {
$newdep = create_group(array( $new_dep = create_group(array(
'name' => $name, 'name' => $name,
'description' => $description, 'description' => $description,
'commonname' => $commonname, 'commonname' => $common_name,
'commondescription' => $commondescription, 'commondescription' => $common_description,
'email' => $email, 'email' => $email,
'weight' => $weight, 'weight' => $weight,
'parent' => $parentgroup, 'parent' => $parent_group,
'title' => $title, 'title' => $title,
'chattitle' => $chattitle, 'chattitle' => $chat_title,
'hosturl' => $hosturl, 'hosturl' => $host_url,
'logo' => $logo)); 'logo' => $logo));
header("Location: " . MIBEW_WEB_ROOT . "/operator/groupmembers.php?gid=" . intval($newdep['groupid'])); header("Location: " . MIBEW_WEB_ROOT . "/operator/groupmembers.php?gid=" . intval($new_dep['groupid']));
exit; exit;
} else { } else {
update_group(array( update_group(array(
'id' => $groupid, 'id' => $group_id,
'name' => $name, 'name' => $name,
'description' => $description, 'description' => $description,
'commonname' => $commonname, 'commonname' => $common_name,
'commondescription' => $commondescription, 'commondescription' => $common_description,
'email' => $email, 'email' => $email,
'weight' => $weight, 'weight' => $weight,
'parent' => $parentgroup, 'parent' => $parent_group,
'title' => $title, 'title' => $title,
'chattitle' => $chattitle, 'chattitle' => $chat_title,
'hosturl' => $hosturl, 'hosturl' => $host_url,
'logo' => $logo)); 'logo' => $logo));
header("Location: " . MIBEW_WEB_ROOT . "/operator/group.php?gid=" . intval($groupid) . "&stored"); header("Location: " . MIBEW_WEB_ROOT . "/operator/group.php?gid=" . intval($group_id) . "&stored");
exit; exit;
} }
} else { } else {
$page['formname'] = topage($name); $page['formname'] = to_page($name);
$page['formdescription'] = topage($description); $page['formdescription'] = to_page($description);
$page['formcommonname'] = topage($commonname); $page['formcommonname'] = to_page($common_name);
$page['formcommondescription'] = topage($commondescription); $page['formcommondescription'] = to_page($common_description);
$page['formemail'] = topage($email); $page['formemail'] = to_page($email);
$page['formweight'] = topage($weight); $page['formweight'] = to_page($weight);
$page['formparentgroup'] = topage($parentgroup); $page['formparentgroup'] = to_page($parent_group);
$page['grid'] = topage($groupid); $page['grid'] = to_page($group_id);
$page['formtitle'] = topage($title); $page['formtitle'] = to_page($title);
$page['formchattitle'] = topage($chattitle); $page['formchattitle'] = to_page($chat_title);
$page['formhosturl'] = topage($hosturl); $page['formhosturl'] = to_page($host_url);
$page['formlogo'] = topage($logo); $page['formlogo'] = to_page($logo);
} }
} elseif (isset($_GET['gid'])) { } elseif (isset($_GET['gid'])) {
$groupid = verifyparam('gid', "/^\d{1,9}$/"); $group_id = verify_param('gid', "/^\d{1,9}$/");
$group = group_by_id($groupid); $group = group_by_id($group_id);
if (!$group) { if (!$group) {
$page['errors'][] = getlocal("page.group.no_such"); $page['errors'][] = getlocal("page.group.no_such");
$page['grid'] = topage($groupid); $page['grid'] = to_page($group_id);
} else { } else {
$page['formname'] = topage($group['vclocalname']); $page['formname'] = to_page($group['vclocalname']);
$page['formdescription'] = topage($group['vclocaldescription']); $page['formdescription'] = to_page($group['vclocaldescription']);
$page['formcommonname'] = topage($group['vccommonname']); $page['formcommonname'] = to_page($group['vccommonname']);
$page['formcommondescription'] = topage($group['vccommondescription']); $page['formcommondescription'] = to_page($group['vccommondescription']);
$page['formemail'] = topage($group['vcemail']); $page['formemail'] = to_page($group['vcemail']);
$page['formweight'] = topage($group['iweight']); $page['formweight'] = to_page($group['iweight']);
$page['formparentgroup'] = topage($group['parent']); $page['formparentgroup'] = to_page($group['parent']);
$page['grid'] = topage($group['groupid']); $page['grid'] = to_page($group['groupid']);
$page['formtitle'] = topage($group['vctitle']); $page['formtitle'] = to_page($group['vctitle']);
$page['formchattitle'] = topage($group['vcchattitle']); $page['formchattitle'] = to_page($group['vcchattitle']);
$page['formhosturl'] = topage($group['vchosturl']); $page['formhosturl'] = to_page($group['vchosturl']);
$page['formlogo'] = topage($group['vclogo']); $page['formlogo'] = to_page($group['vclogo']);
} }
} }
$page['stored'] = isset($_GET['stored']); $page['stored'] = isset($_GET['stored']);
$page['availableParentGroups'] = get_available_parent_groups($groupid); $page['availableParentGroups'] = get_available_parent_groups($group_id);
$page['title'] = getlocal("page.group.title"); $page['title'] = getlocal("page.group.title");
$page['menuid'] = "groups"; $page['menuid'] = "groups";
$page = array_merge( $page = array_merge($page, prepare_menu($operator));
$page,
prepare_menu($operator)
);
$page['tabs'] = setup_group_settings_tabs($groupid, 0); $page['tabs'] = setup_group_settings_tabs($group_id, 0);
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('group', $page); $page_style->render('group', $page);
?>

View File

@ -24,36 +24,35 @@ require_once(MIBEW_FS_ROOT.'/libs/operator.php');
require_once(MIBEW_FS_ROOT . '/libs/groups.php'); require_once(MIBEW_FS_ROOT . '/libs/groups.php');
$operator = check_login(); $operator = check_login();
csrfchecktoken(); csrf_check_token();
$groupid = verifyparam("gid", "/^\d{1,9}$/"); $group_id = verify_param("gid", "/^\d{1,9}$/");
$page = array('groupid' => $groupid); $page = array('groupid' => $group_id);
$page['operators'] = get_operators_list(array()); $page['operators'] = get_operators_list(array());
$page['errors'] = array(); $page['errors'] = array();
$group = group_by_id($groupid); $group = group_by_id($group_id);
if (!$group) { if (!$group) {
$page['errors'][] = getlocal("page.group.no_such"); $page['errors'][] = getlocal("page.group.no_such");
} elseif (isset($_POST['gid'])) { } elseif (isset($_POST['gid'])) {
$new_members = array(); $new_members = array();
foreach ($page['operators'] as $op) { foreach ($page['operators'] as $op) {
if (verifyparam("op" . $op['operatorid'], "/^on$/", "") == "on") { if (verify_param("op" . $op['operatorid'], "/^on$/", "") == "on") {
$new_members[] = $op['operatorid']; $new_members[] = $op['operatorid'];
} }
} }
update_group_members($groupid, $new_members); update_group_members($group_id, $new_members);
header("Location: " . MIBEW_WEB_ROOT . "/operator/groupmembers.php?gid=" . intval($groupid) . "&stored"); header("Location: " . MIBEW_WEB_ROOT . "/operator/groupmembers.php?gid=" . intval($group_id) . "&stored");
exit; exit;
} }
$page['formop'] = array(); $page['formop'] = array();
$page['currentgroup'] = $group ? topage(htmlspecialchars($group['vclocalname'])) : ""; $page['currentgroup'] = $group ? to_page(htmlspecialchars($group['vclocalname'])) : "";
foreach (get_group_members($groupid) as $rel) { foreach (get_group_members($group_id) as $rel) {
$page['formop'][] = $rel['operatorid']; $page['formop'][] = $rel['operatorid'];
} }
@ -61,14 +60,9 @@ $page['stored'] = isset($_GET['stored']);
$page['title'] = getlocal("page.groupmembers.title"); $page['title'] = getlocal("page.groupmembers.title");
$page['menuid'] = "groups"; $page['menuid'] = "groups";
$page = array_merge( $page = array_merge($page, prepare_menu($operator));
$page,
prepare_menu($operator)
);
$page['tabs'] = setup_group_settings_tabs($groupid, 1); $page['tabs'] = setup_group_settings_tabs($group_id, 1);
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('groupmembers', $page); $page_style->render('groupmembers', $page);
?>

View File

@ -25,13 +25,13 @@ require_once(MIBEW_FS_ROOT.'/libs/operator.php');
require_once(MIBEW_FS_ROOT . '/libs/groups.php'); require_once(MIBEW_FS_ROOT . '/libs/groups.php');
$operator = check_login(); $operator = check_login();
csrfchecktoken(); csrf_check_token();
if (isset($_GET['act']) && $_GET['act'] == 'del') { if (isset($_GET['act']) && $_GET['act'] == 'del') {
$groupid = isset($_GET['gid']) ? $_GET['gid'] : ""; $group_id = isset($_GET['gid']) ? $_GET['gid'] : "";
if (!preg_match("/^\d+$/", $groupid)) { if (!preg_match("/^\d+$/", $group_id)) {
$page['errors'][] = getlocal("page.groups.error.cannot_delete"); $page['errors'][] = getlocal("page.groups.error.cannot_delete");
} }
@ -41,17 +41,17 @@ if (isset($_GET['act']) && $_GET['act'] == 'del') {
if (count($page['errors']) == 0) { if (count($page['errors']) == 0) {
$db = Database::getInstance(); $db = Database::getInstance();
$db->query("delete from {chatgroup} where groupid = ?", array($groupid)); $db->query("delete from {chatgroup} where groupid = ?", array($group_id));
$db->query("delete from {chatgroupoperator} where groupid = ?", array($groupid)); $db->query("delete from {chatgroupoperator} where groupid = ?", array($group_id));
$db->query("update {chatthread} set groupid = 0 where groupid = ?",array($groupid)); $db->query("update {chatthread} set groupid = 0 where groupid = ?", array($group_id));
header("Location: " . MIBEW_WEB_ROOT . "/operator/groups.php"); header("Location: " . MIBEW_WEB_ROOT . "/operator/groups.php");
exit; exit;
} }
} }
$page = array(); $page = array();
$sort['by'] = verifyparam("sortby", "/^(name|lastseen|weight)$/", "name"); $sort['by'] = verify_param("sortby", "/^(name|lastseen|weight)$/", "name");
$sort['desc'] = (verifyparam("sortdirection", "/^(desc|asc)$/", "desc") == "desc"); $sort['desc'] = (verify_param("sortdirection", "/^(desc|asc)$/", "desc") == "desc");
$page['groups'] = get_sorted_groups($sort); $page['groups'] = get_sorted_groups($sort);
$page['formsortby'] = $sort['by']; $page['formsortby'] = $sort['by'];
$page['formsortdirection'] = $sort['desc'] ? 'desc' : 'asc'; $page['formsortdirection'] = $sort['desc'] ? 'desc' : 'asc';
@ -59,7 +59,7 @@ $page['canmodify'] = is_capable(CAN_ADMINISTRATE, $operator);
$page['availableOrders'] = array( $page['availableOrders'] = array(
array('id' => 'name', 'name' => getlocal('form.field.groupname')), array('id' => 'name', 'name' => getlocal('form.field.groupname')),
array('id' => 'lastseen', 'name' => getlocal('page_agents.status')), array('id' => 'lastseen', 'name' => getlocal('page_agents.status')),
array('id' => 'weight', 'name' => getlocal('page.groups.weight')) array('id' => 'weight', 'name' => getlocal('page.groups.weight')),
); );
$page['availableDirections'] = array( $page['availableDirections'] = array(
array('id' => 'desc', 'name' => getlocal('page.groups.sortdirection.desc')), array('id' => 'desc', 'name' => getlocal('page.groups.sortdirection.desc')),
@ -69,12 +69,7 @@ $page['availableDirections'] = array(
$page['title'] = getlocal("page.groups.title"); $page['title'] = getlocal("page.groups.title");
$page['menuid'] = "groups"; $page['menuid'] = "groups";
$page = array_merge( $page = array_merge($page, prepare_menu($operator));
$page,
prepare_menu($operator)
);
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('groups', $page); $page_style->render('groups', $page);
?>

View File

@ -27,6 +27,7 @@ require_once(MIBEW_FS_ROOT.'/libs/chat.php');
require_once(MIBEW_FS_ROOT . '/libs/userinfo.php'); require_once(MIBEW_FS_ROOT . '/libs/userinfo.php');
require_once(MIBEW_FS_ROOT . '/libs/pagination.php'); require_once(MIBEW_FS_ROOT . '/libs/pagination.php');
require_once(MIBEW_FS_ROOT . '/libs/cron.php'); require_once(MIBEW_FS_ROOT . '/libs/cron.php');
require_once(MIBEW_FS_ROOT . '/libs/track.php');
$operator = check_login(); $operator = check_login();
force_password($operator); force_password($operator);
@ -36,60 +37,63 @@ setlocale(LC_TIME, getstring("time.locale"));
$page = array(); $page = array();
$query = isset($_GET['q']) ? myiconv(getoutputenc(), MIBEW_ENCODING, $_GET['q']) : false; $query = isset($_GET['q']) ? myiconv(getoutputenc(), MIBEW_ENCODING, $_GET['q']) : false;
$searchType = verifyparam('type', '/^(all|message|operator|visitor)$/', 'all'); $search_type = verify_param('type', '/^(all|message|operator|visitor)$/', 'all');
$searchInSystemMessages = (verifyparam('insystemmessages', '/^on$/', 'off') == 'on') || !$query; $search_in_system_messages = (verify_param('insystemmessages', '/^on$/', 'off') == 'on') || !$query;
if ($query !== false) { if ($query !== false) {
$db = Database::getInstance(); $db = Database::getInstance();
$groups = $db->query( $groups = $db->query(
"select {chatgroup}.groupid as groupid, vclocalname " . ("SELECT {chatgroup}.groupid AS groupid, vclocalname " .
"from {chatgroup} order by vclocalname", "FROM {chatgroup} " .
NULL, "ORDER BY vclocalname"),
null,
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
$groupName = array(); $group_name = array();
foreach ($groups as $group) { foreach ($groups as $group) {
$groupName[$group['groupid']] = $group['vclocalname']; $group_name[$group['groupid']] = $group['vclocalname'];
} }
$page['groupName'] = $groupName; $page['groupName'] = $group_name;
$values = array( $values = array(
':query' => "%{$query}%", ':query' => "%{$query}%",
':invitation_accepted' => Thread::INVITATION_ACCEPTED, ':invitation_accepted' => Thread::INVITATION_ACCEPTED,
':invitation_not_invited' => Thread::INVITATION_NOT_INVITED ':invitation_not_invited' => Thread::INVITATION_NOT_INVITED,
); );
$searchConditions = array(); $search_conditions = array();
if ($searchType == 'message' || $searchType == 'all') { if ($search_type == 'message' || $search_type == 'all') {
$searchConditions[] = "({chatmessage}.tmessage LIKE :query" . $search_conditions[] = "({chatmessage}.tmessage LIKE :query"
($searchInSystemMessages?'':" AND ({chatmessage}.ikind = :kind_user OR {chatmessage}.ikind = :kind_agent)") . . ($search_in_system_messages
")"; ? ''
if (! $searchInSystemMessages) { : " AND ({chatmessage}.ikind = :kind_user OR {chatmessage}.ikind = :kind_agent)")
. ")";
if (!$search_in_system_messages) {
$values[':kind_user'] = Thread::KIND_USER; $values[':kind_user'] = Thread::KIND_USER;
$values[':kind_agent'] = Thread::KIND_AGENT; $values[':kind_agent'] = Thread::KIND_AGENT;
} }
} }
if ($searchType == 'operator' || $searchType == 'all') { if ($search_type == 'operator' || $search_type == 'all') {
$searchConditions[] = "({chatthread}.agentName LIKE :query)"; $search_conditions[] = "({chatthread}.agentName LIKE :query)";
} }
if ($searchType == 'visitor' || $searchType == 'all') { if ($search_type == 'visitor' || $search_type == 'all') {
$searchConditions[] = "({chatthread}.userName LIKE :query)"; $search_conditions[] = "({chatthread}.userName LIKE :query)";
$searchConditions[] = "({chatthread}.remote LIKE :query)"; $search_conditions[] = "({chatthread}.remote LIKE :query)";
} }
// Load threads // Load threads
list($threads_count) = $db->query( list($threads_count) = $db->query(
"SELECT COUNT(DISTINCT {chatthread}.dtmcreated) " . ("SELECT COUNT(DISTINCT {chatthread}.dtmcreated) "
"FROM {chatthread}, {chatmessage} " . . "FROM {chatthread}, {chatmessage} "
"WHERE {chatmessage}.threadid = {chatthread}.threadid " . . "WHERE {chatmessage}.threadid = {chatthread}.threadid "
"AND ({chatthread}.invitationstate = :invitation_accepted " . . "AND ({chatthread}.invitationstate = :invitation_accepted "
"OR {chatthread}.invitationstate = :invitation_not_invited) " . . "OR {chatthread}.invitationstate = :invitation_not_invited) "
"AND (" . implode(' OR ', $searchConditions) . ")", . "AND (" . implode(' OR ', $search_conditions) . ")"),
$values, $values,
array( array(
'return_rows' => Database::RETURN_ONE_ROW, 'return_rows' => Database::RETURN_ONE_ROW,
'fetch_type' => Database::FETCH_NUM 'fetch_type' => Database::FETCH_NUM,
) )
); );
@ -102,14 +106,14 @@ if ($query !== false) {
$limit_end = intval($pagination_info['end'] - $pagination_info['start']); $limit_end = intval($pagination_info['end'] - $pagination_info['start']);
$threads_list = $db->query( $threads_list = $db->query(
"SELECT DISTINCT {chatthread}.* " . ("SELECT DISTINCT {chatthread}.* "
"FROM {chatthread}, {chatmessage} " . . "FROM {chatthread}, {chatmessage} "
"WHERE {chatmessage}.threadid = {chatthread}.threadid " . . "WHERE {chatmessage}.threadid = {chatthread}.threadid "
"AND ({chatthread}.invitationstate = :invitation_accepted " . . "AND ({chatthread}.invitationstate = :invitation_accepted "
"OR {chatthread}.invitationstate = :invitation_not_invited) " . . "OR {chatthread}.invitationstate = :invitation_not_invited) "
"AND (" . implode(' OR ', $searchConditions) . ") " . . "AND (" . implode(' OR ', $search_conditions) . ") "
"ORDER BY {chatthread}.dtmcreated DESC " . . "ORDER BY {chatthread}.dtmcreated DESC "
"LIMIT " . $limit_start . ", " .$limit_end, . "LIMIT " . $limit_start . ", " . $limit_end),
$values, $values,
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
@ -122,23 +126,18 @@ if ($query !== false) {
$page['pagination.items'] = false; $page['pagination.items'] = false;
} }
$page['formq'] = topage($query); $page['formq'] = to_page($query);
} else { } else {
$page['pagination'] = false; $page['pagination'] = false;
$page['pagination.items'] = false; $page['pagination.items'] = false;
} }
$page['formtype'] = $searchType; $page['formtype'] = $search_type;
$page['forminsystemmessages'] = $searchInSystemMessages; $page['forminsystemmessages'] = $search_in_system_messages;
$page['title'] = getlocal("page_analysis.search.title"); $page['title'] = getlocal("page_analysis.search.title");
$page['menuid'] = "history"; $page['menuid'] = "history";
$page = array_merge( $page = array_merge($page, prepare_menu($operator));
$page,
prepare_menu($operator)
);
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('thread_search', $page); $page_style->render('thread_search', $page);
?>

View File

@ -26,7 +26,7 @@ require_once(MIBEW_FS_ROOT.'/libs/operator.php');
$operator = check_login(); $operator = check_login();
force_password($operator); force_password($operator);
$isonline = is_operator_online($operator['operatorid']); $is_online = is_operator_online($operator['operatorid']);
$page = array( $page = array(
'version' => MIBEW_VERSION, 'version' => MIBEW_VERSION,
@ -37,17 +37,12 @@ $page = array(
'updateWizard' => MIBEW_WEB_ROOT . "/install/", 'updateWizard' => MIBEW_WEB_ROOT . "/install/",
'newFeatures' => Settings::get('featuresversion') != FEATURES_VERSION, 'newFeatures' => Settings::get('featuresversion') != FEATURES_VERSION,
'featuresPage' => MIBEW_WEB_ROOT . "/operator/features.php", 'featuresPage' => MIBEW_WEB_ROOT . "/operator/features.php",
'isOnline' => $isonline, 'isOnline' => $is_online,
'title' => getlocal("topMenu.admin"), 'title' => getlocal("topMenu.admin"),
'menuid' => "main", 'menuid' => "main",
); );
$page = array_merge( $page = array_merge($page, prepare_menu($operator));
$page,
prepare_menu($operator)
);
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('menu', $page); $page_style->render('menu', $page);
?>

View File

@ -21,5 +21,3 @@ require_once(MIBEW_FS_ROOT.'/libs/operator.php');
$processor = \Mibew\RequestProcessor\InviteProcessor::getInstance(); $processor = \Mibew\RequestProcessor\InviteProcessor::getInstance();
$processor->receiveRequest($_POST['data']); $processor->receiveRequest($_POST['data']);
?>

View File

@ -28,28 +28,25 @@ require_once(MIBEW_FS_ROOT.'/libs/settings.php');
$operator = check_login(); $operator = check_login();
$stylelist = InvitationStyle::availableStyles(); $style_list = InvitationStyle::availableStyles();
$preview = verifyparam("preview", "/^\w+$/", "default"); $preview = verify_param("preview", "/^\w+$/", "default");
if (!in_array($preview, $stylelist)) { if (!in_array($preview, $style_list)) {
$preview = $stylelist[0]; $preview = $style_list[0];
} }
$page['formpreview'] = $preview; $page['formpreview'] = $preview;
$page['preview'] = $preview; $page['preview'] = $preview;
$page['availablePreviews'] = $stylelist; $page['availablePreviews'] = $style_list;
$page['operatorName'] = (empty($operator['vclocalname'])?$operator['vccommonname']:$operator['vclocalname']); $page['operatorName'] = (empty($operator['vclocalname'])
? $operator['vccommonname']
: $operator['vclocalname']);
$page['title'] = getlocal("page.preview.title"); $page['title'] = getlocal("page.preview.title");
$page['menuid'] = "settings"; $page['menuid'] = "settings";
$page = array_merge( $page = array_merge($page, prepare_menu($operator));
$page,
prepare_menu($operator)
);
$page['tabs'] = setup_settings_tabs(5); $page['tabs'] = setup_settings_tabs(5);
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('invitation_themes', $page); $page_style->render('invitation_themes', $page);
?>

View File

@ -17,22 +17,21 @@
require_once(dirname(dirname(__FILE__)) . '/libs/init.php'); require_once(dirname(dirname(__FILE__)) . '/libs/init.php');
require_once(MIBEW_FS_ROOT . '/libs/invitation.php'); require_once(MIBEW_FS_ROOT . '/libs/invitation.php');
require_once(MIBEW_FS_ROOT.'/libs/track.php'); require_once(MIBEW_FS_ROOT . '/libs/chat.php');
require_once(MIBEW_FS_ROOT . '/libs/operator.php'); require_once(MIBEW_FS_ROOT . '/libs/operator.php');
require_once(MIBEW_FS_ROOT . '/libs/track.php');
$operator = check_login(); $operator = check_login();
$visitorid = verifyparam("visitor", "/^\d{1,8}$/"); $visitor_id = verify_param("visitor", "/^\d{1,8}$/");
$thread = invitation_invite($visitorid, $operator); $thread = invitation_invite($visitor_id, $operator);
if (!$thread) { if (!$thread) {
die("Invitation failed!"); die("Invitation failed!");
} }
// Open chat window for operator // Open chat window for operator
$redirect_to = MIBEW_WEB_ROOT . $redirect_to = MIBEW_WEB_ROOT
'/operator/agent.php?thread=' . intval($thread->id) . . '/operator/agent.php?thread=' . intval($thread->id)
'&token=' . urlencode($thread->lastToken); . '&token=' . urlencode($thread->lastToken);
header('Location: ' . $redirect_to); header('Location: ' . $redirect_to);
?>

View File

@ -29,18 +29,20 @@ $page = array(
); );
if (isset($_POST['login']) && isset($_POST['password'])) { if (isset($_POST['login']) && isset($_POST['password'])) {
$login = getparam('login'); $login = get_param('login');
$password = getparam('password'); $password = get_param('password');
$remember = isset($_POST['isRemember']) && $_POST['isRemember'] == "on"; $remember = isset($_POST['isRemember']) && $_POST['isRemember'] == "on";
$operator = operator_by_login($login); $operator = operator_by_login($login);
if ($operator && isset($operator['vcpassword']) && check_password_hash($operator['vclogin'], $password, $operator['vcpassword']) && !operator_is_disabled($operator)) { $operator_can_login = $operator
&& isset($operator['vcpassword'])
&& check_password_hash($operator['vclogin'], $password, $operator['vcpassword'])
&& !operator_is_disabled($operator);
if ($operator_can_login) {
$target = $password == '' $target = $password == ''
? MIBEW_WEB_ROOT . "/operator/operator.php?op=" . intval($operator['operatorid']) ? MIBEW_WEB_ROOT . "/operator/operator.php?op=" . intval($operator['operatorid'])
: (isset($_SESSION['backpath']) : (isset($_SESSION['backpath']) ? $_SESSION['backpath'] : MIBEW_WEB_ROOT . "/operator/index.php");
? $_SESSION['backpath']
: MIBEW_WEB_ROOT . "/operator/index.php");
login_operator($operator, $remember, is_secure_request()); login_operator($operator, $remember, is_secure_request());
header("Location: $target"); header("Location: $target");
@ -54,10 +56,11 @@ if (isset($_POST['login']) && isset($_POST['password'])) {
$page['formlogin'] = $login; $page['formlogin'] = $login;
} }
} elseif (isset($_GET['login'])) { } elseif (isset($_GET['login'])) {
$login = getgetparam('login'); $login = get_get_param('login');
if (preg_match("/^(\w{1,15})$/", $login)) if (preg_match("/^(\w{1,15})$/", $login)) {
$page['formlogin'] = $login; $page['formlogin'] = $login;
} }
}
$page['localeLinks'] = get_locale_links(MIBEW_WEB_ROOT . "/operator/login.php"); $page['localeLinks'] = get_locale_links(MIBEW_WEB_ROOT . "/operator/login.php");
$page['title'] = getlocal("page_login.title"); $page['title'] = getlocal("page_login.title");
@ -67,5 +70,3 @@ $page['fixedwrap'] = true;
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('login', $page); $page_style->render('login', $page);
?>

View File

@ -21,5 +21,3 @@ require_once(MIBEW_FS_ROOT.'/libs/operator.php');
logout_operator(); logout_operator();
header("Location: " . MIBEW_WEB_ROOT . "/operator/login.php"); header("Location: " . MIBEW_WEB_ROOT . "/operator/login.php");
exit;
?>

View File

@ -24,34 +24,36 @@ require_once(MIBEW_FS_ROOT.'/libs/operator.php');
require_once(MIBEW_FS_ROOT . '/libs/operator_settings.php'); require_once(MIBEW_FS_ROOT . '/libs/operator_settings.php');
$operator = check_login(); $operator = check_login();
csrfchecktoken(); csrf_check_token();
$page = array( $page = array(
'opid' => '', 'opid' => '',
'errors' => array(), 'errors' => array(),
); );
$opId = ''; $op_id = '';
if ((isset($_POST['login']) || !is_capable(CAN_ADMINISTRATE, $operator)) && isset($_POST['password'])) { if ((isset($_POST['login']) || !is_capable(CAN_ADMINISTRATE, $operator)) && isset($_POST['password'])) {
$opId = verifyparam("opid", "/^(\d{1,9})?$/", ""); $op_id = verify_param("opid", "/^(\d{1,9})?$/", "");
if (is_capable(CAN_ADMINISTRATE, $operator)) { if (is_capable(CAN_ADMINISTRATE, $operator)) {
$login = getparam('login'); $login = get_param('login');
} else { } else {
$login = $operator['vclogin']; $login = $operator['vclogin'];
} }
$email = getparam('email'); $email = get_param('email');
$password = getparam('password'); $password = get_param('password');
$passwordConfirm = getparam('passwordConfirm'); $password_confirm = get_param('passwordConfirm');
$localname = getparam('name'); $local_name = get_param('name');
$commonname = getparam('commonname'); $common_name = get_param('commonname');
$code = getparam('code'); $code = get_param('code');
if (!$localname) if (!$local_name) {
$page['errors'][] = no_field("form.field.agent_name"); $page['errors'][] = no_field("form.field.agent_name");
}
if (!$commonname) if (!$common_name) {
$page['errors'][] = no_field("form.field.agent_commonname"); $page['errors'][] = no_field("form.field.agent_commonname");
}
if (!$login) { if (!$login) {
$page['errors'][] = no_field("form.field.login"); $page['errors'][] = no_field("form.field.login");
@ -67,107 +69,108 @@ if ((isset($_POST['login']) || !is_capable(CAN_ADMINISTRATE, $operator)) && isse
$page['errors'][] = getlocal("page_agent.error.wrong_agent_code"); $page['errors'][] = getlocal("page_agent.error.wrong_agent_code");
} }
if (!$opId && !$password) if (!$op_id && !$password) {
$page['errors'][] = no_field("form.field.password"); $page['errors'][] = no_field("form.field.password");
}
if ($password != $passwordConfirm) if ($password != $password_confirm) {
$page['errors'][] = getlocal("my_settings.error.password_match"); $page['errors'][] = getlocal("my_settings.error.password_match");
}
$existing_operator = operator_by_login($login); $existing_operator = operator_by_login($login);
if ((!$opId && $existing_operator) || $duplicate_login = (!$op_id && $existing_operator)
($opId && $existing_operator && $opId != $existing_operator['operatorid'])) || ($op_id
&& $existing_operator
&& $op_id != $existing_operator['operatorid']);
if ($duplicate_login) {
$page['errors'][] = getlocal("page_agent.error.duplicate_login"); $page['errors'][] = getlocal("page_agent.error.duplicate_login");
}
// Check if operator with specified email already exists in the database // Check if operator with specified email already exists in the database
$existing_operator = operator_by_email($email); $existing_operator = operator_by_email($email);
if ( $duplicate_email =
// Create operator with email already in database // Create operator with email already in database
(!$opId && $existing_operator) || (!$op_id && $existing_operator)
// Update operator email to existing one // Update operator email to existing one
($opId && $existing_operator && $opId != $existing_operator['operatorid']) || ($op_id
) { && $existing_operator
&& $op_id != $existing_operator['operatorid']);
if ($duplicate_email) {
$page['errors'][] = getlocal("page_agent.error.duplicate_email"); $page['errors'][] = getlocal("page_agent.error.duplicate_email");
} }
$canmodify = ($opId == $operator['operatorid'] && is_capable(CAN_MODIFYPROFILE, $operator)) $can_modify = ($op_id == $operator['operatorid'] && is_capable(CAN_MODIFYPROFILE, $operator))
|| is_capable(CAN_ADMINISTRATE, $operator); || is_capable(CAN_ADMINISTRATE, $operator);
if (!$canmodify) { if (!$can_modify) {
$page['errors'][] = getlocal('page_agent.cannot_modify'); $page['errors'][] = getlocal('page_agent.cannot_modify');
} }
if (count($page['errors']) == 0) { if (count($page['errors']) == 0) {
if (!$opId) { if (!$op_id) {
$newop = create_operator($login, $email, $password, $localname, $commonname, "", $code); $new_operator = create_operator($login, $email, $password, $local_name, $common_name, "", $code);
header("Location: " . MIBEW_WEB_ROOT . "/operator/avatar.php?op=" . intval($newop['operatorid'])); header("Location: " . MIBEW_WEB_ROOT . "/operator/avatar.php?op=" . intval($new_operator['operatorid']));
exit; exit;
} else { } else {
update_operator($opId, $login, $email, $password, $localname, $commonname, $code); update_operator($op_id, $login, $email, $password, $local_name, $common_name, $code);
// update the session password // update the session password
if (!empty($password) && $opId == $operator['operatorid']) { if (!empty($password) && $op_id == $operator['operatorid']) {
$toDashboard = check_password_hash($login, '', $operator['vcpassword']) && $password != ''; $to_dashboard = check_password_hash($login, '', $operator['vcpassword']) && $password != '';
$_SESSION[SESSION_PREFIX . "operator"]['vcpassword'] = calculate_password_hash($login, $password); $_SESSION[SESSION_PREFIX . "operator"]['vcpassword'] = calculate_password_hash($login, $password);
if($toDashboard) { if ($to_dashboard) {
header("Location: " . MIBEW_WEB_ROOT . "/operator/index.php"); header("Location: " . MIBEW_WEB_ROOT . "/operator/index.php");
exit; exit;
} }
} }
header("Location: " . MIBEW_WEB_ROOT . "/operator/operator.php?op=" . intval($opId) . "&stored"); header("Location: " . MIBEW_WEB_ROOT . "/operator/operator.php?op=" . intval($op_id) . "&stored");
exit; exit;
} }
} else { } else {
$page['formlogin'] = topage($login); $page['formlogin'] = to_page($login);
$page['formname'] = topage($localname); $page['formname'] = to_page($local_name);
$page['formemail'] = topage($email); $page['formemail'] = to_page($email);
$page['formcommonname'] = topage($commonname); $page['formcommonname'] = to_page($common_name);
$page['formcode'] = topage($code); $page['formcode'] = to_page($code);
$page['opid'] = topage($opId); $page['opid'] = to_page($op_id);
} }
} elseif (isset($_GET['op'])) { } elseif (isset($_GET['op'])) {
$opId = verifyparam('op', "/^\d{1,9}$/"); $op_id = verify_param('op', "/^\d{1,9}$/");
$op = operator_by_id($opId); $op = operator_by_id($op_id);
if (!$op) { if (!$op) {
$page['errors'][] = getlocal("no_such_operator"); $page['errors'][] = getlocal("no_such_operator");
$page['opid'] = topage($opId); $page['opid'] = to_page($op_id);
} else { } else {
//show an error if the admin password hasn't been set yet. //show an error if the admin password hasn't been set yet.
if (check_password_hash($operator['vclogin'], '', $operator['vcpassword']) && !isset($_GET['stored'])) if (check_password_hash($operator['vclogin'], '', $operator['vcpassword']) && !isset($_GET['stored'])) {
{
$page['errors'][] = getlocal("my_settings.error.no_password"); $page['errors'][] = getlocal("my_settings.error.no_password");
} }
$page['formlogin'] = topage($op['vclogin']); $page['formlogin'] = to_page($op['vclogin']);
$page['formname'] = topage($op['vclocalename']); $page['formname'] = to_page($op['vclocalename']);
$page['formemail'] = topage($op['vcemail']); $page['formemail'] = to_page($op['vcemail']);
$page['formcommonname'] = topage($op['vccommonname']); $page['formcommonname'] = to_page($op['vccommonname']);
$page['formcode'] = topage($op['code']); $page['formcode'] = to_page($op['code']);
$page['opid'] = topage($op['operatorid']); $page['opid'] = to_page($op['operatorid']);
} }
} }
if (!$opId && !is_capable(CAN_ADMINISTRATE, $operator)) { if (!$op_id && !is_capable(CAN_ADMINISTRATE, $operator)) {
$page['errors'][] = getlocal("page_agent.error.forbidden_create"); $page['errors'][] = getlocal("page_agent.error.forbidden_create");
} }
$canmodify = ($opId == $operator['operatorid'] && is_capable(CAN_MODIFYPROFILE, $operator)) $can_modify = ($op_id == $operator['operatorid'] && is_capable(CAN_MODIFYPROFILE, $operator))
|| is_capable(CAN_ADMINISTRATE, $operator); || is_capable(CAN_ADMINISTRATE, $operator);
$page['stored'] = isset($_GET['stored']); $page['stored'] = isset($_GET['stored']);
$page['canmodify'] = $canmodify ? "1" : ""; $page['canmodify'] = $can_modify ? "1" : "";
$page['canchangelogin'] = is_capable(CAN_ADMINISTRATE, $operator); $page['canchangelogin'] = is_capable(CAN_ADMINISTRATE, $operator);
$page['needChangePassword'] = check_password_hash($operator['vclogin'], '', $operator['vcpassword']); $page['needChangePassword'] = check_password_hash($operator['vclogin'], '', $operator['vcpassword']);
$page['title'] = getlocal("page_agent.title"); $page['title'] = getlocal("page_agent.title");
$page['menuid'] = ($opId == $operator['operatorid']) ? "profile" : "operators"; $page['menuid'] = ($op_id == $operator['operatorid']) ? "profile" : "operators";
$page = array_merge( $page = array_merge($page, prepare_menu($operator));
$page,
prepare_menu($operator)
);
$page['tabs'] = setup_operator_settings_tabs($opId, 0); $page['tabs'] = setup_operator_settings_tabs($op_id, 0);
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('agent', $page); $page_style->render('agent', $page);
?>

View File

@ -25,7 +25,7 @@ require_once(MIBEW_FS_ROOT.'/libs/operator.php');
$operator = check_login(); $operator = check_login();
force_password($operator); force_password($operator);
csrfchecktoken(); csrf_check_token();
$page = array( $page = array(
'errors' => array(), 'errors' => array(),
@ -33,8 +33,8 @@ $page = array(
if (isset($_GET['act'])) { if (isset($_GET['act'])) {
$operatorid = isset($_GET['id']) ? $_GET['id'] : ""; $operator_id = isset($_GET['id']) ? $_GET['id'] : "";
if (!preg_match("/^\d+$/", $operatorid)) { if (!preg_match("/^\d+$/", $operator_id)) {
$page['errors'][] = getlocal("no_such_operator"); $page['errors'][] = getlocal("no_such_operator");
} }
@ -43,12 +43,12 @@ if (isset($_GET['act'])) {
$page['errors'][] = getlocal("page_agents.error.forbidden_remove"); $page['errors'][] = getlocal("page_agents.error.forbidden_remove");
} }
if ($operatorid == $operator['operatorid']) { if ($operator_id == $operator['operatorid']) {
$page['errors'][] = getlocal("page_agents.error.cannot_remove_self"); $page['errors'][] = getlocal("page_agents.error.cannot_remove_self");
} }
if (count($page['errors']) == 0) { if (count($page['errors']) == 0) {
$op = operator_by_id($operatorid); $op = operator_by_id($operator_id);
if (!$op) { if (!$op) {
$page['errors'][] = getlocal("no_such_operator"); $page['errors'][] = getlocal("no_such_operator");
} elseif ($op['vclogin'] == 'admin') { } elseif ($op['vclogin'] == 'admin') {
@ -57,7 +57,7 @@ if (isset($_GET['act'])) {
} }
if (count($page['errors']) == 0) { if (count($page['errors']) == 0) {
delete_operator($operatorid); delete_operator($operator_id);
header("Location: " . MIBEW_WEB_ROOT . "/operator/operators.php"); header("Location: " . MIBEW_WEB_ROOT . "/operator/operators.php");
exit; exit;
} }
@ -65,15 +65,17 @@ if (isset($_GET['act'])) {
if ($_GET['act'] == 'disable' || $_GET['act'] == 'enable') { if ($_GET['act'] == 'disable' || $_GET['act'] == 'enable') {
$act_disable = ($_GET['act'] == 'disable'); $act_disable = ($_GET['act'] == 'disable');
if (!is_capable(CAN_ADMINISTRATE, $operator)) { if (!is_capable(CAN_ADMINISTRATE, $operator)) {
$page['errors'][] = $act_disable?getlocal('page_agents.disable.not.allowed'):getlocal('page_agents.enable.not.allowed'); $page['errors'][] = $act_disable
? getlocal('page_agents.disable.not.allowed')
: getlocal('page_agents.enable.not.allowed');
} }
if ($operatorid == $operator['operatorid'] && $act_disable) { if ($operator_id == $operator['operatorid'] && $act_disable) {
$page['errors'][] = getlocal('page_agents.cannot.disable.self'); $page['errors'][] = getlocal('page_agents.cannot.disable.self');
} }
if (count($page['errors']) == 0) { if (count($page['errors']) == 0) {
$op = operator_by_id($operatorid); $op = operator_by_id($operator_id);
if (!$op) { if (!$op) {
$page['errors'][] = getlocal("no_such_operator"); $page['errors'][] = getlocal("no_such_operator");
} elseif ($op['vclogin'] == 'admin' && $act_disable) { } elseif ($op['vclogin'] == 'admin' && $act_disable) {
@ -85,7 +87,7 @@ if (isset($_GET['act'])) {
$db = Database::getInstance(); $db = Database::getInstance();
$db->query( $db->query(
"update {chatoperator} set idisabled = ? where operatorid = ?", "update {chatoperator} set idisabled = ? where operatorid = ?",
array(($act_disable ? '1' : '0'), $operatorid) array(($act_disable ? '1' : '0'), $operator_id)
); );
header("Location: " . MIBEW_WEB_ROOT . "/operator/operators.php"); header("Location: " . MIBEW_WEB_ROOT . "/operator/operators.php");
@ -94,8 +96,8 @@ if (isset($_GET['act'])) {
} }
} }
$sort['by'] = verifyparam("sortby", "/^(login|commonname|localename|lastseen)$/", "login"); $sort['by'] = verify_param("sortby", "/^(login|commonname|localename|lastseen)$/", "login");
$sort['desc'] = (verifyparam("sortdirection", "/^(desc|asc)$/", "desc") == "desc"); $sort['desc'] = (verify_param("sortdirection", "/^(desc|asc)$/", "desc") == "desc");
$page['formsortby'] = $sort['by']; $page['formsortby'] = $sort['by'];
$page['formsortdirection'] = $sort['desc'] ? 'desc' : 'asc'; $page['formsortdirection'] = $sort['desc'] ? 'desc' : 'asc';
$list_options['sort'] = $sort; $list_options['sort'] = $sort;
@ -108,7 +110,7 @@ $page['availableOrders'] = array(
array('id' => 'login', 'name' => getlocal('page_agents.login')), array('id' => 'login', 'name' => getlocal('page_agents.login')),
array('id' => 'localename', 'name' => getlocal('page_agents.agent_name')), array('id' => 'localename', 'name' => getlocal('page_agents.agent_name')),
array('id' => 'commonname', 'name' => getlocal('page_agents.commonname')), array('id' => 'commonname', 'name' => getlocal('page_agents.commonname')),
array('id' => 'lastseen', 'name' => getlocal('page_agents.status')) array('id' => 'lastseen', 'name' => getlocal('page_agents.status')),
); );
$page['availableDirections'] = array( $page['availableDirections'] = array(
array('id' => 'desc', 'name' => getlocal('page_agents.sortdirection.desc')), array('id' => 'desc', 'name' => getlocal('page_agents.sortdirection.desc')),
@ -120,12 +122,7 @@ $page['menuid'] = "operators";
setlocale(LC_TIME, getstring("time.locale")); setlocale(LC_TIME, getstring("time.locale"));
$page = array_merge( $page = array_merge($page, prepare_menu($operator));
$page,
prepare_menu($operator)
);
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('agents', $page); $page_style->render('agents', $page);
?>

View File

@ -24,64 +24,62 @@ require_once(MIBEW_FS_ROOT.'/libs/operator.php');
require_once(MIBEW_FS_ROOT . '/libs/operator_settings.php'); require_once(MIBEW_FS_ROOT . '/libs/operator_settings.php');
$operator = check_login(); $operator = check_login();
csrfchecktoken(); csrf_check_token();
$operator_in_isolation = in_isolation($operator); $operator_in_isolation = in_isolation($operator);
$opId = verifyparam("op", "/^\d{1,9}$/"); $op_id = verify_param("op", "/^\d{1,9}$/");
$page = array('opid' => $opId); $page = array('opid' => $op_id);
$page['groups'] = $operator_in_isolation?get_all_groups_for_operator($operator):get_all_groups(); $page['groups'] = $operator_in_isolation
? get_all_groups_for_operator($operator)
: get_all_groups();
$page['errors'] = array(); $page['errors'] = array();
$canmodify = is_capable(CAN_ADMINISTRATE, $operator); $can_modify = is_capable(CAN_ADMINISTRATE, $operator);
$op = operator_by_id($opId); $op = operator_by_id($op_id);
if (!$op) { if (!$op) {
$page['errors'][] = getlocal("no_such_operator"); $page['errors'][] = getlocal("no_such_operator");
} elseif (isset($_POST['op'])) { } elseif (isset($_POST['op'])) {
if (!$canmodify) { if (!$can_modify) {
$page['errors'][] = getlocal('page_agent.cannot_modify'); $page['errors'][] = getlocal('page_agent.cannot_modify');
} }
if (count($page['errors']) == 0) { if (count($page['errors']) == 0) {
$new_groups = array(); $new_groups = array();
foreach ($page['groups'] as $group) { foreach ($page['groups'] as $group) {
if (verifyparam("group" . $group['groupid'], "/^on$/", "") == "on") { if (verify_param("group" . $group['groupid'], "/^on$/", "") == "on") {
$new_groups[] = $group['groupid']; $new_groups[] = $group['groupid'];
} }
} }
update_operator_groups($op['operatorid'], $new_groups); update_operator_groups($op['operatorid'], $new_groups);
header("Location: " . MIBEW_WEB_ROOT . "/operator/opgroups.php?op=" . intval($opId) . "&stored"); header("Location: " . MIBEW_WEB_ROOT . "/operator/opgroups.php?op=" . intval($op_id) . "&stored");
exit; exit;
} }
} }
$page['formgroup'] = array(); $page['formgroup'] = array();
$page['currentop'] = $op ? topage(get_operator_name($op)) . " (" . $op['vclogin'] . ")" : getlocal("not_found"); $page['currentop'] = $op
$page['canmodify'] = $canmodify ? "1" : ""; ? to_page(get_operator_name($op)) . " (" . $op['vclogin'] . ")"
: getlocal("not_found");
$page['canmodify'] = $can_modify ? "1" : "";
if ($op) { if ($op) {
foreach (get_operator_groupids($opId) as $rel) { foreach (get_operator_group_ids($op_id) as $rel) {
$page['formgroup'][] = $rel['groupid']; $page['formgroup'][] = $rel['groupid'];
} }
} }
$page['stored'] = isset($_GET['stored']); $page['stored'] = isset($_GET['stored']);
$page['title'] = getlocal("operator.groups.title"); $page['title'] = getlocal("operator.groups.title");
$page['menuid'] = ($page['operatorid'] == $opId) ? "profile" : "operators"; $page['menuid'] = ($page['operatorid'] == $op_id) ? "profile" : "operators";
$page = array_merge( $page = array_merge($page, prepare_menu($operator));
$page,
prepare_menu($operator)
);
$page['tabs'] = setup_operator_settings_tabs($opId, 2); $page['tabs'] = setup_operator_settings_tabs($op_id, 2);
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('operator_groups', $page); $page_style->render('operator_groups', $page);
?>

View File

@ -25,12 +25,12 @@ require_once(MIBEW_FS_ROOT.'/libs/settings.php');
$operator = check_login(); $operator = check_login();
$stylelist = PageStyle::availableStyles(); $style_list = PageStyle::availableStyles();
$preview = verifyparam("preview", "/^\w+$/", "default"); $preview = verify_param("preview", "/^\w+$/", "default");
if (!in_array($preview, $stylelist)) { if (!in_array($preview, $style_list)) {
$style_names = array_keys($stylelist); $style_names = array_keys($style_list);
$preview = $stylelist[$style_names[0]]; $preview = $style_list[$style_names[0]];
} }
$preview_style = new PageStyle($preview); $preview_style = new PageStyle($preview);
@ -40,26 +40,21 @@ $screenshots = array();
foreach ($style_config['screenshots'] as $name => $desc) { foreach ($style_config['screenshots'] as $name => $desc) {
$screenshots[] = array( $screenshots[] = array(
'name' => $name, 'name' => $name,
'file' => MIBEW_WEB_ROOT . '/' . $preview_style->filesPath() 'file' => (MIBEW_WEB_ROOT . '/' . $preview_style->filesPath()
. '/screenshots/' . $name . '.png', . '/screenshots/' . $name . '.png'),
'description' => $desc 'description' => $desc,
); );
} }
$page['formpreview'] = $preview; $page['formpreview'] = $preview;
$page['availablePreviews'] = $stylelist; $page['availablePreviews'] = $style_list;
$page['screenshotsList'] = $screenshots; $page['screenshotsList'] = $screenshots;
$page['title'] = getlocal("page.preview.title"); $page['title'] = getlocal("page.preview.title");
$page['menuid'] = "settings"; $page['menuid'] = "settings";
$page = array_merge( $page = array_merge($page, prepare_menu($operator));
$page,
prepare_menu($operator)
);
$page['tabs'] = setup_settings_tabs(3); $page['tabs'] = setup_settings_tabs(3);
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('page_themes', $page); $page_style->render('page_themes', $page);
?>

View File

@ -25,7 +25,7 @@ require_once(MIBEW_FS_ROOT.'/libs/operator.php');
require_once(MIBEW_FS_ROOT . '/libs/settings.php'); require_once(MIBEW_FS_ROOT . '/libs/settings.php');
$operator = check_login(); $operator = check_login();
csrfchecktoken(); csrf_check_token();
$page = array( $page = array(
'agentId' => '', 'agentId' => '',
@ -33,10 +33,17 @@ $page = array(
); );
$options = array( $options = array(
'online_timeout', 'updatefrequency_operator', 'updatefrequency_chat', 'online_timeout',
'updatefrequency_operator',
'updatefrequency_chat',
'max_connections_from_one_host', 'max_connections_from_one_host',
'updatefrequency_tracking', 'visitors_limit', 'invitation_lifetime', 'updatefrequency_tracking',
'tracking_lifetime', 'thread_lifetime', 'statistics_aggregation_interval'); 'visitors_limit',
'invitation_lifetime',
'tracking_lifetime',
'thread_lifetime',
'statistics_aggregation_interval',
);
$params = array(); $params = array();
foreach ($options as $opt) { foreach ($options as $opt) {
@ -44,58 +51,57 @@ foreach ($options as $opt) {
} }
if (isset($_POST['onlinetimeout'])) { if (isset($_POST['onlinetimeout'])) {
$params['online_timeout'] = getparam('onlinetimeout'); $params['online_timeout'] = get_param('onlinetimeout');
if (!is_numeric($params['online_timeout'])) { if (!is_numeric($params['online_timeout'])) {
$page['errors'][] = wrong_field("settings.onlinetimeout"); $page['errors'][] = wrong_field("settings.onlinetimeout");
} }
$params['updatefrequency_operator'] = getparam('frequencyoperator'); $params['updatefrequency_operator'] = get_param('frequencyoperator');
if (!is_numeric($params['updatefrequency_operator'])) { if (!is_numeric($params['updatefrequency_operator'])) {
$page['errors'][] = wrong_field("settings.frequencyoperator"); $page['errors'][] = wrong_field("settings.frequencyoperator");
} }
$params['updatefrequency_chat'] = getparam('frequencychat'); $params['updatefrequency_chat'] = get_param('frequencychat');
if (!is_numeric($params['updatefrequency_chat'])) { if (!is_numeric($params['updatefrequency_chat'])) {
$page['errors'][] = wrong_field("settings.frequencychat"); $page['errors'][] = wrong_field("settings.frequencychat");
} }
$params['max_connections_from_one_host'] = getparam('onehostconnections'); $params['max_connections_from_one_host'] = get_param('onehostconnections');
if (!is_numeric($params['max_connections_from_one_host'])) { if (!is_numeric($params['max_connections_from_one_host'])) {
$page['errors'][] = getlocal("settings.wrong.onehostconnections"); $page['errors'][] = getlocal("settings.wrong.onehostconnections");
} }
$params['thread_lifetime'] = getparam('threadlifetime'); $params['thread_lifetime'] = get_param('threadlifetime');
if (!is_numeric($params['thread_lifetime'])) { if (!is_numeric($params['thread_lifetime'])) {
$page['errors'][] = getlocal("settings.wrong.threadlifetime"); $page['errors'][] = getlocal("settings.wrong.threadlifetime");
} }
$params['statistics_aggregation_interval'] = getparam('statistics_aggregation_interval'); $params['statistics_aggregation_interval'] = get_param('statistics_aggregation_interval');
if (!is_numeric($params['statistics_aggregation_interval'])) { if (!is_numeric($params['statistics_aggregation_interval'])) {
$page['errors'][] = wrong_field("settings.statistics_aggregation_interval"); $page['errors'][] = wrong_field("settings.statistics_aggregation_interval");
} }
if (Settings::get('enabletracking')) { if (Settings::get('enabletracking')) {
$params['updatefrequency_tracking'] = getparam('frequencytracking'); $params['updatefrequency_tracking'] = get_param('frequencytracking');
if (!is_numeric($params['updatefrequency_tracking'])) { if (!is_numeric($params['updatefrequency_tracking'])) {
$page['errors'][] = wrong_field("settings.frequencytracking"); $page['errors'][] = wrong_field("settings.frequencytracking");
} }
$params['visitors_limit'] = getparam('visitorslimit'); $params['visitors_limit'] = get_param('visitorslimit');
if (!is_numeric($params['visitors_limit'])) { if (!is_numeric($params['visitors_limit'])) {
$page['errors'][] = wrong_field("settings.visitorslimit"); $page['errors'][] = wrong_field("settings.visitorslimit");
} }
$params['invitation_lifetime'] = getparam('invitationlifetime'); $params['invitation_lifetime'] = get_param('invitationlifetime');
if (!is_numeric($params['invitation_lifetime'])) { if (!is_numeric($params['invitation_lifetime'])) {
$page['errors'][] = wrong_field("settings.invitationlifetime"); $page['errors'][] = wrong_field("settings.invitationlifetime");
} }
$params['tracking_lifetime'] = getparam('trackinglifetime'); $params['tracking_lifetime'] = get_param('trackinglifetime');
if (!is_numeric($params['tracking_lifetime'])) { if (!is_numeric($params['tracking_lifetime'])) {
$page['errors'][] = wrong_field("settings.trackinglifetime"); $page['errors'][] = wrong_field("settings.trackinglifetime");
} }
} }
if (count($page['errors']) == 0) { if (count($page['errors']) == 0) {
@ -121,7 +127,6 @@ if (Settings::get('enabletracking')) {
$page['formvisitorslimit'] = $params['visitors_limit']; $page['formvisitorslimit'] = $params['visitors_limit'];
$page['forminvitationlifetime'] = $params['invitation_lifetime']; $page['forminvitationlifetime'] = $params['invitation_lifetime'];
$page['formtrackinglifetime'] = $params['tracking_lifetime']; $page['formtrackinglifetime'] = $params['tracking_lifetime'];
} }
$page['enabletracking'] = Settings::get('enabletracking'); $page['enabletracking'] = Settings::get('enabletracking');
@ -130,14 +135,9 @@ $page['stored'] = isset($_GET['stored']);
$page['title'] = getlocal("settings.title"); $page['title'] = getlocal("settings.title");
$page['menuid'] = "settings"; $page['menuid'] = "settings";
$page = array_merge( $page = array_merge($page, prepare_menu($operator));
$page,
prepare_menu($operator)
);
$page['tabs'] = setup_settings_tabs(2); $page['tabs'] = setup_settings_tabs(2);
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('performance', $page); $page_style->render('performance', $page);
?>

View File

@ -24,20 +24,19 @@ require_once(MIBEW_FS_ROOT.'/libs/operator.php');
require_once(MIBEW_FS_ROOT . '/libs/operator_settings.php'); require_once(MIBEW_FS_ROOT . '/libs/operator_settings.php');
$operator = check_login(); $operator = check_login();
csrfchecktoken(); csrf_check_token();
$opId = verifyparam("op", "/^\d{1,9}$/"); $op_id = verify_param("op", "/^\d{1,9}$/");
$page = array( $page = array(
'opid' => $opId, 'opid' => $op_id,
'canmodify' => is_capable(CAN_ADMINISTRATE, $operator) ? "1" : "", 'canmodify' => is_capable(CAN_ADMINISTRATE, $operator) ? "1" : "",
'errors' => array(), 'errors' => array(),
); );
$op = operator_by_id($opId); $op = operator_by_id($op_id);
if (!$op) { if (!$op) {
$page['errors'][] = getlocal("no_such_operator"); $page['errors'][] = getlocal("no_such_operator");
} elseif (isset($_POST['op'])) { } elseif (isset($_POST['op'])) {
if (!is_capable(CAN_ADMINISTRATE, $operator)) { if (!is_capable(CAN_ADMINISTRATE, $operator)) {
@ -47,7 +46,7 @@ if (!$op) {
$new_permissions = isset($op['iperm']) ? $op['iperm'] : 0; $new_permissions = isset($op['iperm']) ? $op['iperm'] : 0;
foreach (permission_ids() as $perm => $id) { foreach (permission_ids() as $perm => $id) {
if (verifyparam("permissions$id", "/^on$/", "") == "on") { if (verify_param("permissions$id", "/^on$/", "") == "on") {
$new_permissions |= (1 << $perm); $new_permissions |= (1 << $perm);
} else { } else {
$new_permissions &= ~(1 << $perm); $new_permissions &= ~(1 << $perm);
@ -57,18 +56,17 @@ if (!$op) {
if (count($page['errors']) == 0) { if (count($page['errors']) == 0) {
update_operator_permissions($op['operatorid'], $new_permissions); update_operator_permissions($op['operatorid'], $new_permissions);
if ($opId && $_SESSION[SESSION_PREFIX."operator"] && $operator['operatorid'] == $opId) { if ($op_id && $_SESSION[SESSION_PREFIX . "operator"] && $operator['operatorid'] == $op_id) {
$_SESSION[SESSION_PREFIX . "operator"]['iperm'] = $new_permissions; $_SESSION[SESSION_PREFIX . "operator"]['iperm'] = $new_permissions;
} }
header("Location: " . MIBEW_WEB_ROOT . "/operator/permissions.php?op=" . intval($opId) . "&stored"); header("Location: " . MIBEW_WEB_ROOT . "/operator/permissions.php?op=" . intval($op_id) . "&stored");
exit; exit;
} }
} }
$page['permissionsList'] = get_permission_list(); $page['permissionsList'] = get_permission_list();
$page['formpermissions'] = array(""); $page['formpermissions'] = array("");
$page['currentop'] = $op ? topage(get_operator_name($op)) . " (" . $op['vclogin'] . ")" : getlocal("not_found"); $page['currentop'] = $op ? to_page(get_operator_name($op)) . " (" . $op['vclogin'] . ")" : getlocal("not_found");
if ($op) { if ($op) {
foreach (permission_ids() as $perm => $id) { foreach (permission_ids() as $perm => $id) {
@ -80,16 +78,11 @@ if ($op) {
$page['stored'] = isset($_GET['stored']); $page['stored'] = isset($_GET['stored']);
$page['title'] = getlocal("permissions.title"); $page['title'] = getlocal("permissions.title");
$page['menuid'] = ($operator['operatorid'] == $opId) ? "profile" : "operators"; $page['menuid'] = ($operator['operatorid'] == $op_id) ? "profile" : "operators";
$page = array_merge( $page = array_merge($page, prepare_menu($operator));
$page,
prepare_menu($operator)
);
$page['tabs'] = setup_operator_settings_tabs($opId, 3); $page['tabs'] = setup_operator_settings_tabs($op_id, 3);
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('permissions', $page); $page_style->render('permissions', $page);
?>

View File

@ -25,13 +25,14 @@ require_once(dirname(dirname(__FILE__)).'/libs/init.php');
require_once(MIBEW_FS_ROOT . '/libs/operator.php'); require_once(MIBEW_FS_ROOT . '/libs/operator.php');
require_once(MIBEW_FS_ROOT . '/libs/chat.php'); require_once(MIBEW_FS_ROOT . '/libs/chat.php');
require_once(MIBEW_FS_ROOT . '/libs/groups.php'); require_once(MIBEW_FS_ROOT . '/libs/groups.php');
require_once(MIBEW_FS_ROOT . '/libs/track.php');
$operator = check_login(); $operator = check_login();
$threadid = verifyparam("thread", "/^\d{1,8}$/"); $thread_id = verify_param("thread", "/^\d{1,8}$/");
$token = verifyparam("token", "/^\d{1,8}$/"); $token = verify_param("token", "/^\d{1,8}$/");
$thread = Thread::load($threadid, $token); $thread = Thread::load($thread_id, $token);
if (!$thread) { if (!$thread) {
die("wrong thread"); die("wrong thread");
} }
@ -44,15 +45,18 @@ $page = array(
$chat_style = new ChatStyle(ChatStyle::currentStyle()); $chat_style = new ChatStyle(ChatStyle::currentStyle());
if (isset($_GET['nextGroup'])) { if (isset($_GET['nextGroup'])) {
$nextid = verifyparam("nextGroup", "/^\d{1,8}$/"); $next_id = verify_param("nextGroup", "/^\d{1,8}$/");
$nextGroup = group_by_id($nextid); $next_group = group_by_id($next_id);
if ($nextGroup) { if ($next_group) {
$page['message'] = getlocal2("chat.redirected.group.content", array(topage(get_group_name($nextGroup)))); $page['message'] = getlocal2(
"chat.redirected.group.content",
array(to_page(get_group_name($next_group)))
);
if ($thread->state == Thread::STATE_CHATTING) { if ($thread->state == Thread::STATE_CHATTING) {
$thread->state = Thread::STATE_WAITING; $thread->state = Thread::STATE_WAITING;
$thread->nextAgent = 0; $thread->nextAgent = 0;
$thread->groupId = $nextid; $thread->groupId = $next_id;
$thread->agentId = 0; $thread->agentId = 0;
$thread->agentName = ''; $thread->agentName = '';
$thread->save(); $thread->save();
@ -71,26 +75,29 @@ if (isset($_GET['nextGroup'])) {
} else { } else {
$page['errors'][] = "Unknown group"; $page['errors'][] = "Unknown group";
} }
} else { } else {
$nextid = verifyparam("nextAgent", "/^\d{1,8}$/"); $next_id = verify_param("nextAgent", "/^\d{1,8}$/");
$nextOperator = operator_by_id($nextid); $next_operator = operator_by_id($next_id);
if ($nextOperator) { if ($next_operator) {
$page['message'] = getlocal2("chat.redirected.content", array(topage(get_operator_name($nextOperator)))); $page['message'] = getlocal2(
"chat.redirected.content",
array(to_page(get_operator_name($next_operator)))
);
if ($thread->state == Thread::STATE_CHATTING) { if ($thread->state == Thread::STATE_CHATTING) {
$thread->state = Thread::STATE_WAITING; $thread->state = Thread::STATE_WAITING;
$thread->nextAgent = $nextid; $thread->nextAgent = $next_id;
$thread->agentId = 0; $thread->agentId = 0;
if ($thread->groupId != 0) { if ($thread->groupId != 0) {
$db = Database::getInstance(); $db = Database::getInstance();
list($groups_count) = $db->query( list($groups_count) = $db->query(
"select count(*) AS count from {chatgroupoperator} " . ("SELECT count(*) AS count "
"where operatorid = ? and groupid = ?", . "FROM {chatgroupoperator} "
array($nextid, $thread->groupId), . "WHERE operatorid = ? AND groupid = ?"),
array($next_id, $thread->groupId),
array( array(
'return_rows' => Database::RETURN_ONE_ROW, 'return_rows' => Database::RETURN_ONE_ROW,
'fetch_type' => Database::FETCH_NUM 'fetch_type' => Database::FETCH_NUM,
) )
); );
if ($groups_count === 0) { if ($groups_count === 0) {
@ -114,15 +121,10 @@ if (isset($_GET['nextGroup'])) {
} }
} }
$page = array_merge_recursive( $page = array_merge_recursive($page, setup_logo());
$page,
setup_logo()
);
if (count($page['errors']) > 0) { if (count($page['errors']) > 0) {
$chat_style->render('error', $page); $chat_style->render('error', $page);
} else { } else {
$chat_style->render('redirected', $page); $chat_style->render('redirected', $page);
} }
?>

View File

@ -36,10 +36,10 @@ $page = array(
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$opId = verifyparam("id", "/^\d{1,9}$/"); $op_id = verify_param("id", "/^\d{1,9}$/");
$token = verifyparam("token", "/^[\dabcdef]+$/"); $token = verify_param("token", "/^[\dabcdef]+$/");
$operator = operator_by_id($opId); $operator = operator_by_id($op_id);
if (!$operator) { if (!$operator) {
$page['errors'][] = "No such operator"; $page['errors'][] = "No such operator";
@ -50,23 +50,29 @@ if (!$operator) {
} }
if (count($page['errors']) == 0 && isset($_POST['password'])) { if (count($page['errors']) == 0 && isset($_POST['password'])) {
$password = getparam('password'); $password = get_param('password');
$passwordConfirm = getparam('passwordConfirm'); $password_confirm = get_param('passwordConfirm');
if (!$password) if (!$password) {
$page['errors'][] = no_field("form.field.password"); $page['errors'][] = no_field("form.field.password");
}
if ($password != $passwordConfirm) if ($password != $password_confirm) {
$page['errors'][] = getlocal("my_settings.error.password_match"); $page['errors'][] = getlocal("my_settings.error.password_match");
}
if (count($page['errors']) == 0) { if (count($page['errors']) == 0) {
$page['isdone'] = true; $page['isdone'] = true;
$db = Database::getInstance(); $db = Database::getInstance();
$db->query( $db->query(
"update {chatoperator} set vcpassword = ?, vcrestoretoken = '' " . ("UPDATE {chatoperator} "
"where operatorid = ?", . "SET vcpassword = ?, vcrestoretoken = '' "
array(calculate_password_hash($operator['vclogin'], $password), $opId) . "WHERE operatorid = ?"),
array(
calculate_password_hash($operator['vclogin'], $password),
$op_id,
)
); );
$page['loginname'] = $operator['vclogin']; $page['loginname'] = $operator['vclogin'];
@ -75,10 +81,8 @@ if (count($page['errors']) == 0 && isset($_POST['password'])) {
} }
} }
$page['id'] = $opId; $page['id'] = $op_id;
$page['token'] = $token; $page['token'] = $token;
$page['isdone'] = false; $page['isdone'] = false;
$page_style->render('resetpwd', $page); $page_style->render('resetpwd', $page);
?>

View File

@ -34,39 +34,53 @@ $page = array(
'errors' => array(), 'errors' => array(),
); );
$loginoremail = ""; $login_or_email = "";
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
if (isset($_POST['loginoremail'])) { if (isset($_POST['loginoremail'])) {
$loginoremail = getparam("loginoremail"); $login_or_email = get_param("loginoremail");
$torestore = is_valid_email($loginoremail) ? operator_by_email($loginoremail) : operator_by_login($loginoremail); $to_restore = is_valid_email($login_or_email)
if (!$torestore) { ? operator_by_email($login_or_email)
: operator_by_login($login_or_email);
if (!$to_restore) {
$page['errors'][] = getlocal("no_such_operator"); $page['errors'][] = getlocal("no_such_operator");
} }
$email = $torestore['vcemail']; $email = $to_restore['vcemail'];
if (count($page['errors']) == 0 && !is_valid_email($email)) { if (count($page['errors']) == 0 && !is_valid_email($email)) {
$page['errors'][] = "Operator hasn't set his e-mail"; $page['errors'][] = "Operator hasn't set his e-mail";
} }
if (count($page['errors']) == 0) { if (count($page['errors']) == 0) {
$token = sha1($torestore['vclogin'] . (function_exists('openssl_random_pseudo_bytes') ? openssl_random_pseudo_bytes(32) : (time() + microtime()) . mt_rand(0, 99999999))); $token = sha1($to_restore['vclogin'] . (function_exists('openssl_random_pseudo_bytes')
? openssl_random_pseudo_bytes(32)
: (time() + microtime()) . mt_rand(0, 99999999)));
$db = Database::getInstance(); $db = Database::getInstance();
$db->query( $db->query(
"update {chatoperator} set dtmrestore = :now, " . ("UPDATE {chatoperator} "
"vcrestoretoken = :token where operatorid = :operatorid", . "SET dtmrestore = :now, vcrestoretoken = :token "
. "WHERE operatorid = :operatorid"),
array( array(
':now' => time(), ':now' => time(),
':token' => $token, ':token' => $token,
':operatorid' => $torestore['operatorid'] ':operatorid' => $to_restore['operatorid'],
) )
); );
$href = get_app_location(true, false) . "/operator/resetpwd.php?id=" . $torestore['operatorid'] . "&token=$token"; $href = get_app_location(true, false) . "/operator/resetpwd.php?id="
mibew_mail($email, $email, getstring("restore.mailsubj"), getstring2("restore.mailtext", array(get_operator_name($torestore), $href))); . $to_restore['operatorid'] . "&token=$token";
mibew_mail(
$email,
$email,
getstring("restore.mailsubj"),
getstring2(
"restore.mailtext",
array(get_operator_name($to_restore), $href)
)
);
$page['isdone'] = true; $page['isdone'] = true;
$page_style->render('restore', $page); $page_style->render('restore', $page);
@ -74,11 +88,9 @@ if (isset($_POST['loginoremail'])) {
} }
} }
$page['formloginoremail'] = topage($loginoremail); $page['formloginoremail'] = to_page($login_or_email);
$page['localeLinks'] = get_locale_links(MIBEW_WEB_ROOT . "/operator/restore.php"); $page['localeLinks'] = get_locale_links(MIBEW_WEB_ROOT . "/operator/restore.php");
$page['isdone'] = false; $page['isdone'] = false;
$page_style->render('restore', $page); $page_style->render('restore', $page);
?>

View File

@ -29,7 +29,7 @@ require_once(MIBEW_FS_ROOT.'/libs/cron.php');
$operator = check_login(); $operator = check_login();
force_password($operator); force_password($operator);
csrfchecktoken(); csrf_check_token();
$page = array( $page = array(
'agentId' => '', 'agentId' => '',
@ -47,7 +47,7 @@ $options = array(
'geolink', 'geolink',
'geolinkparams', 'geolinkparams',
'sendmessagekey', 'sendmessagekey',
'cron_key' 'cron_key',
); );
$params = array(); $params = array();
@ -70,29 +70,33 @@ if (Settings::get('enabletracking')) {
} }
if (isset($_POST['email']) && isset($_POST['title']) && isset($_POST['logo'])) { if (isset($_POST['email']) && isset($_POST['title']) && isset($_POST['logo'])) {
$params['email'] = getparam('email'); $params['email'] = get_param('email');
$params['title'] = getparam('title'); $params['title'] = get_param('title');
$params['logo'] = getparam('logo'); $params['logo'] = get_param('logo');
$params['hosturl'] = getparam('hosturl'); $params['hosturl'] = get_param('hosturl');
$params['usernamepattern'] = getparam('usernamepattern'); $params['usernamepattern'] = get_param('usernamepattern');
$params['chattitle'] = getparam('chattitle'); $params['chattitle'] = get_param('chattitle');
$params['geolink'] = getparam('geolink'); $params['geolink'] = get_param('geolink');
$params['geolinkparams'] = getparam('geolinkparams'); $params['geolinkparams'] = get_param('geolinkparams');
$params['sendmessagekey'] = verifyparam('sendmessagekey', "/^c?enter$/"); $params['sendmessagekey'] = verify_param('sendmessagekey', "/^c?enter$/");
$params['cron_key'] = getparam('cronkey'); $params['cron_key'] = get_param('cronkey');
$styles_params['chat_style'] = verifyparam("chat_style", "/^\w+$/", $styles_params['chat_style']); $styles_params['chat_style'] = verify_param("chat_style", "/^\w+$/", $styles_params['chat_style']);
if (!in_array($styles_params['chat_style'], $chat_style_list)) { if (!in_array($styles_params['chat_style'], $chat_style_list)) {
$styles_params['chat_style'] = $chat_style_list[0]; $styles_params['chat_style'] = $chat_style_list[0];
} }
$styles_params['page_style'] = verifyparam("page_style", "/^\w+$/", $styles_params['page_style']); $styles_params['page_style'] = verify_param("page_style", "/^\w+$/", $styles_params['page_style']);
if (!in_array($styles_params['page_style'], $page_style_list)) { if (!in_array($styles_params['page_style'], $page_style_list)) {
$styles_params['page_style'] = $page_style_list[0]; $styles_params['page_style'] = $page_style_list[0];
} }
if (Settings::get('enabletracking')) { if (Settings::get('enabletracking')) {
$styles_params['invitation_style'] = verifyparam("invitation_style", "/^\w+$/", $styles_params['invitation_style']); $styles_params['invitation_style'] = verify_param(
"invitation_style",
"/^\w+$/",
$styles_params['invitation_style']
);
if (!in_array($styles_params['invitation_style'], $invitation_style_list)) { if (!in_array($styles_params['invitation_style'], $invitation_style_list)) {
$styles_params['invitation_style'] = $invitation_style_list[0]; $styles_params['invitation_style'] = $invitation_style_list[0];
} }
@ -103,9 +107,15 @@ if (isset($_POST['email']) && isset($_POST['title']) && isset($_POST['logo'])) {
} }
if ($params['geolinkparams']) { if ($params['geolinkparams']) {
foreach (preg_split("/,/", $params['geolinkparams']) as $oneparam) { foreach (preg_split("/,/", $params['geolinkparams']) as $one_param) {
if (!preg_match("/^\s*(toolbar|scrollbars|location|status|menubar|width|height|resizable)=\d{1,4}$/", $oneparam)) { $wrong_param = !preg_match(
$page['errors'][] = "Wrong link parameter: \"$oneparam\", should be one of 'toolbar, scrollbars, location, status, menubar, width, height or resizable'"; "/^\s*(toolbar|scrollbars|location|status|menubar|width|height|resizable)=\d{1,4}$/",
$one_param
);
if ($wrong_param) {
$page['errors'][] = "Wrong link parameter: \"$one_param\", "
. "should be one of 'toolbar, scrollbars, location, "
. "status, menubar, width, height or resizable'";
} }
} }
} }
@ -134,17 +144,17 @@ if (isset($_POST['email']) && isset($_POST['title']) && isset($_POST['logo'])) {
} }
} }
$page['formemail'] = topage($params['email']); $page['formemail'] = to_page($params['email']);
$page['formtitle'] = topage($params['title']); $page['formtitle'] = to_page($params['title']);
$page['formlogo'] = topage($params['logo']); $page['formlogo'] = to_page($params['logo']);
$page['formhosturl'] = topage($params['hosturl']); $page['formhosturl'] = to_page($params['hosturl']);
$page['formgeolink'] = topage($params['geolink']); $page['formgeolink'] = to_page($params['geolink']);
$page['formgeolinkparams'] = topage($params['geolinkparams']); $page['formgeolinkparams'] = to_page($params['geolinkparams']);
$page['formusernamepattern'] = topage($params['usernamepattern']); $page['formusernamepattern'] = to_page($params['usernamepattern']);
$page['formpagestyle'] = $styles_params['page_style']; $page['formpagestyle'] = $styles_params['page_style'];
$page['availablePageStyles'] = $page_style_list; $page['availablePageStyles'] = $page_style_list;
$page['formchatstyle'] = $styles_params['chat_style']; $page['formchatstyle'] = $styles_params['chat_style'];
$page['formchattitle'] = topage($params['chattitle']); $page['formchattitle'] = to_page($params['chattitle']);
$page['formsendmessagekey'] = $params['sendmessagekey']; $page['formsendmessagekey'] = $params['sendmessagekey'];
$page['availableChatStyles'] = $chat_style_list; $page['availableChatStyles'] = $chat_style_list;
$page['stored'] = isset($_GET['stored']); $page['stored'] = isset($_GET['stored']);
@ -161,14 +171,9 @@ if (Settings::get('enabletracking')) {
$page['availableInvitationStyles'] = $invitation_style_list; $page['availableInvitationStyles'] = $invitation_style_list;
} }
$page = array_merge( $page = array_merge($page, prepare_menu($operator));
$page,
prepare_menu($operator)
);
$page['tabs'] = setup_settings_tabs(0); $page['tabs'] = setup_settings_tabs(0);
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('settings', $page); $page_style->render('settings', $page);
?>

View File

@ -26,6 +26,7 @@ require_once(MIBEW_FS_ROOT.'/libs/chat.php');
require_once(MIBEW_FS_ROOT . '/libs/operator.php'); require_once(MIBEW_FS_ROOT . '/libs/operator.php');
require_once(MIBEW_FS_ROOT . '/libs/statistics.php'); require_once(MIBEW_FS_ROOT . '/libs/statistics.php');
require_once(MIBEW_FS_ROOT . '/libs/cron.php'); require_once(MIBEW_FS_ROOT . '/libs/cron.php');
require_once(MIBEW_FS_ROOT . '/libs/track.php');
$operator = check_login(); $operator = check_login();
force_password($operator); force_password($operator);
@ -33,15 +34,15 @@ force_password($operator);
setlocale(LC_TIME, getstring("time.locale")); setlocale(LC_TIME, getstring("time.locale"));
$page = array(); $page = array();
$page['operator'] = topage(get_operator_name($operator)); $page['operator'] = to_page(get_operator_name($operator));
$page['availableDays'] = range(1, 31); $page['availableDays'] = range(1, 31);
$page['availableMonth'] = get_month_selection(time() - 400 * 24 * 60 * 60, time() + 50 * 24 * 60 * 60); $page['availableMonth'] = get_month_selection(time() - 400 * 24 * 60 * 60, time() + 50 * 24 * 60 * 60);
$page['showresults'] = false; $page['showresults'] = false;
$statisticstype = verifyparam("type", "/^(bydate|byagent|bypage)$/", "bydate"); $statistics_type = verify_param("type", "/^(bydate|byagent|bypage)$/", "bydate");
$page['type'] = $statisticstype; $page['type'] = $statistics_type;
$page['showbydate'] = ($statisticstype == 'bydate'); $page['showbydate'] = ($statistics_type == 'bydate');
$page['showbyagent'] = ($statisticstype == 'byagent'); $page['showbyagent'] = ($statistics_type == 'byagent');
$page['showbypage'] = ($statisticstype == 'bypage'); $page['showbypage'] = ($statistics_type == 'bypage');
$page['cron_path'] = cron_get_uri(Settings::get('cron_key')); $page['cron_path'] = cron_get_uri(Settings::get('cron_key'));
$page['last_cron_run'] = Settings::get('_last_cron_run'); $page['last_cron_run'] = Settings::get('_last_cron_run');
@ -51,13 +52,12 @@ $page['show_invitations_info'] = (bool)Settings::get('enabletracking');
$page['errors'] = array(); $page['errors'] = array();
if (isset($_GET['startday'])) { if (isset($_GET['startday'])) {
$startday = verifyparam("startday", "/^\d+$/"); $start_day = verify_param("startday", "/^\d+$/");
$startmonth = verifyparam("startmonth", "/^\d{2}.\d{2}$/"); $start_month = verify_param("startmonth", "/^\d{2}.\d{2}$/");
$endday = verifyparam("endday", "/^\d+$/"); $end_day = verify_param("endday", "/^\d+$/");
$endmonth = verifyparam("endmonth", "/^\d{2}.\d{2}$/"); $end_month = verify_param("endmonth", "/^\d{2}.\d{2}$/");
$start = get_form_date($startday, $startmonth); $start = get_form_date($start_day, $start_month);
$end = get_form_date($endday, $endmonth) + 24 * 60 * 60; $end = get_form_date($end_day, $end_month) + 24 * 60 * 60;
} else { } else {
$curr = getdate(time()); $curr = getdate(time());
if ($curr['mday'] < 7) { if ($curr['mday'] < 7) {
@ -86,111 +86,106 @@ if ($start > $end) {
$page['errors'][] = getlocal("statistics.wrong.dates"); $page['errors'][] = getlocal("statistics.wrong.dates");
} }
$activetab = 0; $active_tab = 0;
$db = Database::getInstance(); $db = Database::getInstance();
if ($statisticstype == 'bydate') { if ($statistics_type == 'bydate') {
$page['reportByDate'] = $db->query( $page['reportByDate'] = $db->query(
"SELECT DATE(FROM_UNIXTIME(date)) AS date, " . ("SELECT DATE(FROM_UNIXTIME(date)) AS date, "
"threads, " . . "threads, "
"missedthreads, " . . "missedthreads, "
"sentinvitations, " . . "sentinvitations, "
"acceptedinvitations, " . . "acceptedinvitations, "
"rejectedinvitations, " . . "rejectedinvitations, "
"ignoredinvitations, " . . "ignoredinvitations, "
"operatormessages AS agents, " . . "operatormessages AS agents, "
"usermessages AS users, " . . "usermessages AS users, "
"averagewaitingtime AS avgwaitingtime, " . . "averagewaitingtime AS avgwaitingtime, "
"averagechattime AS avgchattime " . . "averagechattime AS avgchattime "
"FROM {chatthreadstatistics} s " . . "FROM {chatthreadstatistics} s "
"WHERE s.date >= :start " . . "WHERE s.date >= :start "
"AND s.date < :end " . . "AND s.date < :end "
"GROUP BY DATE(FROM_UNIXTIME(date)) " . . "GROUP BY DATE(FROM_UNIXTIME(date)) "
"ORDER BY s.date DESC", . "ORDER BY s.date DESC"),
array( array(
':start' => $start, ':start' => $start,
':end' => $end ':end' => $end,
), ),
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
$page['reportByDateTotal'] = $db->query( $page['reportByDateTotal'] = $db->query(
"SELECT DATE(FROM_UNIXTIME(date)) AS date, " . ("SELECT DATE(FROM_UNIXTIME(date)) AS date, "
"SUM(threads) AS threads, " . . "SUM(threads) AS threads, "
"SUM(missedthreads) AS missedthreads, " . . "SUM(missedthreads) AS missedthreads, "
"SUM(sentinvitations) AS sentinvitations, " . . "SUM(sentinvitations) AS sentinvitations, "
"SUM(acceptedinvitations) AS acceptedinvitations, " . . "SUM(acceptedinvitations) AS acceptedinvitations, "
"SUM(rejectedinvitations) AS rejectedinvitations, " . . "SUM(rejectedinvitations) AS rejectedinvitations, "
"SUM(ignoredinvitations) AS ignoredinvitations, " . . "SUM(ignoredinvitations) AS ignoredinvitations, "
"SUM(operatormessages) AS agents, " . . "SUM(operatormessages) AS agents, "
"SUM(usermessages) AS users, " . . "SUM(usermessages) AS users, "
"ROUND(SUM(averagewaitingtime * s.threads) / SUM(s.threads),1) AS avgwaitingtime, " . . "ROUND(SUM(averagewaitingtime * s.threads) / SUM(s.threads),1) AS avgwaitingtime, "
"ROUND(SUM(averagechattime * s.threads) / SUM(s.threads),1) AS avgchattime " . . "ROUND(SUM(averagechattime * s.threads) / SUM(s.threads),1) AS avgchattime "
"FROM {chatthreadstatistics} s " . . "FROM {chatthreadstatistics} s "
"WHERE s.date >= :start " . . "WHERE s.date >= :start "
"AND s.date < :end", . "AND s.date < :end"),
array( array(
':start' => $start, ':start' => $start,
':end' => $end ':end' => $end,
), ),
array('return_rows' => Database::RETURN_ONE_ROW) array('return_rows' => Database::RETURN_ONE_ROW)
); );
$activetab = 0; $active_tab = 0;
} elseif($statisticstype == 'byagent') { } elseif ($statistics_type == 'byagent') {
$page['reportByAgent'] = $db->query( $page['reportByAgent'] = $db->query(
"SELECT o.vclocalename AS name, " . ("SELECT o.vclocalename AS name, "
"SUM(s.threads) AS threads, " . . "SUM(s.threads) AS threads, "
"SUM(s.messages) AS msgs, " . . "SUM(s.messages) AS msgs, "
"ROUND( " . . "ROUND( "
"SUM(s.averagelength * s.messages) / SUM(s.messages), " . . "SUM(s.averagelength * s.messages) / SUM(s.messages), "
"1) AS avglen, " . . "1) AS avglen, "
"SUM(sentinvitations) AS sentinvitations, " . . "SUM(sentinvitations) AS sentinvitations, "
"SUM(acceptedinvitations) AS acceptedinvitations, " . . "SUM(acceptedinvitations) AS acceptedinvitations, "
"SUM(rejectedinvitations) AS rejectedinvitations, " . . "SUM(rejectedinvitations) AS rejectedinvitations, "
"SUM(ignoredinvitations) AS ignoredinvitations " . . "SUM(ignoredinvitations) AS ignoredinvitations "
"FROM {chatoperatorstatistics} s, {chatoperator} o " . . "FROM {chatoperatorstatistics} s, {chatoperator} o "
"WHERE s.operatorid = o.operatorid " . . "WHERE s.operatorid = o.operatorid "
"AND s.date >= :start " . . "AND s.date >= :start "
"AND s.date < :end " . . "AND s.date < :end "
"GROUP BY s.operatorid", . "GROUP BY s.operatorid"),
array( array(
':start' => $start, ':start' => $start,
':end' => $end ':end' => $end,
), ),
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
$activetab = 1; $active_tab = 1;
} elseif($statisticstype == 'bypage') { } elseif ($statistics_type == 'bypage') {
$page['reportByPage'] = $db->query( $page['reportByPage'] = $db->query(
"SELECT SUM(visits) as visittimes, " . ("SELECT SUM(visits) as visittimes, "
"address, " . . "address, "
"SUM(chats) as chattimes, " . . "SUM(chats) as chattimes, "
"SUM(sentinvitations) AS sentinvitations, " . . "SUM(sentinvitations) AS sentinvitations, "
"SUM(acceptedinvitations) AS acceptedinvitations, " . . "SUM(acceptedinvitations) AS acceptedinvitations, "
"SUM(rejectedinvitations) AS rejectedinvitations, " . . "SUM(rejectedinvitations) AS rejectedinvitations, "
"SUM(ignoredinvitations) AS ignoredinvitations " . . "SUM(ignoredinvitations) AS ignoredinvitations "
"FROM {visitedpagestatistics} " . . "FROM {visitedpagestatistics} "
"WHERE date >= :start " . . "WHERE date >= :start "
"AND date < :end " . . "AND date < :end "
"GROUP BY address", . "GROUP BY address"),
array(':start' => $start, ':end' => $end), array(':start' => $start, ':end' => $end),
array('return_rows' => Database::RETURN_ALL_ROWS) array('return_rows' => Database::RETURN_ALL_ROWS)
); );
$activetab = 2; $active_tab = 2;
} }
$page['showresults'] = count($page['errors']) == 0; $page['showresults'] = count($page['errors']) == 0;
$page['title'] = getlocal("statistics.title"); $page['title'] = getlocal("statistics.title");
$page['menuid'] = "statistics"; $page['menuid'] = "statistics";
$page = array_merge( $page = array_merge($page, prepare_menu($operator));
$page,
prepare_menu($operator)
);
$page['tabs'] = setup_statistics_tabs($activetab); $page['tabs'] = setup_statistics_tabs($active_tab);
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('statistics', $page); $page_style->render('statistics', $page);
?>

View File

@ -26,15 +26,16 @@ require_once(MIBEW_FS_ROOT.'/libs/pagination.php');
require_once(MIBEW_FS_ROOT . '/libs/operator.php'); require_once(MIBEW_FS_ROOT . '/libs/operator.php');
require_once(MIBEW_FS_ROOT . '/libs/groups.php'); require_once(MIBEW_FS_ROOT . '/libs/groups.php');
require_once(MIBEW_FS_ROOT . '/libs/settings.php'); require_once(MIBEW_FS_ROOT . '/libs/settings.php');
require_once(MIBEW_FS_ROOT . '/libs/track.php');
$operator = check_login(); $operator = check_login();
$stylelist = ChatStyle::availableStyles(); $style_list = ChatStyle::availableStyles();
$preview = verifyparam("preview", "/^\w+$/", "default"); $preview = verify_param("preview", "/^\w+$/", "default");
if (!in_array($preview, $stylelist)) { if (!in_array($preview, $style_list)) {
$style_names = array_keys($stylelist); $style_names = array_keys($style_list);
$preview = $stylelist[$style_names[0]]; $preview = $style_list[$style_names[0]];
} }
$chat_style = new ChatStyle($preview); $chat_style = new ChatStyle($preview);
@ -45,26 +46,21 @@ $screenshots = array();
foreach ($style_config['screenshots'] as $name => $desc) { foreach ($style_config['screenshots'] as $name => $desc) {
$screenshots[] = array( $screenshots[] = array(
'name' => $name, 'name' => $name,
'file' => MIBEW_WEB_ROOT . '/' . $chat_style->filesPath() 'file' => (MIBEW_WEB_ROOT . '/' . $chat_style->filesPath()
. '/screenshots/' . $name . '.png', . '/screenshots/' . $name . '.png'),
'description' => $desc 'description' => $desc
); );
} }
$page['formpreview'] = $preview; $page['formpreview'] = $preview;
$page['availablePreviews'] = $stylelist; $page['availablePreviews'] = $style_list;
$page['screenshotsList'] = $screenshots; $page['screenshotsList'] = $screenshots;
$page['title'] = getlocal("page.preview.title"); $page['title'] = getlocal("page.preview.title");
$page['menuid'] = "settings"; $page['menuid'] = "settings";
$page = array_merge( $page = array_merge($page, prepare_menu($operator));
$page,
prepare_menu($operator)
);
$page['tabs'] = setup_settings_tabs(4); $page['tabs'] = setup_settings_tabs(4);
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('themes', $page); $page_style->render('themes', $page);
?>

View File

@ -25,6 +25,7 @@ require_once(MIBEW_FS_ROOT.'/libs/operator.php');
require_once(MIBEW_FS_ROOT . '/libs/chat.php'); require_once(MIBEW_FS_ROOT . '/libs/chat.php');
require_once(MIBEW_FS_ROOT . '/libs/groups.php'); require_once(MIBEW_FS_ROOT . '/libs/groups.php');
require_once(MIBEW_FS_ROOT . '/libs/userinfo.php'); require_once(MIBEW_FS_ROOT . '/libs/userinfo.php');
require_once(MIBEW_FS_ROOT . '/libs/track.php');
$operator = check_login(); $operator = check_login();
@ -34,8 +35,8 @@ setlocale(LC_TIME, getstring("time.locale"));
if (isset($_GET['threadid'])) { if (isset($_GET['threadid'])) {
// Load thread info // Load thread info
$threadid = verifyparam("threadid", "/^(\d{1,9})?$/", ""); $thread_id = verify_param("threadid", "/^(\d{1,9})?$/", "");
$thread = Thread::load($threadid); $thread = Thread::load($thread_id);
$group = group_by_id($thread->groupId); $group = group_by_id($thread->groupId);
$thread_info = array( $thread_info = array(
@ -45,19 +46,14 @@ if (isset($_GET['threadid'])) {
$page['thread_info'] = $thread_info; $page['thread_info'] = $thread_info;
// Build messages list // Build messages list
$lastid = -1; $last_id = -1;
$messages = $thread_info['thread']->getMessages(false, $lastid); $messages = $thread_info['thread']->getMessages(false, $last_id);
$page['threadMessages'] = json_encode($messages); $page['threadMessages'] = json_encode($messages);
} }
$page['title'] = getlocal("thread.chat_log"); $page['title'] = getlocal("thread.chat_log");
$page = array_merge( $page = array_merge($page, prepare_menu($operator, false));
$page,
prepare_menu($operator, false)
);
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('thread_log', $page); $page_style->render('thread_log', $page);
?>

View File

@ -34,20 +34,18 @@ if (Settings::get('enabletracking') == "0") {
} }
if (isset($_GET['thread'])) { if (isset($_GET['thread'])) {
$threadid = verifyparam("thread", "/^\d{1,8}$/"); $thread_id = verify_param("thread", "/^\d{1,8}$/");
} } else {
else { $visitor_id = verify_param("visitor", "/^\d{1,8}$/");
$visitorid = verifyparam("visitor", "/^\d{1,8}$/");
} }
if (isset($threadid)) { if (isset($thread_id)) {
$visitor = track_get_visitor_by_threadid($threadid); $visitor = track_get_visitor_by_thread_id($thread_id);
if (!$visitor) { if (!$visitor) {
die("Wrong thread!"); die("Wrong thread!");
} }
} } else {
else { $visitor = track_get_visitor_by_id($visitor_id);
$visitor = track_get_visitor_by_id($visitorid);
if (!$visitor) { if (!$visitor) {
die("Wrong visitor!"); die("Wrong visitor!");
} }
@ -58,13 +56,13 @@ $page['entry'] = htmlspecialchars($visitor['entry']);
$page['history'] = array(); $page['history'] = array();
ksort($path); ksort($path);
foreach ($path as $k => $v) { foreach ($path as $k => $v) {
$page['history'][] = array( 'date' => date_to_text($k), $page['history'][] = array(
'link' => htmlspecialchars($v) ); 'date' => date_to_text($k),
'link' => htmlspecialchars($v),
);
} }
$page['title'] = getlocal("tracked.path"); $page['title'] = getlocal("tracked.path");
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('tracked', $page); $page_style->render('tracked', $page);
?>

Some files were not shown because too many files have changed in this diff Show More