WebBlocks CMS Plugin-System

Dieses Dokument hält die Architektur des WebBlocks CMS Plugin-Systems fest. Der CMS-Kern ist ein generischer Plugin-Host mit registry-gestützten Plugin-Definitionen, manuellem ZIP-Upload/-Installation durch Super-Admins, storage-eigenen Installationspfaden, standardmäßig deaktivierten installierten Plugins, expliziter Aktivierungs-/Deaktivierungsverwaltung, Deinstallation für manuelle Uploads, Kompatibilitätsprüfungen, Routen und Befehlen nur für aktivierte Plugins, einem Gerüst für Einstellungen/Detailseiten, Zustands-/Statusberichten, typisierten Admin-Erweiterungs-Slots, plugin-eigenen Block-Deklarationen, Hooks für öffentliche Assets, Wächtern für Paketkonventionen, einer prüfsummenverifizierten Plugin-Katalog-Installationsbrücke für kompatible öffentliche Katalog-Artefakte sowie einer kontrollierten katalogbasierten Update-Aktion für installierte Plugins mit neueren kompatiblen Releases. Der WebBlocks UI Manager ist nicht mehr Teil der CMS-Kern-Laufzeit; er ist ein internes/Operator-Plugin-Artefakt, das nur auf Operator-Installationen wie webblocksui.com manuell installiert wird. Es gibt keinen öffentlichen Marketplace, keinen vollständigen Remote-Plugin-Store, keinen Installer für beliebige Composer-Pakete, keinen automatischen Download/kein automatisches Update externer Plugins, kein automatisches externes Produktions-Deployment auf das WebBlocks UI CDN und kein generisches Publishing auf Update-Server.

Kernentscheidung

Der WebBlocks-CMS-Kern ist ein Plugin-Host.

Das Kernpaket stellt die wiederverwendbare CMS-Produktoberfläche bereit:

  • Inhalts- und Site-Verwaltung
  • öffentliche Rendering-Infrastruktur
  • Grundlagen für Benutzer, Rollen und Berechtigungen
  • Admin-Shell und Standard-Admin-UI-Oberflächen
  • Plugin-Discovery, Registry und Verträge für Erweiterungs-Slots

Produktspezifische oder geschäftsdomänenspezifische Fähigkeiten dürfen nicht in den CMS-Kern eingebettet werden, sofern sie nicht Teil des wiederverwendbaren CMS-Produkts sind. Sie sollten als Plugins ausgeliefert werden, damit eine Installation nicht die Menüs, Befehle, Einstellungen, Datentabellen oder betrieblichen Workflows eines anderen Produkts erbt.

Zu den erwarteten Plugin-Bereichen gehören:

  • WebBlocks UI Release/CDN Manager
  • QuizTem-Integration
  • Analytics
  • SEO-Pro-Tools
  • Newsletter
  • Commerce
  • Medien-Optimierer
  • Update-Server-Manager
  • eigene Block-Pakete

Grenze zwischen Kern und Plugin

Kernfähigkeiten:

  • Sites, Seiten, Blöcke, Medien, Benutzer, Sprachen (Locales) und Basiseinstellungen
  • Rendering, öffentliche Shell, Layout-, Slot- und Block-Infrastruktur
  • Grundlage für Berechtigungen und Rollen
  • Admin-Shell und Standard-Admin-UI-Oberfläche
  • Plugin-Discovery, Registry und Verträge für Erweiterungs-Slots

Plugin-Fähigkeiten:

  • Admin-Bildschirme für ein bestimmtes Produkt oder eine bestimmte Geschäftsdomäne
  • ein plugin-eigener Routen-Namensraum
  • plugin-eigene Berechtigungen
  • plugin-eigene Einstellungen
  • plugin-eigene Konsolenbefehle
  • plugin-eigene Migrationen
  • plugin-eigene Dashboard-Widgets
  • plugin-eigene Blöcke oder Block-Pakete
  • plugin-eigene öffentliche Routen, nur wenn explizit deklariert

Das Überschreiben von Kern-Views ist standardmäßig verboten. Plugins erweitern das CMS ausschließlich über dokumentierte Erweiterungs-Slots und Registry-Verträge. Ein Plugin darf keine Paket-Views ersetzen, keine Kern-Services per Monkey-Patching verändern, keine versteckten Routendateien hinzufügen und sich nicht auf beliebige Include-Nebeneffekte verlassen.

Manuelle ZIP-Installation

System -> Plugins erlaubt Super-Admins das Hochladen einer lokalen Plugin-ZIP-Datei. Das Hochladen einer ZIP-Datei ist eine privilegierte Installation ausführbaren Codes. Der Installer validiert das Archiv, bevor er irgendetwas unterhalb des konfigurierten Plugin-Stammverzeichnisses schreibt, standardmäßig storage/app/webblocks/plugins/{plugin-handle}/{version}.

Die Validierung erfordert webblocks-plugin.json oder manifest.json, ein Handle in Kebab-Case, eine semver-artige Version, Provider-/Klassen-Metadaten, eine kompatible CMS-Versionseinschränkung, keine Kollision mit einem installierten Handle, ausschließlich relative Paketpfade, keinen Path-Traversal, keine absoluten Pfade, keine Symlink-Einträge und keine Schreibzugriffe auf verbotene CMS-/Kernziele wie app, packages, project, storage, vendor oder public/cms. Installierte Plugins bleiben deaktiviert, bis ein expliziter Aktivierungsschritt abgeschlossen ist. Deaktivierte Plugins sind inaktiv: Routen, Befehle, Menüs, Einstellungsrouten, Zustandsberichte, Widgets, Block-Deklarationen und Assets werden weder registriert noch ausgeführt, und System -> Plugins meldet den Zustand als inaktiv/nicht geprüft.

Die manuelle Deinstallation ist nur für manuell hochgeladene Plugins verfügbar und erfordert eine Super-Admin-Autorisierung. Das Plugin muss zuerst deaktiviert werden. Die Deinstallation entfernt das Paketverzeichnis des installierten Plugins und die Datei mit dem Aktivierungsstatus unterhalb des konfigurierten Plugin-Stammverzeichnisses, löscht jedoch keine plugin-eigenen Datenbanktabellen und führt keine destruktiven Migrationen aus. Geschützte/Kern-/nicht-manuelle Plugins können über diesen Ablauf nicht deinstalliert werden.

Zu den unterstützten Manifest-Feldern gehören handle, label, description, version, provider, required_cms_version, permissions, commands, routes, settings, migrations, assets und health. Migrationen werden als plugin-eigene Dateien installiert und niemals automatisch beim Hochladen oder Aktivieren ausgeführt. Super-Admins können die explizite Plugin-Setup-Aktion auf der Plugin-Detailseite ausführen; der Runner beschränkt die Ausführung auf den installierten Plugin-Pfad und die im Manifest deklarierten Migrationsverzeichnisse, protokolliert die Setup-Ergebnisse im Aktivierungsstatus und kann ein Plugin mit ausstehendem Setup reparieren, dessen Migrationseinträge existieren, während erforderliche Plugin-Tabellen fehlen.

Der manuelle Plugin-Lebenszyklus lautet:

  1. ZIP hochladen/installieren. Das Plugin ist standardmäßig deaktiviert.
  2. Die Plugin-Detailseite prüfen.
  3. Das Plugin aktivieren, sobald es kompatibel ist.
  4. Plugin-Setup/Migrationen ausführen, wenn die Detailseite Setup required oder Plugin migrations pending meldet.
  5. Operative Plugin-Routen nutzen, sobald das Setup abgeschlossen ist.
  6. Das Plugin deaktivieren, um Routen, Befehle, Menüs, Einstellungen, Zustandsprüfungen und Beiträge inaktiv zu machen.
  7. Erst nach der Deaktivierung deinstallieren; die Deinstallation erhält plugin-eigene Tabellen.

Aktivierte Plugins mit ausstehendem Setup dürfen Admin-Routen nicht zum Absturz bringen. Wenn plugin-eigene Tabellen fehlen, sollten Zustands- und Routen-Bildschirme Hinweise auf das erforderliche Setup melden, etwa Plugin migrations pending oder Release tables are missing.

