Technische Referenz

Widget Storm v4.0.0 — Systemdokumentation

1. Systemübersicht

Widget Storm ist eine modulare Widget-Plattform für das Web, aktiv seit 2008. Widgets sind eigenständige Webkomponenten aus drei Schichten (PHP, CSS, JavaScript), die verschlüsselt auf dem Server gespeichert und über HTTP-Endpunkte ausgeliefert werden.

EigenschaftWert
Version4.0.0
SprachePHP 8.3
DatenbankMySQL / MariaDB
VerschlüsselungRIJNDAEL-256 (Legacy), AES-256-CBC (Modern)
Standard-AutorWidgetStormSystem
AusführungskontexteLokal (wgclient.php), Remote (wgcall.php), Client-seitig (wghandler.php)
Für eine geführte Einführung mit interaktiven Beispielen siehe das Tutorial.

2. Widget-Struktur

Jedes Widget besteht aus exakt drei Dateien. Alle drei Schichten haben Zugriff auf die gleichen Parameter ($wgparams) und die Instanz-ID ($wgguid).

SchichtDateiContent-TypeBeschreibung
PHPwidget_name.phptext/htmlServerseitige Logik und HTML-Ausgabe
CSSwidget_name.csstext/cssStyling mit optionaler PHP-Bridge
JSwidget_name.jstext/javascriptClient-seitige Interaktion

Verfügbare Variablen im Widget-Code

VariableTypBeschreibung
$wgparamsobject|array|stringWidget-Parameter (geparst aus JSON, Semikolon-Liste oder String)
$widgetparamsobject|array|stringAlias für $wgparams
$wgguidstringEindeutige Instanz-ID für CSS/JS-Scoping

PHP-Schicht — Beispiel

<?php
if(isset($widgetparams->uid)) $wgguid = $widgetparams->uid;
else $wgguid = "";
if(isset($wgparams)){
    $text = isset($wgparams->text) ? $wgparams->text : "Standard-Text";
    ?>
    <div id="mein_widget<?= $wgguid;?>" class="mein-widget">
        <p><?= $text;?></p>
    </div>
    <?php
}
?>

Ausgabemodi

ModusAusgabe
phpNur HTML (evalBei Widget-Storm führt eval() ausschließlich Widget-Code aus, der von authentifizierten Autoren in der Datenbank hinterlegt wurde — nicht von Benutzereingaben. Es ist die technische Grundlage der PHP-in-CSS Bridge und der dynamischen Widget-Komposition. Kein User-Input erreicht eval().-Ergebnis)
cssNur CSS (evalDie CSS-Schicht wird durch eval() gerendert, um die PHP-in-CSS Bridge zu aktivieren. Der Code stammt ausschließlich aus der Datenbank — erstellt von authentifizierten Widget-Autoren. Dynamische Selektoren und instanzspezifisches Styling wären ohne diesen Mechanismus nicht möglich.-Ergebnis)
jsNur JavaScript (evalAuch die JS-Schicht nutzt eval() für eingebettete PHP-Variablen (UID-Scoping, Parameter). Wie bei allen Widget-Schichten: der ausgeführte Code ist autorengeprüft und datenbankgespeichert, nicht nutzergeneriert.-Ergebnis)
(leer)<style>CSS</style> PHP <script>JS</script>

3. Parameter-System

Parameter werden über wgparams an Widgets übergeben. Das System unterstützt drei Formate:

JSON (empfohlen)

{"text":"Hallo Welt","color":"#ff0000","items":[1,2,3]}

Wird zu einem stdClass-Objekt geparst. Zugriff via $wgparams->text.

Semikolon-getrennt

Wert1;Wert2;Wert3

Wird zu einem Array geparst. Zugriff via $wgparams[0], $wgparams[1], etc.

Einfacher String

Ein beliebiger Text

Wird unverändert als String durchgereicht.

URL-Encoding für HTTP-Requests

wgparams={"text":"Hallo","uid":"abc123"}

// In PHP für URL-Parameter:
$packurl = http_build_query(['wgparams' => $paramsArray]);

4. PHP-in-CSS/JS Bridge

CSS- und JS-Dateien können eingebetteten PHP-Code enthalten. Da PHP-Tags in CSS/JS syntaktisch ungültig sind, werden sie in Kommentare verpackt. Das System konvertiert diese automatisch vor der Ausführung.

