Prejsť na obsah

DotBridge

DotBridge je kľúčová súčasť frameworku DotApp, ktorá zabezpečuje bezpečnú a efektívnu komunikáciu medzi serverovým PHP a klientským JavaScriptom cez AJAX požiadavky. Umožňuje vám definovať PHP funkcie volateľné z frontendu, spravovať vstupy a chrániť komunikáciu pred neoprávneným prístupom alebo zneužitím. DotBridge je navrhnutý tak, aby poskytoval flexibilitu, bezpečnosť a jednoduchú integráciu dynamických funkcií do webových aplikácií.

1.1 Čo je DotBridge?

DotBridge vo frameworku DotApp je trieda Dotsystems\App\Parts\Bridge, ktorá slúži ako most medzi back-endovou PHP logikou a front-endovými akciami v JavaScripte. Umožňuje volať PHP funkcie z HTML prvkov (napr. tlačidlá, vstupy formulára) cez šifrované AJAX požiadavky. Volania Bridge posielajú POST na URL aktuálnej stránky. Primárnou úlohou je zjednodušiť komunikáciu medzi klientom a serverom a zároveň zaručiť, že je overená, šifrovaná a chránená pred útokmi, ako sú CSRF alebo opakovanie požiadavky.

Funkcie Bridge sa v module registrujú cez Bridge::listen() alebo Router::bridge() (reťazec kontroléra).

1.2 Kľúčové vlastnosti

DotBridge ponúka širokú škálu funkcií, ktoré zjednodušujú vývoj bezpečných a dynamických aplikácií:

  • Bezpečná komunikácia: Na ochranu požiadaviek používa šifrovanie dát, overenie kľúča a kontroly CRC.
  • Volanie PHP funkcií: Definujte PHP funkcie volateľné z JavaScriptu s podporou callbackov before a after.
  • Validačné filtre: Validácia vstupov v reálnom čase (napr. e-mail, URL, heslo) s vizuálnou spätnou väzbou na strane klienta.
  • Rate limiting: Možnosť nastaviť limity požiadaviek za čas (rateLimit(seconds,clicks)).
  • Jednorazové kľúče: Podpora oneTimeUse a regenerateId pre vyššiu bezpečnosť.
  • Flexibilita: Podporuje rôzne udalosti (napr. click, keyup) a dynamické vstupy z HTML.
  • Reťazenie: Reťazenie metód pre prehľadnejší kód na strane PHP aj JavaScriptu.

1.3 Základné princípy fungovania

DotBridge spracúva komunikáciu medzi klientom a serverom v týchto krokoch:

  1. Vygeneruje jedinečný kľúč relácie a na strane servera zaregistruje PHP funkcie cez Bridge::listen() alebo Router::bridge().
  2. V HTML sa definujú udalosti (napr. {{ dotbridge:on(click)="fnName" }}) a vstupy (napr. {{ dotbridge:input="name" }} alebo skrátene dotbridge="name") a prepoja sa s PHP funkciami.
  3. Pri spustení udalosti (napr. kliknutí) sa na viazanú URL stránky (predvolene: aktuálna stránka) odošle AJAX POST so šifrovanými dátami.
  4. Server overí kľúč, dešifruje dáta, skontroluje limity požiadaviek a vykoná požadovanú PHP funkciu.
  5. Výsledok sa vráti ako JSON odpoveď, ktorú môže JavaScript ďalej spracovať.

Komunikácia je chránená šifrovaním dát, overením kľúča a limitmi, ktoré bránia zneužitiu alebo neoprávnenému prístupu.

Príklad základného použitia:

<button {{ dotbridge:on(click)="sayHello" }}>Click me</button>
        

use Dotsystems\App\Parts\Bridge;
use Dotsystems\App\Parts\Router;

$urls = ['/hello', '/hello/'];
Bridge::listen($urls, "sayHello", function ($request) {
    return ["status" => 1, "message" => "Hello from the server!"];
}, Router::STATIC_ROUTE);
        

Po kliknutí na tlačidlo sa zavolá PHP funkcia sayHello a vráti JSON odpoveď so správou "Hello from the server!".

2. Začíname

Táto kapitola vás prevedie základmi práce s DotBridge vo frameworku DotApp – od inicializácie cez definovanie prvej funkcie, pridanie front-endovej udalosti až po spracovanie odpovede v JavaScripte.

Handlery registrujte cez Router::bridge(['/path','/path/'], 'fnName', 'Examples:Forms@submit3!', Router::STATIC_ROUTE) alebo Bridge::listen($urls, 'fnName', $callback, Router::STATIC_ROUTE) v initialize() modulu.

