Aplikační moduly

Moduly a modularita, pojmy které se táhnou celým Jetem jak červená niť, jak jste si již všimli i při čtení dokumentace. Ano, modularitu mám velice rád a v praxi se mi vždy osvědčila a přinesla samá pozitiva. Ale co to vlastně je ta modularita? K čemu je to dobré? Proč a jak aplikaci "kouskovat"? Na to můžou být různé pohledy. Tedy nejprve bych rád ujasnil jak je modularita chápána ve světě aplikací postavených s pomocí PHP Jet.

Co je to ta modularita?

Je to sice abstraktní pojem, ale ve skutečnosti je všude kolem nás. Vše kolem nás se skládá z nějakých dílčích částí, základních stavebních prvků, které jsou ale propojené, umí spolupracovat a tvořit jeden funkční celek. Příklad? Co třeba auto? To má modul motor, moduly náprav, modul brzdový systém, modul elektronika (tvořený řadou modulů). Nebo počítač (ať je to staré dobré PC, nebo smartphone - stále je to počítač). Ano, počítače ... Však se stačí kouknou na Von Neumannovo schéma. Počítač je modularita sama od sebe (procesor, paměť, řadiče, ...). Ale i naše vlastní tělo je modulární. Každý orgán je modul, každá končetina je modul. I lidská společnost je modulární a každý v ní plníme nějakou roli (sami jsme moduly). Tedy modularita (ve smyslu celku tvořeného stavebními prvky) je něco naprosto přirozeného a vidíme to na každém kroku. A je tedy přirozené takto dělat i aplikace. Tedy přemýšlet o aplikacích jako o celku, který je tvořený jednotlivými stavebními prvky. Má to celou řadu obrovských výhod.

Výhody modularity

  • Přehlednost
    Pokud aplikaci dobře navrhnete, tak bude vždy přehlednější než když je vše tak říkajíc na jedné hromadě.
  • Organizace práce
    "Franto, prosím Tě, potřebuju upravit view toho vyskakovacího okna nákupního košíku. Grafiku posílám. Najdeš to v modulu Shop.ShoppingCart a je to view popup_content. Díky!" To je velice důležité při práci v týmu. Ať je to malý tým, nebo firma mající desítky projektů a hromadu zaměstnanců, tak vždy je důležité snadno a efektivně komunikovat a organizovat práci. A modularita a správný návrh architektury aplikace tomu jde přímo naproti.
  • Znovupoužitelnost kódu
    Už jednou máte modul kvízy pro vaše CMS, tak jej určitě můžete použít na dalším projektu, kde klient kvízy chce. Jen si z jiného projektu nakopírujete adresář a pak už jen doladíte view (a případně další věci) dle přání klienta. Že to nemusíte dělat znovu je jasné. Ale hlavně ani to nemusíte preparovat a ze všech možných míst a adresářů. Prostě použijete a upravíte modul, který je v jednom adresáři - bez složitého pátrání.

Moduly aplikace Jet

Jak jsem již zmínil, tak na téma modularita se v Jet naráží často. Autloader má své moduly, keš má své backendy jako moduly a tak dále. To je sice také modularita, ale není to ta modularita o které si budeme povídat zde. Jak již jistě tušíte například z kapitol o MVC, tak modul aplikace je něco víc.

Dá se říct, že moduly aplikace jsou mikroaplikace dohromady tvořící celou aplikaci a Jet poskytuje pro tyto mikroaplikace základní ekosystém a zabezpečuje jejich základní integraci.

Než budeme pokračovat dál, tak si prosím zdůrazněme jednu důležitou věc. Mohlo by se zdát, že moduly pro Jet aplikace jsou zamýšlené jako univerzální. Tedy že Pepa vytvoří nějaký modul pro Jet aplikaci X a Franta jej může automaticky použít ve své aplikaci Y, která je zcela odlišná. Tak to myšleno není. Jet poskytuje základní úroveň, základní ekosystém a základní integraci. A očekává se, že nad Jet vznikne něco dalšího. Například je ve vývoji na Jet plně postavený e-commerce systém Jet Shop. A Jet Shop má další úroveň ekosystému, další úroveň integrace. Jet Shop již má své API, své třídy, svou knihovnu. Ano, to vše je postavené na Jet a využívá to co Jet nabízí. Ale je to už velká nadstavba. A až tady v této úrovni se dá předpokládat, že Pepa vyvine modul pro Jet Shop a Franta jej použije. To už je ta správná úroveň pro takové úvahy. Stejně tak může vzniknout vaše e-commerce řešení, vaše CMS či cokoliv dalšího a pak můžete operovat s moduly tak jak se předpokládá. Ale vždy to budou moduly pro nějaké konkrétní řešení, pro nějaký konkrétní systém. Nepočítá se s tím, že by měly být přenositelné moduly pro holý Jet. Ne že by to technicky nešlo, ale není to cílem a smyslem.

