/** * Processes submitting of the form which is generated in * {@link \Mibew\Controller\Operator\PermissionsController::showFormAction()} * method. * * @param Request $request Incoming request. * @return string Rendered page content. * @throws NotFoundException If the operator with specified ID is not found * in the system. */ public function submitFormAction(Request $request) { csrf_check_token($request); $operator = $this->getOperator(); $op_id = $request->attributes->getInt('operator_id'); // Check if the target operator exists $op = operator_by_id($op_id); if (!$op) { throw new NotFoundException('The operator is not found.'); } $new_permissions = isset($op['iperm']) ? $op['iperm'] : 0; foreach (permission_ids() as $perm => $id) { if ($request->request->get('permissions' . $id) == 'on') { $new_permissions |= 1 << $perm; } else { $new_permissions &= ~(1 << $perm); } } // Update operator's permissions in the database and in cached // authentication manager data if it is needed. update_operator_permissions($op['operatorid'], $new_permissions); if ($operator['operatorid'] == $op_id) { $operator['iperm'] = $new_permissions; $this->getAuthenticationManager()->setOperator($operator); } // Redirect the current operator to the same page using GET method. $redirect_to = $this->generateUrl('operator_permissions', array('operator_id' => $op_id, 'stored' => true)); return $this->redirect($redirect_to); }
header("Location: {$webimroot}/operator/operator.php?op={$opId}&stored"); exit; } } else { $page['formlogin'] = topage($login); $page['formname'] = topage($localname); $page['formemail'] = topage($email); $page['formjabber'] = topage($jabber); $page['formjabbernotify'] = $jabbernotify; $page['formcommonname'] = topage($commonname); $page['opid'] = topage($opId); } } else { if (isset($_GET['op'])) { $opId = verifyparam('op', "/^\\d{1,9}\$/"); $op = operator_by_id($opId); if (!$op) { $errors[] = getlocal("no_such_operator"); $page['opid'] = topage($opId); } else { $page['formlogin'] = topage($op['vclogin']); $page['formname'] = topage($op['vclocalename']); $page['formemail'] = topage($op['vcemail']); $page['formjabber'] = topage($op['vcjabbername']); $page['formjabbernotify'] = $op['inotify'] != 0; $page['formcommonname'] = topage($op['vccommonname']); $page['opid'] = topage($op['operatorid']); } } } if (!$opId && !is_capable($can_administrate, $operator)) {
/** * Returns relative path of the avatar for operator related with the thread. * * @param array $args Associative array of arguments. It must contains the * following keys: * - 'threadId': ID of the thread the avatar should be retrieved for. * - 'token': Token of the thread. * @return array Array of results. It contains following keys: * - 'imageLink': string, relative path to operator's avatar. */ protected function apiGetAvatar($args) { // Load thread and check thread's last token $thread = self::getThread($args['threadId'], $args['token']); $image_link = false; if ($thread->agentId) { $operator = operator_by_id($thread->agentId); if ($operator['vcavatar']) { $url_generator = $this->getAssetManager()->getUrlGenerator(); $image_link = $url_generator->generate($operator['vcavatar']); } } return array('imageLink' => $image_link); }
/** * Makes an operator enabled. * * @param int $operator_id ID of the operator to enable. */ function enable_operator($operator_id) { $operator = operator_by_id($operator_id); $operator['idisabled'] = 0; update_operator($operator); }
if ($nextGroup) { $page['message'] = getlocal2("chat.redirected.group.content", array(safe_htmlspecialchars(topage(get_group_name($nextGroup))))); if ($thread['istate'] == $state_chatting) { $link = connect(); commit_thread($threadid, array("istate" => intval($state_waiting), "nextagent" => 0, "groupid" => intval($nextid), "agentId" => 0, "agentName" => "''"), $link); post_message_($thread['threadid'], $kind_events, getstring2_("chat.status.operator.redirect", array(get_operator_name($operator)), $thread['locale'], true), $link); mysql_close($link); } else { $errors[] = getlocal("chat.redirect.cannot"); } } else { $errors[] = getlocal("chat.redirect.unknown_group"); } } else { $nextid = verifyparam("nextAgent", "/^\\d{1,10}\$/"); $nextOperator = operator_by_id($nextid); if ($nextOperator) { $page['message'] = getlocal2("chat.redirected.content", array(safe_htmlspecialchars(topage(get_operator_name($nextOperator))))); if ($thread['istate'] == $state_chatting) { $link = connect(); $threadupdate = array("istate" => intval($state_waiting), "nextagent" => intval($nextid), "agentId" => 0); if ($thread['groupid'] != 0) { if (FALSE === select_one_row("select groupid from {$mysqlprefix}chatgroupoperator where operatorid = " . intval($nextid) . " and groupid = " . intval($thread['groupid']), $link)) { $threadupdate['groupid'] = 0; } } commit_thread($threadid, $threadupdate, $link); post_message_($thread['threadid'], $kind_events, getstring2_("chat.status.operator.redirect", array(get_operator_name($operator)), $thread['locale'], true), $link); mysql_close($link); } else { $errors[] = getlocal("chat.redirect.cannot");
/** * Start chat thread for user * * @param int $group_id Id of group related to thread * @param array $requested_operator Array of requested operator info * @param string $visitor_id Id of the visitor * @param string $visitor_name Name of the visitor * @param string $referrer Page user came from * @param string $info User info * * @return Thread thread object */ 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']; // Check connection limit if (Thread::connectionLimitReached($remote_host)) { die("number of connections from your IP is exceeded, try again later"); } // Check if visitor was invited to chat $is_invited = false; if (Settings::get('enabletracking')) { $invitation_state = invitation_state($_SESSION[SESSION_PREFIX . 'visitorid']); if ($invitation_state['invited']) { $is_invited = true; } } // Get info about requested operator $requested_operator_online = false; if ($requested_operator) { $requested_operator_online = is_operator_online($requested_operator['operatorid']); } // Get thread object if ($is_invited) { // Get thread from invitation $thread = invitation_accept($_SESSION[SESSION_PREFIX . 'visitorid']); if (!$thread) { die("Cannot start thread"); } } else { // Create thread $thread = new Thread(); $thread->state = Thread::STATE_LOADING; $thread->agentId = 0; if ($requested_operator && $requested_operator_online) { $thread->nextAgent = $requested_operator['operatorid']; } } // Update thread fields $thread->groupId = $group_id; $thread->userName = $visitor_name; $thread->remote = $remote_host; $thread->referer = $referrer; $thread->locale = get_current_locale(); $thread->userId = $visitor_id; $thread->userAgent = $user_browser; $thread->save(); $_SESSION[SESSION_PREFIX . 'threadid'] = $thread->id; // Store own thread ids to restrict access for other people if (!isset($_SESSION[SESSION_PREFIX . 'own_threads'])) { $_SESSION[SESSION_PREFIX . 'own_threads'] = array(); } $_SESSION[SESSION_PREFIX . 'own_threads'][] = $thread->id; // Bind thread to the visitor if (Settings::get('enabletracking')) { track_visitor_bind_thread($visitor_id, $thread); } // Send several messages if ($is_invited) { $operator = operator_by_id($thread->agentId); $operator_name = get_operator_name($operator); $thread->postMessage(Thread::KIND_FOR_AGENT, getlocal('Visitor accepted invitation from operator {0}', array($operator_name), get_current_locale(), true)); } else { if ($referrer) { $thread->postMessage(Thread::KIND_FOR_AGENT, getlocal('Vistor came from page {0}', array($referrer), get_current_locale(), true)); } if ($requested_operator && !$requested_operator_online) { $thread->postMessage(Thread::KIND_INFO, getlocal('Thank you for contacting us. We are sorry, but requested operator <strong>{0}</strong> is offline. Another operator will be with you shortly.', array(get_operator_name($requested_operator)), get_current_locale(), true)); } else { $thread->postMessage(Thread::KIND_INFO, getlocal('Thank you for contacting us. An operator will be with you shortly.', null, get_current_locale(), true)); } } // TODO: May be move sending this message somewhere else? if ($info) { $thread->postMessage(Thread::KIND_FOR_AGENT, getlocal('Info: {0}', array($info), get_current_locale(), true)); } // Let plugins know that user is ready to chat. $dispatcher = EventDispatcher::getInstance(); $event_args = array('thread' => $thread); $dispatcher->triggerEvent(Events::THREAD_USER_IS_READY, $event_args); return $thread; }
/** * Process chat thread redirection. * * @param Request $request Incoming request. * @return string|\Symfony\Component\HttpFoundation\RedirectResponse Rendered * page content or a redirect response. * @throws NotFoundException If the thread with specified ID and token is * not found. * @throws BadRequestException If one or more arguments have a wrong format. */ public function redirectAction(Request $request) { $thread_id = $request->attributes->get('thread_id'); $token = $request->attributes->get('token'); $thread = Thread::load($thread_id, $token); if (!$thread) { throw new NotFoundException('The thread is not found.'); } $page = array('errors' => array()); if ($request->query->has('nextGroup')) { // The thread was redirected to a group. $next_id = $request->query->get('nextGroup'); if (!preg_match("/^\\d{1,10}\$/", $next_id)) { throw new BadRequestException('Wrong value of "nextGroup" argument.'); } $next_group = group_by_id($next_id); if ($next_group) { $page['message'] = getlocal('The visitor has been placed in a priorty queue of the group {0}.', array(get_group_name($next_group))); if (!$this->redirectToGroup($thread, (int) $next_id)) { $page['errors'][] = getlocal('You are not chatting with the visitor.'); } } else { $page['errors'][] = 'Unknown group'; } } else { // The thread was redirected to an operator. $next_id = $request->query->get('nextAgent'); if (!preg_match("/^\\d{1,10}\$/", $next_id)) { throw new BadRequestException('Wrong value of "nextAgent" argument.'); } $next_operator = operator_by_id($next_id); if ($next_operator) { $page['message'] = getlocal('The visitor has been placed in the priorty queue of the operator {0}.', array(get_operator_name($next_operator))); if (!$this->redirectToOperator($thread, $next_id)) { $page['errors'][] = getlocal('You are not chatting with the visitor.'); } } else { $page['errors'][] = 'Unknown operator'; } } $page = array_merge_recursive($page, setup_logo()); if (count($page['errors']) > 0) { return $this->render('error', $page); } else { return $this->render('redirected', $page); } }
csrfchecktoken(); check_permissions($operator, $can_administrate); $errors = array(); if (isset($_GET['act']) && $_GET['act'] == 'del') { $operatorid = isset($_GET['id']) ? $_GET['id'] : ""; if (!preg_match("/^\\d+\$/", $operatorid)) { $errors[] = "Cannot delete: wrong argument"; } if (!is_capable($can_administrate, $operator)) { $errors[] = "You are not allowed to remove operators"; } if ($operatorid == $operator['operatorid']) { $errors[] = "Cannot remove self"; } if (count($errors) == 0) { $op = operator_by_id($operatorid); if (!$op) { $errors[] = getlocal("no_such_operator"); } else { if ($op['vclogin'] == 'admin') { $errors[] = 'Cannot remove operator "admin"'; } } } if (count($errors) == 0) { $link = connect(); perform_query("delete from {$mysqlprefix}chatgroupoperator where operatorid = " . intval($operatorid), $link); perform_query("delete from {$mysqlprefix}chatoperator where operatorid = " . intval($operatorid), $link); mysql_close($link); header("Location: {$mibewroot}/operator/operators.php"); exit;
/** * Return updated visitors list. API function. * * Triggers * {@link \Mibew\EventDispatcher\Events::USERS_UPDATE_VISITORS_LOAD} and * {@link \Mibew\EventDispatcher\Events::USERS_UPDATE_VISITORS_ALTER} * events. * * @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 the following keys: * - 'visitors': array of visitors on the site */ protected function apiUpdateVisitors($args) { // Check access $this->checkOperator($args['agentId']); // Close old invitations invitation_close_old(); // Remove old visitors track_remove_old_visitors(); // Get instance of event dispatcher $dispatcher = EventDispatcher::getInstance(); // Trigger load event $arguments = array('visitors' => false); $dispatcher->triggerEvent(Events::USERS_UPDATE_VISITORS_LOAD, $arguments); // Check if visiors list loaded by plugins if (!is_array($arguments['visitors'])) { // 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 {sitevisitor} v " . "LEFT OUTER JOIN {thread} 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'); $rows = $db->query($query, array(':state_invited' => Thread::STATE_INVITED, ':invitation_wait' => Thread::INVITATION_WAIT), array('return_rows' => Database::RETURN_ALL_ROWS)); $visitors = array(); foreach ($rows as $row) { // Get visitor details $details = track_retrieve_details($row); // Get 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) { $user_ip = $matches[1]; } else { $user_ip = false; } // Get invitation info $row['invited'] = $row['invitationstate'] == Thread::INVITATION_WAIT; if ($row['invited']) { $agent_name = get_operator_name(operator_by_id($row['invitedby'])); $invitation_info = array('time' => $row['invitationtime'], 'agentName' => $agent_name); } else { $invitation_info = false; } // Create resulting visitor structure $visitors[] = array('id' => (int) $row['visitorid'], 'userId' => $row['userid'], 'userName' => $row['username'], 'userAgent' => $user_agent, 'userIp' => $user_ip, 'remote' => $details['remote_host'], 'firstTime' => $row['firsttime'], 'lastTime' => $row['lasttime'], 'invitations' => (int) $row['invitations'], 'chats' => (int) $row['chats'], 'invitationInfo' => $invitation_info); } } else { $visitors = $arguments['visitors']; } // Provide ability to alter visitors list $arguments = array('visitors' => $visitors); $dispatcher->triggerEvent(Events::USERS_UPDATE_VISITORS_ALTER, $arguments); // Send results back to the client. "array_values" function should be // used to avoid problems with JSON conversion. If there will be gaps in // keys (the keys are not serial) JSON Object will be produced instead // of an Array. return array('visitors' => array_values($arguments['visitors'])); }
/** * Removes operator's avatar from the database. * * @param Request $request Incoming request. * @return string Rendered page content. * @throws NotFoundException If the operator with specified ID is not found * in the system. */ public function deleteAction(Request $request) { csrf_check_token($request); $operator = $this->getOperator(); $op_id = $request->attributes->getInt('operator_id'); // Try to load the target operator. if (!operator_by_id($op_id)) { throw new NotFoundException('The operator is not found'); } // Try to remove the current operator's avatar if it exists. $current_avatar = $operator['vcavatar']; if ($current_avatar) { @unlink(MIBEW_FS_ROOT . '/files/avatar/' . basename($current_avatar)); } // Update avatar value in database update_operator_avatar($op_id, ''); // Redirect the current operator to the same page using GET method. $redirect_to = $this->generateUrl('operator_avatar', array('operator_id' => $op_id)); return $this->redirect($redirect_to); }
/** * Processes submitting of the form which is generated in * {@link \Mibew\Controller\Operator\GroupsController::showFormAction()} * method. * * @param Request $request Incoming request. * @return string Rendered page content. * @throws NotFoundException If the operator with specified ID is not found * in the system. */ public function submitFormAction(Request $request) { csrf_check_token($request); $operator = $this->getOperator(); $operator_in_isolation = in_isolation($operator); $op_id = $request->attributes->getInt('operator_id'); // Check if the target operator exists $op = operator_by_id($op_id); if (!$op) { throw new NotFoundException('The operator is not found.'); } // Get all groups that are available for the target operator. $groups = $operator_in_isolation ? get_groups_for_operator($operator) : get_all_groups(); // Build list of operator's new groups. $new_groups = array(); foreach ($groups as $group) { if ($request->request->get('group' . $group['groupid']) == 'on') { $new_groups[] = $group['groupid']; } } // Update operator's group and redirect the current operator to the same // page using GET method. update_operator_groups($op['operatorid'], $new_groups); $redirect_to = $this->generateUrl('operator_groups', array('operator_id' => $op_id, 'stored' => true)); return $this->redirect($redirect_to); }
/** * Processes submitting of the form which is generated in * {@link \Mibew\Controller\OperatorController::showEditFormAction()} method. * * @param Request $request Incoming request. * @return string Rendered page content. */ public function submitFormAction(Request $request) { csrf_check_token($request); $errors = array(); $operator = $this->getOperator(); $op_id = $request->attributes->getInt('operator_id'); $login = $request->request->get('login'); $email = $request->request->get('email'); $password = $request->request->get('password'); $password_confirm = $request->request->get('passwordConfirm'); $local_name = $request->request->get('name'); $common_name = $request->request->get('commonname'); $code = $request->request->get('code'); if (!$local_name) { $errors[] = no_field('Name'); } if (!$common_name) { $errors[] = no_field('International name (Latin)'); } // The login is needed only for new operators. If login is changed for // existing operator the stored password hash becomes invalid. if (!$op_id) { if (!$login) { $errors[] = no_field('Login'); } elseif (!preg_match("/^[\\w_\\.]+\$/", $login)) { $errors[] = getlocal('Login should contain only latin characters, numbers and underscore symbol.'); } } if (!$email || !MailUtils::isValidAddress($email)) { $errors[] = wrong_field('E-mail'); } if ($code && !preg_match("/^[A-Za-z0-9_]+\$/", $code)) { $errors[] = getlocal('Code should contain only latin characters, numbers and underscore symbol.'); } if (!$op_id && !$password) { $errors[] = no_field('Password'); } if ($password != $password_confirm) { $errors[] = getlocal('Entered passwords do not match'); } $existing_operator = operator_by_login($login); $duplicate_login = !$op_id && $existing_operator || $op_id && $existing_operator && $op_id != $existing_operator['operatorid']; if ($duplicate_login) { $errors[] = getlocal('Please choose another login because an operator with that login is already registered in the system.'); } // Check if operator with specified email already exists in the database. $existing_operator = operator_by_email($email); $duplicate_email = !$op_id && $existing_operator || $op_id && $existing_operator && $op_id != $existing_operator['operatorid']; if ($duplicate_email) { $errors[] = getlocal('Please choose another email because an operator with that email is already registered in the system.'); } if (count($errors) != 0) { $request->attributes->set('errors', $errors); // The form should be rebuild. Invoke appropriate action. return $this->showFormAction($request); } if (!$op_id) { // Create new operator and redirect the current operator to avatar // page. $new_operator = create_operator($login, $email, $password, $local_name, $common_name, '', $code); $redirect_to = $this->generateUrl('operator_avatar', array('operator_id' => $new_operator['operatorid'])); return $this->redirect($redirect_to); } // Mix old operator's fields with updated values $target_operator = array('vcemail' => $email, 'vclocalename' => $local_name, 'vccommonname' => $common_name, 'code' => $code) + operator_by_id($op_id); // Set the password only if it's not an empty string. if ($password !== '') { $target_operator['vcpassword'] = calculate_password_hash($target_operator['vclogin'], $password); } // Update operator's fields in the database. update_operator($target_operator); // Operator's data are cached in the authentication manager, thus we need // to manually update them. if ($target_operator['operatorid'] == $operator['operatorid']) { // Check if the admin has set his password for the first time. $to_dashboard = check_password_hash($operator['vclogin'], '', $operator['vcpassword']) && $password != ''; // Update operator's fields. $this->getAuthenticationManager()->setOperator($target_operator); // Redirect the admin to the home page if needed. if ($to_dashboard) { return $this->redirect($this->generateUrl('home_operator')); } } // Redirect the operator to edit page again to use GET method instead of // POST. $redirect_to = $this->generateUrl('operator_edit', array('operator_id' => $op_id, 'stored' => true)); return $this->redirect($redirect_to); }
/** * Resets operators password and provides an ability to set the new one. * * @param Request $request * @return string Rendered page content */ public function resetAction(Request $request) { $page = array('version' => MIBEW_VERSION, 'showform' => true, 'title' => getlocal('Change your password'), 'headertitle' => getlocal('Mibew Messenger'), 'show_small_login' => true, 'fixedwrap' => true, 'errors' => array()); if ($request->isMethod('POST')) { // When HTTP GET method is used the form is just rendered but the // user does not pass any data. Thus we need to prevent CSRF attacks // only for POST requests csrf_check_token($request); } // Make sure user id is specified and its format is correct. $op_id = $request->isMethod('GET') ? $request->query->get('id') : $request->request->get('id'); if (!preg_match("/^\\d{1,9}\$/", $op_id)) { throw new BadRequestException(); } // Make sure token is specified and its format is correct. $token = $request->isMethod('GET') ? $request->query->get('token') : $request->request->get('token'); if (!preg_match("/^[\\dabcdef]+\$/", $token)) { throw new BadRequestException(); } $operator = operator_by_id($op_id); if (!$operator) { $page['errors'][] = 'No such operator'; $page['showform'] = false; } elseif ($token != $operator['vcrestoretoken']) { $page['errors'][] = 'Wrong token'; $page['showform'] = false; } if (count($page['errors']) == 0 && $request->isMethod('POST') && $request->request->has('password')) { $password = $request->request->get('password'); $password_confirm = $request->request->get('passwordConfirm'); if (!$password) { $page['errors'][] = no_field('Password'); } if ($password != $password_confirm) { $page['errors'][] = getlocal('Entered passwords do not match'); } if (count($page['errors']) == 0) { $page['isdone'] = true; // Update the operator $operator['vcrestoretoken'] = ''; $operator['vcpassword'] = calculate_password_hash($operator['vclogin'], $password); update_operator($operator); $page['loginname'] = $operator['vclogin']; return $this->render('password_recovery_reset', $page); } } $page['id'] = $op_id; $page['token'] = $token; $page['isdone'] = false; return $this->render('password_recovery_reset', $page); }
/** * Enables an operator. * * @param Request $request Incoming request. * @return string Rendered page content. * @throws NotFoundException If the operator with specified ID is not found * in the system. */ public function enableAction(Request $request) { csrf_check_token($request); $operator_id = $request->attributes->getInt('operator_id'); if (!operator_by_id($operator_id)) { throw new NotFoundException('The operator is not found.'); } enable_operator($operator_id); // Redirect the current operator to the page with operators list return $this->redirect($this->generateUrl('operators')); }
/** * Provides a gateway for widget requests. * * Triggers {@link \Mibew\EventDispatcher\Events::VISITOR_TRACK} event. * * @param Request $request * @return string Rendered page content */ public function indexAction(Request $request) { $operator = array(); $response_data = array('load' => array(), 'handlers' => array(), 'dependencies' => array(), 'data' => array()); $tracking_allowed = Settings::get('enabletracking') == '1' && (Settings::get('trackoperators') == '1' || !$this->getOperator()); if ($tracking_allowed) { $entry = $request->query->get('entry', ''); $referer = $request->server->get('HTTP_REFERER', ''); $user_id = $request->query->get('user_id', false); // Check if session was started if (isset($_SESSION[SESSION_PREFIX . 'visitorid']) && preg_match('/^[0-9]+$/', $_SESSION[SESSION_PREFIX . 'visitorid'])) { // Session was started. Just track the visitor. $visitor_id = track_visitor($_SESSION[SESSION_PREFIX . 'visitorid'], $entry, $referer); $visitor = track_get_visitor_by_id($visitor_id); } else { $visitor = track_get_visitor_by_user_id($user_id); if ($visitor !== false) { // Session is not started but the visitor exists in // database. Probably third-party cookies are disabled by // the browser. Use tracking by local cookie at target site. $visitor_id = track_visitor($visitor['visitorid'], $entry, $referer); } else { // Start tracking session $visitor_id = track_visitor_start($entry, $referer); $visitor = track_get_visitor_by_id($visitor_id); } } if ($visitor_id) { $_SESSION[SESSION_PREFIX . 'visitorid'] = $visitor_id; } if ($user_id === false) { // Update local cookie value at target site $response_data['handlers'][] = 'updateUserId'; $response_data['dependencies']['updateUserId'] = array(); $response_data['data']['user']['id'] = $visitor['userid']; } // Provide an ability for others to make something on visitor // tracking $event_arguments = array('visitor' => $visitor); EventDispatcher::getInstance()->triggerEvent(Events::VISITOR_TRACK, $event_arguments); // Get invitation state $invitation_state = invitation_state($visitor_id); // Check if invitation is closed if (!$invitation_state['invited'] && !empty($_SESSION[SESSION_PREFIX . 'invitation_threadid'])) { $response_data['handlers'][] = 'invitationClose'; $response_data['dependencies']['invitationClose'] = array(); unset($_SESSION[SESSION_PREFIX . 'invitation_threadid']); } // Check if the visitor is just invited to chat $is_invited = $invitation_state['invited'] && (empty($_SESSION[SESSION_PREFIX . 'invitation_threadid']) ? true : $_SESSION[SESSION_PREFIX . 'invitation_threadid'] != $invitation_state['threadid']); if ($is_invited) { // Load invitation thread $thread = Thread::load($invitation_state['threadid']); // Get operator info $operator = operator_by_id($thread->agentId); $locale = $request->query->get('locale', ''); $operator_name = $locale == get_home_locale() ? $operator['vclocalename'] : $operator['vccommonname']; $avatar_url = $operator['vcavatar'] ? $this->asset($operator['vcavatar'], AssetUrlGeneratorInterface::ABSOLUTE_URL) : false; // Show invitation dialog at widget side $response_data['handlers'][] = 'invitationCreate'; $response_data['dependencies']['invitationCreate'] = array(); $response_data['data']['invitation'] = array('operatorName' => htmlspecialchars($operator_name), 'avatarUrl' => htmlspecialchars($avatar_url), 'threadUrl' => $this->generateUrl('chat_user_invitation', array(), UrlGeneratorInterface::ABSOLUTE_URL), 'acceptCaption' => getlocal('Answer')); $_SESSION[SESSION_PREFIX . 'invitation_threadid'] = $thread->id; } // Check if the visitor rejects invitation if ($invitation_state['invited'] && $request->query->get('invitation_rejected')) { invitation_reject($visitor_id); } $event_arguments = array('visitor' => $visitor, 'request' => $request, 'response' => $response_data, 'route_url_generator' => $this->getRouter(), 'asset_url_generator' => $this->getAssetManager()->getUrlGenerator()); EventDispatcher::getInstance()->triggerEvent(Events::WIDGET_RESPONSE_ALTER, $event_arguments); $response_data = $event_arguments['response']; } // Builds JSONP response $response = new JsonResponse($response_data); $response->setCallback("Mibew.Objects.widget.onResponse"); // Add headers to overcome third-party cookies problem. $response->headers->set('P3P', 'CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"'); return $response; }