Exemplo n.º 1
0
 /**
  * Records a phone call as a notification.
  *
  * Given a phone number, if a contact matching that phone number exists, a
  * notification assigned to that contact's assignee will be created.
  * Software-based telephony systems such as Asterisk can thus immediately
  * notify sales reps of a phone call by making a cURL request to a url
  * formatted as follows:
  *
  * api/voip/data/[phone number]
  *
  * (Note: the phone number itself must not contain anything but digits, i.e.
  * no periods or dashes.)
  *
  * For Asterisk, one possible integration method is to insert into the
  * dialplan, at the appropriate position, a call to a script that uses
  * {@link http://phpagi.sourceforge.net/ PHPAGI} to extract the phone
  * number. The script can then make the necessary request to this action.
  * @param bool $actionHist If set to 1, create an action history item for the contact.
  */
 public function actionVoip($actionHist = 0)
 {
     if (isset($_GET['data'])) {
         $matches = array();
         if (preg_match('/\\d{10,}/', $_GET['data'], $matches)) {
             $number = ltrim($matches[0], '1');
             $phoneCrit = new CDbCriteria(array('condition' => "modelType='Contacts' AND number LIKE :number", 'params' => array(':number' => "%{$number}%")));
             $phoneCrit->join = 'join x2_contacts on modelId=x2_contacts.id AND ' . Contacts::model()->getHiddenCondition('x2_contacts');
             $phoneNumber = PhoneNumber::model()->find($phoneCrit);
             if (!empty($phoneNumber)) {
                 $contact = X2Model::model('Contacts')->findByPk($phoneNumber->modelId);
                 if (isset($contact)) {
                     $contact->disableBehavior('changelog');
                     $contact->updateLastActivity();
                     $assignees = array($contact->assignedTo);
                     if ($contact->assignedTo == 'Anyone' || $contact->assignedTo == null) {
                         $users = User::model()->findAll();
                         $assignees = array_map(function ($u) {
                             return $u->username;
                         }, $users);
                     }
                     $multiUser = count($assignees) > 1;
                     $usersSuccess = array();
                     $usersFailure = array();
                     // Format the phone number:
                     $formattedNumber = '';
                     $strNumber = (string) $number;
                     $strl = strlen($strNumber);
                     $formattedNumber = substr($strNumber, $strl - 4, $strl);
                     $formattedNumber = substr($strNumber, $strl - 7, 3) . "-{$formattedNumber}";
                     if ($strl >= 10) {
                         $formattedNumber = substr($strNumber, $strl - 10, 3) . "-{$formattedNumber}";
                         if ($strl > 10) {
                             $formattedNumber = substr($strNumber, 0, $strl - 10) . "-{$formattedNumber}";
                         }
                     }
                     $time = time();
                     // Create notifications:
                     foreach ($assignees as $user) {
                         $notif = new Notification();
                         $notif->type = 'voip_call';
                         $notif->user = $user;
                         $notif->modelType = 'Contacts';
                         $notif->modelId = $contact->id;
                         $notif->value = $formattedNumber;
                         $notif->createDate = $time;
                         if ($notif->save()) {
                             $usersSuccess[] = $user;
                         } else {
                             $usersFailure = array();
                         }
                     }
                     if ($actionHist) {
                         // Create an action:
                         $action = new Actions();
                         $action->assignedTo = 'Anyone';
                         $action->visibility = 1;
                         $action->associationId = $contact->id;
                         $action->associationType = 'contacts';
                         $action->associationName = $contact->name;
                         $action->dueDate = $time;
                         $action->createDate = $time;
                         $action->completeDate = $time;
                         $action->lastUpdated = $time;
                         $action->type = 'call';
                         $action->complete = 'Yes';
                         $action->completedBy = 'Anyone';
                         $action->save();
                         $action->actionText = Yii::t('app', 'Phone system reported inbound call from contact.');
                     }
                     $failure = count($usersSuccess) == 0;
                     $partialFailure = count($usersFailure) > 0;
                     if ($failure) {
                         $message = 'Saving notifications failed.';
                     } else {
                         /*X2Flow::trigger('RecordVoipInboundTrigger', array(
                         			'model' => $contact,
                         			'number' => $matches[0]
                         		));*/
                         $message = 'Notifications created for user(s): ' . implode(',', $usersSuccess);
                         if ($partialFailure) {
                             $message .= '; saving notifications failed for users(s): ' . implode(',', $usersFailure);
                         }
                     }
                     // Create an event record for the feed:
                     $event = new Events();
                     $event->type = 'voip_call';
                     $event->associationType = get_class($contact);
                     $event->associationId = $contact->id;
                     $event->save();
                     $this->_sendResponse($failure ? 500 : 200, $message);
                 } else {
                     $this->_sendResponse(404, 'Phone number record refers to a contact that no longer exists.');
                 }
             } else {
                 $this->_sendResponse(404, 'No matching phone number found.');
                 // $notif = new Notification;
                 // $notif->type = 'voip_call';
                 // $notif->user = ?;
                 // $notif->modelType = 'Contacts';
                 // $notif->value = $matches[0];
                 // $notif->createDate = time();
                 // $notif->save();
             }
         } else {
             $this->_sendResponse(400, 'Invalid phone number format.');
         }
     } else {
         $this->_sendResponse(400, 'Phone number required as "data" URL parameter.');
     }
 }
