cslant/laravel-like
A Laravel package that adds like and favorite behavior to Eloquent models. Use traits and polymorphic relationships to like, unlike, toggle, count, and query liked items with minimal setup and clean syntax.
Architecture fit. csslant/laravel-like is a conventional Laravel package: a service layer (LikeManager), facade entry points (Like, Love), and Eloquent model traits (HasLike, HasLove) that proxy to the manager. This is the idiomatic Laravel shape for a cross-cutting concern — consumers get both a testable injection point (LikeManager via the container) and ergonomic static/model-level call sites. The v2.1.0 additions fill a real gap: v2.0.0 exposed model traits only, so application code that needed to react to arbitrary subjects (e.g., a controller toggling a like on a comment, a post, or a user) had no clean entry point. The facade/manager pair now covers that case without requiring consumers to instantiate interactable models first. Interaction semantics are expressed as distinct verbs (like, dislike, love, unlike, unlove, unDislike, toggle) rather than a generic type argument, which is readable but bakes a fixed taxonomy into the API surface.
Integration feasibility. Low friction: composer require, publish config and migrations, add the relevant trait(s) to each interactable model. Laravel package auto-discovery should register the service provider and facades. The main work is schema review — the release notes do not describe the storage model, so the interaction table's shape (polymorphic interactable_type/interactable_id plus user reference plus a type discriminator) must be confirmed from the migration before sizing indexes and constraints.
Technical risk.
LoveScope → LoveScopes) is a hard BC break for any v2.0.x consumer that referenced the trait by name in a model's use list or in a use statement inside application code. This is fatal at class-load time, not a soft deprecation. Mitigated only by the fact that it landed on a minor bump, which implies the maintainer considers direct trait references non-public API — worth validating against actual usage.like.interaction_model or like.users.model produced an error; now it silently resolves to a default. That is the right DX call but converts a loud misconfiguration into a quiet one — if the default models differ from what the adopter intended, likes may write to an unexpected table.ForgetsInteractions extraction suggests shared teardown logic, which is a good sign but does not by itself prove write-path parity.toggle — a read-then-write is race-prone without a unique constraint or upsert.Key questions.
toggle implemented as an atomic upsert or a read-then-write?LikeManager fire domain events (ModelLiked, etc.) that the application can hook for notifications and feeds?LoveScope → LoveScopes rename the only BC-affecting change in the diff?Stack fit. Well-suited to any Laravel application with Eloquent models that need lightweight reaction primitives — community/forum posts, comments, articles, internal recognition feeds. It is a poor fit if the product needs weighted reactions, reaction history/audit, or reactions on non-Eloquent entities; those would need a bespoke table and the package would become an awkward wrapper.
Migration path.
LoveScope in model use lists and imports, and every place that depended on a hard failure when interaction_model or users.model was unset. Both are mechanical to fix once identified.Compatibility checks. Confirm the package's composer.json constraints against the platform's PHP and laravel/framework versions; verify no facade alias collision with existing Like or Love aliases in config/app.php; confirm the interaction model and user model config keys point at the intended application classes after the fallback change.
Sequencing.
HasLike to a single low-risk model and wire one user-facing surface (e.g., post likes) behind a feature flag.HasLove and the Love facade only after the first surface is stable, since the love/dislike taxonomy usually needs product sign-off before it ships.Maintenance. Strong positive signal: v2.1.0 ships a testbench + Pest suite covering manager, facades, traits, enum, helper, and config. For a small community package, that is the difference between "safe to depend on" and "adopt at your own risk" — it means the facade/manager/trait surface is now regression-tested, and future refactors (like the ForgetsInteractions extraction in this release) can be verified rather than hoped for. The internal deduplication is housekeeping that reduces future bug surface without changing behavior.
Support. The maintainer is a single author (csslant), so bus factor is the dominant supply-side risk. Mitigate by pinning to a known-good minor and reviewing changelogs before upgrading rather than floating on ^2.1. Because the package is small, forking is a realistic fallback — worth noting in the risk register as the exit strategy.
Scaling. Interaction tables grow with engagement, not with content, so they typically become one of the largest tables in the app. Three things determine whether this scales: an index covering (interactable_type, interactable_id, type) for count lookups, an index or unique constraint covering (user, interactable, type) for "did this user react" lookups, and whether counts are computed per-request or denormalized. If the package always aggregates, high-traffic index pages will need application-level caching layered on top. Write volume from toggle is bounded by human interaction rates and is unlikely to be the bottleneck; read amplification on listing pages is the real cost.
Failure modes.
Class not found on upgrade for consumers referencing LoveScope directly — surfaces immediately, easy to diagnose, easy to fix.toggle if no unique constraint exists — surfaces as inflated counts.Ramp-up. Low for anyone fluent in Laravel: config file plus traits plus a facade is a familiar pattern, and the verb-per-method API reads clearly. Expect roughly half a day for a mid-level engineer to install, review the schema, attach traits to one model, and ship a working like button with tests; one to two days if replacing an existing reaction system with backfill and parity checks. The main conceptual overhead is understanding the distinction between manager/facade calls and model-trait calls well enough to pick one consistently — recommend the team standardize on the facade/manager for application code and reserve traits for model-local helpers, and document that convention up front.
How can I help you explore Laravel packages today?