Plugin-Admin-Routen sollten deklarierte, mit dem Handle geprefixte Berechtigungen verwenden. CMS-Benutzer mit super_admin sind für aktive Berechtigungen aktivierter Plugins explizit zugelassen, einschließlich Berechtigungen aus Manifesten manuell installierter Plugins. Rollen ohne Super-Admin bleiben abgelehnt, sofern nicht ein zukünftiges CMS-Modell für Berechtigungszuweisungen die spezifische plugin-eigene Berechtigung erteilt. Einstellungsrouten verwenden {plugin-handle}.manage, wenn das Plugin sie deklariert, andernfalls fallen sie auf den Systemzugriff zurück.

Admin-Routen aktivierter kompatibler Plugins laufen immer innerhalb des CMS-Admin-Routen-Stacks: web, Installationspflicht, CMS-Authentifizierung, CMS-Admin-Zugriff, Plugin-Setup-Guard und anschließend die plugin-eigene Berechtigungs-Middleware, wenn die Plugin-Route sie deklariert. Die CMS-Auth-Middleware verwendet den Web-Guard/Session-Benutzer von Laravel und leitet Gäste über die CMS-eigene Route webblocks.auth.login um. Plugin-Setup-Guards sind additiv und dürfen die CMS-Authentifizierung oder die Admin-Autorisierung nicht ersetzen; Plugin-Controller können sich darauf verlassen, dass der authentifizierte CMS-Benutzer vorhanden ist, nachdem die Auth-/Admin-Middleware durchlaufen wurde.

Plugin-Vertrag und Manifest

Jedes Plugin muss ein Handle haben:

  • Kebab-Case
  • global eindeutig innerhalb der Installation
  • stabil über Releases hinweg
  • als Standard-Präfix für Berechtigungen, Routen, Tabellen, Einstellungen, Assets und die Paketidentität verwendet

Jedes Plugin sollte Metadaten über ein Manifest oder ein Definitionsobjekt deklarieren:

  • Handle
  • Label
  • Version
  • Provider-Klasse
  • optionale Beschreibung
  • erforderliche CMS-Version oder Versionseinschränkung
  • Einstellungs-Namensraum
  • Datenbank-/Tabellenpräfix
  • Berechtigungen
  • Admin-Menüeinträge
  • Admin- und öffentliche Routen
  • Konsolenbefehle
  • Einstellungsschema oder Einstellungsseiten
  • Migrationen
  • Blöcke oder Block-Pakete
  • Assets
  • Zustandsprüfungen, sofern unterstützt

Plugins sind registry-first. Sie verbinden sich mit dem CMS über explizite Verträge statt über zufällige Includes, das Überschreiben von Root-Views oder installationsspezifische Routendateien.

Über den Katalog aktualisierte installierte Plugins werden nach dem Schreiben des Ersatzpakets über eine Laufzeitaktualisierung des CMS-Kerns neu geladen. Die Aktualisierung leert die Plugin-Registry sowie den Berechtigungs-, Erweiterungs-, Zustands- und optimierten Laravel-Laufzeit-Cache-Status und baut anschließend die aktiven Plugin-Routen für die aktuelle Laufzeit neu auf, damit die installierte Version, die aktive Manifest-Version, die aktiven Provider-Metadaten und der Quellpfad von Routen/Controllern konsistent bleiben. Wenn eine Provider-Klasse aus einer älteren installierten Paketversion im selben PHP-Prozess bereits geladen ist, behandelt das CMS diesen Provider als veraltet und greift auf die aktualisierten Manifest-Metadaten zurück, statt alte Routenpfade wiederzuverwenden.

Die Plugin-Autorisierung wird zentral vom CMS-Kern aufgelöst. Aktive plugin-eigene Berechtigungen, die vom aktivierten Plugin deklariert werden, lassen CMS-Benutzer mit super_admin zu, und derselbe Resolver wird für die Sichtbarkeit von Plugin-Menüs, Dashboard-/System-Beiträge und die Routen-Middleware plugin.permission:* verwendet. Nicht autorisierte Benutzer sehen die entsprechenden Plugin-Menüeinträge nicht; der direkte URL-Zugriff bleibt ein kontrollierter 403. Die Behandlung von ausstehendem Setup bleibt nach der Autorisierung bestehen, und Plugin-Migrationen bleiben explizit.

Aktuelle Form der Registry-API:

PluginDefinition::make('webblocks-ui-manager')
  ->label('WebBlocks UI Manager')
  ->version('1.0.0')
  ->requiresCms('^1.32')
  ->provider(WebBlocksUiManagerServiceProvider::class)
  ->settingsNamespace('webblocks_ui_manager')
  ->databasePrefix('webblocks_ui_manager_')
  ->menu([
    PluginMenuItem::make('releases')
      ->label('WebBlocks UI Releases')
      ->icon('package')
      ->route('webblocks.plugins.webblocks_ui_manager.releases.index')
      ->permission('webblocks-ui-manager.view'),
  ])
  ->permissions([
    PluginPermission::make('webblocks-ui-manager.view')->label('View releases'),
    PluginPermission::make('webblocks-ui-manager.manage')->label('Manage release metadata'),
    PluginPermission::make('webblocks-ui-manager.publish')->label('Prepare CDN artifacts'),
  ])
  ->adminRoutes(__DIR__.'/../routes/admin.php')
  ->commands([
    PrepareWebBlocksUiReleaseCommand::class,
  ])
  ->settings(
    PluginSettingsDefinition::make()
      ->label('Release Settings')
      ->description('Controls WebBlocks UI release publishing defaults.')
  )
  ->dashboardWidgets([
    PluginDashboardWidget::make('webblocks-ui-manager.release-status')
      ->title('WebBlocks UI Releases')
      ->description('Read-only release publishing summary.')
      ->permission('webblocks-ui-manager.view'),
  ])
  ->systemCards([
    PluginSystemCard::make('webblocks-ui-manager.cdn-status')
      ->title('CDN Status')
      ->description('Read-only CDN artifact status.')
      ->permission('webblocks-ui-manager.view'),
  ])
  ->blockTypes([
    PluginBlockTypeDefinition::make('webblocks-ui-manager::release-card')
      ->label('Release Card'),
  ])
  ->publicAssets([
    PluginPublicAsset::cssHead('webblocks-ui-manager.public-css', '/cms/plugins/webblocks-ui-manager/public.css'),
    PluginPublicAsset::jsBodyEnd('webblocks-ui-manager.public-js', '/cms/plugins/webblocks-ui-manager/public.js'),
  ])
  ->health(WebBlocksUiManagerHealth::class);

Die genaue API kann sich während der Implementierung ändern, der Vertrag muss jedoch diese Regeln bewahren:

  • deklarierte Metadaten sind einsehbar, bevor ein Plugin aktiviert wird
  • die Eigentümerschaft an Menüs, Routen, Berechtigungen, Befehlen, Migrationen, Blöcken, Assets und Einstellungen ist einem Plugin-Handle zuzuordnen
  • Konflikte schlagen während Build, Test, Boot-Diagnose oder Plugin-Aktivierung fehl, bevor Benutzer gemischte Eigentümerschaft sehen

Regeln für Paketkonventionen

