Další příklady z Drupalu

Jste zde

Na následujících příkladech si ukážeme několik dalších funkcí a příkazů, kromě toho si procvičíte, co už jstese naučili.

Má uživatel roli s daným názvem?

Ke zjištění, zda uživatel má konkrétní roli (tedy: zda pole s rolemi obsahuje konkrétní hodnotu), mohli byste teoreticky použít příkaz foreach. V PHP však existuje funkce, pomocí níž se dopracujete k výsledku mnohem snáze.

Funkce in_array() umožňuje zjistit, zda pole obsahuje určitou hodnotu:

global $user;
//dpm($user);
$roles = $user->roles;
$name = check_plain($user->name);
//Vypíšeme strukturu pole $roles pomocí funkce dpm()
dpm($roles);
//Zjistíme, zda uživatel má roli „editor“. V závislosti na výsledku vypíšeme zprávu na monitor.
if (in_array('editor', $roles)) {
  print 'Uživatel' . ' ' . $name . ' ' . 'má roli editor';
} else {
  print 'Uživatel' . ' ' . $name . ' ' . 'nemá roli editor';
}

Funkce in_array() je jednou z mnoha funkcí pro práci s polemi. V manuálu PHP se dozvíte, že má tuto syntaxi:

bool in_array (mixed $needle , array $haystack [,bool $strict = FALSE])

  • boll - znamená, že funkce vrací booleanovskou (logickou) hodnotu, tedy TRUE nebo FALSE.
  • Následuje název funkce a syntaxe zápisu.
  • $needle - proměnná, jejíž název podle konvence označuje „jehlu v kupce sena“. V manuálu se používá pro označení toho, co hledáte. (V našem příkladu jsme hledali hodnotu editor). Ve svém kódu si proměnnou můžete pojmenovat, jak chcete, nebo na její místo zadat rovnou hodnotu (což jsme udělali).
  • mixed - znamená, že proměnná $needle může patřit k různým datovým typům (řetězec, číslo...)
  • $haystack - proměnná, jejíž název podle konvence označuje „kupku sena“, tedy nějaký celek, který prohledáváme (a hledáme v něm jehlu). V našem případě to bylo pole $roles.
  • [] - hranaté závorky se do kódu nepíšou, označují nepovinnou část funkce. Zde je to proměnná $strict, která vyjadřuje, zda se při hledání má porovnávat také datový typ. Je to logická/booleanovská proměnná a její výchozí hodnota je FALSE (ta se použije, když nic nezadáte).

Má uživatel roli s daným RID?

Zjišťování uživatelské role podle názvu funguje, ale není příliš praktické, protože uživatelskou roli může někdo přejmenovat. Pokud ovšem jednou vytvoříte skript, jehož výstup se řídí příslušností uživatele k určité roli, pravděpodobně nebudete chtít, aby přestal fungovat jen díky tomu, že roli někdo v administraci přejmenuje.

Naštěstí, jak už jste zjistili, má každá role unikátní RID, které se nemění. Příslušnost uživatele k roli je tedy lepší zjišťovat na základě RID. V poli ovšem toto číslo není hodnotou, ale klíčem, proto nám funkce in_array nepomůže.

Musíme si vybrat jinou z moha funkcí pro práci s polemi: array_key_exists.

Podobně jako in_array prochází hodnoty, funkce array_key_exists prochází klíče. Má následující syntaxi.

bool array_key_exists ( mixed $key , array $search )

Vyzkoušejte v příkladu:

global $user;
//dpm($user);
$roles = $user->roles;
$name = check_plain($user->name);
//Vypíšeme strukturu pole $roles pomocí funkce dpm()
dpm($roles);
//Zjistíme, zda uživatel má roli „editor“. V závislosti na výsledku vypíšeme zprávu na monitor.
if (array_key_exists(4, $roles)) {
  print 'Uživatel' . ' ' . $name . ' ' . 'má roli editor';
} else {
  print 'Uživatel' . ' ' . $name . ' ' . 'nemá roli editor';
}

