CRM-19810 - Add api joins on optionValue table
authorColeman Watts <coleman@civicrm.org>
Thu, 29 Dec 2016 17:22:36 +0000 (12:22 -0500)
committerColeman Watts <coleman@civicrm.org>
Thu, 29 Dec 2016 17:22:36 +0000 (12:22 -0500)
Civi/API/SelectQuery.php
templates/CRM/Admin/Page/APIExplorer.js
tests/phpunit/api/v3/EntityJoinTest.php

index 357dc92ceb1a9737a09cf122a3f6069f0c6f8a0a..f44365f08d9f0d48a9107d033e85a7e8569d44e6 100644 (file)
@@ -230,8 +230,8 @@ abstract class SelectQuery {
       }
       $fieldInfo = \CRM_Utils_Array::value($fieldName, $fkField['FKApiSpec']);
 
-      // FIXME: What if the foreign key is not the "id" column?
-      if (!$fieldInfo || !isset($fkField['FKApiSpec']['id'])) {
+      $keyColumn = \CRM_Utils_Array::value('FKKeyColumn', $fkField, 'id');
+      if (!$fieldInfo || !isset($fkField['FKApiSpec'][$keyColumn])) {
         // Join doesn't exist - might be another param with a dot in it for some reason, we'll just ignore it.
         return NULL;
       }
@@ -240,10 +240,14 @@ abstract class SelectQuery {
 
       // Add acl condition
       $joinCondition = array_merge(
-        array("$prev.$fk = $tableAlias.id"),
+        array("$prev.$fk = $tableAlias.$keyColumn"),
         $this->getAclClause($tableAlias, \_civicrm_api3_get_BAO($fkField['FKApiName']), $subStack)
       );
 
+      if (!empty($fkField['FKCondition'])) {
+        $joinCondition[] = str_replace($fkTable, $tableAlias, $fkField['FKCondition']);
+      }
+
       $this->join($side, $fkTable, $tableAlias, $joinCondition);
 
       if (strpos($fieldName, 'custom_') === 0) {
@@ -259,7 +263,7 @@ abstract class SelectQuery {
   }
 
   /**
-   * Get join info for dynamically-joined fields (e.g. "entity_id")
+   * Get join info for dynamically-joined fields (e.g. "entity_id", "option_group")
    *
    * @param $fkField
    * @param $stack
@@ -273,6 +277,12 @@ abstract class SelectQuery {
         $fkField['FKApiName'] = \CRM_Core_DAO_AllCoreTables::getBriefName($fkField['FKClassName']);
       }
     }
+    if (!empty($fkField['pseudoconstant']['optionGroupName'])) {
+      $fkField['FKClassName'] = 'CRM_Core_DAO_OptionValue';
+      $fkField['FKApiName'] = 'OptionValue';
+      $fkField['FKKeyColumn'] = 'value';
+      $fkField['FKCondition'] = "civicrm_option_value.option_group_id = (SELECT id FROM civicrm_option_group WHERE name = '{$fkField['pseudoconstant']['optionGroupName']}')";
+    }
   }
 
   /**
index 7c3a4b18945dc6ec4d6053211d1949fbb6d0b141..bbcc7260954dd8483fe76dd8de9c054ae9090dd1 100644 (file)
         field.FKApiName = getField(entityTableParam).options[params[entityTableParam]];
       }
     }
+    if (field.pseudoconstant && field.pseudoconstant.optionGroupName) {
+      field.FKApiName = 'OptionValue';
+    }
   }
 
   /**
index 30713a962d29b961d581157a807a8fc3a153b562..25c598d4d841ee80f6929c50d7c6485011786189 100644 (file)
@@ -42,14 +42,15 @@ class api_v3_EntityJoinTest extends CiviUnitTestCase {
     $first = 'firstthisisatest';
     $last = 'lastthisisatest';
     $org = $this->organizationCreate(array('organization_name' => 'Employer of one'));
-    $person1 = $this->individualCreate(array('employer_id' => $org, 'first_name' => $first, 'last_name' => $last));
+    $person1 = $this->individualCreate(array('employer_id' => $org, 'first_name' => $first, 'last_name' => $last, 'gender_id' => 1));
     $person2 = $this->individualCreate(array(), 1);
     $result = $this->callAPISuccessGetSingle('Email', array(
-      'return' => 'contact_id.employer_id.display_name',
+      'return' => 'contact_id.employer_id.display_name,contact_id.gender_id.label',
       'contact_id.last_name' => $last,
       'contact_id.first_name' => $first,
     ));
     $this->assertEquals('Employer of one', $result['contact_id.employer_id.display_name']);
+    $this->assertEquals('Female', $result['contact_id.gender_id.label']);
   }
 
 }