---
title: "Filing reports — Reports for Laravel | Roundly"
description: "File reports through the fluent Reports facade or the GivesReports trait — subject, reporter, typed reason and description in one chain."
url: https://roundly-consulting.com/open-source/docs/reports-for-laravel/filing-reports
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Reports for Laravel](https://roundly-consulting.com/open-source/docs/reports-for-laravel.md)

# Filing reports

The fluent facade is the recommended entry point. Reports::report() starts a PendingReport about a subject; create() validates and stores it:

```php
use RoundlyConsulting\Reports\Enums\Reason;
use RoundlyConsulting\Reports\Facades\Reports;

$report = Reports::report($post)
    ->by($user)
    ->for(Reason::Abuse)            // typed, validated reason
    ->because('This post violates the community guidelines.')
    ->create();
```

You can also start from the reporter, or pass a custom reason slug:

```php
// 'copyright' must be listed in config('reports.reasons')
Reports::from($user)->about($post)->for('copyright')->create();
```

Or hand over a DTO in one call:

```php
use RoundlyConsulting\Reports\DataTransferObjects\CreateReportData;
use RoundlyConsulting\Reports\Enums\Reason;
use RoundlyConsulting\Reports\Facades\Reports;

Reports::create(new CreateReportData(subject: $post, reason: Reason::Spam, reporter: $user));
```

## From the reporter trait

The trait methods go through the manager, so Reports::fake() records them too:

```php
// Description and reason are optional — the reason falls back to default_reason.
$report = $user->giveReportTo($post);
$report = $user->giveReportTo($post, 'Violates the guidelines.', Reason::Abuse);

// Or start a fluent build from the reporter:
$user->report($post)->for(Reason::Spam)->because('Spammy.')->create();
```

## The PendingReport builder

- about($subject) — the reported model. Reports::report() sets it for you.
- by($reporter) — the reporting model. Clears any guest identifier.
- asGuest($identifier) — a guest dedupe key instead of a reporter. Clears the reporter.
- for($reason) / reason($reason) — a Reason case or a slug string; reason() is an alias.
- because($description) — the reporter’s free-text description.
- create() — validates the reason, enforces duplicate prevention, stores the report as Pending and returns it.

Without a reason, create() uses default\_reason. Without a subject it throws a LogicException. The subject and the reporter must be saved models — an unsaved one throws a LogicException too, and nothing is written.

## In a controller

A typical report endpoint validates against the allowed slugs — custom ones included — and turns a duplicate into a friendly message:

```php
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use RoundlyConsulting\Reports\Exceptions\DuplicateReportException;
use RoundlyConsulting\Reports\Facades\Reports;

public function store(Request $request, Post $post): RedirectResponse
{
    $data = $request->validate([
        'reason' => ['required', Rule::in(array_keys(Reports::reasons()))],
        'description' => ['nullable', 'string', 'max:2000'],
    ]);

    $pending = Reports::report($post)->by($request->user())->for($data['reason']);

    if (filled($data['description'] ?? null)) {
        $pending->because($data['description']);
    }

    try {
        $pending->create();
    } catch (DuplicateReportException) {
        return back()->with('status', 'You have already reported this post.');
    }

    return back()->with('status', 'Thanks, a moderator will review it.');
}
```

## 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](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## 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.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/reports-for-laravel.md)
