lara-zeus/mark
A compact Laravel package from the Lara Zeus ecosystem that brings simple marking features to your app. Easy to install and integrate, it helps add flagging or bookmark-style behavior to Eloquent models without extra complexity.
lara-zeus/mark adds polymorphic "marks" (reactions such as like/dislike, or custom named marks) to Eloquent models. Version 1.2.0 is a minor, non-breaking release: it completes the indicator surface (PR #43) and adds test coverage for relations (#41) and indicators (#42). Nothing to migrate.
Minimal setup:
composer require lara-zeus/mark and, if you use the Filament plugin, keep the matching lara-zeus plugin versions in lockstep.php artisan vendor:publish --tag=mark-migrations && php artisan migrate). The marks table is polymorphic, so it stores markable_type/markable_id — decide now whether you'll use a morph map.Post), and make sure your User model is the one the config points at.Look first at: the config file (defines available marks and indicators), then the trait's public methods, then the indicator class/contracts. The test suite added in 1.2.0 (tests/ for relations and indicators) is the fastest reference for exact method names and expected return shapes.
First use case: a "like" button on a Post — toggle the mark for the current user, then render the count. That path exercises the two things 1.2.0 hardened: the relation traversal and the indicator output.
Toggle in a controller/livewire action. Keep the toggle idempotent — call the mark/unmark pair rather than a raw create, so repeated clicks don't violate the unique (user, markable, mark-name) index. Guard with auth middleware plus a policy check on the markable model.
Read counts through indicators, not raw queries. Indicators are the package's aggregation layer and are exactly what #43 extended. Use them for badges ("3 likes"), for sorting ("most liked"), and for API responses, so that when you later add a second mark type you don't rewrite your query layer. Where an indicator maps to a withCount, eager-load it on index pages to avoid N+1.
Blade / frontend integration. Render the button with the current user's mark state resolved server-side (already-marked vs not) and return the fresh indicator value from the toggle endpoint so the UI can patch a single number instead of refetching the page.
Filament. If you're in the Lara Zeus ecosystem, the accompanying Filament plugin exposes the mark column/action; keep it out of admin tables with high row counts unless you've verified the indicator query is eager-loaded, since each row otherwise resolves its own counts.
Events and side effects. If the package fires events on mark creation/removal (or you wrap the service), hook notifications, activity logs, and cache invalidation there rather than in the controller — that keeps console/queued paths consistent with HTTP.
Custom mark names. Register additional marks (e.g. bookmark, star) in config and treat the mark name as part of the uniqueness key. Per-mark indicators then let you show separate counters without extra tables.
Testing. Mirror the new package tests: assert the polymorphic relation returns the right models both directions, assert indicator values after mark/unmark, and assert a second identical mark is a no-op. Add a cascade test — deleting a Post should remove its marks (see gotchas).
firstOrCreate guessing. Duplicate marks are the classic bug. Rely on the compound unique constraint and catch/handle the duplicate-key exception, or use the package's toggle helper; don't check-then-insert.Relation::enforceMorphMap(), existing rows written with FQCNs will stop resolving. Introduce the map before going to production, or write a data migration.deleting hook on markable models, or a scheduled cleanup, otherwise orphaned mark rows accumulate and skew global indicators.deleted_at scope is required. 1.2.0's new indicator tests are the place to confirm expected behaviour before you rely on it.php artisan config:clear in local and ensure CI doesn't serve a stale cached config — a missing mark name fails confusingly at runtime.withCount vs indicator objects. Indicator objects are convenient but not always a single query; profile list endpoints before shipping. Batch them for collections rather than resolving per model.^1.2 and read the indicator changelog on each bump rather than assuming output shape is frozen.How can I help you explore Laravel packages today?