Plugin-Paketkonventionen sind von den CMS-Kernkonventionen getrennt. Der CMS-Kern besitzt die Host-Verträge; Plugins besitzen ihr Domänenverhalten.

  • Handle-Benennung: verwenden Sie stabiles Kebab-Case wie analytics-tools; benennen Sie ein Handle nach dem Release niemals um, da es Routen, Berechtigungen, Einstellungen, Tabellen, Assets und die Upgrade-Historie verankert.
  • Service-Provider-Registrierung: ein Plugin-Paket sollte einen einzigen Laravel-Service-Provider bereitstellen und dort oder über den Integrationspunkt der CMS-Registry seine PluginDefinition registrieren. First-Party-Piloten innerhalb des Pakets dürfen sich direkt über den CMS-Paket-Provider registrieren, bis sie in eigene Composer-Pakete ausgelagert werden.
  • Definitions- oder Manifest-Struktur: deklarieren Sie handle, label, version, provider, description, requiresCms, Einstellungs-Namensraum, Datenbankpräfix, Berechtigungen, Routen, Befehle, Erweiterungs-Slots, Assets, Blöcke und den Zustandsberichterstatter explizit.
  • Routen-Namensraum: Admin-Routen liegen unter /webadmin/plugins/{plugin-handle}/... mit Namen unter webblocks.plugins.{plugin_handle}.*.
  • Berechtigungsbenennung: jede Plugin-Berechtigung beginnt mit {plugin-handle}., zum Beispiel analytics-tools.view.
  • Einstellungskonventionen: Einstellungs-Namensräume sind snake_case und entsprechen standardmäßig dem Handle mit in Unterstriche umgewandelten Bindestrichen.
  • Befehlsbenennung: auflösbare Artisan-Befehlsnamen müssen mit {plugin-handle}: beginnen, zum Beispiel analytics-tools:sync.
  • Migrations- und Tabellenbenennung: Tabellen verwenden ein in der Registry reserviertes snake_case-Präfix, das auf _ endet, standardmäßig das in snake_case umgewandelte Handle plus _.
  • Asset-Beiträge: Handles öffentlicher Assets erhalten einen Punkt-Namensraum mit dem Plugin-Handle, und statische Dateien müssen unter einem plugin-eigenen Pfad veröffentlicht werden.
  • Dashboard- und Systemkarten-Beiträge: Schlüssel erhalten einen Punkt-Namensraum mit dem Plugin-Handle und bleiben schreibgeschützt, bis ein späterer Erweiterungsvertrag bearbeitbares Verhalten hinzufügt.

Der WebBlocks UI Manager folgt diesen Konventionen als First-Party-Pilot: Handle webblocks-ui-manager, Einstellungs-Namensraum webblocks_ui_manager, Datenbankpräfix webblocks_ui_manager_, Befehle webblocks-ui-manager:prepare-release und webblocks-ui-manager:publish-release, Routen unter /webadmin/plugins/webblocks-ui-manager und Routennamen unter webblocks.plugins.webblocks_ui_manager.*.

Kompatibilität und Inaktivität

Plugin-Versionen sind semver-artige Metadaten. requiresCms() deklariert die vom Plugin benötigte CMS-Versionseinschränkung. Die aktuelle Grundlage unterstützt exakte/Vergleichs-Einschränkungen wie >=1.32.0 und Caret-Einschränkungen wie ^1.32.

Die Registry unterscheidet den konfigurierten Aktivierungsstatus vom aktiven Status:

  • Konfiguriert aktiviert: config/webblocks-plugins.php gibt an, dass das Plugin aktiviert sein soll.
  • Kompatibel: die installierte CMS-Version erfüllt die vom Plugin geforderte CMS-Einschränkung.
  • Aktiv: das Plugin ist sowohl konfiguriert aktiviert als auch kompatibel.

Nur aktive Plugins steuern Menüs, Routen, Befehle, Einstellungsrouten, Dashboard-Widgets, Systemkarten, Block-Deklarationen, öffentliche Assets, Berechtigungen und die Ausführung von Zustandsberichterstattern bei. Deaktivierte und inkompatible Plugins bleiben inaktiv. System -> Plugins zeigt Incompatible zusammen mit der erforderlichen und der installierten CMS-Version an, wenn ein konfiguriertes Plugin nicht aktiviert werden kann.

Discovery und lokale Aktivierung

Phase 5 fügt kein Marketplace-Verhalten und keine beliebige Remote-Installation hinzu. Sichere Discovery ist lokal und explizit:

  • First-Party-Plugins, die zum Paket gehören, können vom CMS-Paket-Provider registriert werden
  • zukünftige Composer-Paket-Plugins sollten einen Service-Provider über die Laravel-Paket-Discovery oder eine explizite App-Provider-Konfiguration registrieren
  • installationslokale Experimente können während der Entwicklung lokale Composer-Path-Repositories nutzen, müssen aber trotzdem einen normalen Provider und eine Definition registrieren
  • die Aktivierung bleibt konfigurationsgestützt über webblocks-plugins.enabled.{plugin-handle}

Keine Laufzeitfunktion installiert beliebige Composer-Pakete, veröffentlicht Marketplace-Kataloge, schreibt Produktions-Artefakte für CDN/Update-Server, aktiviert Plugins automatisch, führt Plugin-Migrationen/-Setup automatisch aus oder führt automatische Plugin-Updates durch. Brücken für entfernte Plugin-Artefakte sind auf die unten beschriebenen, von Super-Admins initiierten Installations-/Update-Aktionen des Plugin-Katalogs beschränkt, und beide sind auf kontrollierte Katalog-ZIP-URLs mit übereinstimmenden SHA-256-Metadaten begrenzt.

Ausrichtung des Ökosystem-Katalogs

Das CMS-Plugin-System ist der erste Implementierungs-Host für eine breitere Ausrichtung des WebBlocks-Plugin-Ökosystems. Zukünftige Plugin-Verträge sollten von WebBlocks CMS, QuizTem, Herne Panel, WebBlocks Publisher und späteren WebBlocks-Produkten wiederverwendbar sein, wobei jeder Host seine eigenen produktspezifischen Erweiterungspunkte bereitstellt.

Die vorgeschlagene Katalog-/Store-Oberfläche ist plugins.webblocksui.com. Das kurzfristige Ziel ist ein Plugin-Katalog für Discovery, Metadaten, Kompatibilität, Dokumentation, Release-Informationen, Prüfsummen, kontrollierte ZIP-Download-Links und eine konservative Installationsbrücke auf Basis vertrauenswürdiger Katalog-Artefakt-Metadaten. Marketplace-Verhalten, einschließlich Konten, Lizenzierung, kostenpflichtiger Plugins, Bewertungen und Freigabe-Workflows, ist zurückgestellt.

System -> Plugins enthält unter /webadmin/plugins/catalog (admin.plugins.catalog.index) eine Aktion Browse Plugin Catalog. Die Katalogliste fragt öffentlich gelistete Plugins für host_product=webblocks-cms über GET /api/plugins an und ruft, sobald ein Handle verfügbar ist, das neueste kompatible Release über GET /api/plugins/{handle}/latest ab. Katalog-Plugin-Beschriftungen und die Aktion View details öffnen /webadmin/plugins/catalog/{handle} (admin.plugins.catalog.show); diese Seite fragt GET /api/plugins/{handle} sowie den Endpunkt für das neueste kompatible Release an, um Plugin-Metadaten, Kompatibilität, Release Notes, Dokumentations-/Support-Links, Artefakt-Download-URL, SHA-256-Prüfsumme, Artefakt-Dateinamen, Artefaktgröße, Release-Status, Artefakt-Validierungsstatus, Artefakt-Scan-Status, Kanal, Version und sichere deklarierte Capability-Metadaten anzuzeigen, sofern die API diese zurückliefert. Aktuelle Detailantworten der WebBlocks Plugins API können Plugin-Daten direkt unter data, Release-Daten unter data.latest_release und Artefakt-Metadaten unter data.latest_release.artifact zurückgeben; Antworten der API für das neueste kompatible Release können Release-Metadaten außerdem unter data.release mit Artefakt-Metadaten im benachbarten data.artifact zurückgeben. Das CMS normalisiert diese Formen, bevor Details gerendert, die Installationsverfügbarkeit geprüft oder die serverseitige Kataloginstallationsaktion verarbeitet wird. Zu den unterstützten Artefaktfeldern gehören file_name, size_bytes, checksum_sha256, download_url, validation_status und scan_status; ältere flache Release-Feldnamen werden aus Kompatibilitätsgründen weiterhin akzeptiert. Die kanonische WebBlocks-CMS-Produktversion wird für den Kompatibilitätsabgleich als version und cms_version gesendet. Die integrierte öffentliche Katalog-URL ist standardmäßig https://plugins.webblocksui.com; Betreiber benötigen für die Standarderkennung keine .env-Änderungen und können das interne Anfrageziel mit WEBBLOCKS_PLUGIN_CATALOG_BASE_URL (webblocks-plugins.catalog.base_url) überschreiben. Timeout-Einstellungen stehen über WEBBLOCKS_PLUGIN_CATALOG_TIMEOUT_SECONDS und WEBBLOCKS_PLUGIN_CATALOG_CONNECT_TIMEOUT_SECONDS zur Verfügung. Die normale Katalogoberfläche zeigt weder die konfigurierte Basis-URL noch die Anfrageversion an; bei Nichtverfügbarkeit werden verständliche Hinweise für Betreiber angezeigt, während sichere Diagnosedaten in den Logs verbleiben.

