Further join tests & fixes
authoreileen <emcnaughton@wikimedia.org>
Mon, 4 Nov 2019 06:08:17 +0000 (19:08 +1300)
committereileen <emcnaughton@wikimedia.org>
Mon, 4 Nov 2019 10:08:18 +0000 (23:08 +1300)
Turns out the carefully constructed join was being whomped - but only sometimes

CRM/Contact/BAO/Query.php
tests/phpunit/CRM/Core/BAO/CustomFieldTest.php
tests/phpunit/CRM/Core/BAO/CustomQueryTest.php

index 777d09d4c9856fe58b58d28fb9d0ecd75f8f00bd..bc127ac765b17489605ffed99896e6854dcf9c86 100644 (file)
@@ -5298,7 +5298,10 @@ civicrm_relationship.start_date > {$today}
   ) {
     // @todo - remove dateFormat - pretty sure it's never passed in...
     list($name, $op, $value, $grouping, $wildcard) = $values;
-
+    if ($name !== $fieldName && $name !== "{$fieldName}_low" && $name !== "{$fieldName}_high") {
+      CRM_Core_Error::deprecatedFunctionWarning('Date query builder called unexpectedly');
+      return;
+    }
     if ($tableName === 'civicrm_contact') {
       // Special handling for contact table as it has a known alias in advanced search.
       $tableName = 'contact_a';
@@ -5360,7 +5363,6 @@ civicrm_relationship.start_date > {$today}
         $secondDateFormat = CRM_Utils_Date::customFormat($secondDate);
       }
 
-      $this->_tables[$tableName] = $this->_whereTables[$tableName] = 1;
       if ($secondDate) {
         $highDBFieldName = $highDBFieldName ?? $dbFieldName;
         $this->_where[$grouping][] = "
@@ -5411,11 +5413,13 @@ civicrm_relationship.start_date > {$today}
         $this->_where[$grouping][] = self::buildClause("{$tableName}.{$dbFieldName}", $op);
       }
 
-      $this->_tables[$tableName] = $this->_whereTables[$tableName] = 1;
-
       $op = CRM_Utils_Array::value($op, CRM_Core_SelectValues::getSearchBuilderOperators(), $op);
       $this->_qill[$grouping][] = "$fieldTitle $op $format";
     }
+
+    // Ensure the tables are set, but don't whomp anything.
+    $this->_tables[$tableName] = $this->_tables[$tableName] ?? 1;
+    $this->_whereTables[$tableName] = $this->_whereTables[$tableName] ?? 1;
   }
 
   /**
index c11ad96b5b94ab95d74659da21c4f58c2380dd78..0b97de581618dc9647b857eed5f09db10a4d32d9 100644 (file)
@@ -578,7 +578,7 @@ class CRM_Core_BAO_CustomFieldTest extends CiviUnitTestCase {
       $this->getCustomFieldName('select_date') => [
         'name' => $this->getCustomFieldName('select_date'),
         'type' => 4,
-        'title' => 'test_date',
+        'title' => 'Test Date',
         'headerPattern' => '//',
         'import' => 1,
         'custom_field_id' => $this->getCustomFieldID('select_date'),
@@ -590,7 +590,7 @@ class CRM_Core_BAO_CustomFieldTest extends CiviUnitTestCase {
         'date_format' => 'mm/dd/yy',
         'time_format' => '1',
         'id' => $this->getCustomFieldID('select_date'),
-        'label' => 'test_date',
+        'label' => 'Test Date',
         'groupTitle' => 'Custom Group',
         'default_value' => '20090711',
         'custom_group_id' => $customGroupID,
index 15b93fcb19af7de445c33e0dcc59cbff5e1fa753..32e62037e4c119793a907b3de3226ce752acd90d 100644 (file)
@@ -121,6 +121,43 @@ class CRM_Core_BAO_CustomQueryTest extends CiviUnitTestCase {
     $this->assertEquals('LEFT JOIN ' . $this->getCustomGroupTable() . ' ON ' . $this->getCustomGroupTable() . '.entity_id = `contact_a`.id', trim($queryObject->_whereTables[$this->getCustomGroupTable()]));
   }
 
+  /**
+   * Test filtering by the renamed custom date fields.
+   *
+   * The conversion to date picker will result int these fields
+   * being renamed _high & _low and needing to return correctly.
+   *
+   * @throws \CRM_Core_Exception
+   */
+  public function testSearchCustomDataDateLowWithPermsInPlay() {
+    $this->createLoggedInUser();
+    CRM_Core_Config::singleton()->userPermissionClass->permissions = ['view all contacts', 'access all custom data'];
+    $this->createCustomGroupWithFieldOfType([], 'date');
+    $dateCustomFieldName = $this->getCustomFieldName('date');
+    // Assigning the relevant form value to be within a custom key is normally done in
+    // build field params. It would be better if it were all done in convertFormValues
+    // but for now we just imitate it.
+    $formValues = [
+      $dateCustomFieldName . '_low' => '2014-06-06',
+    ];
+
+    $params = CRM_Contact_BAO_Query::convertFormValues($formValues);
+    $queryObject = new CRM_Contact_BAO_Query($params);
+    $queryObject->query();
+    $this->assertEquals(
+      'civicrm_value_group_with_fi_1.' . $this->getCustomFieldColumnName('date') . ' >= \'20140606000000\'',
+      trim($queryObject->_where[0][0])
+    );
+    $this->assertEquals(
+      'FROM civicrm_contact contact_a   LEFT JOIN civicrm_address ON ( contact_a.id = civicrm_address.contact_id AND civicrm_address.is_primary = 1 )  LEFT JOIN civicrm_country ON ( civicrm_address.country_id = civicrm_country.id )  LEFT JOIN civicrm_email ON (contact_a.id = civicrm_email.contact_id AND civicrm_email.is_primary = 1)  LEFT JOIN civicrm_phone ON (contact_a.id = civicrm_phone.contact_id AND civicrm_phone.is_primary = 1)  LEFT JOIN civicrm_im ON (contact_a.id = civicrm_im.contact_id AND civicrm_im.is_primary = 1)  LEFT JOIN civicrm_worldregion ON civicrm_country.region_id = civicrm_worldregion.id  
+LEFT JOIN ' . $this->getCustomGroupTable() . ' ON ' . $this->getCustomGroupTable() . '.entity_id = `contact_a`.id',
+      trim($queryObject->_fromClause)
+    );
+    $this->assertEquals('Test Date - greater than or equal to "June 6th, 2014 12:00 AM"', $queryObject->_qill[0][0]);
+    $this->assertEquals(1, $queryObject->_whereTables['civicrm_contact']);
+    $this->assertEquals('LEFT JOIN ' . $this->getCustomGroupTable() . ' ON ' . $this->getCustomGroupTable() . '.entity_id = `contact_a`.id', trim($queryObject->_whereTables[$this->getCustomGroupTable()]));
+  }
+
   /**
    * Test filtering by relative custom data dates.
    *