2.1 Inicializácia DotBridge

DotBridge sa spúšťa spolu s aplikáciou. Jedinečný kľúč relácie sa ukladá v _bridge.key. Handlery stránky registrujte z modulu cez Bridge::listen() alebo Router::bridge(). AJAX požiadavky Bridge posielajú POST na URL aktuálnej stránky; modifikátor šablóny url(/path) viaže volanie na inú URL (neplatná viazaná URL: HTTP 403, error_code 6). Na stránky, ktoré používajú udalosti Bridge, vložte /assets/dotapp/dotapp.js.

2.2 Definovanie PHP funkcie

Na strane servera zaregistrujte funkciu cez Bridge::listen(). Callback dostane objekt $request; polia payloadu sú v $request->data(true)['data']. Vráťte reťazec alebo pole (napr. ['ok' => true, 'message' => '...']) — framework ho zabalí ako JSON { status: 1, body: <your return> }. Handlery umiestnite do initialize() modulu alebo do metódy modulového kontroléra.

Príklad:

use Dotsystems\App\Parts\Bridge;
use Dotsystems\App\Parts\Router;

$urls = ['/contact', '/contact/'];
Bridge::listen($urls, "sendMessage", function ($request) {
    $data = $request->data(true)['data'];
    $message = $data["user.message"] ?? "No message";
    return ["ok" => true, "message" => "Message received: " . $message];
}, Router::STATIC_ROUTE);
    

Funkcia sendMessage je teraz pripravená na volanie z frontendu a vráti JSON odpoveď s prijatou správou.

2.3 Pridanie front-endovej udalosti

V HTML použite atribút {{ dotbridge:on(event)="functionName(params)" }} na prepojenie udalosti (napr. click, keyup) s PHP funkciou. Vstupy definujte cez {{ dotbridge:input="name" }} alebo skráteným zápisom dotbridge="name" na bežných HTML prvkoch. Správanie riadte modifikátormi, ako sú rateLimit(60,5) alebo oneTimeUse.

Príklad:

<input type="text" {{ dotbridge:input="user.message" }}>
<button {{ dotbridge:on(click)="sendMessage(user.message)" rateLimit(60,5) }}>Send</button>
    

Po kliknutí na tlačidlo sa hodnota zo vstupu user.message odošle funkcii sendMessage s limitom 5 požiadaviek za 60 sekúnd.

2.4 Spracovanie odpovede v JavaScripte

Na strane klienta vložte /assets/dotapp/dotapp.js a cez $dotapp().bridge() definujte callbacky before a after. Callback after dostane body (návratovú hodnotu z PHP). Na čítanie obálok chýb frameworku použite onResponseCode s $dotapp().parseReply() (status_txt pri HTTP 400/403/429).

Príklad:

$dotapp().bridge("sendMessage", "click")
    .before(function () {
        $dotapp("button").html("Sending...");
    })
    .after(function (body) {
        $dotapp("button").html("Done!");
        alert(body.message || body);
    })
    .onResponseCode(function (status, text) {
        var reply = $dotapp().parseReply(text);
        alert((reply && reply.status_txt) ? reply.status_txt : "Failed");
    }, 429);
    

Pred odoslaním sa text tlačidla zmení na "Sending..." a po prijatí odpovede sa zobrazí správa z PHP funkcie. Prekročenie limitu a ďalšie chyby frameworku sa spracúvajú cez onResponseCode a parseReply.

3. Pokročilé použitie

Táto kapitola pokrýva pokročilé funkcie DotBridge, ako sú validačné filtre, rate limiting, reťazenie metód a práca s dynamickými dátami. Tieto nástroje umožňujú vytvárať robustnejšie a bezpečnejšie aplikácie s väčšou kontrolou nad správaním.

3.1 Validačné filtre

DotBridge poskytuje vstavané validačné filtre na validáciu vstupov v reálnom čase na strane klienta. Filtre ako email, url, phone alebo password aplikujú regulárne výrazy a vizuálnu spätnú väzbu (CSS triedy) podľa platnosti vstupu. V HTML sa používajú cez atribút dotbridge-result="0" dotbridge-input="name".

Dostupné argumenty:

  • filter: Názov filtra (napr. email).
  • start_checking_length: Minimálny počet znakov, od ktorého sa začne validácia.
  • class_ok: CSS trieda pre platný vstup.
  • class_bad: CSS trieda pre neplatný vstup.