Zobrazení bloku, pokud PHP kód vrátí TRUE

Vraťte se k nastavení bloku Testování PHP a nastavte viditelnost bloku pomocí PHP, takto (pozor, zde musíte použít počáteční a koncový tag, viz nápověda nastavení bloku):

<?php
global $user;
//Deklarujeme proměnnou $visibility, která bude obsahovat logickou hodnotu pro (ne)zobrazení bloku. Přiřadíme jí výchozí hodnotu FALSE.
$visibility = FALSE;
$roles = $user->roles;
if (array_key_exists(4, $roles)) {
  $visibility = TRUE;
}
//Nakonec vrátíme (return) proměnnou. To je nutné, jinak by Drupal žádný výstup našeho kódu nedostal.
return $visibility;
?>

Jedná se pouze o cvičný příklad - jak asi víte, zobrazení bloku podle uživatelské role můžete v Drupalu snadno nastavit konfiguračně. Drupal 7 má oproti starším verzím mnohem více možností, jak nastavit viditelnost bloků, takže těžko najdeme (jednoduchý) příklad, kde byste PHP potřebovali. Mohlo by se třeba jednat o kombinaci různých podmínek (např. uživatel s určitou rolí a první den v měsíci).

Nastavení viditelnosti bloku pomocí PHP, stejně jako jiné vkládání PHP přes administraci Drupalu, je každopádně krajní varianta, kterou byste měli použít pouze tehdy, když jinou možnost nemáte. Používání PHP v administraci Drupalu není samo o sobě nebezpečné (proto je také povoleno), ale obrazně se dá říci, že v aplikaci „dělá nepořádek“ a tudíž také mírně zvyšuje riziko, že nějakou bezpečnostní chybu uděláte. PHP kód ideálně patří do vašeho vlastního modulu nebo do vlastního tématu vzhledu (především pak do souboru template.php).

Zjištění zda existuje neprázdná proměnná

Změňte nyní nastavení bloku Zpráva pro tento den tak, aby se zobrazoval všem uživatelům. Odhlaste se z webu. Uvidíte chybovou hlášku, která odkazuje na tento řádek v kódu bloku:

$name = check_plain($user->name);

Důvodem je to, že kód se „snaží pracovat“ s neexistující, resp. prázdnou proměnnou $name - ta totiž v případě anonymního uživatele žádnou hodnotu neobsahuje.

Kód proto ošetříme podmínkou funkcí isset(), která zjišťuje, zda proměnná existuje a obsahuje jinou hodnotu než NULL.

Syntaxe:

bool isset  ( mixed $var [, mixed $... ] )

Nepovinné parametry vyjadřují, že pomocí funkce můžete testovat více než jednu proměnnou. Funkce vrátí TRUE pouze tehdy, pokud „projde“ testování všech proměnných.

V příkladu nyní upravte část, kde se deklaruje proměnná $name, takto:

if (isset($user->name)) {
  $name = check_plain($user->name);
}

Na výstupu ovšem zjistíte další chybu: funkce daily_message() totiž stále pracuje s neexistující proměnnou.

Proto je třeba upravit ještě volání funkce, například takto:

if (isset ($name)) {
  print daily_message($name, $day, $day_number, $node);
}

Použití hodnot z uzlu v bloku

Vraťme se ještě jednou k příkladu Zpráva pro tento den. V praxi by určitě nevyhovovalo, aby každý, kdo chce upravit text zprávy, musel zasahovat do PHP kódu. Ve skutečnosti by bylo nutné oddělit PHP kód (který zabezpečí zobrazení odpovídajících zpráv ve správné dny) od editace samotných zpráv, kterou provádí poučený uživatel přes administrační rozhraní Drupalu.

Berte prosím v úvahu, že příklad je ještě hodně vzdálený optimálnímu řešení. Pro jednoduchost budeme předpokládat, že zpráva existuje pro každý den v týdnu, a všechny zprávy uložíme do jednoho uzlu - jako 7 hodnot jednoho pole.