Konvertierungsregeln

Im QuellcodeWird zu
/*<?php<?php
/*<?=<?=
?>*/?>

CSS-Beispiel

/*<?php
if(isset($wgparams->uid)) $wgguid = $wgparams->uid;
else $wgguid = "";
?>*/
div#mein_widget/*<?= $wgguid;?>*/ {
    background: rgba(170,210,210,0.08);
    border: 1px solid rgba(170,210,210,0.2);
    padding: 1em;
    border-radius: 0.4em;
}

JS-Beispiel

/*<?php
if(isset($wgparams->uid)) $wgguid = $wgparams->uid;
else $wgguid = "";
?>*/
jQuery(document).ready(function(){
    jQuery("#mein_widget/*<?= $wgguid;?>*/").on("click", function(){
        jQuery(this).toggleClass("active");
    });
});
Die PHP-Bridge ermöglicht instanzspezifische CSS-Selektoren und JS-Handler, sodass mehrere Instanzen desselben Widgets auf einer Seite koexistieren können.

5. Verschachtelung & Marker

Widgets können andere Widgets laden. Dies geschieht über Marker im PHP-Code, die vom Server rekursiv aufgelöst werden.

Marker-Syntax

##wgstart##widgetname::autor::parameter##wgend##
SegmentBeschreibung
widgetnameName des einzubettenden Widgets
autorAutor des Widgets
parameterParameter als JSON oder Semikolon-Liste

Auflösungsprozess

  1. Server findet alle ##wgstart##...##wgend## Marker im PHP-Code
  2. Extrahiert Name, Autor und Parameter aus dem Marker
  3. Löst das verschachtelte Widget rekursiv auf
  4. CSS und JS des verschachtelten Widgets werden an das Eltern-Widget angehängt
  5. PHP wird Base64-kodiert und über intern_script_wall() ausgeführt

UID-Scoping & Platzhalter

PlatzhalterErsetzungVerwendung
##self##widgetname + md5($wgguid)Eindeutiger Selektor pro Instanz
##wgself##widgetname + md5($wgguid)Alias für ##self##
##selfreplace####self##Escape: literales ##self## im Output

6. Verfügbarkeitsstufen

StufeZugriffBilling
openAlle registrierten NutzerKostenlos
authenticatedAutor + Nutzer mit expliziter BerechtigungOptional
paymentAutor + Nutzer mit aktivem BillingErforderlich

Entwickler legen die Verfügbarkeit beim Upload fest (Parameter wgrmode). Die Stufe bestimmt, wer das Widget über seinen wgclient abrufen kann — und ob eine Abrechnung erforderlich ist.

Zugriffskontrolle

1. Widget.availability == 'open'       → Zugriff gewährt
2. Widget.author == RequestUser        → Zugriff gewährt (Autor)
3. Berechtigungsprüfung              → Prüfung in interner Berechtigungstabelle
   - Globale Berechtigung              → Gilt für alle Nutzer
   - Spezifische Berechtigung          → Gilt für einzelne Nutzer

Sicherheit auf Widget-Ebene

Widgets können eigene Sicherheitsmechanismen mitbringen — unabhängig vom Hostsystem. Das Widget wg_demo_todo demonstriert dieses Prinzip: AES-256-verschlüsselte Persistenz, schlüsselbasierte Authentifizierung mit Brute-Force-Schutz und automatische Preflight-Checks für Abhängigkeiten und Berechtigungen. Weitere Details finden Sie auf der Widget-Übersicht.

7. HTTP-Endpunkte

wgclient.php — Widget-Auslieferung (lokal)

Dient als HTTP-Endpunkt und als PHP-Include für serverseitige Einbindung.

ParameterPflichtBeschreibung
wgnameJaWidget-Name
wgauthorNeinWidget-Autor (Standard: WidgetStormSystem)
wgmodeNeinAusgabemodus: php, css, js oder leer (alle)
wgparamsNeinWidget-Parameter (JSON, Semikolon-Liste oder String)
wgguidNeinInstanz-ID für Scoping

wgcall.php — Remote Widget-Auslieferung

Endpunkt für externe Server. Erfordert Authentifizierung und verschlüsselt die Antwort.

