From 5828ae54c7f3a59a52216da31509dbc1e0dc3708 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Wed, 27 Jan 2021 08:32:48 -0500 Subject: [PATCH] SearchKit: Add support for multi-record custom field groups This adds support for multi-record custom field group pseudo-entities to be added to the search as joins --- Civi/Api4/Action/Entity/Get.php | 3 +++ ext/search/Civi/Search/Admin.php | 35 ++++++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/Civi/Api4/Action/Entity/Get.php b/Civi/Api4/Action/Entity/Get.php index 4c2cbf2e8b..d9aef3655c 100644 --- a/Civi/Api4/Action/Entity/Get.php +++ b/Civi/Api4/Action/Entity/Get.php @@ -102,6 +102,9 @@ class Get extends \Civi\Api4\Generic\BasicGetAction { 'title' => $customEntity['title'], 'title_plural' => $customEntity['title'], 'description' => ts('Custom group for %1', [1 => $baseEntity::getInfo()['title_plural']]), + 'searchable' => TRUE, + 'type' => ['CustomValue'], + 'paths' => [], 'see' => [ 'https://docs.civicrm.org/user/en/latest/organising-your-data/creating-custom-fields/#multiple-record-fieldsets', '\\Civi\\Api4\\CustomGroup', diff --git a/ext/search/Civi/Search/Admin.php b/ext/search/Civi/Search/Admin.php index f359c93fc2..7a558ef19e 100644 --- a/ext/search/Civi/Search/Admin.php +++ b/ext/search/Civi/Search/Admin.php @@ -120,7 +120,34 @@ class Admin { public static function getJoins(array $allowedEntities) { $joins = []; foreach ($allowedEntities as $entity) { - if (!empty($entity['dao'])) { + // Multi-record custom field groups (to-date only the contact entity supports these) + if (in_array('CustomValue', $entity['type'])) { + $targetEntity = $allowedEntities['Contact']; + // Join from Custom group to Contact (n-1) + $alias = $entity['name'] . '_Contact_entity_id'; + $joins[$entity['name']][] = [ + 'label' => $entity['title'] . ' ' . $targetEntity['title'], + 'description' => '', + 'entity' => 'Contact', + 'conditions' => self::getJoinConditions('entity_id', $alias . '.id'), + 'defaults' => self::getJoinDefaults($alias, $targetEntity), + 'alias' => $alias, + 'multi' => FALSE, + ]; + // Join from Contact to Custom group (n-n) + $alias = 'Contact_' . $entity['name'] . '_entity_id'; + $joins['Contact'][] = [ + 'label' => $entity['title_plural'], + 'description' => '', + 'entity' => $entity['name'], + 'conditions' => self::getJoinConditions('id', $alias . '.entity_id'), + 'defaults' => self::getJoinDefaults($alias, $entity), + 'alias' => $alias, + 'multi' => TRUE, + ]; + } + // Non-custom DAO entities + elseif (!empty($entity['dao'])) { /* @var \CRM_Core_DAO $daoClass */ $daoClass = $entity['dao']; $references = $daoClass::getReferenceColumns(); @@ -142,14 +169,14 @@ class Admin { ) { continue; } + // 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']) { continue; } $targetEntity = $allowedEntities[$targetEntityName]; - // Dynamic references use a column like "entity_table" - $dynamicCol = $reference->getTypeColumn(); // Non-bridge joins directly between 2 entities if (!$bridge) { // Add the straight 1-1 join @@ -233,7 +260,7 @@ class Admin { * @param string|null $dynamicCol * @return array[] */ - private static function getJoinConditions($nearCol, $farCol, $targetTable, $dynamicCol) { + private static function getJoinConditions($nearCol, $farCol, $targetTable = NULL, $dynamicCol = NULL) { $conditions = [ [ $nearCol, -- 2.25.1