Routing & Aufruf
Ein Report wird über seinen key() adressiert. Das Paket registriert Filterformular, Vorschau, Dokument und PDF als eigene Routen — du kannst sie verlinken oder direkt aus dem Code aufrufen.
Die Report-Routen
Alle Routen tragen standardmässig das Präfix reports. Die Route-Namen bleiben gleich, auch wenn du das Präfix änderst.
| GET /reports/{name} · reports.form | Filterformular. Existieren keine Filter-Controls, leitet die Route direkt zur Vorschau weiter. |
|---|---|
| GET /reports/{name}/run · reports.preview | Vorschau-Seite mit Frame, Zoom, Drucken, PDF- und «Filter ändern»-Link. Die Filter kommen als Query-Parameter. |
| GET /reports/internal/{name} · reports.internal | Nur das Report-Dokument als HTML — für ein eigenes iframe oder eine Einbettung ohne Vorschau-Chrome. |
| GET /reports/{name}/pdf · reports.pdf | Streamt das PDF mit denselben Filtern. |
| GET /reports/assets/{file} · reports.asset | Gemeinsame CSS-Datei für Formular und Vorschau. Die UI-Komponenten binden sie automatisch ein. |
Formular zuerst — oder direkt zur Vorschau
Der Link auf /reports/{name} zeigt zuerst das Filterformular. Gibt es keine Filter (leere filterControls()), macht die Route automatisch einen Redirect auf /reports/{name}/run. Für einen direkten Sprung ohne Formular verlinkst du die preview-Route.
Der Ablauf
Der Report wird erst ausgeführt, wenn die Filter feststehen. Die Vorschau ist nur die Hülle; das eigentliche Dokument liegt auf der internal-Route.
reports.form
Filter wählen
Der User füllt das Formular aus. Die Werte landen als Query-Parameter am Formular-Ziel.
reports.preview
Vorschau
Die Route validiert die Filter und rendert den Frame. Das iframe lädt das Dokument von reports.internal.
reports.internal · reports.pdf
Dokument oder PDF
Dieselben Filter, zwei Ausgaben: HTML für die Einbettung oder ein gestreamtes PDF.
Links erzeugen
Verwende die Route-Namen statt hartcodierter Pfade. So bleibst du unabhängig vom konfigurierten Präfix.
{{-- 1. Filter form first: the user chooses filters, then continues. --}}
<a href="{{ route('reports.form', ['name' => 'price_list']) }}">Preisliste öffnen</a>
{{-- 2. Direct preview, with filters in the query string. --}}
@php($filters = [
'category' => 'Küche',
'price' => ['operator' => '>=', 'value' => [50]],
])
<a href="{{ route('reports.preview', ['name' => 'price_list']).'?'.http_build_query($filters) }}">Vorschau</a>
{{-- 3. The raw report document, e.g. for your own iframe. --}}
<iframe src="{{ route('reports.internal', ['name' => 'price_list']).'?'.http_build_query($filters) }}"></iframe>
{{-- 4. Streamed PDF with the same filters. --}}
<a href="{{ route('reports.pdf', ['name' => 'price_list']).'?'.http_build_query($filters) }}">PDF</a>
Vier typische Links: Formular, Vorschau, eingebettetes Dokument und PDF.
Achtung: Filterfeld «name»
Die Route hat einen Parameter {name} für den Report-Key. Ein Filterfeld mit dem Key name würde bei route(..., ["name" => ...] + $filters) den Report-Key überschreiben. Hänge Filter deshalb immer als eigenen Query-String an: route(...)."?".http_build_query($filters). Die Paket-Routen machen das intern genauso.
Filter als Query-Parameter
Die Paket-Routen akzeptieren dieselben Formen, die auch das automatische Formular erzeugt. Unbekannte Keys werden verworfen.
| ?category=Küche | Einfacher Wert. Der Default-Operator des Controls wird verwendet. |
|---|---|
| ?category[]=Küche&category[]=Büro | Mehrere Werte für Multiselect und Picker. |
| ?price[operator]=>=&price[value][]=50 | Expliziter Operator mit einem Wert. |
| ?price[operator]=between&price[value][]=50&price[value][]=100 | Bereich mit zwei Werten. |
| ?name[operator]=like&name[value]=Kaffee | Textfilter. Ohne Operator wird like verwendet und der Wert mit % umschlossen. |
| ?foo=bar | Unbekannte Keys werden vom FilterValidator still verworfen. |
Aus dem Code aufrufen
Die Reports-Fassade nimmt denselben Report-Key und dieselben Filter-Arrays. html() liefert das vollständige Dokument als String; pdf() gibt einen fluenten PDF-Builder zurück.
| Reports::html($report, $filters = []) | Vollständiges HTML-Dokument als String — ideal für eigene Controller oder Einbettungen. |
|---|---|
| Reports::render($report, $filters = []) | Gleiche Pipeline; der konfigurierte Renderer bestimmt den Rückgabetyp. |
| Reports::pdf($report, $filters = []) | PdfBuilder mit stream(), download(), save(), name() und disk(). |
| Reports::filterControls($report) | Liste von FilterControl-Objekten für eine eigene Filter-UI. |
| Reports::filterSchema($report) | Dieselben Controls als JSON-fähige Arrays. |
| Reports::find($key) | Report-Instanz anhand des key() auflösen. |
| Reports::all() · register() · resolve() | Registry lesen, Reports registrieren oder eine Instanz durchreichen. |
| Reports::definition($report) · pageSetup($report) | Aufgelöste ReportDefinition und effektive Seiteneinrichtung. |
use Guggach\Reports\Facades\Reports;
// Full HTML document (layout + bands) as a string.
$html = Reports::html('price_list', ['category' => 'Küche']);
// Same pipeline; the configured renderer decides the return type.
$result = Reports::render('price_list', ['category' => 'Küche']);
// PDF: stream, download or save.
return Reports::pdf('price_list', ['category' => 'Küche'])
->name('preisliste.pdf')
->download();
// Filter metadata for a custom UI.
$controls = Reports::filterControls('price_list'); // FilterControl[]
$schema = Reports::filterSchema('price_list'); // array, JSON-ready
use Guggach\Reports\Facades\Reports;
use Illuminate\Http\Response;
final class PriceListController
{
public function __invoke(): Response
{
return response(
Reports::html('price_list', ['category' => 'Küche'])
);
}
}
Einen Report aus einem Controller rendern oder als PDF ausliefern.
Präfix, Middleware und Schutz
Die Routen sind standardmässig aktiv und laufen in der web-Middleware-Gruppe. Für Produktion solltest du Authentifizierung oder eine Policy ergänzen.
'routes' => [
'enabled' => true,
'prefix' => 'reports',
// Add your own middleware, e.g. auth or a report policy.
'middleware' => ['web', 'auth'],
],
Routing in config/reports.php anpassen.
reports.routes.prefix ändert nur den Pfad, nicht die Route-Namen (reports.form, reports.preview, reports.internal, reports.pdf, reports.asset). Mit reports.routes.enabled = false schaltest du die Routen komplett ab; dann rufst du Reports::html()/pdf() aus eigenen Controllern auf.