Príklad:

<input type="text" {{ dotbridge:input="user.email(email, 5, 'valid-email', 'invalid-email')" }}>
    

Vstup user.email začne validáciu po 5 znakoch. Ak je e-mail platný, pridá sa trieda valid-email; ak je neplatný, invalid-email.

3.2 Rate limiting a bezpečnostné mechanizmy

DotBridge umožňuje obmedziť počet požiadaviek parametrami rateLimit(seconds,clicks), čím chráni aplikáciu pred zneužitím. Ďalšie bezpečnostné funkcie zahŕňajú oneTimeUse (jednorazový kľúč) a regenerateId (regenerácia kľúča po každom použití).

Použitie:

  • rateLimit(seconds,clicks): Maximálne clicks požiadaviek za seconds. Modifikátor zopakujte pre viaceré okná (napr. rateLimit(60,2) rateLimit(3600,5)).
  • oneTimeUse: Kľúč je platný iba na jedno použitie.
  • regenerateId: Po každom volaní vygeneruje nový kľúč.
  • url(path): Cieľová URL pre POST (predvolene: aktuálna stránka).
  • internalID(id): Priradí objektu Bridge stabilné interné ID.
  • expireAt(timestamp): Vyprší kľúč Bridge v danom Unixovom časovom razítku.
Príklad:

<button {{ dotbridge:on(click)="submitForm" rateLimit(60,10) rateLimit(3600,100) }}>Submit</button>
<button {{ dotbridge:on(click)="submitForm" oneTimeUse }}>Submit</button>
<button {{ dotbridge:on(click)="submitForm" regenerateId }}>Submit</button>
    

1. Príklad – Tlačidlo povolí maximálne 10 kliknutí za minútu, 100 za hodinu.

2. Príklad – Tlačidlo povolí iba jedno kliknutie a listener sa odstráni.

3. Príklad – Tlačidlo pri každom kliknutí regeneruje svoje ID.

3.3 Reťazenie metód

V PHP registrujte cez Bridge::listen(); voliteľné before() / after() reťazte na tom istom volaní. V JavaScripte použite $dotapp().bridge() s before() a after().

Príklad:

use Dotsystems\App\Parts\Bridge;
use Dotsystems\App\Parts\Router;

$urls = ['/process', '/process/'];
Bridge::listen($urls, "processData", function ($request) {
    $data = $request->data(true)['data'];
    return ["result" => trim($data["value"] ?? "")];
}, Router::STATIC_ROUTE)
->before(function ($request) {
    return null;
})
->after(function ($request) {
    return null;
});
    

// JavaScript
$dotapp().bridge("processData", "click")
    .before(function () {
        $dotapp(".trigger").addClass("loading");
    })
    .after(function (body) {
        $dotapp(".trigger").removeClass("loading");
        console.log(body.result);
    });
    

Handler na serveri orezáva vstup; hooky before a after dostanú $request. Na klientovi sa okolo volania prepína stav načítavania.

3.4 Práca s dynamickými dátami

DotBridge umožňuje odosielať a spracúvať dynamické dáta z viacerých vstupov definovaných v HTML. Vstupy používajú {{ dotbridge:input="name" }} alebo skrátený zápis dotbridge="name" a na server prichádzajú v $request->data(true)['data'].

Príklad:

<input type="text" {{ dotbridge:input="user.name" }}>
<input type="text" {{ dotbridge:input="user.email" }}>
<button {{ dotbridge:on(click)="saveUser(user.name, user.email)" }}>Save</button>
    

use Dotsystems\App\Parts\Bridge;
use Dotsystems\App\Parts\Router;

$urls = ['/account', '/account/'];
Bridge::listen($urls, "saveUser", function ($request) {
    $data = $request->data(true)['data'];
    $name = $data["user.name"] ?? "";
    $email = $data["user.email"] ?? "";
    return ["ok" => true, "message" => "User $name ($email) saved"];
}, Router::STATIC_ROUTE);
    

Po kliknutí sa hodnoty zo vstupov user.name a user.email odošlú funkcii saveUser a vrátia sa v odpovedi.

4. Odporúčané postupy a tipy

Táto kapitola poskytuje odporúčania a tipy na efektívne a bezpečné používanie DotBridge. Pokrýva optimalizáciu bezpečnosti, ladenie problémov a integráciu s ostatnými časťami frameworku DotApp.

4.1 Optimalizácia bezpečnosti

