Skip to content

Commit

Permalink
Merge pull request #20117 from colemanw/searchKitFixContactRef
Browse files Browse the repository at this point in the history
SearchKit - Fix display of contact reference fields (single-value)
  • Loading branch information
colemanw authored Apr 21, 2021
2 parents 8378696 + ede387b commit c926d5a
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 64 deletions.
8 changes: 7 additions & 1 deletion Civi/Api4/Service/Schema/SchemaMapBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ private function addJoins(Table $table, $field, array $data) {
if ($fkClass) {
$tableName = AllCoreTables::getTableForClass($fkClass);
$fkKey = $data['FKKeyColumn'] ?? 'id';
// Fixme: Clumsy string manipulation to transform e.g. "contact_id" to "contact" - we never should have done this
$alias = str_replace('_id', '', $field);
$joinable = new Joinable($tableName, $fkKey, $alias);
$joinable->setJoinType($joinable::JOIN_TYPE_MANY_TO_ONE);
Expand Down Expand Up @@ -154,7 +155,7 @@ private function addCustomFields(SchemaMap $map, Table $baseTable, string $entit
}
$fieldData = \CRM_Utils_SQL_Select::from('civicrm_custom_field f')
->join('custom_group', 'INNER JOIN civicrm_custom_group g ON g.id = f.custom_group_id')
->select(['g.name as custom_group_name', 'g.table_name', 'g.is_multiple', 'f.name', 'label', 'column_name', 'option_group_id'])
->select(['g.name as custom_group_name', 'g.table_name', 'g.is_multiple', 'f.name', 'f.data_type', 'label', 'column_name', 'option_group_id'])
->where('g.extends IN (@entity)', ['@entity' => $customInfo['extends']])
->where('g.is_active')
->where('f.is_active')
Expand Down Expand Up @@ -182,6 +183,11 @@ private function addCustomFields(SchemaMap $map, Table $baseTable, string $entit
$joinable = new Joinable($baseTable->getName(), $customInfo['column'], AllCoreTables::convertEntityNameToLower($entityName));
$customTable->addTableLink('entity_id', $joinable);
}

if ($fieldData->data_type === 'ContactReference') {
$joinable = new Joinable('civicrm_contact', 'id', $fieldData->name);
$customTable->addTableLink($fieldData->column_name, $joinable);
}
}

foreach ($links as $alias => $link) {
Expand Down
15 changes: 12 additions & 3 deletions ext/search/Civi/Search/Admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,20 @@ public static function getSchema() {
if (in_array('DAOEntity', $entity['type'], TRUE) && !in_array('EntityBridge', $entity['type'], TRUE)) {
foreach (array_reverse($entity['fields'], TRUE) as $index => $field) {
if (!empty($field['fk_entity']) && !$field['options'] && !empty($schema[$field['fk_entity']]['label_field'])) {
// The original field will get title instead of label since it represents the id (title usually ends in ID but label does not)
$entity['fields'][$index]['label'] = $field['title'];
$isCustom = strpos($field['name'], '.');
// Custom fields: append "ID" to original field label
if ($isCustom) {
$entity['fields'][$index]['label'] .= ' ' . E::ts('Contact ID');
}
// DAO fields: use title instead of label since it represents the id (title usually ends in ID but label does not)
else {
$entity['fields'][$index]['label'] = $field['title'];
}
// Add the label field from the other entity to this entity's list of fields
$newField = \CRM_Utils_Array::findAll($schema[$field['fk_entity']]['fields'], ['name' => $schema[$field['fk_entity']]['label_field']])[0];
$newField['name'] = str_replace('_id', '', $field['name']) . '.' . $schema[$field['fk_entity']]['label_field'];
// Due to string manipulation in \Civi\Api4\Service\Schema\SchemaMapBuilder::addJoins()
$alias = $isCustom ? $field['name'] : str_replace('_id', '', $field['name']);
$newField['name'] = $alias . '.' . $schema[$field['fk_entity']]['label_field'];
$newField['label'] = $field['label'] . ' ' . $newField['label'];
array_splice($entity['fields'], $index, 0, [$newField]);
}
Expand Down
29 changes: 10 additions & 19 deletions ext/search/ang/crmSearchAdmin.module.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@
return new RegExp('^' + join.alias + '_\\d\\d').test(path);
});
if (!join) {
console.warn( 'Join ' + fullNameOrAlias + ' not found.');
return;
}
path = path.replace(join.alias + '_', '');
Expand Down Expand Up @@ -138,28 +137,20 @@
return result;
}
function getFieldAndJoin(fieldName, entityName) {
var dotSplit = fieldName.split('.'),
joinEntity = dotSplit.length > 1 ? dotSplit[0] : null,
name = _.last(dotSplit).split(':')[0],
var fieldPath = fieldName.split(':')[0],
dotSplit = fieldPath.split('.'),
name,
join,
field;
// Custom fields contain a dot in their fieldname
// If 3 segments, the first is the joinEntity and the last 2 are the custom field
if (dotSplit.length === 3) {
name = dotSplit[1] + '.' + name;
}
// If 2 segments, it's ambiguous whether this is a custom field or joined field. Search the main entity first.
if (dotSplit.length === 2) {
field = _.find(getEntity(entityName).fields, {name: dotSplit[0] + '.' + name});
if (field) {
field.baseEntity = entityName;
return {field: field};
// If 2 or more segments, the first might be the name of a join
if (dotSplit.length > 1) {
join = getJoin(dotSplit[0]);
if (join) {
dotSplit.shift();
entityName = join.entity;
}
}
if (joinEntity) {
join = getJoin(joinEntity);
entityName = getJoin(joinEntity).entity;
}
name = dotSplit.join('.');
field = _.find(getEntity(entityName).fields, {name: name});
if (!field && join && join.bridge) {
field = _.find(getEntity(join.bridge).fields, {name: name});
Expand Down
73 changes: 73 additions & 0 deletions tests/phpunit/api/v4/Action/CustomJoinTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

/*
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC. All rights reserved. |
| |
| This work is published under the GNU AGPLv3 license with some |
| permitted exceptions and without any warranty. For full license |
| and copyright information, see https://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/

/**
*
* @package CRM
* @copyright CiviCRM LLC https://civicrm.org/licensing
*/


namespace api\v4\Action;

use Civi\Api4\Contact;
use Civi\Api4\CustomField;
use Civi\Api4\CustomGroup;

/**
* @group headless
*/
class CustomJoinTest extends BaseCustomValueTest {

public function testGetWithJoin() {

$customGroup = CustomGroup::create(FALSE)
->addValue('name', 'MyContactRef')
->addValue('extends', 'Individual')
->execute()
->first();

CustomField::create(FALSE)
->addValue('label', 'FavPerson')
->addValue('custom_group_id', $customGroup['id'])
->addValue('html_type', 'Autocomplete-Select')
->addValue('data_type', 'ContactReference')
->execute();

$favPersonId = Contact::create(FALSE)
->addValue('first_name', 'Favorite')
->addValue('last_name', 'Person')
->addValue('contact_type', 'Individual')
->execute()
->first()['id'];

$contactId = Contact::create(FALSE)
->addValue('first_name', 'Mya')
->addValue('last_name', 'Tester')
->addValue('contact_type', 'Individual')
->addValue('MyContactRef.FavPerson', $favPersonId)
->execute()
->first()['id'];

$contact = Contact::get(FALSE)
->addSelect('display_name')
->addSelect('MyContactRef.FavPerson.first_name')
->addSelect('MyContactRef.FavPerson.last_name')
->addWhere('id', '=', $contactId)
->execute()
->first();

$this->assertEquals('Favorite', $contact['MyContactRef.FavPerson.first_name']);
$this->assertEquals('Person', $contact['MyContactRef.FavPerson.last_name']);
}

}
41 changes: 0 additions & 41 deletions tests/phpunit/api/v4/AllTests.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,37 +16,6 @@
* @copyright CiviCRM LLC https://civicrm.org/licensing
*/

// vim: set si ai expandtab tabstop=4 shiftwidth=4 softtabstop=4:

/**
* File for the api_v4_AllTests class
*
* (PHP 5)
*
* @author Walt Haas <walt@dharmatech.org> (801) 534-1262
* @copyright Copyright CiviCRM LLC (C) 2009
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html
* GNU Affero General Public License version 3
* @version $Id: AllTests.php 40328 2012-05-11 23:06:13Z allen $
* @package CiviCRM
*
* This file is part of CiviCRM
*
* CiviCRM is free software; you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either version 3 of
* the License, or (at your option) any later version.
*
* CiviCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*/

/**
* Class containing the APIv4 test suite
*
Expand All @@ -73,13 +42,3 @@ public static function suite() {
}

}
// class AllTests

// -- set Emacs parameters --
// Local variables:
// mode: php;
// tab-width: 4
// c-basic-offset: 4
// c-hanging-comment-ender-p: nil
// indent-tabs-mode: nil
// End:

0 comments on commit c926d5a

Please sign in to comment.