Raiju/api/form-submit.php
2026-10-25 06:05:42 +03:00

133 lines
4.8 KiB
PHP

<?php
/**
* Generic JSON-backed form submission endpoint.
*/
header('Content-Type: application/json; charset=utf-8');
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode(['success' => false, 'message' => 'Method not allowed']);
exit;
}
require_once __DIR__ . '/../includes/forms.php';
$lang = $_POST['lang'] ?? 'de';
$formId = raijuFormIdClean((string)($_POST['form_id'] ?? ''));
$form = $formId ? raijuFormLoad($formId) : null;
$clientKey = raijuFormClientKey();
function raijuFormSubmitResponse(bool $success, string $message, array $extra = [], int $status = 200): void
{
http_response_code($status);
echo json_encode(array_merge([
'success' => $success,
'message' => $message,
], $extra), JSON_UNESCAPED_UNICODE);
exit;
}
if (!$form || empty($form['enabled'])) {
raijuFormSubmitResponse(false, $lang === 'de' ? 'Formular nicht gefunden.' : 'Form not found.', [], 404);
}
if (!raijuFormReserveRequest($clientKey)) {
raijuFormSubmitResponse(false, $lang === 'de' ? 'Zu viele Versuche. Bitte versuchen Sie es später erneut.' : 'Too many attempts. Please try again later.', [], 429);
}
if (!empty($_POST['website'])) {
raijuFormRecordAttempt($clientKey, false);
raijuFormSubmitResponse(true, (string)($form['submit']['successText'] ?? 'Vielen Dank.'));
}
$tokenResult = raijuValidateFormToken($_POST['form_token'] ?? null, $form['id']);
if (empty($tokenResult['valid'])) {
raijuFormRecordAttempt($clientKey, false);
raijuFormSubmitResponse(false, $lang === 'de'
? 'Das Formular ist abgelaufen oder wurde zu schnell gesendet. Bitte versuchen Sie es erneut.'
: 'The form expired or was submitted too quickly. Please try again.', [
'formToken' => raijuCreateFormToken($form['id']),
], 400);
}
[$errors, $values] = raijuFormValidateSubmission($form, (string)$lang);
if ($errors) {
raijuFormRecordAttempt($clientKey, false);
raijuFormSubmitResponse(false, implode(', ', $errors), [
'formToken' => raijuCreateFormToken($form['id']),
]);
}
if (raijuFormLooksLikeSpam($values)) {
raijuFormRecordAttempt($clientKey, false);
raijuFormSubmitResponse(false, $lang === 'de'
? 'Die Nachricht konnte nicht gesendet werden. Bitte prüfen Sie Ihre Eingaben.'
: 'The message could not be sent. Please check your input.', [
'formToken' => raijuCreateFormToken($form['id']),
]);
}
$subject = raijuFormsApplySubjectTemplate((string)($form['submit']['subject'] ?? ''), $form, $values);
$body = raijuFormsBuildBody($form, $values);
$sent = false;
if (!empty($form['submit']['email'])) {
$sent = raijuFormsSendNotification($form, $values, $subject, $body);
}
$store = !array_key_exists('store', $form['submit']) || !empty($form['submit']['store']);
$saved = true;
if ($store) {
$fieldRows = [];
foreach ($form['fields'] as $field) {
if (in_array(($field['type'] ?? ''), ['heading', 'note', 'hidden'], true)) {
continue;
}
$fieldRows[] = [
'key' => $field['key'],
'label' => $field['label'],
'type' => $field['type'],
'value' => $values[$field['key']] ?? '',
];
}
$saved = raijuFormsSaveSubmission([
'id' => uniqid('mail_', true),
'formId' => $form['id'],
'formLabel' => $form['label'],
'name' => $values['name'] ?? ($values['email'] ?? $form['label']),
'email' => $values['email'] ?? '',
'phone' => $values['phone'] ?? '',
'occasion' => $subject,
'message' => $values['message'] ?? '',
'fields' => $fieldRows,
'timestamp' => date('c'),
'status' => $sent ? 'sent' : (!empty($form['submit']['email']) ? 'send_failed' : 'local_only'),
'read' => false,
'starred' => false,
]);
}
if (!$saved) {
raijuFormRecordAttempt($clientKey, false);
raijuFormSubmitResponse(false, $lang === 'de'
? 'Die Nachricht konnte nicht gespeichert werden. Bitte versuchen Sie es später erneut.'
: 'The message could not be saved. Please try again later.', [
'formToken' => raijuCreateFormToken($form['id']),
], 500);
}
// A successful response requires at least one actual delivery channel.
if (!$store && !$sent) {
raijuFormRecordAttempt($clientKey, false);
raijuFormSubmitResponse(false, $lang === 'de'
? 'Die Nachricht konnte nicht gesendet werden. Bitte versuchen Sie es später erneut.'
: 'The message could not be sent. Please try again later.', [
'formToken' => raijuCreateFormToken($form['id']),
], 503);
}
raijuFormRecordAttempt($clientKey, true);
raijuFormSubmitResponse(true, (string)($form['submit']['successText'] ?? 'Vielen Dank.'), [
'formToken' => raijuCreateFormToken($form['id']),
]);