Die Katalogdetailseite hält die Links Website, Documentation, Support und Catalog Detail von Installationsaktionen getrennt. Die Seite zeigt einen eindeutigen Zustand für nicht verfügbare Artefakte, wenn ein kompatibles Release keine herunterladbaren Artefakt-Metadaten enthält. Die Aktion Download ZIP öffnet ausschließlich die kontrollierte absolute öffentliche download_url, die vom Katalog zurückgegeben wird, und darf keine rohen Speicherpfade offenlegen.

Install from Catalog ist nur verfügbar, wenn das Katalog-Plugin kompatibel ist, das neueste kompatible Release den Status published hat und das normalisierte Release-Artefakt Werte für download_url, checksum_sha256 und file_name enthält. Ältere flache Release-Felder sha256/checksum_sha256 und filename/artifact_filename werden aus Kompatibilitätsgründen weiterhin akzeptiert. Die POST-Aktion verwendet CSRF, liest die Katalog-Metadaten serverseitig erneut, lädt die kontrollierte ZIP-URL in temporären Speicher herunter, prüft den HTTP-Erfolg, weist unplausible bzw. Nicht-ZIP-Antworten zurück, berechnet SHA-256, vergleicht diese Prüfsumme exakt mit den Katalog-Metadaten und übergibt das temporäre ZIP anschließend an den vorhandenen manuellen Plugin-ZIP-Validator/-Installer. Temporäre Dateien werden nach Erfolg oder Fehlschlag entfernt, und Dateinamen aus dem Katalog oder von entfernten Quellen wird nicht als Dateisystempfade vertraut.

Kataloginstallationen registrieren das Plugin standardmäßig deaktiviert, genau wie der manuelle Upload. Sie aktivieren das Plugin nicht, führen keine Plugin-Migrationen bzw. kein Setup aus, führen keinen Plugin-Provider-Code aus, registrieren keine Plugin-Routen, keine Berechtigungen, keine Befehle, keine Assets und keine Blocks, fügen keine Dashboard-/System-Karten hinzu, wenden keine Updates an und ändern den Aktivierungszustand nicht. Jeder auf der Katalogdetailseite angezeigte lokale Installations-/Aktivierungszustand stammt ausschließlich aus der CMS-Plugin-Registry, nicht aus Angaben des entfernten Katalogs. Der manuelle ZIP-Upload bzw. die manuelle Installation bleibt verfügbar und unverändert.

System -> Plugins -> Registered Plugins führt für installierte Plugin-Handles eine Best-Effort-Abfrage der Katalogverfügbarkeit durch. Wenn der Katalog nicht verfügbar ist oder keine vertrauenswürdigen Metadaten liefert, wird die Liste dennoch gerendert und keine Update-Aktion angezeigt. Wenn für ein installiertes Handle laut version_compare ein neueres neuestes kompatibles Release vorliegt, dieses Release published ist, das Plugin kompatibel ist und das normalisierte Artefakt download_url, checksum_sha256 und file_name enthält, zeigt die Spalte Version Update available: {version} an und die Zeilenaktionsgruppe zeigt eine ausschließlich per POST ausgelöste Symbolaktion Update from Catalog.

Der Update-POST liest die Katalogdetail- bzw. Latest-Metadaten serverseitig erneut, verlangt dieselben vollständigen Artefakt-Metadaten eines kompatiblen veröffentlichten Releases, lädt das kontrollierte ZIP herunter, verifiziert SHA-256, validiert das ZIP über denselben Plugin-Paket-Validator und ersetzt die installierte Plugin-Paketversion. Die pluginzugehörigen Datenbanktabellen bleiben erhalten, der aktivierte oder deaktivierte Lebenszykluszustand bleibt erhalten, indem der Aktivierungszustand nur dann auf die neue Version übertragen wird, wenn die alte Version aktiviert war, und Plugin-Migrationen werden nicht automatisch ausgeführt. Deklariert das aktualisierte Plugin neue Migrationen oder fehlen seine Tabellen, bleiben die bestehende Anleitung für erforderliches Setup und der explizite Ablauf Run Plugin Migrations für die Schemaeinrichtung zuständig.

Siehe WebBlocks Plugin-Ökosystem und Katalog für die Ausrichtung auf Produktebene und den Phasenplan.

Die Planung für die vorgeschlagene Produktoberfläche plugins.webblocksui.com, den MVP-Umfang, mögliche Implementierungsmodelle, öffentliche Katalogseiten, Betreiberoberflächen und eine mögliche schreibgeschützte API-Form findet sich in der Plugin-Katalog-Produktarchitektur.

Minimales Plugin-Beispiel

Ein minimales Plugin-Paket sollte einen Provider und eine Definition ähnlich der folgenden bereitstellen:

final class AnalyticsToolsPlugin
{
  public static function definition(): PluginDefinition
  {
    return PluginDefinition::make('analytics-tools')
      ->label('Analytics Tools')
      ->version('0.1.0')
      ->provider(AnalyticsToolsServiceProvider::class)
      ->requiresCms('^1.32')
      ->settingsNamespace('analytics_tools')
      ->databasePrefix('analytics_tools_')
      ->permissions([
        PluginPermission::make('analytics-tools.view')->label('View analytics tools'),
      ])
      ->adminRoutes(__DIR__.'/../routes/admin.php')
      ->commands([
        SyncAnalyticsCommand::class,
      ])
      ->health(AnalyticsToolsHealth::class);
  }
}

Der Provider sollte Paket-Views, Konfiguration, Migrationen und die Plugin-Definition registrieren, ohne CMS-eigene /admin-, /cms- oder öffentliche Root-Routendateien hinzuzufügen. Plugin-Routen sollten relativ zur Plugin-Routengruppe definiert werden; aus /reports wird beispielsweise /webadmin/plugins/analytics-tools/reports.

Regeln für das Admin-Menü

Plugins dürfen Einträge zum Admin-Menü hinzufügen, aber jeder Plugin-Menüeintrag muss durch eine Berechtigung geschützt sein.

Bevorzugt werden Einträge zu bestehenden Admin-Gruppen hinzugefügt, etwa:

  • System
  • Tools
  • Integrations

Ein Plugin-Menü auf oberster Ebene darf nur für eine große Produktoberfläche reserviert werden, die als einzelner Gruppeneintrag verwirrend wäre.

Regeln für das Admin-Menü:

  • Icons müssen aus dem WebBlocks-UI-Icon-Katalog stammen
  • Routennamen müssen im Plugin-Routen-Namensraum liegen
  • Menüreihenfolge und Kollisionsregeln müssen von der Registry verwaltet werden
  • deaktivierte oder nicht installierte Plugins dürfen keine Menüeinträge rendern
  • Menübeschriftungen sollten die Funktion beschreiben und keine installationsspezifischen Projektnamen in generische CMS-Installationen durchsickern lassen
  • Menüeinträge dürfen in Core-Installationen nicht erscheinen, wenn das zugehörige Plugin fehlt

Regeln für Routen-Namensräume

Admin-Plugin-Routen verwenden standardmäßig dieses URL-Präfix:

/webadmin/plugins/{plugin-handle}/...

Admin-Plugin-Routennamen verwenden standardmäßig diesen Namensraum:

webblocks.plugins.{plugin_handle}.*

Der Routennamen-Namensraum verwendet das Plugin-Handle und wandelt es nur so weit um, wie es für Laravel-Routennamen erforderlich ist. Beispielsweise wird aus webblocks-ui-manager der Namensraum webblocks.plugins.webblocks_ui_manager.*, falls die Implementierung Unterstriche erfordert.

Ein Plugin darf ein kürzeres Admin-Präfix nur über die Registry anfordern. Reservierte Kurzpräfixe müssen global eindeutig sein. Präfixkonflikte müssen beim Build, in Tests, in der Boot-Diagnose oder bei der Plugin-Aktivierung fehlschlagen.

