VYSOKÁ ŠKOLA POLYTECHNICKÁ JIHLAVA Katedra technických studií Obor Aplikovaná informatika
Implementace vlastní webové administrace p ro f i r m u bakalářská práce
Autor: Radek Štumbauer Vedoucí práce: Ing. Marek Musil Jihlava 2016
Abstrakt Práce se zabývá implementací vlastní webové prezentace pro firmu včetně administrativního rozhraní zajišťující její pohodlnou správu. Čtenáře seznámí s moderními technologiemi používanými při vývoji webových aplikací, jimiž jsou například PHP framework Symfony, knihovna pro práci s databází Doctrine a nebo šablonovací systém Twig. Dále práce klade důraz na přizpůsobení rozvržení pro mobilní zařízení a také na optimalizaci pro vyhledávače.
Klíčová slova Doctrine, Optimalizace SEO, PHP aplikace, PHP Framework Symfony, Šablonovací systém Twig, Vlastní webová administrace
Abstract Bachelor thesis is focused on implementation of own custom website for the company, including administrative interface ensuring its comfortable management. Readers become familiar with modern technologies used in development of web applications such as PHP framework Symfony, library for working with databases as Doctrine and Templating engine Twig. Further the work puts emphasis on adaptation of the layout for mobile devices, as well as search engine optimization.
Key words Doctrine, Own web administration, PHP application, PHP Framework Symfony, SEO optimization, Templating engine Twig
Prohlašuji, že předložená bakalářská práce je původní a zpracoval jsem ji samostatně. Prohlašuji, že citace použitých pramenů je úplná, že jsem v práci neporušil autorská práva (ve smyslu zákona č. 121/2000 Sb., o právu autorském, o právech souvisejících s právem autorským a o změně některých zákonů, v platném znění, dále též „AZ“). Souhlasím s umístěním bakalářské práce v knihovně VŠPJ a s jejím užitím k výuce nebo k vlastní vnitřní potřebě VŠPJ. Byl jsem seznámen s tím, že na mou bakalářskou práci se plně vztahuje AZ, zejména § 60 (školní dílo). Beru na vědomí, že VŠPJ má právo na uzavření licenční smlouvy o užití mé bakalářské práce a prohlašuji, že s o u h l a s í m s případným užitím mé bakalářské práce (prodej, zapůjčení apod.). Jsem si vědom toho, že užít své bakalářské práce či poskytnout licenci k jejímu využití mohu jen se souhlasem VŠPJ, která má právo ode mne požadovat přiměřený příspěvek na úhradu nákladů, vynaložených vysokou školou na vytvoření díla (až do jejich skutečné výše), z výdělku dosaženého v souvislosti s užitím díla či poskytnutí licence. V Jihlavě dne 25. května 2016
............................................... Podpis
Poděkování Na tomto místě bych rád poděkoval svému vedoucímu bakalářské práce, panu inženýru Marku Musilovi, za jeho ochotu, cenné připomínky, užitečné rady a odbornou pomoc při tvorbě mé bakalářské práce.
Obsah 1
Úvod.......................................................................................................................... 8
2
Současný stav .......................................................................................................... 10
3
Možné způsoby řešení............................................................................................. 11
4
3.1
Webové redakční systémy .............................................................................. 11
3.2
Vlastní webová administrace .......................................................................... 12
Zvolený způsob řešení ............................................................................................ 14 4.1
Rozvržení webové prezentace......................................................................... 14
4.2
Programovací jazyk PHP ................................................................................ 15
4.3
PHP Framework Symfony .............................................................................. 15
4.3.1
Návrhový vzor MVC .............................................................................. 16
4.3.2
Datová struktura ...................................................................................... 17
4.3.3
Bundles ................................................................................................... 18
4.3.4
Formuláře ................................................................................................ 18
4.3.5
Služby ..................................................................................................... 20
4.4
Composer ........................................................................................................ 20
4.5
Databáze .......................................................................................................... 21
4.5.1
Doctrine................................................................................................... 21
4.5.2
Adminer .................................................................................................. 21
4.6
4.6.1
Twitter Bootstrap .................................................................................... 22
4.6.2
Font Awesome ........................................................................................ 23
4.6.3
LESS ....................................................................................................... 23
4.6.4
CKEditor ................................................................................................. 24
4.7
5
Rozvržení aplikace .......................................................................................... 22
Vývojové prostředí.......................................................................................... 25
4.7.1
Vagrant.................................................................................................... 25
4.7.2
PhpStorm ................................................................................................ 25
4.8
Systém pro správu verzí GIT .......................................................................... 26
4.9
YUI Compressor ............................................................................................. 26
Postup řešení ........................................................................................................... 28 5.1
Příprava vývojového prostředí ........................................................................ 28
5.1.1
Virtuální operační systém ....................................................................... 28
5.1.2
Nastavení vývojového prostředí aplikace ............................................... 29
5.2
Databázová struktura ...................................................................................... 29
5.2.1
Analýza požadavků a popis jednotlivých tabulek ................................... 30
5.2.2
ER diagram ............................................................................................. 31
5.2.3
Implementace databáze ........................................................................... 32
5.2.4
Výchozí data ........................................................................................... 33
5.3
Ověřování uživatele ........................................................................................ 33
5.3.1
Uživatelské role ...................................................................................... 33
5.3.2
Implementace .......................................................................................... 33
5.4
Vývoj administrátorské sekce ......................................................................... 34
5.4.1
Práce s obrázky ....................................................................................... 34
5.4.2
Asynchronní ovládání aplikace ............................................................... 35
5.4.3
Služby ..................................................................................................... 36
5.5
Vývoj sekce přístupné běžným návštěvníkům ................................................ 36
5.5.1
Navigace ................................................................................................. 36
5.5.2
Úvodní prezentace .................................................................................. 36
5.5.3
Stránka s produkty .................................................................................. 37
5.6
Optimalizace SEO pro vyhledávače ............................................................... 37
6
Aktualizace frameworku Symfony ......................................................................... 38
7
Testování a závěrečné kroky ................................................................................... 39
8
7.1
Testy................................................................................................................ 39
7.2
Vypuštění na produkční server ....................................................................... 40
Závěr ....................................................................................................................... 42 8.1
Splnění cílů ..................................................................................................... 42
8.2
Problémy a jejich řešení .................................................................................. 42
8.3
Návrhy na další vývoj aplikace ....................................................................... 43
Seznam použité literatury ............................................................................................... 44 Seznam obrázků .............................................................................................................. 46 Seznam použitých zkratek .............................................................................................. 47 Přílohy ............................................................................................................................. 48 1
Obsah přiloženého CD ............................................................................................ 48
2
Uživatelská příručka ............................................................................................... 49 2.1
Prezentace ....................................................................................................... 49
2.2
Uživatelé ......................................................................................................... 49
2.3
Produkty .......................................................................................................... 50
2.4
Stránky s produkty .......................................................................................... 50
2.5
Blog ................................................................................................................. 50
2.6
Navigace ......................................................................................................... 51
1 Úvod Vzhledem k dnešní době je již prakticky nezbytné, aby měla firma svou vlastní webovou stránku, kde prezentuje sebe, svou činnost či své produkty. Správa takovýchto stránek není ovšem vůbec jednoduchá, pokud nejsou postavené na nějakém webovém redakčním systému jako je například WordPress nebo Joomla. Webové redakční systémy obecně umí spoustu věcí, ale jsou nejvhodnější pro webové stránky, které mají pouze pár podstránek bez dynamického obsahu a není potřeba je často upravovat. Další možností pro snadnou správu obsahu webových stránek je naprogramování vlastního administrátorského rozhraní pro ovládání webu. To je ale mnohonásobně nákladnější a pracnější než vytvoření statického webu nebo webu s použitím redakčního systému. Firma TopStein, s. r. o. se zabývá poradenstvím, prodejem různorodých kamenných obkladů, desek, dlažeb a také zprostředkovává služby pokrývání, zastřešování či samostatný prodej výrobků z kamene. V současnosti má firma velmi zastaralou a již nevyhovující webovou prezentaci, která dostatečně firmu nereprezentuje. Potýká se s problémy u návštěvníků při zobrazování webu na mobilním zařízení a s komplikovanou i nepohodlnou administrací webu. Do kontaktu se společností jsem přišel poprvé před rokem. Tehdy mě oslovil webový designer, který je také synem majitele společnosti, zda bych se nechtěl podílet na realizaci tohoto projektu. Nejprve bylo nutné, aby tento webový designer vytvořil vzhled webové prezentace, podle kterého jsem poté mohl začít pracovat na implementaci nového designu a tvorbě administrační části webu. Cílem mé bakalářské práce je připravit administrátorské rozhraní webových stránek společnosti TopStein a implementovat nový moderní vzhled webu, navržený designérem, včetně optimalizace SEO pro vyhledávače a podpory přizpůsobeného zobrazení na jednotlivých zařízeních od mobilních telefonů přes tablety až po počítače. Realizaci takovéhoto webu dle požadavků na aplikaci lze provést hned několika způsoby. Tyto způsoby jsou společně s analýzou současného stavu blíže popsány v kapitole Současný stav.
8
Toto téma bakalářské práce jsem si zvolil z toho důvodu, že je mi vývoj webových stránek velmi blízký a zabývám se jím již několik let. S vývojem webových aplikací prakticky začalo mé první programování a toto nadšení mi vydrželo až do současnosti.
Obrázek 1: Administrační část aplikace
9
2 Současný stav V této kapitole je zhodnocen stav stávající webového systému používaný ve firmě. Společnost má v současné době dynamicky generované webové stránky, jejichž design i údržba je na dnešní dobu již nevyhovující. Stránky jsou poháněné python frameworkem Django, který ale běží na virtuálním serveru, protože jej webhostingové společnosti nepodporují. Naprogramováním aplikace v PHP a přesunutím na klasický webhosting se až 12 krát sníží náklady na provoz webu nemluvě o nákladech na údržbu. Optimalizace SEO pro vyhledávače se v současné chvíli podle online validátoru SEO-Servis nachází na 75 procentech, mým cílem je dosáhnout maximální hodnoty tohoto ukazatele. [1] Dostupnost responzivního zobrazení pro mobilní telefony je v současné době nedostupná, takže se web nezobrazuje přehledně na menších zařízeních, a proto jej i vyhledávací nástroj Google neupřednostňuje při vyhledávání na mobilních zařízeních. [2] Na trhu samozřejmě existuje již několik řešení. Jedním z nejvhodnějších je řešení společnosti Webaster CZ, s. r. o., které pokrývá většinu mých nároků vyplývajících z požadavků cílové společnosti. Je zde ale nutnost zavázat se k používání pouze této služby, kde si nelze přizpůsobit vzhled dle vlastních požadavků a náklady na provoz jsou mnohonásobně vyšší než u mého řešení. Služba navíc zahrnuje spoustu komponent, které bychom ke tvorbě a provozování webu vůbec nevyužili a také nemá podporu responzivního nebo mobilního zobrazení, které je jedním z hlavních požadavků cílové společnosti. [3]
10
3 Možné způsoby řešení V této kapitole jsou popsány možné způsoby řešení administrace webu. Jako možná řešení se nám nabízí hned několik možností, které je potřeba detailně prozkoumat a vybrat z nich to nejvhodnější, které bude pokrývat všechny požadavky a také zajistí plynulý a bezpečný chod aplikace.
3.1 Webové redakční systémy Pro účely této práce je nejprve nutné objasnit, co jsou to redakční systémy. Jedná se o systémy, které jsou určeny pro snadnou správu, uchovávání a vyhledávání elektronických médií. Většinou jsou používány pro publikování článků, brožur a dalších druhů textu. V anglickém jazyce se pro ně ustálil název Content Management System (CMS) anebo Document Management System (DMS). [4]
Obrázek 2: Ukázka administrace Wordpressu
V tomto případě nás zajímají pouze webové redakční systémy, což jsou webové aplikace umožňující jednoduchou správu internetového obsahu na základě uživatelských práv. Jsou jimi například Joomla, Drupal nebo nejvíce oblíbený a nejčastěji používaný WordPress. Všechny výše vyjmenované redakční systémy jsou pod Open Source licencí 11
GNU General Public License a jsou naprogramované v PHP s daty ukládanými implicitně do databáze MySQL. [5]
Obrázek 3: Loga vybraných redakčních systémů
Následuje posouzení z hlediska potencionálního využití a z hlediska bezpečnosti systému. Přestože tyto systémy nám pokrývají většinu požadavků na aplikaci, mají i řadu podstatných nevýhod. Při porovnání možností redakčních systémů s požadovanou funkčností webové prezentace zjistíme následující. Ze systému se použijí pouze základní vlastnosti a většina komponent bude muset být pro naše účely doprogramována. Co se oblasti bezpečnosti týče, jsou tyto systémy náchylné na napadení například instalací trojského koně v podobě zásuvného modulu nebo modulu s neošetřenými vstupy. V našem případě budou systém používat zaměstnanci firmy, kteří nic netuší o možném napadení. Z tohoto důvodu je výše zmíněné řešení prakticky nepoužitelné.
3.2 Vlastní webová administrace Dalším řešením je vytvoření vlastní aplikace webové administrace. Přestože toto řešení je z hlediska implementace časově náročné a finančně nákladné, finální aplikace bude vyhovovat potřebám cílové společnosti.1 Pro vývoj vlastní webové aplikace je potřeba se důkladně zamyslet nad tím, jakou cestou se vydáme. Jedna z možností, která se nám nabízí je naprogramovat si aplikaci úplně od základů. Na jednu stranu má toto řešení obrovskou výhodu v rychlosti výsledné aplikace, ovšem na stranu druhou, vývoj takovéto aplikace zabere spoustu času, je nepřehledný a pokračování v dalším vývoji aplikace jiným programátorem je z počátku velmi pomalé a obtížné.
1
Řešení šité na míru. 12
Jednou z dalších nevýhod je také bezpečnost, jelikož veškeré vstupy musíme pečlivě ošetřovat a je jen otázkou času, kdy na nějaký zapomeneme. Pokud ale chceme rychlou a z hlediska zdrojového kódu i přehlednou aplikaci, můžeme jí napsat pod křídly frameworku Phalcon. Tento framework je vyvinut v programovacím jazyce C jako zásuvný modul pro PHP, z tohoto důvodu je oproti ostatním řešením velmi rychlý. Má ale také jednu velkou nevýhodu a tou je absence dostupnosti u poskytovatelů webhostingových služeb. To znamená, že jej můžeme provozovat ve většině případech pouze na vlastním serveru, což nám úplně nevyhovuje. [6] Posledním řešením je použití jednoho z dostupných PHP frameworků, jimiž jsou například Zend, Nette nebo Symfony. Všechny PHP frameworky mají své výhody i nevýhody, většinou jsou ale srovnávány podle popularity nebo podle jejich rychlosti. Takovéto řešení nám vývoj aplikace velmi urychlí a zároveň bude také vhodné pro použití na jakémkoliv webhostingu.
13
4 Zvolený způsob řešení V této kapitole se dozvíme, jaké řešení jsme zvolili a jaké technologie budou k realizaci použity. Jak již bylo zmíněno v předchozí kapitole, použití redakčních systémů už jenom z důvodu bezpečnosti není vhodné, proto jsem si zvolil variantu vývoje vlastní webové administrace. Pro řešení tohoto problému jsem si vybral programovací jazyk PHP a jeho nadstavbu v podobě frameworku Symfony. O generování a následné zobrazování HTML kódu se postará integrovaná šablonovací komponenta frameworku Symfony, kterou je Twig. Práci s databází MySQL nám usnadní knihovna Doctrine a také nástroj pro procházení dat v databázi Adminer. Responzivitu webových stránek budu řešit pomocí frameworku Twitter Bootstrap. V administraci také použiji sadu ikonek z balíčku Font Awesome. Programovací jazyk PHP jsem si zvolil z důvodu jeho podpory u všech poskytovatelů webhostingových služeb, a také, protože je to nejpopulárnější jazyk spojovaný s vývojem webových aplikací. Důvod volby frameworku Symfony bude objasněn v podkapitole o PHP frameworku Symfony. Doctrine nám umožní pohodlné mapování objektů nad relační databází MySQL a ochrání web a jeho data vůči útokům typu SQL injection. Framework Twitter Bootstrap jsem zvolil pro pohodlné implementování responzivního zobrazení. Důvodem volby ikonek balíčku Font Awesome je jejich snadná implementace a použití.
4.1 Rozvržení webové prezentace Rozvržení webové prezentace navrhneme tak, aby se automaticky přeuspořádalo podle velikost zařízení, na kterém je tato stránka prohlížena. Tímto docílíme snadné čitelnosti především na mobilních zařízeních, které se v současnosti více používají a tedy i upřednostňují před ostatními. Dříve se zobrazování na mobilních zařízeních provádělo oddělenými stránkami speciálně pro mobilní zařízení, což bylo mnohonásobě pracnější a při změně se musely aktualizovat obě tyto stránky. Dnes jsme takovéhoto řešení ušetřeni, jelikož jsou dostupné technologie, jimiž je především CSS3, které se o toto postarají a to bez jakékoliv aktualizace obsahu webové prezentace. Jednotlivé bloky kaskádových stylů se použijí podle velikost zobrazení a tím pádem můžeme například 14
i skrýt nějakou část webu pouze na určitém zařízení. Aby byl vývoj takového responzivního designu ještě pohodlnější, byl vyvinut CSS framework Twitter Bootstrap, který nám vývoj takovéto aplikace dost usnadní. Zmiňovaný CSS framework obsahuje předdefinované třídy a metody, které můžeme používat přímo při psaní HTML kódu a nemusíme se tím tedy zaobírat více do hloubky.
4.2 Programovací jazyk PHP PHP, zkratka z anglického výrazu Hypertext Preprocessor původně Personal Home Page, je programovací jazyk určený a vytvořený především pro vývoj dynamicky generovaných webových aplikací. Na rozdíl od značkovacího jazyka HTML nebo skriptovacího jazyka JavaScript probíhá zpracování klientova požadavku na straně serveru, ten jej vyhodnotí a vygeneruje data převážně ve formátu HTML, která obratem odešle dotazovanému klientovi ke konečnému zpracování a následnému zobrazení v cílovém webovém prohlížeči. Zajímavostí oproti ostatním programovacím jazykům je to, že není potřeba definovat datový typ proměnné, ten se přiřadí dynamicky v průběhu překládání a lze tento typ v průběhu procesu libovolně měnit. Také není potřeba řešit problémy s alokováním paměti, ta je přidělována automaticky. Zdrojový kód není potřeba kompilovat do strojového kódu, sestavuje se vždy až po jeho spuštění interpretem PHP. Jednou z hlavních výhod jazyka PHP oproti ostatním programovacím jazykům webových aplikací je podpora téměř všech známých operačních systémů používaných pro provozování serverových aplikací. [7]
4.3 PHP Framework Symfony Dnes již existuje mnoho populárních PHP frameworků. Mezi nejznámější a často používané patří Zend, Nette nebo Symfony Ty usměrňují vývojáře k dodržování základních pravidel správně napsané aplikace, zvyšují přehlednost kódu a chrání aplikaci před napadením. Zvolit si, jaký framework použít pro tento případ, nebylo vůbec těžkým úkolem. Zend Framework jsem vyřadil hned na začátku, protože s ním nemám žádné zkušenosti. Dalším důvodem byly negativní recenze a články, na které jsem narazil, než jsem začal tyto frameworky používat. S českým frameworkem Nette jsem začínal, ještě než jsem objevil Symfony, a naprogramoval v něm jednu aplikaci. Vývoj byl velmi rychlý a pohodlný až do toho okamžiku, než jsem potřeboval udělat nějakou funkcionalitu 15
trochu jiným způsobem. Řešení mého problému mi v Nette zabralo spoustu času, a proto se i trochu změnil můj názor na tento framework. S frameworkem Symfony jsem se poté setkal náhodou při mé praxi a byl jsem jím mile překvapen, proto jsem si jej také vybral pro realizaci této aplikace. Symfony, původně Sensio Framework, je celosvětově populární MVC PHP Framework. Velkou výhodou tohoto frameworku je obrovská komunita vývojářů, kteří do něj přispívají svými nápady a společnými silami ho vylepšují. V současné době existuje nesmírné množství aplikací postavených právě na tomto frameworku. Jsou jimi například webové aplikace již zmiňovaných redakčních systémů Drupal a Joomla nebo také velmi populární hudební služba Spotify. [8] Framework byl vyvinut a je stále sponzorován společností Sensio Labs, sídlící v Paříži, pod open-source licencí MIT. [9]
4.3.1 Návrhový vzor MVC Symfony praktikuje velmi oblíbený návrhový vzor, nebo spíše agregační vzor, který rozděluje aplikaci do tří vrstev - Model, View a Controller. Model obsahuje data, potřebná pro vygenerování uživatelského rozhraní. View, neboli uživatelské rozhraní, je vlastně jedinou částí, která se uživateli zobrazí. Je to grafické zobrazení informací z datového modelu. Poslední část nazývající se Controller, do češtiny bychom její název přeložili jako řadič, je řídící vrstva, která obsahuje hlavní logiku celé aplikace. Do této vrstvy uživatel zasílá své požadavky, na základě nichž upravuje datový model a ten je na závěr odeslán vrstvě View, která jej zobrazí. [10]
Obrázek 4: Návrhový vzor MVC
16
4.3.2 Datová struktura Pro každý framework je specifická datová struktura, kterou je do jisté míry možno upravovat, ale je vhodné se jí řídit. Symfony ve své nejnovější stabilní verzi, kterou je v současnosti verze 3.0.6, používá strukturu známou pro Unixové operační systému. V kořenové složce projektu proto můžeme najít adresáře s názvem bin nebo var. Kořenová složka projektu Symfony app/ – nastavení aplikace, šablony a překlady conifg/ – hlavní složka s nastavení projektu resources/ – šablony, soubory dostupné z webu a překlady console – konzolový nástroj Symfony projektu bin/ – spustitelné nástroje console – konzolový nástroj Symfony projektu src/ – zdrojové soubory projektu tests/ – testy aplikace var/ – logy a dočasné soubory cache/ – pomocné soubory pro zrychlení aplikace log/ – soubory s chybami aplikace vendor/ – pomocné knihovny web/ – soubory veřejné z webu bundles/ – veřejné soubory z jednotlivých částí aplikace app.php – startovací soubor aplikace produkčního prostředí app_dev.php – startovací soubor aplikace pro vývojové prostředí composer.json - soubor Composeru obsahující seznam potřebných knihoven phpunit.xml.dist – soubor s definováním a nastavením testů aplikace 17
4.3.3 Bundles Adresář src poté obsahuje do jisté míry oddělené části aplikace, které se nazývají Bundles. Pro vytvoření této části se dá požít konzolový nástroj frameworku Symfony, nebo jej můžeme vytvořit ručně. Každá tato část má opět danou strukturu, kterou je vhodné dodržet. AppBundle/ – kořenová složka části aplikace s názvem App Controller/ – části ovládající jednotlivé stránky z návrhového vzoru MVC Entity/ – třídy symbolizující jednotlivé tabulky v databázi Form/ – formulářové typy Resources/ – zdroje specifické pro bundle config/ – nastavení nadřazené hlavnímu nastavení aplikace views/ – šablony knihovny Twig pro generování obsahu translations/ – soubory s překlady aplikace Utils/ – služby
4.3.4 Formuláře Jednou z hlavních výhod frameworku je tvorba a obsluha formulářů, s čímž je v čistém PHP celkem dost práce. Proto nám Symfony nabízí velmi silný nástroj, který nám nejen tuto práci ulehčí, ale také chrání aplikaci před různými druhy útoků. Formuláře můžeme vytvářet dvěma různými způsoby. Prvním je vytvoření formuláře přímo v řadiči a tím druhým je vytvoření třídy formulářového typu, který pak můžeme použít i v jiné části aplikace. Vytvořený formulářový typ je možno do sebe vnořovat a kombinovat. Například máme základní nastavení produktu a chceme k němu přidat rozšiřující parametry, které jsou odlišné v závislosti na typu produktu, vytvoříme si tedy vlastní formulářový typ sjednocující tyto dva formuláře. V budoucnosti, když budeme potřebovat něco pozměnit, upravíme požadovanou část formuláře a změny se projeví v celém projektu.
18
Při vytváření formuláře, až ve výjimečných případech, nepracujeme vůbec s HTML kódem, vše se generuje automaticky, jak je možné vidět na následující ukázce. class SlideShowForm extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('title', TextType::class); $builder->add('description', TextareaType::class); $builder->add('file', FileType::class, ['label'=>'Image']); } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => 'TopStein\ApiBundle\Entity\GalleryImage']); } }
Vytvořili jsme tedy formulářový typ o třech polích, prvním je titulek ve formě klasického textového pole, druhý je popis, ten je typu víceřádkového textového pole a posledním je prvek typu file sloužící pro nahrávání souborů. Funkce configureOptions() specifikuje jaká třída se má použít pro validaci uživatelských vstupů a slouží zároveň jako datový model, v našem případě jím je entita GalleryImage. Následuje ukázka anotace zajišťující validaci hesla. Říká nám, že heslo nesmí být prázdné a zároveň musí být dlouhé minimálně pět znaků, jinak formulář vypíše chybu specifikovanou v atributu message. /** * @Assert\NotBlank() * @Assert\Length( * min = 5, * minMessage = "Password must be at least {{ limit }} characters long." * ) */ private $plainPassword;
Nyní je potřeba formulář inicializovat v příslušném řadiči aplikace a popřípadě do něj nahrát třídu s vyplněnými daty pro získání předvyplněného formuláře. public function iAction() { $slide = new GalleryImage(); $slideShowForm = $this->createForm(SlideShowForm::class, $slide); $slideShowForm->add("Submit", SubmitType::class); $slideShowForm->handleRequest($request); if($slideShowForm->isValid()) { // Kód, který se provede při správně vyplňeném formuláři } return $this->render( 'AppBundle:SlideShow:slideshow.html.twig', ['slide_show_form' => $slideShowForm->createView(),] ); }
19
Nakonec formulář vykreslíme v šabloně pomocí funkce form a vzhledem k tomu, že máme nastavená vykreslovací pravidla formátovaná pomocí knihovny Twitter Bootstrap, budou formuláře i pěkně vypadat. {{ form(slide_show_form) }}
4.3.5 Služby Služby jsou také jednou z důležitých schopností frameworku Symfony, o které je potřeba se zmínit. Z názvu plyne, že to budou pravděpodobně programy, běžící na pozadí aplikace, které můžeme používat kdykoli se nám zamane. Není tomu úplně tak, ale také nejsme daleko od pravdy. Jsou to vlastně instance objektů, které lze používat kdykoliv během procesu a díky technice vkládání závislostí, neboli Dependency Injection, dostanou vždy instance objektů potřebných pro jejich správnou funkčnost. Službu vytvoříme registrací v konfiguračním souboru services.yml, kde uvedeme její název, třídu a potřebné závislosti, která vypadá například následovně. image_tools: class: TopStein\AppBundle\Utils\ImageUtility arguments: ["@doctrine.orm.entity_manager", "@service_container"]
Prvním řádkem definujeme název služby, pod kterým bude dostupná například v řadiči nebo v kontejneru uchovávající instance služeb. Zavináč u argumentů značí jinou existující službu, můžeme tedy své vlastní služby vnořovat do sebe. Instanci objektu dostaneme v řadiči pomocí rodičovské funkce get() a následně můžeme používat všechny veřejné metody, které má třída definované.
4.4 Composer Composer je nástroj určený pro vývoj PHP aplikací s cílem co nejvíce zjednodušit práci s knihovnami třetích stran. Program Composer je tedy balíčkový manažer, napsaný v jazyce PHP, který spravuje balíčky neboli knihovny používané v projektu. Tyto knihovny jsou automaticky stahované z GIT repozitářů služby GitHub, tudíž je velmi jednoduše dostupná aktualizace těchto balíčků, nebo je tu také možnost vrátit se ke starší verzi. Stažené balíčky jsou implicitně ukládané v kořenové složce projektu do adresáře vendor a informace o nich jsou poté uchovávány v souboru, umístěném v kořenu projektu, nesoucím název composer.lock. Seznam všech balíčků včetně specifikovaných 20
verzí je poté uchováván v souboru composer.json. Ve spojení s PHP frameworkem Symfony tvoří silný a téměř nezbytný nástroj pro vývoj aplikací. Composer není ani prvním a určitě nebude ani posledním balíčkovým manažerem. Existuje již několik balíčkových manažerů, jimiž jsou například NPM, velmi známý pro javascriptové knihovny (z anglického jazyka Node Package Manager), anebo Bundler pro správu balíčků projektů v jazyce Ruby.
4.5 Databáze Jako datové uložiště jsem z hlediska dostupnosti a také rychlosti zvolil databázi MySQL, která je také nejpoužívanější ve spojení s webovými aplikacemi. Je to klasická relační databáze, která nám poskytuje data na základě správně formulovaného SQL dotazu. Tyto data jsou uchovávána v tabulce, kde sloupce definují datový typ informace a v řádcích je poté uchované prakticky neomezené množství dat.
4.5.1 Doctrine Ve spojením s databází MySQL použiji jako její nadstavbu PHP knihovnu Doctrine, která mi umožní na základě anotací v PHP pracovat s tabulkami jako s objekty, což mi usnadní práci především při psaní SQL dotazů a získáváním dat spojených přes více tabulek najednou. Knihovna navíc vygenerované dotazy optimalizuje a uchovává je v paměti pro další použití, proto toto rozšíření nezpomalí aplikaci při práci s databází, ba naopak, v případě špatně optimalizovaných dotazů jí může i zrychlit. Knihovna nám samozřejmě umožní i psaní vlastních dotazů a při správném zacházení nás také chrání před útoky specializovanými na databázové dotazy.
4.5.2 Adminer Pro správu a kontrolu databáze použijeme velmi populární nástroj Adminer od dobře známého vývojáře Jakuba Vrány, který mimo jiné spolupracuje také na vývoji frameworku Nette. Adminer má oproti phpMyAdmin celou řadu vylepšení a je známý svou rychlostí, přehledným uživatelský rozhraním, bezpečností a podporou mnoha typů databázových serverů. Jeho instalace je také velmi intuitivní, protože celý program je obsažen pouze v jednom PHP souboru. [11] 21
Obrázek 5: Logo nástroje Adminer
4.6 Rozvržení aplikace Design aplikace budeme tvořit podle návrhu a od začátku responzivně, respektující pravidlo mobile-first. Toto pravidlo nám přikazuje programovat nejprve pro mobilní zařízení a poté aplikaci rozšiřovat pro zařízení ostatní. V praxi to tedy znamená, že hlavní styly budou pro zobrazení na mobilním zařízení a poté se tyto styly budou upravovat podle media bloků v CSS stylech, které se použijí podle velikosti obrazovky zobrazovaného zařízení.
4.6.1 Twitter Bootstrap Na základní rozvržení aplikace použiji populární HTML, CSS a JS Framework Twitter Bootstrap. Tento framework má předdefinované funkce a třídy, které nám pomáhají vytvořit responzivní design aplikace. Framework rozděluje web do 12ti dílků, aby se tedy vše zobrazilo v jednom řádku, musíme specifikovat délku tak, aby nám dohromady dávala číslo 12. Tyto velikosti se dají nastavit pro každé zařízení jiné, což nám zajišťuje právě tu zmiňovanou responzivitu. Implicitně je pro mobilní zařízení nastavena velikost dílku na 12, aby byl každý blok přes celý řádek, tedy 100% šířky.
Obrázek 6: Ukázka dělení webu pomocí Twitter Bootstrap
22
Twitter Bootstrap nám mimo jiné rozšiřuje aplikaci o další užitečné komponenty, jimiž jsou například rozbalovací nabídky, různorodé ukazatele průběhu či vylepšené tabulky a formulářové prvky.
Obrázek 7: Ukázka vybraných komponent Twitter Bootstrap
4.6.2 Font Awesome Tento balíček ikonek založených na CSS a LESS původně vznikl v souvislosti s používáním ve frameworku Twitter Boostrap. Je to vlastně druh písma složený pouze z vektorových obrázků, které lze jednotlivě používat v kódu uvedením ve třídě HTML elementu.
4.6.3 LESS LESS je pomocný nástroj pro tvorbu CSS stylů. Oproti klasickému CSS nám umožňuje používat proměnné, vlastní funkce nebo umožňuje vnořování kódu do sebe. Funkce, neboli mixiny, nám pomáhají odstranit duplicitní nebo opakující se kód, který je potřebný především pro správné zobrazení ve všech moderních prohlížečích, protože každý má své speciální argumenty. Jako ukázku tu máme funkci na zaoblené okraje s výchozí hodnotou 5 pixelů. .border-radius (@radius: 5px) { -webkit-border-radius: @radius; -moz-border-radius: @radius; border-radius: @radius; }
Vytvořenou funkci poté zavoláme v jakémkoliv bloku, jako je tomu na následujícím příkladu. 23
#roundedImage { .border-radius(10px); &.hidden { display: none; } }
Ampersandem říkáme kompilátoru, že má použít selektor rodiče. Toto se hodí například u odkazů, kdy potřebujeme specifikovat chování po najetí ukazatelem myši a nechceme uvádět znovu selektory vybraného elementu. Po zpracování kódu LESS kompilátorem bude výsledný CSS styl vypadat následovně. #roundedImage { -webkit-border-radius: 10px; -moz-border-radius: 10px; border-radius:10px; } #roundedImage.hidden { display: none; }
Pro sestavení LESS kódu bude potřeba ještě doinstalovat knihovnu, která se o to postará. Existuje hned několik řešení v různých programovacích jazycích, například v JavaScriptu, Javě, nebo i v PHP. Naše aplikace je naprogramovaná v PHP, proto použijeme knihovnu vytvořenou ve stejném jazyce. Jednou z nabízených je knihovna LessPHP.
4.6.4 CKEditor Příjemné vkládání HTML obsahu na web nám zajistí WYSIWYG editor pojmenovaný CKEditor. Použití bude mít například u produktových stránek nebo u blogu. Umožní tak uživatelům vkládat formátovaný text bez znalosti jazyka HTML. CKEditor je jeden z mála použitelných editorů generující validní HTML kód a v základní verzi je zcela zdarma.
Obrázek 8: Ukázka WYSIWYG editoru CKEditor
24
4.7 Vývojové prostředí Pro samotný vývoj budu potřebovat dva druhy vývojového prostředí. Prvním je prostředí pro běh aplikace a tím druhým je editor. Prostředí pro běh aplikace nám zajistí možnost testovat aplikaci na vlastním zařízení i bez dostupnosti internetového připojení. Editor nám naopak usnadní a urychlí vývoj výsledné aplikace.
4.7.1 Vagrant Vagrant je konzolový nástroj pro ovládání programů zprostředkovávajících virtualizaci operačních systémů, jimiž jsou například VMWare, VirtualBox nebo KVM. Program umí také nastavit virtualizační program podle vlastního konfiguračního souboru. Toto nám umožní například pohodlné nastavování síťové karty nebo sdílení lokálních souborů do kořenové složky virtuálního systému. Jednou z dalších funkcionalit je také možnost, publikovat svůj nastavený virtuální systém nebo jej stáhnout z již nasdílených. Tímto nám tedy odpadá stahování obrazu operačního systému a jeho následná instalace. Stačí si vybrat distribuci, nastavit konfigurační soubor a virtuální stroj se stáhne a potřebně nastaví, proto je tato služba vhodná pro projekty v týmu, jelikož se nastaví jeden virtuální systém a ten se nasdílí. Konfigurační soubor se nahraje do GIT repozitáře a vyvíjenou aplikaci poté spustí každý uživatel, bez složité konfigurace vývojového prostředí a bez ohledu na operační systém na svém počítači jedním příkazem.
4.7.2 PhpStorm Pro vývoj aplikace bych mohl použít klasický poznámkový blok, nebo jakýkoliv jiný textový editor, ovšem vzhledem k tomu, že by byl vývoj velmi zdlouhavý a museli bychom si pamatovat každou funkci frameworku Symfony, budu vyvíjet pod křídly multiplatformního editoru PhpStorm.
Obrázek 9: Současné logo editoru PhpStorm
25
Editor lze rozšiřovat o různé zásuvné moduly, které nám vývoj ještě zpříjemní. Jedním z nejdůležitějších, který používám, je modul pro Symfony, který mimo jiné obsahuje i různé šablony, například pro vytváření formulářových typů nebo řadičů. Kromě základní funkce napovídání, kterou umí prakticky každý editor specializovaný na určitý programovací jazyk, nám během programování vyhledává různé chyby, i ty, které by mohly nastat jen v určité situaci.
4.8 Systém pro správu verzí GIT Abych předešel ztrátě dat a zároveň si uchovával historii svého postupu, rozhodl jsem se používat při vývoji systém pro správu verzí projektu, kterým je GIT. Pro uchovávání verzí online použiji službu BitBucket od společnosti Atlassian. GIT tedy slouží k uchovávání verzí projektu a byl vyvinut Linusem Torvaldsem, známým autorem linuxového jádra. [12]
4.9 YUI Compressor Podle průzkumu, který sleduje statistiky počtu načtených stránek s použitou nebo prázdnou vyrovnávací pamětí, se zjistilo, že 20% všech uživatelů si stránky načítá právě s prázdnou vyrovnávací pamětí. Z toho vyplývá, že je potřeba programovat úsporně, především při vývoji designu v CSS nebo funkční části v JavaScriptu. [13] Částečně vyřešit tento problém s vyrovnávací pamětí nám pomůže knihovna YUI Compressor, z anglického názvu Yahoo! User Interface Compressor. Knihovna před vypuštěním na produkční server provede kompresi odstraněním komentářů a prázdných znaků ze stylů a skriptů jazyka JavaScript, popřípadě upraví kód takovým způsobem, aby při přenosu ušetřil každý zbytečný bajt. Následující ukázka znázorňuje změny, které YUI Compressor provádí při kompresi souboru se styly.
26
/** Více řádkový komentář **/ .nazevTridy { /* komentář v deklaraci třídy */ font-weight: normal;; ; margin: 0px 0pt 0em 0%; padding: 0.1px 0.66pt 2.1em 9.1cm; color: rgb(123, 123, 123); background: rgb(255, 0,0); border: none; border-top: #ffeedd; } .prazdnaTrida { ; }
Data v souboru se styly budou postupně komprimována pomocí následujících úprav. Nejprve jsou odstraněny všechny komentáře a prázdné znaky, poté jsou odstraněny duplicitní středníky a středníky na konci bloku CSS třídy. Odstraněny jsou celé třídy, které nemají vnořené žádné parametry, v našem případě bude odstraněna celá třída s názvem prazdnaTrida. Dále jsou individuálně upravovány parametry jednotlivých tříd. Barvy jsou převedeny z RGB formátu do formátu hexadecimálního a dále optimalizovány. U desetinných čísel je odstraněna počáteční nula a u atributů s hodnotou none je tato hodnota nahrazena číslem nula. Jak bude zkomprimovaný kód vypadat, se můžeme podívat níže. .nazevTrydy{font-weight:normal;margin:0;padding:.1px .66pt 2.1em 9.1em;color:#7b7b7b;background:#f00;border:0;border-top:#fed}
Knihovna nám svou kompresí zmenší velikost kódu přibližně o 20% jeho původní velikosti, což může být u rozsáhlejších projektů klíčové.
27
5 Postup řešení Vývoj aplikace jsem si rozdělil do čtyř hlavních částí. Nejprve se budeme věnovat přípravě vývojového prostředí, poté začneme vyvíjet administraci aplikace, následně a někdy i souběžně s tím budeme vytvářet informační část pro návštěvníky webu a nakonec si vytvoříme testy a celou aplikaci otestujeme.
5.1 Příprava vývojového prostředí Vývojové prostředí nás bude provázet celým vývojem aplikace, proto je velmi podstatné se o něm alespoň zmínit. Prostředí si rozdělíme do dvou částí, tou první bude prostředí, na kterém webová aplikace poběží, abychom ji nemuseli mít umístěnou na vzdáleném webovém serveru a každou změnu tam nepohodlně nahrávali. Druhou částí bude prostředí pro samotný vývoj zastoupené především chytrým editorem.
5.1.1 Virtuální operační systém Nejprve, než začneme něco programovat, je potřeba si zprovoznit vývojové prostředí. To provedeme tak, že si na svém počítači nainstalujeme aplikaci VirtualBox a k němu již zmiňovaný nástroj Vagrant. V online repozitáři si vyhledáme vhodný předinstalovaný operační systém, já si zvolil Ubuntu, následně si ho pomocí nástroje Vagrant a příkazu vagrant init ubuntu/trusty64 stáhneme. Po dokončení stahování se nám vytvoří soubor Vagrantfile. Tomu nastavíme takové parametry, aby po spuštění přesměroval soubory lokálního projektu do souborového systému virtuálního operačního systému. Dále je potřeba nastavit síťovou kartu a přidělit systému dostatečnou operační paměť. Ještě než si virtuální systém spustíme, editujeme lokální soubor s DNS záznamy, v mém případě je to soubor hosts umístěný ve složce etc, a nastavíme si libovolné doménové jméno pro ip adresu virtuálního stroje, abychom si k němu usnadnili přístup. Nakonec si virtuální stroj spustíme příkazem vagrant up a připojíme se do něj přes ssh zadáním příkazu vagrant ssh. Pomocí konzolového rozhraní virtuálního stroje si ověříme správnou funkčnost našeho zásahu do nastavení a nainstalujeme námi potřebné serverové aplikace, jimiž jsou Apache2, MySQL5 a podporu PHP pro Apache. Nainstalované aplikace, především Apache2, je nutné nakonfigurovat. Nejprve tedy zajistíme, aby se aplikace spouštěly po 28
startu a nemuseli jsme se o ně již starat. Konfigurace Apache je velmi jednoduchá a netýká se přímo mé bakalářské práce, proto si dovolím ji vypustit.
5.1.2 Nastavení vývojového prostředí aplikace Po ověření správné funkčnosti všech potřebných aplikací si připravím do kořenové složky webu soubory frameworku Symfony, kde hned pomocí konzolového příkazu frameworku inicializuji základní části projektu, jimiž jsou ApiBundle, AppBundle a FrontBundle. ApiBundle bude sloužit jako podpora pro aplikační rozhraní dostupné neautorizovaným návštěvníkům a také jako datová část uchovávající třídy symbolizující jednotlivé databázové tabulky. V AppBundle bude obsažena administrační část přístupná pouze autorizovaným uživatelům. Nakonec tu máme část FrontBundle, která na základě dat uložených v databázi, vygeneruje veřejnosti dostupnou webovou prezentaci. Pro samotný vývoj aplikace použiji editor PhpStorm od společnosti JetBrains, kterému je potřeba nastavit kořenové složky zdrojových kódů, knihoven a složky, které má ignorovat. Posledním mým krokem pro inicializaci projektu je zprovoznění lokálního systému pro správu verzí projektu schovaného pod zkratkou GIT, který následně propojím s repozitářem vytvořeným u poskytovatele online služby pro uchovávání verzí projektu BitBucket, čímž si zajistím minimální ztráty vyvíjené aplikace v případě selhání hardwaru a zachovám si tak i veškeré její verze.
5.2 Databázová struktura Datová struktura je důležitou součástí každé dynamické webové aplikace. Vytvoříme si tedy novou databázi v programu MySQL WorkBench, nadefinujeme a navrhneme databázové tabulky podle požadavků na aplikaci. Řešení bylo navrhnuto tak, aby obsahovalo vztahy maximálně 1:M, a proto jsme nemuseli řešit problematiku vztahů M:N.
29
5.2.1 Analýza požadavků a popis jednotlivých tabulek Databázové tabulky jsem volil tak, aby byly co nejlépe využívány. Naší první tabulkou, kterou jsem začal, byla jak jinak než tabulka uživatelů uchovávající základní data o správcích webové aplikace. Nejdůležitějšími atributy jsou uživatelské jméno, heslo, role a logický typ označující uživatele za aktivovaného. Na základě těchto parametrů se aplikace rozhoduje, jak bude k uživateli přistupovat. Tabulka gallery souvisí s tabulkou gallery_image, protože každý obrázek by měl být zahrnut do nějaké galerie. Tabulka galerie slouží tedy pro shromažďování obrázků, proto má pouze jeden atribut a tím je cizí klíč určující výchozí obrázek galerie. Tyto dvě tabulky se používají tam, kde je potřeba propojit jinou tabulku s obrázkem. Je tomu tak například u produktů, produktových stránek či u blogového příspěvku. Další z již zmíněných tabulek je produkt, který obsahuje atributy uchovávající detailní parametry produktu. Každý produkt je zároveň členem nějaké stránky s produkty. Pro dynamickou správu navigace webu potřebujeme tabulku, která bude uchovávat data pro její vygenerování. V ER diagramu jí nalezneme pod názvem menu_item. Tato tabulka je zajímavá tím, že obsahuje cizí klíč sama na sebe, protože budeme potřebovat více úrovní navigace. Tyto úrovně jsou omezeny na dvě, jelikož další šablona nepodporuje, ale do budoucna bude určitě možné toto omezení změnit a rozšiřovat úrovně prakticky do nekonečna. Jako poslední tabulku tu máme blogové příspěvky. Tato tabulka není ničím zajímavá, pouze uchovává články napsané kompetentním uživatelem aplikace.
30
5.2.2 ER diagram Provedeme tedy základní analýzu současných požadavků firmy a na základě té vytvoříme ER diagram databáze.
Obrázek 10: ER diagram návrhu databáze
31
5.2.3 Implementace databáze Návrh databáze již máme, nyní vytvoříme objekty v podobě entit, zastupující jednotlivé tabulky. Vytvořeným třídám a jejím parametrům přidáme potřebné anotace, aby knihovna Doctrine věděla, jaký datový typ má atribut mít. U každé entity na závěr přidáme takzvané gettery a settery. /** * @ORM\Id() * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") * @var integer */ private $id; /** * @ORM\ManyToOne(targetEntity="Gallery", inversedBy="images") * @ORM\JoinColumn(onDelete="SET NULL") * @var Gallery */ private $gallery; /** * @ORM\Column(type="string", length=128) * @var string */ private $title;
Výše uvedené definice proměnných třídy patří do databázové entity GalleryImage, která má definované tři sloupce databázové tabulky. Prvním je automaticky generovaný primární klíč. Druhým je reference neboli v tomto případě cizí klíč odkazující na objekt Gallery ve vzájemném vztahu M:1 a posledním je titulek o maximální délce 128 znaků. Nahrávání obrázků vyřešíme velmi elegantně, využijeme k tomu funkce knihovny Doctrine, které nám umožní provádět operace před uložením do databáze nebo při jeho odstraňování. Přidáním anotace HasLifeCycleCallbacks k entitě GalleryImage řekneme, že chceme zavolat implementované metody při spuštění určitého procesu. Tyto funkce využijeme právě při nahrávání souborů, v našem případě obrázků nebo fotografií, na server. Průběh celého procesu nahrávání obrázků probíhá následujícím způsobem. Po odeslání formuláře se modifikuje načtená entita GalleryImage tak, že bude vyplněna hodnota proměnné file instancí objektu UploadFile. Následně je hned spuštěn příkaz pro uložení změn do databáze. Ten ovšem ještě před svým vykonáním spustí námi vytvořenou metodu, která zkontroluje a přesune nahraný soubor s nově vygenerovaným názvem do veřejnosti dostupného adresáře. Po přesunutí souboru zapíše do proměnné image 32
vygenerované jméno souboru a až poté jsou data uložena do databáze. Při editaci vše probíhá stejným způsobem, až na to, že pokud není proměnná image prázdná, je nejprve předchozí obrázek odstraněn a až poté je nahrán obrázek nový. Odstraněním obrázku z databáze pomocí PHP se automaticky odstraní i z disku.
5.2.4 Výchozí data Aby aplikace správně fungovala potřebuje nějaká výchozí data, jimiž je například registrace prvního uživatele s nejvyššími právy, pro první přístup do administrace nebo nastavení výchozí galerie pro prezentaci. K tomu aby se výchozí data do databáze zanesla nám pomůže rozšiřující modul knihovny Doctrine schovávající se pod názvem DoctrineFixturesBundle. Po instalaci si vytvoříme třídy, které nám data do databáze nahrají. Celý proces spustíme zadáním příkazu php app/console doctrine:fixtures:load v kořenové složce projektu.
5.3 Ověřování uživatele Ověření uživatele je nezbytnou součástí administrace, proto je potřeba jej implementovat. Autentifikace uživatele proběhne na základě jeho přihlašovacího jména a hesla. Odhlašování z aplikace probíhá přes speciální odkaz, který se volí v nastavení autentifikačního poskytovatele.
5.3.1 Uživatelské role Aplikace bude mít dvě námi definované a jednu automatickou uživatelskou roli. Pro náš případ potřebujeme tedy uživatele s nejvyššími právy, jímž je právě administrátor a jednu pro správu obsahu, kterou je moderátor. Administrátor, jak již bylo zmíněno, bude mít kontrolu nad celou aplikací, zatímco moderátor bude mít omezený přístup pouze na práci s obsahovou částí webu. Poslední automatickou roli dostane každý návštěvník webu, je jí role neautentizovaného uživatele.
5.3.2 Implementace Aby nám vše správně fungovalo, je potřeba si vytvořit třídu uživatele, používanou zároveň jako databázový model. Této třídě nejprve nastavíme rozšíření v podobě třídy frameworku Symfony a poté jí uvedeme v nastavení aplikace jako kompetentní třídu pro 33
ověřování uživatelů. Následně nastavíme pravidla firewallu tak, aby do administrátorské sekce pustil pouze ověřené a přihlášené uživatele. Dále si programově vytvořím uživatele s nejvyššími právy pro mou potřebu přístupu do administrace webu. Nakonec vytvořím přihlašovací obrazovku, kterou také zahrnu do pravidel firewallu.
5.4 Vývoj administrátorské sekce Po zhotovení předchozích kroků se můžeme pustit do tvorby samotné administrace webu. Vytvoříme si tedy základní rozvržení, pro které použijeme šablonu administrátorského rozhraní postavenou právě na frameworku Twitter Bootstrap. Toto rozvržení bude stejné pro všechny ostatní podstránky administrace a proto je potřeba si u něj nadefinovat několik bloků, abychom byli schopni do něj vložit obsah z části webu vygenerované příslušným řadičem aplikace. Dále importujeme do základního rozvržení aplikace potřebné komponenty jako je například jQuery, Twitter Bootstrap nebo Font-Awesome a následně vytvoříme výchozí stránku, která se zobrazí hned po přihlášení. Vytvoříme stránku pro správu uživatelských účtu, aby bylo možné přidat nového administrátora nebo měnit hesla uživatelům.
5.4.1 Práce s obrázky Jednou z důležitých součástí aplikace je nahrávání a práce s obrázky. Nahrávání probíhá společně s ukládáním dat do databáze. Po nahrání obrázku na server je potřeba jej ještě zpracovat. Na toto použiji knihovnu z frameworku Nette, protože mi přijde nejvhodnější. Obrázek tedy ořízneme, aby jeden z jeho rozměrů nebyl větší než je maximální nastavená velikost a poté z něj vytvoříme malý náhledový obrázek. Vytvoření takovéhoto obrázku není vůbec jednoduché, pokud tedy chceme, aby všechny měly stejné rozměry. Docílíme toho tak, že spočítáme poměr stran jak z rozměrů zdrojového obrázku, tak i z rozměrů obrázku cílového. Podle tohoto údaje se poté rozhodneme, jaký rozměr upravíme a jaký ořízneme. Ořezávání proběhne ve středu ořezávané strany, proto použitím tohoto způsobu získáme
takový
obrázek,
který
bude
mít
co
největší
možnou
a podstatnou část z originálního obrázku. Nakonec obrázek doostříme.
34
public function resizeAndCropImage($imagePath, $size = [], $retina = true) { if(count($size) === 0) $size = self::$SIZE_PRODUCT_PAGE; $thumbnailWidth = $retina?$size[0]*2:$size[0]; // 2x for Retina displays $thumbnailHeight = $retina?$size[1]*2:$size[1]; // 2x for Retina displays $image = $this->openImage($imagePath); $originalRatio = $image->getWidth()/$image->getHeight(); $thumbnailRatio = $thumbnailWidth/$thumbnailHeight; if($originalRatio <= $thumbnailRatio) { $image->resize($thumbnailWidth, null); if($originalRatio != $thumbnailRatio) { $image->crop( 0, round(($image->getHeight()/2)-($thumbnailHeight/2)), $thumbnailWidth, $thumbnailHeight ); } } else { $image->resize(null, $thumbnailHeight); $image->crop( round(($image->getWidth()/2)-($thumbnailWidth/2)), 0, $thumbnailWidth, $thumbnailHeight ); } $image->sharpen(); return $image; }
Uvedený úryvek kódu patří do třídy ImageUtility a zpracovává obrázek dle nastíněného postupu výše.
5.4.2 Asynchronní ovládání aplikace Asynchronní ovládání nám ještě více zpříjemní práci s administračním rozhraním a to tak, že některé akce budeme provádět bez nutnosti načtení celého obsahu. Sice je v současnosti JavaScript prakticky nutností, ale i přes to se také zaměříme na funkčnost webu s jeho absencí. Zmíněné ovládání použijeme na řazení a odstraňování různých typů položek, kde to má nějaký smysl. U odstraňování to není zase takovou nutností, jako u přesouvání položek, jelikož odstraňujeme jednou za čas, ale řadit položky podle své fantazie můžeme během jednoho požadavku i několikrát. Pro realizaci tohoto vylepšení budeme potřebovat dvě implementace. První bude v JavaScriptu. Tu naprogramujeme univerzálně, aby se dala použít u všech položek. Druhá bude na straně serveru přímo v daném řadiči. Řadič upravíme tak, aby zvládal přijmout jak klasický požadavek tak i ten zaslaný JavaScriptem. JavaScriptu bude řadič odpovídat strukturovanou formou JSON typickou právě pro JavaScript. 35
5.4.3 Služby V projektu použijeme hned tři služby. První službu, kterou budeme potřebovat je služba pro práci s obrázky, jelikož práce s obrázky se v projektu objevuje velmi často a nechceme mít duplicitní funkčnosti. Tato služba umí obrázek zpracovat a oříznout dle nastavených rozměrů. Budeme potřebovat vygenerovat vždy nějaké jméno stránky pro sestavení hezké url adresy, proto si vytvoříme službu, která nám z názvu stránky toto jméno vygeneruje. Tuto službu bude poté využívat služba další, která obsahuje nástroje pro ovládání produktových stránek. Jednou z metod je například metoda, která se stará o to, aby bylo vygenerované jméno unikátní, a pokud není, přidává se na konec zvyšující se číslo dokud této unikátnosti nedosáhneme.
5.5 Vývoj sekce přístupné běžným návštěvníkům Po dokončení administrátorské sekce můžeme začít pracovat na sekci pro běžné návštěvníky webu. Opět vytvoříme základní rozvržení webu, podle kterého se budou generovat všechny ostatní podstránky a nastavíme hlavičku, kam doplníme základní informace o společnosti a importujeme potřebné komponenty třetích stran jako v případě administrátorské sekce.
5.5.1 Navigace Navigační část webu je velmi komplikovaná, protože se bude její zobrazení měnit v závislosti na velikost obrazovky. Navigace bude zároveň rozdělena do dvou úrovní. První úroveň bude zobrazována vždy a ta druha jen pokud je její nadřazená stránka právě zvolena.
5.5.2 Úvodní prezentace Prezentace na hlavní stránce bude sloužit k rychlému zobrazení důležitých informací, které budou doplněny obrázkem. Nejprve je potřeba si naformátovat vzhled této prezentace, která se také bude automaticky přizpůsobovat velikosti zařízení, na kterém je stránka prohlížena, a proto musíme CSS styly rozdělit hned do několika bloků.
36
Po zhotovení základního zobrazení naprogramujeme JavaScript, který prezentaci rozpohybuje a nakonec implementujeme načítání dat z databáze. Vzhledem k tomu, že mají zobrazované obrázky větší velikost a chceme snížit původní přenos dat mezi serverem a úvodní stránkou na klientské straně, načteme pouze první obrázek a ostatní nahrajeme asynchronně pomocí JavaScriptu. Obrázky nahrávané asynchronně se budou předávat kódované v Base64.
5.5.3 Stránka s produkty Tato stránka je nejpoužívanější v celé aplikace, proto nás bude také stát spoustu úsilí. Stránka má různé podoby v závislosti na tom, jaká data jsou vyplněna a jaký má produktová stránka typ. Abychom trochu oddělili jednotlivé části šablony produktové stránky, vytvoříme si makro, které nám bude vykreslovat seznamy produktů. {% macro drawProducts(products, type='types') %} {# Definování často používaných proměnných #} {% for product in products %} {# Podmínky a HTML kód pro vygenerování produktů #} {% endfor %} {% endmacro %}
Vytvořenému makru předáme pole produktů a typ produktové stránky na němž je generování závislé. {{ macros.drawProducts(products, productPage.type) }}
Generování spustíme vložením výše uvedeného řádku do šablony produktové stránky.
5.6 Optimalizace SEO pro vyhledávače Na závěr vytvoříme automaticky generovaný soubor sitemap.xml, obsahující odkazy na každou stránku dostupnou běžným návštěvníkům a robots.txt, který vyhledávačům řekne, kde mají prohledávat web a naopak, kde ho prohledávat nesmějí. Dále provedeme inspekci veškerého HTML kódu, aby odpovídal standartu HTML5, doplníme individuální META informace ke každé podstránce webu a ověřím správnou strukturu nadpisů. Nakonec odstraníme kód JavaScriptu a stylů, umístěný přímo v HTML kódu aplikace tak, že jej přesuneme do externích souborů.
37
6 Aktualizace frameworku Symfony Při inicializaci projektu byla dostupná stabilní verze 2.7.6 a verze 3.0 byla v testovacím stavu, proto jsme zvolili verzi stabilní. V průběhu vývoje se dokončili práce a testování nové verze Symfony 3.0 a byla vypuštěna jako stabilní. Abychom získali co nejdelší podporu, provedeme aktualizaci na nejnovější verzi. V nové verzi je poměrně dost změn, proto aktualizujeme Symfony nejprve na verzi 2.8.6, což je přechodová verze. V této verzi můžeme používat jak metody ze staré verze, tak i z té nové, což nám nenaruší funkčnost webu. Postupným procházením webu a sledováním ladící lišty frameworku Symfony zjišťujeme zastaralé funkce a ty následně opravujeme na funkce nové. Po opravení všech zastaralých funkcí provedeme aktualizaci na nejnovější verzi, kterou je 3.0.6. Adresářová struktura nové verze je lehce odlišná, proto si vytvoříme nový projekt s novou verzí a postupným zkoumáním změn jí opatrně pozměníme.
Obrázek 11: Ladící lišta frameworku Symfony
38
7 Testování a závěrečné kroky V průběhu vývoje aplikace budeme také vytvářet různé testy, které budou ověřovat funkčnost celého webu a podle nich budeme vždy vědět, zda provedené změny neměly vliv na jinou funkčnost webu. V případě konfliktů můžeme tyto problémy okamžitě vyřešit. Jakmile bude aplikace připravena a otestována, provedeme závěrečné kroky, které jsou nezbytné pro úspěšné publikování nové webové prezentace.
7.1 Testy Základní testy budou provádět kontrolu dostupnosti všech stránek webu a ověřovat u nich základní pravidla HTML, jako je například ověření zda má každý obrázek uvedený alternativní text, zda každá stránka má právě jeden hlavní nadpis nebo zda se na stránce nevyskytují duplicitní identifikátory HTML elementů. Pro všechny testy použijeme takzvaný Crawler, což je vlastně takový webový klient pomocí něhož můžeme zkontrolovat zdrojový kód stránky a také ji libovolně procházet včetně podpory odesílání formulářů nebo klikání na odkazy. Abychom tohoto klienta mohli používat, musíme naší testovací třídu rozšířit o třídu WebTestCase. Funkční test si jako první načte domovskou stránku, kde si přečte odkazy z navigace a postupně je prochází. Aby test proběhl co nejrychleji, vytváříme si nové instance objektu Crawler s povolenou možností běhu na pozadí a ty uchováme v lokálním poli. private function checkPageCode(Crawler $crawler) { $this->assertEquals($crawler->filter("h1")->count(), 1); $elementsId = ($crawler->filter("[id]")->extract("id")); $elementsStartCount = count($elementsId); $elementsId = array_unique($elementsId); $this->assertEquals($elementsStartCount, count($elementsId));
}
$crawler->filter("img")->each( function (Crawler $node) { $this->assertNotEmpty($node->attr('alt')); } );
private function isAvailable(Client $client) { $this->assertTrue($client->getResponse()->isSuccessful()); }
39
Zde je ukázka dvou funkcí, které spouští funkční test u každé načtené stránky. První funkce nazvaná checkPageCode nejprve zkontroluje zda je na hlavní stránce právě jeden hlavní nadpis, poté si načte všechny identifikátory elementů a vyřadí z nich ty duplicitní. Vyfiltrované položky spočítá a následně porovná s původním počtem nalezených identifikátorů. Pokud se tyto čísla shodují, neexistují na stránce duplicitní identifikátory HTML elementů. Dále test ověřuje neprázdnost alt atributu u obrázků na stránce. Druhá nastíněná funkce pod názvem isAvailable pouze zkontroluje status HTML hlavičky dokumentu, zda odpovídá stavovému kódu 200, což znamená, že je vše v pořádku.
Obrázek 12: Ukázka výstupu testu aplikace
Obrázek výše zobrazuje část výstupu testu aplikace po zadání příkazu phpunit v kořenové složce projektu. Testování samozřejmě probíhalo i průběžně a to tak, že jsme každou nově přidanou funkci řádně, z hlediska její funkčnosti, otestovali.
7.2 Vypuštění na produkční server Po úspěšném otestování bude web umístěn na produkční server, kde bude vypnut ladící režim, povolí se automatické generování a následné ukládání pomocných souborů na disk, čímž se výrazně zrychlí načítání webu. Styly aplikace budou poté vygenerovány z pomocného jazyka LESS do klasického CSS, kterému rozumí každý webový prohlížeč. Veškeré skriptovací soubory a soubory se styly se sjednotí do jednoho souboru a nakonec budou odstraněny komentáře a přebytečné mezery či nové řádky, pro snížení přenosu dat mezi serverem a klientem. O toto se postará externí knihovna naprogramovaná v Javě a tou je YUI Compressor. 40
Pro sestavení projektu dle výše zmíněných procesů, je potřeba spustit několik konzolových příkazů frameworku Symfony. Vzhledem k tomu, že budeme jednotlivé verze vypouštět na produkční server celkem často, vytvoříme si skript, který tyto příkazy postupně zavolá. Na závěr nahrajeme soubory na webový server přes FTP a nastavíme přístupové údaje k databázi.
41
8 Závěr Cílem mé bakalářské práce bylo připravit administrátorské rozhraní webových stránek společnosti TopStein, s. r. o., implementovat nový moderní vzhled webu včetně optimalizace SEO pro vyhledávače a podpory přizpůsobitelného zobrazení na různých zařízeních dle velikosti obrazovky. K realizaci měl být použit PHP framework Symfony a jako uložiště dat databáze MySQL včetně její nadstavby pro objektové mapování v podobě knihovny Doctrine. Generování obsahu měl zprostředkovávat šablonovací systém Twig.
8.1 Splnění cílů Kromě nadefinovaných cílů mé bakalářské práce jsem oživil administrátorské rozhraní o asynchronní komunikaci webového prohlížeče se serverem v podobě přesouvání položek, jejich odstraňování a zobrazování jednorázových informativních zpráv v sekci pro administrátory. Dále jsem pomocí JavaScriptu oživil úvodní prezentaci a zprovoznil načítání obrázků opět skrz komunikaci na pozadí, abych zrychlil načítání úvodní stránky webové prezentace. Nakonec jsem implementoval pokročilou práci s obrázky, aby se na webu nezobrazovaly v plné velikosti a měly všechny stejné rozlišení. Všechny cíle mé bakalářské práce byly splněny a realizovány do posledního detailu, jak podle zadání, tak i podle požadavků cílové společnosti.
8.2 Problémy a jejich řešení Při vývoji aplikace jsem se setkal hned s několika problémy, které jsem musel vyřešit. Prvním problémem bylo navržení databáze takovým způsobem, aby v ní mohly být uložené všechny důležité údaje. Řešením byla důkladná analýza ukládaných dat a následoval návrh datové struktury formou ER diagramu. Dále jsem se dlouho trápil při vytváření responzivní navigace veřejné části webu. Nakonec se mi jí podařilo pomocí JavaScriptu a CSS3 dokončit podle mých představ. Největším problémem ovšem bylo zprovoznit samotné nahrávání obrázků do aplikace a jejich následné zpracování. To jsem vyřešil velmi elegantně přímo v databázové entitě za použití funkcí a událostí z knihovny Doctrine. Nahrání obrázku na server proběhne úplně automaticky hned po zavolání funkce pro uložení dat do databáze. Navíc při editaci nebo odstranění záznamu v databázi 42
se provedou změny i na disku, kde jsou obrázky uloženy. Jejich následné zpracování jsem vyřešil pomocí knihovny frameworku Nette pro práci s obrázky a to tak, že jsem si nastínil možné situace, které by při zmenšování mohly nastat a na základě nich jsem sestavil algoritmus, který obrázek spolehlivě zmenší a bezkonfliktně ořízne.
8.3 Návrhy na další vývoj aplikace Je možné, že v budoucnosti bude chtít cílová společnost mít možnost své produkty prodávat přes svou webovou aplikaci, proto bych doporučil rozšířit aplikaci například o košík a objednávkový formulář, na základě něhož bude zákazník informován o stavu své objednávky. Implementace internetového obchodu včetně všech náležitostí, jimiž jsou například generování faktur nebo online platba kartou, je velmi náročná, proto bych zůstal pouze u výše zmíněného formuláře. Design webu by také nemusel do budoucna vyhovovat, proto bych jej časem nahradil novým, což vzhledem k použití šablonovacího systému Twig nebude vůbec žádný problém a jeho nasazení by mohl zvládnout i grafický návrhář nebo člověk pracující pouze s HTML či CSS. Díky přehlednému kódu a použití frameworku Symfony, může jakýkoliv vývojář webovou aplikaci kdykoliv vylepšit nebo rozšířit.
43
Seznam použité literatury [1] SEO Servis. SEO Servis [online]. [cit. 2016-01-21]. Dostupné z: http://seo-servis.cz [2] Interval.cz: Google upřednostňuje mobilní weby v SERP. Je váš web připraven? Interval.cz [online]. [cit. 2016-01-21]. Dostupné z: https://www.interval.cz/clanky/google-uprednostnuje-mobilni-weby-v-serp/
[3] Webaster CZ, s. r. o. Webaster.cz [online]. [cit. 2016-01-21]. Dostupné z: http://webaster.cz [4] Co je Redakční systém (CMS). In: Redakční Systémy [online]. 2009 [cit. 2016-0523]. Dostupné z: http://www.redakcni-systemy.com/vseobecne/clanky/76-co-jeredakcni-system [5] Redakční systémy – populární a ty ostatní. Markomu [online]. 2015 [cit. 2016-0523]. Dostupné z: http://markomu.cz/redakcni-systemy/ [6] Phalcon. Phalcon [online]. 2012 [cit. 2016-05-23]. Dostupné z: https://phalconphp.com/en/ [7] What is PHP? PHP [online]. c2001-2016 [cit. 2016-05-23]. Dostupné z: http://php.net/manual/en/intro-whatis.php [8] Projects using Symfony. Symfony, High Performance PHP Framework for Web Development [online]. Paris, 2016 [cit. 2016-05-23]. Dostupné z: http://symfony.com/projects [9] About Symfony Project. Symfony, High Performance PHP Framework for Web Development [online]. Paris, 2016 [cit. 2016-05-23]. Dostupné z: http://symfony.com/cs/about [10] Model-View-Controller. Vojtěch Hordějčuk [online]. c2008-2016 [cit. 2016-0523]. Dostupné z: http://voho.cz/wiki/model-view-controller/ [11] Čím je Adminer lepší než phpMyAdmin? Adminer - Správa databáze v jednom PHP souboru [online]. Praha, 2007 [cit. 2016-05-23]. Dostupné z: https://www.adminer.org/cs/phpmyadmin/ [12] Getting Started - A Short History of Git. Git [online]. 2005 [cit. 2016-05-23]. Dostupné z: https://git-scm.com/book/en/v2/Getting-Started-A-Short-History-of-Git 44
[13] Performance Research, Part 2: Browser Cache Usage - Exposed!. In: YUI Blog [online]. 2007 [cit. 2016-05-23]. Dostupné z: http://yuiblog.com/blog/2007/01/04/performance-research-part-2/ [14] VRÁNA, Jakub. 1001 tipů a triků pro PHP. Brno: Computer Press, 2010. ISBN 978-80-251-2940-1. [15] GILMORE, W. J. Velká kniha PHP 5 a MySQL. Brno: Zoner Press. Encyklopedie webdesignera. ISBN 80-868-1520-X. [16] CHAFFER, Jonathan a Karl SWEDBERG. Mistrovství v jQuery: [kompletní průvodce vývojáře]. Překlad Jan Pokorný. Brno: Computer Press, 2013. Mistrovství. ISBN 978-80-251-4103-8.
45
Seznam obrázků Obrázek 1: Administrační část aplikace ........................................................................... 9 Obrázek 3: Loga vybraných redakčních systémů ........................................................... 12 Obrázek 4: Návrhový vzor MVC.................................................................................... 16 Obrázek 5: Logo nástroje Adminer ................................................................................ 22 Obrázek 6: Ukázka dělení webu pomocí Twitter Bootstrap ........................................... 22 Obrázek 7: Ukázka vybraných komponent Twitter Bootstrap ....................................... 23 Obrázek 9: Současné logo editoru PhpStorm ................................................................. 25 Obrázek 10: ER diagram návrhu databáze ..................................................................... 31 Obrázek 11: Ladící lišta frameworku Symfony .............................................................. 38
46
Seznam použitých zkratek CMS – Content Management System CSS – Cascading Style Sheets DMS – Document Management System FTP – File Transfer Protocol HTML – HyperText Markup Language JS – JavaScript JSON – JavaScript Object Notation KVM – Kernel-based Virtual Machine MVC – Model View Controller NPM – Node Package Manager PHP – Hypertext Preprocessor SEO – Search Engine Optimization SSH – Secure Shell SQL – Structured Query Language URL – Uniform Resource Locator WYSIWYG – Wahat You See Is What You Get XML – Extensible Markup Language
47
Přílohy 1 Obsah přiloženého CD Na přiloženém CD v kořenovém adresáři se nachází tato bakalářská práce ve formátu PDF, adresář s webovou aplikací včetně jednoduchého návodu na instalaci.
48
2 Uživatelská příručka Vzhledem k tomu, že by nemusela být administrace pro běžné uživatele úplně srozumitelná, popíšeme si stručně její vlastnosti a souvislosti.
Obrázek 1: Administrační část aplikace
2.1 Prezentace Viditelnou část prezentace je k nalezení pouze na úvodní stránce, kde se po určitém časovém intervalu snímky prohazují včetně informačního textu. Doporučujeme nahrávat fotky ve vysokém rozlišení, logická část aplikace poté tento obrázek zpracuje podle svých potřeb. Jednotlivé snímky lze jednoduše seřadit podle toho v jakém pořadí je chceme postupně zobrazit.
2.2 Uživatelé V této části aplikace se nachází správa uživatelských účtů, je možné je vytvořit, editovat nebo smazat. Do administrační části se může přihlásit každý registrovaný uživatel, který je zároveň aktivován, to znamená, že pokud nechcete někoho přímo odstranit, stačí ho jen deaktivovat, s okamžitou platností bude odhlášen a jeho pokusy o přihlášení budou systémem zamítnuty.
49
2.3 Produkty Po vstupu do této sekce se vypíše detailní seznam všech produktů, které jsou v systému zaneseny. Zde není možné produkty přidávat, toto se provádí z příslušné produktové stránky, aby byly produkty zařazeny právě pod určitou stránku.
2.4 Stránky s produkty Tato sekce obsahuje detailní seznam všech dostupných stránek s produkty. Tyto stránky je zde možné i vytvářet. Produktové stránky jsou stránky prezentující skupiny produktů a jsou rozděleny do čtyř kategorií, jimiž jsou materiály, typy, vzorky a reference. Každá tato stránka má jiné parametry jak u přidávaných produktů, tak i u samotné administrace jejího obsahu. Tento typ již nelze po vytvoření stránky změnit, jelikož je každý vázán na jiná data. Podle typu stránky je pak možné nahrávat obsah do různých částí zvolené stránky. Obrázky referencí se zobrazí na konci každé produktové stránky nebo v případě typu reference se zobrazí jako hlavní část. Obrázky na stránce jsou obrázky umístěné napravo od textu a zobrazující se pod sebou. Obsah nebo název stránky lze kdykoliv upravit. Doporučujeme nepoužívat u hlavního obsahu nadpisy první úrovně, jelikož by daná produktová stránka nebyla správně z hlediska pravidel pro internetové vyhledávače. Jednotlivé produkty spojené s vybranou stránkou je zde možné opět libovolně seřadit. Nezapomeňte také na to, že když stránku smažete, bude smazána s veškerým jejím obsahem včetně umístění v navigaci.
2.5 Blog Blog slouží k přidávání článků neboli příspěvků. Vložené články se zobrazí jak na hlavní stránce, tak i v části blog schovávající se pod sekcí o firmě. Na hlavní stránce se zobrazí pouze tři naposledy zveřejněné články. Každý článek lze vytvořit, aniž by byl zveřejněn na webu, protože je potřeba vždy po jeho uložení tento článek zveřejnit, tím pádem můžeme uchovávat i více rozepsaných článků najednou. Pokud ale starší, již zveřejněný článek označíte jako koncept a poté jej znovu zveřejníte, objeví se jako článek nový zobrazený na prvním místě.
50
2.6 Navigace Poslední částí administračního rozhraní je navigace. Navigace provází běžné uživatele webovou prezentací, proto je potřeba jí vhodně nastavit, tak aby z ní byly všechny stránky dostupné. Do první úrovně navigace lze přidat hned několik typů položek. První z nich je odkaz, což je jak již název vypovídá odkaz nejčastěji na jinou externí stránku. Dalším typem je produktová stránka, tato položka v dalším kroku obsahuje seznam všech nepřiřazených produktových stránek a lze jej tedy jednoduše připnout k navigaci. Předposledním typem je statická stránka, ta v dalším kroku obsahuje na výběr seznam všech statických stránek, které nelze z administrace měnit. Jde většinou o informativní stránky, jež není potřeba tak často aktualizovat. Posledním typem, který je dostupný pouze z první úrovně je nadřazená položka menu. Tento typ slouží pouze jako rodič vnořených položek navigace nebo jako vstup do další úrovně. Všechny položky lze opět libovolně seřadit. Ještě jedna informace na závěr, při odstranění jakékoliv položky svázané s jakoukoliv stránkou se odstraní pouze tato položka a data s ní související zůstanou zachovány.
51