From 577810c5ead221dd57f79b0de0573c4753c5c562 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Thu, 1 Jul 2021 18:36:56 -0400 Subject: [PATCH] SearchKit - Improve join labels This fixes the order of joins, fixes a bug where the label fields were getting overwritten by implicit joins before they could be used for explicit joins, and uses the label field for explicit joins instead of just the entity name. --- ext/search_kit/Civi/Search/Admin.php | 30 ++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/ext/search_kit/Civi/Search/Admin.php b/ext/search_kit/Civi/Search/Admin.php index 05ae166e76..36d587a97c 100644 --- a/ext/search_kit/Civi/Search/Admin.php +++ b/ext/search_kit/Civi/Search/Admin.php @@ -26,8 +26,8 @@ class Admin { $schema = self::getSchema(); $extensions = \CRM_Extension_System::singleton()->getMapper(); return [ - 'schema' => $schema, - 'joins' => self::getJoins(array_column($schema, NULL, 'name')), + 'schema' => self::addImplicitFKFields($schema), + 'joins' => self::getJoins($schema), 'operators' => \CRM_Utils_Array::makeNonAssociative(self::getOperators()), 'functions' => \CRM_Api4_Page_Api4Explorer::getSqlFunctions(), 'displayTypes' => Display::getDisplayTypes(['id', 'name', 'label', 'description', 'icon']), @@ -119,8 +119,16 @@ class Admin { } } } - // Add in FK fields for implicit joins - // For example, add a `campaign_id.title` field to the Contribution entity + return $schema; + } + + /** + * Add in FK fields for implicit joins + * For example, add a `campaign_id.title` field to the Contribution entity + * @param $schema + * @return array + */ + private static function addImplicitFKFields($schema) { foreach ($schema as &$entity) { if ($entity['searchable'] !== 'bridge') { foreach (array_reverse($entity['fields'], TRUE) as $index => $field) { @@ -185,8 +193,13 @@ class Admin { $daoClass = $entity['dao']; $references = $daoClass::getReferenceColumns(); // Only the first bridge reference gets processed, so if it's dynamic we want to be sure it's first in the list - usort($references, function($reference) { - return is_a($reference, 'CRM_Core_Reference_Dynamic') ? -1 : 1; + usort($references, function($first, $second) { + foreach ([-1 => $first, 1 => $second] as $weight => $reference) { + if (is_a($reference, 'CRM_Core_Reference_Dynamic')) { + return $weight; + } + } + return 0; }); $fields = array_column($entity['fields'], NULL, 'name'); $bridge = in_array('EntityBridge', $entity['type']) ? $entity['name'] : NULL; @@ -207,6 +220,7 @@ class Admin { } // Dynamic references use a column like "entity_table" (for normal joins this value will be null) $dynamicCol = $reference->getTypeColumn(); + // For dynamic references getTargetEntities will return multiple targets; for normal joins this loop will only run once foreach ($reference->getTargetEntities() as $targetTable => $targetEntityName) { if (!isset($allowedEntities[$targetEntityName]) || $targetEntityName === $entity['name']) { @@ -218,8 +232,8 @@ class Admin { // Add the straight 1-1 join $alias = $entity['name'] . '_' . $targetEntityName . '_' . $keyField['name']; $joins[$entity['name']][] = [ - 'label' => $entity['title'] . ' ' . $targetEntity['title'], - 'description' => $dynamicCol ? '' : $keyField['label'], + 'label' => $entity['title'] . ' ' . ($dynamicCol ? $targetEntity['title'] : $keyField['label']), + 'description' => '', 'entity' => $targetEntityName, 'conditions' => self::getJoinConditions($keyField['name'], $alias . '.' . $reference->getTargetKey(), $targetTable, $dynamicCol), 'defaults' => self::getJoinDefaults($alias, $targetEntity), -- 2.25.1