Plugins dürfen Folgendes nicht verunreinigen:

  • CMS-Core-Routennamen
  • den /webadmin-Core-Routen-Namensraum außerhalb ihres reservierten Plugin-Präfixes
  • den Legacy-Namensraum /admin
  • den statischen Asset-Namensraum /cms

Deaktivierte und inkompatible Plugins dürfen keine Admin-Routen registrieren. Der Registrar für ausschließlich aktive Plugins ist bewusst konservativ: Ist ein Plugin über config/webblocks-plugins.php deaktiviert oder erfüllt es seine CMS-Versionsbedingung nicht, sind seine Routen abwesend statt vorhanden-aber-verboten.

Öffentliche Routen sind Opt-in. Ein Plugin, das öffentliche Routen deklariert, muss die Eigentümerschaft so klar deklarieren, dass die Routen-Eigentümerschaft testbar ist. Öffentliche Plugin-Routen müssen Kollisionen mit Site-Seiten, öffentlichen CMS-Routen und Routen des Host-Produkts vermeiden.

Berechtigungsregeln

Jedes Admin-Menü, jede Route und jede Aktion muss an eine Plugin-Berechtigung gebunden sein.

Berechtigungsnamen müssen das Plugin-Handle-Präfix enthalten:

webblocks-ui-manager.view
webblocks-ui-manager.publish
webblocks-ui-manager.settings

Das Berechtigungsverhalten muss mit dem CMS-Berechtigungsmodell kompatibel bleiben. Falls ein Super-Admin-Bypass existiert, muss er denselben expliziten CMS-Autorisierungspfad verwenden wie die Core-CMS-Berechtigungen.

Plugin-Berechtigungen müssen in der Admin-Rollenverwaltung sichtbar sein, wenn das Plugin installiert oder auffindbar ist. Berechtigungen deaktivierter Plugins dürfen kein aktives Verhalten autorisieren, selbst wenn eine Rolle noch eine passende Berechtigungszeichenkette speichert.

Einstellungsregeln

Plugin-Einstellungen müssen im eigenen Namensraum des Plugins gespeichert werden. Sie dürfen nicht mit der allgemeinen CMS-Konfiguration, der Konfiguration der Host-Anwendung oder Umgebungsvariablen kollidieren.

Einstellungsregeln:

  • Einstellungsschlüssel sollten mit dem Plugin-Handle als Präfix versehen sein
  • sensible Werte müssen, wo verfügbar, eine für Geheimnisse geeignete Speicherung verwenden
  • sensible Werte dürfen niemals in Logs, Health-Check-Ausgaben, Ausnahmemeldungen oder Admin-Flash-Meldungen gerendert werden
  • die Einstellungsoberfläche muss im Plugin-Routen-Namensraum oder unter System -> Plugins -> Plugin detail liegen
  • Umgebungsvariablen dürfen Standardwerte vorbelegen, aber Laufzeiteinstellungen sollten pluginzugehörig bleiben und über die Registry einsehbar sein

Phase 2 stellt eine schreibgeschützte Einstellungs-Routen-Grundlage für aktivierte Plugins bereit, die PluginSettingsDefinition ohne eigenen Routennamen deklarieren. Die Standardroute lautet:

/webadmin/plugins/{plugin-handle}/settings

Ihr Standardroutenname lautet:

webblocks.plugins.{plugin_handle}.settings.edit

Editierbare Einstellungsspeicherung und Validierungsschemata sind einer späteren Phase vorbehalten. Phase 5 reserviert Einstellungs-Namensräume über PluginDefinition::settingsNamespace(), damit Plugins nicht mit der CMS-Core-Konfiguration oder anderen Plugins kollidieren.

Regeln für Migrationen und Datenlebenszyklus

Plugin-Migrationen dürfen nicht mit Core-Migrationen kollidieren.

Plugin-Tabellennamen müssen das Plugin-Handle-Präfix oder ein dokumentiertes, von der Plugin-Registry reserviertes Kurzpräfix tragen. Für webblocks-ui-manager verwenden Tabellennamen webblocks_ui_manager_. Phase 5 reserviert Datenbankpräfixe über PluginDefinition::databasePrefix() und weist doppelte Präfixe zurück.

Die Lebenszykluszustände müssen klar voneinander getrennt sein:

  • Aktivieren: Plugin-Menü, Routen, Befehle, geplante Jobs, Widgets, Blocks, Einstellungen, Health-Checks und Aktionen werden entsprechend Berechtigungen und Kompatibilität verfügbar.
  • Deaktivieren: Plugin-Menü, geplante Jobs, Plugin-Routen, Plugin-Aktionen, Einstellungsrouten, Health-Checks, Widgets, Blocks und Assets sind nicht verfügbar; die Daten bleiben erhalten.
  • Deinstallieren: manuell hochgeladene deaktivierte Plugins können aus dem speicherverwalteten Installationsstammverzeichnis entfernt werden. Pluginzugehörige Datenbanktabellen und historische Daten bleiben erhalten.
  • Deinstallieren: einem zukünftigen Design vorbehalten; standardmäßig dürfen dabei keine Daten gelöscht werden.
  • Außerbetriebnahme oder Bereinigung: zukünftiger destruktiver Datenlöschablauf, der eine explizite destruktive Bestätigung erfordert.

Die Deinstallation darf nicht datenbankdestruktiv sein. Das Löschen von Plugin-Tabellen, Artefakten, hochgeladenen Dateien außerhalb des Plugin-Paketverzeichnisses oder historischen Datensätzen erfordert ein separates, explizites Design mit destruktiver Bestätigung.

Schema-Upgrades sollten additiv und, wo praktikabel, umkehrbar sein. Ein Plugin-Release, das das Schema ändert, muss Folgendes dokumentieren:

  • minimale kompatible CMS-Version
  • Plugin-Version, die das Schema einführt
  • verwendetes Migrations-/Tabellenpräfix
  • ob deaktivierte Plugins vorhandene Daten sicher an Ort und Stelle belassen können
  • operative Hinweise für Rollback oder Außerbetriebnahme

Der manuelle Plugin-Migrationsrunner ist bewusst eng gefasst. Er führt nur Migrationsverzeichnisse aus, die vom installierten Plugin deklariert wurden, und nur, nachdem diese Verzeichnisse innerhalb des konfigurierten Plugin-Installationsstamms aufgelöst wurden. Er führt weder Migrationen der Host-App noch Migrationen anderer Plugins aus. Plugin-Migrationen sollten additiv, wo praktikabel umkehrbar und bei erforderlicher Setup-Reparatur sicher wiederholbar sein.

Regeln für Assets und statische Dateien

Plugin-Assets müssen unter ihrem eigenen Namensraum veröffentlicht werden. Sie dürfen sich nicht mit den Core-Assets unter public/cms vermischen.

Für den WebBlocks UI Manager sollte versionierte CDN-Ausgabe unveränderliche Pfade verwenden, etwa:

public/cdn/webblocks-ui/v2.7.9/...

Asset-Regeln:

  • versionierte Artefaktverzeichnisse sind unveränderlich
  • alte versionierte Verzeichnisse dürfen im Rahmen einer normalen Veröffentlichung nicht gelöscht werden
  • latest darf nicht für die First-Party-CDN-Nutzung verwendet werden
  • eine Dry-Run-Veröffentlichung muss Schreibvorgänge, Auslassungen und blockierte Operationen melden, ohne Dateien zu schreiben
  • eine Apply-Veröffentlichung muss erwartete Dist-Dateien, Quellpfade, Release-Version, Zielpfade, Prüfsummen und Manifest-Konsistenz vor dem Schreiben validieren
  • vorhandene Dateien mit übereinstimmenden Prüfsummen werden übersprungen; vorhandene Dateien mit abweichenden Prüfsummen blockieren den Lauf
  • CDN oder statisches Hosting sollte nach Möglichkeit von Nginx oder einem anderen statischen Dienst ausgeliefert werden
  • Laravel-routenbasiertes Asset-Streaming darf nicht der Standard für CDN-Dateien sein
  • Plugin-Admin-Assets müssen von den Core-CMS-Admin-Assets isoliert sein und unter einem Plugin-Namensraum veröffentlicht werden

