filledString($service->moderator_name); if ($override !== null) { return $override; } $firstAgendaItem = $service->agendaItems() ->where('is_before_event', false) ->orderBy('sort_order') ->orderBy('id') ->first(); return $firstAgendaItem ? $this->namesFromResponsible($firstAgendaItem->responsible) : null; } public function preacherFor(Service $service): ?string { $override = $this->filledString($service->preacher_name_override); if ($override !== null) { return $override; } $preacherName = $this->filledString($service->preacher_name); if ($preacherName !== null) { return $preacherName; } $sermonItem = $service->agendaItems() ->where('is_before_event', false) ->whereNull('service_song_id') ->orderBy('sort_order') ->orderBy('id') ->get() ->first(fn (ServiceAgendaItem $item) => $this->isSermonItem($item)); return $sermonItem ? $this->namesFromResponsible($sermonItem->responsible) : null; } private function filledString(?string $value): ?string { $trimmed = trim((string) $value); return $trimmed === '' ? null : $trimmed; } private function namesFromResponsible(mixed $responsible): ?string { if (! is_array($responsible) || $responsible === []) { return null; } $people = Arr::isAssoc($responsible) ? [$responsible] : $responsible; $names = collect($people) ->map(fn (mixed $person) => $this->nameFromResponsiblePerson($person)) ->filter() ->values() ->all(); return $names === [] ? null : implode(', ', $names); } private function nameFromResponsiblePerson(mixed $person): ?string { if (is_string($person)) { return $this->filledString($person); } if (! is_array($person)) { return null; } $name = $this->filledString($person['name'] ?? null); if ($name !== null) { return $name; } $firstName = $this->filledString($person['firstName'] ?? $person['first_name'] ?? null) ?? ''; $lastName = $this->filledString($person['lastName'] ?? $person['last_name'] ?? null) ?? ''; $fullName = trim($firstName.' '.$lastName); return $fullName === '' ? null : $fullName; } private function isSermonItem(ServiceAgendaItem $item): bool { $configuredPatterns = $this->patternsFromSetting(Setting::get('agenda_sermon_matching')); if ($configuredPatterns !== []) { return $this->agendaMatcherService->matchesAny($item->title, $configuredPatterns); } $title = Str::lower($item->title); $type = Str::lower($item->type ?? ''); return str_contains($title, 'predigt') || str_contains($title, 'sermon') || str_contains($type, 'predigt') || str_contains($type, 'sermon'); } /** @return array */ private function patternsFromSetting(?string $patterns): array { if ($patterns === null || trim($patterns) === '') { return []; } return array_values(array_filter( array_map(fn (string $pattern) => trim($pattern), explode(',', $patterns)), fn (string $pattern) => $pattern !== '', )); } }