rezaghz/laravel-reports
Add reporting to Eloquent models (spam, violence, abuse, drugs, etc.). Mark a User as reporter and any model as reportable via traits/contracts. Simple API to report, remove, or toggle reports, with publishable migrations. Supports Laravel 6–12, PHP 8.2+.
Installation
Run composer require rezaghz/laravel-reports in your project root.
Publish migrations with:
php artisan vendor:publish --provider="Rezaghz\Laravel\Reports\ReportsServiceProvider" --tag=laravel-reports-migrations
php artisan migrate
First Use Case: Enable Reporting on a Model
Extend a model (e.g., Post) to support reporting:
use Rezaghz\Laravel\Reports\Traits\Reports;
use Rezaghz\Laravel\Reports\Contracts\ReportsInterface;
class Post extends Model implements ReportsInterface
{
use Reports;
// ...
}
Define Reportable Types
In your model, specify reportable types (e.g., spam, violence):
protected $reportableTypes = ['spam', 'violence', 'child_abuse'];
Trigger a Report In a controller or service:
$post = Post::find(1);
$post->report('spam'); // Reports the post as spam
Use the report() method on any model implementing ReportsInterface:
$user = User::find(1);
$user->report('violence'); // Stores report in `reports` table
Check if a model has reports or is flagged:
if ($post->hasReports()) {
// Handle reported content
}
Fetch reports for a model:
$reports = $post->reports; // Collection of Report models
Override default logic in the Reports trait:
class Post extends Model implements ReportsInterface
{
use Reports;
public function report($type)
{
// Custom logic (e.g., validate type, notify admins)
return parent::report($type);
}
}
Validate report types before processing:
if (!in_array($type, $this->reportableTypes)) {
throw new \InvalidArgumentException("Invalid report type.");
}
Trigger events or notifications when reports are created:
event(new ReportCreated($report));
// Or use Laravel Notifications:
$this->notify(new AdminReportNotification($report));
Create a controller to handle report submissions:
public function store(Request $request, $modelId)
{
$model = Model::findOrFail($modelId);
$model->report($request->type);
return response()->json(['success' => true]);
}
Query reports for moderation:
$reports = Report::with('reportable')->latest()->get();
Missing Trait/Contract
Forgetting to implement ReportsInterface or use the Reports trait will break reporting functionality.
Fix: Ensure both are included in your model.
Unpublished Migrations
Skipping vendor:publish for migrations will cause database errors.
Fix: Always run migrations after publishing.
Report Type Mismatch
Passing invalid report types (not in $reportableTypes) may silently fail or cause errors.
Fix: Validate types before processing (see Validation in Integration Tips).
Circular Dependencies
If reportable() returns a model that also uses the Reports trait, ensure no infinite loops in relationships.
Fix: Use explicit foreign keys or lazy-loading.
Check Database
Verify reports are stored in the reports table:
php artisan tinker
>>> \DB::table('reports')->get();
Log Reports
Add logging in the report() method to trace issues:
\Log::debug("Reporting {$this->id} as {$type}");
Test Edge Cases Test reporting on:
ModelNotFoundException).InvalidArgumentException).Custom Report Model
Extend the default Report model:
class CustomReport extends \Rezaghz\Laravel\Reports\Models\Report
{
protected $table = 'custom_reports';
}
Bind it in the service provider:
$this->app->bind(
\Rezaghz\Laravel\Reports\Contracts\ReportModel::class,
CustomReport::class
);
Add Metadata
Extend the report() method to store additional data:
public function report($type, $metadata = [])
{
$this->reports()->create([
'type' => $type,
'metadata' => $metadata,
]);
}
Bulk Reporting Add a method to report multiple instances:
public static function bulkReport(array $ids, $type)
{
foreach ($ids as $id) {
self::find($id)->report($type);
}
}
Soft-Deleting Reports
Enable soft deletes in the Report model:
use Illuminate\Database\Eloquent\SoftDeletes;
class Report extends Model
{
use SoftDeletes;
// ...
}
Default Report Model
The package uses Rezaghz\Laravel\Reports\Models\Report by default. Override via binding (see Custom Report Model).
Reportable Types
Ensure $reportableTypes is defined in your model or the package will default to an empty array.
Relationship Naming
The package assumes a reports() relationship. Customize via:
public function reports()
{
return $this->morphMany(\Rezaghz\Laravel\Reports\Models\Report::class, 'reportable')
->where('type', 'in', $this->reportableTypes);
}
How can I help you explore Laravel packages today?