Merge remote-tracking branch 'upstream/4.3' into 4.3-master-2013-07-31-15-53-16
[civicrm-core.git] / CRM / Contact / BAO / Query.php
index 9d510df582867e93408ddc51b15e7d491a47f3b1..e57b2a8eab0c6e7989bad015577472424f5f4847 100644 (file)
@@ -578,12 +578,10 @@ class CRM_Contact_BAO_Query {
    * @access public
    */
   function selectClause() {
-    $properties = array();
 
     $this->addSpecialFields();
 
     foreach ($this->_fields as $name => $field) {
-
       // skip component fields
       // there are done by the alter query below
       // and need not be done on every field
@@ -607,10 +605,32 @@ class CRM_Contact_BAO_Query {
         continue;
       }
 
+      // make an exception for special cases, to add the field in select clause
+      $makeException = FALSE;
+
+      //special handling for groups/tags
+      if (in_array($name, array('groups', 'tags', 'notes'))
+        && isset($this->_returnProperties[substr($name, 0, -1)])
+      ) {
+        $makeException = TRUE;
+      }
+
+      // since note has 3 different options we need special handling
+      // note / note_subject / note_body
+      if ($name == 'notes') {
+        foreach (array('note', 'note_subject', 'note_body') as $noteField) {
+          if (isset($this->_returnProperties[$noteField])) {
+            $makeException = TRUE;
+            break;
+          }
+        }
+      }
+
       $cfID = CRM_Core_BAO_CustomField::getKeyID($name);
       if (
         CRM_Utils_Array::value($name, $this->_paramLookup) ||
-        CRM_Utils_Array::value($name, $this->_returnProperties)
+        CRM_Utils_Array::value($name, $this->_returnProperties) ||
+        $makeException
       ) {
         if ($cfID) {
           // add to cfIDs array if not present
@@ -1211,13 +1231,12 @@ class CRM_Contact_BAO_Query {
       $this->filterRelatedContacts($from, $where, $having);
     }
 
-    // CRM_Core_Error::debug($this);
     return array($select, $from, $where, $having);
   }
 
   function &getWhereValues($name, $grouping) {
     $result = NULL;
-    foreach ($this->_params as $id => $values) {
+    foreach ($this->_params as $values) {
       if ($values[0] == $name && $values[3] == $grouping) {
         return $values;
       }
@@ -3507,7 +3526,7 @@ WHERE  id IN ( $groupIDs )
       $this->_qill[$grouping][] = ts('State/Province') . " $op " . implode(' ' . ts('or') . ' ', $names) . $countryQill;
     }
     else {
-      return implode(' ' . ts('or') . ' ', $names) . $countryQill;;
+      return implode(' ' . ts('or') . ' ', $names) . $countryQill;
     }
   }
 
@@ -3590,10 +3609,8 @@ WHERE  id IN ( $groupIDs )
   function privacyOptions($values) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
 
-    if (empty($value) ||
-      !is_array($value)
-    ) {
-      continue;
+    if (empty($value) || !is_array($value)) {
+      return;
     }
 
     // get the operator and toggle values
@@ -4032,13 +4049,9 @@ civicrm_relationship.start_date > {$today}
       $this->_whereClause = $this->whereClause();
     }
 
-    // hack for now, add permission only if we are in search
-    // FIXME: we should actually filter out deleted contacts (unless requested to do the opposite)
-    $permission = ' ( 1 ) ';
-    $onlyDeleted = FALSE;
     $onlyDeleted = in_array(array('deleted_contacts', '=', '1', '0', '0'), $this->_params);
 
-    // if we’re explicitely looking for a certain contact’s contribs, events, etc.
+    // if we’re explicitly looking for a certain contact’s contribs, events, etc.
     // and that contact happens to be deleted, set $onlyDeleted to true
     foreach ($this->_params as $values) {
       $name = CRM_Utils_Array::value(0, $values);
@@ -4053,13 +4066,6 @@ civicrm_relationship.start_date > {$today}
     }
     $this->generatePermissionClause($onlyDeleted, $count);
 
-    list($select, $from, $where, $having) = $this->query($count, $sortByChar, $groupContacts);
-
-    //additional from clause should be w/ proper joins.
-    if ($additionalFromClause) {
-      $from .= "\n" . $additionalFromClause;
-    }
-
     if (empty($where)) {
       $where = "WHERE $this->_permissionWhereClause";
     }
@@ -4126,7 +4132,6 @@ civicrm_relationship.start_date > {$today}
         }
       }
 
-      $doOpt = TRUE;
       // hack for order clause
       if ($order) {
         $fieldStr = trim(str_replace('ORDER BY', '', $order));
@@ -4157,72 +4162,22 @@ civicrm_relationship.start_date > {$today}
               $this->_whereTables["civicrm_email"] = 1;
               $order = str_replace($field, "civicrm_email.{$field}", $order);
               break;
-
-            default:
-              $doOpt = FALSE;
           }
+          $this->_fromClause = self::fromClause($this->_tables, NULL, NULL, $this->_primaryLocation, $this->_mode);
+          $this->_simpleFromClause = self::fromClause($this->_whereTables, NULL, NULL, $this->_primaryLocation, $this->_mode);
         }
       }
 
-
       if ($rowCount > 0 && $offset >= 0) {
         $limit = " LIMIT $offset, $rowCount ";
+      }
+    }
 