ParameterPflichtBeschreibung
wgnameJaWidget-Name (alphanumerisch + Unterstrich + Bindestrich)
wgauthorJaWidget-Autor
wgmodeJaErlaubte Werte: php, css, js, go, c, md
requestuserJaBenutzername
requestkeyJaAuthentifizierungsschlüssel (MD5-Hash)
wgparamsNeinWidget-Parameter
wgguidNeinInstanz-ID
wgfirstNeintrue = keine Verschachtelungsauflösung

wgregistration.php — Widget-Upload

Endpunkt zum Hochladen neuer oder aktualisierter Widgets.

ParameterBeschreibung
wgrnameWidget-Name
wgrparamSchicht: php, css, js
wgrcodeVerschlüsselter Widget-Code
wgrmodeVerfügbarkeit: authenticated, open, payment
wgrrequestuserBenutzername
wgrrequestkeyAuthentifizierungsschlüssel
Autoren-Isolation: Uploads sind an den authentifizierten Nutzer gebunden. Es können nur eigene Widgets erstellt oder aktualisiert werden — Widgets anderer Autoren sind vor Überschreibung geschützt. Beim Upload aus wgbuilds/ (Batch-Modus) werden entsprechend nur Widgets verarbeitet, die dem eigenen Autoren-Konto zugeordnet sind.

wgclientcreator.php — Client-Download

Generiert eine personalisierte wgclient.php mit eingebetteten Zugangsdaten. Erfordert aktive Session (Login über Station). Bei jedem Download wird ein neuer requestkey generiert (Key-Rotation via md5(username + uniqid())).

wghandlercreator.php — Handler-Download

Generiert eine portable wghandler.php Klasse mit eingebetteter RIJNDAEL-256 Implementierung (pure PHP via phpseclib3, kompatibel mit PHP 8+), lokalem Widget-Caching und Unterstützung für verschachtelte Widgets.

8. Widget-Einbindung

Lokale Einbindung (gleicher Server)

<!-- CSS im <head> -->
<link rel="stylesheet"
    href="wgclient.php?wgname=basic&wgauthor=WidgetStormSystem&wgmode=css&wgparams=..."
    type="text/css">

<!-- JavaScript vor </body> -->
<script src="wgclient.php?wgname=basic&wgauthor=WidgetStormSystem&wgmode=js&wgparams=..."></script>

<!-- PHP im <body> -->
<?php
require_once 'wgclient.php';
$wg->get('basic', 'WidgetStormSystem', $params, 'php');
?>

Remote-Einbindung (externer Server)

<?php
// wgclient.php und wghandler.php auf eigenem Server platzieren
require_once 'wgclient.php';

// Zugangsdaten sind in wgclient.php eingebettet
$wg->get('basic', 'WidgetStormSystem', $params, 'php');
?>

Ausführungsmodi (wgexecutionmode)

Der Entwickler steuert über den wgexecutionmode, ob ein Widget lokal aus dem CodeVault gerendert wird oder live vom Widget-Storm-Server abgerufen werden soll. Der Standard-Modus nutzt den lokalen Cache — das bedeutet keine Netzwerk-Latenz und maximale Ladegeschwindigkeit.

ModusVerhaltenEinsatz
(Standard)Lokaler CodeVault — Widgets aus dem Cache ladenProduktion: schnellste Auslieferung, keine Server-Abhängigkeit
liveRemote Fetch — Widget live vom Server laden und ausführenEntwicklung: immer aktuelle Version, keine lokale Datei nötig
uploadwidgetsBatch-Upload — lokale Widgets in wgbuilds/ hochladenDeployment: alle eigenen Widgets aus dem lokalen Verzeichnis synchronisieren
Rendering-Kontrolle: Der Modus bestimmt woher der Widget-Code kommt — das Rendering selbst erfolgt immer serverseitig via PHP (evaleval() führt den Widget-Code im Server-Kontext aus. Der Code stammt entweder aus dem lokalen CodeVault (Dateisystem) oder aus der Datenbank — beides autorengeprüfte Quellen, keine Nutzereingaben.). Dadurch erhält jede Widget-Instanz ihre eigenen Parameter und CSS-Selektoren.

9. Verschlüsselung

Die Kommunikation zwischen Client und Server ist verschlüsselt. Das System unterstützt zwei Verschlüsselungsversionen pro Benutzer: RIJNDAEL-256 (das ursprüngliche Verfahren seit 2008) und AES-256-CBC (der moderne Standard für neue Nutzer). Beide koexistieren über einen zentralen EncryptionNegotiator, der automatisch die passende Version pro Benutzer wählt.