Co moduly umí

  • Instanace / deinstalace
    Moduly je možne naintalovat a odinstalovat. Modul může mít své vlastní instalační / deinstalační skripty.
  • Aktivace / deaktivace
    Moduly je možné například ponechat nainstalované, ale dočasně deaktivovat.
  • Metainformace a manifest
    Modul si nese informace o sobě samém v podobě manifestu. Součástí těchto informací může být běžná věc jako popis modulu, ale i například sada ACL operací pro systém autorizace. Tuto sadu informací můžete ve vašich aplikacích a systémech dále rozšiřovat.
  • Vlastní třídy
    Modul si může nést své vlastní třídy. Ba naopak dokonce musí nést minimálně jednu třídu označenou jako hlavní - třídu Main dědící od Jet\Application_Module. Ale krom této hlavní třídy a také kontrolerů může mít další své třídy, které modul potřebuje (a které nejsou potřebné pro ostatní moduly a části aplikace!)
  • Vlastní jmenný prostor
    Jak si za chvíli ukážeme, tak každý modul má svůj vlastní jmenný prostor, jehož název je určen přesně danou koncepcí.
  • Vlastní definice stránek
    Na to jsme již narazili v tématu MVC. Modul může poskytovat další definice stránek. To se v praxi používá zejména pro moduly určené pro administraci a podobně.
  • Vlastní definice položek menu
    Obdobně jako modul definuje stránky, tak může poskytovat definice položek menu. Opět se to v praxi používá zejména pro moduly určené pro administraci a podobně.
  • Vlastní view skripty
    Pochopitelně krom kontrolerů modul potřebuje i své view skripty.
  • Vlastní data
    Pokud modul potřebuje pro svou práci nějaká svá data, tak i ta mohou být uložena v jeho adresáři.
  • Moduly umí spolupracovat
    Jeden modul může získat instanci modulu druhého (přesněji jeho hlavní třídy Main)) a s tou dál pracovat (pochopitelně po té co si ověří dostupnost daného modulu). Tedy mezi moduly může být a ve skutečné praxi často je vazba. Ta vazba by ideálně neměla být moc pevná (mělo by se počítat s tím, že požadovaný modul není k dispozici). Ale provázanost modulů je věc běžná a žádaná.
  • Moduly může být označen jako mandatorní
    Modul může být označen jako mandatorní. To znamená, že musí být nainstalován vždy.

Umístění, uspořádání, jmenné prostory a názvy modulů

Moduly jsou standardně v adresáři ~/application/Modules/. Každý modul má svůj adresář. Ale pozor! Adresáře se mohou zanořovat. To je velice důležité a díky tomu je možné moduly tématicky seskupovat. To velice vřele doporučuji. Tedy adresář v adresáři modulů nepředstavuje automaticky modul, ale mohou v něm být další podadresáře. Modul je až ten adresář, ve kterém se nachází soubory manifest.php obsahující metadata modulu a Main.php obsahující hlavní třídu modulu.

Ono zanoření adresářů nemá jen důležitý význam pro organizaci modulů a přehlednost. Adresáře a jejich zanoření zároveň tvoří název modulu a také jmenný prostor. Ukažme si to rovnou na příkladu jednoho z modulů ukázkové aplikace. Jako pokusného králíka si vezmeme adresář, který je v adresáři ~/application/Modules/Content/Articles/Admin/. Tento adresář je modul nesoucí název Content.Articles.Admin. Tedy název modulu přesně odpovídá adresářové cestě. Jediný rozdíl je ten, že jsou z praktických důvodů lomítka (která se mi v praxi neosvědčila) nahrazená tečkami. Když budu chtít s modulem někde operovat, budu potřebovat tento údaj - jeho název.

