Zum Inhalt springen

DotBridge-Beispiel

Live-Demo öffnen unter /documentation/examples/run/bridge (auch verfügbar unter /documentation/examples/run/forms3).

Einführung

Dieses Beispiel ist die Live-Seite Examples:Forms@index3! / @submit3!. Template-Tags rufen PHP über einen verschlüsselten AJAX-POST an die aktuelle Seiten-URL auf. Eingaben können gefiltert, verschlüsselt, mit einem Ratenlimit versehen und an eine bestimmte URL gebunden werden.

Voraussetzungen

Beginnen Sie mit dem Beispiel zu benannten Formularen, sodass das Modul Examples und der Controller Forms bereits vorhanden sind.

Die View erstellen

Die Live-Demo verwendet eine eigenständige View unter /app/modules/Examples/views/bridge.view.php. Die Datei ist ein vollständiges HTML-Dokument.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>{{ var: $title }} — DotApp PHP Framework 2.0</title>
  <link rel="stylesheet" href="/assets/modules/Examples/css/examples.css" />
</head>
<body class="ex-body">
  <header class="ex-top">
    <a href="{{ var: $docsUrl }}">Documentation</a>
    <span>DotBridge</span>
  </header>
  <main class="ex-main">
    <h1>DotBridge</h1>
    <p class="ex-lead">Each button calls PHP over the current page URL.</p>
    <form method="post" class="ex-card" data-dotapp-nojs>
      <label for="email">Email</label>
      <input type="text" id="email" {{ dotbridge:input="email.address(email, 6, email_ok, email_bad)" }} placeholder="Enter your email" />
      <label for="category">Category</label>
      <select id="category" {{ dotbridge:input="category" }}>
        <option value="" disabled selected>Select a category</option>
        <option value="{{ enc(additionalKey): "AdminVal" }}">Admin</option>
        <option value="{{ enc(additionalKey): "EditorVal" }}">Editor</option>
        <option value="{{ enc(additionalKey): "OtherVal" }}">Other</option>
      </select>
      <div class="ex-bridge-actions">
        <div class="ex-btn" {{ dotbridge:on(click)="example.showEmailCategory(email.address, category)" oneTimeUse }}>Submit only once</div>
        <div class="ex-btn" {{ dotbridge:on(click)="example.showEmailCategory2(email.address, category)" regenerateId rateLimit(60,2) rateLimit(3600,5) url(/documentation/examples/run/forms3/) }}>Submit 2× per minute</div>
        <div class="ex-btn" {{ dotbridge:on(click)="example.showEmailCategory3(email.address, category)" regenerateId }}>Submit no limit</div>
      </div>
    </form>
    <div class="output" id="output1">Submit with the first button to see the result</div>
    <div class="output" id="output2">Submit with the second button to see the result</div>
    <div class="output" id="output3">Submit with the third button to see the result</div>
  </main>
  <script src="/assets/dotapp/dotapp.js"></script>
  <script src="/assets/modules/Examples/js/bridge.js"></script>
</body>
</html>

Styles hinzufügen

Das gemeinsame Erscheinungsbild der Beispiele liegt unter /app/modules/Examples/assets/css/examples.css und wird als /assets/modules/Examples/css/examples.css ausgeliefert.

Das Layout erstellen

setView('bridge') rendert das vollständige HTML-Dokument. Module können Views auch mit {{ layout:name }} umschließen. Diese Demo hält die View in sich abgeschlossen.

DotBridge-Eingaben

Markieren Sie Felder mit {{ dotbridge:input="name" }} oder der Kurzform dotbridge="name". Verschachtelte Namen wie email.address kommen in PHP als $request->data(true)['data']['email.address'] an.

Eingebaute Filter umfassen email, url, phone, password, date, time, creditcard, username und ipv4. Weitere registrieren Sie mit Bridge::addFilter($name, $callback).

DotBridge-Filter

Das E-Mail-Feld verwendet email.address(email, 6, email_ok, email_bad): den Filter email, eine Mindestlänge von 6 und optionale Erfolgs-/Fehler- Callbacks. Kategorieoptionen werden im Template mit {{ enc(additionalKey): "AdminVal" }} verschlüsselt und in PHP mit demselben Zusatzschlüssel entschlüsselt.

DotBridge-Ereignisse

Binden Sie einen Klick (oder ein anderes Ereignis) mit {{ dotbridge:on(click)="functionName(arg1, arg2)" }}. Modifikatoren am selben Tag steuern Wiederverwendung und Grenzen:

  • oneTimeUse — der Schlüssel wird nach einem erfolgreichen Aufruf verbraucht.
  • regenerateId — nach dem Aufruf wird eine neue ID ausgegeben.
  • rateLimit(seconds,count) — Sie können mehrere Zeitfenster stapeln, z. B. rateLimit(60,2) rateLimit(3600,5).
  • url(/path) — POST-Ziel für diesen Aufruf. Eine ungültige gebundene URL liefert HTTP 403 mit error_code 6.

