Example #1
0
 /**
  * Settings class constructor. Set default values and load setting from
  * database.
  */
 protected function __construct()
 {
     // Set default values
     $this->settings = array('dbversion' => 0, 'title' => 'Your Company', 'hosturl' => 'http://mibew.org', 'logo' => '', 'usernamepattern' => '{name}', 'chat_style' => 'default', 'invitation_style' => 'default', 'page_style' => 'default', 'chattitle' => 'Live Support', 'geolink' => 'http://api.hostip.info/get_html.php?ip={ip}', 'geolinkparams' => 'width=440,height=100,toolbar=0,scrollbars=0,location=0,status=1,menubar=0,resizable=1', 'max_uploaded_file_size' => 100000, 'max_connections_from_one_host' => 10, 'thread_lifetime' => 600, 'email' => '', 'left_messages_locale' => get_home_locale(), 'sendmessagekey' => 'center', 'enableban' => '0', 'enablessl' => '0', 'forcessl' => '0', 'usercanchangename' => '1', 'enablegroups' => '0', 'enablegroupsisolation' => '0', 'enablestatistics' => '1', 'enabletracking' => '0', 'enablepresurvey' => '1', 'surveyaskmail' => '0', 'surveyaskgroup' => '1', 'surveyaskmessage' => '0', 'enablepopupnotification' => '0', 'autocheckupdates' => '1', 'showonlineoperators' => '0', 'enablecaptcha' => '0', 'online_timeout' => 30, 'connection_timeout' => 30, 'updatefrequency_operator' => 2, 'updatefrequency_chat' => 2, 'updatefrequency_tracking' => 10, 'visitors_limit' => 20, 'invitation_lifetime' => 60, 'tracking_lifetime' => 600, 'trackoperators' => '0', 'cron_key' => DEFAULT_CRON_KEY, '_last_cron_run' => 0, '_instance_id' => '');
     // Load values from database
     $db = Database::getInstance();
     $rows = $db->query("SELECT vckey, vcvalue FROM {config}", null, array('return_rows' => Database::RETURN_ALL_ROWS));
     foreach ($rows as $row) {
         $name = $row['vckey'];
         $this->settings[$name] = $row['vcvalue'];
         $this->settingsInDb[$name] = true;
     }
 }
Example #2
0
    /**
     * 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 the
     *   following keys:
     *    - 'threadId': for this function this param equals to null;
     *    - 'token': for this function this param equals to null;
     *    - 'name': string, user name;
     *    - 'email': string, user email;
     *    - 'message': string, user message;
     *    - 'info': string, some info about user;
     *    - 'referrer': string, page user came from;
     *    - 'captcha': string, captcha value;
     *    - 'groupId': selected group id.
     *
     * @throws \Mibew\RequestProcessor\ThreadProcessorException Can throw an
     *   exception if captcha or email is wrong.
     */
    protected function apiProcessLeaveMessage($args)
    {
        // Check captcha
        if (Settings::get('enablecaptcha') == '1' && can_show_captcha()) {
            $captcha = $args['captcha'];
            $original = isset($_SESSION[SESSION_PREFIX . 'mibew_captcha'])
                ? $_SESSION[SESSION_PREFIX . 'mibew_captcha']
                : '';
            unset($_SESSION[SESSION_PREFIX . 'mibew_captcha']);
            if (empty($original) || empty($captcha) || $captcha != $original) {
                throw new ThreadProcessorException(
                    getlocal('The letters you typed don\'t match the letters that were shown in the picture.'),
                    ThreadProcessorException::ERROR_WRONG_CAPTCHA
                );
            }
        }

        // Get form fields
        $email = $args['email'];
        $name = $args['name'];
        $message = $args['message'];
        $info = $args['info'];
        $referrer = $args['referrer'];

        if (!MailUtils::isValidAddress($email)) {
            throw new ThreadProcessorException(
                wrong_field("Your email"),
                ThreadProcessorException::ERROR_WRONG_EMAIL
            );
        }

        // Verify group id
        $group_id = '';
        if (Settings::get('enablegroups') == '1') {
            if (preg_match("/^\d{1,8}$/", $args['groupId']) != 0) {
                $group = group_by_id($args['groupId']);
                if ($group) {
                    $group_id = $args['groupId'];
                }
            }
        }

        // Create thread for left message
        $remote_host = get_remote_host();
        $user_browser = $_SERVER['HTTP_USER_AGENT'];
        $visitor = visitor_from_request();

        // Get message locale
        $message_locale = Settings::get('left_messages_locale');
        if (!locale_is_available($message_locale)) {
            $message_locale = get_home_locale();
        }

        // Create thread
        $thread = new Thread();
        $thread->groupId = $group_id;
        $thread->userName = $name;
        $thread->remote = $remote_host;
        $thread->referer = $referrer;
        $thread->locale = get_current_locale();
        $thread->userId = $visitor['id'];
        $thread->userAgent = $user_browser;
        $thread->state = Thread::STATE_LEFT;
        $thread->closed = time();
        $thread->save();

        // Send some messages
        if ($referrer) {
            $thread->postMessage(
                Thread::KIND_FOR_AGENT,
                getlocal('Vistor came from page {0}', array($referrer), get_current_locale(), true)
            );
        }
        if ($email) {
            $thread->postMessage(
                Thread::KIND_FOR_AGENT,
                getlocal('E-Mail: {0}', array($email), get_current_locale(), true)
            );
        }
        if ($info) {
            $thread->postMessage(
                Thread::KIND_FOR_AGENT,
                getlocal('Info: {0}', array($info), get_current_locale(), true)
            );
        }
        $thread->postMessage(Thread::KIND_USER, $message, array('name' => $name));

        // Get email for message
        $inbox_mail = get_group_email($group_id);

        if (empty($inbox_mail)) {
            $inbox_mail = Settings::get('email');
        }

        // Send email
        if ($inbox_mail) {
            // Prepare message to send by email
            $mail_template = MailTemplate::loadByName('leave_message', $message_locale);
            if (!$mail_template) {
                trigger_error(
                    'Cannot send e-mail because "leave_message" mail template cannot be loaded.',
                    E_USER_WARNING
                );

                return;
            }

            $subject = $mail_template->buildSubject(array($args['name']));
            $body = $mail_template->buildBody(array(
                $args['name'],
                $email,
                $message,
                ($info ? $info . "\n" : ""),
            ));

            // Send
            $this->getMailerFactory()->getMailer()->send(
                MailUtils::buildMessage($inbox_mail, $email, $subject, $body)
            );
        }
    }
