121 lines
4.2 KiB
PHP
121 lines
4.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Collection;
|
|
use App\Models\User;
|
|
use Illuminate\Support\Collection as SupportCollection;
|
|
|
|
class CollectionSeriesService
|
|
{
|
|
public function __construct(
|
|
private readonly CollectionService $collections,
|
|
) {
|
|
}
|
|
|
|
public function updateSeries(Collection $collection, array $attributes, ?User $actor = null): Collection
|
|
{
|
|
return $this->collections->updateCollection(
|
|
$collection->loadMissing('user'),
|
|
$this->normalizeAttributes($attributes),
|
|
$actor,
|
|
);
|
|
}
|
|
|
|
public function metadataFor(Collection|SupportCollection $seriesSource): array
|
|
{
|
|
$items = $seriesSource instanceof Collection
|
|
? collect([$seriesSource])->when($seriesSource->series_key, fn (SupportCollection $current) => $current->concat($this->publicSeriesItems((string) $seriesSource->series_key)))
|
|
: $seriesSource;
|
|
|
|
$metaSource = $items
|
|
->first(fn (Collection $item) => filled($item->series_title) || filled($item->series_description));
|
|
|
|
return [
|
|
'title' => $metaSource?->series_title,
|
|
'description' => $metaSource?->series_description,
|
|
];
|
|
}
|
|
|
|
public function seriesContext(Collection $collection): array
|
|
{
|
|
if (! $collection->inSeries()) {
|
|
return [
|
|
'key' => null,
|
|
'title' => null,
|
|
'description' => null,
|
|
'items' => [],
|
|
'previous' => null,
|
|
'next' => null,
|
|
];
|
|
}
|
|
|
|
$items = Collection::query()
|
|
->public()
|
|
->where('series_key', $collection->series_key)
|
|
->with(['user:id,username,name', 'coverArtwork:id,user_id,title,slug,hash,thumb_ext,published_at,is_public,is_approved,deleted_at'])
|
|
->orderBy('series_order')
|
|
->orderBy('id')
|
|
->get();
|
|
|
|
$index = $items->search(fn (Collection $item) => (int) $item->id === (int) $collection->id);
|
|
|
|
return [
|
|
'key' => $collection->series_key,
|
|
'title' => $this->metadataFor($items->prepend($collection))['title'],
|
|
'description' => $this->metadataFor($items->prepend($collection))['description'],
|
|
'items' => $items,
|
|
'previous' => $index !== false && $index > 0 ? $items->get($index - 1) : null,
|
|
'next' => $index !== false ? $items->get($index + 1) : null,
|
|
];
|
|
}
|
|
|
|
public function publicSeriesItems(string $seriesKey): SupportCollection
|
|
{
|
|
return Collection::query()
|
|
->public()
|
|
->where('series_key', $seriesKey)
|
|
->with(['user:id,username,name', 'coverArtwork:id,user_id,title,slug,hash,thumb_ext,published_at,is_public,is_approved,deleted_at'])
|
|
->orderByRaw('CASE WHEN series_order IS NULL THEN 1 ELSE 0 END')
|
|
->orderBy('series_order')
|
|
->orderBy('id')
|
|
->get();
|
|
}
|
|
|
|
public function summary(Collection $collection): array
|
|
{
|
|
$context = $collection->inSeries()
|
|
? $this->seriesContext($collection)
|
|
: ['key' => null, 'title' => null, 'description' => null, 'items' => [], 'previous' => null, 'next' => null];
|
|
|
|
return [
|
|
'key' => $context['key'] ?? $collection->series_key,
|
|
'title' => $context['title'] ?? $collection->series_title,
|
|
'description' => $context['description'] ?? $collection->series_description,
|
|
'order' => $collection->series_order,
|
|
'siblings_count' => max(0, count($context['items'] ?? [])),
|
|
'previous_id' => $context['previous']?->id,
|
|
'next_id' => $context['next']?->id,
|
|
'public_url' => filled($collection->series_key)
|
|
? route('collections.series.show', ['seriesKey' => $collection->series_key])
|
|
: null,
|
|
];
|
|
}
|
|
|
|
private function normalizeAttributes(array $attributes): array
|
|
{
|
|
if (blank($attributes['series_key'] ?? null)) {
|
|
return [
|
|
'series_key' => null,
|
|
'series_title' => null,
|
|
'series_description' => null,
|
|
'series_order' => null,
|
|
];
|
|
}
|
|
|
|
return $attributes;
|
|
}
|
|
}
|