Masarykova univerzita Fakulta informatiky
Internetový redakční systém Bakalářská práce
Štěpán Havlíček
Brno, leden 2007
Prohlášení Prohlašuji, že tato práce je mým původním autorským dílem, které jsem vypracoval samostatně. Všechny zdroje, prameny a literaturu, které jsem při vypracování používal nebo z nich čerpal, v práci řádně cituji s uvedením úplného odkazu na příslušný zdroj. Štěpán Havlíček
Poděkování Rád bych poděkoval vedoucímu mé bakalářské práce, Mgr. Radku Ošlejškovi, za odborné vedení, rady a pomoc při tvorbě této práce.
ii
Shrnutí Tématem této bakalářské práce je analýza, návrh a implementace redakčního systému, který umožní spravovat obsah více internetových portálů. Jako nástroj analýzy je zvolena metoda strukturované analýzy vytvořená Tomem DeMarcem. Vytvářený systém je založen na webových technologiích. Konkrétní nástroje použité při implementaci jsou skriptovací jazyk PHP a databázový systém MySQL.
Klíčová slova strukturovaná analýza, redakční systém, PHP, MySQL, stromová struktura dat
iii
Obsah 1 Úvod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 2 Analýza systému . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 2.1 Model okolí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 2.1.1 Účel systému . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 2.1.2 Kontextový diagram a seznam událostí . . . . . . . . . . . . . . . . . . . . . . 3 2.2 Model chování . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 2.2.1 Datový model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 2.2.2 Datový slovník . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.2.3 Funkční model a minispecifikace . . . . . . . . . . . . . . . . . . . . . . . . . 16 3
Implementace systému . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 3.1 Použité technologie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 3.1.1 Skriptovací jazyk PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 3.1.2 Databázový server MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 3.1.3 Webový server Apache . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 3.1.4 PhpMyAdmin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 3.2 Vytvoření databáze . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 3.3 Proces autentizace a autorizace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4
Ukládání stromových dat v databázích . . . . . . . . . . . . . . . . . . . . . . . . . . 25
5
Závěr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Literatura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
iv
Kapitola 1
Úvod Obsah publikovaný na internetových stránkách v dnešní době tvoří z velké části obsah dynamicky generovaný. Představa, že by správci některého z mnoha zpravodajských serverů utvářeli obsah portálu editací statických stránek, je nemyslitelná. Proto při tvorbě webových stránek začaly hrát významnou úlohu databáze a skriptovací jazyky. Redakční systémy jsou aplikace, které umožňují kolektivu autorů spolupracovat na tvorbě obsahu internetového portálu. Plní funkci grafického rozhraní mezi uživatelem a databází, ve které jsou ukládána samotná data. Cílem této práce je analýza a návrh redakčního systému, který bude schopný spravovat více portálů. Hlavním rysem systému přitom bude možnost obsah publikovaný na jednotlivých portálech sdílet. Redaktoři tak budou mít možnost publikovat článek vytvořený pro portál jiný, který ovšem může jejich čtenáře též zajímat. Velká část této práce je věnována analýze systému. Na základě analýzy je potom implementován samotný redakční systém. Práce také pojednává o problémech, které je při implementaci potřeba řešit. Je popsána implementace přihlašování do systému a jedna kapitola je věnována ukládání hierarchických struktur v databázích.
1
Kapitola 2
Analýza systému Metoda strukturované analýzy a návrhu vytvořená Tomem DeMarcem[1] v 80. letech minulého století se skládá ze dvou základních kroků. Prvním krokem je vytvoření modelu okolí. Model okolí popisuje rozhraní mezi navrhovaným systémem a okolním světem. Je tvořen následujícími komponentami:
Účel systému – krátký textový dokument, který vyjadřuje hlavní cíle, kterých by mělo být dosaženo po implementaci a nasazení navrhovaného systému. Kontextový diagram – zvláštní případ DFD, který obsahuje pouze jediný proces reprezentující celý systém Seznam událostí – textový výčet stimulů, které se mohou objevit ve vnějším světě a na které musí navrhovaný systém reagovat
Kontextový diagram poskytuje přehled o základní funkcionalitě systému v grafické podobě. Zdůrazňuje přitom tyto rysy: terminátory – představují lidi a systémy z okolí, s nimiž systém komunikuje data přijímaná z vnějšího světa, která mají být systémem zpracována data produkovaná systémem, které jsou zasílána do vnějšího světa datové paměti sdílené systémem a terminátory hranice mezi systémem a okolním světem Seznam událostí obsahuje události tří druhů: F (Flow) – tokově orientovaná událost, je sdružená s datovým tokem T (Temporal) – časová událost, která nastává v nějakém významném časovém bodě C (Control) – řídící událost, povel, signál (je sdružena s vnějším řídícím tokem, povelem) Jakmile je vypracován model okolí, je dalším krokem zpracování modelu chování. Model chování popisuje vnitřní části systému. Hlavní části jsou datový a funkční model, které podrobněji popisuji v dalších kapitolách. Kompletní model chování je tvořen následujícími komponentami: sada diagramů datových toků sada entitně-vztahových diagramů sada minispecifikací procesů na nejnižší úrovni DFD datový slovník
2.1 Model okolí 2.1.1 Účel systému Navrhovaný redakční systém umožní spravovat obsah více internetových portálů. Systém umožní pověřeným osobám založit nový portál a měnit jeho vlastnosti. Každý portál má své redaktory, kteří vkládají články, aktuality a ankety, které svým tématem souvisí s oblastí, kterou se daný portál zabývá.
2
V systému jsou definovány dvě základní uživatelské role, šéfredaktor a redaktor. Šéfredaktor má oprávnění zakládat účty novým redaktorům a měnit jejich oprávnění. Aby byla šéfredaktorovi umožněna lepší kontrola nad změnami obsahu, je možné jednotlivým redaktorům přidělit práva pro vkládání aktualit, anket a nakonec i právo přispívat do jednotlivých rubrik. Pokud má tedy například redaktor právo vkládat aktuality, může vkládat aktuality pouze do rubrik, ke kterým má oprávnění. Šéfredaktor dále může měnit strukturu kategorií, do kterých jsou řazeny jednotlivé články a aktuality. Uživatel s právem 'Správce portálů' má oprávnění vytvářet nové portály, měnit jejich atributy a portály mazat. Také může dočasně označit portál za 'neplatný' a znemožnit tak uživatelům se přihlásit a měnit jeho obsah. Redaktoři přispívají do jednotlivých rubrik. Jakmile autor dokončí článek, označí ho jako hotový. Tím dává šéfredaktorovi najevo, že článek je možné publikovat. Šéfredaktor je zodpovědný za publikování článků. Systém oprávnění umožní, aby jedna osoba vystupovala jako redaktor u jednoho portálu a jako šéfredaktor u portálu jiného. Také jeden redaktor může přispívat do více portálů, pokud mu šéfredaktor daného portálu založí účet. Před publikováním článku mohou ostatní redaktoři vyjádřit své názory na článek v diskuzi s autorem. Ke každému článku lze připojit anketní otázku. Jedna anketní otázka může být připojena k více článkům a může být vystavena i na hlavní stránce portálu, popřípadě i více portálů, aby na ní reagovalo co nejvíce lidí. Systém umožní zveřejnění jednoho článku nebo aktuality na více portálech. Odkaz na článek nebo aktualitu, která je zveřejněna na více portálech, směřuje na portál, pro který byl daný článek či aktualita napsána. Článek může být zveřejněn na dalších portálech i s časovým odstupem. Čtenář má možnost se zaregistrovat. Registrovaný čtenář si může vyžádat zasílání buletinu, který obsahuje přehled nových článků a aktualit. Toto nastavení lze provést zvlášť pro každý portál. Další výhodou registrace je zpříjemnění čtení diskusních příspěvků. Registrovanému čtenáři se zvýrazňují příspěvky, které přibyly od jeho posledního přihlášení. Systém redaktorům umožní zobrazit u každého jejich článku počet příspěvků, které byly vloženy ke článku od jejich posledního přihlášení. Každý redaktor bude mít také možnost odstranit nevhodné diskusní příspěvky čtenářů.
2.1.2 Kontextový diagram a seznam událostí Kontextový diagram jsem rozdělil do samostatných částí podle jednotlivých terminátorů, kteří se v systému vyskytují. Kompletní kontextový diagram je k dispozici na přiloženém CD. Terminátor čtenář Čtenář je osoba, která přistupuje k jednotlivým portálům a prohlíží si jejich obsah. Čtenář nemá možnost měnit publikovaný obsah. Může pouze přispívat do diskuzních fór nebo hlasovat v anketě. Čtenář je z pohledu systému anonymní uživatel, o kterém aplikace neuchovává žádné informace. Není tedy možné čtenáři jakkoliv stránky personalizovat.
3
Obrázek 2.1 Kontextový diagram – terminátor čtenář Seznam událostí pro terminátor čtenář:
čtenář žádá zobrazení článku čtenář žádá zobrazení všech článků rubriky čtenář žádá zobrazení všech článků autora čtenář žádá zobrazení aktuality čtenář zadává vyhledávací dotaz čtenář vkládá hlas do ankety čtenář žádá zobrazení ankety čtenář vkládá příspěvek do diskusního fóra čtenář se registruje
F F F F F F F F F
Terminátor registrovaný čtenář Registrovaný čtenář je čtenář, který se na nějakém portále zaregistroval a má tedy možnost se přihlásit. Aplikace uchovává o registrovaných čtenářích informace, které slouží pro zpříjemnění prohlížení stránek. Registrovanému čtenáři může být zaslán například informační buletin. Seznam událostí pro terminátor registrovaný čtenář:
registrovaný čtenář mění své nastavení registrovaný čtenář si žádá zasílání buletinu registrovaný čtenář ruší zasílání buletinu 4
F F F
Obrázek 2.2 Kontextový diagram – terminátor registrovaný čtenář Terminátor redaktor Redaktor je osoba, která má přístup k redakčnímu systému. Hlavní úlohou redaktora je psát články, které jsou publikovány šéfredaktorem. Redaktor s oprávněním pro vkládání aktualit nebo vytváření anket může publikovat aktuality, respektive zveřejňovat ankety, sám bez vědomí šéfredaktora. Seznam událostí pro terminátor redaktor:
redaktor mění své osobní údaje redaktor vkládá příspěvek do diskusního fóra redaktor maže příspěvek čtenáře redaktor vkládá aktualitu redaktor maže aktualitu redaktor vkládá článek
redaktor maže článek
redaktor vkládá novou anketu redaktor uzavírá anketu redaktor upravuje anketu redaktor maže anketu
F F F F F F F F F F F
5
Obrázek 2.3 Kontextový diagram – terminátor redaktor Terminátor šéfredaktor Šéfredaktor je zodpovědný za publikování článků. Může měnit strukturu kategorií, do kterých jsou řazeny články a aktuality. Šéfredaktor má oprávnění zakládat účty novým redaktorům, měnit jejich oprávnění a účty rušit. Seznam událostí pro terminátor šéfredaktor:
šéfredaktor vytváří účet nového redaktora šéfredaktor mění účet redaktora šéfredaktor ruší účet redaktora šéfredaktor vytváří novou kategorii pro články šéfredaktor mění kategorii pro články šéfredaktor ruší kategorii pro články šéfredaktor publikuje článek šéfredaktor stahuje článek z portálu 6
F
F F F F F F F
Obrázek 2.4 Kontextový diagram – terminátor šéfredaktor Terminátor správce portálů Správce portálů je uživatel, který má oprávnění zakládat nové portály, pozastavovat jejich platnost a portály rušit. Má také možnost přidělit právo na spravování portálů jinému uživateli. Seznam událostí pro terminátor správce portálů: správce portálů vytváří nový portál
F
správce portálů mění atributy portálu
F
správce portálů ruší portál
F
7
Obrázek 2.5 Kontextový diagram – terminátor správce portálů
2.2 Model chování 2.2.1 Datový model Datový model definuje neměnné atributy a strukturu dat. Slouží jako základ procesního modelu a také je na jeho základě vytvářena databázová struktura na konkrétní databázové platformě ve fázi implementace navrhovaného systému. Datový model vyjadřuje vztahy, které nejsou zachyceny v procesních modelech a které nesmí být porušeny při transformaci dat jednotlivými procesy. Komponenty datového modelu jsou:
Entita – objekt, o němž uchováváme informace a který je jednoznačně identifikovatelný Entitní množina – množina entit stejného typu Vztah – vztah mezi entitami, který evidujeme a o němž uchováváme informace Vztahová množina – množina vztahů stejného typu Atribut – vlastnost entity nebo vztahu, jejíž hodnotu uchováváme a používáme Doména atributu – obor hodnot atributu
Při tvorbě datového modelu je třeba dbát především na to, aby schéma databáze dodržovalo třetí normální formu (3.NF). Dodržením 3.NF se vyhneme případným anomáliím, které můžou vzniknout při práci s daty. K definici 3.NF slouží 1.NF a 2.NF. První normální forma říká, že domény atributů obsahují pouze atomické prvky. To znamená, že pokud uchováváme v tabulce například adresu osoby, tak jednotlivé části adresy musí být samostatnými atributy v tabulce. Pokud schéma nesplňuje 1.NF, potom je nesnadné nad takto
8
navrženou databází klást dotazy v jazyce SQL. Kdybychom například chtěli vypsat osoby bydlící v konkrétním městě, a celou adresu bychom ukládali jako jeden atribut, bylo by nutné adresu složitě parsovat na jednotlivé údaje. Druhá normální forma je splněna pokud je splněna 1.NF a navíc neexistuje parciální funkční závislost na klíči. Datová položka B záznamu R funkčně závisí na datové položce A z R, pokud v libovolném časovém okamžiku každé hodnotě A odpovídá nejvýše jedna sdružená hodnota B v záznamu R. Říkáme, že položka A identifikuje položku B. Například atribut id_osoby jednoznačně identifikuje atribut věk_osoby. Je tedy vyžadována plná funkční závislost všech neklíčových atributů na celém klíči. Příkladem nesplněné 2.NF je schéma tabulky na obrázku 2.6.
Obrázek 2.6 Příklad nesplněné 2.NF Atribut název_dodavatele je funkčně závislý pouze na části primárního klíče, na atributu dodavatel. Takovéto schéma způsobuje řadu problémů. Mezi největší nedostatky patří fakt, že pokud dodavatel nedodává nějaký materiál, není možné vést si o něm jakékoliv údaje. Další důvod, proč by se měla dodržovat 2.NF, je redundance ukládaných dat. Atribut název_dodavatele se v databázi opakuje s každým záznamem daného dodavatele v tabulce. Správné schéma splňující 2.NF je na obrázku 2.7.
Obrázek 2.7 Příklad splněné 2.NF Třetí normální forma je splněna pokud je splněna 2.NF a zároveň neexistují tranzitivní funkční závislosti.
9
Modelovací nástroj Case Studio umožňuje pohodlně vytvářet z hlavního datového modelu jednotlivé submodely, které znázorňují pouze část systému. Vytváření submodelů usnadňuje orientaci u rozsáhlých projektů. Datový model jsem pro větší přehlednost rozdělil do několika submodelů. Následující části pojednávají o nejdůležitějších částech systému. Celý datový model je na přiloženém CD. Submodel Přístupová práva Na obrázku 2.8 jsou entitní množiny, které slouží ke správě přístupových práv. Entitní množina Osoba obsahuje mimo osobních údajů také atributy potřebné pro autentizaci uživatele. Jedna osoba může mít přístup k více portálům. Entitní množina Nastavení účtů tedy obsahuje atributy potřebné ve fázi autorizace uživatele, to znamená tyto atributy určují, které operace, a na kterém portále, je osoba oprávněna provádět. Takto navrhnuté schéma dovoluje, aby jedna osoba vystupovala jako šéfredaktor u jednoho portálu a jako redaktor u portálu jiného. Oprávnění lze navíc zúžit na jednotlivé kategorie, do kterých jsou řazeny články a aktuality. Entitní množina Práva pro kategorie definuje, ke kterým kategoriím z hierarchie kategorií daného portálu má uživatel přístup.
Obrázek 2.8 Datový model – submodel Přístupová práva Submodel Publikování obsahu Systém publikování článků, aktualit a anket je navržen tak, aby bylo možné obsah vytvořený pro jeden portál sdílet i s ostatními portály. Entitní množina Publikování článků slouží k ukládání informací, kdy je jaký článek publikován na stránkách daného portálu. Podobně je tomu u entitní množiny Publikování anket, kdy jedna anketa může být vystavena na více
10
portálech. Anketa může být také přiřazena ke konkrétnímu článku či aktualitě.
Obrázek 2.9 Datový model – submodel Publikování obsahu O úspěchu článku svědčí mimo jiné i návštěvnost. Entitní množina Návštěvnost uchovává údaje o počtu přístupů k jednotlivým článkům a dovoluje nad takto navrženým schématem klást například následující složitější dotazy:
nejčtenější články od založení portálu nejčtenější články publikované v posledním měsíci nejčtenější články v posledním měsíci (publikované kdykoliv v minulosti) návštěvnost konkrétního článku rozdělená podle portálů, ze kterého čtenář na článek přišel (pokud je článek publikován na více portálech, informace o počtu čtenářů se nekumuluje, ale je k dispozici zvlášť pro každý portál) měsíc v roce, ve kterém portál navštívilo (četlo články) nejvíce čtenářů atd.
Submodel Ankety Schéma umožňující vytvářet a publikovat ankety je vidět na obrázku 2.10. Entitní množina Anketa obsahuje atribut text představující anketní otázku. Ke každé anketě je možné přiřadit
11
libovolný počet možností (entitní množina Volba), mezi kterými má možnost čtenář při odpovědi volit. Jedna anketa může být zveřejněna na více portálech. Entitní množina Publikování anket poskytuje atributy pro řízení způsobu zobrazování ankety na portále. Atribut uzavřená indikuje, zda je anketa již uzavřená a lze pouze prohlížet výsledky nebo je otevřená a na anketu lze reagovat. Pro uchovávání počtu, kolikrát byla daná možnost vybrána, slouží entitní množina Odpověď. Realizuje vazbu mezi entitními množinami Volba a Publikování anket. Takové schéma umožňuje, že ankety vystavené na více portálech lze vyhodnocovat jednak v rámci jednoho portálu tak i kumulovaně pro všechny portály. Nedochází proto ke ztrátě informace, ze kterého portálu bylo na anketní otázku odpovídáno. Příkladem anket, kdy nás zajímá výsledek ankety v rámci jednoho portálu i v kontextu portálů všech, může být otázka „Jak se Vám líbí vzhled těchto stránek?“ nebo „Koho byste volili v následujících volbách?“.
Obrázek 2.10 Datový model – submodel Ankety Submodel Články a aktuality Struktura databázových tabulek uchovávající údaje o článcích je na obrázku 2.11. Článek během svého vzniku prochází několika stavy. Tuto skutečnost zachycuje entitní množina
12
Stav Článku. Definici nového stavu lze kdykoliv přidat a rozšířit tím funkcionalitu aplikace, aniž by se muselo měnit schéma databáze. Každý článek může obsahovat libovolný počet kapitol (entitní množina Kapitola). Samotný text jednotlivých kapitol je uložen v entitní množině Verze kapitoly. To, že ke každé kapitole může existovat více kopií, umožní uchovávat historii změn v textu. Tuto možnost v návrhu lze využít zvláště tehdy, pokud změny provádí někdo jiný než autor článku, například korektor, a je žádoucí, aby se neztratil původní text autora. Z hlediska datových struktur není žádný rozdíl mezi článkem a aktualitou. Proto skutečnost, že se jedná o aktualitu, která je na stránkách portálu zobrazena jinde než články, určuje atribut aktualita entitní množiny Článek.
Obrázek 2.11 Datový model – submodel Články a aktuality
2.2.2 Datový slovník Datový slovník je složen z datových elementů. Znázorňuje základní strukturu dat, které bude systém uchovávat a s kterými bude pracovat. Definice datového elementu zachycuje jednak význam datového elementu v kontextu aplikace a také možné hodnoty, kterých může nabývat. Datový element se může dále skládat z dalších datových elementů. Při tvorbě datového slovníku se používá následující notace: = + () [|]
skládá se z a zároveň nepovinná část (0 nebo 1) výběr jedné z možností
13
{} ** @
iterace (například a = 5{b}10 ) komentář identifikátor (klíč)
datový element portál portál = @id_portálu + informace o portále + {kategorie} + 0{článek} + 0{anketa} + {osoba} id_portálu = přirozené číslo informace o portále = název portálu + popis portálu + datum založení + platný portál název portálu = {přípustný znak} popis portálu = {přípustný znak} datum založení = datum platný portál = enum * značí, zda je portál platný a jde tedy měnit jeho obsah * datový element kategorie kategorie = @id_kategorie + název kategorie + id_nadřazené_kategorie id_kategorie = přirozené číslo název kategorie = {přípustný znak} id_nadřazené_kategorie = přirozené číslo datový element článek článek = @id_článku + id_kategorie + autor + (korektor) + (anketa) + informace o článku + {kapitola} + stav článku + 0{diskuzní příspěvek} id_článku = přirozené číslo autor = osoba korektor = osoba informace o článku = nadpis + (anotace) + (počet hodnotících) + (známka) + aktualita + korektura nadpis = {přípustný znak} anotace = {přípustný znak} počet hodnotících = přirozené číslo známka = přirozené číslo * průměrné hodnocení článku se spočítá podle vzorce známka/počet hodnotících * aktualita = enum * značí, zda jde o aktualitu nebo o obsáhlejší článek * korektura = enum * značí, zda je vyžadována korektura článku * stav článku = @id_stavu + popis stavu id_stavu = přirozené číslo popis stavu = {přípustný znak} datový element kapitola kapitola = @id_kapitoly + nadpis kapitoly + text nadpis kapitoly = {přípustný znak} text = {přípustný znak}
14
datový element diskuzní příspěvek diskuzní příspěvek = @id_diskuzního_příspěvku + přispívatel + nadpis příspěvku + text příspěvku + čas vložení příspěvku + příznak diskuze redaktorů + zobrazit přispívatel = osoba nadpis příspěvku = {přípustný znak} text příspěvku = {přípustný znak} čas vložení příspěvku = čas příznak diskuze redaktorů = enum * diskuze redaktorů je skryta čtenářům * zobrazit = enum * značí, zda je příspěvek zobrazován na stránkách * datový element anketa anketa = @id_ankety + anketní otázka + {možnost} id_ankety = přirozené číslo anketní otázka = {přípustný znak} datový element možnost možnost = @id_možnosti + znění možnosti + počet hlasů znění možnosti = {přípustný znak} počet hlasů = přirozené číslo datový element osoba osoba = @id_osoby + jméno + příjmení + login + heslo + email + icq + web + popis + redaktor + {účet osoby k portálu} + právo spravovat portály id_osoby = přirozené číslo jméno = {přípustný znak} příjmení = {přípustný znak} login = {alfanumerický znak} heslo = {alfanumerický znak} email = {alfanumerický znak} + [@] + {alfanumerický znak} + [.] + 2{písmeno}3 icq = 3{přirozené číslo}3 + [-] + 3{přirozené číslo}3 + [-] + 3{přirozené číslo}3 web = {alfanumerický znak} + [.] + 2{písmeno}3 popis = {přípustný znak} redaktor = enum * značí, zda se jedná o redaktora nebo jde o registrovaného čtenáře * účet osoby k portálu = účet právo spravovat portály = enum * právo pro přidávání, mazání a měnění portálů * datový element účet účet = @id_osoby + @id_portálu + datum vytvoření účtu + platný účet + šéfredaktor + právo vkládat ankety + právo vkládat aktuality + buletin + {právo pro kategorii} datum vytvoření účtu = datum platný účet = enum * značí, zda je účet aktivní a osoba se smí přihlásit k portálu * šéfredaktor = enum * značí, zda je osoba na daném portále šéfredaktorem * právo vkládat ankety = enum * značí, zda má osoba na daném portále právo vkládat ankety *
15
právo vkládat aktuality = enum * značí, zda má osoba na daném portále právo vkládat aktuality * buletin = enum * značí, zda osoba chce dostávat buletin s informacemi o daném portále * právo pro kategorii = @id_kategorie * id kategorie, do které může osoba vkládat články a aktuality * přirozené číslo = [ 0 | [1-9] | [1-9]{0-9} ] písmeno = [ a-z | A-Z ] přípustný znak = [ a-z | A-Z | 0-9 | ' ' ] * libovolný znak, který se může vyskytnout v běžném textu, včetně diakritiky * alfanumerický znak = [ a-z | A-Z | 0-9 ] datum = den + měsíc + rok čas = den + měsíc + rok + hodina + minuta den = [ [1]([0-9]) | [2]([0-9]) | [3]([0-1 ]) ] měsíc = [ [1-9] | 10 | 11 | 12 ] rok = 4{0-9}4 hodina = * hodnoty, kterých může nabývat údaj o hodině v 24hodinovém formátu * minuta = * hodnoty, kterých může nabývat údaj o minutě * enum = [ a | n ] * ano/ne *
2.2.3 Funkční model a minispecifikace Funkční model umožňuje zobrazit systém jako síť procesů, které plní určené funkce a předávají si mezi sebou data. Jde o postupnou dekompozici systému na jednotlivé procesy. Proces představuje část systému, která transformuje určité vstupy na výstupy. Datové toky slouží pro znázornění cest, po kterých se přesouvají data z jedné části systému do druhé. Toky dat by měli být vhodně pojmenované, aby bylo zřejmé, o jaká data se jedná. Další významnou komponentou funkčního modelu je paměť. Paměť je pasivní část systému, která slouží k uchovávání dat. Data jsou z paměti čtena, respektive do paměti zapisována, pouze pokud o to proces explicitně zažádá. Procesy na nejnižší úrovni jsou opatřeny minispecifikací. Minispecifikace popisuje pravidla transformace datových toků, které vstupují do procesu, na výstupní toky. Slouží programátorům jako pomůcka při implementaci systému, ovšem neobsahuje konkrétní algoritmy transformace. Forma minispecifikace je většinou strukturovaná angličtina. Další možností je použít rozhodovací stromy. Na obrázku 2.12 je vidět příklad dekompozice procesu Zobrazení webu. Jednotlivé procesy se starají o zobrazování stránek portálu v závislosti na druhu obsahu. Jedná se o nejnižší úroveň rozkladu funkčního modelu, proto každý proces musí obsahovat minispecifikaci. Výpis 2.1 ukazuje minispecifikaci pro proces Vyhledávání, který realizuje prohledávání publikovaného obsahu podle zadaných klíčových slov a vrací výsledky hledání. Kompletní funkční model včetně všech minispecifikací lze nalézt na přiloženém CD.
16
Výpis 2.1
Minispecifikace procesu 1.2.4 - Vyhledávání
1 FOR EVERY článek DO 1.1 IF článek obsahuje zadaný vyhledávací řetězec THEN 1.1.1 zařaď článek mezi relevantní články 1.2 END IF 2 END FOR 3 FOR EVERY aktualita DO 3.1 IF aktualita obsahuje zadaný vyhledávací řetězec THEN 3.1.1 zařaď aktualitu mezi relevantní aktuality 3.2 END IF 4 END FOR 5 FOR EVERY diskuze DO 5.1 IF diskuze obsahuje zadaný vyhledávací řetězec THEN 5.1.1 zařaď článek, ke kterému diskuze patří, mezi relevantní články 5.2 END IF 6 END FOR 7 zobraz relevantní články a aktuality
Obrázek 2.12 Dekompozice procesu Zobrazení webu
17
Kapitola 3
Implementace systému 3.1 Použité technologie 3.1.1 Skriptovací jazyk PHP Redakční systém byl implementován pomocí webových technologií. Jako programovací jazyk byl zvolen skriptovací jazyk PHP[5], který je spouštěn na straně serveru a zpracovává jednotlivé požadavky. PHP bylo vytvořeno v roce 1994 a v době psaní této práce je hlavní verzí PHP 5, která se od předešlé verze liší novým přepsaným jádrem Zend. PHP 5 bylo díky tomu výrazně vylepšeno, hlavně objektově orientované rysy jazyka byly zdokonaleny. PHP nyní plně podporuje například modifikátory public, private a protected u metod a vlastností, rozhraní, abstraktní třídy a metody, statické metody a vlastnosti a další významné rysy objektově orientovaného programovaní. PHP je Open Source produkt, což znamená, že každý má přístup ke zdrojovému kódu, který může upravovat a dále rozšiřovat. Velkou výhodou je tedy cena, neboť PHP je zadarmo. Dalším významným rysem jazyka PHP je podpora pro mnoho druhů databázových systémů. PHP umožňuje se přímo připojit k databázím MySQL, PostgreSQl, mSQL, Oracle, Informix a k mnoha dalším. Kromě možnosti uchovávat data v relačních databázích nabízí PHP 5 rozhraní SQL k prostému souboru, které se jmenuje SQLite. To umožňuje přistupovat k datům pomocí SQL dotazů, která jsou uložena v obyčejných souborech. O velké oblibě tohoto skriptovacího jazyka svědčí i jeho rozšířenost. Podle údaje uvedeného na stránkách www.php.net/usage je tato platforma používána na 19 miliónech domén. Podrobné informace o PHP může čtenář najít na domovské stránce www.php.net.
3.1.2 Databázový server MySQL Pro uchovávání informací byla použita relační databáze, konkrétně databázový systém MySQL[6]. MySQL je velmi populární databáze, která nachází své uplatnění právě v kombinaci s jazykem PHP u webových aplikacích. MySQL je víceuživatelská a vícevláknová aplikace, která umožňuje přístup zároveň více uživatelům. Používá SQL (Structured Query Language), což je celosvětově používaný standard pro dotazovací jazyk pro databáze. Tato databáze byla odpočátku optimalizována na rychlost, proto nepodporuje některé pokročilejší funkce velkých komerčních databází jako je například Oracle. MySQL má jen jednoduché způsoby zálohování a až donedávna nepodporovala například pohledy, triggery nebo uložené procedury. Současnou hlavní verzí je MySQL 5, která přináší podporu pro kurzory a uložené procedury. MySQL je k dispozici zdarma jako Open Source nebo lze velmi levně zakoupit komerční licenci, která je nutná pokud chceme MySQL distribuovat jako součást vlastní aplikace, kterou ovšem nebudeme šířit pod podmínkami licence GPL. Vyčerpávající informace o MySQL lze získat na domovské stránce www.mysql.com.
18
3.1.3 Webový server Apache Jako webový server posloužil server Apache[7] pro platformu Windows. Server Apache je celosvětově nejrozšířenějším webovým serverem a v současnosti je používán na 69% webových stránkách. Při implementaci redakčního systému byla použita verze Apache 2.2.3. Stejně jako PHP a MySQL je Apache Open Source produkt. Je vyvíjený komunitou Apache Software
Foundation. Informace o tomto produktu lze nalézt na domovské stránce httpd.apache.org. 3.1.4 PhpMyAdmin Pro samotnou správu databáze MySQL jsem použil webové rozhraní PhpMyAdmin[8]. To umožňuje kompletní správu struktury databáze a manipulaci s daty. Databázové tabulky lze vytvořit jednoduchým importem textového souboru s jejich definicí. Nástroj PhpMyAdmin podporuje řadu funkcí, které uživateli zpříjemní práci. Jmenujme například možnost ukládání SQL dotazů nebo vytváření PDF souborů. Díky PDF souborům lze snadno vyexportovat přehlednou mapu databázové struktury. Tato pokročilá funkcionalita ovšem vyžaduje vytvoření pomocné databáze v MySQL, kterou PhpMyAdmin využívá. Kvůli tomu není instalace PhpMyAdmin zcela triviální. Čtenáře proto odkáži na zdroje na internetu1, kde lze najít podrobný návod jak postupovat při instalaci, aby bylo možné využít všech funkcí PhpMyAdmin na maximum.
3.2 Vytvoření databáze Modelovací nástroj Case Studio umožňuje na základě vytvořeného datového modelu vygenerovat skript pro vytvoření databázových tabulek. Díky široké podpoře mnoha databázových systémů lze nastavit parametry potřebné pro generování skriptu pro konkrétní databázový server. Výpis 3.1 ukazuje část vygenerovaného skriptu pro databázi MySQL. Výpis 3.1
Výňatek z create_database.sql – SQL skript pro vytvoření databáze redakčního systému
Create table `PRISPEVEK` ( `PRISPEVEK_ID` Int UNSIGNED NOT NULL AUTO_INCREMENT, `CLANEK_ID` Int UNSIGNED NOT NULL, `OSOBA_ID` Int UNSIGNED NOT NULL, `NADRAZENY_ID` Int UNSIGNED NOT NULL, `NADPIS` Varchar(100), `TEXT` Varchar(1000), `CAS` Timestamp, `DISKUZERED` Enum('a','n'), `ZOBRAZIT` Enum('a','n'), Primary Key (`PRISPEVEK_ID`), Foreign Key (`CLANEK_ID`) references `CLANEK` (`CLANEK_ID`) on delete cascade on update restrict, Foreign Key (`OSOBA_ID`) references `OSOBA` (`OSOBA_ID`) on delete restrict on update restrict, Foreign Key (`NADRAZENY_ID`) references `PRISPEVEK` (`PRISPEVEK_ID`) on delete cascade on update restrict ) ENGINE = MyISAM AUTO_INCREMENT = 1; 1 http://interval.cz/clanky/instalace-phpmyadmin/
19
Příkazy SQL uvedené ve výpisu 3.1 vytvoří tabulku PRISPEVEK, která uchovává jednotlivé příspěvky čtenářů. Primárním klíčem tabulky je atribut PRISPEVEK_ID, který je vytvořen s modifikátorem AUTO_INCREMENT, který zajistí, že databázový stroj při přidání nového záznamu do tabulky vygeneruje nový primární klíč o 1 větší než předchozí hodnota. Důležitou součástí definice nové tabulky je parametr ENGINE. Tento parametr určuje, jaké úložné jádro bude pro novou tabulku použito. Úložné jádro určuje způsob, jakým je tabulka fyzicky implementována. Každá tabulka databáze může používat jiné úložné jádro a mezi jednotlivými jádry lze snadno převádět. Databáze MySQL nabízí následující úložná jádra[3]:
MyISAM – Jedná se o výchozí jádro. Je založené na standardní metodě pro ukládání souborů a záznamů ISAM (Indexed Sequential Access Method). Toto jádro nabízí nejvíce nástrojů pro kontrolu a opravování tabulek. Tabulky MyISAM mohou být komprimovány a podporují fulltextové vyhledávání. Na druhou stranu ovšem nepodporují cizí klíče. MEMORY – Tabulky tohoto typu jsou uloženy v paměti a mají hashované indexy. Díky tomu jsou velmi rychlé, ovšem v případě pádu systému dojde ke ztrátě veškerých dat. Tento typ tabulek je tedy vhodný pro ukládání dočasných dat. V příkazu CREATE TABLE je také vhodné uvést MAX_ROWS, jinak by mohlo dojít ke spotřebování veškeré volné paměti. U těchto tabulek nelze použít sloupce BLOB, TEXT a AUTO_INCREMENT. MERGE – Tyto tabulky umožňují dotazovat sadu tabulek MyISAM, jakoby to byla tabulka jediná. BDB – Tabulky tohoto typu podporují transakce. Díky tomu jsou pomalejší než tabulky typu MyISAM. InnoDB – Tyto tabulky nabízí totéž co tabulky BDB, ovšem navíc podporují i nevlastní klíče a jsou rychlejší.
Při implementaci jsem jako úložné jádro zvolil u většiny tabulek jádro InnoBD. Výjimkou jsou tabulky, které obsahují atribut datového typu TEXT. Tyto tabulky musí umožňovat fulltextové vyhledávání a proto jsem u nich použil úložné jádro MyISAM. Hlavním důvodem, proč jsem zvolil InnoBD, byla možnost definovat nad tabulkami referenční integritu. Referenční integrita umožňuje přenechat řadu kontrol databázovému serveru. Usnadní tak práci programátorovy, který by jinak musel provádět testy, zda jsou data v konzistentním stavu, v rámci samotné aplikace. U každé relace v datovém modelu lze definovat pravidla integrity vztahující se ke změně, přidání nebo rušení záznamu v parent nebo child entitě. Nejvýznamnější je situace, kdy se ruší záznam v parent entitě. V takovém případě lze u relace nastavit následující možnosti:
none – žádné pravidlo restrict - pokud se maže záznam v parent entitě, a v child entitě existují záznamy přiřazené k parent záznamu, příkaz se neprovede cascade - v případě mazání záznamu v parent entitě se vymažou i záznamy v child entitě set NULL - v případě mazání záznamu v parent entitě se cizí klíče v příslušné
20
child entitě nastaví na NULL Z výše uvedených možností jsou nejpoužívanější volby restrict a cascade. Volbu cascade lze použít u relací mezi tabulkami, které představují jeden logický celek. V implementovaném redakčním systému může být takovým celkem například anketa. Ankety jsou ukládány v tabulkách ANKETA, VOLBA, ODPOVEĎ a PUBLIKOVÁNÍ ANKET. Pokud u relací mezi těmito tabulkami zvolíme typ referenční integrity cascade, potom v případě mazání ankety stačí provést SQL příkaz DELETE na tabulce ANKETA. Databázový server automaticky smaže kaskádovitě i ostatní záznamy ve zbylých tabulkách. Naopak volbou restrict zabráníme nežádoucímu smazání dat. Pokud by někdo chtěl například ze systému smazat záznam z tabulky OSOBA, která je již autorem nějakého článku, potom databázový server ohlásí chybu a příkaz se neprovede.
3.3 Proces autentizace a autorizace K redakčnímu systému mají přístup jenom pověřené osoby. Proto je nezbytné implementovat způsob přihlašování uživatelů do systému, který by vyhovoval požadované míře bezpečnosti. Webové technologie umožňují použít několik technik pro řízení přístupu k obsahu stránek. Samotný protokol HTTP nabízí prostředky pro autentizaci uživatelů. Velkým nedostatkem této metody je ovšem fakt, že vyžádané přihlašovací jméno a heslo je přenášeno jako čistý text. Další nevýhodou je to, že protokol HTTP je bezstavový a nelze tedy mezi jednotlivými požadavky uchovávat potřebné proměnné. Proto jsem zvolil řízení sezení. Sezení (session) umožňuje sledovat uživatele během jednoho sezení na webu. Sezení je řízeno jedinečným popisovačem (ID), což jsou zašifrovaná náhodná čísla. Toto ID je po dobu sezení ukládáno u klienta a při každém požadavku je zasíláno na server. Díky tomu jsou skriptům na serveru přístupné proměnné sezení. ID bývá posíláno buď jako soubor cookie nebo jako součást požadované URL. Při používání sezení se provádí následující základní kroky:
Zahájení sezení – provádí se voláním funkce session_start(). Pokud není nějaké sezení již otevřeno, vytvoří nové a zpřístupní superglobální pole $_SESSION, do kterého jsou proměnné sezení ukládány. Tuto funkci je třeba volat v každém skriptu, kde chceme proměnné sezení používat. Registrace proměnných sezení – proměnné se ukládají do pole $_SESSION následujícím způsobem: $_SESSION['nazev_promenne'] = hodnota_promenne;
Zrušení proměnných a zrušení sezení – sezení rušíme v případě, kdy již nejsou potřeba proměnné sezení. Taková situace nastane například pokud si uživatel přeje odhlásit se. Pokud chceme zrušit všechny proměnné sezení, použijeme $_SESSION = array();
Po zrušení proměnných je potřeba ještě zavolat funkci, která zruší sezení a uklidí ID session_destroy();
21
Proces přihlášení je v systému realizován skriptem login.php, který je pomocí příkazu require_once('login.php') vložen na začátek každého skriptu. Celý skript login.php je vidět ve výpisu 3.2. Výpis 3.2
Skript login.php – skript provádí test, zda je uživatel přihlášen
Skript login.php nejprve testuje, zda se uživatel právě přihlásil. V takovém případě jsou pomocí metody POST nastavené proměnné username nebo passwd: if (isset($_POST[username]) || isset($_POST[passwd])) Pokud je tedy podmínka splněna, je volána funkce check_user() s parametrem přihlašovací jméno a heslo, která provádí samotnou autentizaci a autorizaci uživatele. V případě úspěchu přesměruje skript uživatele na požadovanou stránku, v opačném případě zobrazí přihlašovací dialog. Druhá podmínka ve skriptu testuje, zda je již uživatel přihlášen. if (!isset($_SESSION['user_id']) || !$_SESSION['user_id'])
Jestli je uživatel přihlášen lze zjistit podle toho, zda jsou nastavené proměnné sezení identifikující uživatele. V případě, že se uživatel zatím nepřihlásil, je zobrazen přihlašovací dialog. Funkce refresh_accounts() slouží pro obnovení práv z databáze k jednotlivým portálům. Nutnost obnovovat přístupová práva během sezení je dána tím, že práva k jednotlivým portálům mohou být změněna v průběhu sezení a je tedy potřeba zajistit jejich okamžitou aktualizaci. Jinak by uživatel mohl provádět operace, ke kterým už nemá oprávnění, až do doby, dokud se sám neodhlásí.
22
Obrázek 3.1 Editace oprávnění uživatele Samotná funkce check_user() je vidět ve výpisu 3.3. Výpis 3.3
Funkce check_user() – funkce provádějící autentizaci a autorizaci uživatele
function check_user($username, $passwd) { $result = get_auth_info($username, $passwd); if (!$result) { return 0; } if ($result->num_rows == 1) { $user = $result->fetch_assoc(); $result_accounts = get_user_accounts($user['OSOBA_ID']); if ($result_accounts->num_rows==0 and $user['PERM_PORTAL']=='n') { return 0; } $_SESSION['user_id'] = $user['OSOBA_ID']; $_SESSION['user_jmeno'] = $user['JMENO'] .' '. $user['PRIJMENI']; $_SESSION['user_permportal'] = $user['PERM_PORTAL']; $result_last_login = get_last_login_info($user['OSOBA_ID']); if ($result_last_login->num_rows == 1) { $row = $result_last_login->fetch_assoc(); $_SESSION['last_login_time'] = $row['CAS']; $_SESSION['selected_portal'] = $row['POSLEDNI_PORTAL_ID']; } else { $result = get_first_portal($user['OSOBA_ID']); $row = $result->fetch_assoc(); $_SESSION['selected_portal'] = $row['PRVNI_PORTAL_ID']; } if ($result_accounts->num_rows==0 and $user['PERM_PORTAL']=='a') { return 1;
23
} $_SESSION['accounts'] = array(); for ($count = 0;$row = $result_accounts->fetch_assoc();$count++) { $_SESSION['accounts'][$row['PORTAL_ID']]['nazev']=$row['NAZEV']; $_SESSION['accounts'][$row['PORTAL_ID']]['sefredaktor'] = $row['SEFREDAKTOR']; $_SESSION['accounts'][$row['PORTAL_ID']]['perm_anketa'] = $row['PERM_ANKETA']; $_SESSION['accounts'][$row['PORTAL_ID']]['perm_aktualita'] = $row['PERM_AKTUALITA']; } return 1; } else { return 0; } }
Nejprve je volána funkce get_auth_info(), která provádí dotaz nad tabulkou OSOBA. select OSOBA_ID, JMENO, PRIJMENI, PERM_PORTAL from OSOBA where LOGIN ='$username' and HESLO = SHA1('$passwd') and REDAKTOR = 'a';
V případě, že uživatel zadal správné přihlašovací jméno a heslo, je dále prováděna autorizace uživatele funkcí get_user_accounts(). Ta provádí dotaz, pomocí něhož jsou načtena oprávnění k portálům, ke kterým má uživatel přístup. select N.PORTAL_ID,P.NAZEV,N.SEFREDAKTOR,N.PERM_ANKETA, N.PERM_AKTUALITA from NAST_UCTU N, PORTAL P where N.PORTAL_ID = P.PORTAL_ID and N.OSOBA_ID = '$userid' and N.PLATNY= 'a' and P.PLATNY = 'a';
Jednotlivá oprávnění k portálům jsou ukládána do proměnných sezení a uživatel má možnost po úspěšném přihlášení mezi portály pohodlně přepínat. Funkce check_user() dále získává informaci o posledním úspěšném přihlášení uživatele a jeho posledním zvoleném portále, který je implicitně nastaven jako aktivní po přihlášení.
Obrázek 3.2 Snadné přepínání mezi portály
24
Kapitola 4
Ukládání stromových dat v databázích V aplikacích se mnohokrát setkáme s problémem, jak uložit stromovou strukturu do relační databáze. Ať už se jedná o hierarchii výrobků nabízených v internetovém obchodě, diskuzi ke článkům, strukturu zaměstnanců v podniku nebo o kategorie článků, pokaždé je nutné zvolit vhodnou metodu vyhovujícím požadavkům. Je nutné zajistit, aby bylo možné u stromové struktury efektivně provádět operace s uzly, jako například vytvoření uzlu, mazání uzlu nebo získání uzlu. Vhodně použitá struktura pro ukládání stromových dat navíc umožní pomocí dotazů SQL provádět složitější operace, jako například výběr všech podkategorií dané kategorie nebo nalezení cesty od kořene k vybranému uzlu. Tato kapitola popisuje metodu, kterou jsem zvolil pro ukládání kategorií, do kterých jsou řazeny články a aktuality. Možných přístupů je více. Čtenář má možnost se s některými seznámit v článcích publikovaných na serverech www.abclinuxu.cz2 a www.interval.cz3. Traverzování kolem stromu Metoda traverzování kolem stromu doplňuje sebereferenční tabulku o dva pomocné parametry, left a right. Tabulka 4.1 ukazuje příklad dat reprezentujících stromovou strukturu.
ID
NÁZEV
PARENT_ID LEFT RIGHT
1
Operační systémy
0
1
12
2
Unix
1
2
3
3
Linux
1
4
9
4
Windows
1
10
11
5
Red Hat
3
5
6
6
Mandriva
3
7
8
Tabulka 4.1 Příklad dat reprezentujících stromovou strukturu Na obrázku 4.1 je potom vidět strom, který data v tabulce 4.1 reprezentují.
Obrázek 4.1 Stromová struktura včetně ohodnocených atributů LEFT a RIGHT
2 http://www.abclinuxu.cz/clanky/navody/stromy-v-sql 3 http://interval.cz/clanky/metody-ukladani-stromovych-dat-v-relacnich-databazich/
25
Hodnoty atributů LEFT a RIGHT jsou získány procházením stromu do hloubky (DFS – Depht First Search). Ve výpise 4.1 je uveden pseudokód algoritmu, kterým je strom procházen. Výpis 4.1
Algoritmus DFS – průchod stromu do hloubky
DFS(graf) foreach uzly_grafu as uzel do uzel->barva = bila done cas = 0 foreach uzly_grafu as uzel do if uzel->barva = bila DFS-PROJDI(uzel) done end DFS-PROJDI(uzel) uzel->barva = seda cas = cas + 1 uzel->nalezen = cas foreach sousede[uzel] as soused do if soused->barva = bila DFS-PROJDI(soused) done cas = cas + 1 uzel->barva = cerna uzel->opusten = cas
Algoritmus začíná voláním funkce DFS, které je předán zkoumaný graf. Ta nastaví barvu všech uzlů na bílou (uzel dosud nebyl navštíven), seřídí čas a následně prochází uzly grafu s tím, že pokud je uzel bílý, zavolá funkci DFS-PROJDI. DFS-PROJDI přebarví uzel na šedou (byl navštíven, ale dosud se zpracovává), zvedne čas o jedničku a použije jej jako čas navštívení uzlu a poté rekurzivně prochází dosud nenavštívené sousedy uzlu předaného jako parametr. Jakmile jsou všichni sousedé zpracování, přebarví uzel na černou (zpracování dokončeno), nastaví čas opuštění uzlu a vrací se. Čas navštívení a opuštění uzlu se použijí jako hodnoty atributů LEFT resp. RIGHT v SQL tabulce. Nevýhodou této metody je složitější ukládání a změna struktury. Při každé změně je potřeba aplikovat algoritmus DFS na celý strom. Pomocné atributy ovšem umožní značně zefektivnit získávání dat z databáze. Není nutné používat rekurzi a zátěž databázového serveru je výrazně menší. Řadu složitějších dotazů lze provést pomocí jediného příkazu SELECT. Například všechny podkategorie kategorie Linux z příkladu lze získat následujícím SELECTem: SELECT * FROM kategorie WHERE left >= 4 AND right <= 9
Další užitečnou informací je cesta od kořene ke zvolené kategorii. Například cestu pro kategorii Red Hat lze získat následujícím SELECTem: SELECT * FROM kategorie WHERE left <= 5 AND right >= 6
Na obrázku 4.2 je vidět rozhraní pro správu kategorií portálu. Každý portál má při svém
26
založení vytvořenu jednu implicitní kategorii, která slouží jako kořen stromu. Tato kategorie má nastavený atribut NADRAZENA_ID na hodnotu NULL a je pojmenovaná 'Nezařazené články'. Z obrázku 4.2 je patrné, že s touto kategorií nelze nijak manipulovat. Pokud je některá kategorie mazána, potom v případě, že obsahuje články, jsou tyto články přesunuty do této implicitní kategorie.
Obrázek 4.2 Rozhraní pro editaci kategorií portálu Popis zvolené metody včetně uvedeného příkladu ilustrujícího stromovou strukturu byl převzat z článku „Stromy v SQL“ publikovaném 11.1.2006 na portále www.abclinuxu.cz4.
4 http://www.abclinuxu.cz/clanky/navody/stromy-v-sql
27
Kapitola 5
Závěr Tato práce poskytla podrobnou analýzu redakčního systému. Při návrhu datového modelu byl brán zřetel na možné rozšiřování stávající implementace systému o další funkcionalitu. Díky možnosti definovat nové stavy článků lze rozšiřovat možnosti aplikace například o navrhování a schvalování článků nebo systém korektur již hotových článků. Ve fázi implementace bylo dosaženo funkčního a přehledného systému. Současná implementace obsahuje všechny základní funkce, které byly při návrhu systému požadovány. Další možný vývoj aplikace by se mohl zaměřit na správu diskuzních příspěvků, na rozhraní pro nahrávání a správu obrázků nebo rozšířit editaci článků o kontrolu pravopisu. Součástí práce nebylo vytvořit vzhled samotných portálů, ale pouze systém pro tvorbu a správu obsahu. Je tedy možné v budoucnu vytvořit systém pro definování vzhledu jednotlivých portálů.
28
Literatura [1] Demarco, T.: Structured Analysis and System Specification , Prentice Hall PTR, 1979 [2] Gutmans, A., Bakken, S. S., Rethans, D.: Mistrovství v PHP 5. Brno, CP Books a.s., 2005 [3] Welling, L., Thomson, L.: PHP a MySQL Rozvoj webových aplikací. Praha, SoftPress, 2005 [4] Staníček, P.: CSS Kaskádové styly. Brno, CP Books a.s., 2003 [5] Skriptovací jazyk PHP, www.php.net [6] Databázový server MySQL, www.mysql.com [7] Webový server Apache, httpd.apache.org [8] Nástroj pro správu databáze MySQL PhpMyAdmin, www.phpmyadmin.net [9] Szalbot, P.: Stromy v SQL, Dokument dostupný na URL: http://www.abclinuxu.cz/clanky/navody/stromy-v-sql (prosinec 2006) [10] Zelenka, P.: Metody ukládání stromových dat v relačních databázích, Dokument dostupný na URL: http://interval.cz/clanky/metody-ukladani-stromovych-dat-v-relacnich-databazich/ (prosinec 2006)
29