Search Documentation

Search for pages and headings in the documentation

CollectSearchEntriesEvent

Das CollectSearchEntriesEvent wird vom CMS ausgelöst, sobald ein Suchvorgang gestartet wird. Entwickler können über dieses Event eigene Suchergebnisse bereitstellen und so die Suchfunktion individuell erweitern.


Funktionsweise

  • Das Event enthält den Suchbegriff ($event->getSearchTerm()) und optional den aktuellen Benutzer ($event->getWho()).
  • Entwickler fügen eigene Suchergebnisse mit $event->addSearchEntry() hinzu.
  • Jedes hinzugefügte Objekt muss das Interface SearchResultEntryInterface implementieren (z. B. SearchResultEntryModel).
  • Die Felder createdAt und updatedAt müssen Carbon-Instanzen sein.
  • Das CMS sammelt alle Einträge, berechnet intern einen Score und zeigt sie sortiert nach Relevanz an.

Scopes

Das Event unterstützt verschiedene Suchbereiche (Scopes), die als Bitmasken übergeben werden:

  • SearchScope::ADMIN – Suche im Admin-Bereich
  • SearchScope::FRONTEND – Suche im Frontend

Sie können prüfen, ob ein Scope aktiv ist:

if ($event->hasScope(SearchScope::ADMIN)) {
    // Admin-spezifische Suchergebnisse hinzufügen
}

Mehrere Scopes können kombiniert werden (z. B. als Array oder Bitmaske).


Beispiel: Eigene Suchergebnisse hinzufügen

Registrieren Sie einen Listener, der auf das CollectSearchEntriesEvent reagiert und eigene Ergebnisse bereitstellt:

use Crispy\Events\Search\CollectSearchEntriesEvent;
use Crispy\Models\SearchResultEntryModel;
use Crispy\Enums\SearchScope;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Carbon\Carbon;

final class MySearchSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            CollectSearchEntriesEvent::class => 'onCollectSearchEntries',
        ];
    }

    public function onCollectSearchEntries(CollectSearchEntriesEvent $event): void
    {
        // Reagieren Sie nur im Frontend-Scope
        if (!$event->hasScope(SearchScope::FRONTEND)) {
            return;
        }

        // Beispiel: Ein Suchergebnis hinzufügen
        $entry = new SearchResultEntryModel(
            title: 'Beispielseite',
            snippet: 'Dies ist ein benutzerdefiniertes Suchergebnis.',
            url: '/beispiel-seite',
            source: 'custom',
            createdAt: Carbon::now(),
            updatedAt: Carbon::now()
        );

        $event->addSearchEntry($entry);
    }
}

Beispiel: Scopes und Berechtigungen

Die Scopes steuern, in welchem Bereich die Suchergebnisse angezeigt werden:

  • SearchScope::ADMIN
    Wird im Admin-Backend verwendet. Hier können auch sensible Daten (z. B. Benutzer, Seiten, Kategorien) angezeigt werden, da die Ausgabe nur für berechtigte und authentifizierte Nutzer erfolgt.

  • SearchScope::FRONTEND
    Wird im öffentlichen Bereich (Frontend) verwendet. Hier dürfen keine sensitiven oder administrativen Daten ausgegeben werden, da die Ergebnisse für alle Besucher sichtbar sind.

Beispiel: Unterschiedliche Ergebnisse je nach Scope und Berechtigung

use Crispy\Events\Search\CollectSearchEntriesEvent;
use Crispy\Models\SearchResultEntryModel;
use Crispy\Enums\SearchScope;
use Crispy\Enums\Permissions;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Carbon\Carbon;

final class MySearchSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            CollectSearchEntriesEvent::class => 'onCollectSearchEntries',
        ];
    }

    public function onCollectSearchEntries(CollectSearchEntriesEvent $event): void
    {
        // Admin-Scope: Fügen Sie nur für berechtigte Nutzer sensible Daten hinzu
        if ($event->hasScope(SearchScope::ADMIN)) {
            $user = $event->getWho();
            // Prüfen Sie, ob der Benutzer die nötigen Rechte hat
            if ($user && $user->hasPermission(Permissions::SUPERUSER->value)) {
                $event->addSearchEntry(new SearchResultEntryModel(
                    title: 'Admin-Datensatz',
                    snippet: 'Nur für Admins sichtbar.',
                    url: '/admin/secret',
                    source: 'admin',
                    createdAt: Carbon::now(),
                    updatedAt: Carbon::now()
                ));
            }
        }

        // Frontend-Scope: Fügen Sie nur öffentliche Daten hinzu
        if ($event->hasScope(SearchScope::FRONTEND)) {
            $event->addSearchEntry(new SearchResultEntryModel(
                title: 'Öffentliche Seite',
                snippet: 'Dieses Ergebnis ist für alle Besucher sichtbar.',
                url: '/public-page',
                source: 'frontend',
                createdAt: Carbon::now(),
                updatedAt: Carbon::now()
            ));
        }
    }
}

Zugriff auf Event-Daten

  • Suchbegriff: $event->getSearchTerm()
  • Benutzer: $event->getWho() (optional)
  • Scope: $event->getScope() (Bitmaske)
  • Ergebnisse: $event->getSearchEntries() (liefert sortierte und bewertete Ergebnisse)

Rückgabe und Bewertung

Nach der Verarbeitung stellt das CMS den zusammengesetzten Satz an Suchergebnissen bereit — sortiert nach Relevanzscore. Entwickler müssen keine eigene Sortierung oder Bewertung vornehmen, das CMS übernimmt dies automatisch.


Beispiel: Benutzer und Berechtigungen im Admin-Scope

Im Admin-Scope sollten Sie immer prüfen, ob der aktuelle Benutzer die nötigen Rechte besitzt, bevor Sie sensible Suchergebnisse hinzufügen. Das Event stellt Ihnen den aktuellen Benutzer über $event->getWho() bereit.

Typischerweise prüfen Sie die Berechtigungen so (wie im CMS-Quellcode):

use Crispy\Events\Search\CollectSearchEntriesEvent;
use Crispy\Models\SearchResultEntryModel;
use Crispy\Enums\SearchScope;
use Crispy\Enums\Permissions;
use Crispy\Controllers\UserController;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Carbon\Carbon;

final class MySearchSubscriber implements EventSubscriberInterface
{
    private UserController $userController;

    public function __construct()
    {
        $this->userController = new UserController();
    }

    public static function getSubscribedEvents(): array
    {
        return [
            CollectSearchEntriesEvent::class => 'onCollectSearchEntries',
        ];
    }

    public function onCollectSearchEntries(CollectSearchEntriesEvent $event): void
    {
        // Admin-Scope: Nur für berechtigte Nutzer
        if ($event->hasScope(SearchScope::ADMIN) &&
            $this->userController->checkPermissionStack(
                [Permissions::READ_USERS->value, Permissions::SUPERUSER->value],
                $event->getWho()
            )
        ) {
            // Beispiel: Fügen Sie alle passenden User als Suchergebnis hinzu
            foreach ($this->userController->searchUser($event->getSearchTerm()) as $User) {
                $event->addSearchEntry(new SearchResultEntryModel(
                    title: $User->getName(),
                    snippet: 'Benutzerprofil',
                    url: '/admin/users/#' . $User->getId(),
                    source: 'CMSControl.Common.SearchModels.User',
                    createdAt: $User->getCreatedAt(),
                    updatedAt: $User->getUpdatedAt(),
                ));
            }
        }
    }
}