-        // ok here is a first hack at an optimization, lets get all the contact ids
-        // that are restricted and we'll then do the final clause with it
-        // CRM-5954
-        if (isset($this->_distinctComponentClause)) {
-          if (strpos($this->_distinctComponentClause, 'DISTINCT') == FALSE) {
-            $limitSelect = "SELECT DISTINCT {$this->_distinctComponentClause}";
-          }
-          else {
-            $limitSelect = "SELECT {$this->_distinctComponentClause}";
-          }
-        }
-        else {
-          $limitSelect = 'SELECT DISTINCT contact_a.id as id';
-        }
-
-        if ($doOpt) {
-          $this->_simpleFromClause = self::fromClause($this->_whereTables, NULL, NULL,
-            $this->_primaryLocation, $this->_mode
-          );
-
-          if ($additionalFromClause) {
-            $this->_simpleFromClause .= "\n" . $additionalFromClause;
-          }
-          // if we are doing a transform, do it here
-          // CRM-7969
-          $having = NULL;
-          if ($this->_displayRelationshipType) {
-            $this->filterRelatedContacts($this->_simpleFromClause, $where, $having);
-          }
+    list($select, $from, $where, $having) = $this->query($count, $sortByChar, $groupContacts);
 
-          $limitQuery = "$limitSelect {$this->_simpleFromClause} $where $groupBy $order $limit";
-          $limitDAO = CRM_Core_DAO::executeQuery($limitQuery);
-          $limitIDs = array();
-          while ($limitDAO->fetch()) {
-            if ($limitDAO->id) {
-              $limitIDs[] = $limitDAO->id;
-            }
-          }
-          if (empty($limitIDs)) {
-            $limitClause = ' AND ( 0 ) ';
-          }
-          else {
-            if (isset($this->_distinctComponentClause)) {
-              $limitClause = " AND {$this->_distinctComponentClause} IN ( ";
-            }
-            else {
-              $limitClause = ' AND contact_a.id IN ( ';
-            }
-            $limitClause .= implode(',', $limitIDs) . ' ) ';
-          }
-          $where .= $limitClause;
-          // reset limit clause since we already restrict what records we want
-          $limit = NULL;
-        }
-      }
+    //additional from clause should be w/ proper joins.
+    if ($additionalFromClause) {
+      $from .= "\n" . $additionalFromClause;
     }
 
     // if we are doing a transform, do it here
@@ -4246,8 +4201,6 @@ civicrm_relationship.start_date > {$today}
       return CRM_Core_DAO::singleValueQuery($query);
     }
 
-    // crm_core_error::debug('$query', $query); exit;
-
     $dao = CRM_Core_DAO::executeQuery($query);
     if ($groupContacts) {
       $ids = array();
@@ -4260,6 +4213,26 @@ civicrm_relationship.start_date > {$today}
     return $dao;
   }
 
+  /**
+   * Fetch a list of contacts from the prev/next cache for displaying a search results page
+   *
+   * @param string $cacheKey
+   * @param int    $offset
+   * @param int    $rowCount
+   * @param bool   $includeContactIds
+   * @return CRM_Core_DAO
+   */
+  function getCachedContacts($cacheKey, $offset, $rowCount, $includeContactIds) {
+    $this->_includeContactIds = $includeContactIds;
+    list($select, $from) = $this->query();
+    $from = " FROM civicrm_prevnext_cache pnc INNER JOIN civicrm_contact contact_a ON contact_a.id = pnc.entity_id1 AND pnc.cacheKey = '$cacheKey' " . substr($from, 31);
+    $order = " ORDER BY pnc.id";
+    $groupBy = " GROUP BY contact_a.id";
+    $limit = " LIMIT $offset, $rowCount";
+    $query = "$select $from $groupBy $order $limit";
+    return CRM_Core_DAO::executeQuery($query);
+  }
+
   /**
    * Populate $this->_permissionWhereClause with permission related clause and update other
    * query related properties.