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.

Weiter · Report-Arten Wie Listen, Formulare und Strict-Reports dieselben Routen und Bänder nutzen.