Der lokale Veröffentlichungs-Workflow des WebBlocks UI Managers schreibt ausschließlich in das konfigurierte, projekteigene statische Ziel, standardmäßig public/cdn/webblocks-ui/{version}/.... Er deployt nicht auf externe Produktionsinfrastruktur, veröffentlicht keine Update-Server-Metadaten, ändert keine WebBlocks-UI-Nutzungs-URLs des CMS-Cores und installiert keine Remote-Pakete.

Phase 3 fügt registrygestützte öffentliche Asset-Deklarationen für aktivierte Plugins hinzu. Diese Deklarationen sind derzeit auf explizite Asset-URLs beschränkt und werden nur dann als öffentliche Seiten-Assets gerendert, wenn das zugehörige Plugin aktiviert ist:

  • Head-CSS wird als <link rel="stylesheet"> im öffentlichen <head> gerendert
  • Head-JS wird als deferred- oder async/module-<script>-Tags im öffentlichen <head> gerendert
  • Body-End-JS wird nahe dem Ende des öffentlichen <body> gerendert
  • Asset-Handles müssen mit dem Plugin-Handle punktnamensraumbasiert sein, etwa analytics-tools.public-js
  • Assets deaktivierter Plugins fehlen bei Sammlung und Rendering

Dies ist eine Grundlage für Asset-Beitrags-Hooks, kein Plugin-Paket-Installer und kein Asset-Publisher. Plugins bleiben dafür verantwortlich, ihre eigenen statischen Dateien unter einem plugineigenen Namensraum zu veröffentlichen.

Regeln für Events, Hooks und Extension-Slots

Plugins dürfen den Core nicht per Monkey-Patching verändern oder überschreiben. Core-Extension-Slots müssen explizit, dokumentiert und testbar sein.

Erste Kandidaten für Extension-Slots:

  • admin.menu
  • admin.dashboard.widgets
  • admin.system.cards
  • permissions.registry
  • block.registry
  • public.head.assets
  • public.body_end.assets

Slot-Verträge sollten typisiert und auf Value Objects basiert sein. Vermeiden Sie nach Möglichkeit rohe Array-Verträge, damit Kollisionen, ungültige Strukturen und Eigentümerschaft frühzeitig validiert werden können.

Phase 3 implementiert diese typisierten Erweiterungs-Slot-Objekte:

  • PluginDashboardWidget für schreibgeschützte Dashboard-Karten
  • PluginSystemCard für schreibgeschützte Systemkarten oder Links
  • PluginBlockTypeDefinition für plugineigene Blocktyp-Deklarationen
  • PluginBlockPackDefinition für gruppierte Plugin-Block-Deklarationen
  • PluginPublicAsset für öffentliche Asset-Deklarationen im Head und am Body-Ende
  • PluginAdminExtensionRegistry, PluginBlockRegistry und PluginPublicAssetRegistry für die Sammlung nur aktivierter Beiträge

Schlüssel von Dashboard-Widgets und Systemkarten müssen mit dem Plugin-Handle punktnamensraumbasiert sein, zum Beispiel analytics-tools.overview. Öffentliche Asset-Handles folgen derselben Punktnamensraum-Regel. Plugin-Block-Handles müssen einen plugineigenen Namensraum wie analytics-tools::score-card verwenden; unqualifizierte Block-Handles im Core-Stil wie hero werden abgelehnt. Diese Hooks machen Plugin-Beiträge auffindbar und zuordenbar, ohne Core-Paket-Views zu ersetzen.

Dashboard-Widgets werden nur dann auf dem Super-Admin-Dashboard gerendert, wenn das Plugin aktiviert ist und der aktuelle Benutzer die Widget-Berechtigung erfüllt, sofern eine deklariert ist. Systemkarten werden nur auf den dafür vorgesehenen Systemübersichtsflächen unter denselben Aktivierungs- und Berechtigungsprüfungen gerendert. Die Verwaltungsseite System -> Plugins rendert keine generischen Plugin-Beitragskarten; sie bleibt auf manuelle Plugin-Installation, Lebenszyklus, Zustand, Einrichtung, Einstellungen und Deinstallationsaktionen fokussiert, sofern nicht künftig ein Erweiterungs-Slot explizit für die Plugin-Verwaltung entworfen wird. Beide Slots sind bewusst schreibgeschützte Grundlagen.

Block-Hooks sind reine Deklarationsgrundlagen. Sie erlauben aktivierten Plugins, plugineigene Blocktypen und Block-Packs über die Registry bereitzustellen, ersetzen aber weder Core-Block-Verträge, Core-Block-Views, Core-Block-Seeder noch Blockbearbeitungsdienste.

Plugin-Lebenszyklus

Das Ziel für den vollständigen Lebenszyklus:

  1. Entdecken
  2. Installieren
  3. Aktivieren
  4. Deaktivieren
  5. Zustand/Status
  6. Upgrade
  7. Deinstallation oder Stilllegung, in einem späteren Design für destruktive Daten

Das implementierte Laufzeitziel von Phase 1 bis Phase 5 ist bewusst kleiner als der vollständige Lebenszyklus:

  • Registry
  • Aktivierungskonfiguration
  • System -> Plugins-Auflistung
  • System -> Plugins-Detail- und schreibgeschützte Einstellungsflächen
  • Registrierung von Admin-Menüs
  • Registrierung von Berechtigungen
  • Registrierung von Admin-Routen nur bei aktivierten Plugins
  • Registrierung von Befehlen nur bei aktivierten Plugins
  • grundlegendes Zustands-/Statusreporting
  • typisierte, schreibgeschützte Erweiterungs-Slots für Dashboard- und Systemkarten
  • Deklarations-Hooks für plugineigene Blöcke und Block-Packs
  • Beitrags-Hooks für öffentliche Assets im Head und am Body-Ende
  • First-Party-Pilot-Plugin WebBlocks UI Manager mit Release-Metadaten, sicherer lokaler Manifest-Vorbereitung und kontrolliertem lokalem CDN-Dry-Run/Apply-Publishing
  • Metadaten für Plugin-Version und erforderliche CMS-Kompatibilität
  • Aktivstatus- und Zustandsreporting für inkompatible Plugins
  • Paketkonventions- und Kollisionsschutz
  • Schutz der Routen-Eigentümerschaft

Diese Grundlage gibt dem CMS eine sichere Host-Grenze, bevor Plugins tiefergehendes Lebenszyklusverhalten erhalten.

Implementierungshinweis zu Phase 1

Die initiale Laufzeit von Phase 1 umfasst jetzt:

  • die Value Objects PluginDefinition, PluginRegistry, PluginMenuItem und PluginPermission unter dem Paket-Namensraum Support\Plugins
  • deterministische Validierung für Kebab-Case-Handles, doppelte Handles, doppelte Menüpunkt-Schlüssel, semver-ähnliche Versionen und mit dem Handle präfixierte Plugin-Berechtigungen
  • konfigurationsgestützten Aktivierungsstatus über config/webblocks-plugins.php
  • eine paketeigene System -> Plugins-Auflistung unter /webadmin/system/plugins
  • Routen-Schutzabdeckung, die belegt, dass /webadmin kanonisch bleibt, während CMS-eigene /admin- und Laravel-/cms-Routen weiterhin fehlen

Phase 1 umfasst keine dynamische Composer-Plugin-Erkennung, keine Plugin-Migrationen, keine UI-Aktionen zum Installieren/Aktivieren/Deaktivieren, keine öffentlichen Plugin-Routen, kein Marketplace-/Katalogverhalten und keine WebBlocks UI Manager-Geschäftslogik. Der konfigurationsgestützte Aktivierungsstatus ist bewusst eine Brücke; eine spätere Lebenszyklusphase kann den Installations-/Aktivierungs-/Deaktivierungsstatus in persistente Speicherung überführen.

Implementierungshinweis zu Phase 2

