schema = $schema; } /** * @param array $submission * @return array}> */ public function formatSteps(array $submission): array { $formData = (array) ($submission['form_data'] ?? []); $formData['is_minor'] = $this->deriveIsMinor($formData); $submissionEmail = trim((string) ($submission['email'] ?? '')); $result = []; foreach ($this->schema->getSteps() as $step) { $title = (string) ($step['title'] ?? ''); $fields = []; foreach (($step['fields'] ?? []) as $fieldDef) { $key = (string) ($fieldDef['key'] ?? ''); $type = (string) ($fieldDef['type'] ?? 'text'); if ($key === '' || $type === 'file') { continue; } if (!$this->isVisible($fieldDef, $formData)) { continue; } $raw = $formData[$key] ?? null; if ($raw === null || $raw === '' || $raw === []) { continue; } $label = (string) ($fieldDef['label'] ?? $key); $value = $this->formatValue($raw, $fieldDef); $fields[] = ['label' => $label, 'value' => $value]; } if ($this->isPersonalDataStep($title) && $submissionEmail !== '' && !$this->hasEmailField($fields)) { $fields[] = ['label' => 'E-Mail', 'value' => $submissionEmail]; } if ($fields !== []) { $result[] = ['title' => $title, 'fields' => $fields]; } } return $result; } /** * @param array $submission * @return array}> */ public function formatUploads(array $submission): array { $uploads = (array) ($submission['uploads'] ?? []); $uploadFields = $this->schema->getUploadFields(); $result = []; foreach ($uploadFields as $key => $fieldDef) { $files = $uploads[$key] ?? []; if (!is_array($files) || $files === []) { continue; } $label = (string) ($fieldDef['label'] ?? $key); $names = []; foreach ($files as $file) { if (is_array($file)) { $names[] = (string) ($file['original_filename'] ?? 'Datei'); } } if ($names !== []) { $result[] = ['label' => $label, 'files' => $names]; } } return $result; } /** @param array $fieldDef */ private function formatValue(mixed $raw, array $fieldDef): string { $type = (string) ($fieldDef['type'] ?? 'text'); if ($type === 'date' && is_string($raw)) { return $this->formatDate($raw); } if ($type === 'checkbox') { return ((string) $raw === '1' || $raw === true) ? 'Ja' : 'Nein'; } if ($type === 'select' && is_string($raw)) { return $this->resolveSelectLabel($raw, $fieldDef); } if ($type === 'table' && is_array($raw)) { return $this->formatTable($raw, $fieldDef); } if (is_scalar($raw)) { return (string) $raw; } return json_encode($raw, JSON_UNESCAPED_UNICODE) ?: ''; } private function formatDate(string $value): string { $ts = strtotime($value); if ($ts === false) { return $value; } return date('d.m.Y', $ts); } /** @param array $fieldDef */ private function resolveSelectLabel(string $value, array $fieldDef): string { foreach (($fieldDef['options'] ?? []) as $opt) { if (is_array($opt) && (string) ($opt['value'] ?? '') === $value) { return (string) ($opt['label'] ?? $value); } } return $value; } /** @param array $fieldDef */ private function formatTable(array $rows, array $fieldDef): string { $columns = $fieldDef['columns'] ?? []; if (!is_array($columns) || $columns === []) { return ''; } $lines = []; foreach ($rows as $row) { if (!is_array($row)) { continue; } $cells = []; $hasContent = false; foreach ($columns as $i => $col) { $cellValue = (string) ($row[$i] ?? ''); $colType = (string) ($col['type'] ?? 'text'); if ($colType === 'date' && $cellValue !== '') { $cellValue = $this->formatDate($cellValue); } if ($cellValue !== '') { $hasContent = true; } $colLabel = (string) ($col['label'] ?? ''); $cells[] = $colLabel . ': ' . $cellValue; } if ($hasContent) { $lines[] = implode(' | ', $cells); } } return implode("\n", $lines); } /** @param array $fieldDef */ private function isVisible(array $fieldDef, array $formData): bool { if (isset($fieldDef['visible_if'])) { $cond = $fieldDef['visible_if']; $field = (string) ($cond['field'] ?? ''); $expected = (string) ($cond['equals'] ?? ''); $actual = (string) ($formData[$field] ?? ''); if ($actual !== $expected) { return false; } } if (isset($fieldDef['hidden_if'])) { $cond = $fieldDef['hidden_if']; $field = (string) ($cond['field'] ?? ''); $expected = (string) ($cond['equals'] ?? ''); $actual = (string) ($formData[$field] ?? ''); if ($actual === $expected) { return false; } } return true; } private function isPersonalDataStep(string $title): bool { return trim($title) === 'Persönliche Daten'; } /** @param array $fields */ private function hasEmailField(array $fields): bool { foreach ($fields as $field) { if (strtolower(trim((string) ($field['label'] ?? ''))) === 'e-mail') { return true; } } return false; } /** @param array $formData */ private function deriveIsMinor(array $formData): string { $birthdate = trim((string) ($formData['geburtsdatum'] ?? '')); if ($birthdate === '') { return '0'; } $date = \DateTimeImmutable::createFromFormat('!Y-m-d', $birthdate); if (!$date || $date->format('Y-m-d') !== $birthdate) { return '0'; } $today = new \DateTimeImmutable('today'); if ($date > $today) { return '0'; } return $date->diff($today)->y < 18 ? '1' : '0'; } }