Když v adresáři ~/application/Modules/Content/Articles/Admin/ otevřete třeba skript Main.php (tedy soubor obsahující hlavní třídu modulu), tak uvidíte toto: namespace JetApplicationModule\Content\Articles\Admin; Tedy ano, jmenný prostor všech tříd modulu také odpovídá adresáři. U jmenného prostoru se ještě zastavme. Ten začíná kořenovým jmenným prostorem JetApplicationModule. Ale nic nebrání tomu si definovat vlastní kořenový jmenný prostor pro moduly systémovou konfigurací.

Tedy název a zanoření adresáře kde se modul nachází je determinantou jeho názvu i jmenného prostoru. Moduly pochopitelně můžete přejmenovávat, nebo kopírovat (klonovat). Stačí změnit adresář a jmenný prostor ve skriptech modulu - v praxi je to triviální a užitečná operace.

Struktura modulu

Ať pouze neteoretizujeme, tak si sáhněme opět pro jeden z modulů ukázkové aplikace a to opět pro modul Content.Articles.Admin, který je určený pro správu článků v administraci. Na tomto modulu si rozeberme typické uspořádání adresáře modulu.

Adresář / Soubor Význam
_install/
_install/install.php
_install/uninstall.php
Jak název napovídá, tak se jedná o instalační adresář modulu.
(Jistě jste si všimli znaku _ na jeho začátku a jak již víte, tak tento adresář nemá být na produkční prostředí - to jen pro pořádek :-) )

Adresář může (ale nemusí) obsahovat skripty volané při instalace / deinstalaci modulu. V těchto skriptech je možné provést vše potřebné. Tedy založit databázové tabulky, nakopírovat slovníky do hlavního adresáře slovníků a tak dále.

Krom skriptů může adresář obsahovat potřebná data pro instalaci (např. soubory, které instalační skript někam nakopíruje a podobně).

Nic z uvedeného však není povinné. Instalace / deinstalace funguje i bez tohoto adresáře a skriptů.
menu-items/
menu-items/admin.php
Jak již bylo řečeno, tak modul může definovat položky menu. Tento ukázkový modul definuje svou položky v menu administrace.

Pochopitelně není povinné a modul co menu nepotřebuje tento adresář vůbec mít nemusí. Stejně tak není dogma, že menu musí být pro administraci - naopak, definice může být pro cokoliv je třeba.
pages/
pages/admin/
pages/admin/articles/
pages/admin/articles/page_data.php
Jak vidno, tak modul si definuje stránku pro bázi admin, která bude na URL /admin/articles/ a na této URL bude samotný modul uživatelům k dispozici.

Opět platí, že ne každý modul musí definovat nějaké stránky a adresář je tedy zcela nepovinný. Stejně tak není dogma, že definice stránek má být pro administraci.
views/
views/edit.phtml
views/list.phtml
A zde jsou view skripty modulu. Demonstrační modul má view pro seznam článků (list.phtml) a jejich úpravu (detail.phtml) v administraci.

Nic z toho není povinné. Jaké bude mít modul view a jestli vůbec nějaké je čistě vaše věc.
Controller/
Controller/Main.php
Pokud má být modul použit pro MVC, tak musí mít minimálně jednu třídu kontroleru. Výchozí je kontroler Main, ale kontrolerů může být víc.

Pokud však tvoříte modul, který nebude nikde poskytovat obsah stránkám a kontrolery tedy nebude potřebovat, tak samozřejmě žádné kontrolery mít nemusí.
Listin.php A další nepovinná věc - pouze za účelem názornosti a demonstrace co lze. Jak již bylo řečeno, tak modul může mít své vlastní třídy. A v tomto souboru je třída pro práci se seznamem článků. Pokud má modul své třídy, tak mohou být samozřejmě uspořádány do adresářů podle stejné konvence jakou používá zbytek systému.
Main.php Toto je povinné. Modul musí mít třídu Main, která dědí od Jet\Application_Module (nebo od jiné třídy, která však od Jet\Application_Module musí dědit). Tato třída je hlavním bodem přes který modul může komunikovat se zbytek systému a s ostatními moduly. Proto je povinná.
manifest.php Soubor obsahující manifest modulu, tedy jeho metadata. To je logicky povinné.

Dále se prosím koukněte jak se moduly vytváří, instalují, aktivují, prostě jak se s nimi pracuje.

Předchozí kapitola
Jiné (zjednodušené) přístupy k MVC
Další kapitola
Práce s moduly