optimizations
This commit is contained in:
116
app/Services/CollectionLinkedCollectionsService.php
Normal file
116
app/Services/CollectionLinkedCollectionsService.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Collection;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class CollectionLinkedCollectionsService
|
||||
{
|
||||
public function linkedCollections(Collection $collection): EloquentCollection
|
||||
{
|
||||
return $collection->manualRelatedCollections()
|
||||
->with(['user:id,username,name', 'coverArtwork:id,user_id,title,slug,hash,thumb_ext,published_at,is_public,is_approved,deleted_at'])
|
||||
->get();
|
||||
}
|
||||
|
||||
public function publicLinkedCollections(Collection $collection, int $limit = 6): EloquentCollection
|
||||
{
|
||||
return $collection->manualRelatedCollections()
|
||||
->public()
|
||||
->with(['user:id,username,name', 'coverArtwork:id,user_id,title,slug,hash,thumb_ext,published_at,is_public,is_approved,deleted_at'])
|
||||
->limit(max(1, min($limit, 12)))
|
||||
->get();
|
||||
}
|
||||
|
||||
public function manageableLinkOptions(Collection $collection, User $actor, int $limit = 24): EloquentCollection
|
||||
{
|
||||
$linkedIds = $collection->manualRelatedCollections()->pluck('collections.id')->map(static fn ($id) => (int) $id)->all();
|
||||
|
||||
return Collection::query()
|
||||
->with([
|
||||
'user:id,username,name',
|
||||
'members',
|
||||
'coverArtwork:id,user_id,title,slug,hash,thumb_ext,published_at,is_public,is_approved,deleted_at',
|
||||
])
|
||||
->where('id', '!=', $collection->id)
|
||||
->whereNotIn('id', $linkedIds)
|
||||
->orderByDesc('updated_at')
|
||||
->get()
|
||||
->filter(fn (Collection $candidate): bool => $candidate->canBeManagedBy($actor))
|
||||
->take(max(1, min($limit, 48)))
|
||||
->values();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, int|string> $relatedCollectionIds
|
||||
*/
|
||||
public function syncLinks(Collection $collection, User $actor, array $relatedCollectionIds): Collection
|
||||
{
|
||||
$normalizedIds = collect($relatedCollectionIds)
|
||||
->map(static fn ($id) => (int) $id)
|
||||
->filter(static fn (int $id): bool => $id > 0)
|
||||
->reject(fn (int $id): bool => $id === (int) $collection->id)
|
||||
->unique()
|
||||
->values();
|
||||
|
||||
$targets = $normalizedIds->isEmpty()
|
||||
? collect()
|
||||
: Collection::query()
|
||||
->with('members')
|
||||
->whereIn('id', $normalizedIds->all())
|
||||
->get();
|
||||
|
||||
if ($targets->count() !== $normalizedIds->count()) {
|
||||
throw ValidationException::withMessages([
|
||||
'related_collection_ids' => 'Choose valid collections to link.',
|
||||
]);
|
||||
}
|
||||
|
||||
if ($targets->contains(fn (Collection $target): bool => ! $target->canBeManagedBy($actor))) {
|
||||
throw ValidationException::withMessages([
|
||||
'related_collection_ids' => 'You can only link collections that you can manage.',
|
||||
]);
|
||||
}
|
||||
|
||||
$before = $collection->manualRelatedCollections()->pluck('collections.id')->map(static fn ($id) => (int) $id)->all();
|
||||
|
||||
DB::transaction(function () use ($collection, $actor, $normalizedIds): void {
|
||||
DB::table('collection_related_links')
|
||||
->where('collection_id', $collection->id)
|
||||
->delete();
|
||||
|
||||
if ($normalizedIds->isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$now = now();
|
||||
|
||||
DB::table('collection_related_links')->insert($normalizedIds->values()->map(
|
||||
fn (int $relatedId, int $index): array => [
|
||||
'collection_id' => $collection->id,
|
||||
'related_collection_id' => $relatedId,
|
||||
'sort_order' => $index,
|
||||
'created_by_user_id' => $actor->id,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]
|
||||
)->all());
|
||||
});
|
||||
|
||||
$fresh = $collection->fresh(['user.profile', 'coverArtwork']);
|
||||
|
||||
app(CollectionHistoryService::class)->record($fresh, $actor, 'linked_collections_updated', 'Manual linked collections updated.', [
|
||||
'related_collection_ids' => $before,
|
||||
], [
|
||||
'related_collection_ids' => $normalizedIds->all(),
|
||||
]);
|
||||
|
||||
return $fresh;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user