--- /dev/null
+<?php
+namespace Civi\Afform\Event;
+
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Class AfformSubmitEvent
+ * @package Civi\Afform\Event
+ *
+ * Handle submission of an "<af-form>".
+ * Listeners ought to take any recognized items from `entityValues`, handle
+ * them, and remove them.
+ *
+ * NOTE: I'm on the fence about whether to expose the arrays or more targeted
+ * methods. For the moment, this is only expected to be used internally,
+ * so KISS.
+ */
+class AfformSubmitEvent extends Event {
+
+ /**
+ * @var array
+ * List of definitions of the entities.
+ * $entityDefns['spouse'] = ['type' => 'Individual'];
+ */
+ public $entityDefns;
+
+ /**
+ * @var array
+ * List of submitted entities to save.
+ * $entityValues['Contact']['spouse'] = ['first_name' => 'Optimus Prime'];
+ */
+ public $entityValues;
+
+ /**
+ * AfformSubmitEvent constructor.
+ * @param $entityDefns
+ * @param array $entityValues
+ */
+ public function __construct($entityDefns, array $entityValues) {
+ $this->entityDefns = $entityDefns;
+ $this->entityValues = $entityValues;
+ }
+
+ /**
+ * List of entity types which need processing.
+ *
+ * @return array
+ * Ex: ['Contact', 'Activity']
+ */
+ public function getTypes() {
+ return array_keys($this->entityValues);
+ }
+
+}
namespace Civi\Api4\Action\Afform;
+use Civi\Afform\Event\AfformSubmitEvent;
+
/**
* Class Submit
* @package Civi\Api4\Action\Afform
*/
class Submit extends AbstractProcessor {
+ const EVENT_NAME = 'civi.afform.submit';
+
/**
* Submitted values
* @var array
*/
protected $values;
- /**
- * @var array
- */
- protected $_submission = [];
-
protected function processForm() {
+ $entityValues = [];
foreach ($this->_afformEntities as $entityName => $entity) {
// Predetermined values override submitted values
- $this->_submission[$entity['type']][$entityName] = ($entity['af-values'] ?? []) + ($this->values[$entityName] ?? []);
+ $entityValues[$entity['type']][$entityName] = ($entity['af-values'] ?? []) + ($this->values[$entityName] ?? []);
}
- // Determines the order in which to process entities. Contacts go first.
- $entitiesToProcess = [
- 'Contact' => 'processContacts',
- 'Activity' => 'processActivities',
- ];
- foreach ($entitiesToProcess as $entityType => $callback) {
- if (!empty($this->_submission[$entityType])) {
- $this->$callback($this->_submission[$entityType]);
- }
- }
- foreach (array_diff_key($this->_submission, $entitiesToProcess) as $entityType) {
+ $event = new AfformSubmitEvent($this->_afformEntities, $entityValues);
+ \Civi::dispatcher()->dispatch(self::EVENT_NAME, $event);
+ foreach ($event->entityValues as $entityType => $entities) {
+ if (!empty($entities)) {
+ throw new \API_Exception(sprintf("Failed to process entities (type=%s; name=%s)", $entityType, implode(',', array_keys($entities))));
+ }
}
- }
- protected function processGenericEntity($entityType, $items) {
- foreach ($items as $name => $item) {
- civicrm_api4($entityType, 'save', $items);
- }
+ // What should I return?
+ return [];
}
- protected function processContacts($contacts) {
- foreach ($contacts as $name => $contact) {
+ ///**
+ // * @param \Civi\Afform\Event\AfformSubmitEvent $event
+ // * @see afform_civicrm_config
+ // */
+ //public function processContacts(AfformSubmitEvent $event) {
+ // if (empty($event->entityValues['Contact'])) {
+ // return;
+ // }
+ // foreach ($event->entityValues['Contact'] as $entityName => $contact) {
+ // // Do something
+ // unset($event->entityValues['Contact'][$entityName]);
+ // }
+ //}
+ /**
+ * @param \Civi\Afform\Event\AfformSubmitEvent $event
+ * @see afform_civicrm_config
+ */
+ public static function processGenericEntity(AfformSubmitEvent $event) {
+ foreach ($event->entityValues as $entityType => $records) {
+ civicrm_api4($entityType, 'save', [
+ 'records' => $records,
+ ]);
+ unset($event->entityValues[$entityType]);
}
}
require_once 'afform.civix.php';
use CRM_Afform_ExtensionUtil as E;
+use Civi\Api4\Action\Afform\Submit;
function _afform_fields() {
return ['name', 'title', 'description', 'requires', 'layout', 'server_route', 'client_route', 'is_public'];
*/
function afform_civicrm_config(&$config) {
_afform_civix_civicrm_config($config);
+ // Civi::dispatcher()->addListener(Submit::EVENT_NAME, [Submit::class, 'processContacts'], -500);
+ Civi::dispatcher()->addListener(Submit::EVENT_NAME, [Submit::class, 'processGenericEntity'], -1000);
}
/**