Die Laufzeit von Phase 2 umfasst jetzt:

  • Registrierung von Plugin-Admin-Routen nur bei aktivierten Plugins über PluginRouteRegistrar
  • Standard-Admin-Plugin-URLs unter /webadmin/plugins/{plugin-handle}/...
  • Standard-Admin-Plugin-Routennamen unter webblocks.plugins.{plugin_handle}.*
  • schreibgeschützte Standard-Einstellungsseiten für aktivierte Plugins, die PluginSettingsDefinition deklarieren
  • Sammlung von Konsolenbefehlen nur bei aktivierten Plugins über PluginCommandRegistrar
  • PluginHealthResult, PluginLifecycleStatus und PluginHealthMonitor für grundlegendes Statusreporting
  • System -> Plugins-Detailseiten, die Zusammenfassungen zu Lebenszyklus, Zustand, Einstellungen, Routen, Befehlen, Berechtigungen und Menübeiträgen anzeigen
  • Routen-Schutzabdeckung, die belegt, dass Routen aktivierter Test-Plugins registriert werden, Routen deaktivierter Plugins fehlen, /webadmin kanonisch bleibt, /cms kein Laravel-Admin-Routennamensraum ist und CMS-eigene /admin-Routen weiterhin fehlen

Diese Phase hält Migrationserkennung, Plugin-Aktionen zum Installieren/Anwenden/Ausführen, destruktive Lebenszyklusaktionen, dynamische Composer-Erkennung, öffentliche Plugin-Routen und das Laufzeitverhalten des WebBlocks UI Manager bewusst außerhalb des Umfangs.

Implementierungshinweis zu Phase 3

Die Laufzeit von Phase 3 umfasst jetzt:

  • typisierte Admin-Erweiterungsverträge unter Support\Plugins\Contracts
  • die Value Objects PluginDashboardWidget und PluginSystemCard, gesammelt über PluginAdminExtensionRegistry
  • Rendering von Dashboard-Widgets auf dem Super-Admin-Dashboard nur bei aktivierten Plugins
  • Sammlung von Systemkarten nur bei aktivierten Plugins für die vorgesehenen Systemübersichtsflächen, getrennt von der System -> Plugins-Lebenszyklusverwaltungsseite
  • PluginBlockTypeDefinition, PluginBlockPackDefinition und PluginBlockRegistry für plugineigene Block-Deklarationen
  • PluginPublicAsset und PluginPublicAssetRegistry für sichere öffentliche Asset-Deklarationen im Head und am Body-Ende
  • Validierungsschutz für Erweiterungsschlüssel, Widget-Schlüssel, Systemkartenschlüssel, Block-Handles, Block-Pack-Namensräume, Asset-Handles, Plugin-Eigentümerschaft und doppelte Deklarationen
  • inertes Verhalten deaktivierter Plugins für Dashboard-Widgets, Systemkarten, Block-Hooks und öffentliche Assets
  • Routen-Schutzabdeckung, die bestätigt, dass /webadmin und /webadmin/plugins/... gültig bleiben, während /admin- und Laravel-/cms-Admin-Routen weiterhin fehlen

Diese Phase hält echtes Marketplace-Verhalten, Paketinstallation, Plugin-Migrations-Runner, öffentliche Plugin-Routen, bearbeitbare Widgets, Core-Block-Override-Hooks und das WebBlocks UI Manager-Plugin bewusst außerhalb des Umfangs. Plugins dürfen weiterhin keine Paket-Views überschreiben und keine Core-Dienste per Monkey-Patching verändern.

Implementierungshinweis zu Phase 4

Die Laufzeit von Phase 4 umfasst jetzt das First-Party-Pilot-Plugin webblocks-ui-manager. Das Plugin wird von der Paket-Registry registriert, ist aber über config/webblocks-plugins.php standardmäßig deaktiviert.

Wenn aktiviert, steuert der Pilot Folgendes bei:

  • mit dem Handle präfixierte Berechtigungen: webblocks-ui-manager.view, webblocks-ui-manager.manage und webblocks-ui-manager.publish
  • einen Plugin-Admin-Routennamensraum unter /webadmin/plugins/webblocks-ui-manager/... mit Routennamen unter webblocks.plugins.webblocks_ui_manager.*
  • einen Plugin-Menüpunkt für WebBlocks UI-Release-Datensätze
  • schreibgeschützte Dashboard- und Systemkarten über die Erweiterungs-Slots aus Phase 3
  • schreibgeschützte Einstellungs-/Detailsichtbarkeit über die Einstellungsgrundlage aus Phase 2
  • Plugin-Zustandsprüfungen für die Bereitschaft der Release-Metadaten, den Status „Einrichtung erforderlich/Tabelle fehlt“ und die Bereitschaft des konfigurierten CDN-Basispfads
  • plugineigene Tabellen und Modelle: webblocks_ui_manager_releases, webblocks_ui_manager_artifacts und webblocks_ui_manager_publish_runs
  • einen sicheren lokalen Befehl webblocks-ui-manager:prepare-release, der Release-Metadaten aufzeichnet, SHA-256-Prüfsummen der Artefakte berechnet und optional eine lokale manifest.json schreiben kann
  • einen kontrollierten Workflow webblocks-ui-manager:publish-release {version} --dry-run und webblocks-ui-manager:publish-release {version}, der Publish-Läufe aufzeichnet und erst nach bestandener Validierung schreibt
  • First-Party-CDN-Zielkonventionen unter public/cdn/webblocks-ui/{version}/...

Der deaktivierte Zustand bleibt inert: Routen, Befehle, Menüs, Einstellungsrouten, Berechtigungen, Dashboard-/Systemkarten, Zustandsverhalten und Asset-Beiträge fehlen in der aktiven Sammlung. Der aktivierte, aber nicht eingerichtete Zustand bleibt sicher: Das Menü kann sichtbar sein, aber die Releases-Route prüft vor der Abfrage die Schemabereitschaft und zeigt eine Anleitung „Einrichtung erforderlich“ an, wenn Release-Tabellen fehlen. Aktivierte, kompatible manuelle Plugin-Admin-URLs dürfen nicht auf das Dashboard zurückfallen, wenn die dynamische Routen-Hydrierung veraltet ist oder Routen-Caching aktiv ist; der Plugin-Routen-Fallback hält bekannte Plugin-Admin-Seiten auf ihrer /webadmin/plugins/{plugin-handle}/...-URL und rehydriert plugineigene Routen/Quellen, bevor kontrollierte Einrichtungs- oder Betriebsbildschirme gerendert werden. First-Party-URLs für WebBlocks UI Manager Releases, die Release-Aktionen create/store/show/edit/update/dry-run/publish sowie die Settings-URLs werden zusätzlich über den CMS-Kern überbrückt, bevor Plugin-Routendateien ausgeführt werden, damit veralteter installierter Artefaktquellcode diese Aktionen nicht zurück zum Dashboard schicken kann.

Phase 4 fügt bewusst keine Automatisierung für externe Produktions-CDN-Bereitstellung, kein Marketplace-Verhalten, keine generischen Installations-/Update-Flows für Drittanbieter-Plugins, keine generischen Plugin-Migrations-Runner, keine öffentlichen Plugin-Routen, keine Core-View-Overrides, kein Update-Server-Publishing und keine Änderungen an den WebBlocks UI-Verbrauchs-URLs des CMS-Kerns hinzu.

Implementierungshinweis zu Phase 5

Die Laufzeit von Phase 5 umfasst jetzt Grundlagen für Paketierung und Ökosystem-Bereitschaft:

  • Kompatibilitätsprüfungen der Plugin-Version und von requiresCms() gegen die installierte CMS-Version
  • vom Aktivstatus getrennten konfigurierten Aktivierungsstatus, sodass inkompatible konfigurierte Plugins inert bleiben
  • System -> Plugins-Lebenszyklusmeldungen für Enabled, Disabled und Incompatible
  • Zustandsergebnisse inkompatibler Plugins, die keine Plugin-Zustandsreporter ausführen
  • Konventionsmetadaten für Einstellungs-Namensräume und Datenbank-/Tabellenpräfixe
  • Befehlsnamen-Schutz für auflösbare Artisan-Befehlsklassen mit der Anforderung {plugin-handle}:...
  • Kollisionsschutz für Datenbankpräfixe
  • fokussierte Tests für Kompatibilitätsmetadaten, inkompatibles Verhalten, Befehls- und Präfixkollisionen, Inertheit bei Deaktivierung/Inkompatibilität, WebBlocks UI Manager-Regression, Paketgrenzen und Routen-Eigentümerschaft
  • Dokumentation für Paketkonventionen, lokale Erkennung, minimale Plugin-Erstellung, Schema-Upgrade-Strategie und Release-Kompatibilitätsrichtlinie

