optimizations

This commit is contained in:
2026-03-28 19:15:39 +01:00
parent 0b25d9570a
commit cab4fbd83e
509 changed files with 1016804 additions and 1605 deletions

View File

@@ -0,0 +1,120 @@
<?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;
}
}