- How do I install and configure cybercog/laravel-eloquent-flag in a Laravel app?
- Run composer require cybercog/laravel-eloquent-flag, add a boolean or timestamp column to the table, and import the matching trait into your Eloquent model. There is no service provider, no config file, and no migration to publish, so setup is just Composer plus a trait import. Optionally implement shouldApplyXxxScope() on the model to control whether the flag's global scope is applied.
- Which Laravel and PHP versions does laravel-eloquent-flag support?
- The package supports Laravel 9 through 13 and PHP 8.0 through 8.5, which covers most current Laravel applications. Check the composer.json constraints for the exact release you install. Because it is trait-only with no container bindings or boot cycle changes, framework upgrades rarely break it.
- What is the difference between the classic and inverse flag traits?
- Classic traits make the default query return only flagged records, while inverse traits make the default query return only unflagged records. The two trait trees have near-identical names, and you cannot mix classic and inverse on the same model. Choose inverse semantics only when the unflagged set is the normal working set, such as a queue of items awaiting processing.
- How do I query only flagged or only unflagged records?
- Use the provided helpers and local scopes to check and change state, such as isPublished(), isNotPublished(), publish(), undoPublish(), and toggle, and use macros like withNotPublished() and onlyNotPublished() for queries. These wrap the underlying column predicates so you avoid hand-writing where clauses everywhere. The exact method names follow the flag attribute you configure on the model.
- Why are rows missing from my Eloquent queries after adding a flag trait?
- Once shouldApplyXxxScope() returns true, the trait registers a global scope, so every Eloquent query on that model silently excludes the opposite set of rows, including admin panels, exports, aggregates, and relationship eager loads. If reports return fewer rows than reality, the flag scope is the first thing to check. Apply the scope only to models where hiding rows is genuinely the desired default.
- How do I bypass or disable the flag global scope for an admin panel or report?
- Call withoutGlobalScopes() on the query, or drop to DB::table() or toBase(), to escape the flag predicate. Be aware that joined tables and raw query-builder code bypass the behavior entirely, so any BI or reporting layer built on the builder will disagree with the ORM. There is no package-level kill switch, so disabling all flag scopes during an incident requires a per-model code change and a redeploy.
- Should I use boolean flags or timestamp flags for state like published?
- Boolean flags store state only, while timestamp flags store when the flag was set, which is useful for published_at-style ordering and expiry checks. Timestamp flags never record who changed the state or why, so attribution requires your own audit table and event listeners. Undoing a timestamp flag also leaves no trace unless you listen for the publishedUndone event yourself.
- Can I build approval workflows and permissions with laravel-eloquent-flag?
- This is a behavior layer, not a workflow engine: it provides flag state, helper methods, query scopes, and the published and publishedUndone model events. Approval chains, permissions, transition guards, and audit trails remain your responsibility. If you need to record who flipped a flag, build that in your own listeners.
- Is laravel-eloquent-flag a performance risk on large tables and how should I index it?
- Every applied scope adds a predicate to your queries, and a lone boolean index on a large table is low-selectivity and close to useless. Size composite indexes around the columns you actually filter and sort by, such as the flag combined with created_at. Also review models using HasKeptFlag, since that trait performs writes on create and update that you did not explicitly ask for.
- Is cybercog/laravel-eloquent-flag actively maintained and what if it is abandoned?
- The package is a single-vendor project with roughly 134 stars and no ecosystem integrations, though it is actively supported through Laravel 13. Because the code surface is small and there is no service provider or config, forking is cheap insurance. For compliance, billing, or published-content visibility domains, pin exact versions and treat fork-readiness as a precondition rather than a contingency.