From 37bc0f615e1677acfd173a56e4de59cc76597977 Mon Sep 17 00:00:00 2001 From: Seamus Lee Date: Thu, 6 May 2021 18:34:03 +1000 Subject: [PATCH] WIP Entity Reference Submission fields --- .../Civi/Afform/Event/AfformSubmitEvent.php | 19 +++++++++- .../core/Civi/Api4/Action/Afform/Submit.php | 38 ++++++++++++++----- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/ext/afform/core/Civi/Afform/Event/AfformSubmitEvent.php b/ext/afform/core/Civi/Afform/Event/AfformSubmitEvent.php index 88112fd873..f2bdf951aa 100644 --- a/ext/afform/core/Civi/Afform/Event/AfformSubmitEvent.php +++ b/ext/afform/core/Civi/Afform/Event/AfformSubmitEvent.php @@ -32,6 +32,17 @@ class AfformSubmitEvent extends AfformBaseEvent { */ public $entityValues; + /** + * @var array + * List of Submitted Entities and their matching ids + * $entityIds['Individual1'] = 1; + */ + public $entityIds; + + public $entityWeights; + + public $entityMapping; + /** * AfformSubmitEvent constructor. * @@ -40,11 +51,17 @@ class AfformSubmitEvent extends AfformBaseEvent { * @param \Civi\Api4\Action\Afform\Submit $apiRequest * @param array $entityDefns * @param array $entityValues + * @param array $entityIds + * @param array $entityWeights + * @param array $entityMapping */ - public function __construct(array $afform, FormDataModel $formDataModel, Submit $apiRequest, $entityDefns, array $entityValues) { + public function __construct(array $afform, FormDataModel $formDataModel, Submit $apiRequest, $entityDefns, array $entityValues, array $entityIds, array $entityWeights, array $entityMapping) { parent::__construct($afform, $formDataModel, $apiRequest); $this->entityDefns = $entityDefns; $this->entityValues = $entityValues; + $this->entityIds = $entityIds; + $this->entityWeights = $entityWeights; + $this->entityMapping = $entityMapping; } /** diff --git a/ext/afform/core/Civi/Api4/Action/Afform/Submit.php b/ext/afform/core/Civi/Api4/Action/Afform/Submit.php index ec505c10c4..b79b807150 100644 --- a/ext/afform/core/Civi/Api4/Action/Afform/Submit.php +++ b/ext/afform/core/Civi/Api4/Action/Afform/Submit.php @@ -20,8 +20,11 @@ class Submit extends AbstractProcessor { protected $values; protected function processForm() { - $entityValues = []; + $entityValues = $entityIds = $entityWeights = $entityMapping = []; foreach ($this->_formDataModel->getEntities() as $entityName => $entity) { + $entityIds[$entityName] = NULL; + $entityWeights[$entityName] = 1; + $entityMapping[$entityName] = $entity['type']; foreach ($this->values[$entityName] ?? [] as $values) { $entityValues[$entity['type']][$entityName][] = $values + ['fields' => []]; // Predetermined values override submitted values @@ -31,8 +34,17 @@ class Submit extends AbstractProcessor { } } } + foreach ($entityValues[$entity['type']][$entityName] as $index => $vals) { + foreach ($vals as $field => $value) { + if (in_array($value, array_keys($entityWeights))) { + $entityWeights[$entityName] = max((int) $entityWeights[$entityName], (int) ($entityWeights[$value] + 1)); + } + } + } } - $event = new AfformSubmitEvent($this->_afform, $this->_formDataModel, $this, $this->_formDataModel->getEntities(), $entityValues); + // Numerically sort the weights smallest to largest. + asort($entityWeights); + $event = new AfformSubmitEvent($this->_afform, $this->_formDataModel, $this, $this->_formDataModel->getEntities(), $entityValues, $entityIds, $entityWeights, $entityMapping); \Civi::dispatcher()->dispatch(self::EVENT_NAME, $event); foreach ($event->entityValues as $entityType => $entities) { if (!empty($entities)) { @@ -54,6 +66,7 @@ class Submit extends AbstractProcessor { $api4 = $event->formDataModel->getSecureApi4($entityName); foreach ($contacts as $contact) { $saved = $api4('Contact', 'save', ['records' => [$contact['fields']]])->first(); + $event->entityIds[$entityName] = $saved['id']; self::saveJoins('Contact', $saved['id'], $contact['joins'] ?? []); } } @@ -66,17 +79,22 @@ class Submit extends AbstractProcessor { * @see afform_civicrm_config */ public static function processGenericEntity(AfformSubmitEvent $event) { - foreach ($event->entityValues as $entityType => $entities) { - // Each record is an array of one or more items (can be > 1 if af-repeat is used) - foreach ($entities as $entityName => $records) { - $api4 = $event->formDataModel->getSecureApi4($entityName); - foreach ($records as $record) { - $saved = $api4($entityType, 'save', ['records' => [$record['fields']]])->first(); - self::saveJoins($entityType, $saved['id'], $record['joins'] ?? []); + foreach ($event->entityWeights as $entityName => $weight) { + $records = $event->entityValues[$event->entityMapping[$entityName]][$entityName]; + $api4 = $event->formDataModel->getSecureApi4($entityName); + // Replace Entity reference fields that reference other form based entities with their created ids. + foreach ($records as $record) { + foreach ($record['fields'] as $field => $value) { + if (in_array($value, array_keys($event->entityIds)) && !empty($event->entityIds[$value])) { + $record['fields'][$field] = $event->entityIds[$value]; + } } + $saved = $api4($entityType, 'save', ['records' => [$record['fields']]])->first(); + $event->entityIds[$entityName] = $saved['id']; + self::saveJoins($entityType, $saved['id'], $record['joins'] ?? []); } - unset($event->entityValues[$entityType]); } + unset($event->entityValues[$entityType]); } protected static function saveJoins($mainEntityName, $entityId, $joins) { -- 2.25.1