NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages

Open source

Reports for Laravel

Install
composer require roundly-consulting/reports-for-laravel
Requires: PHP ^8.4 · Laravel ^12.0|^13.0

Overview

A content-moderation and flagging foundation for Laravel. Let any model file reports — or let guests report anonymously — against any reportable model, tag each report with a typed reason and move it through a guarded status lifecycle, with optional multi-moderator sign-off. Duplicate prevention, aggregation scopes, threshold escalation and lifecycle events come built in, behind a fluent facade with Action classes and DTOs underneath. Native and MIT-licensed, it builds only on Laravel and our own approvals, enums and package-toolkit packages — no third-party dependencies.

What you get

Report anything, from anyone

GivesReports and HasReports turn any Eloquent model into a reporter or a reportable subject — guests can report too, keyed by a hashed identifier.

Typed, extensible reasons

A Reason enum with ready-made labels and select options, plus your own custom slugs validated against a config allow-list.

Guarded status lifecycle

Pending → in review → resolved or rejected → closed, enforced by a transition table that records who settled each report, when and why.

Multi-moderator sign-off

Route decisions through approvals-for-laravel — unanimous, quorum, any or weighted — and the report settles itself once the bar is met.

Duplicate prevention & insights

Block repeat reports from the same reporter or guest, count reports per subject and sort content by most reported.

Threshold escalation & events

ReportThresholdReached fires when a subject hits your threshold, alongside events for every creation, status change and decision.

Facade, DI or actions

One Reports facade, the injectable ReportsManager or six single-purpose actions — and a recording Reports::fake() for your tests.

Documentation

Installation

Install via Composer, publish the config if you change the table or key type, then publish and run the publish-only reports and approvals migrations.

Configuration

Every config key and its default — model, table, key type, reasons, duplicate prevention, strict transitions, threshold, pruning and moderation.

Database schema & key types

The reports table column by column, its indexes, and how key_type types the morph columns for bigint, UUID or ULID models.

Preparing your models

Add GivesReports to models that file reports and HasReports to models that can be reported; Reporter and Reportable are optional markers.

The Reports facade

One facade for filing, reviewing, settling, moderating and pruning reports, plus the reason reads — with builders for filing and moderation.

DI, actions & DTOs

Inject ReportsManager instead of calling the facade, or run one of six Action classes with readonly DTOs from jobs and services.

Filing reports

File reports through the fluent Reports facade or the GivesReports trait — subject, reporter, typed reason and description in one chain.

Guest & anonymous reports

Accept reports from visitors who aren’t signed in, deduplicated by a hashed IP or email identifier.

Reasons

Typed report reasons via the Reason enum, custom slugs in config, and the facade’s reason reads — slug => label, defaults and allow checks.

Status lifecycle

Five statuses and a transition table — move reports with Reports::review(), close() or changeStatus(), guarded by strict_transitions.

Resolving & rejecting

Settle a report with Reports::resolve() or reject(), recording the moderator, a timestamp and a note, and firing the matching event.

Multi-moderator moderation

Require several moderators to sign off — unanimous, quorum, any or weighted — before a report settles, powered by approvals-for-laravel.

Duplicate prevention

Stop the same reporter or guest from reporting a subject twice — scoped to open reports or to every report ever filed.

Aggregation & querying

Count reports per subject, check who reported what, and sort or filter subjects by report count with ready-made scopes.

Threshold auto-actions

Fire ReportThresholdReached when a subject’s open report count hits your threshold — auto-hide content, alert moderators, or both.

The Report model

Report attributes, relations, scopes and soft deletes — and how to swap in your own Report subclass.

Events

Five events cover creation, status changes, resolution, rejection and threshold crossings — the same whether settled directly or via moderation.

Artisan commands

Prune old settled reports, list per-subject open report counts, and inspect the active configuration with php artisan about.

Exceptions

The typed exceptions the package throws — all extending ReportsException — and the context each one carries.

Testing

Reports::fake() records every mutating call instead of running it, with an assertion per verb — plus a factory state for every lifecycle stage.

Requirements

PHP 8.4+ and Laravel 12 or 13; approvals, enums and package-toolkit are installed automatically as dependencies.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.