VersionAlgorithmusModusStatus
v1_rijndaelRIJNDAEL-256ECBLegacy (seit 2008)
v2_aesAES-256-CBCCBC mit zufälligem IVStandard für neue Nutzer

Beide Richtungen (Server → Client und Client → Server) sind auf Anwendungsebene verschlüsselt. Jeder Nutzer hat einen individuellen Schlüssel, der bei jedem Client-Download rotiert wird.

RIJNDAEL-256 ≠ AES-256. AES verwendet 128-Bit-Blöcke (von NIST standardisiert), RIJNDAEL-256 verwendet 256-Bit-Blöcke (verwandter Algorithmus, aber nicht Teil des AES-Standards).
Historischer Kontext: RIJNDAEL-256 wurde 2008 gewählt, als PHP’s mcrypt-Extension der Standard-Weg für Kryptografie war und openssl_encrypt() noch nicht verfügbar war. Die Entscheidung war dem damaligen Stand der Technik entsprechend. Seit der Modernisierung auf PHP 8.3 wird phpseclib3 als Drop-in-Ersatz für die entfernte mcrypt-Extension verwendet. Ausführliche Hintergründe dazu finden Sie in den FAQ.

10. Rate Limiting

EndpunktLimitFensterHTTP-Status bei Überschreitung
wgcall.php120 Anfragen60 Sekunden429 Too Many Requests
wgregistration.php30 Uploads60 Sekunden429 Too Many Requests

Tracking erfolgt pro IP-Adresse und Endpunkt. Zustandsdateien in /tmp/ws-ratelimit/.

11. CodeVault

Der CodeVault ist das Herzstück der Widget-Auslieferung. Er speichert Widget-Code als lokale Dateien auf dem Client-Server — das bedeutet direkten Dateisystem-Zugriff statt Netzwerk-Roundtrips. Widgets werden so schnell geladen wie jede andere lokale PHP-Datei, ohne Abhängigkeit vom zentralen Widget-Storm-Server.

Zweck & Vorteile

EigenschaftBeschreibung
GeschwindigkeitLokale Datei-Reads statt HTTP-Anfragen — Ladezeiten im Mikrosekundenbereich
UnabhängigkeitWidgets funktionieren auch wenn der Widget-Storm-Server nicht erreichbar ist
RedundanzDoppelte Speicherung: Datenbank (Server) + Dateisystem (Client)
Autoren-IsolationJeder Autor hat sein eigenes Unterverzeichnis — kein Überschreiben fremder Widgets möglich

Verzeichnisstruktur

wgbuilds/
  ├─ {Autor}/
  │   ├─ {widget_name}.php
  │   ├─ {widget_name}.css
  │   └─ {widget_name}.js
  └─ WidgetStormSystem/
      ├─ basic.php
      ├─ basic.css
      ├─ basic.js
      ├─ wg_nav.php
      └─ ...

Die Verzeichnisstruktur ist nach Autoren organisiert. Beim Batch-Upload (uploadwidgets-Modus) scannt der wghandler das wgbuilds/ Verzeichnis und lädt geänderte Dateien automatisch auf den Server hoch — dabei werden nur eigene Widgets verarbeitet. Widgets anderer Autoren bleiben unberührt.

Rendering aus dem CodeVault

Im Standard-Modus liest der wgclient den Widget-Code direkt aus wgbuilds/ und führt ihn lokal aus (evalDer CodeVault-Code wird via eval() im Server-Kontext ausgeführt. Die Dateien stammen aus dem authentifizierten Download oder eigenem Upload — sie sind identisch mit dem Datenbank-Original. Kein externer Input fließt in die Ausführung ein.). Der Live-Modus umgeht den CodeVault und fragt den Widget-Storm-Server direkt ab — nützlich während der Entwicklung, aber langsamer als der lokale Cache.

Design-Philosophie: Der CodeVault ist bewusst als erstes Speichermedium für die Auslieferung konzipiert — nicht als Fallback. Lokale Dateien sind die schnellstmögliche Art, Widgets auszuliefern, und machen jede Website mit Widget-Storm-Integration resilient gegen temporäre Server-Ausfälle.