Skip to content

Commit

Permalink
CustomField - Support filters in EntityReference fields on all forms
Browse files Browse the repository at this point in the history
This ensures filters are applied on both quickforms and afforms when defined for a custom field.
Note: There is still no UI for adding these filters to a custom field, but they can be set via api explorer.
  • Loading branch information
colemanw committed Mar 30, 2023
1 parent 3e87784 commit c39aded
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 12 deletions.
8 changes: 7 additions & 1 deletion Civi/Api4/Event/Subscriber/AutocompleteFieldSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,15 @@ public function onApiPrepare(\Civi\API\Event\PrepareEvent $event): void {
return;
}
try {
$where = ['name', '=', $fieldName];
// Legacy support for QuickForm custom field format (`custom_xx`)
if (strpos($fieldName, 'custom_') === 0 && strlen($fieldName) > 7 && is_numeric($fieldName[7])) {
[, $customId] = explode('_', $fieldName);
$where = ['custom_field_id', '=', $customId];
}
$fieldSpec = civicrm_api4($entityName, 'getFields', [
'checkPermissions' => FALSE,
'where' => [['name', '=', $fieldName]],
'where' => [$where],
])->single();

// Auto-add filters defined in schema
Expand Down
6 changes: 0 additions & 6 deletions tests/phpunit/api/v4/Action/AutocompleteTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
use Civi\Api4\MockBasicEntity;
use Civi\Api4\SavedSearch;
use Civi\Core\Event\GenericHookEvent;
use Civi\Test\CiviEnvBuilder;
use Civi\Test\HookInterface;
use Civi\Test\TransactionalInterface;

Expand Down Expand Up @@ -55,11 +54,6 @@ public function on_civi_api_prepare(\Civi\API\Event\PrepareEvent $event) {
}
}

public function setUpHeadless(): CiviEnvBuilder {
// TODO: search_kit should probably be part of the 'headless()' baseline.
return \Civi\Test::headless()->install(['org.civicrm.search_kit'])->apply();
}

public function setUp(): void {
$this->hookCallback = NULL;
// Ensure MockBasicEntity gets added via above listener
Expand Down
3 changes: 2 additions & 1 deletion tests/phpunit/api/v4/Api4TestBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ public function __construct($name = NULL, array $data = [], $dataName = '') {
}

public function setUpHeadless(): CiviEnvBuilder {
return Test::headless()->apply();
// TODO: search_kit should probably be part of the 'headless()' baseline.
return Test::headless()->install(['org.civicrm.search_kit'])->apply();
}

/**
Expand Down
33 changes: 30 additions & 3 deletions tests/phpunit/api/v4/Custom/CustomEntityReferenceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

namespace api\v4\Custom;

use Civi\Api4\Activity;
use Civi\Api4\Contact;
use Civi\Api4\CustomGroup;
use Civi\Api4\CustomField;
Expand All @@ -27,26 +28,52 @@
class CustomEntityReferenceTest extends CustomTestBase {

/**
* Ensure custom fields of type EntityReference show up correctly in getFields metadata.
* Ensure custom fields of type EntityReference correctly apply filters
*/
public function testEntityReferenceCustomField() {
$subject = uniqid();
CustomGroup::create()->setValues([
'title' => 'EntityRefFields',
'extends' => 'Individual',
])->execute();
CustomField::create()->setValues([
$field = CustomField::create()->setValues([
'label' => 'TestActivityReference',
'custom_group_id.name' => 'EntityRefFields',
'html_type' => 'Autocomplete-Select',
'data_type' => 'EntityReference',
'fk_entity' => 'Activity',
])->execute();
'filter' => "subject=$subject",
])->execute()->single();
// Check metadata
$spec = Contact::getFields(FALSE)
->addWhere('name', '=', 'EntityRefFields.TestActivityReference')
->execute()->single();
$this->assertNull($spec['suffixes']);
$this->assertEquals('EntityRef', $spec['input_type']);
$this->assertEquals('Activity', $spec['fk_entity']);
$this->assertEquals($subject, $spec['input_attrs']['filter']['subject']);
// Check results
$activities = $this->saveTestRecords('Activity', [
'records' => [
['subject' => $subject],
['subject' => 'wrong one'],
['subject' => $subject],
],
]);
// Filter using APIv4-style name
$result = Activity::autocomplete(FALSE)
->setFieldName("Contact.EntityRefFields.TestActivityReference")
->execute();
$this->assertCount(2, $result);
// No filter
$result = Activity::autocomplete(FALSE)
->execute();
$this->assertGreaterThan(2, $result->countFetched());
// Filter using Quickform-style name
$result = Activity::autocomplete(FALSE)
->setFieldName("Contact.custom_{$field['id']}")
->execute();
$this->assertCount(2, $result);
}

}
3 changes: 2 additions & 1 deletion tests/phpunit/api/v4/Entity/ConformanceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ public function getEntitiesHitech(): array {
* @return array
*/
public function getEntitiesLotech(): array {
$manual['add'] = [];
// TODO: Auto-scan required core extensions like search_kit
$manual['add'] = ['SearchDisplay', 'SearchSegment'];
$manual['remove'] = ['CustomValue'];
$manual['transform'] = ['CiviCase' => 'Case'];

Expand Down

0 comments on commit c39aded

Please sign in to comment.