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/operator.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'] : "";
if ($referer && isset($_SESSION['threadid'])) {
$thread = Thread::load($_SESSION['threadid']);
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);
}
}
$image = verifyparam(isset($_GET['image']) ? "image" : "i", "/^\w+$/", "mibew");
$lang = verifyparam(isset($_GET['language']) ? "language" : "lang", "/^[\w-]{2,5}$/", "");
$image = verify_param(isset($_GET['image']) ? "image" : "i", "/^\w+$/", "mibew");
$lang = verify_param(isset($_GET['language']) ? "language" : "lang", "/^[\w-]{2,5}$/", "");
if (!$lang || !locale_exists($lang)) {
$lang = CURRENT_LOCALE;
}
$groupid = verifyparam( "group", "/^\d{1,8}$/", "");
if($groupid) {
$group_id = verify_param("group", "/^\d{1,8}$/", "");
if ($group_id) {
if (Settings::get('enablegroups') == '1') {
$group = group_by_id($groupid);
$group = group_by_id($group_id);
if (!$group) {
$groupid = "";
$group_id = "";
}
} else {
$groupid = "";
$group_id = "";
}
}
$image_postfix = has_online_operators($groupid) ? "on" : "off";
$filename = "locales/${lang}/button/${image}_${image_postfix}.gif";
$image_postfix = has_online_operators($group_id) ? "on" : "off";
$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("Cache-Control: no-store, no-cache, must-revalidate");
header("Pragma: no-cache");
header("Content-Type: image/gif");
header("Content-Length: ".filesize($filename));
header("Content-Length: " . filesize($file_name));
if (function_exists('fpassthru')) {
@fpassthru($fp);
} else {
@ -70,5 +75,3 @@ if(function_exists('fpassthru')){
}
fclose($fp);
}
exit;
?>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -36,6 +36,8 @@ define('MIBEW_WEB_ROOT', $mibewroot);
// Include common functions
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/misc.php');
require_once(MIBEW_FS_ROOT.'/libs/common/response.php');
@ -48,7 +50,7 @@ function runsql($query, $link)
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)
or show_install_err('Could not connect: ' . mysql_error());

View File