Phase 5 fügt bewusst keine Marketplace-/Katalog-UI, keine beliebige Remote-Paketinstallation, keine dynamische Remote-Composer-Erkennung, keine generischen Migrations-Runner für Drittanbieter-Plugins, keine automatische externe Produktions-CDN-Bereitstellung, kein generisches Update-Server-Publishing und keine öffentlichen Plugin-Routen hinzu.

Test- und Release-Leitplanken

Das Plugin-System muss durch Tests zu Routen-Eigentümerschaft, Paketgrenzen und Koexistenz geschützt sein.

Erforderliche Leitplanken:

  • Die Plugin-Routen-Eigentümerschaft ist testbar
  • Core-CMS-Installationen zeigen keine Plugin-Menüs, wenn keine Plugins aktiviert sind
  • Menüs deaktivierter Plugins werden nicht gerendert
  • Routen und Aktionen deaktivierter Plugins sind nicht verfügbar oder scheitern an der Autorisierung
  • Widgets, Systemkarten, Block-Deklarationen und öffentliche Assets deaktivierter Plugins fehlen
  • Routen, Befehle, Menüs, Berechtigungen, Widgets, Systemkarten, Block-Deklarationen, öffentliche Assets, Einstellungsrouten und Zustandsreporter-Verhalten inkompatibler Plugins fehlen
  • Befehlsnamen, Datenbankpräfixe, Handles, Erweiterungs-Slots, Widgets, Blöcke, Assets und Berechtigungsnamensräume bleiben kollisionsgeschützt
  • Plugin-Dashboard-/System-Erweiterungskarten werden nur gerendert, wenn aktiviert und berechtigt
  • plugineigene Block-Deklarationen sind auffindbar, ohne Core-Block-Verträge zu überschreiben
  • öffentliche Plugin-Assets werden nach sicherem Ort gesammelt und fehlen bei Deaktivierung
  • die Plugin-Routenregistrierung darf keinen CMS-eigenen /admin-Namensraum wiederherstellen
  • /webadmin bleibt das kanonische CMS-Admin-Präfix
  • /cms bleibt Gebiet statischer Assets, kein Laravel-Plugin-Routennamensraum
  • Versuche von Plugins, Core-Tabellen, Routennamen oder Views zu überschreiben, sollten in Tests oder Diagnosen fehlschlagen
  • Paketgrenzen-Tests werden erweitert, um plugineigene Routen, Views, Assets, Migrationen und Befehle abzudecken
  • Koexistenztests sollten in der Roadmap CMS-+-QuizTem-+-Plugin-Szenarien abdecken

Plugin-Tests sollten sowohl Fälle ohne Plugin als auch mit deaktiviertem Plugin umfassen, damit das Core-CMS in generischen Installationen sauber bleibt. Der WebBlocks UI Manager-Pilot trägt außerdem Tests zu Migration/Schema, Befehlen, Manifest/Prüfsumme, Nur-bei-Aktivierung, Inertheit bei Deaktivierung, Admin-Rendering, Routenschutz und Paketgrenzen.

Entscheidungen zum Pilot-Plugin WebBlocks UI Manager

WebBlocks UI Manager ist nicht in das Core-Verhalten des CMS eingebettet. Es startet derzeit als paketeigenes First-Party-Pilot-Plugin unter dem CMS-Paketnamensraum, damit der Plugin-Host eine echte produktspezifische Betriebsoberfläche nachweisen kann, ohne die WebBlocks UI-Release-/CDN-Verwaltung in den generischen CMS-Kern zu verlagern.

Das bevorzugte langfristige Modell kann dennoch ein separates Composer-Paket oder ein separates Repository werden, sobald Plugin-Lebenszyklus und Paketierungskonventionen ausgereift sind.

Die Verantwortung des Plugins:

  • WebBlocks UI-Release-Artefakt-Datensätze
  • Validierung der Quell-Dist
  • sichere lokale Publish-Vorbereitung
  • kontrollierte lokale statische Publish-Dry-Runs und Apply-Läufe
  • Publish-Lauf-Historie
  • Manifest- und Prüfsummenerzeugung
  • CDN-Zustandsprüfungen

Der WebBlocks UI-Build bleibt im WebBlocks UI-Repository. Das Plugin baut WebBlocks UI nicht. Es empfängt oder validiert Release-Artefakte, zeichnet lokale Metadaten für First-Party-CDN-Pfade auf und kann validierte Dateien in das konfigurierte lokale/projekteigene statische Ziel veröffentlichen. Die externe Produktions-CDN-Bereitstellung ist bewusst zurückgestellt und muss explizit bleiben.

Unsere eigenen Produkte dürfen cdn.webblocksui.com für gepinnte First-Party-Assets nutzen. Die externe Benutzerdokumentation sollte weiterhin die CDN-Nutzung über GitHub oder jsDelivr empfehlen, sofern sich diese Richtlinie nicht separat ändert.

CDN-Regeln für den Piloten:

  • Verwenden Sie versionierte Pfade
  • Verwenden Sie nicht latest
  • Verändern Sie niemals ein bestehendes versioniertes Artefaktverzeichnis
  • Löschen Sie beim normalen Publishing keine alten versionierten CDN-Verzeichnisse
  • Führen Sie bei manueller Bedienung vor dem Apply einen Dry-Run aus
  • Blockieren Sie Prüfsummenabweichungen, statt Dateien stillschweigend zu ersetzen
  • Bevorzugen Sie statische Auslieferung gegenüber Laravel-Routen-Streaming

WebBlocks UI Manager Publish-Ablauf

Release-Metadaten und Prüfsummen vorbereiten:

php artisan webblocks-ui-manager:prepare-release v2.7.9 --artifact=/path/to/webblocks-ui.css --artifact=/path/to/webblocks-icons.css --artifact=/path/to/webblocks-ui.js

Publish als Dry-Run ausführen:

php artisan webblocks-ui-manager:publish-release v2.7.9 --dry-run

Das lokale Publish anwenden:

php artisan webblocks-ui-manager:publish-release v2.7.9

Der Admin-Release-Detailbildschirm bietet dieselben Dry-Run- und Publish-Aktionen, wenn das Plugin aktiviert und kompatibel ist und der Benutzer webblocks-ui-manager.publish besitzt. Die echte Publish-Aktion verwendet ein Bestätigungsmodal. Der Dry-Run ist nicht destruktiv.

Erforderliche Einstellungen:

  • WEBBLOCKS_UI_MANAGER_ENABLED=true aktiviert das Plugin.
  • WEBBLOCKS_UI_MANAGER_CDN_BASE_PATH=cdn/webblocks-ui steuert das lokale/projekteigene statische Stammverzeichnis unter public/.
  • WEBBLOCKS_UI_MANAGER_CDN_BASE_URL ist optionales Anzeige-Metadatum für generierte öffentliche URLs.
  • webblocks-plugins.webblocks_ui_manager.expected_dist_files listet die erforderlichen Dist-Dateinamen auf.

Prüfungen der Publish-Validierung:

  • Release-Metadaten existieren und sind kein Entwurf
  • die Release-Version ist semver-ähnlich
  • der Release-CDN-Pfad entspricht dem konfigurierten Stammverzeichnis plus der Release-Version
  • die erwarteten Dist-Dateien sind vorhanden
  • die Quelldateien existieren innerhalb des Projektstamms und sind keine Symlink-Ausbrüche
  • die Artefakt-Zielpfade bleiben innerhalb des konfigurierten CDN-Stammverzeichnisses
  • gespeicherte Artefakt-Prüfsummen stimmen mit den aktuellen Quelldateien und Manifest-Metadaten überein
  • bereits veröffentlichte Dateien stimmen entweder mit den Prüfsummen überein und werden übersprungen, oder sie blockieren den Lauf
  • der Inhalt eines bestehenden Manifests muss mit dem vorbereiteten Manifest-Inhalt übereinstimmen

Publish-Läufe werden in webblocks_ui_manager_publish_runs mit Modus, Status, Zielpfaden, Vorgangsdetails und geheimnisfreien Fehlermeldungen gespeichert.