Získání dat z objektů v Drupalu (příklad: uživatel)
Jste zde
Už jsme předeslali, že náš výklad není „učebnicový“ a systematický. Proto si nyní dovolíme přesunout se k naprostým základům práce s objekty, abychom mohli z některých důležitých proměnných v Drupalu získávat data, která budeme v dalším výkladu potřebovat.
Uživatelé a uzly v Drupalu jsou z programátorského hlediska tzv. objekty (více o objektech v Drupalu). Jak už jsme si ukázali, objekt nelze vypsat prostým print
nebo echo
. Celou strukturu uživatele nebo uzlu můžeme vypsat například pomocí funkce modu Devel dpm()
.
Nyní si to ukážeme na příkladu uživatele. Cílem bude dostat se k obsaženým datům (konkrétně k uživatelskému jménu), abychom ho mohli použít v našem příkladu a vypsat tak skutečný název účtu aktuálně přihlášeného uživatele.
Upravte pouze začátek kódu, se kterým pracujeme, takto:
<h4>Zpráva pro tento den</h4> <?php global $user; dpm($user); (...) ?>
Dostanete již známý výpis struktury objektu $user (aktuálně přihlášený uživatel, tedy vy), se všemi dostupnými daty, která se postupně rozbalují na kliknutí.
Následně získáme název uživatelského účtu:
$name = $user->name;
Celá úvodní část kódu bude tedy upravena takto:
Všimněte si, že jakmile už funkci dpm()
nepotřebujeme, okamžitě jsme ji zakomentovali (tj. označili jsme ji jako komentář). To je velmi užitečný zvyk - tak nehrozí, že po vypnutí modulu Devel dojde k fatální chybě (volání neexistující funkce).
<h4>Zpráva pro tento den</h4> <?php global $user; //dpm($user); // POZOR, tohle zatím není hotové, protože níže uvedený kód není bezpečný. Proměnná $name se ve funkci daily_message přímo vypisuje, což by mohlo umožnit útok zvaný XSS... $name = $user->name; (...) ?>
POZOR, jak jsme naznačili v komentáři kódu: to ještě není všechno. Veškerá data, která na web zadává přímo uživatel, je třeba ošetřit z hlediska bezpečnosti. To se týká i uživatelského jména. Je třeba uvědomit si, že databáze obsahuje surové, neformátované hodnoty. Z programátorského hlediska je to v pořádku - zpracovávají se až na výstupu. Pokud je však na výstupu neošetříme a budeme s nimi rovnou pracovat, otevíráme tím prostor případnému útoku na web (v daném případě tzv. Cross-sites scripting (XSS). Ukážeme si jednu z možností, jak data ošetřit:
Uživatelské jméno, které jsme získali z databáze, obalíme funkcí Drupalu check_plain()
, která nahradí případné speciální znaky prostým textem:
<h4>Zpráva pro tento den</h4> <?php global $user; //dpm($user); // Nyní získáme uživatelské jméno a zároveň ho ošetříme proti XSS: $name = check_plain($user->name); (...) ?>
Výsledek (za předpokladu, že jste přihlášeni k účtu s názvem admin, bude vypadat takto):
Zpráva pro tento den
Jste přihlášeni k účtu admin. Dnes je
(... další část výstupu dle aktuálního dne v týdnu)
Pokud bychom funkci daily_message()
předávali nezpracovaná data z databáze, je nutné ošetřit je proti XSS uvnitř funkce. O zpracování (zabezpečení) dat se starají také některé funkce Drupalu. Od Drupalu 5 výše je to například již zmíněná funkce t()
, která se stará o překlad, zároveň však výstup zabezpečí proti XSS.
Pokud opět odkomentujete funkci dpm()
a podíváte se na strukturu objektu, uvidíte, že obsahuje spoustu zajímavých dat, která si můžete zkusit podobně vypsat, například:
global $user; dpm($user); $uid = $user->uid; //Vypíšeme unikátní číslo uživatele - UID. To nemusíme nijak zpracovávat, je automaticky vytvořeno Drupalem. Můžeme se tedy spolehnout na to, že to je celé číslo a neobsahuje žádný škodlivý kód. print $uid;
Všimněte si, že jako $user->pass
se nevypisuje samotné heslo, nýbrž tzv. hash - tj. šifrovaná podoba, která je uložena v databázi. Hesla uživatelů tak nelze získat ani z databáze.
Jednu z hodnot ovšem podobným způsobem vypsat nelze. Vyzkoušejte:
global $user; dpm($user); $roles = $user->roles; //Zkusíme vypsat uživatelské role. Zatím nesprávným způsobem - abychom zjistili, že to není jen tak :-) echo $roles;
Výsledek:
Array
Uživatelské role jsou totiž uloženy jako pole.
V následující kapitole si ukážeme, jak z tohoto pole získat užitečná data pro výstup našeho příkladu Zpráva pro teto den.