Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Flags Laravel Package

flarum/flags

Flarum extension that lets moderators flag posts for review, adding a dedicated flags list and permission controls for reviewing and resolving flagged content.

Deep Wiki
Context7

Getting Started

This is a Flarum extension, not a general-purpose Laravel package. You are working inside Flarum's container and extension API — Illuminate database, events, and validation are available, but there is no app/Http/Kernel.php, no routes/web.php, and no php artisan.

# already bundled with flarum/core in most installs — check first
composer show flarum/flags

# only if it's genuinely absent
composer require flarum/flags
php flarum extend:enable flarum-flags
php flarum cache:clear

Where to look first (in order):

  1. extend.php — the whole integration surface: API routes (POST|DELETE /api/posts/{id}/flags), the Flag model, serializers, and permission registrations.
  2. src/Flag.php and src/Command/ — the flag entity and the flag/unflag command handlers.
  3. src/Event/ — Flagging (pre-persist) and Flagged (post-persist); these are your primary hooks.
  4. js/src/forum/ — the flag button, the flag-reason modal, and the moderator flag list page. js/src/admin/ — permission labels.

First use case: grant discussion.flagPosts to members and discussion.viewFlags to moderators in the admin Permissions tab, then confirm a flag round-trips: flag a post on the frontend, open the moderator flag list, and GET /api/flags?include=user,post with a token to see the raw payload. That single end-to-end pass validates permissions, serializer output, and event wiring in one go.

Implementation Patterns

React to flags in your own extension via events — the cleanest integration point, no core edits:

use Flarum\Flags\Event\Flagged;
use Flarum\Extend;

return [
    (new Extend\Event())
        ->listen(Flagged::class, function (Flagged $event) {
            $flag = $event->flag;          // Flag model, already persisted
            // push to Slack, bump a report counter, write an audit row
        }),
];

Keep listeners fast — Flarum dispatches these synchronously inside the request. Anything network-bound belongs in a queued job dispatched from the listener.

Auto-hide after N flags — count distinct flaggers in your Flagged listener and dispatch Flarum's hide command (Flarum\Post\Command\HidePost) through the command bus using a moderator/system actor. Verify the command's constructor in flarum/core before wiring it; treat this as the canonical "moderation automation" pattern rather than reaching for raw SQL.

Expose extra flag data to the frontend — extend the serializer rather than shipping a parallel endpoint:

(new Extend\ApiSerializer(\Flarum\Flags\Api\FlagSerializer::class))
    ->attribute('riskScore', fn ($serializer, $flag) => /* ... */);

Same approach works for adding includes or tightening visibility with Extend\ApiController on the flag list/show controllers.

Custom moderation dashboard — consume GET /api/flags?include=user,post&page[limit]=25 with a token scoped to a moderator account. The post include is what you need to render title/discussion context; request post.discussion explicitly if you want it, since includes are not deep by default. Filter and sort server-side where the resource supports it instead of pulling everything and filtering in JavaScript.

Frontend extension — from your own extension's js/src/forum/index.js, import { extend } from 'flarum/common/extend' and hook the flag button/modal components (js/src/forum/components). Overriding the reason list is common; overriding the whole flag flow is a maintenance liability across upgrades.

System/automated flags — create flags with an explicit actor (a dedicated bot user) so the user relationship is populated. Flags without a user render as broken rows in most moderator UIs and break include=user assumptions in downstream tooling.

Gotchas and Tips

  • Read-only subtree split. Issues and PRs must go to the upstream Flarum monorepo, not this repo. Forking this package to patch a bug guarantees you a merge conflict on the next core update. Patch via an event listener or a small companion extension instead.
  • Version-lockstep. The extension version tracks flarum/core. Never relax the flarum/core constraint in composer.json to force an install — you'll get serializer/route mismatches that only show up at runtime.
  • Assets are prebuilt and committed (js/dist). Changing js/src in a vendored copy does nothing until you rebuild (cd js && npm ci && npm run build). If you're extending the frontend, do it from your own extension so composer update doesn't silently wipe your edits.
  • Duplicate flags are a real risk. There is no hard uniqueness guarantee you can rely on across all versions; the UI hides the button after flagging, but API clients can double-post. Deduplicate on (user_id, post_id) in your own listener before acting on thresholds.
  • Orphaned flags. A flag's post relationship and user relationship can both be null after deletions. Guard every access — especially in serializers and custom API resources, where a null dereference becomes a 500 for the whole list.
  • Permission caching bites. After editing extend.php or permissions, run php flarum cache:clear and restart queue workers. "My listener isn't firing" is almost always stale cached code or a listener registered from an extension that isn't enabled.
  • Don't query the flags table directly for moderator-facing features — you'll bypass visibility rules and leak flags across permission boundaries. Go through the model, policies, and the API resource.
  • Throttle flag creation. Flagging is an unauthenticated-ish write from a logged-in user's perspective; without the throttler it's a trivial way to spam your moderation queue and your Slack integration.
  • Keep reasonDetail short. It's intended as a free-text adjunct to a short reason category; if you're storing structured payloads there, you're fighting the schema and every UI that renders flags.
  • Debugging: check storage/logs/ for Flarum's Monolog output and use php flarum info to confirm the extension is enabled and its version matches core. For API-level issues, hit the endpoint with an explicit token — permission failures on flags are silent-ish (fields simply disappear from the payload) rather than loudly erroring, so a 200 with missing attributes usually means a permission problem, not a serializer bug.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle