Skip to content

Commit

Permalink
Merge pull request #28940 from colemanw/improveParticipantPseudoconstant
Browse files Browse the repository at this point in the history
APIv4 - Improve getFields internal value lookups
  • Loading branch information
colemanw authored Jan 9, 2024
2 parents 288091b + 29a5ace commit bb61894
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 15 deletions.
52 changes: 39 additions & 13 deletions Civi/Api4/Service/Spec/RequestSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,25 +57,51 @@ public function __construct(string $entity, string $action, array $values = [])
$this->entity = $entity;
$this->action = $action;
$this->entityTableName = CoreUtil::getTableName($entity);
$this->values = $this->resolveValues($values);
}

// If `id` given, lookup other values needed to filter custom fields
$customInfo = \Civi\Api4\Utils\CoreUtil::getCustomGroupExtends($entity);
/**
* Resolve as many values as possible based on available data
*/
private function resolveValues(array $values) {
if (!$values) {
return $values;
}
$customInfo = \Civi\Api4\Utils\CoreUtil::getCustomGroupExtends($this->entity);
$idCol = $customInfo['column'] ?? NULL;
if ($idCol && !empty($values[$idCol])) {
$grouping = (array) $customInfo['grouping'];
$lookupNeeded = array_diff($grouping, array_keys($values));
if ($lookupNeeded) {
$record = \civicrm_api4($entity, 'get', [
$grouping = (array) ($customInfo['grouping'] ?? []);
$lookupNeeded = array_diff($grouping, array_keys($values));
// If `id` given, use that first
if ($lookupNeeded && $idCol && !empty($values[$idCol])) {
$record = \civicrm_api4($this->entity, 'get', [
'checkPermissions' => FALSE,
'where' => [[$idCol, '=', $values[$idCol]]],
'select' => $lookupNeeded,
])->first();
if ($record) {
$values += $record;
}
}
$lookupNeeded = array_diff($grouping, array_keys($values));
foreach ($lookupNeeded as $fieldName) {
// If we need a value like `event_id.event_type_id` and we only have `event_id`,
// use the FK to lookup the value from the event.
if (str_contains($fieldName, '.')) {
[$fkFrom, $fkTo] = explode('.', $fieldName);
$fkEntity = \civicrm_api4($this->entity, 'getFields', [
'checkPermissions' => FALSE,
'where' => [[$idCol, '=', $values[$idCol]]],
'select' => $lookupNeeded,
])->first();
if ($record) {
$values += $record;
'where' => [['name', '=', $fkFrom]],
])->first()['fk_entity'] ?? NULL;
if (!empty($values[$fkFrom]) && $fkEntity) {
$values[$fieldName] = \civicrm_api4($fkEntity, 'get', [
'checkPermissions' => FALSE,
'where' => [['id', '=', $values[$fkFrom]]],
'select' => [$fkTo],
])->first()[$fkTo] ?? NULL;
}
}
}
$this->values = $values;
return $values;
}

/**
Expand Down
18 changes: 16 additions & 2 deletions tests/phpunit/api/v4/Custom/CustomFieldGetFieldsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ public function testCustomGetFieldsForParticipantSubTypes(): void {
->setRecords($sampleData)
->execute();

// CustomGroup based on Event Type
// CustomGroup based on Event Type = Meeting|Conference
CustomGroup::create(FALSE)
->addValue('extends', 'Participant')
->addValue('extends_entity_column_id:name', 'ParticipantEventType')
Expand All @@ -234,7 +234,7 @@ public function testCustomGetFieldsForParticipantSubTypes(): void {
)
->execute();

// CustomGroup based on Participant Status
// CustomGroup based on Participant Role
CustomGroup::create(FALSE)
->addValue('extends', 'Participant')
->addValue('extends_entity_column_id:name', 'ParticipantRole')
Expand Down Expand Up @@ -307,6 +307,20 @@ public function testCustomGetFieldsForParticipantSubTypes(): void {
$this->assertArrayHasKey('volunteer_host.sub_field', $participant3Fields);
$this->assertArrayNotHasKey('event_3_and_3.sub_field', $participant3Fields);
$this->assertArrayHasKey('always.on', $participant3Fields);

$event1Fields = Participant::getFields(FALSE)
->addValue('event_id', $event1['id'])
->execute()->indexBy('name');
$this->assertArrayHasKey('meeting_conference.sub_field', $event1Fields);
$this->assertArrayNotHasKey('event_2_and_3.sub_field', $event1Fields);
$this->assertArrayHasKey('always.on', $event1Fields);

$event4Fields = Participant::getFields(FALSE)
->addValue('event_id', $event4['id'])
->execute()->indexBy('name');
$this->assertArrayNotHasKey('meeting_conference.sub_field', $event4Fields);
$this->assertArrayNotHasKey('event_3_and_3.sub_field', $event4Fields);
$this->assertArrayHasKey('always.on', $event4Fields);
}

public function testFiltersAreReturnedForContactRefFields(): void {
Expand Down

0 comments on commit bb61894

Please sign in to comment.