2026-06-11 19:03:29 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
use Reservair\Logger\Logger;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handles submitting a form. If any element fails, nothing is persisted.
|
|
|
|
|
*/
|
|
|
|
|
class RsvFormSubmission {
|
|
|
|
|
public function submit(string $formId, array $data) : array {
|
|
|
|
|
$repo = new RsvFormDefinitionRepository();
|
|
|
|
|
$row = $repo->get((int) $formId);
|
|
|
|
|
|
|
|
|
|
if ($row === null) {
|
|
|
|
|
return ['success' => false, 'errors' => [['element' => '', 'code' => 'not_found', 'message' => 'Form not found']]];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$definition = new RsvFormDefinition($formId, $row['definition']);
|
|
|
|
|
$form_data = new RsvFormData($data);
|
|
|
|
|
$processor = new RsvFormProcessor();
|
|
|
|
|
|
|
|
|
|
// Persist the submission first so element handlers can link to it.
|
|
|
|
|
$submit_repo = new RsvFormSubmitRepository();
|
|
|
|
|
$submit_id = $submit_repo->add((int) $definition->getId(), $data);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
$result = $processor->submit($definition, $submit_id, $form_data);
|
|
|
|
|
} catch (\Throwable $e) {
|
|
|
|
|
Logger::error($e);
|
|
|
|
|
$this->discard_submission($submit_repo, $submit_id);
|
|
|
|
|
return ['success' => false, 'errors' => [['element' => '', 'code' => 'internal_error', 'message' => 'An unexpected error occurred.']]];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($result->hasErrors()) {
|
|
|
|
|
$this->discard_submission($submit_repo, $submit_id);
|
|
|
|
|
return ['success' => false, 'errors' => $result->getErrors()];
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-22 11:20:28 +02:00
|
|
|
global $rsv_template_registry;
|
|
|
|
|
$message = trim($definition->getSuccessMessage());
|
|
|
|
|
if ($message !== '') {
|
|
|
|
|
$allowed = $rsv_template_registry->kses_allowed(wp_kses_allowed_html('post'));
|
|
|
|
|
$template = wp_kses($message, $allowed);
|
|
|
|
|
} else {
|
|
|
|
|
$template = '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$data = array_merge($result->getValues(), (new RsvFormCalculatedValues())->for($definition, $form_data));
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
$submit_repo->set_computed($submit_id, $data);
|
|
|
|
|
} catch (\Throwable $e) {
|
|
|
|
|
Logger::error($e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ['success' => true, 'submit_id' => $submit_id, 'template' => $template, 'data' => $data];
|
2026-06-11 19:03:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Remove a submission whose run failed. */
|
|
|
|
|
private function discard_submission(RsvFormSubmitRepository $repo, int $submit_id): void {
|
|
|
|
|
try {
|
|
|
|
|
$repo->delete($submit_id);
|
|
|
|
|
} catch (\Throwable $e) {
|
|
|
|
|
Logger::error($e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|