Additional event informations can be added
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Event\Actions\SetParticipationOptions;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class SetParticipationOptionsCommand
|
||||
{
|
||||
public function __construct(private SetParticipationOptionsRequest $request)
|
||||
{
|
||||
}
|
||||
|
||||
public function execute(): SetParticipationOptionsResponse
|
||||
{
|
||||
$response = new SetParticipationOptionsResponse();
|
||||
|
||||
$this->request->event->participation_options = $this->normalize($this->request->questions);
|
||||
$this->request->event->save();
|
||||
|
||||
$response->success = true;
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalisiert die rohe Fragen-Definition: trimmt Labels, generiert stabile Keys/Values und verwirft
|
||||
* unvollständige Fragen (kein Label oder keine gültige Option). Keys/Values sind innerhalb ihres
|
||||
* Geltungsbereichs eindeutig, damit Antworten robust referenzieren können.
|
||||
*
|
||||
* @param array<int, array<string, mixed>> $questions
|
||||
* @return array<int, array{key: string, label: string, options: array<int, array{value: string, label: string}>}>
|
||||
*/
|
||||
private function normalize(array $questions): array
|
||||
{
|
||||
$normalized = [];
|
||||
$usedKeys = [];
|
||||
|
||||
foreach ($questions as $question) {
|
||||
$label = trim((string)($question['label'] ?? ''));
|
||||
if ($label === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$options = $this->normalizeOptions($question['options'] ?? []);
|
||||
if ($options === []) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$key = $this->uniqueSlug((string)($question['key'] ?? ''), $label, $usedKeys);
|
||||
$usedKeys[] = $key;
|
||||
|
||||
$normalized[] = [
|
||||
'key' => $key,
|
||||
'label' => $label,
|
||||
'options' => $options,
|
||||
];
|
||||
}
|
||||
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, array<string, mixed>> $options
|
||||
* @return array<int, array{value: string, label: string}>
|
||||
*/
|
||||
private function normalizeOptions(mixed $options): array
|
||||
{
|
||||
if (!is_array($options)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$normalized = [];
|
||||
$usedValues = [];
|
||||
|
||||
foreach ($options as $option) {
|
||||
$label = trim((string)($option['label'] ?? ''));
|
||||
if ($label === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$value = $this->uniqueSlug((string)($option['value'] ?? ''), $label, $usedValues);
|
||||
$usedValues[] = $value;
|
||||
|
||||
$normalized[] = ['value' => $value, 'label' => $label];
|
||||
}
|
||||
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert einen eindeutigen Slug: bevorzugt den bestehenden Wert (Bestandsschutz für schon gespeicherte
|
||||
* Fragen/Antworten), sonst aus dem Label abgeleitet; Kollisionen werden durchnummeriert.
|
||||
*
|
||||
* @param array<int, string> $used
|
||||
*/
|
||||
private function uniqueSlug(string $existing, string $label, array $used): string
|
||||
{
|
||||
$base = $existing !== '' ? $existing : Str::slug($label);
|
||||
if ($base === '') {
|
||||
$base = 'option';
|
||||
}
|
||||
|
||||
$candidate = $base;
|
||||
$suffix = 2;
|
||||
while (in_array($candidate, $used, true)) {
|
||||
$candidate = $base . '-' . $suffix;
|
||||
$suffix++;
|
||||
}
|
||||
|
||||
return $candidate;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user