Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SearchKit - Support form filters for relationships #24293

Merged
merged 2 commits into from
Aug 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CRM/Contact/DAO/RelationshipCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*
* Generated from xml/schema/CRM/Contact/RelationshipCache.xml
* DO NOT EDIT. Generated by CRM_Core_CodeGen
* (GenCodeChecksum:79cb98a7730bede29ea2cf1aeb5a780e)
* (GenCodeChecksum:3f113a0869fa2a649d0e6044a8e59572)
*/

/**
Expand Down Expand Up @@ -305,6 +305,7 @@ public static function &fields() {
'bao' => 'CRM_Contact_BAO_RelationshipCache',
'localizable' => 0,
'html' => [
'type' => 'Select',
'label' => ts("Relationship to contact"),
],
'pseudoconstant' => [
Expand Down Expand Up @@ -345,6 +346,7 @@ public static function &fields() {
'bao' => 'CRM_Contact_BAO_RelationshipCache',
'localizable' => 0,
'html' => [
'type' => 'Select',
'label' => ts("Relationship from contact"),
],
'pseudoconstant' => [
Expand Down Expand Up @@ -419,6 +421,7 @@ public static function &fields() {
'FKClassName' => 'CRM_Case_DAO_Case',
'component' => 'CiviCase',
'html' => [
'type' => 'EntityRef',
'label' => ts("Case"),
],
'readonly' => TRUE,
Expand Down
7 changes: 7 additions & 0 deletions ext/afform/admin/Civi/Api4/Action/Afform/LoadAdminData.php
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,18 @@ public function _run(\Civi\Api4\Generic\Result $result) {
$entities[] = $display['saved_search_id.api_entity'];
foreach ($display['saved_search_id.api_params']['join'] ?? [] as $join) {
$entities[] = explode(' AS ', $join[0])[0];
// Add bridge entities (but only if they are tagged searchable e.g. RelationshipCache)
if (is_string($join[2] ?? NULL) &&
in_array(CoreUtil::getInfoItem($join[2], 'searchable'), ['primary', 'secondary'])
) {
$entities[] = $join[2];
}
}
}
if (!$newForm) {
$scanBlocks($info['definition']['layout']);
}
$entities = array_unique($entities);
$this->loadAvailableBlocks($entities, $info, [['join_entity', 'IS NULL']]);
}

Expand Down
22 changes: 18 additions & 4 deletions ext/afform/admin/ang/afGuiEditor/afGuiSearch.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,18 +101,32 @@
label: mainEntity.label,
fields: mainEntity.fields
}];
entityCount[mainEntity.entity] = 1;

// Increment count of entityName and return a suffix string if > 1
function countEntity(entityName) {
entityCount[entityName] = (entityCount[entityName] || 0) + 1;
return entityCount[entityName] > 1 ? ' ' + entityCount[entityName] : '';
}
countEntity(mainEntity.entity);

_.each(ctrl.display.settings['saved_search_id.api_params'].join, function(join) {
var joinInfo = join[0].split(' AS '),
entity = afGui.getEntity(joinInfo[0]);
entityCount[entity.entity] = (entityCount[entity.entity] || 0) + 1;
entity = afGui.getEntity(joinInfo[0]),
joinEntity = afGui.getEntity(join[2]);
entities.push({
name: entity.entity,
prefix: joinInfo[1] + '.',
label: entity.label + (entityCount[entity.entity] > 1 ? ' ' + entityCount[entity.entity] : ''),
label: entity.label + countEntity(entity.entity),
fields: entity.fields,
});
if (joinEntity) {
entities.push({
name: joinEntity.entity,
prefix: joinInfo[1] + '.',
label: joinEntity.label + countEntity(joinEntity.entity),
fields: _.omit(joinEntity.fields, _.keys(entity.fields)),
});
}
});

return entities;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@
};

// Returns the entity type for fields within this conainer (join entity type if this is a join, else the primary entity type)
this.getFieldEntityType = function(fieldName) {
this.getFieldEntityType = function(fieldKey) {
var entityType;
// If entityName is declared for this fieldset, return entity-type or join-type
if (ctrl.entityName) {
Expand All @@ -409,17 +409,22 @@
} else {
var searchKey = ctrl.getDataEntity(),
searchDisplay = afGui.getSearchDisplay.apply(null, searchKey.split('.')),
prefix = _.includes(fieldName, '.') ? fieldName.split('.')[0] : null;
fieldName = fieldKey.substr(fieldKey.indexOf('.') + 1),
prefix = _.includes(fieldKey, '.') ? fieldKey.split('.')[0] : null;
if (prefix) {
_.each(searchDisplay['saved_search_id.api_params'].join, function(join) {
var joinInfo = join[0].split(' AS ');
if (prefix === joinInfo[1]) {
entityType = joinInfo[0];
// If entity doesn't contain field, it belongs to the bridge join
if (!(fieldName in afGui.getEntity(entityType).fields)) {
entityType = join[2];
}
return false;
}
});
}
if (!entityType && fieldName && afGui.getField(searchDisplay['saved_search_id.api_entity'], fieldName)) {
if (!entityType && fieldKey && afGui.getField(searchDisplay['saved_search_id.api_entity'], fieldKey)) {
entityType = searchDisplay['saved_search_id.api_entity'];
}
}
Expand Down
26 changes: 19 additions & 7 deletions ext/afform/core/Civi/Afform/AfformMetadataInjector.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,19 @@ public static function preprocess($e) {
/**
* Merge field definition metadata into an afform field's definition
*
* @param string $entityName
* @param string|array $entityNames
* @param string $action
* @param \DOMElement $afField
* @throws \API_Exception
*/
private static function fillFieldMetadata($entityName, $action, \DOMElement $afField) {
private static function fillFieldMetadata($entityNames, $action, \DOMElement $afField) {
$fieldName = $afField->getAttribute('name');
$fieldInfo = self::getField($entityName, $fieldName, $action);
foreach ((array) $entityNames as $entityName) {
$fieldInfo = self::getField($entityName, $fieldName, $action);
if ($fieldInfo) {
break;
}
}
// Merge field definition data with whatever's already in the markup.
$deep = ['input_attrs'];
if ($fieldInfo) {
Expand Down Expand Up @@ -179,6 +184,9 @@ private static function getField(string $entityName, string $fieldName, string $
break;
}
}
if (!isset($field)) {
return NULL;
}
// Id field for selecting existing entity
if ($action === 'update' && $field['name'] === CoreUtil::getIdFieldName($entityName)) {
$entityTitle = CoreUtil::getInfoItem($entityName, 'title');
Expand All @@ -200,24 +208,28 @@ private static function getField(string $entityName, string $fieldName, string $
}

/**
* Determines name of the api entity based on the field name prefix
* Determines name of the api entit(ies) based on the field name prefix
*
* Note: Normally will return a single entity name, but
* Will return 2 entity names in the case of Bridge joins e.g. RelationshipCache
*
* @param string $fieldName
* @param string[] $entityList
* @return string
* @return string|array
*/
private static function getFieldEntityType($fieldName, $entityList) {
$prefix = strpos($fieldName, '.') ? explode('.', $fieldName)[0] : NULL;
$joinEntities = [];
$baseEntity = array_shift($entityList);
if ($prefix) {
foreach ($entityList as $entityAndAlias) {
[$entity, $alias] = explode(' AS ', $entityAndAlias);
if ($alias === $prefix) {
return $entityAndAlias;
$joinEntities[] = $entityAndAlias;
}
}
}
return $baseEntity;
return $joinEntities ?: $baseEntity;
}

private static function getFormEntities(\phpQueryObject $doc) {
Expand Down
8 changes: 7 additions & 1 deletion ext/search_kit/Civi/Search/AfformSearchMetadataInjector.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,13 @@ public static function preprocess($e) {
// Add entity names to the fieldset so that afform can populate field metadata
$fieldset = pq($component)->parents('[af-fieldset]');
if ($fieldset->length) {
$entityList = array_merge([$display['saved_search_id.api_entity']], array_column($display['saved_search_id.api_params']['join'] ?? [], 0));
$entityList = [$display['saved_search_id.api_entity']];
foreach ($display['saved_search_id.api_params']['join'] ?? [] as $join) {
$entityList[] = $join[0];
if (is_string($join[2] ?? NULL)) {
$entityList[] = $join[2] . ' AS ' . (explode(' AS ', $join[0])[1]);
}
}
$fieldset->attr('api-entities', htmlspecialchars(\CRM_Utils_JS::encode($entityList)));
}
}
Expand Down
3 changes: 3 additions & 0 deletions xml/schema/Contact/RelationshipCache.xml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
<add>5.29</add>
<html>
<label>Relationship to contact</label>
<type>Select</type>
</html>
<pseudoconstant>
<callback>CRM_Core_PseudoConstant::relationshipTypeOptions</callback>
Expand Down Expand Up @@ -152,6 +153,7 @@
<add>5.29</add>
<html>
<label>Relationship from contact</label>
<type>Select</type>
</html>
<pseudoconstant>
<callback>CRM_Core_PseudoConstant::relationshipTypeOptions</callback>
Expand Down Expand Up @@ -237,6 +239,7 @@
<comment>FK to civicrm_case</comment>
<html>
<label>Case</label>
<type>EntityRef</type>
</html>
<add>5.44</add>
<readonly>true</readonly>
Expand Down