guard($actor, $collection); $inserted = false; DB::transaction(function () use ($actor, $collection, &$inserted): void { $rows = DB::table('collection_likes')->insertOrIgnore([ 'collection_id' => $collection->id, 'user_id' => $actor->id, 'created_at' => now(), ]); if ($rows === 0) { return; } $inserted = true; DB::table('collections') ->where('id', $collection->id) ->update([ 'likes_count' => DB::raw('likes_count + 1'), 'last_activity_at' => now(), 'updated_at' => now(), ]); }); if ($inserted) { event(new CollectionLiked($collection->fresh(), (int) $actor->id)); } return $inserted; } public function unlike(User $actor, Collection $collection): bool { $deleted = false; DB::transaction(function () use ($actor, $collection, &$deleted): void { $rows = DB::table('collection_likes') ->where('collection_id', $collection->id) ->where('user_id', $actor->id) ->delete(); if ($rows === 0) { return; } $deleted = true; DB::table('collections') ->where('id', $collection->id) ->where('likes_count', '>', 0) ->update([ 'likes_count' => DB::raw('likes_count - 1'), 'updated_at' => now(), ]); }); if ($deleted) { event(new CollectionUnliked($collection->fresh(), (int) $actor->id)); } return $deleted; } public function isLiked(?User $viewer, Collection $collection): bool { if (! $viewer) { return false; } return DB::table('collection_likes') ->where('collection_id', $collection->id) ->where('user_id', $viewer->id) ->exists(); } private function guard(User $actor, Collection $collection): void { if (! $collection->isPubliclyEngageable()) { throw ValidationException::withMessages([ 'collection' => 'Only public collections can be liked.', ]); } if ($collection->isOwnedBy($actor)) { throw ValidationException::withMessages([ 'collection' => 'You cannot like your own collection.', ]); } } }