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
beforeaafter. - 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
oneTimeUsearegenerateIdpre 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:
- Vygeneruje jedinečný kľúč relácie a na strane servera zaregistruje PHP funkcie cez
Bridge::listen()aleboRouter::bridge(). - V HTML sa definujú udalosti (napr.
{{ dotbridge:on(click)="fnName" }}) a vstupy (napr.{{ dotbridge:input="name" }}alebo skrátenedotbridge="name") a prepoja sa s PHP funkciami. - 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.
- Server overí kľúč, dešifruje dáta, skontroluje limity požiadaviek a vykoná požadovanú PHP funkciu.
- 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.
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álneclickspožiadaviek zaseconds. 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
oneTimeUsealeboregenerateId, 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()aleboRouter::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.