CRM-15495 - Improve entityRef contact_type filter
[civicrm-core.git] / CRM / Contact / Page / AJAX.php
index 102924e7658689f770df2126481a177f6d895f92..3bb980db4e584fb41c11c9b15c9cf93c29185a6c 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 /*
  +--------------------------------------------------------------------+
- | CiviCRM version 4.5                                                |
+ | CiviCRM version 4.6                                                |
  +--------------------------------------------------------------------+
  | Copyright CiviCRM LLC (c) 2004-2014                                |
  +--------------------------------------------------------------------+
  * This class contains all contact related functions that are called using AJAX (jQuery)
  */
 class CRM_Contact_Page_AJAX {
-  static function getContactList() {
+  /**
+   * When a user chooses a username, CHECK_USERNAME_TTL
+   * is the time window in which they can check usernames
+   * (without reloading the overall form).
+   */
+  const CHECK_USERNAME_TTL = 10800; // 3hr; 3*60*60
+
+  const AUTOCOMPLETE_TTL = 21600; // 6hr; 6*60*60
+
+  /**
+   * @deprecated
+   */
+  public static function getContactList() {
     // if context is 'customfield'
     if (CRM_Utils_Array::value('context', $_GET) == 'customfield') {
       return self::contactReference();
@@ -90,18 +102,23 @@ class CRM_Contact_Page_AJAX {
     CRM_Core_Page_AJAX::autocompleteResults(CRM_Utils_Array::value('values', $result), 'data');
   }
 
-  static function contactReference() {
-    $name = CRM_Utils_Array::value('s', $_GET);
+  /**
+   * Ajax callback for custom fields of type ContactReference
+   *
+   * Todo: Migrate contact reference fields to use EntityRef
+   */
+  public static function contactReference() {
+    $name = CRM_Utils_Array::value('term', $_GET);
     $name = CRM_Utils_Type::escape($name, 'String');
     $cfID = CRM_Utils_Type::escape($_GET['id'], 'Positive');
 
     // check that this is a valid, active custom field of Contact Reference type
-    $params           = array('id' => $cfID);
+    $params = array('id' => $cfID);
     $returnProperties = array('filter', 'data_type', 'is_active');
-    $fldValues = $cf = array();
+    $cf = array();
     CRM_Core_DAO::commonRetrieve('CRM_Core_DAO_CustomField', $params, $cf, $returnProperties);
     if (!$cf['id'] || !$cf['is_active'] || $cf['data_type'] != 'ContactReference') {
-      CRM_Core_Page_AJAX::autocompleteResults(array('error' => $name));
+      CRM_Utils_System::civiExit('error');
     }
 
     if (!empty($cf['filter'])) {
@@ -113,7 +130,7 @@ class CRM_Contact_Page_AJAX {
       if (!empty($action) &&
         !in_array($action, array('get', 'lookup'))
       ) {
-        CRM_Core_Page_AJAX::autocompleteResults(array('error' => $name));
+        CRM_Utils_System::civiExit('error');
       }
     }
 
@@ -123,12 +140,7 @@ class CRM_Contact_Page_AJAX {
 
     $return = array_unique(array_merge(array('sort_name'), $list));
 
-    $config = CRM_Core_Config::singleton();
-
-    $limit = 10;
-    if (!empty($_GET['limit'])) {
-      $limit = CRM_Utils_Type::escape($_GET['limit'], 'Positive');
-    }
+    $limit = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'search_autocomplete_count', NULL, 10);
 
     $params = array('offset' => 0, 'rowCount' => $limit, 'version' => 3);
     foreach ($return as $fld) {
@@ -166,7 +178,7 @@ class CRM_Contact_Page_AJAX {
     $contact = civicrm_api('Contact', 'Get', $params);
 
     if (!empty($contact['is_error'])) {
-      CRM_Core_Page_AJAX::autocompleteResults(array('error' => $name));
+      CRM_Utils_System::civiExit('error');
     }
 
     $contactList = array();
@@ -177,20 +189,16 @@ class CRM_Contact_Page_AJAX {
           $view[] = $value[$fld];
         }
       }
-      $contactList[$value['id']] = implode(' :: ', $view);
-    }
-
-    if (!$contactList) {
-      $contactList = array($name => $name);
+      $contactList[] = array('id' => $value['id'], 'text' => implode(' :: ', $view));
     }
 
-    CRM_Core_Page_AJAX::autocompleteResults($contactList);
+    CRM_Utils_System::civiExit(json_encode($contactList));
   }
 
   /**
-   * Function to fetch PCP ID by PCP Supporter sort_name, also displays PCP title and associated Contribution Page title
+   * Fetch PCP ID by PCP Supporter sort_name, also displays PCP title and associated Contribution Page title
    */
-  static function getPCPList() {
+  public static function getPCPList() {
     $name  = CRM_Utils_Array::value('s', $_GET);
     $name  = CRM_Utils_Type::escape($name, 'String');
     $limit = '10';
@@ -243,11 +251,10 @@ class CRM_Contact_Page_AJAX {
     while ($dao->fetch()) {
       $results[] = array('id' => $dao->id, 'text' => $dao->data);
     }
-    print json_encode($results);
-    CRM_Utils_System::civiExit();
+    CRM_Utils_JSON::output($results);
   }
 
-  static function relationship() {
+  public static function relationship() {
     $relType = CRM_Utils_Request::retrieve('rel_type', 'Positive', CRM_Core_DAO::$_nullObject, TRUE);
     $relContactID = CRM_Utils_Request::retrieve('rel_contact', 'Positive', CRM_Core_DAO::$_nullObject, TRUE);
     $relationshipID = CRM_Utils_Array::value('rel_id', $_REQUEST); // this used only to determine add or update mode
@@ -306,44 +313,23 @@ class CRM_Contact_Page_AJAX {
       }
     }
 
-    echo json_encode($ret);
-    CRM_Utils_System::civiExit();
+    CRM_Utils_JSON::output($ret);
   }
 
   /**
-   * Function to fetch the custom field help
+   * Fetch the custom field help
    */
-  static function customField() {
+  public static function customField() {
     $fieldId          = CRM_Utils_Type::escape($_REQUEST['id'], 'Integer');
     $params           = array('id' => $fieldId);
     $returnProperties = array('help_pre', 'help_post');
     $values           = array();
 
     CRM_Core_DAO::commonRetrieve('CRM_Core_DAO_CustomField', $params, $values, $returnProperties);
-    echo json_encode($values);
-    CRM_Utils_System::civiExit();
+    CRM_Utils_JSON::output($values);
   }
 
-  /**
-   * Function to obtain list of permissioned employer for the given contact-id.
-   */
-  static function getPermissionedEmployer() {
-    $cid  = CRM_Utils_Type::escape($_GET['cid'], 'Integer');
-    $name = trim(CRM_Utils_Type::escape($_GET['s'], 'String'));
-    $name = str_replace('*', '%', $name);
-
-    $elements = CRM_Contact_BAO_Relationship::getPermissionedEmployer($cid, $name);
-    $results = array();
-    if (!empty($elements)) {
-      foreach ($elements as $cid => $name) {
-        $results[$cid] = $name['name'];
-      }
-    }
-    CRM_Core_Page_AJAX::autocompleteResults($results);
-  }
-
-
-  static function groupTree() {
+  public static function groupTree() {
     $gids = CRM_Utils_Type::escape($_GET['gids'], 'String');
     echo CRM_Contact_BAO_GroupNestingCache::json($gids);
     CRM_Utils_System::civiExit();
@@ -354,7 +340,7 @@ class CRM_Contact_Page_AJAX {
    * Old quicksearch function. No longer used in core.
    * @todo: Remove this function and associated menu entry in CiviCRM 5
    */
-  static function search() {
+  public static function search() {
     $json = TRUE;
     $name = CRM_Utils_Array::value('name', $_GET, '');
     if (!array_key_exists('name', $_GET)) {
@@ -532,10 +518,10 @@ ORDER BY sort_name ";
   }
 
   /**
-   * Function to delete custom value
+   * Delete custom value
    *
    */
-  static function deleteCustomValue() {
+  public static function deleteCustomValue() {
     $customValueID = CRM_Utils_Type::escape($_REQUEST['valueID'], 'Positive');
     $customGroupID = CRM_Utils_Type::escape($_REQUEST['groupID'], 'Positive');
 
@@ -551,10 +537,10 @@ ORDER BY sort_name ";
   }
 
   /**
-   * Function to perform enable / disable actions on record.
+   * Perform enable / disable actions on record.
    *
    */
-  static function enableDisable() {
+  public static function enableDisable() {
     $op        = CRM_Utils_Type::escape($_REQUEST['op'], 'String');
     $recordID  = CRM_Utils_Type::escape($_REQUEST['recordID'], 'Positive');
     $recordBAO = CRM_Utils_Type::escape($_REQUEST['recordBAO'], 'String');
@@ -590,16 +576,26 @@ ORDER BY sort_name ";
           CRM_Utils_Hook::enableDisable($recordBAO, $recordID, $isActive);
         }
       }
-      echo json_encode($status);
-      CRM_Utils_System::civiExit();
+      CRM_Utils_JSON::output($status);
     }
   }
 
   /**
-     *Function to check the CMS username
+     *  check the CMS username
      *
     */
   static public function checkUserName() {
+    $signer = new CRM_Utils_Signer(CRM_Core_Key::privateKey(), array('for', 'ts'));
+    if (
+      CRM_Utils_Time::getTimeRaw() > $_REQUEST['ts'] + self::CHECK_USERNAME_TTL
+      || $_REQUEST['for'] != 'civicrm/ajax/cmsuser'
+      || !$signer->validate($_REQUEST['sig'], $_REQUEST)
+    ) {
+      $user = array('name' => 'error');
+      echo json_encode($user);
+      CRM_Utils_System::civiExit();
+    }
+
     $config = CRM_Core_Config::singleton();
     $username = trim($_REQUEST['cms_name']);
 
@@ -624,9 +620,12 @@ ORDER BY sort_name ";
   /**
    *  Function to get email address of a contact
    */
-  static function getContactEmail() {
+  public static function getContactEmail() {
     if (!empty($_REQUEST['contact_id'])) {
       $contactID = CRM_Utils_Type::escape($_REQUEST['contact_id'], 'Positive');
+      if (!CRM_Contact_BAO_Contact_Permission::allow($contactID, CRM_Core_Permission::EDIT)) {
+        return;
+      }
       list($displayName,
         $userEmail
       ) = CRM_Contact_BAO_Contact_Location::getEmailDetails($contactID);
@@ -648,23 +647,22 @@ ORDER BY sort_name ";
         }
       }
       else {
-       $cid = CRM_Utils_Array::value('cid', $_GET);
-       if ($cid) {
+        $cid = CRM_Utils_Array::value('cid', $_GET);
+        if ($cid) {
           //check cid for interger
           $contIDS = explode(',', $cid);
           foreach ($contIDS as $contID) {
             CRM_Utils_Type::escape($contID, 'Integer');
           }
           $queryString = " cc.id IN ( $cid )";
-       }
+        }
       }
 
       if ($queryString) {
         $offset = CRM_Utils_Array::value('offset', $_GET, 0);
-        $rowCount = CRM_Utils_Array::value('rowcount', $_GET, 20);
+        $rowCount = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'search_autocomplete_count', NULL, 10);
 
         $offset = CRM_Utils_Type::escape($offset, 'Int');
-        $rowCount = CRM_Utils_Type::escape($rowCount, 'Int');
 
         // add acl clause here
         list($aclFrom, $aclWhere) = CRM_Contact_BAO_Contact_Permission::cacheClause('cc');
@@ -691,8 +689,8 @@ LIMIT {$offset}, {$rowCount}
           $dao = CRM_Core_DAO::executeQuery($query);
           while ($dao->fetch()) {
             $result[] = array(
-              'name' => $dao->name,
               'id' => $dao->id,
+              'text' => $dao->name,
             );
           }
         }
@@ -717,13 +715,13 @@ LIMIT {$offset}, {$rowCount}
           $dao = CRM_Core_DAO::executeQuery($query);
 
           while ($dao->fetch()) {
+              //working here
             $result[] = array(
-              'name' => '"' . $dao->name . '" &lt;' . $dao->email . '&gt;',
+              'text' => '"' . $dao->name . '" <' . $dao->email . '>',
               'id' => (CRM_Utils_Array::value('id', $_GET)) ? "{$dao->id}::{$dao->email}" : '"' . $dao->name . '" <' . $dao->email . '>',
             );
           }
         }
-
         if ($result) {
           echo json_encode($result);
         }
@@ -732,7 +730,7 @@ LIMIT {$offset}, {$rowCount}
     CRM_Utils_System::civiExit();
   }
 
-  static function getContactPhone() {
+  public static function getContactPhone() {
 
     $queryString = NULL;
     //check for mobile type
@@ -745,8 +743,8 @@ LIMIT {$offset}, {$rowCount}
       $queryString = " ( cc.sort_name LIKE '%$name%' OR cp.phone LIKE '%$name%' ) ";
     }
     else {
-       $cid = CRM_Utils_Array::value('cid', $_GET);
-       if ($cid) {
+      $cid = CRM_Utils_Array::value('cid', $_GET);
+      if ($cid) {
         //check cid for interger
         $contIDS = explode(',', $cid);
         foreach ($contIDS as $contID) {
@@ -789,7 +787,7 @@ LIMIT {$offset}, {$rowCount}
 
       while ($dao->fetch()) {
         $result[] = array(
-          'name' => '"' . $dao->name . '" &lt;' . $dao->phone . '&gt;',
+          'text' => '"' . $dao->name . '" (' . $dao->phone . ')',
           'id' => (CRM_Utils_Array::value('id', $_GET)) ? "{$dao->id}::{$dao->phone}" : '"' . $dao->name . '" <' . $dao->phone . '>',
         );
       }
@@ -802,7 +800,7 @@ LIMIT {$offset}, {$rowCount}
   }
 
 
-  static function buildSubTypes() {
+  public static function buildSubTypes() {
     $parent = CRM_Utils_Array::value('parentId', $_REQUEST);
 
     switch ($parent) {
@@ -821,11 +819,10 @@ LIMIT {$offset}, {$rowCount}
 
     $subTypes = CRM_Contact_BAO_ContactType::subTypePairs($contactType, FALSE, NULL);
     asort($subTypes);
-    echo json_encode($subTypes);
-    CRM_Utils_System::civiExit();
+    CRM_Utils_JSON::output($subTypes);
   }
 
-  static function buildDedupeRules() {
+  public static function buildDedupeRules() {
     $parent = CRM_Utils_Array::value('parentId', $_REQUEST);
 
     switch ($parent) {
@@ -844,14 +841,13 @@ LIMIT {$offset}, {$rowCount}
 
     $dedupeRules = CRM_Dedupe_BAO_RuleGroup::getByType($contactType);
 
-    echo json_encode($dedupeRules);
-    CRM_Utils_System::civiExit();
+    CRM_Utils_JSON::output($dedupeRules);
   }
 
   /**
    * Function used for CiviCRM dashboard operations
    */
-  static function dashboard() {
+  public static function dashboard() {
     $operation = CRM_Utils_Type::escape($_REQUEST['op'], 'String');
 
     switch ($operation) {
@@ -877,14 +873,13 @@ LIMIT {$offset}, {$rowCount}
         CRM_Utils_System::civiExit();
     }
 
-    echo json_encode($dashlets);
-    CRM_Utils_System::civiExit();
+    CRM_Utils_JSON::output($dashlets);
   }
 
   /**
-   * Function to retrieve signature based on email id
+   * Retrieve signature based on email id
    */
-  static function getSignature() {
+  public static function getSignature() {
     $emailID = CRM_Utils_Type::escape($_REQUEST['emailID'], 'Positive');
     $query   = "SELECT signature_text, signature_html FROM civicrm_email WHERE id = {$emailID}";
     $dao     = CRM_Core_DAO::executeQuery($query);
@@ -897,15 +892,14 @@ LIMIT {$offset}, {$rowCount}
       );
     }
 
-    echo json_encode($signatures);
-    CRM_Utils_System::civiExit();
+    CRM_Utils_JSON::output($signatures);
   }
 
   /**
-   * Function to process dupes.
+   * Process dupes.
    *
    */
-  static function processDupes() {
+  public static function processDupes() {
     $oper = CRM_Utils_Type::escape($_REQUEST['op'], 'String');
     $cid  = CRM_Utils_Type::escape($_REQUEST['cid'], 'Positive');
     $oid  = CRM_Utils_Type::escape($_REQUEST['oid'], 'Positive');
@@ -931,11 +925,10 @@ LIMIT {$offset}, {$rowCount}
       $status = $exception->delete();
     }
 
-    echo json_encode(array('status' => ($status) ? $oper : $status));
-    CRM_Utils_System::civiExit();
+    CRM_Utils_JSON::output(array('status' => ($status) ? $oper : $status));
   }
 
-  static function getDedupes() {
+  public static function getDedupes() {
 
     $sEcho     = CRM_Utils_Type::escape($_REQUEST['sEcho'], 'Integer');
     $offset    = isset($_REQUEST['iDisplayStart']) ? CRM_Utils_Type::escape($_REQUEST['iDisplayStart'], 'Integer') : 0;
@@ -987,30 +980,28 @@ LIMIT {$offset}, {$rowCount}
   }
 
   /**
-   * Function to retrieve a PDF Page Format for the PDF Letter form
+   * Retrieve a PDF Page Format for the PDF Letter form
    */
-  function pdfFormat() {
+  public function pdfFormat() {
     $formatId = CRM_Utils_Type::escape($_REQUEST['formatId'], 'Integer');
 
     $pdfFormat = CRM_Core_BAO_PdfFormat::getById($formatId);
 
-    echo json_encode($pdfFormat);
-    CRM_Utils_System::civiExit();
+    CRM_Utils_JSON::output($pdfFormat);
   }
 
   /**
-   * Function to retrieve Paper Size dimensions
+   * Retrieve Paper Size dimensions
    */
-  static function paperSize() {
+  public static function paperSize() {
     $paperSizeName = CRM_Utils_Type::escape($_REQUEST['paperSizeName'], 'String');
 
     $paperSize = CRM_Core_BAO_PaperSize::getByName($paperSizeName);
 
-    echo json_encode($paperSize);
-    CRM_Utils_System::civiExit();
+    CRM_Utils_JSON::output($paperSize);
   }
 
-  static function selectUnselectContacts() {
+  public static function selectUnselectContacts() {
     $name         = CRM_Utils_Array::value('name', $_REQUEST);
     $cacheKey     = CRM_Utils_Array::value('qfKey', $_REQUEST);
     $state        = CRM_Utils_Array::value('state', $_REQUEST, 'checked');
@@ -1041,18 +1032,22 @@ LIMIT {$offset}, {$rowCount}
     $countSelectionCids = count($contactIds[$cacheKey]);
 
     $arrRet = array('getCount' => $countSelectionCids);
-    echo json_encode($arrRet);
-    CRM_Utils_System::civiExit();
+    CRM_Utils_JSON::output($arrRet);
   }
 
-  static function _convertToId($name) {
+  /**
+   * @param string $name
+   *
+   * @return string
+   */
+  public static function _convertToId($name) {
     if (substr($name, 0, CRM_Core_Form::CB_PREFIX_LEN) == CRM_Core_Form::CB_PREFIX) {
       $cId = substr($name, CRM_Core_Form::CB_PREFIX_LEN);
     }
     return $cId;
   }
 
-  static function getAddressDisplay() {
+  public static function getAddressDisplay() {
     $contactId = CRM_Utils_Array::value('contact_id', $_REQUEST);
     if (!$contactId) {
       $addressVal["error_message"] = "no contact id found";
@@ -1066,12 +1061,11 @@ LIMIT {$offset}, {$rowCount}
       $addressVal = CRM_Core_BAO_Address::getValues($entityBlock);
     }
 
-    echo json_encode($addressVal);
-    CRM_Utils_System::civiExit();
+    CRM_Utils_JSON::output($addressVal);
   }
 
   /**
-   * Function to retrieve contact relationships
+   * Retrieve contact relationships
    */
   public static function getContactRelationships() {
     $contactID = CRM_Utils_Type::escape($_GET['cid'], 'Integer');