Skip to main content

Report Handlers

A report handler defines a report available on the platform: its filters, export formats, minimum permission, and execution logic. Each handler implements App\Contracts\ReportContract and is registered by a module through the reportHandlers() method of the module contract. Core reports also implement this contract.

Method name × interface name

The module contract method is called reportHandlers(), but the classes it returns implement the ReportContract interface (there is no ReportHandlerContract).

Registration

public function reportHandlers(): array
{
return [ExposureComplianceReport::class];
}

The ReportContract interface

MethodReturnDescription
type()ReportTypeReport type — value from the App\Enums\ReportType enum
module()?stringIdentifier of the owning module, or null for core reports
feature()?stringSub-resource the report depends on, or null if always available
name()stringDisplay name
description()stringShort description
minimumRole()UserRoleMinimum profile required to run it (App\Enums\UserRole enum)
availableFilters()array<string, array{label: string, type: string}>Filters the report accepts
supportedFormats()list<ReportFormat>Supported export formats (App\Enums\ReportFormat enum)
execute(ReportFilters $filters, User $user)ReportResultRuns the report and returns the result

execute() receives an App\DataObjects\ReportFilters and the requesting user, and returns an App\DataObjects\ReportResult. The report declares its own filters and formats — there is no fixed set of formats imposed by the core.

Formats vary by report

Do not assume that every report exports CSV/XLSX/PDF. The actual set comes from each handler's supportedFormats(). In v0.8.7, core reports export only the formats they individually declare.

Exporters

Converting a ReportResult into a file is the responsibility of exporters that implement App\Contracts\ReportExporterContract:

interface ReportExporterContract
{
public function export(ReportResult $result, string $filename): string;
}

export() receives the result and a file name, and returns the path of the generated file. Each ReportFormat format has its corresponding exporter.

Execution flow

  1. The user requests a report; the core checks minimumRole() and, where applicable, whether the module/sub-resource (module()/feature()) is enabled for the site.
  2. The provided filters are validated against availableFilters() and packaged into ReportFilters.
  3. execute() produces a ReportResult.
  4. An exporter (ReportExporterContract) converts the result to the chosen format among the supportedFormats().

Next steps