Plugin Update Checker: Technische Details
Technik des Plugin Update Checkers: Ablauf, welche Plugins geprüft werden, URL-Erkennung, Versionsvergleich, Cache, Ausgabe der Badges per Output Buffer, Sicherheit und Dateistruktur.
Plugin Update Checker: Technische Details
Kennzeichen
| Eigenschaft | Wert |
|---|---|
| Plugin-Name | Plugin Update Checker |
| Plugin-ID | net.michalski:update-check |
| Composer-Paket | mmd/osticket-plugin-update-check (Typ osticket-plugin) |
| Plugin-Klasse | UpdateCheckPlugin in class.UpdateCheckPlugin.php |
| Konfigurationsklasse | UpdateCheckConfig in config.php |
| Instanzen | Singleton, wird beim Aktivieren automatisch angelegt |
Ablauf
graph TD
A[Seitenaufruf im Admin Panel] --> B{Skript plugins.php?}
B -->|Nein| Z[Nichts tun]
B -->|Ja| C{AJAX-Anfrage?}
C -->|Ja| Z
C -->|Nein| D[Alle installierten Plugins durchgehen]
D --> E{url im plugin.php ist GitHub-Repo?}
E -->|Nein| F[Plugin überspringen]
E -->|Ja| G{Cache-Eintrag gültig?}
G -->|Ja| H[Gecachte Release-Daten]
G -->|Nein| I[GitHub API releases/latest]
I --> H
H --> J{Release neuer als installierte Version?}
J -->|Nein| F
J -->|Ja| K[Badge-Daten sammeln]
K --> L[CSS und JS inline in die Seite einfügen]
L --> M[Browser setzt Badge in die Versionsspalte]
bootstrap()läuft nur, wenn das aufgerufene Skriptplugins.phpheißt, also auf der Plugin-Liste des Admin Panels. Bei AJAX-Anfragen (X-Requested-With: XMLHttpRequest) passiert nichts.- Der
UpdateCheckPluginliest die Einstellungen aus der ersten aktiven Instanz. PluginUpdateCollectorgeht alle überPluginManager::allInstalled()bekannten Plugins durch und liest deren Metadaten perPluginManager::getInfoForPath().GitHubReleaseCheckerholt je Plugin mit GitHub-URL das neueste Release, zuerst aus dem Cache, sonst von GitHub.- Gibt es mindestens ein Update, startet das Plugin einen Output Buffer.
AssetInjectorfügt das CSS vor</head>und die Update-Daten samt JavaScript vor</body>ein. - Das JavaScript sucht die Zeilen der Plugin-Liste über die Checkbox
ids[](ihr Wert ist die Plugin-ID) und hängt das Badge an die dritte Spalte, die Versionsspalte.
Gibt es kein Update, bleibt die Seite unverändert und es wird nichts eingefügt.
Welche Plugins geprüft werden
Geprüft wird jedes installierte Plugin, dessen plugin.php im Feld url ein GitHub-Repository nennt. Das gilt für Plugins beliebiger Entwickler, auch für den Plugin Update Checker selbst.
- Erkannt werden
https://github.com/owner/repo,http://github.com/owner/repo,github.com/owner/repo, jeweils mit optionalem.gitund optionalem Schrägstrich am Ende. - URLs mit weiteren Pfadteilen (zum Beispiel
/tree/main) werden nicht erkannt. - Der Repository-Name darf keinen Punkt enthalten. Ein Repository wie
owner/my.pluginwird übersprungen. - Der Entwickler des Plugins muss ein GitHub Release veröffentlichen. Ein nackter Git-Tag genügt nicht, weil die Abfrage
releases/latestlautet. - Als installierte Version zählt die
versionaus den Plugin-Metadaten des geprüften Plugins.
Versionsvergleich
Vom Tag-Namen und von der installierten Version wird ein führendes v entfernt. Danach entscheidet PHP version_compare(): Ein Badge erscheint nur, wenn die Release-Version größer ist als die installierte. Gleiche oder ältere Versionen und leere Werte erzeugen kein Badge. Pre-Release-Suffixe werden nicht eigens behandelt, sie folgen den Regeln von version_compare().
Cache
| Fall | Dauer | Inhalt |
|---|---|---|
| Erfolgreiche Abfrage | Einstellung Cache Duration (hours), Standard 6 Stunden | tag_name und html_url des Releases |
| Fehler oder kein Release | fest 1 Stunde | Marker none |
- Ort: Ordner
osticket-update-checkim PHP-Temp-Verzeichnis (sys_get_temp_dir()), angelegt mit den Rechten0755. - Pro Repository eine JSON-Datei
github_release_<owner>_<repo>.jsonmit den Feldernexpires_atunddata. Der Token steht nicht im Cache. - Abgelaufene oder beschädigte Dateien werden beim Lesen gelöscht. Ist der Ordner nicht beschreibbar, arbeitet das Plugin ohne Cache weiter.
- Als Fehler zählen HTTP-Antworten außer 200, fehlendes cURL, Verbindungsfehler, ungültiges JSON und ein Release ohne Tag-Namen.
Anfragen an GitHub
| Eigenschaft | Wert |
|---|---|
| URL | https://api.github.com/repos/<owner>/<repo>/releases/latest |
| Methode | GET, über cURL |
| Header | Accept: application/vnd.github.v3+json, User-Agent: osTicket-Plugin-UpdateChecker/..., optional Authorization: Bearer <Token> |
| Timeout | 5 Sekunden Gesamtdauer und 5 Sekunden für den Verbindungsaufbau |
| Weiterleitungen | bis zu 3 |
| TLS | Zertifikat und Hostname werden geprüft |
Die Abfragen laufen nacheinander während des Seitenaufbaus der Plugin-Liste. Bei kaltem Cache und nicht erreichbarem GitHub kann sich die Ladezeit je geprüftem Plugin um bis zu 5 Sekunden verlängern. Danach merkt sich das Plugin den Fehler für eine Stunde. Welche Daten dabei an GitHub gehen, steht unter Datenschutz.
Ausgabe der Badges
Das CSS und das JavaScript des Plugins liegen im Ordner assets/ und werden inline in die Seite geschrieben, nicht als externe Dateien eingebunden. So braucht es keine Webserver-Anpassung. Die Update-Daten stehen als JSON in window.__pluginUpdates.
Das Badge ist ein Link mit dem Text der neuen Version. Er führt auf die Release-Seite bei GitHub, öffnet in einem neuen Tab (rel="noopener noreferrer") und hat den Tooltip Update available: v<Version>. Das Skript registriert sich außerdem auf pjax:end, damit die Badges nach einer PJAX-Navigation erneut gesetzt werden.
Sicherheit
- Die JSON-Daten werden mit
JSON_HEX_TAGundJSON_HEX_APOSkodiert, damit sie kein Script-Tag beenden können. - Das JavaScript setzt ein Badge nur, wenn die Release-URL mit
http:oderhttps:beginnt, und schreibt die Werte pertextContent. - Ein Marker
data-plugin="update-check"verhindert eine doppelte Einfügung. - Wirft die Einfügung einen Fehler, gibt der Output-Buffer-Callback die Seite unverändert zurück und schreibt
[UpdateCheck] Asset injection failedins PHP-Fehlerprotokoll. - Das Plugin legt keine eigenen Datenbanktabellen an und ändert weder das Datenbankschema noch osTicket-Dateien. In der Datenbank steht nur die Plugin-Instanz mit der Konfiguration (einschließlich eines eingetragenen Tokens), die osTicket verwaltet. Dazu kommen die Cache-Dateien im Temp-Verzeichnis.
Dateistruktur
include/plugins/update-check/
+-- plugin.php Plugin-Metadaten
+-- class.UpdateCheckPlugin.php Plugin-Klasse
+-- config.php Konfigurationsformular
+-- src/
| +-- AssetInjector.php Einfügen von CSS/JS in den Output Buffer
| +-- FileCache.php Dateibasierter Cache mit Ablaufzeit
| +-- GitHubReleaseChecker.php URL-Erkennung, GitHub-Abfrage, Versionsvergleich
| +-- PluginUpdateCollector.php Durchläuft die installierten Plugins
+-- assets/
| +-- update-badges.css Badge-Stil
| +-- update-badges.js Badges in die Tabelle setzen
+-- vendor/ Composer-Autoloader (nach composer install)