DotBridge-JavaScript-Funktionen

Koppeln Sie jeden Template-Funktionsnamen mit $dotapp().bridge(name, event). Hooks: before, onValueError, after und onResponseCode. Warten Sie auf das Ereignis dotapp, falls die Bibliothek noch geladen wird.

Routen konfigurieren

Registrieren Sie das GET der Seite und binden Sie jede Bridge-Funktion an dieselben URLs in initialize($dotApp):

$bridgePages = array_merge($pair($p . '/forms3'), $pair($p . '/bridge'));
Router::get($bridgePages, 'Examples:Forms@index3!', Router::STATIC_ROUTE);
foreach (['example.showEmailCategory', 'example.showEmailCategory2', 'example.showEmailCategory3'] as $fn) {
    Router::bridge($bridgePages, $fn, 'Examples:Forms@submit3!', Router::STATIC_ROUTE);
}

Router::bridge($urls, $functionName, $handler, Router::STATIC_ROUTE) beschränkt den Handler auf diese Seiten-URLs. Closures verwenden Bridge::listen() mit derselben Argumentreihenfolge.

Den Controller aktualisieren

Methoden sind public static und nehmen $request entgegen. Die GET- Aktion rendert die View. Die Bridge-Aktion liest die Nutzlast und gibt eine Zeichenkette (oder ein Array) zurück, die zum JSON-body wird.

public static function index3($request)
{
    return self::view('bridge', [
        'title' => 'DotBridge demo',
        'docsUrl' => '/documentation/examples/dotbridge',
    ]);
}

public static function submit3($request)
{
    $payload = $request->data(true)['data'] ?? [];
    $email = (string) ($payload['email.address'] ?? '');
    $category = Crypto::decrypt((string) ($payload['category'] ?? ''), 'additionalKey');
    if ($category === false) {
        $category = '(invalid category)';
    }
    return 'This is reply from submit3() function. Email: ' . $email . ', category: ' . $category;
}

Eine fehlgeschlagene Entschlüsselung gibt false zurück — vergleichen Sie mit === false.

JavaScript implementieren

Live-Datei: /app/modules/Examples/assets/js/bridge.js. Die Client- API ist $dotapp.

(function () {
  var runMe = function ($dotapp) {
    function before(selector) {
      var categoryInput = $dotapp('[dotbridge-input="category"]').val();
      if (categoryInput === null || categoryInput === "") {
        alert("Select a category.");
        return $dotapp().halt();
      }
      $dotapp(selector).html("Loading...").removeClass("error").removeClass("success").addClass("loading");
    }

    function after(selector, body) {
      var text = "";
      if (typeof body === "string") text = body;
      else if (body && body.body) text = body.body;
      else if (body) text = String(body);
      if (text) {
        $dotapp(selector).html(text).removeClass("error").removeClass("loading").addClass("success");
      }
    }

    function onResponse(selector, data) {
      var reply = $dotapp().parseReply(data);
      var text = (reply && reply.status_txt) ? reply.status_txt : "Request failed.";
      $dotapp(selector).html(text).addClass("error").removeClass("loading").removeClass("success");
    }

    $dotapp()
      .bridge("example.showEmailCategory", "click")
      .before(function () { return before("#output1"); })
      .onValueError(function (inputname) {
        if (inputname == "email.address") alert("Enter a valid email address.");
      })
      .after(function (body) { after("#output1", body); })
      .onResponseCode(function (status, text) { onResponse("#output1", text); }, 429);
  };
  if (window.$dotapp) runMe(window.$dotapp);
  else window.addEventListener("dotapp", function () { runMe(window.$dotapp); }, { once: true });
})();

Wiederholen Sie dieselbe .bridge()-Kette für example.showEmailCategory2 und example.showEmailCategory3 mit ihren Ausgabe-Selektoren.

Fehlercodes

Erfolg ist HTTP 200 mit JSON { status: 1, body: <your return> } und dem Header X-Answered-By: dotbridge.

  • HTTP 400, error_code 1: CRC-Prüfung fehlgeschlagen.
  • HTTP 403, error_code 2: Bridge-Schlüssel stimmt nicht überein.
  • HTTP 404, error_code 3: Funktion nicht registriert oder nicht aufrufbar.
  • HTTP 429, error_code 4: Ratenlimit, ungültige ID oder fehlender gültiger Schlüssel.
  • HTTP 403, error_code 5: CSRF-Referer stimmt nicht überein.
  • HTTP 403, error_code 6: ungültige dotbridge-url.

Live-Demo

/documentation/examples/run/bridge und /documentation/examples/run/forms3 rendern dieselbe Seite.