@ -48,6 +48,8 @@ define('MIBEW_WEB_ROOT', $base_url);
// Include common functions
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/misc.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) {
if (! in_array($locale, $existlocales)) {
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
use Mibew\Database;
function load_canned_messages($locale, $groupid)
function load_canned_messages($locale, $group_id)
{
$db = Database::getInstance();
$values = array(':locale' => $locale);
if ($groupid) {
$values[':groupid'] = $groupid;
if ($group_id) {
$values[':groupid'] = $group_id;
}
return $db->query(
"select id, vctitle, vcvalue from {chatresponses} " .
"where locale = :locale AND (" .
($groupid ? "groupid = :groupid" : "groupid is NULL OR groupid = 0") .
") order by vcvalue",
("SELECT id, vctitle, vcvalue FROM {chatresponses} "
. "WHERE locale = :locale AND ("
. ($group_id ? "groupid = :groupid" : "groupid is NULL OR groupid = 0")
. ") ORDER BY vcvalue"),
$values,
array('return_rows' => Database::RETURN_ALL_ROWS)
);
@ -39,10 +40,11 @@ function load_canned_message($key)
{
$db = Database::getInstance();
$result = $db->query(
"select vctitle, vcvalue from {chatresponses} where id = ?",
"SELECT vctitle, vcvalue FROM {chatresponses} WHERE id = ?",
array($key),
array('return_rows' => Database::RETURN_ONE_ROW)
);
return $result ? $result : null;
}
@ -50,24 +52,22 @@ function save_canned_message($key, $title, $message)
{
$db = Database::getInstance();
$db->query(
"update {chatresponses} set vcvalue = ?, vctitle = ? where id = ?",
"UPDATE {chatresponses} SET vcvalue = ?, vctitle = ? WHERE id = ?",
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->query(
"insert into {chatresponses} (locale,groupid,vctitle,vcvalue) " .
"values (?, ?, ?, ?)",
("INSERT INTO {chatresponses} (locale,groupid,vctitle,vcvalue) "
. "VALUES (?, ?, ?, ?)"),
array(
$locale,
($groupid ? $groupid : "null"),
($group_id ? $group_id : "null"),
$title,
$message
$message,
)
);
}
?>

View File

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

View File

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

View File

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

View File

@ -20,18 +20,21 @@ namespace Mibew\API;
/**
* Implements functions execution context
*/
class ExecutionContext {
class ExecutionContext
{
/**
* Values which returns after execution of all functions in request
*
* @var array
*/
protected $return = array();
/**
* Results of execution of all function in request
*
* @var array
*/
protected $functions_results = array();
protected $functionsResults = array();
/**
* Returns requets results
@ -39,27 +42,35 @@ class ExecutionContext {
* @return array Request results
* @see \Mibew\API\ExecutionContext::$return
*/
public function getResults () {
public function getResults()
{
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.
* @return array Arguments list
* @throws \Mibew\API\APIException
*/
public function getArgumentsList ($function) {
public function getArgumentsList($function)
{
$arguments = $function['arguments'];
$references = $function['arguments']['references'];
foreach ($references as $variable => $func_num) {
// Check target function in context
if (! isset($this->functions_results[$func_num - 1])) {
if (!isset($this->functionsResults[$func_num - 1])) {
// Wrong function num
$message = "Wrong reference in '%s' function. "
. "Function #%s does not call yet.";
throw new APIException(
"Wrong reference in '{$function['function']}' function. " .
"Function #{$func_num} does not call yet.",
sprintf(
$message,
$function['function'],
$func_num
),
APIException::WRONG_FUNCTION_NUM_IN_REFERENCE
);
}
@ -68,47 +79,63 @@ class ExecutionContext {
if (empty($arguments[$variable])) {
// Empty argument that should contains reference
throw new APIException(
"Wrong reference in '{$function['function']}' function. " .
"Empty {$variable} argument.",
sprintf(
"Wrong reference in '%s' function. Empty %s argument.",
$function['function'],
$variable
),
APIException::EMPTY_VARIABLE_IN_REFERENCE
);
}
$reference_to = $arguments[$variable];
// 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
$message = "Wrong reference in '%s' function. "
. "There is no '%s' argument in #%s function results";
throw new APIException(
"Wrong reference in '{$function['function']}' function. " .
"There is no '{$reference_to}' argument in #{$func_num} " .
"function results",
sprintf(
$message,
$function['function'],
$reference_to,
$func_num
),
APIException::VARIABLE_IS_UNDEFINED_IN_REFERENCE
);
}
// 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;
}
/**
* 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 $results Associative array of the function results.
* @throws \Mibew\API\APIException
*/
public function storeFunctionResults ($function, $results) {
public function storeFunctionResults($function, $results)
{
// Check if function return correct results
if (empty($results['errorCode'])) {
// Add value to request results
foreach ($function['arguments']['return'] as $name => $alias) {
if (!isset($results[$name])) {
// 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(
"Variable with name '{$name}' is undefined in the " .
"results of the '{$function['function']}' function",
sprintf(
$message,
$name,
$function['function']
),
APIException::VARIABLE_IS_UNDEFINED_IN_RESULT
);
}
@ -124,9 +151,6 @@ class ExecutionContext {
}
// 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
*/
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
* @var array
@ -31,21 +41,10 @@ class ChatInteraction extends Interaction {
'threadId' => null,
'token' => null,
'references' => array(),
'return' => array()
'return' => array(),
),
'result' => array(
'errorCode' => 0
)
);
/**
* Reserved function's names
* @var array
* @see \Mibew\API\Interaction\Interaction::$reservedFunctionNames
*/
public $reservedFunctionNames = array(
'result'
'errorCode' => 0,
),
);
}
?>

View File

@ -20,28 +20,8 @@ namespace Mibew\API\Interaction;
/**
* Encapsulates interaction type
*/
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();
abstract class Interaction
{
/**
* Reserved function's names
*
@ -50,13 +30,39 @@ abstract class Interaction {
*/
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
*
* @param string $function_name Function name
* @return array An array of obligatory arguments
*/
public function getObligatoryArguments($function_name) {
public function getObligatoryArguments($function_name)
{
$obligatory_arguments = array();
// Add obligatory for all functions arguments
if (!empty($this->obligatoryArguments['*'])) {
@ -72,28 +78,36 @@ abstract class Interaction {
array_keys($this->obligatoryArguments[$function_name])
);
}
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
* @return array Associative array with keys are obligatory arguments and values are default
* values of them
* @return array Associative array with keys are obligatory arguments and
* values are default values of them
*/
public function getObligatoryArgumentsDefaults($function_name) {
public function getObligatoryArgumentsDefaults($function_name)
{
$obligatory_arguments = array();
// Add obligatory for all functions arguments
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
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;
}
}
?>

View File

@ -20,7 +20,17 @@ namespace Mibew\API\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
* @var array
@ -30,21 +40,10 @@ class InviteInteraction extends Interaction {
'*' => array(
'references' => array(),
'return' => array(),
'visitorId' => null
'visitorId' => null,
),
'result' => array(
'errorCode' => 0
)
);
/**
* Reserved function's names
* @var array
* @see \Mibew\API\Interaction\Interaction::$reservedFunctionNames
*/
public $reservedFunctionNames = array(
'result'
'errorCode' => 0,
),
);
}
?>

View File

@ -20,7 +20,17 @@ namespace Mibew\API\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
* @var array
@ -30,24 +40,13 @@ class UsersInteraction extends Interaction {
'*' => array(
'agentId' => null,
'references' => array(),
'return' => array()
'return' => array(),
),
'updateThreads' => array(
'revision' => 0
'revision' => 0,
),
'result' => array(
'errorCode' => 0
)
);
/**
* Reserved function's names
* @var array
* @see \Mibew\API\Interaction\Interaction::$reservedFunctionNames
*/
public $reservedFunctionNames = array(
'result'
'errorCode' => 0,
),
);
}
?>

View File

@ -21,8 +21,8 @@ namespace Mibew;
* Encapsulates work with database. Implenets singleton pattern to provide only
* one instance.
*/
Class Database{
class Database
{
const FETCH_ASSOC = 1;
const FETCH_NUM = 2;
const FETCH_BOTH = 4;
@ -33,13 +33,13 @@ Class Database{
* An instance of Database class
* @var Database
*/
protected static $instance = NULL;
protected static $instance = null;
/**
* PDO object
* @var \PDO
*/
protected $dbh = NULL;
protected $dbh = null;
/**
* Database host
@ -72,7 +72,8 @@ Class Database{
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
*
* @see Database::$forceCharsetInConnection
@ -104,7 +105,7 @@ Class Database{
* Id of the last query
* @var type
*/
protected $lastQuery = NULL;
protected $lastQuery = null;
/**
* Controls if exception must be processed into class or thrown
@ -116,45 +117,59 @@ Class Database{
* Get instance of Database class.
*
* If no instance exists, creates new instance.
* Use Database::initialize() before try to get an instance. If database was not initilize coorectly triggers an
* error with E_USER_ERROR level.
* Use Database::initialize() before try to get an instance. If database
* was not initilize coorectly triggers an error with E_USER_ERROR level.
*
* @return Database
* @see Database::initialize()
*/
public static function getInstance(){
public static function getInstance()
{
if (is_null(self::$instance)) {
trigger_error('Database was not initialized correctly', E_USER_ERROR);
}
return self::$instance;
}
/**
* Destroy internal database object
*/
public static function destroy(){
public static function destroy()
{
if (!is_null(self::$instance)) {
self::$instance->__destruct();
self::$instance = NULL;
self::$instance = null;
}
}
/**
* Initialize database.
*
* Set internal database and connectionproperties. Create Database object. Create PDO object and store it in the
* Database object.
* Set internal database and connectionproperties. Create Database object.
* Create PDO object and store it in the Database object.
*
* @param string $host Database host.
* @param string $user Database user name.
* @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 $prefix Database tables prefix
* @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
if (!extension_loaded('PDO')) {
throw new \Exception('PDO extension is not loaded');
@ -198,27 +213,6 @@ Class Database{
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
* previous value.
@ -229,52 +223,55 @@ Class Database{
* @param boolean $value Value that should be set. This argument is optional
* @return bool Previous value
*/
public function throwExeptions(){
public function throwExeptions()
{
$last_value = $this->throwExceptions;
if (func_num_args() > 0) {
$this->throwExceptions = func_get_arg(0);
}
return $last_value;
}
/**
* Database class destructor.
*/
public function __destruct(){
public function __destruct()
{
foreach ($this->preparedStatements as $key => $statement) {
$this->preparedStatements[$key] = NULL;
$this->preparedStatements[$key] = null;
}
$this->dbh = NULL;
self::$instance = NULL;
$this->dbh = null;
self::$instance = null;
}
/**
* Executes SQL query.
*
* In SQL query can be used PDO style placeholders:
* unnamed placeholders (question marks '?') and named placeholders (like
* ':name').
* If unnamed placeholders are used, $values array must have numeric indexes.
* If named placeholders are used, $values param must be an associative array
* with keys corresponding to the placeholders names
* ':name'). If unnamed placeholders are used, $values array must have
* numeric indexes. If named placeholders are used, $values param must be an
* associative array with keys corresponding to the placeholders names
*
* Table prefix automatically substitute if table name puts in curly braces
*
* @param string $query SQL query
* @param array $values Values, that must be substitute instead of
* placeholders in SQL query.
* @param array $params Array of query parameters. It can contains values with
* following keys:
* @param array $params Array of query parameters. It can contains values
* with following keys:
* - '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
* or Database::RETURN_ALL_ROWS for all rows. If this key not specified,
* the function will not return any rows.
* be returnd. The value can be Database::RETURN_ONE_ROW for olny one
* row or Database::RETURN_ALL_ROWS for all rows. If this key not
* specified, the function will not return any rows.
* - 'fetch_type' control indexes in resulting rows. The value can be
* Database::FETCH_ASSOC for associative array, Database::FETCH_NUM for
* array with numeric indexes and Database::FETCH_BOTH for both indexes.
* Default value is Database::FETCH_ASSOC.
* @return mixed If 'return_rows' key of the $params array is specified,
* returns one or several rows (depending on $params['return_rows'] value) or
* boolean false on fail.
* returns one or several rows (depending on $params['return_rows'] value)
* or boolean false on fail.
* If 'return_rows' key of the $params array is not specified, returns
* boolean true on success or false on fail.
*
@ -284,7 +281,8 @@ Class Database{
* @see Database::FETCH_NUM
* @see Database::FETCH_BOTH
*/
public function query($query, $values = NULL, $params = array()){
public function query($query, $values = null, $params = array())
{
try {
$query = preg_replace("/\{(\w+)\}/", $this->tablesPrefix . "$1", $query);
@ -310,7 +308,6 @@ Class Database{
}
// Some rows must be returned
// Get indexes type
if (!array_key_exists('fetch_type', $params)) {
$params['fetch_type'] = Database::FETCH_ASSOC;
@ -347,21 +344,23 @@ Class Database{
}
/**
* Returns value of PDOStatement::$errorInfo property for last query
* @return string Error info array
* Returns value of PDOStatement::$errorInfo property for last query.
*
* @return string Error info array
* @see \PDOStatement::$erorrInfo
*/
public function errorInfo(){
public function errorInfo()
{
if (is_null($this->lastQuery)) {
return false;
}
try {
$errorInfo = $this->preparedStatements[$this->lastQuery]->errorInfo();
$error_info = $this->preparedStatements[$this->lastQuery]->errorInfo();
} catch (\Exception $e) {
$this->handleError($e);
}
return $errorInfo;
return $error_info;
}
/**
@ -369,13 +368,15 @@ Class Database{
*
* @return int The ID
*/
public function insertedId(){
public function insertedId()
{
try {
$lastInsertedId = $this->dbh->lastInsertId();
$last_inserted_id = $this->dbh->lastInsertId();
} catch (\Exception $e) {
$this->handleError($e);
}
return $lastInsertedId;
return $last_inserted_id;
}
/**
@ -383,7 +384,8 @@ Class Database{
*
* @return int Affected rows count
*/
public function affectedRows(){
public function affectedRows()
{
if (is_null($this->lastQuery)) {
return false;
}
@ -392,9 +394,33 @@ Class Database{
} catch (\Exception $e) {
$this->handleError($e);
}
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.
* Implements singleton pattern.
*/
Class EventDispatcher {
class EventDispatcher
{
/**
* An instance of EventDispatcher class.
*
* @var EventDispatcher
*/
protected static $instance = null;
/**
* Events and listeners array.
*
* @var array
*/
protected $events = array();
/**
* Increments any time when plugin adds. Use for determine plugins order for plugins with
* equal priority.
* Increments any time when plugin adds. Is used for determine plugins order
* for plugins with equal priority.
*
* @var int
*/
protected $offset = 0;
@ -47,18 +50,15 @@ Class EventDispatcher {
*
* @return EventDispatcher
*/
public static function getInstance(){
public static function getInstance()
{
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Make constructor unavailable for client code
*/
protected function __constructor() {}
/**
* Attaches listener function to event.
*
@ -67,16 +67,18 @@ Class EventDispatcher {
* @param string $event_name Event's name
* @param \Mibew\Plugin $plugin Plugin object, 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
* use instead.
* @param int $priority Priority of listener. If $priority = null, the
* plugin weight will use instead.
* @return boolean true on success or false on failure.
*
* @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
if (!is_callable(array($plugin, $listener))) {
trigger_error("Method '{$listener}' is not callable!", E_USER_WARNING);
return false;
}
// Create empty array for event listener if it not exists
@ -90,9 +92,10 @@ Class EventDispatcher {
// Attach listener
$this->events[$event_name][$priority . "_" . $this->offset] = array(
'plugin' => $plugin,
'listener' => $listener
'listener' => $listener,
);
$this->offset++;
return true;
}
@ -104,7 +107,8 @@ Class EventDispatcher {
* @param string $listener Plugins method, that handles the event
* @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
if (!array_key_exists($event_name, $this->events)) {
return false;
@ -114,9 +118,11 @@ Class EventDispatcher {
if ($event['plugin'] === $plugin && $event['listener'] == $listener) {
// Detach listener
unset($this->events[$event_name][$index]);
return true;
}
}
return false;
}
@ -127,7 +133,8 @@ Class EventDispatcher {
* @param array &$arguments Arguments passed to listener
* @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
if (!array_key_exists($event_name, $this->events)) {
return true;
@ -140,9 +147,14 @@ Class EventDispatcher {
$listener = $event['listener'];
$plugin->$listener($arguments);
}
return true;
}
/**
* Make constructor unavailable for client code
*/
protected function __constructor()
{
}
}
?>

View File

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

View File

@ -20,13 +20,14 @@ namespace Mibew;
/**
* Manage plugins
*/
Class PluginManager {
class PluginManager
{
/**
* Contains all loaded plugins
*
* @var array
*/
protected static $loaded_plugins = array();
protected static $loadedPlugins = array();
/**
* Returns plugin object
@ -34,14 +35,16 @@ Class PluginManager {
* @param string $plugin_name
* @return \Mibew\Plugin
*/
public static function getPlugin($plugin_name) {
if (empty(self::$loaded_plugins[$plugin_name])) {
public static function getPlugin($plugin_name)
{
if (empty(self::$loadedPlugins[$plugin_name])) {
trigger_error(
"Plugin '{$plugin_name}' does not initialized!",
E_USER_WARNING
);
}
return self::$loaded_plugins[$plugin_name];
return self::$loadedPlugins[$plugin_name];
}
/**
@ -51,8 +54,9 @@ Class PluginManager {
*
* @return array
*/
public static function getAllPlugins() {
return self::$loaded_plugins;
public static function getAllPlugins()
{
return self::$loadedPlugins;
}
/**
@ -76,7 +80,8 @@ Class PluginManager {
*
* @see Plugin::registerListeners()
*/
public static function loadPlugins($plugins_list){
public static function loadPlugins($plugins_list)
{
// Add include path
$include_path = get_include_path();
$include_path .= empty($include_path) ? '' : PATH_SEPARATOR;
@ -112,26 +117,22 @@ Class PluginManager {
}
// Check if plugin extends abstract 'Plugin' class
if ('Mibew\\Plugin' != get_parent_class($plugin_classname)) {
trigger_error(
"Plugin class '{$plugin_classname}' does not extend " .
"abstract '\\Mibew\\Plugin' class!",
E_USER_WARNING
);
$error_essage = "Plugin class '{$plugin_classname}' does not "
. "extend abstract '\\Mibew\\Plugin' class!";
trigger_error($error_essage, E_USER_WARNING);
continue;
}
// Check plugin dependences
$plugin_dependences = call_user_func(array(
$plugin_classname,
'getDependences'
'getDependences',
));
foreach ($plugin_dependences as $dependence) {
if (empty(self::$loaded_plugins[$dependence])) {
trigger_error(
"Plugin '{$dependence}' was not loaded yet, but " .
"exists in '{$plugin_name}' dependences list!",
E_USER_WARNING
);
if (empty(self::$loadedPlugins[$dependence])) {
$error_essage = "Plugin '{$dependence}' was not loaded "
. "yet, but exists in '{$plugin_name}' dependences list!";
trigger_error($error_essage, E_USER_WARNING);
continue 2;
}
}
@ -140,7 +141,7 @@ Class PluginManager {
$plugin_instance = new $plugin_classname($plugin_config);
if ($plugin_instance->initialized) {
// Store plugin instance
self::$loaded_plugins[$plugin_name] = $plugin_instance;
self::$loadedPlugins[$plugin_name] = $plugin_instance;
$loading_queue[$plugin_instance->getWeight() . "_" . $offset] = $plugin_instance;
$offset++;
} 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
* applications at the client side.
*/
abstract class ClientSideProcessor extends Processor {
abstract class ClientSideProcessor extends Processor
{
/**
* Call function at client side
@ -34,7 +35,8 @@ abstract class ClientSideProcessor extends Processor {
* @param array|null $callback callback array for synchronous requests.
* @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);
}
@ -44,7 +46,8 @@ abstract class ClientSideProcessor extends Processor {
* @param array $responses An array of the 'Request' arrays. See Mibew API
* for details
*/
protected function sendAsyncResponses($responses) {
protected function sendAsyncResponses($responses)
{
header("Content-type: text/plain; charset=UTF-8");
echo($this->mibewAPI->encodePackage(
$responses,
@ -60,7 +63,8 @@ abstract class ClientSideProcessor extends Processor {
* @param String $key Request key. Use to load request from buffer.
* @param $request Request array.
*/
protected function addRequestToBuffer($key, $request) {
protected function addRequestToBuffer($key, $request)
{
// Save request to database
$db = Database::getInstance();
$db->query(
@ -75,7 +79,8 @@ abstract class ClientSideProcessor extends Processor {
* @param String $key Request key
* @return array Array of requests with given key
*/
protected function getRequestsFromBuffer($key) {
protected function getRequestsFromBuffer($key)
{
$db = Database::getInstance();
$key = md5($key);
@ -96,9 +101,7 @@ abstract class ClientSideProcessor extends Processor {
foreach ($requests as $request_info) {
$result[] = unserialize($request_info['request']);
}
return $result;
}
}
?>

View File

@ -20,11 +20,10 @@ namespace Mibew\RequestProcessor\Exception;
/**
* Class for {@link \Mibew\RequestProcessor\InviteRequestProcessor} exceptions
*/
class InviteProcessorException extends ProcessorException {
class InviteProcessorException extends ProcessorException
{
/**
* Operator is not logged in
*/
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 ProcessorException extends \Exception {
class ProcessorException extends \Exception
{
/**
* Wrong function arguments
*/
const WRONG_ARGUMENTS = 1;
}
?>

View File

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

View File

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

View File

@ -33,22 +33,26 @@ use Mibew\RequestProcessor\Exception\InviteProcessorException;
*
* Implements Singleton pattern
*/
class InviteProcessor extends ClientSideProcessor {
class InviteProcessor extends ClientSideProcessor
{
/**
* An instance of the InviteProcessor class
*
* @var \Mibew\RequestProcessor\InviteProcessor
*/
protected static $instance = null;
/**
* Return an instance of the InviteProcessor class.
*
* @return \Mibew\RequestProcessor\InviteProcessor
*/
public static function getInstance() {
public static function getInstance()
{
if (is_null(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
@ -57,9 +61,11 @@ class InviteProcessor extends ClientSideProcessor {
*
* Do not use directly __construct method! Use
* \Mibew\RequestProcessor\InviteProcessor::getInstance() instead!
*
* @todo Think about why the method is not protected
*/
public function __construct() {
public function __construct()
{
parent::__construct(array(
'signature' => '',
'trusted_signatures' => array(''),
@ -72,7 +78,8 @@ class InviteProcessor extends ClientSideProcessor {
*
* @return \Mibew\API\API
*/
protected function getMibewAPIInstance() {
protected function getMibewAPIInstance()
{
return MibewAPI::getAPI('\\Mibew\\API\\Interaction\\InviteInteraction');
}
@ -80,9 +87,11 @@ class InviteProcessor extends ClientSideProcessor {
* Stub for sendAsyncRequest method.
*
* Actually request not send to client side. This method is ONLY STUB.
*
* @return boolean Always true
*/
protected function sendAsyncRequest() {
protected function sendAsyncRequest()
{
return true;
}
@ -90,9 +99,11 @@ class InviteProcessor extends ClientSideProcessor {
* Stub for call method.
*
* Actually nothing can be called at client side. This method is ONLY STUB.
*
* @return boolean Always false.
*/
public function call() {
public function call()
{
return false;
}
@ -104,9 +115,11 @@ class InviteProcessor extends ClientSideProcessor {
* - 'visitorId': Id of the invited visitor
* @return array Array of results. It contains following keys:
* - '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();
if (!$operator) {
throw new InviteProcessorException(
@ -116,11 +129,10 @@ class InviteProcessor extends ClientSideProcessor {
}
$invitation = invitation_state($args['visitorId']);
return array(
'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()
*/
abstract class Processor {
abstract class Processor
{
/**
* Instance of the MibewAPI class
*
* @var \Mibew\API\API
*/
protected $mibewAPI = null;
/**
* Prefix that uses for all events triggered by the class.
*
* @var string
*/
protected $eventPrefix = '';
/**
* Array of the responses packages
*
* @var array
*/
protected $responses = array();
/**
* Array of configurations
*
* @var array
*/
protected $config = array();
@ -124,14 +128,15 @@ abstract class Processor {
* @param type $config Configuration data.
* It must contains following keys:
* - 'signature': Use for verification sender
* - 'trusted_signatures': array of trusted signatures. Uses for identify another
* side of interaction.
* - 'trusted_signatures': array of trusted signatures. Uses for identify
* another side of interaction.
* And may contains following (if not default values will be used)
* - 'event_prefix': prefix that uses for all events triggered by the
* class. The default value is the class name with first character in
* lower case
*/
public function __construct($config) {
public function __construct($config)
{
// Check signature
if (!isset($config['signature'])) {
trigger_error("Signature is not specified", E_USER_ERROR);
@ -159,13 +164,15 @@ abstract class Processor {
/**
* Proccess received packages
*
* On any error function returns only boolean false. To handle error add listener to the
* "<eventPrefix>RequestError" event.
* On any error function returns only boolean false. To handle error add
* listener to the "<eventPrefix>RequestError" event.
*
* @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();
// Try to handle request
try {
@ -245,23 +252,27 @@ abstract class Processor {
// Something went wrong. Trigger error event
$vars = array('exception' => $e);
$dispatcher->triggerEvent($this->eventPrefix . 'RequestError', $vars);
return false;
}
return true;
}
/**
* Call functions at the other side
*
* On any error function returns only boolean false. To handle error add listener to the
* "<eventPrefix>CallError" event.
* On any error function returns only boolean false. To handle error add
* listener to the "<eventPrefix>CallError" event.
*
* @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.
* @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
$dispatcher = EventDispatcher::getInstance();
// Try to call function at Other side
@ -279,7 +290,8 @@ abstract class Processor {
}
// 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());
$request = array(
'token' => $token,
@ -317,8 +329,10 @@ abstract class Processor {
// Trigger error event
$vars = array('exception' => $e);
$dispatcher->triggerEvent($this->eventPrefix . "CallError", $vars);
return false;
}
return $result;
}
@ -326,12 +340,13 @@ abstract class Processor {
* Process request
*
* @param array $request 'Requests' array. See Mibew API for details.
* @param mixed $result_function 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.
* @param mixed $result_function 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 array Array of requests results.
*/
protected function processRequest($request, $result_function = null) {
protected function processRequest($request, $result_function = null)
{
$context = new \Mibew\API\ExecutionContext();
// Get result functions
@ -356,6 +371,7 @@ abstract class Processor {
break;
}
}
return $context->getResults();
} else {
// Return result
@ -368,16 +384,18 @@ abstract class Processor {
*
* @param array $function 'Function' array. See Mibew API for details
* @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
$arguments = $context->getArgumentsList($function);
$call_vars = array(
'function' => $function['function'],
'arguments' => $arguments,
'results' => array()
'results' => array(),
);
// Call processor function
@ -401,25 +419,30 @@ abstract class Processor {
* Stores callback function
*
* Callback is an associative array with following keys
* - 'function': function name to call
* - 'arguments': additional arguments, that passed to the callback function
* - 'function': function name to call.
* - 'arguments': additional arguments, that passed to the callback
* function.
*
* @param string $token Request token
* @param array $callback Callback function array
* @todo Create some unit tests
*/
protected function saveCallback($token, $callback) {
protected function saveCallback($token, $callback)
{
$db = Database::getInstance();
$query = "INSERT INTO {requestcallback} ( "
. "token, function, arguments "
. ") VALUES ( "
. ":token, :function, :arguments"
. ")";
$db->query(
"INSERT INTO {requestcallback} ( ".
"token, function, arguments ".
") VALUES ( " .
":token, :function, :arguments" .
")",
$query,
array(
':token' => $token,
':function' => $callback['function'],
':arguments' => serialize($callback['arguments'])
':arguments' => serialize($callback['arguments']),
)
);
}
@ -428,14 +451,17 @@ abstract class Processor {
* Loads callback function
*
* Callback is an associative array with following keys
* - 'function': function name to call
* - 'arguments': additional arguments, that passed to the callback function
* - 'function': function name to call.
* - 'arguments': additional arguments, that passed to the 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
*/
protected function loadCallback($token) {
protected function loadCallback($token)
{
$db = Database::getInstance();
$callback = $db->query(
"SELECT * FROM {requestcallback} WHERE token = :token",
@ -445,22 +471,26 @@ abstract class Processor {
if (!$callback) {
return null;
}
return array(
'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.
* 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
*/
protected function processorCall(&$func) {
protected function processorCall(&$func)
{
$method_name = 'api' . ucfirst($func['function']);
if (is_callable(array($this, $method_name))) {
try {
@ -468,7 +498,7 @@ abstract class Processor {
} catch (ProcessorException $e) {
$func['results'] = array(
'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
* @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);
}
@ -490,25 +521,30 @@ abstract class Processor {
* @param array $request The 'request' array. See Mibew API for details
* @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);
}
/**
* 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);
}
/**
* 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);
}
@ -519,14 +555,14 @@ abstract class Processor {
*
* @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.
*
* @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
*/
class ThreadProcessor extends ClientSideProcessor {
class ThreadProcessor extends ClientSideProcessor
{
/**
* An instance of the ThreadProcessor class
*
* @var \Mibew\RequestProcessor\ThreadProcessor
*/
protected static $instance = null;
/**
* Return an instance of the ThreadProcessor class.
*
* @return \Mibew\RequestProcessor\ThreadProcessor
*/
public static function getInstance() {
public static function getInstance()
{
if (is_null(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
@ -66,7 +70,8 @@ class ThreadProcessor extends ClientSideProcessor {
* @return \Mibew\Thread
* @throws \Mibew\RequestProcessor\ThreadProcessorException
*/
public static function getThread($thread_id, $last_token) {
public static function getThread($thread_id, $last_token)
{
// Load thread
$thread = Thread::load($thread_id, $last_token);
// Check thread
@ -76,6 +81,7 @@ class ThreadProcessor extends ClientSideProcessor {
ThreadProcessorException::ERROR_WRONG_THREAD
);
}
// Return thread
return $thread;
}
@ -87,7 +93,8 @@ class ThreadProcessor extends ClientSideProcessor {
* @param array $vars Array of arguments names that must be checked
* @throws \Mibew\RequestProcessor\ThreadProcessorException
*/
public static function checkParams($args, $vars) {
public static function checkParams($args, $vars)
{
if (empty($vars)) {
return;
}
@ -109,27 +116,31 @@ class ThreadProcessor extends ClientSideProcessor {
* @throws \Mibew\RequestProcessor\ThreadProcessorException If operator is
* not logged in.
*/
public static function checkOperator() {
public static function checkOperator()
{
$operator = get_logged_in();
if (!$operator) {
throw new ThreadProcessorException(
"Operator not logged in!",
"Operator is not logged in!",
ThreadProcessorException::ERROR_AGENT_NOT_LOGGED_IN
);
}
return $operator;
}
/**
* 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(
'signature' => '',
'trusted_signatures' => array(''),
'event_prefix' => 'thread'
'event_prefix' => 'thread',
));
}
@ -138,7 +149,8 @@ class ThreadProcessor extends ClientSideProcessor {
*
* @return \Mibew\API\API
*/
protected function getMibewAPIInstance() {
protected function getMibewAPIInstance()
{
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
* @return boolean true on success or false on failure
*/
protected function sendAsyncRequest($request) {
protected function sendAsyncRequest($request)
{
// Define empty thread id and thread token
$thread_id = null;
$token = null;
@ -162,8 +175,9 @@ class ThreadProcessor extends ClientSideProcessor {
continue;
}
// Check thread id and thread token for the remaining functions
if ($thread_id != $function['arguments']['threadId']
|| $token != $function['arguments']['token']) {
$wrong_thread_id = $thread_id != $function['arguments']['threadId'];
$wrong_token = $token != $function['arguments']['token'];
if ($wrong_thread_id || $wrong_token) {
throw new ThreadProcessorException(
'Various thread id or thread token in different functions in one package!',
ThreadProcessorException::VARIOUS_THREAD_ID
@ -184,6 +198,7 @@ class ThreadProcessor extends ClientSideProcessor {
if ($recipient == 'user' || $recipient == 'both') {
$this->addRequestToBuffer('thread_user_' . $thread_id, $request);
}
return true;
}
@ -192,19 +207,18 @@ class ThreadProcessor extends ClientSideProcessor {
*
* @param Array $function A Function array
*/
protected function checkFunction($function) {
protected function checkFunction($function)
{
// Check recipient argument existance
if (!array_key_exists('recipient', $function['arguments'])) {
throw new ThreadProcessorException(
"'recipient' argument is not set in function '{function['function]}'!",
"'recipient' argument is not set in function '{$function['function']}'!",
ThreadProcessorException::EMPTY_RECIPIENT
);
}
$recipient = $function['arguments']['recipient'];
// Check recipient value
if ($recipient != 'agent'
&& $recipient != 'both'
&& $recipient != 'user') {
if ($recipient != 'agent' && $recipient != 'both' && $recipient != 'user') {
throw new ThreadProcessorException(
"Wrong recipient value '{$recipient}'! It should be one of 'agent', 'user', 'both'",
ThreadProcessorException::WRONG_RECIPIENT_VALUE
@ -216,17 +230,21 @@ class ThreadProcessor extends ClientSideProcessor {
* Update chat window state. API function
*
* 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
* - 'token': last thread token
* - 'user': TRUE if window used by user and FALSE otherwise
* - 'typed': indicates if user(or agent) typed
* - 'lastId': id of the last sent to message
* @return array Array of results. It contains following keys:
* - 'typing': indicates if another side of the conversation is typing message
* - 'canPost': indicates if agent(user can post message all the time) can post the message
* - 'typing': indicates if another side of the conversation is typing
* 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
$thread = self::getThread($args['threadId'], $args['token']);
@ -260,28 +278,32 @@ class ThreadProcessor extends ClientSideProcessor {
// Get status values
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 {
$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;
return array(
'typing' => $is_typing,
'canPost' => $can_post
'canPost' => $can_post,
);
}
/**
* 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
* - 'token': last thread token
* - 'user': TRUE if window used by user and FALSE otherwise
* - 'lastId': last sent message id
*/
protected function apiUpdateMessages($args) {
protected function apiUpdateMessages($args)
{
// Load thread
$thread = self::getThread($args['threadId'], $args['token']);
@ -302,21 +324,23 @@ class ThreadProcessor extends ClientSideProcessor {
return array(
'messages' => $messages,
'lastId' => $last_message_id
'lastId' => $last_message_id,
);
}
/**
* 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
* - 'token': last thread token
* - 'user': TRUE if window used by user and FALSE otherwise
* - 'message': posted message
* @throws ThreadProcessorException
*/
protected function apiPost($args) {
protected function apiPost($args)
{
// Load thread
$thread = self::getThread($args['threadId'], $args['token']);
@ -330,7 +354,10 @@ class ThreadProcessor extends ClientSideProcessor {
// Check message can be sent
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
@ -340,7 +367,7 @@ class ThreadProcessor extends ClientSideProcessor {
} else {
$msg_options = array(
'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
*
* @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
* - 'token': last thread token
* - 'name': new user name
* @throws \Mibew\RequestProcessor\ThreadProcessorException
*/
protected function apiRename($args) {
protected function apiRename($args)
{
// Check rename possibility
if (Settings::get('usercanchangename') != "1") {
throw new ThreadProcessorException(
@ -388,14 +417,16 @@ class ThreadProcessor extends ClientSideProcessor {
/**
* 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
* - 'token': last thread token
* - 'user': TRUE if window used by user and FALSE otherwise
* @return array Array of results. It contains following keys:
* - 'closed': indicates if thread can be closed
*/
protected function apiClose($args) {
protected function apiClose($args)
{
// Load thread and check thread's last token
$thread = self::getThread($args['threadId'], $args['token']);
@ -413,14 +444,14 @@ class ThreadProcessor extends ClientSideProcessor {
}
return array(
'closed' => true
'closed' => true,
);
}
/**
* 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:
* - 'threadId': 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;
* - 'options': options array for next module.
*/
protected function apiProcessSurvey($args) {
protected function apiProcessSurvey($args)
{
$visitor = visitor_from_request();
// Get form values
@ -446,7 +477,7 @@ class ThreadProcessor extends ClientSideProcessor {
// Verify group id
$group_id = '';
$group = NULL;
$group = null;
if (Settings::get('enablegroups') == '1') {
if (preg_match("/^\d{1,8}$/", $args['groupId']) != 0) {
$group = group_by_id($args['groupId']);
@ -481,9 +512,10 @@ class ThreadProcessor extends ClientSideProcessor {
);
$options = $client_data['leaveMessage'];
$options['page'] += setup_logo($group);
return array(
'next' => 'leaveMessage',
'options' => $options
'options' => $options,
);
}
@ -522,7 +554,7 @@ class ThreadProcessor extends ClientSideProcessor {
return array(
'next' => 'chat',
'options' => $options
'options' => $options,
);
}
@ -530,7 +562,7 @@ class ThreadProcessor extends ClientSideProcessor {
* Process submitted leave message form.
*
* 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:
* - 'threadId': 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
* exception if captcha or email is wrong.
*/
protected function apiProcessLeaveMessage($args) {
protected function apiProcessLeaveMessage($args)
{
// Check captcha
if (Settings::get('enablecaptcha') == '1' && can_show_captcha()) {
$captcha = $args['captcha'];
@ -641,7 +674,8 @@ class ThreadProcessor extends ClientSideProcessor {
// Send email
if ($inbox_mail) {
// Prepare message to send by email
$subject = getstring2_("leavemail.subject",
$subject = getstring2_(
"leavemail.subject",
array($args['name']),
$message_locale
);
@ -661,5 +695,3 @@ class ThreadProcessor extends ClientSideProcessor {
}
}
}
?>

View File

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

View File

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

View File

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

View File

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

View File

@ -23,14 +23,16 @@ use Mibew\Settings;
/**
* 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
* does not contain neither leading nor trailing slash.
*
* @return string Base path for style files
*/
public function filesPath() {
public function filesPath()
{
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
* 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
$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
// specified view name
$full_view_name = MIBEW_FS_ROOT . '/' . $this->filesPath() . '/views/' .
str_replace("/\\", '', $template_name) . '.php';
$full_view_name = MIBEW_FS_ROOT . '/' . $this->filesPath() . '/views/'
. str_replace("/\\", '', $template_name) . '.php';
// $page variable is used in included views files, so we need to create
// it as an alias of $data argument.
@ -70,7 +73,8 @@ class PageStyle extends Style implements StyleInterface {
*
* @return string Name of a style
*/
public static function currentStyle() {
public static function currentStyle()
{
// Just use the default style
return self::defaultStyle();
}
@ -80,7 +84,8 @@ class PageStyle extends Style implements StyleInterface {
*
* @return string Name of a style
*/
public static function defaultStyle() {
public static function defaultStyle()
{
// Load value from system settings
return Settings::get('page_style');
}
@ -90,7 +95,8 @@ class PageStyle extends Style implements StyleInterface {
*
* @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::update();
}
@ -100,7 +106,8 @@ class PageStyle extends Style implements StyleInterface {
*
* @param array List of styles names
*/
public static function availableStyles() {
public static function availableStyles()
{
$styles_root = MIBEW_FS_ROOT . '/styles/pages';
return self::getStyleList($styles_root);
@ -112,7 +119,8 @@ class PageStyle extends Style implements StyleInterface {
*
* @return array Default configurations of the style
*/
protected function defaultConfigurations() {
protected function defaultConfigurations()
{
return array(
'chat' => array(
'window_params' => ''
@ -120,9 +128,7 @@ class PageStyle extends Style implements StyleInterface {
'mail' => array(
'window_params' => ''
),
'screenshots' => array()
'screenshots' => array(),
);
}
}
?>

View File

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

View File

@ -20,13 +20,12 @@ namespace Mibew\TemplateEngine;
/**
* Simple template engine for chat templates
*/
class ChatTemplateEngine {
class ChatTemplateEngine
{
/**
* Regular expression for conditional blocks in templates
*/
const IF_REGEXP = "/\\\${(if|ifnot):([\w\.]+)}(.*?)(\\\${else:\\2}.*?)?\\\${endif:\\2}/s";
/**
* Path to teplates relative to MIBEW_FS_ROOT.
* @var string
@ -58,7 +57,8 @@ class ChatTemplateEngine {
* @param string $style_path Path to the style relative to MIBEW_FS_ROOT.
* @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->styleName = $style_name;
}
@ -71,10 +71,12 @@ class ChatTemplateEngine {
* @param array $data Data for substitutions.
* @return string Rendered HTML markup.
*/
public function render($template_name, $data) {
public function render($template_name, $data)
{
$this->flattenTemplateData = array_flatten_recursive($data);
$this->templateData = $data;
$contents = $this->getTemplateFileContent($template_name);
return $this->expandText($contents);
}
@ -84,11 +86,13 @@ class ChatTemplateEngine {
* @param string $condition Condition name. Can be any element name of the
* template data array.
*/
public function checkCondition($condition) {
public function checkCondition($condition)
{
if ($condition == 'errors') {
return !empty($this->templateData['errors'])
&& is_array($this->templateData['errors']);
}
return !empty($this->flattenTemplateData[$condition]);
}
@ -100,7 +104,8 @@ class ChatTemplateEngine {
* function.
* @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');
if ($value) {
@ -129,7 +134,8 @@ class ChatTemplateEngine {
* @return string Value of the variable or empty string if the value was not
* passed in with template data.
*/
public function expandVar($matches) {
public function expandVar($matches)
{
$prefix = $matches[1];
$var = $matches[2];
@ -146,10 +152,9 @@ class ChatTemplateEngine {
$this->templateData['pagination']
);
} elseif ($var == 'errors' || $var == 'harderrors') {
if (
!empty($this->templateData['errors'])
&& is_array($this->templateData['errors'])
) {
$errors_data_exists = !empty($this->templateData['errors'])
&& is_array($this->templateData['errors']);
if ($errors_data_exists) {
$result = getlocal("$var.header");
foreach ($this->templateData['errors'] as $e) {
$result .= getlocal("errors.prefix")
@ -157,10 +162,10 @@ class ChatTemplateEngine {
. getlocal("errors.suffix");
}
$result .= getlocal("errors.footer");
return $result;
}
}
} elseif ($prefix == 'msg:' || $prefix == 'msgjs:' || $prefix == 'url:') {
$message = '';
if (strpos($var, ",") !== false) {
@ -181,6 +186,7 @@ class ChatTemplateEngine {
$message = isset($this->flattenTemplateData[$var])
? $this->flattenTemplateData[$var]
: "";
return ($prefix == 'pagejs:') ? json_encode($message) : $message;
} elseif ($prefix == 'if:' || $prefix == 'else:' || $prefix == 'endif:' || $prefix == 'ifnot:') {
return "<!-- wrong $prefix:$var -->";
@ -197,8 +203,10 @@ class ChatTemplateEngine {
* function.
* @return string Contents of including file
*/
public function expandInclude($matches) {
public function expandInclude($matches)
{
$template_name = $matches[1];
return $this->getTemplateFileContent($template_name);
}
@ -208,7 +216,8 @@ class ChatTemplateEngine {
* @param string $text Source text
* @return string Markup with no control structures
*/
public function expandText($text) {
public function expandText($text)
{
$text = preg_replace_callback(
"/\\\${include:([\w\.]+)}/",
array($this, "expandInclude"),
@ -237,9 +246,10 @@ class ChatTemplateEngine {
* @throws \RuntimeException If there is no such template file or the file
* is not readable.
*/
protected function getTemplateFileContent($template_name) {
$full_file_path = MIBEW_FS_ROOT . '/' . $this->stylePath .
'/templates/' . $template_name . '.tpl';
protected function getTemplateFileContent($template_name)
{
$full_file_path = MIBEW_FS_ROOT . '/' . $this->stylePath
. '/templates/' . $template_name . '.tpl';
if (!is_readable($full_file_path)) {
throw new \RuntimeException(
@ -250,5 +260,3 @@ class ChatTemplateEngine {
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
* them.
*/
Class Thread {
class Thread
{
/**
* User in the users queue
*/
@ -129,8 +129,9 @@ Class Thread {
/**
* 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
* and __set methods. Real values are stored in the Thread::$threadInfo array.
* Keys are object properties and vlues are {chatthread} table fields.
* Properties are available via magic __get and __set methods. Real values
* are stored in the Thread::$threadInfo array.
*
* Thread object have following properties:
* - 'id': id of the thread
@ -139,7 +140,8 @@ Class Thread {
* - 'invitationState': state of invitation. See INVITATION_* constants,
* defined in libs/invitation.php
* - '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
* - 'shownMessageId': last id of shown message
* - '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
* - 'agentId': id 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
* - 'locale': locale code of the chat related to thread
* - 'userId': id of an user who take part in the chat
@ -168,44 +171,37 @@ Class Thread {
*/
protected $propertyMap = array(
'id' => 'threadid',
'lastRevision' => 'lrevision',
'state' => 'istate',
'invitationState' => 'invitationstate',
'lastToken' => 'ltoken',
'nextAgent' => 'nextagent',
'groupId' => 'groupid',
'shownMessageId' => 'shownmessageid',
'messageCount' => 'messageCount',
'created' => 'dtmcreated',
'modified' => 'dtmmodified',
'chatStarted' => 'dtmchatstarted',
'closed' => 'dtmclosed',
'agentId' => 'agentId',
'agentName' => 'agentName',
'agentTyping' => 'agentTyping',
'lastPingAgent' => 'lastpingagent',
'locale' => 'locale',
'userId' => 'userid',
'userName' => 'userName',
'userTyping' => 'userTyping',
'lastPingUser' => 'lastpinguser',
'remote' => 'remote',
'referer' => 'referer',
'userAgent' => 'userAgent'
'userAgent' => 'userAgent',
);
/**
* Contain loaded from database information about thread
*
* Do not use this property manually!
*
* @var array
*/
protected $threadInfo;
@ -214,22 +210,19 @@ Class Thread {
* List of modified fields.
*
* Do not use this property manually!
*
* @var array
*/
protected $changedFields = array();
/**
* Forbid create instance from outside of the class
*/
protected function __construct() {}
/**
* Create new empty thread in database
*
* @return boolean|Thread Returns an object of the Thread class or boolean
* false on failure
*/
public static function create() {
public static function create()
{
// Get database object
$db = Database::getInstance();
@ -252,6 +245,7 @@ Class Thread {
// Set initial values
$thread->lastToken = self::nextToken();
$thread->created = time();
return $thread;
}
@ -264,7 +258,8 @@ Class Thread {
* @return boolean|Thread Returns an object of the Thread class or boolean
* false on failure
*/
public static function createFromDbInfo($thread_info) {
public static function createFromDbInfo($thread_info)
{
// Create new empty thread
$thread = new self();
@ -279,6 +274,7 @@ Class Thread {
// Copy field to Thread object
$thread->threadInfo[$field] = $thread_info[$field];
}
return $thread;
}
@ -289,7 +285,8 @@ Class Thread {
* @return boolean|Thread Returns an object of the Thread class or boolean
* false on failure
*/
public static function load($id, $last_token = null) {
public static function load($id, $last_token = null)
{
// Check $id
if (empty($id)) {
return false;
@ -303,10 +300,8 @@ Class Thread {
// Load thread
$thread_info = $db->query(
"select * from {chatthread} where threadid = :threadid",
array(
':threadid' => $id
),
"SELECT * FROM {chatthread} WHERE threadid = :threadid",
array(':threadid' => $id),
array('return_rows' => Database::RETURN_ONE_ROW)
);
@ -329,28 +324,34 @@ Class Thread {
return false;
}
}
return $thread;
}
/**
* 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
$thread = self::load($id);
// Check if user and agent gone
if (Settings::get('thread_lifetime') != 0 &&
abs($thread->lastPingUser - time()) > Settings::get('thread_lifetime') &&
abs($thread->lastPingAgent - time()) > Settings::get('thread_lifetime')) {
$user_gone = abs($thread->lastPingUser - time()) > Settings::get('thread_lifetime');
$agent_gone = abs($thread->lastPingAgent - time()) > Settings::get('thread_lifetime');
if (Settings::get('thread_lifetime') != 0 && $user_gone && $agent_gone) {
unset($thread);
return false;
}
// Check if thread closed
if ($thread->state == self::STATE_CLOSED || $thread->state == self::STATE_LEFT) {
unset($thread);
return false;
}
@ -361,57 +362,62 @@ Class Thread {
}
// 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;
}
/**
* 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) {
return;
}
$db = Database::getInstance();
$query = "UPDATE {chatthread} SET " .
"lrevision = :next_revision, " .
"dtmmodified = :now, " .
"dtmclosed = :now, " .
"istate = :state_closed " .
"WHERE istate <> :state_closed " .
"AND istate <> :state_left " .
$query = "UPDATE {chatthread} SET "
. "lrevision = :next_revision, "
. "dtmmodified = :now, "
. "dtmclosed = :now, "
. "istate = :state_closed "
. "WHERE istate <> :state_closed "
. "AND istate <> :state_left "
// Check created timestamp
"AND ABS(:now - dtmcreated) > :thread_lifetime " .
. "AND ABS(:now - dtmcreated) > :thread_lifetime "
// Check pings
"AND ( " .
"( " .
. "AND ( "
. "( "
// Both user and operator have no connection problems.
// Check all pings.
"lastpingagent <> 0 " .
"AND lastpinguser <> 0 " .
"AND ABS(:now - lastpinguser) > :thread_lifetime " .
"AND ABS(:now - lastpingagent) > :thread_lifetime " .
") OR ( " .
. "lastpingagent <> 0 "
. "AND lastpinguser <> 0 "
. "AND ABS(:now - lastpinguser) > :thread_lifetime "
. "AND ABS(:now - lastpingagent) > :thread_lifetime "
. ") OR ( "
// Only operator have connection problems.
// Check user's ping.
"lastpingagent = 0 " .
"AND lastpinguser <> 0 " .
"AND ABS(:now - lastpinguser) > :thread_lifetime " .
") OR ( " .
. "lastpingagent = 0 "
. "AND lastpinguser <> 0 "
. "AND ABS(:now - lastpinguser) > :thread_lifetime "
. ") OR ( "
// Only user have connection problems.
// Check operator's ping.
"lastpinguser = 0 " .
"AND lastpingagent <> 0 " .
"AND ABS(:now - lastpingagent) > :thread_lifetime " .
") OR ( " .
. "lastpinguser = 0 "
. "AND lastpingagent <> 0 "
. "AND ABS(:now - lastpingagent) > :thread_lifetime "
. ") OR ( "
// Both user and operator have connection problems.
// Just close thread.
"lastpinguser = 0 " .
"AND lastpingagent = 0 " .
") " .
")";
. "lastpinguser = 0 "
. "AND lastpingagent = 0 "
. ") "
. ")";
$db->query(
$query,
@ -420,7 +426,7 @@ Class Thread {
':now' => time(),
':state_closed' => self::STATE_CLOSED,
':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
* @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) {
return false;
}
$db = Database::getInstance();
$result = $db->query(
"select count(*) as opened from {chatthread} " .
"where remote = ? AND istate <> ? AND istate <> ?",
array($remote, Thread::STATE_CLOSED, Thread::STATE_LEFT),
"SELECT COUNT(*) AS opened FROM {chatthread} WHERE remote = ? AND istate <> ? AND istate <> ?",
array(
$remote,
Thread::STATE_CLOSED,
Thread::STATE_LEFT,
),
array('return_rows' => Database::RETURN_ONE_ROW)
);
if ($result && isset($result['opened'])) {
return $result['opened'] >= Settings::get('max_connections_from_one_host');
}
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
*
* Check if variable with name $name exists in the Thread::$propertyMap array.
* If it does not exist triggers an error with E_USER_NOTICE level and returns false.
* Check if variable with name $name exists in the Thread::$propertyMap
* array. If it does not exist triggers an error with E_USER_NOTICE level
* and returns false.
*
* @param string $name property name
* @return mixed
* @see Thread::$propertyMap
*/
public function __get($name) {
public function __get($name)
{
// Check property existance
if (!array_key_exists($name, $this->propertyMap)) {
trigger_error("Undefined property '{$name}'", E_USER_NOTICE);
return NULL;
return null;
}
$field_name = $this->propertyMap[$name];
return $this->threadInfo[$field_name];
}
@ -513,16 +500,17 @@ Class Thread {
* @return mixed
* @see Thread::$propertyMap
*/
public function __set($name, $value) {
public function __set($name, $value)
{
if (empty($this->propertyMap[$name])) {
trigger_error("Undefined property '{$name}'", E_USER_NOTICE);
return;
}
$field_name = $this->propertyMap[$name];
if (array_key_exists($field_name, $this->threadInfo)
&& ($this->threadInfo[$field_name] === $value)) {
if (array_key_exists($field_name, $this->threadInfo) && ($this->threadInfo[$field_name] === $value)) {
return;
}
@ -541,19 +529,22 @@ Class Thread {
* param string $name Variable name
* return boolean True if variable exists and false otherwise
*/
public function __isset($name) {
public function __isset($name)
{
if (!array_key_exists($name, $this->propertyMap)) {
return false;
}
$property_name = $this->propertyMap[$name];
return isset($this->threadInfo[$property_name]);
}
/**
* Remove thread from database
*/
public function delete() {
public function delete()
{
$db = Database::getInstance();
$db->query(
"DELETE FROM {chatthread} WHERE threadid = :id LIMIT 1",
@ -564,13 +555,16 @@ Class 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
* otherwise.
* @param boolean $is_typing Indicates if user or operator is typing a message.
* @param boolean $is_user Indicates user or operator pings thread. Boolean
* true for user and boolean false otherwise.
* @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.
// Update revision leads to rerender thread in threads list at client
// side. Do it on every ping is too costly.
@ -606,14 +600,14 @@ Class Thread {
// Check if user chatting at the moment
if ($this->state == self::STATE_CHATTING) {
// 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(
self::KIND_CONN,
$message_to_post,
array(
'created' => $last_ping_other_side
+ self::CONNECTION_TIMEOUT
)
array('created' => $last_ping_other_side + self::CONNECTION_TIMEOUT)
);
// And update thread
@ -630,14 +624,14 @@ Class Thread {
$this->lastPingUser = 0;
// 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(
self::KIND_FOR_AGENT,
$message_to_post,
array(
'created' => $last_ping_other_side
+ self::CONNECTION_TIMEOUT
)
array('created' => $last_ping_other_side + self::CONNECTION_TIMEOUT)
);
}
}
@ -648,9 +642,11 @@ Class Thread {
/**
* 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();
// Update modified time and last revision if need
@ -672,14 +668,15 @@ Class Thread {
$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;
$db->query($query, $values);
// Trigger thread changed event
$args = array(
'thread' => $this,
'changed_fields' => $this->changedFields
'changed_fields' => $this->changedFields,
);
$dispatcher = EventDispatcher::getInstance();
$dispatcher->triggerEvent('threadChanged', $args);
@ -691,14 +688,20 @@ Class Thread {
/**
* 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
*/
public function checkForReassign($operator) {
$operator_name = ($this->locale == HOME_LOCALE) ? $operator['vclocalename'] : $operator['vccommonname'];
public function checkForReassign($operator)
{
$operator_name = ($this->locale == HOME_LOCALE)
? $operator['vclocalename']
: $operator['vccommonname'];
if ($this->state == self::STATE_WAITING &&
($this->nextAgent == $operator['operatorid'] || $this->agentId == $operator['operatorid'])) {
$is_operator_correct = $this->nextAgent == $operator['operatorid']
|| $this->agentId == $operator['operatorid'];
if ($this->state == self::STATE_WAITING && $is_operator_correct) {
// Prepare message
if ($this->nextAgent == $operator['operatorid']) {
@ -708,7 +711,11 @@ Class Thread {
$this->locale
);
} 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
@ -745,20 +752,23 @@ Class Thread {
* - 'data' array, arbitrary data attached to the message
* @see Thread::postMessage()
*/
public function getMessages($is_user, &$last_id) {
public function getMessages($is_user, &$last_id)
{
$db = Database::getInstance();
// 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(
"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",
$query,
array(
':threadid' => $this->id,
':lastid' => $last_id
':lastid' => $last_id,
),
array('return_rows' => Database::RETURN_ALL_ROWS)
);
@ -819,8 +829,8 @@ Class Thread {
* - '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.
* will be converted to array and serialized before save. If there is
* no such data do not set this field.
*
* @return int Message ID
*
@ -834,90 +844,22 @@ Class Thread {
* @see Thread::getMessages()
* @see Thread::postPluginMessage()
*/
public function postMessage($kind, $message, $options = array()) {
public function postMessage($kind, $message, $options = array())
{
$options = is_array($options) ? $options : array();
// Send message
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
*
* @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
if ($is_user) {
$this->postMessage(
@ -953,14 +895,15 @@ Class Thread {
$db = Database::getInstance();
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(
':threadid' => $this->id,
':kind_user' => Thread::KIND_USER
':kind_user' => Thread::KIND_USER,
),
array(
'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
* @return boolean Boolean TRUE on success or FALSE on failure
*/
public function take($operator) {
public function take($operator)
{
$take_thread = false;
$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
$take_thread = true;
if ($this->state == self::STATE_WAITING) {
@ -995,10 +945,18 @@ Class Thread {
$this->locale
);
} else {
$message = getstring2_("chat.status.operator.returned", array($operator_name), $this->locale);
$message = getstring2_(
"chat.status.operator.returned",
array($operator_name),
$this->locale
);
}
} 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) {
// User chatting
@ -1034,6 +992,7 @@ Class Thread {
$operator['vcavatar'] ? $operator['vcavatar'] : ""
);
}
return true;
}
@ -1042,7 +1001,8 @@ Class Thread {
*
* @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
if ($this->userName != $new_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
*
* @param string $link URL of the new operator avatar
*/
protected function setupAvatar($link) {
protected function setupAvatar($link)
{
$processor = ThreadProcessor::getInstance();
$processor->call(array(
array(
@ -1076,11 +1148,9 @@ Class Thread {
'return' => array(),
'references' => array(),
'recipient' => 'user',
'imageLink' => $link
)
)
'imageLink' => $link,
),
),
));
}
}
?>

View File

@ -17,9 +17,11 @@
/**
* Autoloader for classes which implements PSR-0 standard.
*
* @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' .
DIRECTORY_SEPARATOR . 'classes';
@ -35,5 +37,3 @@ function class_autoload($class_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
* not be read.
*/
function read_config_file($file) {
function read_config_file($file)
{
if (!is_readable($file)) {
return false;
}
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.
*/
define('DEFAULT_CRON_KEY', md5(
$mysqlhost . '##' . $mysqldb . '##' . $mysqllogin. '##' .
$mysqlpass . '##' . $mysqlprefix . '##'
$mysqlhost . '##' . $mysqldb . '##' . $mysqllogin . '##'
. $mysqlpass . '##' . $mysqlprefix . '##'
));
/**
@ -54,5 +54,3 @@ define('VISITOR_COOKIE_NAME', 'MIBEW_VisitorID');
* Internal system 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",
"\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");
?>

View File

@ -16,20 +16,18 @@
*/
/* 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 token match
// If token match
if (!isset($_POST['csrf_token']) || ($_POST['csrf_token'] != $_SESSION['csrf_token'])) {
die("CSRF failure");
}
} elseif (isset($_GET['act'])) {
if (($_GET['act'] == 'del' || $_GET['act'] == 'delete') && $_GET['csrf_token'] != $_SESSION['csrf_token']) {
die("CSRF failure");
}
}
@ -38,7 +36,7 @@ function csrfchecktoken()
/* print csrf token as a hidden field */
function print_csrf_token_input()
{
setcsrftoken();
set_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 */
function print_csrf_token_in_url()
{
setcsrftoken();
set_csrf_token();
echo "&amp;csrf_token=" . $_SESSION['csrf_token'];
}
/* set csrf token */
function setcsrftoken()
function set_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.
*/
require_once(MIBEW_FS_ROOT.'/libs/common/locale.php');
function date_diff_to_text($seconds)
{
$minutes = div($seconds, 60);
@ -26,13 +24,14 @@ function date_diff_to_text($seconds)
} else {
$hours = div($minutes, 60);
$minutes = $minutes % 60;
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'];
$year = $start['year'];
$result = array();
@ -44,7 +43,8 @@ function get_month_selection($fromtime, $totime)
$month = 1;
$year++;
}
} while ($current < $totime);
} while ($current < $to_time);
return $result;
}
@ -53,20 +53,23 @@ function get_form_date($day, $month)
if (preg_match('/^(\d{2}).(\d{2})$/', $month, $matches)) {
return mktime(0, 0, 0, $matches[1], $day, $matches[2]);
}
return 0;
}
function set_form_date($utime, $prefix) {
function set_form_date($utime, $prefix)
{
return array(
"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)
{
if ($unixtime < 60 * 60 * 24 * 30)
if ($unixtime < 60 * 60 * 24 * 30) {
return getlocal("time.never");
}
$then = getdate($unixtime);
$now = getdate();
@ -81,5 +84,3 @@ function date_to_text($unixtime)
return strftime($date_format . " " . getlocal("time.timeformat"), $unixtime);
}
?>

View File

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

View File

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

View File

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

View File

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

View File

@ -15,25 +15,28 @@
* limitations under the License.
*/
// Import namespaces and classes of the core
use Mibew\EventDispatcher;
// Initialize libraries
require_once(MIBEW_FS_ROOT.'/libs/common/locale.php');
function get_popup($href, $jshref, $message, $title, $wndName, $options)
function get_popup($href, $js_href, $message, $title, $wnd_name, $options)
{
if (!$jshref) {
$jshref = "'$href'";
if (!$js_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)
{
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\" alt=\"\"/>";
}
@ -55,7 +58,8 @@ function start_html_output()
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("Cache-Control: no-store, no-cache, must-revalidate");
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"');
}
function topage($text)
function to_page($text)
{
return myiconv(MIBEW_ENCODING, getoutputenc(), $text);
}
@ -81,11 +85,12 @@ function topage($text)
* @param string $page_name CSS files load to this page
* @return string HTML block of 'link' tags
*/
function get_additional_css($page_name) {
function get_additional_css($page_name)
{
// Prepare event arguments array
$args = array(
'page' => $page_name,
'css' => array()
'css' => array(),
);
// Trigger event
@ -114,7 +119,8 @@ function get_additional_css($page_name) {
* @param string $page_name JavaScript files load to this page
* @return string HTML block of 'script' tags
*/
function get_additional_js($page_name) {
function get_additional_js($page_name)
{
// Prepare event arguments array
$args = array(
'page' => $page_name,
@ -145,11 +151,12 @@ function get_additional_js($page_name) {
* @param string $page_name Localized strings add to this page
* @return string JSON encoded localized strings
*/
function get_additional_localized_strings($page_name) {
function get_additional_localized_strings($page_name)
{
// Prepare event arguments array
$args = array(
'page' => $page_name,
'localized_strings' => array()
'localized_strings' => array(),
);
// Trigger event
@ -158,8 +165,7 @@ function get_additional_localized_strings($page_name) {
// Build result
$result = array();
if (! empty($args['localized_strings'])
&& is_array($args['localized_strings'])) {
if (!empty($args['localized_strings']) && is_array($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
* @return string JavaScript options block
*/
function get_js_plugin_options($page_name) {
function get_js_plugin_options($page_name)
{
// Prepare event arguments array
$args = array(
'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'
* function
*/
function get_plugins_data($page_name) {
function get_plugins_data($page_name)
{
return array(
'additional_css' => get_additional_css($page_name),
'additional_js' => get_additional_js($page_name),
@ -222,8 +230,7 @@ function no_field($key)
function failed_uploading_file($filename, $key)
{
return getlocal2("errors.failed.uploading.file",
array($filename, getlocal($key)));
return getlocal2("errors.failed.uploading.file", array($filename, getlocal($key)));
}
function wrong_field($key)
@ -234,12 +241,14 @@ function wrong_field($key)
function add_params($servlet, $params)
{
$infix = '?';
if (strstr($servlet, $infix) !== FALSE)
if (strstr($servlet, $infix) !== false) {
$infix = '&amp;';
}
foreach ($params as $k => $v) {
$servlet .= $infix . $k . "=" . $v;
$infix = '&amp;';
}
return $servlet;
}
@ -259,14 +268,14 @@ function add_params($servlet, $params)
* functions, specified in 'handlers' item.
* @return string JSONP response that ready to send to the widget
*/
function build_widget_response($response) {
function build_widget_response($response)
{
$result = $response + array(
'load' => array(),
'handlers' => array(),
'dependences' => array(),
'data' => array()
'data' => array(),
);
return "Mibew.Objects.widget.onResponse(" . json_encode($result) . ");";
}
?>

View File

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

View File

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

View File

@ -21,12 +21,10 @@
* @param string $cron_key Cron security key
* @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 .= empty($cron_key)
? ''
: '?cron_key='.$cron_key;
$path .= empty($cron_key) ? '' : '?cron_key=' . $cron_key;
return $path;
}
?>

View File

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

View File

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

View File

@ -23,10 +23,11 @@ function group_by_id($id)
{
$db = Database::getInstance();
$group = $db->query(
"select * from {chatgroup} where groupid = ?",
"SELECT * FROM {chatgroup} WHERE groupid = ?",
array($id),
array('return_rows' => Database::RETURN_ONE_ROW)
);
return $group;
}
@ -34,20 +35,22 @@ function group_by_name($name)
{
$db = Database::getInstance();
$group = $db->query(
"select * from {chatgroup} where vclocalname = ?",
"SELECT * FROM {chatgroup} WHERE vclocalname = ?",
array($name),
array('return_rows' => Database::RETURN_ONE_ROW)
);
return $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'];
else
} else {
return $group['vccommonname'];
}
}
/**
* 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.
* @return array Tabs list
*/
function setup_group_settings_tabs($gid, $active) {
function setup_group_settings_tabs($gid, $active)
{
$tabs = array();
if ($gid) {
$tabs = array(
getlocal("page_group.tab.main") => $active != 0 ? (MIBEW_WEB_ROOT . "/operator/group.php?gid=$gid") : "",
getlocal("page_group.tab.members") => $active != 1 ? (MIBEW_WEB_ROOT . "/operator/groupmembers.php?gid=$gid") : "",
getlocal("page_group.tab.main") => ($active != 0
? (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;
}
function get_operator_groupslist($operatorid)
function get_operator_groups_list($operator_id)
{
$db = Database::getInstance();
if (Settings::get('enablegroups') == '1') {
$groupids = array(0);
$allgroups = $db->query(
"select groupid from {chatgroupoperator} where operatorid = ? order by groupid",
array($operatorid),
$group_ids = array(0);
$all_groups = $db->query(
"SELECT groupid FROM {chatgroupoperator} WHERE operatorid = ? ORDER BY groupid",
array($operator_id),
array('return_rows' => Database::RETURN_ALL_ROWS)
);
foreach ($allgroups as $g) {
$groupids[] = $g['groupid'];
foreach ($all_groups as $g) {
$group_ids[] = $g['groupid'];
}
return implode(",", $groupids);
return implode(",", $group_ids);
} else {
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();
$groupslist = $db->query(
"select {chatgroup}.groupid as groupid, parent, vclocalname " .
"from {chatgroup} order by vclocalname",
NULL,
$groups_list = $db->query(
("SELECT {chatgroup}.groupid AS groupid, parent, vclocalname "
. "FROM {chatgroup} ORDER BY vclocalname"),
null,
array('return_rows' => Database::RETURN_ALL_ROWS)
);
$result = array(array('groupid' => '', 'level' => '', 'vclocalname' => getlocal("form.field.groupparent.root")));
if ($skipgroup) {
$skipgroup = (array)$skipgroup;
if ($skip_group) {
$skip_group = (array) $skip_group;
} 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;
}
function group_has_children($groupid)
function group_has_children($group_id)
{
$db = Database::getInstance();
$children = $db->query(
"select COUNT(*) as count from {chatgroup} where parent = ?",
array($groupid),
"SELECT COUNT(*) AS count FROM {chatgroup} WHERE parent = ?",
array($group_id),
array('return_rows' => Database::RETURN_ONE_ROW)
);
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.
*
* @param int $group_id Group id
* @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
$group = group_by_id($group_id);
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.
* @return bool
*/
function group_is_online($group) {
return ($group['ilastseen'] !== NULL
&& $group['ilastseen'] < Settings::get('online_timeout'));
function group_is_online($group)
{
return $group['ilastseen'] !== null
&& $group['ilastseen'] < Settings::get('online_timeout');
}
/**
@ -168,8 +189,9 @@ function group_is_online($group) {
* key.
* @return bool
*/
function group_is_away($group) {
return $group['ilastseenaway'] !== NULL
function group_is_away($group)
{
return $group['ilastseenaway'] !== null
&& $group['ilastseenaway'] < Settings::get('online_timeout');
}
@ -181,17 +203,20 @@ function group_is_away($group) {
* - 'vclocaldescription': string, contain local description of the group.
* @return string Group description
*/
function get_group_description($group) {
if (HOME_LOCALE == CURRENT_LOCALE
function get_group_description($group)
{
$use_local_description = HOME_LOCALE == CURRENT_LOCALE
|| !isset($group['vccommondescription'])
|| !$group['vccommondescription']) {
|| !$group['vccommondescription'];
if ($use_local_description) {
return $group['vclocaldescription'];
} else {
return $group['vccommondescription'];
}
}
function check_group_params($group, $extra_params = NULL)
function check_group_params($group, $extra_params = null)
{
$obligatory_params = array(
'name',
@ -203,8 +228,13 @@ function check_group_params($group, $extra_params = NULL)
'parent',
'chattitle',
'hosturl',
'logo');
$params = is_null($extra_params)?$obligatory_params:array_merge($obligatory_params,$extra_params);
'logo',
);
$params = is_null($extra_params)
? $obligatory_params
: array_merge($obligatory_params, $extra_params);
if (count(array_diff($params, array_keys($group))) != 0) {
die('Wrong parameters set!');
}
@ -213,22 +243,34 @@ function check_group_params($group, $extra_params = NULL)
/**
* Creates group
*
* @param array $group Operators' group.
* The $group array must contains following keys:
* name, description, commonname, commondescription,
* email, weight, parent, title, chattitle, hosturl, logo
* @param array $group Operators' group. The $group array must contains the
* following keys:
* - name,
* - description,
* - commonname,
* - commondescription,
* - email,
* - weight,
* - parent,
* - title,
* - chattitle,
* - hosturl,
* - logo
* @return array Created group
*/
function create_group($group)
{
$db = Database::getInstance();
check_group_params($group);
$db = Database::getInstance();
$db->query(
"insert into {chatgroup} (parent, vclocalname,vclocaldescription,vccommonname, " .
"vccommondescription,vcemail,vctitle,vcchattitle,vchosturl,vclogo,iweight) " .
"values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
("INSERT INTO {chatgroup} ("
. "parent, vclocalname, vclocaldescription, vccommonname, "
. "vccommondescription, vcemail, vctitle, vcchattitle, vchosturl, "
. "vclogo, iweight"
. ") values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"),
array(
($group['parent'] ? (int)$group['parent'] : NULL),
($group['parent'] ? (int) $group['parent'] : null),
$group['name'],
$group['description'],
$group['commonname'],
@ -238,37 +280,52 @@ function create_group($group)
$group['chattitle'],
$group['hosturl'],
$group['logo'],
$group['weight']
$group['weight'],
)
);
$id = $db->insertedId();
$newdep = $db->query(
"select * from {chatgroup} where groupid = ?",
$new_group = $db->query(
"SELECT * FROM {chatgroup} WHERE groupid = ?",
array($id),
array('return_rows' => Database::RETURN_ONE_ROW)
);
return $newdep;
return $new_group;
}
/**
* Updates group info
*
* @param array $group Operators' group.
* The $group array must contains following keys:
* id, name, description, commonname, commondescription,
* email, weight, parent, title, chattitle, hosturl, logo
* @param array $group Operators' group. The $group array must contains the
* following keys:
* - id,
* - name,
* - description,
* - commonname,
* - commondescription,
* - email,
* - weight,
* - parent,
* - title,
* - chattitle,
* - hosturl,
* - logo
*/
function update_group($group)
{
$db = Database::getInstance();
check_group_params($group, array('id'));
$db = Database::getInstance();
$db->query(
"update {chatgroup} set parent = ?, vclocalname = ?, vclocaldescription = ?, " .
"vccommonname = ?, vccommondescription = ?, vcemail = ?, vctitle = ?, " .
"vcchattitle = ?, vchosturl = ?, vclogo = ?, iweight = ? where groupid = ?",
("UPDATE {chatgroup} SET "
. "parent = ?, vclocalname = ?, vclocaldescription = ?, "
. "vccommonname = ?, vccommondescription = ?, "
. "vcemail = ?, vctitle = ?, vcchattitle = ?, "
. "vchosturl = ?, vclogo = ?, iweight = ? "
. "where groupid = ?"),
array(
($group['parent'] ? (int)$group['parent'] : NULL),
($group['parent'] ? (int) $group['parent'] : null),
$group['name'],
$group['description'],
$group['commonname'],
@ -285,33 +342,34 @@ function update_group($group)
if ($group['parent']) {
$db->query(
"update {chatgroup} set parent = NULL where parent = ?",
"UPDATE {chatgroup} SET parent = NULL WHERE parent = ?",
array($group['id'])
);
}
}
function get_group_members($groupid)
function get_group_members($group_id)
{
$db = Database::getInstance();
return $db->query(
"select operatorid from {chatgroupoperator} where groupid = ?",
array($groupid),
"SELECT operatorid FROM {chatgroupoperator} WHERE groupid = ?",
array($group_id),
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->query("delete from {chatgroupoperator} where groupid = ?", array($groupid));
foreach ($newvalue as $opid) {
$db->query(
"insert into {chatgroupoperator} (groupid, operatorid) values (?, ?)",
array($groupid,$opid)
"DELETE FROM {chatgroupoperator} WHERE groupid = ?",
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');
// 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
@ -43,20 +49,21 @@ spl_autoload_register('class_autoload');
// Include common libs
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/datetime.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/request.php');
require_once(MIBEW_FS_ROOT . '/libs/common/response.php');
require_once(MIBEW_FS_ROOT . '/libs/common/string.php');
// Make session cookie more secure
@ini_set('session.cookie_httponly', TRUE);
@ini_set('session.cookie_httponly', true);
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.name', 'MibewSessionID');
@ -86,5 +93,3 @@ if (! empty($plugins_list)) {
// Variable $plugins_config defined in libs/config.php
\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
* if visitor with specfied ID does not exist.
*/
function invitation_state($visitor_id) {
function invitation_state($visitor_id)
{
$db = Database::getInstance();
$db_result = $db->query(
"SELECT t.threadid, t.invitationstate, t.istate " .
"FROM {chatsitevisitor} v, {chatthread} t " .
"WHERE visitorid = ? " .
"AND t.threadid = v.threadid",
("SELECT t.threadid, t.invitationstate, t.istate "
. "FROM {chatsitevisitor} v, {chatthread} t "
. "WHERE visitorid = ? "
. "AND t.threadid = v.threadid"),
array($visitor_id),
array('return_rows' => Database::RETURN_ONE_ROW)
);
@ -49,6 +50,7 @@ function invitation_state($visitor_id) {
&& ($db_result['invitationstate'] == Thread::INVITATION_WAIT);
$ret['threadid'] = $db_result['threadid'];
}
return $ret;
}
@ -60,7 +62,8 @@ function invitation_state($visitor_id) {
* @return Thread|boolean Thread object related with invitation or boolean
* false on failure
*/
function invitation_invite($visitor_id, $operator) {
function invitation_invite($visitor_id, $operator)
{
// Check if visitor already invited
$invitation_state = invitation_state($visitor_id);
if ($invitation_state['invited']) {
@ -103,13 +106,13 @@ function invitation_invite($visitor_id, $operator) {
$db = Database::getInstance();
$db->query(
"UPDATE {chatsitevisitor} set " .
"invitations = invitations + 1, " .
"threadid = :thread_id " .
"WHERE visitorid = :visitor_id",
("UPDATE {chatsitevisitor} set "
. "invitations = invitations + 1, "
. "threadid = :thread_id "
. "WHERE visitorid = :visitor_id"),
array(
':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"),
array(
'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
* @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
$invitation_state = invitation_state($visitor_id);
if (!$invitation_state['invited']) {
@ -174,8 +178,8 @@ function invitation_accept($visitor_id) {
// Update visitor info
$db->query(
"UPDATE {chatsitevisitor} SET chats = chats + 1 " .
"WHERE visitorid = :visitor_id",
("UPDATE {chatsitevisitor} SET chats = chats + 1 "
. "WHERE visitorid = :visitor_id"),
array(':visitor_id' => $visitor_id)
);
@ -187,7 +191,8 @@ function invitation_accept($visitor_id) {
*
* @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);
// Send message to operator
@ -201,18 +206,18 @@ function invitation_reject($visitor_id) {
$db = Database::getInstance();
$db->query(
"UPDATE {chatsitevisitor} v, {chatthread} t SET " .
"v.threadid = NULL, " .
"t.invitationstate = :invitation_rejected, " .
"t.istate = :state_closed, " .
"t.dtmclosed = :now " .
"WHERE t.threadid = v.threadid " .
"AND visitorid = :visitor_id",
("UPDATE {chatsitevisitor} v, {chatthread} t SET "
. "v.threadid = NULL, "
. "t.invitationstate = :invitation_rejected, "
. "t.istate = :state_closed, "
. "t.dtmclosed = :now "
. "WHERE t.threadid = v.threadid "
. "AND visitorid = :visitor_id"),
array(
':invitation_rejected' => Thread::INVITATION_REJECTED,
':state_closed' => Thread::STATE_CLOSED,
':visitor_id' => $visitor_id,
':now' => time()
':now' => time(),
)
);
}
@ -220,41 +225,42 @@ function invitation_reject($visitor_id) {
/**
* Close old invitations
*/
function invitation_close_old() {
function invitation_close_old()
{
$db = Database::getInstance();
// Get all threads to close
$threads = $db->query(
"SELECT * FROM {chatthread} " .
"WHERE istate = :state_invited " .
"AND invitationstate = :invitation_wait " .
"AND (:now - dtmcreated) > :lifetime",
("SELECT * FROM {chatthread} "
. "WHERE istate = :state_invited "
. "AND invitationstate = :invitation_wait "
. "AND (:now - dtmcreated) > :lifetime"),
array(
':invitation_wait' => Thread::INVITATION_WAIT,
':state_invited' => Thread::STATE_INVITED,
':lifetime' => Settings::get('invitation_lifetime'),
':now' => time()
':now' => time(),
),
array('return_rows' => Database::RETURN_ALL_ROWS)
);
// Remove old invitations
$db->query(
"UPDATE {chatsitevisitor} v, {chatthread} t SET " .
"t.invitationstate = :invitation_ignored, " .
"t.istate = :state_closed, " .
"t.dtmclosed = :now, " .
"v.threadid = NULL " .
"WHERE t.istate = :state_invited " .
"AND t.invitationstate = :invitation_wait " .
"AND (:now - t.dtmcreated) > :lifetime",
("UPDATE {chatsitevisitor} v, {chatthread} t SET "
. "t.invitationstate = :invitation_ignored, "
. "t.istate = :state_closed, "
. "t.dtmclosed = :now, "
. "v.threadid = NULL "
. "WHERE t.istate = :state_invited "
. "AND t.invitationstate = :invitation_wait "
. "AND (:now - t.dtmcreated) > :lifetime"),
array(
':invitation_ignored' => Thread::INVITATION_IGNORED,
':invitation_wait' => Thread::INVITATION_WAIT,
':state_closed' => Thread::STATE_CLOSED,
':state_invited' => Thread::STATE_INVITED,
':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
* @return array Array of invitation data
*/
function setup_invitation_view(Thread $thread) {
function setup_invitation_view(Thread $thread)
{
$data = prepare_chat_app_data();
// Set refresh frequency
@ -290,18 +297,16 @@ function setup_invitation_view(Thread $thread) {
$data['invitation']['thread'] = array(
'id' => $thread->id,
'token' => $thread->lastToken
'token' => $thread->lastToken,
);
$data['invitation']['user'] = array(
'name' => htmlspecialchars(topage($thread->userName)),
'name' => htmlspecialchars(to_page($thread->userName)),
'canChangeName' => false,
'isAgent' => false
'isAgent' => false,
);
$data['startFrom'] = 'invitation';
return $data;
}
?>

View File

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

View File

@ -15,7 +15,6 @@
* limitations under the License.
*/
/**
* Builds list of operator settings tabs. The keys of the resulting array are
* 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.
* @return array Tabs list
*/
function setup_operator_settings_tabs($operator_id, $active) {
function setup_operator_settings_tabs($operator_id, $active)
{
$tabs = array();
if ($operator_id) {
$tabs = array(
getlocal("page_agent.tab.main") => $active != 0 ? (MIBEW_WEB_ROOT . "/operator/operator.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) : ""
getlocal("page_agent.tab.main") => ($active != 0
? (MIBEW_WEB_ROOT . "/operator/operator.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;
}
?>

View File

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

View File

@ -25,20 +25,31 @@ use Mibew\Settings;
* @param int $active Number of the active tab. The count starts from 0.
* @return array Tabs list
*/
function setup_settings_tabs($active) {
function setup_settings_tabs($active)
{
$tabs = array(
getlocal("page_settings.tab.main") => $active != 0 ? (MIBEW_WEB_ROOT . "/operator/settings.php") : "",
getlocal("page_settings.tab.features") => $active != 1 ? (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") : "",
getlocal("page_settings.tab.main") => ($active != 0
? (MIBEW_WEB_ROOT . "/operator/settings.php")
: ""),
getlocal("page_settings.tab.features") => ($active != 1
? (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')) {
$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;
}
?>

View File

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

View File

@ -20,27 +20,25 @@ use Mibew\Database;
use Mibew\Settings;
use Mibew\Thread;
// Initialize libraries
require_once(MIBEW_FS_ROOT.'/libs/chat.php');
function track_visitor($visitorid, $entry, $referer)
function track_visitor($visitor_id, $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);
return $visitor;
} else {
$db = Database::getInstance();
$db->query(
"update {chatsitevisitor} set lasttime = :now " .
"where visitorid = :visitorid",
"UPDATE {chatsitevisitor} SET lasttime = :now WHERE visitorid = :visitorid",
array(
':visitorid' => $visitor['visitorid'],
':now' => time()
':now' => time(),
)
);
track_visit_page($visitor['visitorid'], $referer);
return $visitor['visitorid'];
}
}
@ -51,14 +49,17 @@ function track_visitor_start($entry, $referer)
$db = Database::getInstance();
$db->query(
"insert into {chatsitevisitor} (userid,username,firsttime,lasttime,entry,details) ".
"values (:userid, :username, :now, :now, :entry, :details)",
("INSERT INTO {chatsitevisitor} ( "
. "userid, username, firsttime, lasttime, entry,details "
. ") VALUES ( "
. ":userid, :username, :now, :now, :entry, :details "
. ")"),
array(
':userid' => $visitor['id'],
':username' => $visitor['name'],
':now' => time(),
':entry' => $entry,
':details' => track_build_details()
':details' => track_build_details(),
)
);
@ -71,22 +72,24 @@ function track_visitor_start($entry, $referer)
return $id ? $id : 0;
}
function track_get_visitor_by_id($visitorid)
function track_get_visitor_by_id($visitor_id)
{
$db = Database::getInstance();
return $db->query(
"select * from {chatsitevisitor} where visitorid = ?",
array($visitorid),
"SELECT * FROM {chatsitevisitor} WHERE visitorid = ?",
array($visitor_id),
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();
return $db->query(
"select * from {chatsitevisitor} where threadid = ?",
array($threadid),
"SELECT * FROM {chatsitevisitor} WHERE threadid = ?",
array($thread_id),
array('return_rows' => Database::RETURN_ONE_ROW)
);
}
@ -97,36 +100,44 @@ function track_get_visitor_by_threadid($threadid)
* @param string $user_id User id
* @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();
return $db->query(
"select * from {chatsitevisitor} where userid = ?",
"SELECT * FROM {chatsitevisitor} WHERE userid = ?",
array($user_id),
array('return_rows' => Database::RETURN_ONE_ROW)
);
}
function track_visit_page($visitorid, $page)
function track_visit_page($visitor_id, $page)
{
$db = Database::getInstance();
if (empty($page)) {
return;
}
$lastpage = $db->query(
"select address from {visitedpage} where visitorid = ? " .
"order by visittime desc limit 1",
array($visitorid),
$last_page = $db->query(
("SELECT address "
. "FROM {visitedpage} "
. "WHERE visitorid = ? "
. "ORDER BY visittime DESC "
. "LIMIT 1"),
array($visitor_id),
array('return_rows' => Database::RETURN_ONE_ROW)
);
if ( $lastpage['address'] != $page ) {
if ($last_page['address'] != $page) {
$db->query(
"insert into {visitedpage} (visitorid, address, visittime) " .
"values (:visitorid, :page, :now)",
("INSERT INTO {visitedpage} ("
. "visitorid, address, visittime "
. ") VALUES ( "
. ":visitorid, :page, :now "
.")"),
array(
':visitorid' => $visitorid,
':visitorid' => $visitor_id,
':page' => $page,
':now' => time()
':now' => time(),
)
);
}
@ -136,8 +147,7 @@ function track_get_path($visitor)
{
$db = Database::getInstance();
$query_result = $db->query(
"select address, visittime from {visitedpage} " .
"where visitorid = ?",
"SELECT address, visittime FROM {visitedpage} WHERE visitorid = ?",
array($visitor['visitorid']),
array('return_rows' => Database::RETURN_ALL_ROWS)
);
@ -145,6 +155,7 @@ function track_get_path($visitor)
foreach ($query_result as $page) {
$result[$page['visittime']] = $page['address'];
}
return $result;
}
@ -152,11 +163,10 @@ function track_build_details()
{
$result = array(
'user_agent' => $_SERVER['HTTP_USER_AGENT'],
'remote_host' => get_remote_host()
'remote_host' => get_remote_host(),
);
return serialize($result);
}
function track_retrieve_details($visitor)
@ -167,27 +177,28 @@ function track_retrieve_details($visitor)
/**
* Remove old visitors
*/
function track_remove_old_visitors() {
function track_remove_old_visitors()
{
$db = Database::getInstance();
// Remove associations of visitors with closed threads
$db->query(
"UPDATE {chatsitevisitor} SET threadid = NULL " .
"WHERE threadid IS NOT NULL AND " .
" (SELECT count(*) FROM {chatthread} " .
"WHERE threadid = {chatsitevisitor}.threadid" .
" AND istate <> " . Thread::STATE_CLOSED . " " .
" AND istate <> " . Thread::STATE_LEFT . ") = 0"
"UPDATE {chatsitevisitor} SET threadid = NULL "
. "WHERE threadid IS NOT NULL AND "
. "(SELECT count(*) FROM {chatthread} "
. "WHERE threadid = {chatsitevisitor}.threadid "
. "AND istate <> " . Thread::STATE_CLOSED . " "
. "AND istate <> " . Thread::STATE_LEFT . ") = 0 "
);
// Remove old visitors
$db->query(
"DELETE FROM {chatsitevisitor} " .
"WHERE (:now - lasttime) > :lifetime ".
"AND threadid IS NULL",
("DELETE FROM {chatsitevisitor} "
. "WHERE (:now - lasttime) > :lifetime "
. "AND threadid IS NULL"),
array(
':lifetime' => Settings::get('tracking_lifetime'),
':now' => time()
':now' => time(),
)
);
}
@ -195,19 +206,20 @@ function track_remove_old_visitors() {
/**
* Remove old tracks
*/
function track_remove_old_tracks() {
function track_remove_old_tracks()
{
$db = Database::getInstance();
// Remove old visitors' tracks
$db->query(
"DELETE FROM {visitedpage} " .
"WHERE (:now - visittime) > :lifetime " .
("DELETE FROM {visitedpage} "
. "WHERE (:now - visittime) > :lifetime "
// Remove only tracks that are included in statistics
"AND calculated = 1 " .
"AND visitorid NOT IN (SELECT visitorid FROM {chatsitevisitor}) ",
. "AND calculated = 1 "
. "AND visitorid NOT IN (SELECT visitorid FROM {chatsitevisitor}) "),
array(
':lifetime' => Settings::get('tracking_lifetime'),
':now' => time()
':now' => time(),
)
);
}
@ -215,15 +227,17 @@ function track_remove_old_tracks() {
/**
* 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
* specified visitor id
*/
function track_get_user_id($visitorid) {
$visitor = track_get_visitor_by_id($visitorid);
function track_get_user_id($visitor_id)
{
$visitor = track_get_visitor_by_id($visitor_id);
if (!$visitor) {
return false;
}
return $visitor['userid'];
}
@ -234,17 +248,16 @@ function track_get_user_id($visitorid) {
* visitor.
* @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->query(
'UPDATE {chatsitevisitor} ' .
'SET threadid = :thread_id ' .
'WHERE userid = :user_id',
('UPDATE {chatsitevisitor} '
. 'SET threadid = :thread_id '
. 'WHERE userid = :user_id'),
array(
':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
use Mibew\Settings;
function get_useragent_version($userAgent)
function get_user_agent_version($user_agent)
{
$known_agents = get_known_user_agents();
if (is_array($known_agents)) {
$userAgent = strtolower($userAgent);
$user_agent = strtolower($user_agent);
foreach ($known_agents as $agent) {
if (strstr($userAgent, $agent)) {
if (preg_match("/" . $agent . "[\\s\/]?(\\d+(\\.\\d+(\\.\\d+(\\.\\d+)?)?)?)/", $userAgent, $matches)) {
if (strstr($user_agent, $agent)) {
if (preg_match("/" . $agent . "[\\s\/]?(\\d+(\\.\\d+(\\.\\d+(\\.\\d+)?)?)?)/", $user_agent, $matches)) {
$ver = $matches[1];
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];
} else {
$ver = "1 or 2 (build " . $ver . ")";
}
if (preg_match("/mobile\/(\\d+(\\.\\d+(\\.\\d+)?)?)/", $userAgent, $matches)) {
$userAgent = "iPhone " . $matches[1] . " ($agent $ver)";
if (preg_match("/mobile\/(\\d+(\\.\\d+(\\.\\d+)?)?)/", $user_agent, $matches)) {
$user_agent = "iPhone " . $matches[1] . " ($agent $ver)";
break;
}
}
$userAgent = ucfirst($agent) . " " . $ver;
$user_agent = ucfirst($agent) . " " . $ver;
break;
}
}
}
}
return $userAgent;
return $user_agent;
}
function get_user_addr($addr)
{
if (Settings::get('geolink') && preg_match("/(\\d+\\.\\d+\\.\\d+\\.\\d+)/", $addr, $matches)) {
$userip = $matches[1];
$user_ip = $matches[1];
return get_popup(
str_replace("{ip}", $userip, Settings::get('geolink')),
str_replace("{ip}", $user_ip, Settings::get('geolink')),
'',
htmlspecialchars($addr),
"GeoLocation",
"ip$userip",
"ip$user_ip",
Settings::get('geolinkparams')
);
}
return htmlspecialchars($addr);
}
?>

View File

@ -28,5 +28,3 @@ $page['fixedwrap'] = true;
$page_style = new PageStyle(PageStyle::currentStyle());
$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/groups.php');
require_once(MIBEW_FS_ROOT . '/libs/notify.php');
require_once(MIBEW_FS_ROOT . '/libs/track.php');
$page = array(
'errors' =>array()
'errors' => array(),
);
$token = verifyparam( "token", "/^\d{1,8}$/");
$threadid = verifyparam( "thread", "/^\d{1,8}$/");
$token = verify_param("token", "/^\d{1,8}$/");
$thread_id = verify_param("thread", "/^\d{1,8}$/");
$thread = Thread::load($threadid, $token);
$thread = Thread::load($thread_id, $token);
if (!$thread) {
die("wrong thread");
}
@ -41,9 +42,9 @@ if (! $thread) {
// Initialize chat style which is currently used in system
$chat_style = new ChatStyle(ChatStyle::currentStyle());
$email = getparam('email');
$email = get_param('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) {
$page['errors'][] = no_field("form.field.email");
} elseif (!is_valid_email($email)) {
@ -73,16 +74,15 @@ foreach ($messages as $msg) {
$subject = getstring("mail.user.history.subject");
$body = getstring2(
"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);
$page = array_merge_recursive(
$page,
setup_logo($group)
);
$page = array_merge_recursive($page, setup_logo($group));
$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/operator.php');
require_once(MIBEW_FS_ROOT . '/libs/pagination.php');
require_once(MIBEW_FS_ROOT . '/libs/track.php');
$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(
'errors' => array()
'errors' => array(),
);
// Initialize chat style which is currently used in system
@ -62,17 +63,17 @@ if (!isset($_GET['token'])) {
exit;
}
$thread = Thread::load($threadid);
$thread = Thread::load($thread_id);
if (!$thread || !isset($thread->lastToken)) {
$page['errors'][] = getlocal("thread.error.wrong_thread");
$chat_style->render('error', $page);
exit;
}
$viewonly = verifyparam("viewonly", "/^true$/", false);
$view_only = verify_param("viewonly", "/^true$/", false);
$forcetake = verifyparam("force", "/^true$/", false);
if (!$viewonly && $thread->state == Thread::STATE_CHATTING && $operator['operatorid'] != $thread->agentId) {
$force_take = verify_param("force", "/^true$/", false);
if (!$view_only && $thread->state == Thread::STATE_CHATTING && $operator['operatorid'] != $thread->agentId) {
if (!is_capable(CAN_TAKEOVER, $operator)) {
$page['errors'][] = getlocal("thread.error.cannot_take_over");
@ -80,11 +81,11 @@ if (!isset($_GET['token'])) {
exit;
}
if ($forcetake == false) {
if ($force_take == false) {
$page = array(
'user' => topage($thread->userName),
'agent' => topage($thread->agentName),
'link' => $_SERVER['PHP_SELF'] . "?thread=$threadid&amp;force=true",
'user' => to_page($thread->userName),
'agent' => to_page($thread->agentName),
'link' => $_SERVER['PHP_SELF'] . "?thread=$thread_id&amp;force=true",
'title' => getlocal("confirm.take.head"),
);
$page_style->render('confirm', $page);
@ -92,7 +93,7 @@ if (!isset($_GET['token'])) {
}
}
if (!$viewonly) {
if (!$view_only) {
if (!$thread->take($operator)) {
$page['errors'][] = getlocal("thread.error.cannot_take");
$chat_style->render('error', $page);
@ -105,13 +106,15 @@ if (!isset($_GET['token'])) {
}
$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;
}
$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) {
die("wrong thread");
}
@ -129,11 +132,11 @@ $page = array_merge_recursive(
start_html_output();
$pparam = verifyparam("act", "/^(redirect)$/", "default");
$pparam = verify_param("act", "/^(redirect)$/", "default");
if ($pparam == "redirect") {
$page = array_merge_recursive(
$page,
setup_redirect_links($threadid, $operator, $token)
setup_redirect_links($thread_id, $operator, $token)
);
$chat_style->render('redirect', $page);
} else {
@ -142,5 +145,3 @@ if ($pparam == "redirect") {
// Render the 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');
$operator = check_login();
csrfchecktoken();
csrf_check_token();
$opId = verifyparam("op", "/^\d{1,9}$/");
$op_id = verify_param("op", "/^\d{1,9}$/");
$page = array(
'opid' => $opId,
'opid' => $op_id,
'avatar' => '',
'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);
$op = operator_by_id($opId);
$op = operator_by_id($op_id);
if (!$op) {
$page['errors'][] = getlocal("no_such_operator");
} elseif (isset($_POST['op'])) {
$avatar = $op['vcavatar'];
if (!$canmodify) {
if (!$can_modify) {
$page['errors'][] = getlocal('page_agent.cannot_modify');
} elseif (isset($_FILES['avatarFile']) && $_FILES['avatarFile']['name']) {
$valid_types = array("gif", "jpg", "png", "tif", "jpeg");
@ -55,7 +53,7 @@ if (!$op) {
$tmp_file_name = $_FILES['avatarFile']['tmp_name'];
$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'];
if ($file_size == 0 || $file_size > Settings::get('max_uploaded_file_size')) {
@ -81,36 +79,30 @@ if (!$op) {
if (count($page['errors']) == 0) {
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;
}
header("Location: " . MIBEW_WEB_ROOT . "/operator/avatar.php?op=" . intval($opId));
header("Location: " . MIBEW_WEB_ROOT . "/operator/avatar.php?op=" . intval($op_id));
exit;
} else {
$page['avatar'] = topage($op['vcavatar']);
$page['avatar'] = to_page($op['vcavatar']);
}
} else {
if (isset($_GET['delete']) && $_GET['delete'] == "true" && $canmodify) {
if (isset($_GET['delete']) && $_GET['delete'] == "true" && $can_modify) {
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;
}
$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['canmodify'] = $canmodify ? "1" : "";
$page['currentop'] = $op ? to_page(get_operator_name($op)) . " (" . $op['vclogin'] . ")" : getlocal("not_found");
$page['canmodify'] = $can_modify ? "1" : "";
$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,
prepare_menu($operator)
);
$page['tabs'] = setup_operator_settings_tabs($opId, 1);
$page = array_merge($page, prepare_menu($operator));
$page['tabs'] = setup_operator_settings_tabs($op_id, 1);
$page_style = new PageStyle(PageStyle::currentStyle());
$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/operator.php');
require_once(MIBEW_FS_ROOT . '/libs/pagination.php');
require_once(MIBEW_FS_ROOT . '/libs/track.php');
$operator = check_login();
csrfchecktoken();
csrf_check_token();
$page = array('banId' => '');
$page['saved'] = false;
$page['thread'] = '';
@ -35,11 +36,11 @@ $page['threadid'] = '';
$page['errors'] = array();
if (isset($_POST['address'])) {
$banId = verifyparam("banId", "/^(\d{1,9})?$/", "");
$address = getparam("address");
$days = getparam("days");
$comment = getparam('comment');
$threadid = isset($_POST['threadid']) ? getparam('threadid') : "";
$ban_id = verify_param("banId", "/^(\d{1,9})?$/", "");
$address = get_param("address");
$days = get_param("days");
$comment = get_param('comment');
$thread_id = isset($_POST['threadid']) ? get_param('threadid') : "";
if (!$address) {
$page['errors'][] = no_field("form.field.address");
@ -55,8 +56,8 @@ if (isset($_POST['address'])) {
$existing_ban = ban_for_addr($address);
if ((!$banId && $existing_ban) ||
($banId && $existing_ban && $banId != $existing_ban['banid'])) {
if ((!$ban_id && $existing_ban) ||
($ban_id && $existing_ban && $ban_id != $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();
$now = time();
$till_time = $now + $days * 24 * 60 * 60;
if (!$banId) {
if (!$ban_id) {
$db->query(
"insert into {chatban} (dtmcreated,dtmtill,address,comment) " .
"values (:now,:till,:address,:comment)",
("INSERT INTO {chatban} (dtmcreated, dtmtill, address, comment) "
. "VALUES (:now,:till,:address,:comment)"),
array(
':now' => $now,
':till' => $till_time,
':address' => $address,
':comment' => $comment
':comment' => $comment,
)
);
} else {
$db->query(
"update {chatban} set dtmtill = :till,address = :address, " .
"comment = :comment where banid = :banid",
("UPDATE {chatban} SET dtmtill = :till, address = :address, "
. "comment = :comment WHERE banid = :banid"),
array(
':till' => $till_time,
':address' => $address,
':comment' => $comment,
':banid' => $banId
':banid' => $ban_id,
)
);
}
$page['saved'] = true;
$page['address'] = $address;
} else {
$page['banId'] = topage($banId);
$page['formaddress'] = topage($address);
$page['formdays'] = topage($days);
$page['formcomment'] = topage($comment);
$page['threadid'] = $threadid;
$page['banId'] = to_page($ban_id);
$page['formaddress'] = to_page($address);
$page['formdays'] = to_page($days);
$page['formcomment'] = to_page($comment);
$page['threadid'] = $thread_id;
}
} elseif (isset($_GET['id'])) {
$banId = verifyparam('id', "/^\d{1,9}$/");
$ban_id = verify_param('id', "/^\d{1,9}$/");
$db = Database::getInstance();
$ban = $db->query(
"select banid,(dtmtill - :now)" .
" as days,address,comment from {chatban} where banid = :banid",
("SELECT banid, (dtmtill - :now) AS days, address, comment "
. "FROM {chatban} WHERE banid = :banid"),
array(
':banid' => $banId,
':now' => time()
':banid' => $ban_id,
':now' => time(),
),
array('return_rows' => Database::RETURN_ONE_ROW)
);
if ($ban) {
$page['banId'] = topage($ban['banid']);
$page['formaddress'] = topage($ban['address']);
$page['formdays'] = topage(round($ban['days'] / 86400));
$page['formcomment'] = topage($ban['comment']);
$page['banId'] = to_page($ban['banid']);
$page['formaddress'] = to_page($ban['address']);
$page['formdays'] = to_page(round($ban['days'] / 86400));
$page['formcomment'] = to_page($ban['comment']);
} else {
$page['errors'][] = "Wrong id";
}
} elseif (isset($_GET['thread'])) {
$threadid = verifyparam('thread', "/^\d{1,9}$/");
$thread = Thread::load($threadid);
$thread_id = verify_param('thread', "/^\d{1,9}$/");
$thread = Thread::load($thread_id);
if ($thread) {
$page['thread'] = topage($thread->userName);
$page['threadid'] = $threadid;
$page['formaddress'] = topage($thread->remote);
$page['thread'] = to_page($thread->userName);
$page['threadid'] = $thread_id;
$page['formaddress'] = to_page($thread->remote);
$page['formdays'] = 15;
}
}
$page['title'] = getlocal("page_ban.title");
$page = array_merge(
$page,
prepare_menu($operator, false)
);
$page = array_merge($page, prepare_menu($operator, false));
$page_style = new PageStyle(PageStyle::currentStyle());
$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/operator.php');
require_once(MIBEW_FS_ROOT . '/libs/pagination.php');
require_once(MIBEW_FS_ROOT . '/libs/track.php');
$operator = check_login();
csrfchecktoken();
csrf_check_token();
$page = array(
'errors' => array(),
@ -37,38 +38,33 @@ setlocale(LC_TIME, getstring("time.locale"));
$db = Database::getInstance();
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";
}
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");
exit;
}
}
$blockedList = $db->query(
"select banid, dtmtill as till,address,comment from {chatban}",
NULL,
$blocked_list = $db->query(
"SELECT banid, dtmtill AS till,address,comment FROM {chatban}",
null,
array('return_rows' => Database::RETURN_ALL_ROWS)
);
$page['title'] = getlocal("page_bans.title");
$page['menuid'] = "blocked";
$pagination = setup_pagination($blockedList);
$pagination = setup_pagination($blocked_list);
$page['pagination'] = $pagination['info'];
$page['pagination.items'] = $pagination['items'];
$page = array_merge(
$page,
prepare_menu($operator)
);
$page = array_merge($page, prepare_menu($operator));
$page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('blocked_visitors', $page);
?>

View File

@ -29,7 +29,7 @@ require_once(MIBEW_FS_ROOT.'/libs/pagination.php');
$operator = check_login();
force_password($operator);
csrfchecktoken();
csrf_check_token();
$page = array(
'errors' => array(),
@ -44,31 +44,30 @@ foreach ($all_locales as $id) {
}
$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)) {
$lang = in_array(CURRENT_LOCALE, $all_locales) ? CURRENT_LOCALE : $all_locales[0];
}
# groups
$groupid = "";
$groupid = verifyparam("group", "/^\d{0,8}$/", "");
if ($groupid) {
$group = group_by_id($groupid);
$group_id = verify_param("group", "/^\d{0,8}$/", "");
if ($group_id) {
$group = group_by_id($group_id);
if (!$group) {
$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(
'groupid' => '',
'vclocalname' => getlocal("page.gen_button.default_group"),
'level' => 0
'level' => 0,
);
foreach ($allgroups as $g) {
foreach ($all_groups as $g) {
$page['groups'][] = $g;
}
@ -83,15 +82,17 @@ if (isset($_GET['act']) && $_GET['act'] == 'delete') {
if (count($page['errors']) == 0) {
$db = Database::getInstance();
$db->query("delete from {chatresponses} where id = ?", array($key));
header("Location: " . MIBEW_WEB_ROOT . "/operator/canned.php?lang=" . urlencode($lang) . "&group=" . intval($groupid));
$db->query("DELETE FROM {chatresponses} WHERE id = ?", array($key));
$redirect_to = MIBEW_WEB_ROOT . "/operator/canned.php?lang="
. urlencode($lang) . "&group=" . intval($group_id);
header("Location: " . $redirect_to);
exit;
}
}
// Get messages and setup pagination
$messages = load_canned_messages($lang, $groupid);
$messages = load_canned_messages($lang, $group_id);
$pagination = setup_pagination($messages);
$page['pagination'] = $pagination['info'];
$page['pagination.items'] = $pagination['items'];
@ -99,16 +100,11 @@ $page['pagination.items'] = $pagination['items'];
# form values
$page['formlang'] = $lang;
$page['formgroup'] = $groupid;
$page['formgroup'] = $group_id;
$page['title'] = getlocal("canned.title");
$page['menuid'] = "canned";
$page = array_merge(
$page,
prepare_menu($operator)
);
$page = array_merge($page, prepare_menu($operator));
$page_style = new PageStyle(PageStyle::currentStyle());
$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');
$operator = check_login();
csrfchecktoken();
csrf_check_token();
$stringid = verifyparam("key", "/^\d{0,9}$/", "");
$string_id = verify_param("key", "/^\d{0,9}$/", "");
$page = array(
'errors' => array(),
@ -35,11 +35,11 @@ $page = array(
$page_style = new PageStyle(PageStyle::currentStyle());
if ($stringid) {
$canned_message = load_canned_message($stringid);
if ($string_id) {
$canned_message = load_canned_message($string_id);
if (!$canned_message) {
$page['errors'][] = getlocal("cannededit.no_such");
$stringid = "";
$string_id = "";
} else {
$title = $canned_message['vctitle'];
$message = $canned_message['vcvalue'];
@ -47,49 +47,41 @@ if ($stringid) {
} else {
$message = '';
$title = '';
$page['locale'] = verifyparam("lang", "/^[\w-]{2,5}$/", "");
$page['locale'] = verify_param("lang", "/^[\w-]{2,5}$/", "");
$page['groupid'] = "";
$page['groupid'] = verifyparam("group", "/^\d{0,8}$/");
$page['groupid'] = verify_param("group", "/^\d{0,8}$/");
}
if (isset($_POST['message']) && isset($_POST['title'])) {
$title = getparam('title');
$title = get_param('title');
if (!$title) {
$page['errors'][] = no_field("form.field.title");
}
$message = getparam('message');
$message = get_param('message');
if (!$message) {
$page['errors'][] = no_field("form.field.message");
}
if (count($page['errors']) == 0) {
if ($stringid) {
save_canned_message($stringid, $title, $message);
if ($string_id) {
save_canned_message($string_id, $title, $message);
} else {
add_canned_message($page['locale'], $page['groupid'], $title, $message);
}
$page['saved'] = true;
$page = array_merge(
$page,
prepare_menu($operator, false)
);
$page = array_merge($page, prepare_menu($operator, false));
$page_style->render('cannededit', $page);
exit;
}
}
$page['saved'] = false;
$page['key'] = $stringid;
$page['formtitle'] = topage($title);
$page['formmessage'] = topage($message);
$page['title'] = empty($stringid) ? getlocal("cannednew.title") : getlocal("cannededit.title");
$page['key'] = $string_id;
$page['formtitle'] = to_page($title);
$page['formmessage'] = to_page($message);
$page['title'] = empty($string_id) ? getlocal("cannednew.title") : getlocal("cannededit.title");
$page = array_merge(
$page,
prepare_menu($operator, false)
);
$page = array_merge($page, prepare_menu($operator, false));
$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');
$operator = check_login();
csrfchecktoken();
csrf_check_token();
$page = array(
'agentId' => '',
@ -33,13 +33,22 @@ $page = array(
);
$options = array(
'enableban', 'usercanchangename',
'enablegroups', 'enablegroupsisolation',
'enablestatistics', 'enabletracking',
'enablessl', 'forcessl',
'enablepresurvey', 'surveyaskmail', 'surveyaskgroup', 'surveyaskmessage',
'enablepopupnotification', 'showonlineoperators',
'enablecaptcha');
'enableban',
'usercanchangename',
'enablegroups',
'enablegroupsisolation',
'enablestatistics',
'enabletracking',
'enablessl',
'forcessl',
'enablepresurvey',
'surveyaskmail',
'surveyaskgroup',
'surveyaskmessage',
'enablepopupnotification',
'showonlineoperators',
'enablecaptcha',
);
if (Settings::get('featuresversion') != FEATURES_VERSION) {
Settings::set('featuresversion', FEATURES_VERSION);
@ -53,7 +62,7 @@ foreach ($options as $opt) {
if (isset($_POST['sent'])) {
if (is_capable(CAN_ADMINISTRATE, $operator)) {
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();
header("Location: " . MIBEW_WEB_ROOT . "/operator/features.php?stored");
@ -72,14 +81,9 @@ foreach ($options as $opt) {
$page['title'] = getlocal("settings.title");
$page['menuid'] = "settings";
$page = array_merge(
$page,
prepare_menu($operator)
);
$page = array_merge($page, prepare_menu($operator));
$page['tabs'] = setup_settings_tabs(1);
$page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('features', $page);
?>

View File

@ -34,55 +34,67 @@ $page = array(
'errors' => array(),
);
$imageLocales = get_image_locales_map(MIBEW_FS_ROOT.'/locales');
$image = verifyparam(isset($_GET['image']) ? "image" : "i", "/^\w+$/", "mibew");
if (!isset($imageLocales[$image])) {
$image_locales_map = get_image_locales_map(MIBEW_FS_ROOT . '/locales');
$image = verify_param(isset($_GET['image']) ? "image" : "i", "/^\w+$/", "mibew");
if (!isset($image_locales_map[$image])) {
$page['errors'][] = "Unknown image: $image";
$avail = array_keys($imageLocales);
$avail = array_keys($image_locales_map);
$image = $avail[0];
}
$image_locales = $imageLocales[$image];
$image_locales = $image_locales_map[$image];
$stylelist = ChatStyle::availableStyles();
$stylelist[""] = getlocal("page.preview.style_default");
$style = verifyparam("style", "/^\w*$/", "");
if ($style && !in_array($style, $stylelist)) {
$style_list = ChatStyle::availableStyles();
$style_list[""] = getlocal("page.preview.style_default");
$style = verify_param("style", "/^\w*$/", "");
if ($style && !in_array($style, $style_list)) {
$style = "";
}
$invitationstylelist = InvitationStyle::availableStyles();
$invitationstylelist[""] = getlocal("page.preview.style_default");
$invitationstyle = verifyparam("invitationstyle", "/^\w*$/", "");
if ($invitationstyle && !in_array($invitationstyle, $invitationstylelist)) {
$invitationstyle = "";
$invitation_style_list = InvitationStyle::availableStyles();
$invitation_style_list[""] = getlocal("page.preview.style_default");
$invitation_style = verify_param("invitationstyle", "/^\w*$/", "");
if ($invitation_style && !in_array($invitation_style, $invitation_style_list)) {
$invitation_style = "";
}
$groupid = verifyparam_groupid("group", $page['errors']);
$showhost = verifyparam("hostname", "/^on$/", "") == "on";
$forcesecure = verifyparam("secure", "/^on$/", "") == "on";
$modsecurity = verifyparam("modsecurity", "/^on$/", "") == "on";
$group_id = verifyparam_groupid("group", $page['errors']);
$show_host = verify_param("hostname", "/^on$/", "") == "on";
$force_secure = verify_param("secure", "/^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");
$lang = verifyparam("lang", "/^[\w-]{2,5}$/", "");
if (!$lang || !in_array($lang, $image_locales))
$lang = verify_param("lang", "/^[\w-]{2,5}$/", "");
if (!$lang || !in_array($lang, $image_locales)) {
$lang = in_array(CURRENT_LOCALE, $image_locales) ? CURRENT_LOCALE : $image_locales[0];
}
$file = MIBEW_FS_ROOT . '/locales/${lang}/button/${image}_on.gif';
$size = get_gifimage_size($file);
$imagehref = get_app_location($showhost, $forcesecure) . "/b.php?i=$image&amp;lang=$lang";
if ($groupid) {
$imagehref .= "&amp;group=$groupid";
$image_href = get_app_location($show_host, $force_secure) . "/b.php?i=$image&amp;lang=$lang";
if ($group_id) {
$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['availableImages'] = array_keys($imageLocales);
$page['buttonCode'] = generate_button(
"",
$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['availableChatStyles'] = $stylelist;
$page['availableInvitationStyles'] = $invitationstylelist;
$page['availableChatStyles'] = $style_list;
$page['availableInvitationStyles'] = $invitation_style_list;
$page['groups'] = get_groups_list();
$page['availableCodeTypes'] = array(
@ -90,14 +102,14 @@ $page['availableCodeTypes'] = array(
'operator_code' => getlocal('page.gen_button.operator_code')
);
$page['formgroup'] = $groupid;
$page['formgroup'] = $group_id;
$page['formstyle'] = $style;
$page['forminvitationstyle'] = $invitationstyle;
$page['forminvitationstyle'] = $invitation_style;
$page['formimage'] = $image;
$page['formlang'] = $lang;
$page['formhostname'] = $showhost;
$page['formsecure'] = $forcesecure;
$page['formmodsecurity'] = $modsecurity;
$page['formhostname'] = $show_host;
$page['formsecure'] = $force_secure;
$page['formmodsecurity'] = $mod_security;
$page['formcodetype'] = $code_type;
$page['enabletracking'] = Settings::get('enabletracking');
@ -106,12 +118,7 @@ $page['operator_code'] = $operator_code;
$page['title'] = getlocal("page.gen_button.title");
$page['menuid'] = "getcode";
$page = array_merge(
$page,
prepare_menu($operator)
);
$page = array_merge($page, prepare_menu($operator));
$page_style = new PageStyle(PageStyle::currentStyle());
$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');
$operator = check_login();
csrfchecktoken();
csrf_check_token();
$page = array(
'grid' => '',
'errors' => array(),
);
$groupid = '';
$group_id = '';
if (isset($_POST['name'])) {
$groupid = verifyparam("gid", "/^(\d{1,9})?$/", "");
$name = getparam('name');
$description = getparam('description');
$commonname = getparam('commonname');
$commondescription = getparam('commondescription');
$email = getparam('email');
$weight = getparam('weight');
$parentgroup = verifyparam("parentgroup", "/^(\d{1,9})?$/", "");
$title = getparam('title');
$chattitle = getparam('chattitle');
$hosturl = getparam('hosturl');
$logo = getparam('logo');
$group_id = verify_param("gid", "/^(\d{1,9})?$/", "");
$name = get_param('name');
$description = get_param('description');
$common_name = get_param('commonname');
$common_description = get_param('commondescription');
$email = get_param('email');
$weight = get_param('weight');
$parent_group = verify_param("parentgroup", "/^(\d{1,9})?$/", "");
$title = get_param('title');
$chat_title = get_param('chattitle');
$host_url = get_param('hosturl');
$logo = get_param('logo');
if (!$name)
if (!$name) {
$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");
}
if (! preg_match("/^(\d{1,9})?$/", $weight))
if (!preg_match("/^(\d{1,9})?$/", $weight)) {
$page['errors'][] = wrong_field("form.field.groupweight");
}
if ($weight == '')
if ($weight == '') {
$weight = 0;
}
if (! $parentgroup)
$parentgroup = NULL;
if (!$parent_group) {
$parent_group = null;
}
$existing_group = group_by_name($name);
if ((!$groupid && $existing_group) ||
($groupid && $existing_group && $groupid != $existing_group['groupid']))
$duplicate_name = (!$group_id && $existing_group)
|| ($group_id
&& $existing_group
&& $group_id != $existing_group['groupid']);
if ($duplicate_name) {
$page['errors'][] = getlocal("page.group.duplicate_name");
}
if (count($page['errors']) == 0) {
if (!$groupid) {
$newdep = create_group(array(
if (!$group_id) {
$new_dep = create_group(array(
'name' => $name,
'description' => $description,
'commonname' => $commonname,
'commondescription' => $commondescription,
'commonname' => $common_name,
'commondescription' => $common_description,
'email' => $email,
'weight' => $weight,
'parent' => $parentgroup,
'parent' => $parent_group,
'title' => $title,
'chattitle' => $chattitle,
'hosturl' => $hosturl,
'chattitle' => $chat_title,
'hosturl' => $host_url,
'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;
} else {
update_group(array(
'id' => $groupid,
'id' => $group_id,
'name' => $name,
'description' => $description,
'commonname' => $commonname,
'commondescription' => $commondescription,
'commonname' => $common_name,
'commondescription' => $common_description,
'email' => $email,
'weight' => $weight,
'parent' => $parentgroup,
'parent' => $parent_group,
'title' => $title,
'chattitle' => $chattitle,
'hosturl' => $hosturl,
'chattitle' => $chat_title,
'hosturl' => $host_url,
'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;
}
} else {
$page['formname'] = topage($name);
$page['formdescription'] = topage($description);
$page['formcommonname'] = topage($commonname);
$page['formcommondescription'] = topage($commondescription);
$page['formemail'] = topage($email);
$page['formweight'] = topage($weight);
$page['formparentgroup'] = topage($parentgroup);
$page['grid'] = topage($groupid);
$page['formtitle'] = topage($title);
$page['formchattitle'] = topage($chattitle);
$page['formhosturl'] = topage($hosturl);
$page['formlogo'] = topage($logo);
$page['formname'] = to_page($name);
$page['formdescription'] = to_page($description);
$page['formcommonname'] = to_page($common_name);
$page['formcommondescription'] = to_page($common_description);
$page['formemail'] = to_page($email);
$page['formweight'] = to_page($weight);
$page['formparentgroup'] = to_page($parent_group);
$page['grid'] = to_page($group_id);
$page['formtitle'] = to_page($title);
$page['formchattitle'] = to_page($chat_title);
$page['formhosturl'] = to_page($host_url);
$page['formlogo'] = to_page($logo);
}
} elseif (isset($_GET['gid'])) {
$groupid = verifyparam('gid', "/^\d{1,9}$/");
$group = group_by_id($groupid);
$group_id = verify_param('gid', "/^\d{1,9}$/");
$group = group_by_id($group_id);
if (!$group) {
$page['errors'][] = getlocal("page.group.no_such");
$page['grid'] = topage($groupid);
$page['grid'] = to_page($group_id);
} else {
$page['formname'] = topage($group['vclocalname']);
$page['formdescription'] = topage($group['vclocaldescription']);
$page['formcommonname'] = topage($group['vccommonname']);
$page['formcommondescription'] = topage($group['vccommondescription']);
$page['formemail'] = topage($group['vcemail']);
$page['formweight'] = topage($group['iweight']);
$page['formparentgroup'] = topage($group['parent']);
$page['grid'] = topage($group['groupid']);
$page['formtitle'] = topage($group['vctitle']);
$page['formchattitle'] = topage($group['vcchattitle']);
$page['formhosturl'] = topage($group['vchosturl']);
$page['formlogo'] = topage($group['vclogo']);
$page['formname'] = to_page($group['vclocalname']);
$page['formdescription'] = to_page($group['vclocaldescription']);
$page['formcommonname'] = to_page($group['vccommonname']);
$page['formcommondescription'] = to_page($group['vccommondescription']);
$page['formemail'] = to_page($group['vcemail']);
$page['formweight'] = to_page($group['iweight']);
$page['formparentgroup'] = to_page($group['parent']);
$page['grid'] = to_page($group['groupid']);
$page['formtitle'] = to_page($group['vctitle']);
$page['formchattitle'] = to_page($group['vcchattitle']);
$page['formhosturl'] = to_page($group['vchosturl']);
$page['formlogo'] = to_page($group['vclogo']);
}
}
$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['menuid'] = "groups";
$page = array_merge(
$page,
prepare_menu($operator)
);
$page = array_merge($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->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');
$operator = check_login();
csrfchecktoken();
csrf_check_token();
$groupid = verifyparam("gid", "/^\d{1,9}$/");
$page = array('groupid' => $groupid);
$group_id = verify_param("gid", "/^\d{1,9}$/");
$page = array('groupid' => $group_id);
$page['operators'] = get_operators_list(array());
$page['errors'] = array();
$group = group_by_id($groupid);
$group = group_by_id($group_id);
if (!$group) {
$page['errors'][] = getlocal("page.group.no_such");
} elseif (isset($_POST['gid'])) {
$new_members = array();
foreach ($page['operators'] as $op) {
if (verifyparam("op" . $op['operatorid'], "/^on$/", "") == "on") {
if (verify_param("op" . $op['operatorid'], "/^on$/", "") == "on") {
$new_members[] = $op['operatorid'];
}
}
update_group_members($groupid, $new_members);
header("Location: " . MIBEW_WEB_ROOT . "/operator/groupmembers.php?gid=" . intval($groupid) . "&stored");
update_group_members($group_id, $new_members);
header("Location: " . MIBEW_WEB_ROOT . "/operator/groupmembers.php?gid=" . intval($group_id) . "&stored");
exit;
}
$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'];
}
@ -61,14 +60,9 @@ $page['stored'] = isset($_GET['stored']);
$page['title'] = getlocal("page.groupmembers.title");
$page['menuid'] = "groups";
$page = array_merge(
$page,
prepare_menu($operator)
);
$page = array_merge($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->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');
$operator = check_login();
csrfchecktoken();
csrf_check_token();
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");
}
@ -41,17 +41,17 @@ if (isset($_GET['act']) && $_GET['act'] == 'del') {
if (count($page['errors']) == 0) {
$db = Database::getInstance();
$db->query("delete from {chatgroup} where groupid = ?", array($groupid));
$db->query("delete from {chatgroupoperator} where groupid = ?", array($groupid));
$db->query("update {chatthread} set groupid = 0 where groupid = ?",array($groupid));
$db->query("delete from {chatgroup} where groupid = ?", array($group_id));
$db->query("delete from {chatgroupoperator} where groupid = ?", array($group_id));
$db->query("update {chatthread} set groupid = 0 where groupid = ?", array($group_id));
header("Location: " . MIBEW_WEB_ROOT . "/operator/groups.php");
exit;
}
}
$page = array();
$sort['by'] = verifyparam("sortby", "/^(name|lastseen|weight)$/", "name");
$sort['desc'] = (verifyparam("sortdirection", "/^(desc|asc)$/", "desc") == "desc");
$sort['by'] = verify_param("sortby", "/^(name|lastseen|weight)$/", "name");
$sort['desc'] = (verify_param("sortdirection", "/^(desc|asc)$/", "desc") == "desc");
$page['groups'] = get_sorted_groups($sort);
$page['formsortby'] = $sort['by'];
$page['formsortdirection'] = $sort['desc'] ? 'desc' : 'asc';
@ -59,7 +59,7 @@ $page['canmodify'] = is_capable(CAN_ADMINISTRATE, $operator);
$page['availableOrders'] = array(
array('id' => 'name', 'name' => getlocal('form.field.groupname')),
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(
array('id' => 'desc', 'name' => getlocal('page.groups.sortdirection.desc')),
@ -69,12 +69,7 @@ $page['availableDirections'] = array(
$page['title'] = getlocal("page.groups.title");
$page['menuid'] = "groups";
$page = array_merge(
$page,
prepare_menu($operator)
);
$page = array_merge($page, prepare_menu($operator));
$page_style = new PageStyle(PageStyle::currentStyle());
$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/pagination.php');
require_once(MIBEW_FS_ROOT . '/libs/cron.php');
require_once(MIBEW_FS_ROOT . '/libs/track.php');
$operator = check_login();
force_password($operator);
@ -36,60 +37,63 @@ setlocale(LC_TIME, getstring("time.locale"));
$page = array();
$query = isset($_GET['q']) ? myiconv(getoutputenc(), MIBEW_ENCODING, $_GET['q']) : false;
$searchType = verifyparam('type', '/^(all|message|operator|visitor)$/', 'all');
$searchInSystemMessages = (verifyparam('insystemmessages', '/^on$/', 'off') == 'on') || !$query;
$search_type = verify_param('type', '/^(all|message|operator|visitor)$/', 'all');
$search_in_system_messages = (verify_param('insystemmessages', '/^on$/', 'off') == 'on') || !$query;
if ($query !== false) {
$db = Database::getInstance();
$groups = $db->query(
"select {chatgroup}.groupid as groupid, vclocalname " .
"from {chatgroup} order by vclocalname",
NULL,
("SELECT {chatgroup}.groupid AS groupid, vclocalname " .
"FROM {chatgroup} " .
"ORDER BY vclocalname"),
null,
array('return_rows' => Database::RETURN_ALL_ROWS)
);
$groupName = array();
$group_name = array();
foreach ($groups as $group) {
$groupName[$group['groupid']] = $group['vclocalname'];
$group_name[$group['groupid']] = $group['vclocalname'];
}
$page['groupName'] = $groupName;
$page['groupName'] = $group_name;
$values = array(
':query' => "%{$query}%",
':invitation_accepted' => Thread::INVITATION_ACCEPTED,
':invitation_not_invited' => Thread::INVITATION_NOT_INVITED
':invitation_not_invited' => Thread::INVITATION_NOT_INVITED,
);
$searchConditions = array();
if ($searchType == 'message' || $searchType == 'all') {
$searchConditions[] = "({chatmessage}.tmessage LIKE :query" .
($searchInSystemMessages?'':" AND ({chatmessage}.ikind = :kind_user OR {chatmessage}.ikind = :kind_agent)") .
")";
if (! $searchInSystemMessages) {
$search_conditions = array();
if ($search_type == 'message' || $search_type == 'all') {
$search_conditions[] = "({chatmessage}.tmessage LIKE :query"
. ($search_in_system_messages
? ''
: " AND ({chatmessage}.ikind = :kind_user OR {chatmessage}.ikind = :kind_agent)")
. ")";
if (!$search_in_system_messages) {
$values[':kind_user'] = Thread::KIND_USER;
$values[':kind_agent'] = Thread::KIND_AGENT;
}
}
if ($searchType == 'operator' || $searchType == 'all') {
$searchConditions[] = "({chatthread}.agentName LIKE :query)";
if ($search_type == 'operator' || $search_type == 'all') {
$search_conditions[] = "({chatthread}.agentName LIKE :query)";
}
if ($searchType == 'visitor' || $searchType == 'all') {
$searchConditions[] = "({chatthread}.userName LIKE :query)";
$searchConditions[] = "({chatthread}.remote LIKE :query)";
if ($search_type == 'visitor' || $search_type == 'all') {
$search_conditions[] = "({chatthread}.userName LIKE :query)";
$search_conditions[] = "({chatthread}.remote LIKE :query)";
}
// Load threads
list($threads_count) = $db->query(
"SELECT COUNT(DISTINCT {chatthread}.dtmcreated) " .
"FROM {chatthread}, {chatmessage} " .
"WHERE {chatmessage}.threadid = {chatthread}.threadid " .
"AND ({chatthread}.invitationstate = :invitation_accepted " .
"OR {chatthread}.invitationstate = :invitation_not_invited) " .
"AND (" . implode(' OR ', $searchConditions) . ")",
("SELECT COUNT(DISTINCT {chatthread}.dtmcreated) "
. "FROM {chatthread}, {chatmessage} "
. "WHERE {chatmessage}.threadid = {chatthread}.threadid "
. "AND ({chatthread}.invitationstate = :invitation_accepted "
. "OR {chatthread}.invitationstate = :invitation_not_invited) "
. "AND (" . implode(' OR ', $search_conditions) . ")"),
$values,
array(
'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']);
$threads_list = $db->query(
"SELECT DISTINCT {chatthread}.* " .
"FROM {chatthread}, {chatmessage} " .
"WHERE {chatmessage}.threadid = {chatthread}.threadid " .
"AND ({chatthread}.invitationstate = :invitation_accepted " .
"OR {chatthread}.invitationstate = :invitation_not_invited) " .
"AND (" . implode(' OR ', $searchConditions) . ") " .
"ORDER BY {chatthread}.dtmcreated DESC " .
"LIMIT " . $limit_start . ", " .$limit_end,
("SELECT DISTINCT {chatthread}.* "
. "FROM {chatthread}, {chatmessage} "
. "WHERE {chatmessage}.threadid = {chatthread}.threadid "
. "AND ({chatthread}.invitationstate = :invitation_accepted "
. "OR {chatthread}.invitationstate = :invitation_not_invited) "
. "AND (" . implode(' OR ', $search_conditions) . ") "
. "ORDER BY {chatthread}.dtmcreated DESC "
. "LIMIT " . $limit_start . ", " . $limit_end),
$values,
array('return_rows' => Database::RETURN_ALL_ROWS)
);
@ -122,23 +126,18 @@ if ($query !== false) {
$page['pagination.items'] = false;
}
$page['formq'] = topage($query);
$page['formq'] = to_page($query);
} else {
$page['pagination'] = false;
$page['pagination.items'] = false;
}
$page['formtype'] = $searchType;
$page['forminsystemmessages'] = $searchInSystemMessages;
$page['formtype'] = $search_type;
$page['forminsystemmessages'] = $search_in_system_messages;
$page['title'] = getlocal("page_analysis.search.title");
$page['menuid'] = "history";
$page = array_merge(
$page,
prepare_menu($operator)
);
$page = array_merge($page, prepare_menu($operator));
$page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('thread_search', $page);
?>

View File

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

View File

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

View File

@ -17,22 +17,21 @@
require_once(dirname(dirname(__FILE__)) . '/libs/init.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/track.php');
$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) {
die("Invitation failed!");
}
// Open chat window for operator
$redirect_to = MIBEW_WEB_ROOT .
'/operator/agent.php?thread=' . intval($thread->id) .
'&token=' . urlencode($thread->lastToken);
$redirect_to = MIBEW_WEB_ROOT
. '/operator/agent.php?thread=' . intval($thread->id)
. '&token=' . urlencode($thread->lastToken);
header('Location: ' . $redirect_to);
?>

View File

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

View File

@ -21,5 +21,3 @@ require_once(MIBEW_FS_ROOT.'/libs/operator.php');
logout_operator();
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');
$operator = check_login();
csrfchecktoken();
csrf_check_token();
$page = array(
'opid' => '',
'errors' => array(),
);
$opId = '';
$op_id = '';
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)) {
$login = getparam('login');
$login = get_param('login');
} else {
$login = $operator['vclogin'];
}
$email = getparam('email');
$password = getparam('password');
$passwordConfirm = getparam('passwordConfirm');
$localname = getparam('name');
$commonname = getparam('commonname');
$code = getparam('code');
$email = get_param('email');
$password = get_param('password');
$password_confirm = get_param('passwordConfirm');
$local_name = get_param('name');
$common_name = get_param('commonname');
$code = get_param('code');
if (!$localname)
if (!$local_name) {
$page['errors'][] = no_field("form.field.agent_name");
}
if (!$commonname)
if (!$common_name) {
$page['errors'][] = no_field("form.field.agent_commonname");
}
if (!$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");
}
if (!$opId && !$password)
if (!$op_id && !$password) {
$page['errors'][] = no_field("form.field.password");
}
if ($password != $passwordConfirm)
if ($password != $password_confirm) {
$page['errors'][] = getlocal("my_settings.error.password_match");
}
$existing_operator = operator_by_login($login);
if ((!$opId && $existing_operator) ||
($opId && $existing_operator && $opId != $existing_operator['operatorid']))
$duplicate_login = (!$op_id && $existing_operator)
|| ($op_id
&& $existing_operator
&& $op_id != $existing_operator['operatorid']);
if ($duplicate_login) {
$page['errors'][] = getlocal("page_agent.error.duplicate_login");
}
// Check if operator with specified email already exists in the database
$existing_operator = operator_by_email($email);
if (
$duplicate_email =
// Create operator with email already in database
(!$opId && $existing_operator) ||
(!$op_id && $existing_operator)
// 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");
}
$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);
if (!$canmodify) {
if (!$can_modify) {
$page['errors'][] = getlocal('page_agent.cannot_modify');
}
if (count($page['errors']) == 0) {
if (!$opId) {
$newop = create_operator($login, $email, $password, $localname, $commonname, "", $code);
header("Location: " . MIBEW_WEB_ROOT . "/operator/avatar.php?op=" . intval($newop['operatorid']));
if (!$op_id) {
$new_operator = create_operator($login, $email, $password, $local_name, $common_name, "", $code);
header("Location: " . MIBEW_WEB_ROOT . "/operator/avatar.php?op=" . intval($new_operator['operatorid']));
exit;
} 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
if (!empty($password) && $opId == $operator['operatorid']) {
$toDashboard = check_password_hash($login, '', $operator['vcpassword']) && $password != '';
if (!empty($password) && $op_id == $operator['operatorid']) {
$to_dashboard = check_password_hash($login, '', $operator['vcpassword']) && $password != '';
$_SESSION[SESSION_PREFIX . "operator"]['vcpassword'] = calculate_password_hash($login, $password);
if($toDashboard) {
if ($to_dashboard) {
header("Location: " . MIBEW_WEB_ROOT . "/operator/index.php");
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;
}
} else {
$page['formlogin'] = topage($login);
$page['formname'] = topage($localname);
$page['formemail'] = topage($email);
$page['formcommonname'] = topage($commonname);
$page['formcode'] = topage($code);
$page['opid'] = topage($opId);
$page['formlogin'] = to_page($login);
$page['formname'] = to_page($local_name);
$page['formemail'] = to_page($email);
$page['formcommonname'] = to_page($common_name);
$page['formcode'] = to_page($code);
$page['opid'] = to_page($op_id);
}
} elseif (isset($_GET['op'])) {
$opId = verifyparam('op', "/^\d{1,9}$/");
$op = operator_by_id($opId);
$op_id = verify_param('op', "/^\d{1,9}$/");
$op = operator_by_id($op_id);
if (!$op) {
$page['errors'][] = getlocal("no_such_operator");
$page['opid'] = topage($opId);
$page['opid'] = to_page($op_id);
} else {
//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['formlogin'] = topage($op['vclogin']);
$page['formname'] = topage($op['vclocalename']);
$page['formemail'] = topage($op['vcemail']);
$page['formcommonname'] = topage($op['vccommonname']);
$page['formcode'] = topage($op['code']);
$page['opid'] = topage($op['operatorid']);
$page['formlogin'] = to_page($op['vclogin']);
$page['formname'] = to_page($op['vclocalename']);
$page['formemail'] = to_page($op['vcemail']);
$page['formcommonname'] = to_page($op['vccommonname']);
$page['formcode'] = to_page($op['code']);
$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");
}
$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);
$page['stored'] = isset($_GET['stored']);
$page['canmodify'] = $canmodify ? "1" : "";
$page['canmodify'] = $can_modify ? "1" : "";
$page['canchangelogin'] = is_capable(CAN_ADMINISTRATE, $operator);
$page['needChangePassword'] = check_password_hash($operator['vclogin'], '', $operator['vcpassword']);
$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,
prepare_menu($operator)
);
$page = array_merge($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->render('agent', $page);
?>

View File

@ -25,7 +25,7 @@ require_once(MIBEW_FS_ROOT.'/libs/operator.php');
$operator = check_login();
force_password($operator);
csrfchecktoken();
csrf_check_token();
$page = array(
'errors' => array(),
@ -33,8 +33,8 @@ $page = array(
if (isset($_GET['act'])) {
$operatorid = isset($_GET['id']) ? $_GET['id'] : "";
if (!preg_match("/^\d+$/", $operatorid)) {
$operator_id = isset($_GET['id']) ? $_GET['id'] : "";
if (!preg_match("/^\d+$/", $operator_id)) {
$page['errors'][] = getlocal("no_such_operator");
}
@ -43,12 +43,12 @@ if (isset($_GET['act'])) {
$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");
}
if (count($page['errors']) == 0) {
$op = operator_by_id($operatorid);
$op = operator_by_id($operator_id);
if (!$op) {
$page['errors'][] = getlocal("no_such_operator");
} elseif ($op['vclogin'] == 'admin') {
@ -57,7 +57,7 @@ if (isset($_GET['act'])) {
}
if (count($page['errors']) == 0) {
delete_operator($operatorid);
delete_operator($operator_id);
header("Location: " . MIBEW_WEB_ROOT . "/operator/operators.php");
exit;
}
@ -65,15 +65,17 @@ if (isset($_GET['act'])) {
if ($_GET['act'] == 'disable' || $_GET['act'] == 'enable') {
$act_disable = ($_GET['act'] == 'disable');
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');
}
if (count($page['errors']) == 0) {
$op = operator_by_id($operatorid);
$op = operator_by_id($operator_id);
if (!$op) {
$page['errors'][] = getlocal("no_such_operator");
} elseif ($op['vclogin'] == 'admin' && $act_disable) {
@ -85,7 +87,7 @@ if (isset($_GET['act'])) {
$db = Database::getInstance();
$db->query(
"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");
@ -94,8 +96,8 @@ if (isset($_GET['act'])) {
}
}
$sort['by'] = verifyparam("sortby", "/^(login|commonname|localename|lastseen)$/", "login");
$sort['desc'] = (verifyparam("sortdirection", "/^(desc|asc)$/", "desc") == "desc");
$sort['by'] = verify_param("sortby", "/^(login|commonname|localename|lastseen)$/", "login");
$sort['desc'] = (verify_param("sortdirection", "/^(desc|asc)$/", "desc") == "desc");
$page['formsortby'] = $sort['by'];
$page['formsortdirection'] = $sort['desc'] ? 'desc' : 'asc';
$list_options['sort'] = $sort;
@ -108,7 +110,7 @@ $page['availableOrders'] = array(
array('id' => 'login', 'name' => getlocal('page_agents.login')),
array('id' => 'localename', 'name' => getlocal('page_agents.agent_name')),
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(
array('id' => 'desc', 'name' => getlocal('page_agents.sortdirection.desc')),
@ -120,12 +122,7 @@ $page['menuid'] = "operators";
setlocale(LC_TIME, getstring("time.locale"));
$page = array_merge(
$page,
prepare_menu($operator)
);
$page = array_merge($page, prepare_menu($operator));
$page_style = new PageStyle(PageStyle::currentStyle());
$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');
$operator = check_login();
csrfchecktoken();
csrf_check_token();
$operator_in_isolation = in_isolation($operator);
$opId = verifyparam("op", "/^\d{1,9}$/");
$page = array('opid' => $opId);
$page['groups'] = $operator_in_isolation?get_all_groups_for_operator($operator):get_all_groups();
$op_id = verify_param("op", "/^\d{1,9}$/");
$page = array('opid' => $op_id);
$page['groups'] = $operator_in_isolation
? get_all_groups_for_operator($operator)
: get_all_groups();
$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) {
$page['errors'][] = getlocal("no_such_operator");
} elseif (isset($_POST['op'])) {
if (!$canmodify) {
if (!$can_modify) {
$page['errors'][] = getlocal('page_agent.cannot_modify');
}
if (count($page['errors']) == 0) {
$new_groups = array();
foreach ($page['groups'] as $group) {
if (verifyparam("group" . $group['groupid'], "/^on$/", "") == "on") {
if (verify_param("group" . $group['groupid'], "/^on$/", "") == "on") {
$new_groups[] = $group['groupid'];
}
}
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;
}
}
$page['formgroup'] = array();
$page['currentop'] = $op ? topage(get_operator_name($op)) . " (" . $op['vclogin'] . ")" : getlocal("not_found");
$page['canmodify'] = $canmodify ? "1" : "";
$page['currentop'] = $op
? to_page(get_operator_name($op)) . " (" . $op['vclogin'] . ")"
: getlocal("not_found");
$page['canmodify'] = $can_modify ? "1" : "";
if ($op) {
foreach (get_operator_groupids($opId) as $rel) {
foreach (get_operator_group_ids($op_id) as $rel) {
$page['formgroup'][] = $rel['groupid'];
}
}
$page['stored'] = isset($_GET['stored']);
$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,
prepare_menu($operator)
);
$page = array_merge($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->render('operator_groups', $page);
?>

View File

@ -25,12 +25,12 @@ require_once(MIBEW_FS_ROOT.'/libs/settings.php');
$operator = check_login();
$stylelist = PageStyle::availableStyles();
$style_list = PageStyle::availableStyles();
$preview = verifyparam("preview", "/^\w+$/", "default");
if (!in_array($preview, $stylelist)) {
$style_names = array_keys($stylelist);
$preview = $stylelist[$style_names[0]];
$preview = verify_param("preview", "/^\w+$/", "default");
if (!in_array($preview, $style_list)) {
$style_names = array_keys($style_list);
$preview = $style_list[$style_names[0]];
}
$preview_style = new PageStyle($preview);
@ -40,26 +40,21 @@ $screenshots = array();
foreach ($style_config['screenshots'] as $name => $desc) {
$screenshots[] = array(
'name' => $name,
'file' => MIBEW_WEB_ROOT . '/' . $preview_style->filesPath()
. '/screenshots/' . $name . '.png',
'description' => $desc
'file' => (MIBEW_WEB_ROOT . '/' . $preview_style->filesPath()
. '/screenshots/' . $name . '.png'),
'description' => $desc,
);
}
$page['formpreview'] = $preview;
$page['availablePreviews'] = $stylelist;
$page['availablePreviews'] = $style_list;
$page['screenshotsList'] = $screenshots;
$page['title'] = getlocal("page.preview.title");
$page['menuid'] = "settings";
$page = array_merge(
$page,
prepare_menu($operator)
);
$page = array_merge($page, prepare_menu($operator));
$page['tabs'] = setup_settings_tabs(3);
$page_style = new PageStyle(PageStyle::currentStyle());
$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');
$operator = check_login();
csrfchecktoken();
csrf_check_token();
$page = array(
'agentId' => '',
@ -33,10 +33,17 @@ $page = array(
);
$options = array(
'online_timeout', 'updatefrequency_operator', 'updatefrequency_chat',
'online_timeout',
'updatefrequency_operator',
'updatefrequency_chat',
'max_connections_from_one_host',
'updatefrequency_tracking', 'visitors_limit', 'invitation_lifetime',
'tracking_lifetime', 'thread_lifetime', 'statistics_aggregation_interval');
'updatefrequency_tracking',
'visitors_limit',
'invitation_lifetime',
'tracking_lifetime',
'thread_lifetime',
'statistics_aggregation_interval',
);
$params = array();
foreach ($options as $opt) {
@ -44,58 +51,57 @@ foreach ($options as $opt) {
}
if (isset($_POST['onlinetimeout'])) {
$params['online_timeout'] = getparam('onlinetimeout');
$params['online_timeout'] = get_param('onlinetimeout');
if (!is_numeric($params['online_timeout'])) {
$page['errors'][] = wrong_field("settings.onlinetimeout");
}
$params['updatefrequency_operator'] = getparam('frequencyoperator');
$params['updatefrequency_operator'] = get_param('frequencyoperator');
if (!is_numeric($params['updatefrequency_operator'])) {
$page['errors'][] = wrong_field("settings.frequencyoperator");
}
$params['updatefrequency_chat'] = getparam('frequencychat');
$params['updatefrequency_chat'] = get_param('frequencychat');
if (!is_numeric($params['updatefrequency_chat'])) {
$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'])) {
$page['errors'][] = getlocal("settings.wrong.onehostconnections");
}
$params['thread_lifetime'] = getparam('threadlifetime');
$params['thread_lifetime'] = get_param('threadlifetime');
if (!is_numeric($params['thread_lifetime'])) {
$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'])) {
$page['errors'][] = wrong_field("settings.statistics_aggregation_interval");
}
if (Settings::get('enabletracking')) {
$params['updatefrequency_tracking'] = getparam('frequencytracking');
$params['updatefrequency_tracking'] = get_param('frequencytracking');
if (!is_numeric($params['updatefrequency_tracking'])) {
$page['errors'][] = wrong_field("settings.frequencytracking");
}
$params['visitors_limit'] = getparam('visitorslimit');
$params['visitors_limit'] = get_param('visitorslimit');
if (!is_numeric($params['visitors_limit'])) {
$page['errors'][] = wrong_field("settings.visitorslimit");
}
$params['invitation_lifetime'] = getparam('invitationlifetime');
$params['invitation_lifetime'] = get_param('invitationlifetime');
if (!is_numeric($params['invitation_lifetime'])) {
$page['errors'][] = wrong_field("settings.invitationlifetime");
}
$params['tracking_lifetime'] = getparam('trackinglifetime');
$params['tracking_lifetime'] = get_param('trackinglifetime');
if (!is_numeric($params['tracking_lifetime'])) {
$page['errors'][] = wrong_field("settings.trackinglifetime");
}
}
if (count($page['errors']) == 0) {
@ -121,7 +127,6 @@ if (Settings::get('enabletracking')) {
$page['formvisitorslimit'] = $params['visitors_limit'];
$page['forminvitationlifetime'] = $params['invitation_lifetime'];
$page['formtrackinglifetime'] = $params['tracking_lifetime'];
}
$page['enabletracking'] = Settings::get('enabletracking');
@ -130,14 +135,9 @@ $page['stored'] = isset($_GET['stored']);
$page['title'] = getlocal("settings.title");
$page['menuid'] = "settings";
$page = array_merge(
$page,
prepare_menu($operator)
);
$page = array_merge($page, prepare_menu($operator));
$page['tabs'] = setup_settings_tabs(2);
$page_style = new PageStyle(PageStyle::currentStyle());
$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');
$operator = check_login();
csrfchecktoken();
csrf_check_token();
$opId = verifyparam("op", "/^\d{1,9}$/");
$op_id = verify_param("op", "/^\d{1,9}$/");
$page = array(
'opid' => $opId,
'opid' => $op_id,
'canmodify' => is_capable(CAN_ADMINISTRATE, $operator) ? "1" : "",
'errors' => array(),
);
$op = operator_by_id($opId);
$op = operator_by_id($op_id);
if (!$op) {
$page['errors'][] = getlocal("no_such_operator");
} elseif (isset($_POST['op'])) {
if (!is_capable(CAN_ADMINISTRATE, $operator)) {
@ -47,7 +46,7 @@ if (!$op) {
$new_permissions = isset($op['iperm']) ? $op['iperm'] : 0;
foreach (permission_ids() as $perm => $id) {
if (verifyparam("permissions$id", "/^on$/", "") == "on") {
if (verify_param("permissions$id", "/^on$/", "") == "on") {
$new_permissions |= (1 << $perm);
} else {
$new_permissions &= ~(1 << $perm);
@ -57,18 +56,17 @@ if (!$op) {
if (count($page['errors']) == 0) {
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;
}
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;
}
}
$page['permissionsList'] = get_permission_list();
$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) {
foreach (permission_ids() as $perm => $id) {
@ -80,16 +78,11 @@ if ($op) {
$page['stored'] = isset($_GET['stored']);
$page['title'] = getlocal("permissions.title");
$page['menuid'] = ($operator['operatorid'] == $opId) ? "profile" : "operators";
$page['menuid'] = ($operator['operatorid'] == $op_id) ? "profile" : "operators";
$page = array_merge(
$page,
prepare_menu($operator)
);
$page = array_merge($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->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/chat.php');
require_once(MIBEW_FS_ROOT . '/libs/groups.php');
require_once(MIBEW_FS_ROOT . '/libs/track.php');
$operator = check_login();
$threadid = verifyparam("thread", "/^\d{1,8}$/");
$token = verifyparam("token", "/^\d{1,8}$/");
$thread_id = verify_param("thread", "/^\d{1,8}$/");
$token = verify_param("token", "/^\d{1,8}$/");
$thread = Thread::load($threadid, $token);
$thread = Thread::load($thread_id, $token);
if (!$thread) {
die("wrong thread");
}
@ -44,15 +45,18 @@ $page = array(
$chat_style = new ChatStyle(ChatStyle::currentStyle());
if (isset($_GET['nextGroup'])) {
$nextid = verifyparam("nextGroup", "/^\d{1,8}$/");
$nextGroup = group_by_id($nextid);
$next_id = verify_param("nextGroup", "/^\d{1,8}$/");
$next_group = group_by_id($next_id);
if ($nextGroup) {
$page['message'] = getlocal2("chat.redirected.group.content", array(topage(get_group_name($nextGroup))));
if ($next_group) {
$page['message'] = getlocal2(
"chat.redirected.group.content",
array(to_page(get_group_name($next_group)))
);
if ($thread->state == Thread::STATE_CHATTING) {
$thread->state = Thread::STATE_WAITING;
$thread->nextAgent = 0;
$thread->groupId = $nextid;
$thread->groupId = $next_id;
$thread->agentId = 0;
$thread->agentName = '';
$thread->save();
@ -71,26 +75,29 @@ if (isset($_GET['nextGroup'])) {
} else {
$page['errors'][] = "Unknown group";
}
} else {
$nextid = verifyparam("nextAgent", "/^\d{1,8}$/");
$nextOperator = operator_by_id($nextid);
$next_id = verify_param("nextAgent", "/^\d{1,8}$/");
$next_operator = operator_by_id($next_id);
if ($nextOperator) {
$page['message'] = getlocal2("chat.redirected.content", array(topage(get_operator_name($nextOperator))));
if ($next_operator) {
$page['message'] = getlocal2(
"chat.redirected.content",
array(to_page(get_operator_name($next_operator)))
);
if ($thread->state == Thread::STATE_CHATTING) {
$thread->state = Thread::STATE_WAITING;
$thread->nextAgent = $nextid;
$thread->nextAgent = $next_id;
$thread->agentId = 0;
if ($thread->groupId != 0) {
$db = Database::getInstance();
list($groups_count) = $db->query(
"select count(*) AS count from {chatgroupoperator} " .
"where operatorid = ? and groupid = ?",
array($nextid, $thread->groupId),
("SELECT count(*) AS count "
. "FROM {chatgroupoperator} "
. "WHERE operatorid = ? AND groupid = ?"),
array($next_id, $thread->groupId),
array(
'return_rows' => Database::RETURN_ONE_ROW,
'fetch_type' => Database::FETCH_NUM
'fetch_type' => Database::FETCH_NUM,
)
);
if ($groups_count === 0) {
@ -114,15 +121,10 @@ if (isset($_GET['nextGroup'])) {
}
}
$page = array_merge_recursive(
$page,
setup_logo()
);
$page = array_merge_recursive($page, setup_logo());
if (count($page['errors']) > 0) {
$chat_style->render('error', $page);
} else {
$chat_style->render('redirected', $page);
}
?>

View File

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

View File

@ -34,39 +34,53 @@ $page = array(
'errors' => array(),
);
$loginoremail = "";
$login_or_email = "";
$page_style = new PageStyle(PageStyle::currentStyle());
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);
if (!$torestore) {
$to_restore = is_valid_email($login_or_email)
? operator_by_email($login_or_email)
: operator_by_login($login_or_email);
if (!$to_restore) {
$page['errors'][] = getlocal("no_such_operator");
}
$email = $torestore['vcemail'];
$email = $to_restore['vcemail'];
if (count($page['errors']) == 0 && !is_valid_email($email)) {
$page['errors'][] = "Operator hasn't set his e-mail";
}
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->query(
"update {chatoperator} set dtmrestore = :now, " .
"vcrestoretoken = :token where operatorid = :operatorid",
("UPDATE {chatoperator} "
. "SET dtmrestore = :now, vcrestoretoken = :token "
. "WHERE operatorid = :operatorid"),
array(
':now' => time(),
':token' => $token,
':operatorid' => $torestore['operatorid']
':operatorid' => $to_restore['operatorid'],
)
);
$href = get_app_location(true, false) . "/operator/resetpwd.php?id=" . $torestore['operatorid'] . "&token=$token";
mibew_mail($email, $email, getstring("restore.mailsubj"), getstring2("restore.mailtext", array(get_operator_name($torestore), $href)));
$href = get_app_location(true, false) . "/operator/resetpwd.php?id="
. $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_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['isdone'] = false;
$page_style->render('restore', $page);
?>

View File

@ -29,7 +29,7 @@ require_once(MIBEW_FS_ROOT.'/libs/cron.php');
$operator = check_login();
force_password($operator);
csrfchecktoken();
csrf_check_token();
$page = array(
'agentId' => '',
@ -47,7 +47,7 @@ $options = array(
'geolink',
'geolinkparams',
'sendmessagekey',
'cron_key'
'cron_key',
);
$params = array();
@ -70,29 +70,33 @@ if (Settings::get('enabletracking')) {
}
if (isset($_POST['email']) && isset($_POST['title']) && isset($_POST['logo'])) {
$params['email'] = getparam('email');
$params['title'] = getparam('title');
$params['logo'] = getparam('logo');
$params['hosturl'] = getparam('hosturl');
$params['usernamepattern'] = getparam('usernamepattern');
$params['chattitle'] = getparam('chattitle');
$params['geolink'] = getparam('geolink');
$params['geolinkparams'] = getparam('geolinkparams');
$params['sendmessagekey'] = verifyparam('sendmessagekey', "/^c?enter$/");
$params['cron_key'] = getparam('cronkey');
$params['email'] = get_param('email');
$params['title'] = get_param('title');
$params['logo'] = get_param('logo');
$params['hosturl'] = get_param('hosturl');
$params['usernamepattern'] = get_param('usernamepattern');
$params['chattitle'] = get_param('chattitle');
$params['geolink'] = get_param('geolink');
$params['geolinkparams'] = get_param('geolinkparams');
$params['sendmessagekey'] = verify_param('sendmessagekey', "/^c?enter$/");
$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)) {
$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)) {
$styles_params['page_style'] = $page_style_list[0];
}
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)) {
$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']) {
foreach (preg_split("/,/", $params['geolinkparams']) as $oneparam) {
if (!preg_match("/^\s*(toolbar|scrollbars|location|status|menubar|width|height|resizable)=\d{1,4}$/", $oneparam)) {
$page['errors'][] = "Wrong link parameter: \"$oneparam\", should be one of 'toolbar, scrollbars, location, status, menubar, width, height or resizable'";
foreach (preg_split("/,/", $params['geolinkparams']) as $one_param) {
$wrong_param = !preg_match(
"/^\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['formtitle'] = topage($params['title']);
$page['formlogo'] = topage($params['logo']);
$page['formhosturl'] = topage($params['hosturl']);
$page['formgeolink'] = topage($params['geolink']);
$page['formgeolinkparams'] = topage($params['geolinkparams']);
$page['formusernamepattern'] = topage($params['usernamepattern']);
$page['formemail'] = to_page($params['email']);
$page['formtitle'] = to_page($params['title']);
$page['formlogo'] = to_page($params['logo']);
$page['formhosturl'] = to_page($params['hosturl']);
$page['formgeolink'] = to_page($params['geolink']);
$page['formgeolinkparams'] = to_page($params['geolinkparams']);
$page['formusernamepattern'] = to_page($params['usernamepattern']);
$page['formpagestyle'] = $styles_params['page_style'];
$page['availablePageStyles'] = $page_style_list;
$page['formchatstyle'] = $styles_params['chat_style'];
$page['formchattitle'] = topage($params['chattitle']);
$page['formchattitle'] = to_page($params['chattitle']);
$page['formsendmessagekey'] = $params['sendmessagekey'];
$page['availableChatStyles'] = $chat_style_list;
$page['stored'] = isset($_GET['stored']);
@ -161,14 +171,9 @@ if (Settings::get('enabletracking')) {
$page['availableInvitationStyles'] = $invitation_style_list;
}
$page = array_merge(
$page,
prepare_menu($operator)
);
$page = array_merge($page, prepare_menu($operator));
$page['tabs'] = setup_settings_tabs(0);
$page_style = new PageStyle(PageStyle::currentStyle());
$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/statistics.php');
require_once(MIBEW_FS_ROOT . '/libs/cron.php');
require_once(MIBEW_FS_ROOT . '/libs/track.php');
$operator = check_login();
force_password($operator);
@ -33,15 +34,15 @@ force_password($operator);
setlocale(LC_TIME, getstring("time.locale"));
$page = array();
$page['operator'] = topage(get_operator_name($operator));
$page['operator'] = to_page(get_operator_name($operator));
$page['availableDays'] = range(1, 31);
$page['availableMonth'] = get_month_selection(time() - 400 * 24 * 60 * 60, time() + 50 * 24 * 60 * 60);
$page['showresults'] = false;
$statisticstype = verifyparam("type", "/^(bydate|byagent|bypage)$/", "bydate");
$page['type'] = $statisticstype;
$page['showbydate'] = ($statisticstype == 'bydate');
$page['showbyagent'] = ($statisticstype == 'byagent');
$page['showbypage'] = ($statisticstype == 'bypage');
$statistics_type = verify_param("type", "/^(bydate|byagent|bypage)$/", "bydate");
$page['type'] = $statistics_type;
$page['showbydate'] = ($statistics_type == 'bydate');
$page['showbyagent'] = ($statistics_type == 'byagent');
$page['showbypage'] = ($statistics_type == 'bypage');
$page['cron_path'] = cron_get_uri(Settings::get('cron_key'));
$page['last_cron_run'] = Settings::get('_last_cron_run');
@ -51,13 +52,12 @@ $page['show_invitations_info'] = (bool)Settings::get('enabletracking');
$page['errors'] = array();
if (isset($_GET['startday'])) {
$startday = verifyparam("startday", "/^\d+$/");
$startmonth = verifyparam("startmonth", "/^\d{2}.\d{2}$/");
$endday = verifyparam("endday", "/^\d+$/");
$endmonth = verifyparam("endmonth", "/^\d{2}.\d{2}$/");
$start = get_form_date($startday, $startmonth);
$end = get_form_date($endday, $endmonth) + 24 * 60 * 60;
$start_day = verify_param("startday", "/^\d+$/");
$start_month = verify_param("startmonth", "/^\d{2}.\d{2}$/");
$end_day = verify_param("endday", "/^\d+$/");
$end_month = verify_param("endmonth", "/^\d{2}.\d{2}$/");
$start = get_form_date($start_day, $start_month);
$end = get_form_date($end_day, $end_month) + 24 * 60 * 60;
} else {
$curr = getdate(time());
if ($curr['mday'] < 7) {
@ -86,111 +86,106 @@ if ($start > $end) {
$page['errors'][] = getlocal("statistics.wrong.dates");
}
$activetab = 0;
$active_tab = 0;
$db = Database::getInstance();
if ($statisticstype == 'bydate') {
if ($statistics_type == 'bydate') {
$page['reportByDate'] = $db->query(
"SELECT DATE(FROM_UNIXTIME(date)) AS date, " .
"threads, " .
"missedthreads, " .
"sentinvitations, " .
"acceptedinvitations, " .
"rejectedinvitations, " .
"ignoredinvitations, " .
"operatormessages AS agents, " .
"usermessages AS users, " .
"averagewaitingtime AS avgwaitingtime, " .
"averagechattime AS avgchattime " .
"FROM {chatthreadstatistics} s " .
"WHERE s.date >= :start " .
"AND s.date < :end " .
"GROUP BY DATE(FROM_UNIXTIME(date)) " .
"ORDER BY s.date DESC",
("SELECT DATE(FROM_UNIXTIME(date)) AS date, "
. "threads, "
. "missedthreads, "
. "sentinvitations, "
. "acceptedinvitations, "
. "rejectedinvitations, "
. "ignoredinvitations, "
. "operatormessages AS agents, "
. "usermessages AS users, "
. "averagewaitingtime AS avgwaitingtime, "
. "averagechattime AS avgchattime "
. "FROM {chatthreadstatistics} s "
. "WHERE s.date >= :start "
. "AND s.date < :end "
. "GROUP BY DATE(FROM_UNIXTIME(date)) "
. "ORDER BY s.date DESC"),
array(
':start' => $start,
':end' => $end
':end' => $end,
),
array('return_rows' => Database::RETURN_ALL_ROWS)
);
$page['reportByDateTotal'] = $db->query(
"SELECT DATE(FROM_UNIXTIME(date)) AS date, " .
"SUM(threads) AS threads, " .
"SUM(missedthreads) AS missedthreads, " .
"SUM(sentinvitations) AS sentinvitations, " .
"SUM(acceptedinvitations) AS acceptedinvitations, " .
"SUM(rejectedinvitations) AS rejectedinvitations, " .
"SUM(ignoredinvitations) AS ignoredinvitations, " .
"SUM(operatormessages) AS agents, " .
"SUM(usermessages) AS users, " .
"ROUND(SUM(averagewaitingtime * s.threads) / SUM(s.threads),1) AS avgwaitingtime, " .
"ROUND(SUM(averagechattime * s.threads) / SUM(s.threads),1) AS avgchattime " .
"FROM {chatthreadstatistics} s " .
"WHERE s.date >= :start " .
"AND s.date < :end",
("SELECT DATE(FROM_UNIXTIME(date)) AS date, "
. "SUM(threads) AS threads, "
. "SUM(missedthreads) AS missedthreads, "
. "SUM(sentinvitations) AS sentinvitations, "
. "SUM(acceptedinvitations) AS acceptedinvitations, "
. "SUM(rejectedinvitations) AS rejectedinvitations, "
. "SUM(ignoredinvitations) AS ignoredinvitations, "
. "SUM(operatormessages) AS agents, "
. "SUM(usermessages) AS users, "
. "ROUND(SUM(averagewaitingtime * s.threads) / SUM(s.threads),1) AS avgwaitingtime, "
. "ROUND(SUM(averagechattime * s.threads) / SUM(s.threads),1) AS avgchattime "
. "FROM {chatthreadstatistics} s "
. "WHERE s.date >= :start "
. "AND s.date < :end"),
array(
':start' => $start,
':end' => $end
':end' => $end,
),
array('return_rows' => Database::RETURN_ONE_ROW)
);
$activetab = 0;
} elseif($statisticstype == 'byagent') {
$active_tab = 0;
} elseif ($statistics_type == 'byagent') {
$page['reportByAgent'] = $db->query(
"SELECT o.vclocalename AS name, " .
"SUM(s.threads) AS threads, " .
"SUM(s.messages) AS msgs, " .
"ROUND( " .
"SUM(s.averagelength * s.messages) / SUM(s.messages), " .
"1) AS avglen, " .
"SUM(sentinvitations) AS sentinvitations, " .
"SUM(acceptedinvitations) AS acceptedinvitations, " .
"SUM(rejectedinvitations) AS rejectedinvitations, " .
"SUM(ignoredinvitations) AS ignoredinvitations " .
"FROM {chatoperatorstatistics} s, {chatoperator} o " .
"WHERE s.operatorid = o.operatorid " .
"AND s.date >= :start " .
"AND s.date < :end " .
"GROUP BY s.operatorid",
("SELECT o.vclocalename AS name, "
. "SUM(s.threads) AS threads, "
. "SUM(s.messages) AS msgs, "
. "ROUND( "
. "SUM(s.averagelength * s.messages) / SUM(s.messages), "
. "1) AS avglen, "
. "SUM(sentinvitations) AS sentinvitations, "
. "SUM(acceptedinvitations) AS acceptedinvitations, "
. "SUM(rejectedinvitations) AS rejectedinvitations, "
. "SUM(ignoredinvitations) AS ignoredinvitations "
. "FROM {chatoperatorstatistics} s, {chatoperator} o "
. "WHERE s.operatorid = o.operatorid "
. "AND s.date >= :start "
. "AND s.date < :end "
. "GROUP BY s.operatorid"),
array(
':start' => $start,
':end' => $end
':end' => $end,
),
array('return_rows' => Database::RETURN_ALL_ROWS)
);
$activetab = 1;
} elseif($statisticstype == 'bypage') {
$active_tab = 1;
} elseif ($statistics_type == 'bypage') {
$page['reportByPage'] = $db->query(
"SELECT SUM(visits) as visittimes, " .
"address, " .
"SUM(chats) as chattimes, " .
"SUM(sentinvitations) AS sentinvitations, " .
"SUM(acceptedinvitations) AS acceptedinvitations, " .
"SUM(rejectedinvitations) AS rejectedinvitations, " .
"SUM(ignoredinvitations) AS ignoredinvitations " .
"FROM {visitedpagestatistics} " .
"WHERE date >= :start " .
"AND date < :end " .
"GROUP BY address",
("SELECT SUM(visits) as visittimes, "
. "address, "
. "SUM(chats) as chattimes, "
. "SUM(sentinvitations) AS sentinvitations, "
. "SUM(acceptedinvitations) AS acceptedinvitations, "
. "SUM(rejectedinvitations) AS rejectedinvitations, "
. "SUM(ignoredinvitations) AS ignoredinvitations "
. "FROM {visitedpagestatistics} "
. "WHERE date >= :start "
. "AND date < :end "
. "GROUP BY address"),
array(':start' => $start, ':end' => $end),
array('return_rows' => Database::RETURN_ALL_ROWS)
);
$activetab = 2;
$active_tab = 2;
}
$page['showresults'] = count($page['errors']) == 0;
$page['title'] = getlocal("statistics.title");
$page['menuid'] = "statistics";
$page = array_merge(
$page,
prepare_menu($operator)
);
$page = array_merge($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->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/groups.php');
require_once(MIBEW_FS_ROOT . '/libs/settings.php');
require_once(MIBEW_FS_ROOT . '/libs/track.php');
$operator = check_login();
$stylelist = ChatStyle::availableStyles();
$style_list = ChatStyle::availableStyles();
$preview = verifyparam("preview", "/^\w+$/", "default");
if (!in_array($preview, $stylelist)) {
$style_names = array_keys($stylelist);
$preview = $stylelist[$style_names[0]];
$preview = verify_param("preview", "/^\w+$/", "default");
if (!in_array($preview, $style_list)) {
$style_names = array_keys($style_list);
$preview = $style_list[$style_names[0]];
}
$chat_style = new ChatStyle($preview);
@ -45,26 +46,21 @@ $screenshots = array();
foreach ($style_config['screenshots'] as $name => $desc) {
$screenshots[] = array(
'name' => $name,
'file' => MIBEW_WEB_ROOT . '/' . $chat_style->filesPath()
. '/screenshots/' . $name . '.png',
'file' => (MIBEW_WEB_ROOT . '/' . $chat_style->filesPath()
. '/screenshots/' . $name . '.png'),
'description' => $desc
);
}
$page['formpreview'] = $preview;
$page['availablePreviews'] = $stylelist;
$page['availablePreviews'] = $style_list;
$page['screenshotsList'] = $screenshots;
$page['title'] = getlocal("page.preview.title");
$page['menuid'] = "settings";
$page = array_merge(
$page,
prepare_menu($operator)
);
$page = array_merge($page, prepare_menu($operator));
$page['tabs'] = setup_settings_tabs(4);
$page_style = new PageStyle(PageStyle::currentStyle());
$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/groups.php');
require_once(MIBEW_FS_ROOT . '/libs/userinfo.php');
require_once(MIBEW_FS_ROOT . '/libs/track.php');
$operator = check_login();
@ -34,8 +35,8 @@ setlocale(LC_TIME, getstring("time.locale"));
if (isset($_GET['threadid'])) {
// Load thread info
$threadid = verifyparam("threadid", "/^(\d{1,9})?$/", "");
$thread = Thread::load($threadid);
$thread_id = verify_param("threadid", "/^(\d{1,9})?$/", "");
$thread = Thread::load($thread_id);
$group = group_by_id($thread->groupId);
$thread_info = array(
@ -45,19 +46,14 @@ if (isset($_GET['threadid'])) {
$page['thread_info'] = $thread_info;
// Build messages list
$lastid = -1;
$messages = $thread_info['thread']->getMessages(false, $lastid);
$last_id = -1;
$messages = $thread_info['thread']->getMessages(false, $last_id);
$page['threadMessages'] = json_encode($messages);
}
$page['title'] = getlocal("thread.chat_log");
$page = array_merge(
$page,
prepare_menu($operator, false)
);
$page = array_merge($page, prepare_menu($operator, false));
$page_style = new PageStyle(PageStyle::currentStyle());
$page_style->render('thread_log', $page);
?>

View File

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

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