Example #3
0
/**
 * Return local or common group description depending on current locale.
 *
 * @param array $group Associative group array. Should contain following keys:
 *  - 'vccommondescription': string, contain common description of the group;
 *  - 'vclocaldescription': string, contain local description of the group.
 * @return string Group description
 */
function get_group_description($group)
{
    $use_local_description = (get_home_locale() == get_current_locale())
        || !isset($group['vccommondescription'])
        || !$group['vccommondescription'];

    if ($use_local_description) {
        return $group['vclocaldescription'];
    } else {
        return $group['vccommondescription'];
    }
}
Example #4
0
 /**
  * Processes submitting of the form which is generated in
  * {@link \Mibew\Controller\Settings\CommonController::showFormAction()}
  * method.
  *
  * @param Request $request Incoming request.
  * @return string Rendered page content.
  * @throws BadRequestException If one or more parameters of the request have
  *   wrong format.
  */
 public function submitFormAction(Request $request)
 {
     csrf_check_token($request);
     $errors = array();
     $params = array();
     $params['email'] = $request->request->get('email');
     $params['title'] = $request->request->get('title');
     $params['logo'] = $request->request->get('logo');
     $params['hosturl'] = $request->request->get('hosturl');
     $params['usernamepattern'] = $request->request->get('usernamepattern');
     $params['chattitle'] = $request->request->get('chattitle');
     $params['geolink'] = $request->request->get('geolink');
     $params['geolinkparams'] = $request->request->get('geolinkparams');
     $params['cron_key'] = $request->request->get('cronkey');
     $send_key = $request->request->get('sendmessagekey');
     if (!preg_match("/^c?enter\$/", $send_key)) {
         throw new BadRequestException('Wrong format of "sendmessagekey" field.');
     }
     $params['sendmessagekey'] = $send_key;
     $params['left_messages_locale'] = $request->request->get('leftmessageslocale');
     if (!in_array($params['left_messages_locale'], get_available_locales())) {
         $params['left_messages_locale'] = get_home_locale();
     }
     if ($params['email'] && !MailUtils::isValidAddress($params['email'])) {
         $errors[] = getlocal('Enter a valid email address');
     }
     if ($params['geolinkparams']) {
         foreach (explode(',', $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) {
                 $errors[] = "Wrong link parameter: \"{$one_param}\", " . "should be one of 'toolbar, scrollbars, location, " . "status, menubar, width, height or resizable'";
             }
         }
     }
     if (preg_match("/^[0-9A-Za-z]*\$/", $params['cron_key']) == 0) {
         $errors[] = getlocal('Use only Latin letters(upper and lower case) and numbers in cron key.');
     }
     // Load styles configs
     $chat_style = $request->request->get('chat_style', ChatStyle::getDefaultStyle());
     $chat_style_list = ChatStyle::getAvailableStyles();
     if (!in_array($chat_style, $chat_style_list)) {
         $chat_style = $chat_style_list[0];
     }
     $page_style = $request->request->get('page_style', PageStyle::getDefaultStyle());
     $page_style_list = PageStyle::getAvailableStyles();
     if (!in_array($page_style, $page_style_list)) {
         $page_style = $page_style_list[0];
     }
     if (Settings::get('enabletracking')) {
         $invitation_style = $request->request->get('invitation_style', InvitationStyle::getDefaultStyle());
         $invitation_style_list = InvitationStyle::getAvailableStyles();
         if (!in_array($invitation_style, $invitation_style_list)) {
             $invitation_style = $invitation_style_list[0];
         }
     }
     if (count($errors) != 0) {
         $request->attributes->set('errors', $errors);
         // The form should be rebuild. Invoke appropriate action.
         return $this->showFormAction($request);
     }
     // Update system settings
     foreach ($params as $key => $value) {
         Settings::set($key, $value);
     }
     // Update styles params
     ChatStyle::setDefaultStyle($chat_style);
     PageStyle::setDefaultStyle($page_style);
     if (Settings::get('enabletracking')) {
         InvitationStyle::setDefaultStyle($invitation_style);
     }
     // Redirect the user to the same page using GET method
     $redirect_to = $this->generateUrl('settings_common', array('stored' => true));
     return $this->redirect($redirect_to);
 }
