From 2e100a6bd782b47b41ef477ce06b781a96d70c73 Mon Sep 17 00:00:00 2001
From: Coleman Watts <coleman@civicrm.org>
Date: Sun, 5 Jan 2020 14:47:35 -0500
Subject: [PATCH] Load join blocks primary first

---
 .../Api4/Action/Afform/AbstractProcessor.php  | 31 ++++++++++++++-----
 .../core/Civi/Api4/Action/Afform/Prefill.php  |  3 +-
 2 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/ext/afform/core/Civi/Api4/Action/Afform/AbstractProcessor.php b/ext/afform/core/Civi/Api4/Action/Afform/AbstractProcessor.php
index 416bde2d90..74a5da495a 100644
--- a/ext/afform/core/Civi/Api4/Action/Afform/AbstractProcessor.php
+++ b/ext/afform/core/Civi/Api4/Action/Afform/AbstractProcessor.php
@@ -77,15 +77,10 @@ abstract class AbstractProcessor extends \Civi\Api4\Generic\AbstractAction {
    * @throws \API_Exception
    */
   protected static function getJoinWhereClause($mainEntityName, $joinEntityName, $mainEntityId) {
-    $joinMeta = \Civi::$statics[__CLASS__][__FUNCTION__][$joinEntityName] ?? NULL;
     $params = [];
-    if (!$joinMeta) {
-      $joinMeta = civicrm_api4($joinEntityName, 'getFields', ['checkPermissions' => FALSE, 'action' => 'create', 'select' => ['name']])->column('name');
-      \Civi::$statics[__CLASS__][__FUNCTION__][$joinEntityName] = $joinMeta;
-    }
-    if (in_array('entity_id', $joinMeta)) {
+    if (self::fieldExists($joinEntityName, 'entity_id')) {
       $params[] = ['entity_id', '=', $mainEntityId];
-      if (in_array('entity_table', $joinMeta)) {
+      if (self::fieldExists($joinEntityName, 'entity_table')) {
         $params[] = ['entity_table', '=', 'civicrm_' . _civicrm_api_get_entity_name_from_camel($mainEntityName)];
       }
     }
@@ -96,4 +91,26 @@ abstract class AbstractProcessor extends \Civi\Api4\Generic\AbstractAction {
     return $params;
   }
 
+  /**
+   * Check if a field exists for a given entity
+   *
+   * @param $entityName
+   * @param $fieldName
+   * @return bool
+   * @throws \API_Exception
+   */
+  public static function fieldExists($entityName, $fieldName) {
+    if (empty(\Civi::$statics[__CLASS__][__FUNCTION__][$entityName])) {
+      $getFields = \Civi\Api4\Utils\ActionUtil::getAction($entityName, 'getFields');
+      $getFields->setCheckPermissions(FALSE);
+      $getFields->setAction('create');
+      $getFields->addSelect('name');
+      if (property_exists($getFields, 'includeCustom')) {
+        $getFields->setIncludeCustom(FALSE);
+      }
+      \Civi::$statics[__CLASS__][__FUNCTION__][$entityName] = $getFields->execute()->column('name');
+    }
+    return in_array($fieldName, \Civi::$statics[__CLASS__][__FUNCTION__][$entityName]);
+  }
+
 }
diff --git a/ext/afform/core/Civi/Api4/Action/Afform/Prefill.php b/ext/afform/core/Civi/Api4/Action/Afform/Prefill.php
index dd9ba99807..e4b93be85f 100644
--- a/ext/afform/core/Civi/Api4/Action/Afform/Prefill.php
+++ b/ext/afform/core/Civi/Api4/Action/Afform/Prefill.php
@@ -53,10 +53,11 @@ class Prefill extends AbstractProcessor {
       $data = ['fields' => $item];
       foreach ($entity['joins'] ?? [] as $joinEntity => $join) {
         $data['joins'][$joinEntity] = (array) civicrm_api4($joinEntity, 'get', [
-          'where' => $this->getJoinWhereClause($entity['type'], $joinEntity, $item['id']),
+          'where' => self::getJoinWhereClause($entity['type'], $joinEntity, $item['id']),
           'limit' => !empty($join['af-repeat']) ? $join['max'] ?? 0 : 1,
           'select' => array_keys($join['fields']),
           'checkPermissions' => $checkPermissions,
+          'orderBy' => self::fieldExists($joinEntity, 'is_primary') ? ['is_primary' => 'DESC'] : [],
         ]);
       }
       $this->_data[$entity['name']][] = $data;
-- 
2.25.1