dev/core#1025 fix unreleased regression on contact.get with custom fields
authoreileen <emcnaughton@wikimedia.org>
Fri, 7 Jun 2019 00:51:25 +0000 (12:51 +1200)
committereileen <emcnaughton@wikimedia.org>
Fri, 7 Jun 2019 00:54:38 +0000 (12:54 +1200)
Fixes a bug where contact.get does not retrieve results if a custom field is requested and an activity custom field exists

This bug came about because a recent fix made metadata more consistent but it turns out this class was filtering the
metadata by the passed in  - and then iterating through the metadata. Now it iterates the ids instead.

CRM/Core/BAO/CustomQuery.php
tests/phpunit/CRMTraits/Custom/CustomDataTrait.php
tests/phpunit/api/v3/ContactTest.php

index 0e5191f60c8fb1caa7c11b8fa287d822fdf4ba9f..eb1b645c744a5bf5015b58bee0029bb1ed915ba9 100644 (file)
@@ -213,7 +213,8 @@ SELECT f.id, f.label, f.data_type,
       return;
     }
 
-    foreach ($this->_fields as $id => $field) {
+    foreach (array_keys($this->_ids) as $id) {
+      $field = $this->_fields[$id];
       $name = $field['table_name'];
       $fieldName = 'custom_' . $field['id'];
       $this->_select["{$name}_id"] = "{$name}.id as {$name}_id";
@@ -227,10 +228,7 @@ SELECT f.id, f.label, f.data_type,
       }
 
       $this->_tables[$name] = "\nLEFT JOIN $name ON $name.entity_id = $joinTable.id";
-
-      if (!empty($this->_ids[$id])) {
-        $this->_whereTables[$name] = $this->_tables[$name];
-      }
+      $this->_whereTables[$name] = $this->_tables[$name];
 
       if ($joinTable) {
         $joinClause = 1;
index d533dd066d6fd020350f5f43d095a32084d48751..541abd0b10550ab4a17957290a4d171fb7a3a028 100644 (file)
@@ -67,16 +67,18 @@ trait CRMTraits_Custom_CustomDataTrait {
    * @param array $groupParams
    * @param string $customFieldType
    *
+   * @param string $identifier
+   *
    * @throws \CRM_Core_Exception
    */
-  public function createCustomGroupWithFieldOfType($groupParams = [], $customFieldType = 'text') {
+  public function createCustomGroupWithFieldOfType($groupParams = [], $customFieldType = 'text', $identifier = '') {
     if ($customFieldType !== 'text') {
       throw new CRM_Core_Exception('we have not yet extracted other custom field types from createCustomFieldsOfAllTypes, Use consistent syntax when you do');
     }
-    $groupParams['title'] = empty($groupParams['title']) ? 'Group with field ' . $customFieldType : $groupParams['title'];
+    $groupParams['title'] = empty($groupParams['title']) ? $identifier . 'Group with field ' . $customFieldType : $groupParams['title'];
     $this->createCustomGroup($groupParams);
     $customField = $this->createTextCustomField(['custom_group_id' => $this->ids['CustomGroup'][$groupParams['title']]]);
-    $this->ids['CustomField'][$customFieldType] = $customField['id'];
+    $this->ids['CustomField'][$identifier . $customFieldType] = $customField['id'];
   }
 
   /**
index 33bd0e6b921bb37eb8e044f480d537ac31afe05a..028cf80beec9312a2054bd5352eb149ac84ee09d 100644 (file)
@@ -1164,6 +1164,20 @@ class api_v3_ContactTest extends CiviUnitTestCase {
     $this->customGroupDelete($ids['custom_group_id']);
   }
 
+  /**
+   * Tests that using 'return' with a custom field not of type contact does not inappropriately filter.
+   *
+   * https://lab.civicrm.org/dev/core/issues/1025
+   *
+   * @throws \CRM_Core_Exception
+   */
+  public function testGetWithCustomOfActivityType() {
+    $this->createCustomGroupWithFieldOfType(['extends' => 'Activity']);
+    $this->createCustomGroupWithFieldOfType(['extends' => 'Contact'], 'text', 'contact_');
+    $contactID = $this->individualCreate();
+    $this->callAPISuccessGetSingle('Contact', ['id' => $contactID, 'return' => ['external_identifier', $this->getCustomFieldName('contact_text')]]);
+  }
+
   /**
    * Check with complete array + custom field.
    *