fix created_date/modified_date relative date filter searches
authorJon Goldberg <jon@megaphonetech.com>
Mon, 13 Jan 2020 22:52:22 +0000 (17:52 -0500)
committerJon Goldberg <jon@megaphonetech.com>
Mon, 13 Jan 2020 23:48:59 +0000 (18:48 -0500)
CRM/Contact/BAO/Query.php
tests/phpunit/CRM/Contact/BAO/QueryTest.php

index f0eaf258842d7086fa320175df92d1bb6c810dc2..a5c0b434d3aad5fa7aa22520b35dcba49ada29ef 100644 (file)
@@ -7066,6 +7066,14 @@ AND   displayRelType.is_active = 1
     $dates = CRM_Utils_Date::getFromTo($value, NULL, NULL);
     // Where end would be populated only if we are handling one of the weird ones with different from & to fields.
     $secondWhere = $fieldSpec['where_end'] ?? $fieldSpec['where'];
+
+    $where = $fieldSpec['where'];
+    if ($fieldSpec['table_name'] === 'civicrm_contact') {
+      // Special handling for contact table as it has a known alias in advanced search.
+      $where = str_replace('civicrm_contact.', 'contact_a.', $where);
+      $secondWhere = str_replace('civicrm_contact.', 'contact_a.', $secondWhere);
+    }
+
     if (empty($dates[0])) {
       // ie. no start date we only have end date
       $this->_where[$grouping][] = $secondWhere . " <= '{$dates[1]}'";
@@ -7077,7 +7085,7 @@ AND   displayRelType.is_active = 1
     elseif (empty($dates[1])) {
 
       // ie. no end date we only have start date
-      $this->_where[$grouping][] = $fieldSpec['where'] . " >= '{$dates[1]}'";
+      $this->_where[$grouping][] = $where . " >= '{$dates[0]}'";
 
       $this->_qill[$grouping][] = ts('%1 is ', [$fieldSpec['title']]) . $filters[$value] . ' (' . ts("from %1", [
         CRM_Utils_Date::customFormat($dates[0]),
@@ -7085,13 +7093,8 @@ AND   displayRelType.is_active = 1
     }
     else {
       // we have start and end dates.
-      $where = $fieldSpec['where'];
-      if ($fieldSpec['table_name'] === 'civicrm_contact') {
-        // Special handling for contact table as it has a known alias in advanced search.
-        $where = str_replace('civicrm_contact.', 'contact_a.', $where);
-      }
-      if ($secondWhere !== $fieldSpec['where']) {
-        $this->_where[$grouping][] = $fieldSpec['where'] . ">=  '{$dates[0]}' AND $secondWhere <='{$dates[1]}'";
+      if ($secondWhere !== $where) {
+        $this->_where[$grouping][] = $where . ">=  '{$dates[0]}' AND $secondWhere <='{$dates[1]}'";
       }
       else {
         $this->_where[$grouping][] = $where . " BETWEEN '{$dates[0]}' AND '{$dates[1]}'";
index f70937de060383ade42d5816644159fcfab697a0..00b2c6c708dda2d3176628771a05a677a03f73f2 100644 (file)
@@ -1067,6 +1067,35 @@ civicrm_relationship.is_active = 1 AND
     $this->disableFinancialACLs();
   }
 
+  /**
+   * Test relative date filters to ensure they generate correct SQL.
+   *
+   * @dataProvider relativeDateFilters
+   */
+  public function testRelativeDateFilters($filter, $expectedWhere) {
+    $params = [['created_date_relative', '=', $filter, 0, 0]];
+
+    $dates = CRM_Utils_Date::getFromTo($filter, NULL, NULL);
+    $expectedWhere = str_replace(['date0', 'date1'], [$dates[0], $dates[1]], $expectedWhere);
+
+    $query = new CRM_Contact_BAO_Query(
+      $params, [],
+      NULL, TRUE, FALSE, 1,
+      TRUE,
+      TRUE, FALSE
+    );
+
+    list($select, $from, $where, $having) = $query->query();
+    $this->assertEquals($expectedWhere, $where);
+  }
+
+  public function relativeDateFilters() {
+    $dataProvider[] = ['this.year', "WHERE  ( contact_a.created_date BETWEEN 'date0' AND 'date1' )  AND (contact_a.is_deleted = 0)"];
+    $dataProvider[] = ['greater.day', "WHERE  ( contact_a.created_date >= 'date0' )  AND (contact_a.is_deleted = 0)"];
+    $dataProvider[] = ['earlier.week', "WHERE  ( contact_a.created_date <= 'date1' )  AND (contact_a.is_deleted = 0)"];
+    return $dataProvider;
+  }
+
   /**
    * Create contributions to test summary calculations.
    *