Merge pull request #6458 from totten/4.6-toxic-list
[civicrm-core.git] / CRM / Contact / BAO / GroupContactCache.php
index dabeebe47cbcb8c7a4fb4ec058c660b37124fdbb..ba013e276dedb5c1ecd4d549c1ea9ebb8f59cd77 100644 (file)
@@ -3,7 +3,7 @@
  +--------------------------------------------------------------------+
  | CiviCRM version 4.6                                                |
  +--------------------------------------------------------------------+
- | Copyright CiviCRM LLC (c) 2004-2014                                |
+ | Copyright CiviCRM LLC (c) 2004-2015                                |
  +--------------------------------------------------------------------+
  | This file is a part of CiviCRM.                                    |
  |                                                                    |
  | GNU Affero General Public License or the licensing of CiviCRM,     |
  | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
  +--------------------------------------------------------------------+
-*/
+ */
 
 /**
  *
  * @package CRM
- * @copyright CiviCRM LLC (c) 2004-2014
+ * @copyright CiviCRM LLC (c) 2004-2015
  * $Id$
  *
  */
@@ -43,7 +43,7 @@ class CRM_Contact_BAO_GroupContactCache extends CRM_Contact_DAO_GroupContactCach
    * @param $groupIDs
    *   Of group that we are checking against.
    *