Vytvořte typ obsahu Zpráva se strojovým názvem message.

Přidejte pole Denní zpráva se strojovým názvem field_message_daily (dlouhý text). Povolte filtrovaný text (uživatelé budou moci použít HTML, popřípadě WYSIWYG editor) a 7 hodnot.

Zadejte text nápovědy: Do jednotlivých polí zadejte zprávy pro jednotlivé pracovní dny v týdnu, v pořadí Pondělí - Pátek. Neuvádějte názvy dní.

Nyní vytvořte uzel typu Zpráva, pojmenujte ho Zdroj: Zpráva pro tento den a zadejte zprávy pro jednotlivé dny.

Po uložení se v záložce Devel podívejte na strukturu pole field_message_daily. Zjistěte a zapamatujte si také NID uzlu - budete ho potřebovat.

Nyní upravte kód příkladu Zpráva pro tento den:

<h4>Zpráva pro tento den</h4> 
<?php 
global $user; 
//dpm($user); 
if (isset($user->name)) {
  $name = check_plain($user->name); 
}
 
//Získáme data z uzlu, kde jsou uloženy zprávy. Použijte NID vašeho uzlu. 
$node = node_load(3); 
 
$day = t(date('l')); 
 
//Nyní budeme pracovat také s číselnou reprezentací dne v týdnu. Pozor, ne všechna číslování týdnů začínají pondělkem - blíže viz manuál PHP 
$day_number = date('N'); 
 
//Pro kontrolu si dočasně vypíšeme kontrolu, zda získáváme odpovídající číslo pro aktuální den v týdnu (1 pro pondělí atd.) - pak je nutné zakomentovat 
dpm($day); 
dpm($day_number); 
 
if (isset ($name)) {
  print daily_message($name, $day, $day_number, $node);
}
 
function daily_message($name, $day, $day_number, $node) { 
  $default_message1 = '<p>Jste přihlášeni k účtu ' . '<strong>' . $name . '</strong>. Dnes je ' . '<strong>' . $day . '</strong>.</p>'; 
  $default_message2 = '<p>Ať se vám dnes všechno daří!</p>'; 
  $daily_message = ''; 
  //Deklarujeme proměnnou (pole), kde budou jednotlivé zprávy (budeme získávat z hodnot v uzlu). 
  $message_array = array(); 
  $message_array = $node->field_message_daily['und']; 
 
  //Číslo dne v týdnu podle PHP je o 1 větší než klíč, který budeme potřebovat k získání hodnoty v poli (číselné klíče začínají vždy od nuly, ale dny týdnu od 1). Proto provedeme korekci. 
  $key = $day_number - 1; 
 
  //Budeme pracovat s hotnotou 'safe_value', která zde představuje již ošetřená data (filtrované HTML). Pokud bychom pracovali se surovou hodnotou - 'value', musíme data ošetřit sami 
  $daily_message = $message_array[$key]['safe_value']; 
  $message = $default_message1 . $daily_message . $default_message2; 
  return ($message); 
} 
?>

Výstup:

Testování PHP

Zpráva pro tento den

Jste přihlášeni k účtu admin. Dnes je NÁZEV AKTUÁLNÍHO DNE V TÝDNU
AKTUÁLNÍ ZPRÁVA PRO SPRÁVNÝ DEN

Ať se vám dnes všechno daří!

A to je (alespoň prozatím) konec našeho stručného úvodu do PHP v Drupalu. Předpokládáme, že u těchto znalostí dlouho nezůstanete a že zažijete mnoho zábavy a úspěchů při získávání dalších. Přejeme vám, ať se vám to vždy daří, a to přímo Squelle.

Vaše Squelle a autoři: Eva Rázgová, Michal Pazderský

Copyright © 2011-2018, Squelle Group, s.r.o., Drupal web, konzultace, školení a šablonování. • Obchodní podmínkyKontakty