Bezpečnosť je pri používaní DotBridge kľúčový aspekt. Nasledujúce odporúčania pomôžu minimalizovať riziká a zabezpečiť robustnú komunikáciu:

  • Používajte rate limiting: Pre akcie citlivé na opakované volania nastavte rateLimit(seconds,count) (napr. rateLimit(60,2) rateLimit(3600,5) pre viaceré okná).
  • Zapnite jednorazové kľúče: Pri kritických operáciách (napr. odoslanie formulára) použite oneTimeUse alebo regenerateId, aby ste zabránili opätovnému použitiu toho istého kľúča.
  • Validujte vstupy: Kombinujte validačné filtre s dodatočnými kontrolami na strane servera (napr. filter_var()), aby bola validácia konzistentná.
  • Monitorujte relácie: Pravidelne kontrolujte a čistite staré kľúče v _bridge.objects, aby ste predišli pretečeniu pamäte.
  • Používajte šifrovanie: Na citlivé dáta v komunikácii využite vstavané šifrovanie DotApp (encrypt(), decrypt()).
Príklad:

<button {{ dotbridge:on(click)="secureAction" rateLimit(60,2) oneTimeUse }}>Execute</button>
    

use Dotsystems\App\Parts\Bridge;
use Dotsystems\App\Parts\Router;

$urls = ['/secure', '/secure/'];
Bridge::listen($urls, "secureAction", function ($request) {
    return ["ok" => true, "message" => "Action executed securely"];
}, Router::STATIC_ROUTE);
    

Tento príklad obmedzí akciu na 2 volania za 60 sekúnd a povolí iba jedno použitie kľúča.

4.2 Ladenie a riešenie problémov

Pri práci s DotBridge môžete naraziť na chyby. Tu sú bežné problémy a ich riešenia:

  • Kontrola CRC zlyhala (error_code 1): Overte, že dáta odoslané z frontendu neboli zmenené. Skontrolujte integritu JavaScriptového kódu a sieťových požiadaviek.
  • Kľúč Bridge sa nezhoduje (error_code 2): Uistite sa, že kľúč relácie (_bridge.key) zodpovedá tomu, čo posiela klient. Môže ísť o vypršanú reláciu.
  • Funkcia sa nenašla (error_code 3): Overte, že je funkcia zaregistrovaná cez Bridge::listen() alebo Router::bridge() a že názov zodpovedá volaniu v HTML.
  • Prekročený rate limit (error_code 4): Prekročili ste nastavený limit. Upravte rateLimit(seconds,count) alebo používateľa informujte, aby počkal.

Tip: Zapnite ladenie v DotApp a v nástrojoch pre vývojárov v prehliadači (záložka Network) skontrolujte POST odpovede Bridge. Predvoleným cieľom POST je URL aktuálnej stránky.

4.3 Integrácia s ostatnými časťami DotApp

DotBridge je navrhnutý tak, aby bezproblémovo spolupracoval s ostatnými komponentmi DotApp, ako sú Router, Request a databáza. Integrácia vám umožňuje stavať komplexné aplikácie s minimálnym úsilím.

Príklady integrácie:

  • S Router: Na viazanie handlerov na URL stránok použite Router::bridge($urls, $fnName, 'Module:Controller@method!', Router::STATIC_ROUTE). Signatúra: ($url, $function_name, $callback, $static = false).
  • S Request: Handlery dostanú $request; polia payloadu sú v $request->data(true)['data'].
  • S databázou: Dáta z frontendu môžete vkladať cez DB::module('RAW').
Príklad s databázou:

<input type="text" {{ dotbridge:input="user.email" }}>
<button {{ dotbridge:on(click)="saveEmail(user.email)" }}>Save</button>
    

use Dotsystems\App\Parts\Bridge;
use Dotsystems\App\Parts\DB;
use Dotsystems\App\Parts\Router;

$urls = ['/notes', '/notes/'];
Bridge::listen($urls, "saveEmail", function ($request) {
    $data = $request->data(true)['data'];
    $email = $data["user.email"] ?? "";
    if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
        DB::module('RAW')->q(function ($qb) use ($email) {
            $qb->insert('helloworld_notes', ['email' => $email]);
        })->execute(
            function ($result, $db, $exec) {},
            function ($error) {}
        );
        return ["ok" => true, "message" => "Email saved"];
    }
    return ["ok" => false, "message" => "Invalid email"];
}, Router::STATIC_ROUTE);
    

Po kliknutí sa e-mail overí a uloží do databázy a vráti sa odpoveď o úspechu alebo chybe.