Exemple #1
0
/**
 * Invitation was accepted by visitor
 *
 * Triggers {@link \Mibew\EventDispatcher\Events::INVITATION_ACCEPT} event.
 *
 * @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)
{
    // Check if visitor was invited
    $invitation_state = invitation_state($visitor_id);
    if (!$invitation_state['invited']) {
        // Visitor was not invited
        return false;
    }
    // Get thread related with the visitor
    $db = Database::getInstance();
    $result = $db->query("SELECT threadid FROM {sitevisitor} WHERE visitorid = :visitor_id", array(':visitor_id' => $visitor_id), array('return_rows' => Database::RETURN_ONE_ROW));
    if (empty($result['threadid'])) {
        // Something went wrong. There is no thread related with the visitor.
        return false;
    }
    $thread = Thread::load($result['threadid']);
    if (!$thread) {
        // Something went wrong. Cannot load thread.
        return false;
    }
    // Update thread info
    $thread->state = Thread::STATE_CHATTING;
    $thread->invitationState = Thread::INVITATION_ACCEPTED;
    $thread->chatStarted = time();
    $thread->save();
    // Update visitor info
    $db->query("UPDATE {sitevisitor} SET chats = chats + 1 " . "WHERE visitorid = :visitor_id", array(':visitor_id' => $visitor_id));
    $args = array('invitation' => $thread);
    EventDispatcher::getInstance()->triggerEvent(Events::INVITATION_ACCEPT, $args);
    return $thread;
}
    /**
     * Process chat in an invitation block.
     *
     * @param Request $request Incoming request.
     * @return string|\Symfony\Component\HttpFoundation\RedirectResponse Rendered
     *   page content or a redirect response.
     */
    public function invitationAction(Request $request)
    {
        // Check if an user tries to use invitation functionality when it's
        // disabled.
        if (!Settings::get('enabletracking')) {
            return $this->redirect($this->generateUrl('chat_user_start'));
        }

        // Check if we should force the user to use SSL.
        $ssl_redirect = $this->sslRedirect($request);
        if ($ssl_redirect !== false) {
            return $ssl_redirect;
        }

        // Check if user invited to chat.
        $invitation_state = invitation_state($_SESSION[SESSION_PREFIX . 'visitorid']);

        if (!$invitation_state['invited'] || !$invitation_state['threadid']) {
            return $this->redirect($this->generateUrl('chat_user_start'));
        }

        $thread = Thread::load($invitation_state['threadid']);

        // 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;

        // Prepare page
        $page = setup_invitation_view($thread);

        // Build js application options
        $page['invitationOptions'] = $page['invitation'];

        // Initialize client side application
        $this->getAssetManager()->attachJs('js/compiled/chat_app.js');
        $this->getAssetManager()->attachJs(
            $this->startJsApplication($request, $page),
            AssetManagerInterface::INLINE,
            1000
        );

        // Expand page
        return $this->render('chat', $page);
    }
Exemple #3
0
function track_visit_page($visitor_id, $page)
{
    $db = Database::getInstance();
    if (empty($page)) {
        return;
    }
    $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 ($last_page['address'] != $page) {
        $db->query("INSERT INTO {visitedpage} (" . "visitorid, address, visittime " . ") VALUES ( " . ":visitorid, :page, :now " . ")", array(':visitorid' => $visitor_id, ':page' => $page, ':now' => time()));
        // If the visitor was invited and he goes to another page the invitation
        // should be automatically rejected.
        $invitation_state = invitation_state($visitor_id);
        if ($invitation_state['invited']) {
            invitation_reject($visitor_id);
        }
    }
}
Exemple #4
0
/**
 * 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;
}
 /**
  * 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;
 }