Jak fungují hooky v Drupalu?

Vydáno:

Jiří Kupka

Jen málo později potom, co jsem začal nějak vážněji programovat, jsem se seznámil s Drupalem (dokonce jsem začínal na nějaké verzi 5.x). Jelikož jsem neměl moc potuchy o tom, jak funguje volání funkcí, že jdou volat dynamicky, že mohou splňovat určité předpisy, že některé vrací hodnotu a jiné mohou dokonce upravovat parametry přímo do nich vložené, byly hooky pro mě něco jako magie. Bez legrace. Tehdy jsem hledal po různu návody, jak si napsat nějaký jednoduchý modul v Drupalu - vytvořit vlastní stránku s formulářem. Něco málo bylo možné najít na drupal.cz, něco za pomocí vyhledávače na různých blozích. Konkrétní návody byly pěkné, ale pochopit fungování celého ekosystému Drupalu obecně nějakou dobu přeci jen trvalo. Jeden z milníku pro pochopení jeho fungování jsou právě hooky.

Drupal je postaven na systému modulů - každý modul má svůj jedinečný identifikátor (svůj název - řetězec) a do celku přidává nějakou funkcionalitu, nebo modifikuje již existující. Může přidávat stránky, formuláře, akce, nebo modifikovat ty, které byly přidány nějakým jiným modulem. Dalo by se říct, že takto si můžeme upravit téměř každou píď webu, a co je nejlepší, bez toho aniž bychom modifikovali jádro. Ne nadarmo je prvním přikázáním Don't hack the Core. Když se bude upravovat jádro, může to vést k nežádoucímu chování - uděláte nějakou změnu, se kterou nebude počítat nějaký jiný modul a ten se sesype. Nebo další příklad - uděláte úpravu v jádru, budete spokojeni (nic se nepokazilo :)), na změnu zapomenete a po půl roce budete chtít jádro aktualizovat. Potom se budete hodně divit, když najednou z webu zmizí něco, co předtím tak pěkně fungovalo.

Ale zpátky k hookům. Celý princip hooku staví na tom, že každý modul má, jak bylo řečeno výše, svůj jedinečný identifikátor. Hooky jsou vlastně funkce, které se drží určitého rozhraní, pravidel, jak je psát. Název každé takovéto funkce je hook_nazev_vlastnosti($parametry). Nahrazovací řetězec hook se vždy zamění za jedinečný název modulu, ve kterém je hook použit. Když vytvoříme modul se jménem muj_modul, bude se funkce jmenovat muj_modul_nazev_vlastnosti($parametry). Pro ukázku, několik nejčastěji používaných hooků:

hook_init()
muj_modul_init()
 
hook_form_alter(&$form, &$form_state, $form_id)
muj_modul_form_alter(&$form, &$form_state, $form_id)
 
hook_menu()
muj_modul_menu()

Hooky by se daly rozdělit do tří kategorií

  • Hooky procedurální - nic nevracejí, jenom vnitřně, když je potřeba, vykonají nějakou činnost - např. hook_cron() nebo hook_init()
  • Hooky tvořící - jsou to hooky, které na webu vytvářejí novou funkcionalitu, nejčastěji vracejí nějaké pole položek - např. hook_menu() nebo hook_block_info()
  • Alter hooky - tyto jsou možná nejzajímavější, jelikož pomocí nich můžete upravit již existující funkcionalitu stránky. Taková funkce může upravit chování, které přidal nějaký jiný modul, můžete upravit výpis podle toho, co jiný modul zpracoval a vůbec bez zásahu do cizích modulů si můžete upravit chování webu dle obrazu svého. Příkladem takovýchto hooků je hook_form_alter(&$form, &$form_state, $form_id) nebo hook_menu_alter(&$items)

A jak to funguje uvnitř? V systému existuje místo, kde se ve správnou chvíli vyžádá seznam všech aktivních modulů a zjistí se, jestli modul implementuje funkci [jeho_název]_nejaky_hook(). Pokud funkce existuje, zavolá se.
Např. v okamžiku, kdy se spustí systémový cron, projdou se všechny moduly, které implementují hook_cron() a tato funkce se zavolá.

  • Procedurální hooky se prostě spustí
  • Tvořící do místa spuštění vrátí nějaké pole objektů, s kterými si žadatel už umí poradit. Často se volají pouze jednou.
  • Alter hooky mezi sebou referencí přenášejí pole dat, které může libovolný z nich pozměnit a na konci se pole zpracuje.