Skip to content

Commit d39eb76

Browse files
committed
feat: do not allow empty submissions
1 parent 909db54 commit d39eb76

File tree

12 files changed

+48
-1
lines changed

12 files changed

+48
-1
lines changed

classes/Fields/Field.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ public function validate(): true|string
9393
return true;
9494
}
9595

96+
/**
97+
* Check if the field value is empty
98+
*/
99+
public function isEmpty(): bool
100+
{
101+
return $this->value()->isEmpty();
102+
}
103+
96104
/**
97105
* Run logic after the form submission
98106
* e.g. for storing an uploaded file

classes/Fields/FileUploadField.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,24 @@ public function validate(): true|string
100100
return true;
101101
}
102102

103+
/**
104+
* Check if the file upload field is empty
105+
*/
106+
public function isEmpty(): bool
107+
{
108+
$files = $this->value()->value();
109+
110+
// if no files array, it's empty
111+
if (!is_array($files)) {
112+
return true;
113+
}
114+
115+
// check if any file was successfully uploaded (error code 0 = UPLOAD_ERR_OK)
116+
$uploadedFiles = array_filter($files, fn ($file) => is_array($file) && isset($file['error']) && $file['error'] === UPLOAD_ERR_OK);
117+
118+
return empty($uploadedFiles);
119+
}
120+
103121
// abusing the sanitize method to get the file from the request
104122
protected function sanitize(ContentField $value): ContentField
105123
{

classes/Models/SubmissionHandling.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ public function handleGuards(bool $postValidation = false): SubmissionPage
6565
public function handleFields()
6666
{
6767
$currentStep = App::instance()->request()->query()->get('dreamform-step', 1);
68+
$allFieldsEmpty = true;
69+
6870
foreach ($this->form()->fields($currentStep) as $field) {
6971
// skip "decorative" fields that don't have a value
7072
if (!$field::hasValue()) {
@@ -84,6 +86,16 @@ public function handleFields()
8486
} else {
8587
$this->removeError($field->key());
8688
}
89+
90+
// check if at least one field is not empty
91+
if (!$field->isEmpty()) {
92+
$allFieldsEmpty = false;
93+
}
94+
}
95+
96+
// reject submission if all fields are empty
97+
if ($allFieldsEmpty) {
98+
$this->setError(t('dreamform.submission.error.emptyFields'));
8799
}
88100

89101
return $this;

classes/Models/SubmissionPage.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,8 @@ public function status(): string
550550
*/
551551
public function isEmpty(): bool
552552
{
553-
foreach ($this->values()->toArray() as $value) {
553+
foreach ($this->values()->toArray() as $key => $value) {
554+
ray($key, $value);
554555
if ($value !== null && $value !== '' && $value !== []) {
555556
return false;
556557
}

i18n.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ checksums:
204204
submission.error.logType: 8ccade6dbadd811549681a5d47a0c228
205205
submission.error.ratelimit: ac3f18655245056d79a43b8d93ca142b
206206
submission.error.csrf: f50aaeec1b998d29fcf256fb9a56d914
207+
submission.error.emptyFields: 7609524fd93fe053e07424ed92c47938
207208
submission.ham: bca6fe1bceb5a6054dff6c1aed978a0d
208209
submission.log.error: a02e13357f41b47114edda8970846ef3
209210
submission.markedAs: 1acc2605319fdc4c375eddbec19ecb12

translations/cs.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@
202202
"submission.error.logType": "Typ položky „{{ type }}“ není platný.",
203203
"submission.error.ratelimit": "Formulář jste odeslali příliš často. Počkejte prosím chvíli a zkuste to znovu.",
204204
"submission.error.csrf": "Platnost formuláře vypršela. Znovu načtěte stránku a zkuste to znovu.",
205+
"submission.error.emptyFields": "Prosím vyplň alespoň jedno pole před odesláním.",
205206
"submission.ham": "Není spam",
206207
"submission.log.error": "Neznámá chyba v <strong>„{{ type }}“</strong>",
207208
"submission.markedAs": "Tato odpověď byla označena jako {{ status }}",

translations/de.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@
202202
"submission.error.logType": "Der Eintragstyp \"{{ type }}\" ist nicht gültig.",
203203
"submission.error.ratelimit": "Du hast das Formular zu häufig abgeschickt. Bitte warte einen Moment und versuche es erneut.",
204204
"submission.error.csrf": "Das Formular ist abgelaufen. Bitte lade die Seite neu und versuche es erneut.",
205+
"submission.error.emptyFields": "Bitte fülle mindestens ein Feld aus, bevor du absendest.",
205206
"submission.ham": "Kein Spam",
206207
"submission.log.error": "Unbekannter Fehler in <strong>\"{{ type }}\"</strong>",
207208
"submission.markedAs": "Diese Antwort wurde als {{ status }} markiert.",

translations/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@
202202
"submission.error.logType": "The submission log type \"{{ type }}\" is not valid.",
203203
"submission.error.ratelimit": "You've submitted the form too often. Please wait a moment and try again.",
204204
"submission.error.csrf": "The form expired. Please reload the page and try again.",
205+
"submission.error.emptyFields": "Please fill out at least one field before submitting.",
205206
"submission.ham": "Not Spam",
206207
"submission.log.error": "Unhandled error in performer <strong>\"{{ type }}\"</strong>",
207208
"submission.markedAs": "This answer is {{ status }}",

translations/es.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@
202202
"submission.error.logType": "El tipo de registro de envío \"{{ type }}\" no es válido.",
203203
"submission.error.ratelimit": "Has enviado el formulario demasiadas veces. Por favor, espera un momento e inténtalo de nuevo.",
204204
"submission.error.csrf": "El formulario ha expirado. Por favor, recarga la página e inténtalo de nuevo.",
205+
"submission.error.emptyFields": "Por favor, completa al menos un campo antes de enviar.",
205206
"submission.ham": "No es spam",
206207
"submission.log.error": "Error no controlado en el ejecutor <strong>\"{{ type }}\"</strong>",
207208
"submission.markedAs": "Esta respuesta está {{ status }}",

translations/fr.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@
202202
"submission.error.logType": "Le type de journal de soumission \"{{ type }}\" n'est pas valide.",
203203
"submission.error.ratelimit": "Vous avez soumis le formulaire trop souvent. Veuillez attendre un moment et réessayer.",
204204
"submission.error.csrf": "Le formulaire a expiré. Veuillez recharger la page et réessayer.",
205+
"submission.error.emptyFields": "Veuillez remplir au moins un champ avant de soumettre.",
205206
"submission.ham": "Pas du spam",
206207
"submission.log.error": "Erreur non gérée dans l'exécuteur <strong>\"{{ type }}\"</strong>",
207208
"submission.markedAs": "Cette réponse est {{ status }}",

0 commit comments

Comments
 (0)