-   * @return boolean
+   * @return bool
    *   TRUE if we did not regenerate, FALSE if we did
    */
   public static function check($groupIDs) {
@@ -65,7 +65,6 @@ class CRM_Contact_BAO_GroupContactCache extends CRM_Contact_DAO_GroupContactCach
    *
    * @return string
    *   the sql query which lists the groups that need to be refreshed
-   * @static
    */
   public static function groupRefreshedClause($groupIDClause = NULL, $includeHiddenGroups = FALSE) {
     $smartGroupCacheTimeout = self::smartGroupCacheTimeout();
@@ -105,7 +104,6 @@ AND     ( g.cache_date IS NULL OR
    *
    * @return string
    *   the sql query which lists the groups that need to be refreshed
-   * @static
    */
   public static function shouldGroupBeRefreshed($groupID, $includeHiddenGroups = FALSE) {
     $query = self::groupRefreshedClause("g.id = %1", $includeHiddenGroups);
@@ -119,12 +117,12 @@ AND     ( g.cache_date IS NULL OR
    * Check to see if we have cache entries for this group
    * if not, regenerate, else return
    *
-   * @param int/array $groupID groupID of group that we are checking against
+   * @param int /array $groupIDs groupIDs of group that we are checking against
    *                           if empty, all groups are checked
    * @param int $limit
    *   Limits the number of groups we evaluate.
    *
-   * @return boolean
+   * @return bool
    *   TRUE if we did not regenerate, FALSE if we did
    */
   public static function loadAll($groupIDs = NULL, $limit = 0) {
@@ -177,7 +175,7 @@ AND     ( g.cache_date IS NULL OR
 
     if (!empty($refreshGroupIDs)) {
       $refreshGroupIDString = CRM_Core_DAO::escapeString(implode(', ', $refreshGroupIDs));
-      $time  = CRM_Utils_Date::getUTCTime(self::smartGroupCacheTimeout() * 60);
+      $time = CRM_Utils_Date::getUTCTime(self::smartGroupCacheTimeout() * 60);
       $query = "
 UPDATE civicrm_group g
 SET    g.refresh_date = $time
@@ -237,16 +235,16 @@ AND    g.refresh_date IS NULL
     // to avoid long strings, lets do BULK_INSERT_COUNT values at a time
     while (!empty($values)) {
       $processed = TRUE;
-      $input     = array_splice($values, 0, CRM_Core_DAO::BULK_INSERT_COUNT);
-      $str       = implode(',', $input);
-      $sql       = "INSERT IGNORE INTO civicrm_group_contact_cache (group_id,contact_id) VALUES $str;";
+      $input = array_splice($values, 0, CRM_Core_DAO::BULK_INSERT_COUNT);
+      $str = implode(',', $input);
+      $sql = "INSERT IGNORE INTO civicrm_group_contact_cache (group_id,contact_id) VALUES $str;";
       CRM_Core_DAO::executeQuery($sql);
     }
     self::updateCacheTime($groupID, $processed);
   }
 
   /**
-   * Change the cache_date
+   * Change the cache_date.
    *
    * @param array $groupID
    * @param bool $processed
@@ -257,11 +255,11 @@ AND    g.refresh_date IS NULL
     if ($processed) {
       // also update the group with cache date information
       //make sure to give original timezone settings again.
-      $now     = CRM_Utils_Date::getUTCTime();
+      $now = CRM_Utils_Date::getUTCTime();
       $refresh = 'null';
     }
     else {
-      $now     = 'null';
+      $now = 'null';
       $refresh = 'null';
     }
 
@@ -275,7 +273,7 @@ WHERE  id IN ( $groupIDs )
   }
 
   /**
-   * Removes all the cache entries pertaining to a specific group
+   * Removes all the cache entries pertaining to a specific group.
    * If no groupID is passed in, removes cache entries for all groups
    * Has an optimization to bypass repeated invocations of this function.
    * Note that this function is an advisory, i.e. the removal respects the
@@ -288,7 +286,6 @@ WHERE  id IN ( $groupIDs )
    *   run the function exactly once for all groups.
    *
    * @return void
-   * @static
    */
   public static function remove($groupID = NULL, $onceOnly = TRUE) {
     static $invoked = FALSE;
@@ -319,10 +316,10 @@ WHERE  id IN ( $groupIDs )
     }
 
     $refresh = NULL;
-    $params  = array();
+    $params = array();
     $smartGroupCacheTimeout = self::smartGroupCacheTimeout();
 
-    $now         = CRM_Utils_Date::getUTCTime();
+    $now = CRM_Utils_Date::getUTCTime();
     $refreshTime = CRM_Utils_Date::getUTCTime($smartGroupCacheTimeout * 60);
 
     if (!isset($groupID)) {
@@ -397,7 +394,7 @@ WHERE  id = %1
   }
 
   /**
-   * Removes one or more contacts from the smart group cache
+   * Removes one or more contacts from the smart group cache.
    * @param int|array $cid
    * @param int $groupId
    * @return bool
@@ -422,7 +419,7 @@ WHERE  id = %1
   }
 
   /**
-   * Load the smart group cache for a saved search
+   * Load the smart group cache for a saved search.
    *
    * @param object $group
    *   The smart group that needs to be loaded.
@@ -437,8 +434,7 @@ WHERE  id = %1
     }
 
     // grab a lock so other processes dont compete and do the same query
-    $lockName = "civicrm.group.{$groupID}";
-    $lock = new CRM_Core_Lock($lockName);
+    $lock = Civi\Core\Container::singleton()->get('lockManager')->acquire("data.core.group.{$groupID}");
     if (!$lock->isAcquired()) {
       // this can cause inconsistent results since we dont know if the other process
       // will fill up the cache before our calling routine needs it.
@@ -459,8 +455,8 @@ WHERE  id = %1
       return;
     }
 
-    $sql         = NULL;
-    $idName      = 'id';
+    $sql = NULL;
+    $idName = 'id';
     $customClass = NULL;
     if ($savedSearchID) {
       $ssParams = CRM_Contact_BAO_SavedSearch::getSearchParams($savedSearchID);
@@ -471,7 +467,6 @@ WHERE  id = %1
         CRM_Contact_BAO_ProximityQuery::fixInputParams($ssParams);
       }
 
-
       $returnProperties = array();
       if (CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_SavedSearch', $savedSearchID, 'mapping_id')) {
         $fv = CRM_Contact_BAO_SavedSearch::getFormValues($savedSearchID);
@@ -484,35 +479,37 @@ WHERE  id = %1
         // we split it up and store custom class
         // so temp tables are not destroyed if they are used
         // hence customClass is defined above at top of function
-        $customClass =
-          CRM_Contact_BAO_SearchCustom::customClass($ssParams['customSearchID'], $savedSearchID);
+        $customClass = CRM_Contact_BAO_SearchCustom::customClass($ssParams['customSearchID'], $savedSearchID);
         $searchSQL = $customClass->contactIDs();
         $searchSQL = str_replace('ORDER BY contact_a.id ASC', '', $searchSQL);
+        if (!strstr($searchSQL, 'WHERE')) {
+          $searchSQL .= " WHERE ( 1 ) ";
+        }
         $idName = 'contact_id';
       }
       else {
         $formValues = CRM_Contact_BAO_SavedSearch::getFormValues($savedSearchID);
 
-        $query =
-          new CRM_Contact_BAO_Query(
+        $query
+          new CRM_Contact_BAO_Query(
             $ssParams, $returnProperties, NULL,
             FALSE, FALSE, 1,
             TRUE, TRUE,
             FALSE,
             CRM_Utils_Array::value('display_relationship_type', $formValues),
             CRM_Utils_Array::value('operator', $formValues, 'AND')
-        );
+          );
         $query->_useDistinct = FALSE;
-        $query->_useGroupBy  = FALSE;
-        $searchSQL           =
-          $query->searchQuery(
+        $query->_useGroupBy = FALSE;
+        $searchSQL
+          $query->searchQuery(
             0, 0, NULL,
-          FALSE, FALSE,
-          FALSE, TRUE,
-          TRUE,
-          NULL, NULL, NULL,
-          TRUE
-        );
+            FALSE, FALSE,
+            FALSE, TRUE,
+            TRUE,
+            NULL, NULL, NULL,
+            TRUE
+          );
       }
       $groupID = CRM_Utils_Type::escape($groupID, 'Integer');
       $sql = $searchSQL . " AND contact_a.id NOT IN (
@@ -536,7 +533,7 @@ WHERE  civicrm_group_contact.status = 'Added'
     $groupIDs = array($groupID);
     self::remove($groupIDs);
     $processed = FALSE;
-    $tempTable = 'civicrm_temp_group_contact_cache' . rand(0,2000);
+    $tempTable = 'civicrm_temp_group_contact_cache' . rand(0, 2000);
     foreach (array($sql, $sqlB) as $selectSql) {
       if (!$selectSql) {
         continue;
@@ -548,7 +545,7 @@ WHERE  civicrm_group_contact.status = 'Added'
         "INSERT IGNORE INTO civicrm_group_contact_cache (contact_id, group_id)
         SELECT DISTINCT $idName, group_id FROM $tempTable
       ");
-      CRM_Core_DAO::executeQuery(" DROP TABLE $tempTable");
+      CRM_Core_DAO::executeQuery(" DROP TEMPORARY TABLE $tempTable");
     }
 
     self::updateCacheTime($groupIDs, $processed);
@@ -595,7 +592,8 @@ AND  civicrm_group_contact.group_id = $groupID ";
     if (
       isset($config->smartGroupCacheTimeout) &&
       is_numeric($config->smartGroupCacheTimeout) &&
-      $config->smartGroupCacheTimeout > 0) {
+      $config->smartGroupCacheTimeout > 0
+    ) {
       return $config->smartGroupCacheTimeout;
     }
 
@@ -604,7 +602,7 @@ AND  civicrm_group_contact.group_id = $groupID ";
   }
 
   /**
-   * Get all the smart groups that this contact belongs to
+   * Get all the smart groups that this contact belongs to.
    * Note that this could potentially be a super slow function since
    * it ensure that all contact groups are loaded in the cache
    *
@@ -617,7 +615,7 @@ AND  civicrm_group_contact.group_id = $groupID ";
    */
   public static function contactGroup($contactID, $showHidden = FALSE) {
     if (empty($contactID)) {
-      return;
+      return NULL;
     }
 
     if (is_array($contactID)) {
@@ -656,12 +654,12 @@ ORDER BY   gc.contact_id, g.children
       }
       $prevContactID = $dao->contact_id;
       if (!array_key_exists($dao->contact_id, $contactGroup)) {
-        $contactGroup[$dao->contact_id] =
-          array('group' => array(), 'groupTitle' => array());
+        $contactGroup[$dao->contact_id]
+          array('group' => array(), 'groupTitle' => array());
       }
 
-      $contactGroup[$dao->contact_id]['group'][] =
-        array(
+      $contactGroup[$dao->contact_id]['group'][]
+        array(
           'id' => $dao->group_id,
           'title' => $dao->title,
           'description' => $dao->description,