$params += [
'checkPermissions' => FALSE,
'loadOptions' => ['id', 'label'],
- 'action' => 'create',
+ 'action' => 'update',
'select' => ['name', 'label', 'input_type', 'input_attrs', 'required', 'options', 'help_pre', 'help_post', 'serialize', 'data_type', 'fk_entity', 'readonly'],
'where' => [['input_type', 'IS NOT NULL']],
];
}
// Index by name
$fields = array_column($fields, NULL, 'name');
- // Mix in alterations declared by afform entities
- if ($params['action'] === 'create') {
+ if ($params['action'] === 'update') {
+ // Add existing entity field
+ $idField = CoreUtil::getIdFieldName($entityName);
+ $fields[$idField]['readonly'] = FALSE;
+ $fields[$idField]['input_type'] = 'EntityRef';
+ $fields[$idField]['is_id'] = TRUE;
+ $fields[$idField]['label'] = E::ts('Existing %1', [1 => CoreUtil::getInfoItem($entityName, 'title')]);
+ // Mix in alterations declared by afform entities
$afEntity = self::getMetadata()['entities'][$entityName] ?? [];
if (!empty($afEntity['alterFields'])) {
foreach ($afEntity['alterFields'] as $fieldName => $changes) {
}
}
- $getFieldsMode = 'create';
+ $getFieldsMode = 'update';
// Generate list of possibly embedded afform tags to search for
$allAfforms = \Civi::service('afform_scanner')->findFilePaths();
};
this.getFkEntity = function() {
- var fkEntity = ctrl.getDefn().fk_entity;
+ var defn = ctrl.getDefn(),
+ fkEntity = defn.is_id ? ctrl.container.getMainEntityType() : defn.fk_entity;
return ctrl.editor.meta.entities[fkEntity];
};
$this->entities[$entity]['fields'] = $this->entities[$entity]['joins'] = [];
}
// Pre-load full list of afforms in case this layout embeds other afform directives
- $this->blocks = (array) Afform::get()->setCheckPermissions(FALSE)->setSelect(['name', 'directive_name'])->execute()->indexBy('directive_name');
+ $this->blocks = (array) Afform::get(FALSE)->setSelect(['name', 'directive_name'])->execute()->indexBy('directive_name');
$this->parseFields($layout);
}
// Recurse into embedded blocks
if (isset($this->blocks[$node['#tag']])) {
if (!isset($this->blocks[$node['#tag']]['layout'])) {
- $this->blocks[$node['#tag']] = Afform::get()->setCheckPermissions(FALSE)->setSelect(['name', 'layout'])->addWhere('name', '=', $this->blocks[$node['#tag']]['name'])->execute()->first();
+ $this->blocks[$node['#tag']] = Afform::get(FALSE)->setSelect(['name', 'layout'])->addWhere('name', '=', $this->blocks[$node['#tag']]['name'])->execute()->first();
}
if (!empty($this->blocks[$node['#tag']]['layout'])) {
$this->parseFields($this->blocks[$node['#tag']]['layout'], $entity, $join, $searchDisplay);
--- /dev/null
+<?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 |
+ +--------------------------------------------------------------------+
+ */
+
+namespace Civi\Api4\Subscriber;
+
+use Civi\Afform\FormDataModel;
+use Civi\API\Events;
+use Civi\Api4\Afform;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * Preprocess api autocomplete requests
+ */
+class AutocompleteSubscriber implements EventSubscriberInterface {
+
+ /**
+ * @return array
+ */
+ public static function getSubscribedEvents() {
+ return [
+ 'civi.api.prepare' => ['onApiPrepare', Events::W_MIDDLE],
+ ];
+ }
+
+ /**
+ * @param \Civi\API\Event\PrepareEvent $event
+ * API preparation event.
+ */
+ public function onApiPrepare(\Civi\API\Event\PrepareEvent $event) {
+ $apiRequest = $event->getApiRequest();
+ if (is_object($apiRequest) && is_a($apiRequest, 'Civi\Api4\Generic\AutocompleteAction')) {
+ $formName = $apiRequest->getFormName();
+ if (!$formName || !str_starts_with('afform:', $formName) || !strpos(':', $apiRequest->getFieldName() ?: '')) {
+ return;
+ }
+ [$entityName, $fieldName] = explode(':', $apiRequest->getFieldName());
+ // Load afform only if user has permission
+ $afform = Afform::get()
+ ->addWhere('name', '=', str_replace('afform:', '', $formName))
+ ->addSelect('layout')
+ ->setLayoutFormat('shallow')
+ ->execute()->first();
+ if (!$afform) {
+ return;
+ }
+ $formDataModel = new FormDataModel($afform['layout']);
+ $entity = $formDataModel->getEntity($entityName);
+ $field = $entity['fields'][$fieldName] ?? NULL;
+ if ($field) {
+ $apiRequest->setCheckPermissions(empty($field['defn']['bypass_permission']));
+ $apiRequest->setSavedSearch($field['defn']['saved_search'] ?? NULL);
+ }
+ }
+ }
+
+}
$dispatcher->addListener('hook_civicrm_alterAngular', ['\Civi\Afform\AfformMetadataInjector', 'preprocess']);
$dispatcher->addListener('hook_civicrm_check', ['\Civi\Afform\StatusChecks', 'hook_civicrm_check']);
$dispatcher->addListener('civi.afform.get', ['\Civi\Api4\Action\Afform\Get', 'getCustomGroupBlocks']);
+ $dispatcher->addSubscriber(new \Civi\Api4\Subscriber\AutocompleteSubscriber());
// Register support for email tokens
if (CRM_Extension_System::singleton()->getMapper()->isActiveModule('authx')) {