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

Add DAO fields to API metadata when the entity type name is known #127

Merged
merged 1 commit into from
Apr 25, 2024
Merged
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
46 changes: 46 additions & 0 deletions Civi/Api4/Service/Spec/Provider/EckEntitySpecProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Civi\Api4\Service\Spec\Provider;

use Civi\Api4\Service\Spec\RequestSpec;
use Civi\Api4\Service\Spec\SpecFormatter;

/**
* Class EckEntitySpecProvider
Expand All @@ -15,13 +16,58 @@ class EckEntitySpecProvider implements Generic\SpecProviderInterface {
* @param \Civi\Api4\Service\Spec\RequestSpec $spec
*/
public function modifySpec(RequestSpec $spec) {
// Add DAO fields, since they might not have been set by \Civi\Api4\Service\Spec\SpecGatherer::addDAOFields(), as
// CRM_Eck_DAO_Entity::fields() is static, but depends on the ECK entity type for compiling the field list.
$entityTypes = \CRM_Eck_BAO_EckEntityType::getEntityTypes();
$entityName = $spec->getEntity();
// Instantiate the BAO for initialization with the given ECK entity type.
$bao = new \CRM_Eck_BAO_Entity($entityTypes[$entityName]['name']);
foreach ($bao::getSupportedFields() as $DAOField) {
if (NULL === $spec->getFieldByName($DAOField['name'])) {
$this->setDynamicFk($DAOField, $spec);
$field = SpecFormatter::arrayToField($DAOField, $entityName);
$spec->addFieldSpec($field);
}
}

if (NULL !== ($subTypeField = $spec->getFieldByName('subtype'))) {
$subTypeField
->setSuffixes(['name', 'label', 'description', 'icon'])
->setOptionsCallback([$this, 'getSubTypes']);
}
}

/**
* Copied from \Civi\Api4\Service\Spec\SpecGatherer::setDynamicFk()
*
* Adds metadata about dynamic foreign key fields.
*
* E.g. some tables have a DFK with a pair of columns named `entity_table` and `entity_id`.
* This will gather the list of 'dfk_entities' to add as metadata to the e.g. `entity_id` column.
*
* Additionally, if $values contains a value for e.g. `entity_table`,
* then getFields will also output the corresponding `fk_entity` for the `entity_id` field.
*/
private function setDynamicFk(array &$DAOField, RequestSpec $spec): void {
if (empty($DAOField['FKClassName']) && !empty($DAOField['bao']) && $DAOField['type'] == \CRM_Utils_Type::T_INT) {
// Check if this field is a key for a dynamic FK
foreach ($DAOField['bao']::getReferenceColumns() ?? [] as $reference) {
if ($reference instanceof \CRM_Core_Reference_Dynamic && $reference->getReferenceKey() === $DAOField['name']) {
$entityTableColumn = $reference->getTypeColumn();
$DAOField['DFKEntities'] = $reference->getTargetEntities();
$DAOField['html']['controlField'] = $entityTableColumn;
// If we have a value for entity_table then this field can pretend to be a single FK too.
if ($spec->hasValue($entityTableColumn) && $DAOField['DFKEntities']) {
$DAOField['FKClassName'] = \CRM_Core_DAO_AllCoreTables::getDAONameForEntity(
$DAOField['DFKEntities'][$spec->getValue($entityTableColumn)]
);
}
break;
}
}
}
}

/**
* @param string $entity
* @param string $action
Expand Down
Loading