# Globale Suche erweitern Letzte Aktualisierung: 2026-02-21 Diese Doku erklärt, wie neue Entitäten sauber in die globale Suche integriert werden. ## Überblick Es gibt zwei Suchausgaben mit derselben Datenquelle: 1. **Aside-Preview** (`admin/search/data`) - zeigt je Resource Count + bis zu 5 Preview-Einträge. 2. **Vollseite Suche** (`search/data` -> `/search`) - zeigt gemischte Trefferliste über alle Resources. Die zentrale Fassade liegt in: - `/lib/Support/SearchConfig.php` Die eigentliche Logik ist in Provider aufgeteilt: - `/lib/Support/Search/SearchSqlResourceProvider.php` - `/lib/Support/Search/SearchUiMetaProvider.php` - `/lib/Support/Search/SearchItemMapperProvider.php` - `/lib/Support/Search/SearchSpecialResourceProvider.php` - `/lib/Support/Search/SearchQueryNormalizer.php` ## Relevante Dateien - `/lib/Support/SearchConfig.php` - stabile Orchestrierungs-Fassade (kompatible Methoden nach außen) - `/lib/Support/Search/SearchSqlResourceProvider.php` - Resource-Definitionen (SQL + Permission + Label) + Tenant-Filter - `/lib/Support/Search/SearchUiMetaProvider.php` - URL- und Icon-Mapping pro Resource-Key - `/lib/Support/Search/SearchItemMapperProvider.php` - Mapping SQL-Row -> Preview-/Result-Item - `/lib/Support/Search/SearchSpecialResourceProvider.php` - Spezialressourcen (`docs`, `hotkeys`) - `/lib/Support/Search/SearchQueryNormalizer.php` - Query-Normalisierung für LIKE/Score - `/pages/admin/search/data().php` - Aside-Preview API (Counts + Preview) - `/pages/search/data().php` - Volltext-Treffer API - `/templates/partials/app-main-aside.phtml` - Sichtbarer Eintrag im Such-Panel (`data-search-key=...`) - `/web/js/components/app-global-search.js` - Render-Logik (generisch; meist keine Anpassung nötig) - `/lib/Service/Docs/DocsCatalogService.php` - Zentrale Katalog-/Anchor-Logik für Entwicklerdoku (Single Source of Truth) ## Standard-Vorgehen für neue Resource ### 1) Resource in `SearchSqlResourceProvider::resources()` anlegen Neue Struktur mit: - `key` (z. B. `scheduled-jobs`) - `label` (übersetzbar via `t(...)`) - `permission` (z. B. `PermissionService::JOBS_VIEW`) - `countSql` + `countParams` - `previewSql` + `previewParams` - `resultSql` + `resultParams` Regeln: - SQL immer mit `... like ? escape '\\'`. - Bei tenant-sensitiven Entitäten `{{tenantFilter}}` nutzen und in `SearchSqlResourceProvider::tenantScopeFilters()` ergänzen. - Preview-Query immer mit `limit ?`. ### 2) URL-/Icon-/Mapping ergänzen - `SearchUiMetaProvider::iconForKey()` erweitern - `SearchUiMetaProvider::listUrl()` erweitern - `SearchItemMapperProvider::mapPreviewItem()` ergänzen (falls Spezialformat nötig) - `SearchItemMapperProvider::mapResultItem()` ergänzen (falls Spezialformat nötig) Ziel: - Preview und Volltreffer sollen sprechende Labels zeigen. - URLs sollen direkt auf sinnvolle Zielseiten gehen. ### 3) Eintrag im Aside-Search-Panel anlegen In `/templates/partials/app-main-aside.phtml`: - `
  • ` ergänzen - Anzeige per Permission guarden (z. B. `$canViewJobs`) Wichtig: - `data-search-key` muss exakt dem `key` in `SearchConfig` entsprechen. ### 4) i18n prüfen Neue Labels in: - `/i18n/default_de.json` - `/i18n/default_en.json` ## Sicherheits- und Qualitätsregeln - Permission in `SearchConfig` setzen, nicht nur im Aside. - Tenant-Scope für tenant-bezogene Daten nicht vergessen. - Keine sensiblen Daten im Preview-Label. - Bei optionalen Modulen nur dann Resource aktivieren, wenn Schema vorhanden ist (oder Migration als Pflicht voraussetzen). ## Kurzes Beispiel: `scheduled-jobs` Integration umfasst: - Resource in `SearchSqlResourceProvider::resources()` - Mapping auf `admin/scheduled-jobs/edit/{id}` - Icon `bi-calendar-check` - Aside-Search-Item mit `data-search-key="scheduled-jobs"` - Permission `jobs.view` ## Doku-Resource (`docs`) im System Die Entwicklerdoku ist als eigene Search-Resource integriert: - Key: `docs` - Permission: `docs.view` - Quelle: `docs/*.md` (über `DocsCatalogService`, kein `openapi.yaml`) - Aside: eigener Block `Documentation` mit Count + Preview - Vollsuche: Treffer vom Typ `Documentation` - Ziel-URLs: `admin/docs/{slug}#anchor` (direkter Abschnitt) Wichtig: - Anchor-Ermittlung für Docs-Seite und Suche läuft über denselben Service. - Dadurch bleiben Hash-Links stabil und konsistent. ## Checkliste vor Merge 1. `php -l /lib/Support/SearchConfig.php` 2. `php -l /lib/Support/Search/*.php` 3. `php -l /templates/partials/app-main-aside.phtml` 3. Global Search manuell testen: - Sidebar-Suche zeigt Count + Preview - Klick auf Resource öffnet richtige Liste - `/search?search=...` zeigt Volltreffer 4. Permission-Test: - ohne Permission kein Eintrag/keine Treffer 5. Tenant-Scope-Test (falls relevant) 6. Bei `docs` zusätzlich: - Preview-Link springt auf richtigen Abschnitt - Vollsuche zeigt `Documentation`-Treffer mit sinnvollem Snippet