131 lines
3.8 KiB
PHP
131 lines
3.8 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Service;
|
|
use App\Models\ServiceAgendaItem;
|
|
use App\Models\Setting;
|
|
use Illuminate\Support\Arr;
|
|
use Illuminate\Support\Str;
|
|
|
|
class NameTagResolver
|
|
{
|
|
public function __construct(
|
|
private readonly AgendaMatcherService $agendaMatcherService,
|
|
) {}
|
|
|
|
public function moderatorFor(Service $service): ?string
|
|
{
|
|
$override = $this->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<int, string> */
|
|
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 !== '',
|
|
));
|
|
}
|
|
}
|