Exemplo n.º 2
0
 /**
  * Search X2Engine for a record.
  *
  * This is the action called by the search bar in the main menu.
  */
 public function actionSearch()
 {
     ini_set('memory_limit', -1);
     $term = isset($_GET['term']) ? $_GET['term'] : "";
     if (empty($term)) {
         $dataProvider = new CArrayDataProvider(array());
         Yii::app()->user->setFlash('error', Yii::t('app', "Search term cannot be empty."));
         $this->render('search', array('dataProvider' => $dataProvider));
     } else {
         if (substr($term, 0, 1) != "#") {
             $modules = Modules::model()->findAllByAttributes(array('searchable' => 1));
             $comparisons = array();
             $other = array();
             foreach ($modules as $module) {
                 $module->name == 'products' ? $type = ucfirst('Product') : ($type = ucfirst($module->name));
                 $module->name == 'quotes' ? $type = ucfirst('Quote') : ($type = $type);
                 $module->name == 'opportunities' ? $type = ucfirst('Opportunity') : ($type = $type);
                 $criteria = new CDbCriteria();
                 $fields = Fields::model()->findAllByAttributes(array('modelName' => $type, 'searchable' => 1));
                 $temp = array();
                 $fieldNames = array();
                 if (count($fields) < 1) {
                     $criteria->compare('id', '<0', true, 'AND');
                 }
                 foreach ($fields as $field) {
                     $temp[] = $field->id;
                     $fieldNames[] = $field->fieldName;
                     $criteria->compare($field->fieldName, $term, true, "OR");
                     if ($field->type == 'phone') {
                         $tempPhone = preg_replace('/\\D/', '', $term);
                         $phoneLookup = PhoneNumber::model()->findByAttributes(array('modelType' => $field->modelName, 'number' => $tempPhone, 'fieldName' => $field->fieldName));
                         if (isset($phoneLookup)) {
                             $criteria->compare('id', $phoneLookup->modelId, true, "OR");
                         }
                     }
                 }
                 if (Yii::app()->user->getName() != 'admin' && X2Model::model($type)->hasAttribute('visibility') && X2Model::model($type)->hasAttribute('assignedTo')) {
                     $condition = 'visibility="1" OR (assignedTo="Anyone" AND visibility!="0")  OR assignedTo="' . Yii::app()->user->getName() . '"';
                     /* x2temp */
                     $groupLinks = Yii::app()->db->createCommand()->select('groupId')->from('x2_group_to_user')->where('userId=' . Yii::app()->user->getId())->queryColumn();
                     if (!empty($groupLinks)) {
                         $condition .= ' OR assignedTo IN (' . implode(',', $groupLinks) . ')';
                     }
                     $condition .= 'OR (visibility=2 AND assignedTo IN
                         (SELECT username FROM x2_group_to_user WHERE groupId IN
                             (SELECT groupId FROM x2_group_to_user WHERE userId=' . Yii::app()->user->getId() . ')))';
                     $criteria->addCondition($condition);
                 }
                 if ($module->name == 'actions') {
                     $criteria->with = array('actionText');
                     $criteria->compare('actionText.text', $term, true, "OR");
                 }
                 if (class_exists($type)) {
                     $arr = X2Model::model($type)->findAll($criteria);
                     $comparisons[$type] = $temp;
                     $other[$type] = $arr;
                 }
             }
             $high = array();
             $medium = array();
             $low = array();
             $userHigh = array();
             $userMedium = array();
             $userLow = array();
             $records = array();
             $userRecords = array();
             $regEx = "/" . preg_quote($term, '/') . "/i";
             foreach ($other as $key => $recordType) {
                 $fieldList = $comparisons[$key];
                 foreach ($recordType as $otherRecord) {
                     if ($key == 'Actions') {
                         if ($otherRecord->hasAttribute('assignedTo') && $otherRecord->assignedTo == Yii::app()->user->getName()) {
                             $userHigh[] = $otherRecord;
                         } else {
                             $high[] = $otherRecord;
                         }
                     } else {
                         foreach ($fieldList as $field) {
                             $fieldRecord = Fields::model()->findByPk($field);
                             $fieldName = $fieldRecord->fieldName;
                             if (preg_match($regEx, $otherRecord->{$fieldName}) > 0) {
                                 switch ($fieldRecord->relevance) {
                                     case "High":
                                         if (!in_array($otherRecord, $high, true) && !in_array($otherRecord, $medium, true) && !in_array($otherRecord, $low, true) && !in_array($otherRecord, $userHigh, true) && !in_array($otherRecord, $userMedium, true) && !in_array($otherRecord, $userLow, true)) {
                                             if ($otherRecord->hasAttribute('assignedTo') && $otherRecord->assignedTo == Yii::app()->user->getName()) {
                                                 $userHigh[] = $otherRecord;
                                             } else {
                                                 $high[] = $otherRecord;
                                             }
                                         }
                                         break;
                                     case "Medium":
                                         if (!in_array($otherRecord, $high, true) && !in_array($otherRecord, $medium, true) && !in_array($otherRecord, $low, true) && !in_array($otherRecord, $userHigh, true) && !in_array($otherRecord, $userMedium, true) && !in_array($otherRecord, $userLow, true)) {
                                             if ($otherRecord->hasAttribute('assignedTo') && $otherRecord->assignedTo == Yii::app()->user->getName()) {
                                                 $userMedium[] = $otherRecord;
                                             } else {
                                                 $medium[] = $otherRecord;
                                             }
                                         }
                                         break;
                                     case "Low":
                                         if (!in_array($otherRecord, $high, true) && !in_array($otherRecord, $medium, true) && !in_array($otherRecord, $low, true) && !in_array($otherRecord, $userHigh, true) && !in_array($otherRecord, $userMedium, true) && !in_array($otherRecord, $userLow, true)) {
                                             if ($otherRecord->hasAttribute('assignedTo') && $otherRecord->assignedTo == Yii::app()->user->getName()) {
                                                 $userLow[] = $otherRecord;
                                             } else {
                                                 $low[] = $otherRecord;
                                             }
                                         }
                                         break;
                                     default:
                                         if ($otherRecord->hasAttribute('assignedTo') && $otherRecord->assignedTo == Yii::app()->user->getName()) {
                                             $userLow[] = $otherRecord;
                                         } else {
                                             $low[] = $otherRecord;
                                         }
                                 }
                             } elseif ($fieldRecord->type == 'phone') {
                                 $tempPhone = preg_replace('/\\D/', '', $term);
                                 if (strlen($tempPhone) == 10) {
                                     $phoneLookup = PhoneNumber::model()->findByAttributes(array('modelType' => $fieldRecord->modelName, 'number' => $tempPhone, 'fieldName' => $fieldName));
                                     if (!in_array($otherRecord, $high, true) && !in_array($otherRecord, $medium, true) && !in_array($otherRecord, $low, true) && !in_array($otherRecord, $userHigh, true) && !in_array($otherRecord, $userMedium, true) && !in_array($otherRecord, $userLow, true)) {
                                         if (isset($phoneLookup) && $otherRecord->id == $phoneLookup->modelId) {
                                             if ($otherRecord->hasAttribute('assignedTo') && $otherRecord->assignedTo == Yii::app()->user->getName()) {
                                                 $userHigh[] = $otherRecord;
                                             } else {
                                                 $high[] = $otherRecord;
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
             $records = array_merge($high, $medium);
             $records = array_merge($records, $low);
             $userRecords = array_merge($userHigh, $userMedium);
             $userRecords = array_merge($userRecords, $userLow);
             $records = array_merge($userRecords, $records);
             $records = Record::convert($records, false);
             if (count($records) == 1) {
                 // Only one match, so go straight to it.
                 //
                 // The record's corresponding model class must have
                 // X2LinkableBehavior for this to be possible.
                 if (!empty($records[0]['#recordUrl'])) {
                     $this->redirect($records[0]['#recordUrl']);
                 }
             }
             $dataProvider = new CArrayDataProvider($records, array('id' => 'id', 'pagination' => array('pageSize' => Profile::getResultsPerPage())));
             $this->render('search', array('records' => $records, 'dataProvider' => $dataProvider, 'term' => $term));
         } else {
             Yii::app()->user->setState('vcr-list', $term);
             $_COOKIE['vcr-list'] = $term;
             $tagQuery = "\n                    SELECT * \n                    FROM x2_tags\n                    WHERE tag=:tag\n                    group BY tag, type, itemId";
             $params = array(':tag' => $term);
             // group by type and itemId to prevent display of duplicate tags
             $sql = Yii::app()->db->createCommand($tagQuery);
             $totalItemCount = Yii::app()->db->createCommand("\n                    SELECT count(*)\n                    FROM ({$tagQuery}) as t1;\n                ")->queryScalar($params);
             $results = new CSqlDataProvider($sql, array('totalItemCount' => $totalItemCount, 'sort' => array('defaultOrder' => 'timestamp DESC'), 'pagination' => array('pageSize' => Profile::getResultsPerPage()), 'params' => $params));
             $this->render('searchTags', array('tags' => $results, 'term' => $term));
         }
     }
 }
 /**
  * Tests hidden condition as well as a query inside ApiController that uses the hidden 
  * condition (since action that contains the query cannot be easily tested without a refactor)
  */
 public function testHiddenCondition()
 {
     $contact = $this->contacts('contactGroupmate');
     $number = '2349182348';
     $phoneCrit = new CDbCriteria(array('condition' => "modelType='Contacts' AND number LIKE :number", 'params' => array(':number' => "%{$number}%")));
     $phoneCrit->join = 'join x2_contacts on modelId=x2_contacts.id AND ' . Contacts::model()->getHiddenCondition('x2_contacts');
     $phoneNumber = PhoneNumber::model()->find($phoneCrit);
     $contact->markAsDuplicate();
     $this->assertNull(PhoneNumber::model()->find($phoneCrit));
 }