Example #5
0
/**
 * Returns name of the operator. Choose between vclocalname and vccommonname
 *
 * @param array $operator Operator's array
 * @return string Operator's name
 */
function get_operator_name($operator)
{
    if (get_home_locale() == get_current_locale()) {
        return $operator['vclocalename'];
    } else {
        return $operator['vccommonname'];
    }
}
Example #6
0
 /**
  * Assign operator to thread
  *
  * @param array $operator Operator who try to take thread
  * @return boolean Boolean TRUE on success or FALSE on failure
  */
 public function take($operator)
 {
     // There are states which forbids thread taking. Make sure the current
     // state is not one of them.
     $forbidden_states = array(self::STATE_CLOSED, self::STATE_LEFT, self::STATE_INVITED);
     if (in_array($this->state, $forbidden_states)) {
         return false;
     }
     $is_operator_changed = $operator['operatorid'] != $this->agentId && ($this->state == self::STATE_WAITING || $this->state == self::STATE_CHATTING);
     // For these states we assume that the thread has no operator yet. The
     // check for operator changing is skipped because it will always
     // return positive result.
     $is_operator_joined = $this->state == self::STATE_LOADING || $this->state == self::STATE_QUEUE;
     $is_operator_back = $this->state == self::STATE_WAITING && $operator['operatorid'] == $this->agentId;
     $message = '';
     $operator_name = $this->locale == get_home_locale() ? $operator['vclocalename'] : $operator['vccommonname'];
     if ($is_operator_changed) {
         $message = getlocal("Operator <strong>{0}</strong> changed operator <strong>{1}</strong>", array($operator_name, $this->agentName), $this->locale, true);
     } elseif ($is_operator_joined) {
         $message = getlocal("Operator {0} joined the chat", array($operator_name), $this->locale, true);
     } elseif ($is_operator_back) {
         $message = getlocal("Operator {0} is back", array($operator_name), $this->locale, true);
     }
     // Make sure the thread have correct operator and state.
     $this->state = self::STATE_CHATTING;
     $this->nextAgent = 0;
     $this->agentId = $operator['operatorid'];
     $this->agentName = $operator_name;
     if (empty($this->chatStarted)) {
         // This is needed only if the chat was not started yet. Such threads
         // should originally belong to STATE_QUEUE or STATE_LOADING.
         $this->chatStarted = time();
     }
     $this->save();
     // Send message
     if ($message) {
         $this->postMessage(self::KIND_EVENTS, $message);
     }
     return true;
 }
Example #7
0
 /**
  * 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;
 }