VYSOKÉ UČENÍ TECHNICKÉ V BRNĚ BRNO UNIVERSITY OF TECHNOLOGY

FAKULTA PODNIKATELSKÁ ÚSTAV INFORMATIKY

FACULTY OF BUSINESS AND MANAGEMENT INSTITUTE OF INFORMATICS

VYTVOŘENÍ SYSTÉMU PRO E-SHOP

CREATION OF E-SHOP SYSTEM

BAKALÁŘSKÁ PRÁCE BACHELOR'S THESIS

AUTOR PRÁCE JAKUB ZAPLETAL AUTHOR

VEDOUCÍ PRÁCE Ing. JIŘÍ KŘÍŽ, Ph.. SUPERVISOR

BRNO 2009

Anotace

Tato práce se v ěnuje vytvo ření aplikace e-shopu pro ú čely komer čního ší ření. Je zde probrán pr ůzkum prost ředí a technologiemi, kterými se m ůže daná aplikace vyvíjet. Nakonec je popsána vlastní práce a spokojenost s volbou daného řešení.

Klíčová slova: ASP, ASP.NET, PHP, MS SQL, Oracle, DB2, Postre SQL, MySQL, ZenCart, OpenCart, OsCommerce, VirtueMart, , , Framework, Prado, , CakePHP, Nette, MVC, e-shop, internetový obchod.

Annotation

This thesis is dedicated to the creation of e-shop for the purposes of commercial distribution. It is discussed exploration of platforms and technologies, which application can be developed. Finally, it is described my own labor and satisfaction with the choice of the solution.

Keywords: ASP, ASP.NET, PHP, MS SQL, Oracle, DB2, Postre SQL, MySQL, ZenCart, OpenCart, OsCommerce, VirtueMart, Joomla, Magento, Zend Framework, Prado, Symfony, CakePHP, Nette, MVC, e-shop.

OBSAH

Úvod ...... 4

1 Vymezení problém ů a cíle práce ...... 5

1.1 Programovací jazyky ...... 5 1.1.1 ASP ...... 5 1.1.2 PHP ...... 7 1.1.3 Shrnutí ...... 10 1.2 Databázové systémy ...... 11 1.2.1 MS SQL ...... 12 1.2.2 Oracle ...... 13 1.2.3 DB2 ...... 14 1.2.4 PostgreSQL ...... 15 1.2.5 MySQL ...... 16 1.2.6 Shrnutí ...... 17 1.3 Cíl práce ...... 18

2 Analýza problému a sou časná situace ...... 19

2.1 ZenCart ...... 20 2.2 OpenCart ...... 21 2.3 OsCommerce...... 22 2.4 VirtueMart (Joomla) ...... 22 2.5 Magento ...... 23 2.6 Shrnutí ...... 24

3 Teoretická východiska práce ...... 25

3.1 Co je to framework? ...... 25 3.2 Voln ě ši řitelné PHP frameworky ...... 26 3.3 Výb ěr frameworku ...... 28 3.4 Bližší seznámení se Zend Frameworkem ...... 29

4 Vlastní návrhy řešení, p řínos návrh ů řešení ...... 34

4.1 Specifikace aplikace ...... 34 4.2 Návrh databáze...... 36 4.3 Vývoj aplikace ...... 38 4.4 Vlastní knihovny ...... 40

4.5 Přínos vlastního řešení ...... 42

Záv ěr ...... 43

Seznam obrázk ů ...... 44

Literatura ...... 45

Seznam p řílohy ...... 46

Úvod

Tato práce je zam ěř ena na tvorbu aplikace pro tvorbu internetové obchodu, a to ne pro individuální obchod, ale aplikaci, kterou by šlo komer čně nabízet zájemc ům o internetové obchody. Jednotlivé kapitoly jsou postupn ě zam ěř eny na výb ěr programovacího jazyka, databázového systému, zjišt ění aktuální stavu na poli open- source řešení, frameworku programovacího jazyka a následn ě vývoj aplikace. Při práci na aplikaci pro individuální internetový obchod by nebylo tolik nutné se zam ěř ovat na volbu, která je v dnešní dob ě k dispozici, ale u využití pro komer ční ú čely nabízet tento produkt, je nutné d ůkladn ě prozkoumat prost ředí a technologie, v kterých se má vyvíjet. Často je to boj mezi dv ěma platformami, a to Linux a Windows. Platforma Windows často nemá dobré mín ění, to je d ůsledkem nestability opera čních systém ů pro stolní po číta če, které byly v posledních patnácti letech k dispozici a práv ě naopak dobré mín ění si získává opera ční systém Linux. Samoz řejm ě to není dáno pouze stabilitou, ale také cenou samotných systém ů a softwaru s daným systémem spojeným. Dalším velkým rozhodovacím kritériem jsou finan ční náklady. Objevují se zde prost ředí, které jsou zcela zdarma, ale také prost ředí, které si žádají desítky, či stovky tisíc. Je tedy nutné si uv ědomit, jaký má daný projekt potenciál a zda je finan čně p řijatelné se dát danou cestou.

- 4 - 1 Vymezení problém ů a cíle práce

Chystáme se vytvo řit aplikaci, která budou sloužit jako kompletní systém pro provoz e- shopu, a to jak back-endové části, tak front-endová části. Na za čátku je t řeba si stanovit, v jakém programovacím jazyku budeme tuto aplikace vytvá řet, a dále je zapot řebí si uv ědomit, že veškerá data obsažená v dané aplikaci musejí být n ěkde uložena. Ukládání do textových soubor ů není ur čit ě tou správnou cestou, je tedy i nutné ur čit, jakého databázového systému využijeme. Práv ě t ěmito dv ěma problémy se budu dále zabývat a stanovím nejvhodn ější řešení.

1.1 Programovací jazyky

Volba vhodného programovacího jazyka je základním kamenem, od kterého se bude odvíjet další rozvoj vytvo ření systému. Mezi nejpoužívan ější technologie v tomto odv ětví se dají za řadit ASP a PHP. Samoz řejm ě jsou zde i další sv ětov ě známé, mezi které se řadí , Python, nebo Ruby. Já jsem se zam ěř il pouze na ASP a PHP, jelikož mají na celém sv ětě největší komunity p říznivc ů a za řadil bych je i v Česku jako nejoblíben ější technologie, kde p řevažuje komunita kolem PHP.

1.1.1 ASP

ASP (Active Server Pages) je skriptovací platforma spole čnosti Microsoft, primárn ě ur čená pro dynamické zpracování webových stránek na stran ě serveru. Její první vydání bylo na konci roku 1996. Její nástupce ASP.NET, lze chápat jako širší a komplexn ější technologii, která se od ASP v mnoha ohledech fundamentáln ě liší. ASP.NET je sou částí .NET Frameworku pro tvorbu webových aplikací a služeb od za čátku roku 2002. Struktura .NET Frameworku je znázorn ěn na Obrázku 1.

- 5 -

Obrázek 1 - Architektura .NET Frameworku

ASP.NET není novou verzí ASP, ale je to zcela nová technologie, která je integrální sou částí platformy .NET Framework. Koncept ASP.NET WebForms uleh čuje programátor ům p řechod od programování klasických aplikací pro Windows do prost ředí webu: stránky jsou poskládány z objekt ů, ovládacích prvk ů ( Controls ), které jsou prot ějškem ovládacích prvk ů ve Windows. P ři tvorb ě webových stránek je tedy možné používat ovládací prvky jako tla čítko ( Button ), nápis ( Label ) a další. T ěmto prvk ům lze p řiřazovat ur čité vlastnosti, zachytávat na nich události, atd. Tak, jako se ovládací prvky pro Windows samy kreslí do formulá řů na obrazovku, webové ovládací prvky produkují HTML kód, který tvo ří část výsledné stránky poslané do klientova prohlíže če.

Klady • Programáto ři mohou vytvá řet aplikace v jakémkoliv programovacím jazyce podporujícím CLR, nap ř. Visual Basic.NET, JScript.NET, #, Managed C++, ale i mutace Perlu nebo Pythonu a další. • Firma, která se specializuje jak na software, tak na webové aplikace, nemusí mít více tým ů programátor ů. Stejným nástrojem s velmi podobnými komponentami lze napsat i konzolovou aplikaci nad .NET Frameworkem.

- 6 - • Objektový design od za čátku. • Výborný vývojový nástroj VisualStudio. • Generované HTML nebo XHTML je zcela validní za p ředpokladu, že programátor osobn ě n ěco nenaruší. • Možnost p římo provázat s SharePoint Services. • Dobrá podpora cachování. Díky tomu se dají velmi efektivn ě zrychlit n ěkteré části aplikace, p ředchází se tím neustálým zpracováním částí, které se pravideln ě opakují a jsou náro čné na výpo čet. • Celý kód je kompilován. Tím se p ředchází chybám, které vzniknou v pr ůběhu programování. Také to umož ňuje rychlejší zpracování, protože p řevod na programové instrukce prob ěhne v pr ůběhu kompilace.

Zápory • Vázáno na platformu Win/IIS. S tím také souvisí velké náklady p ři po řizovaní vlastního serveru. Na tuto platformu je nejlepší využívat software p římo od výrobce Microsoft. • Drahá školení pohybující se řádov ě v desítkách tisíc. • Náro čnější na výkon hardwaru oproti Unix platform ě. • Je nutné platit vyšší částky za kvalitní nástroje na tvorbu aplikací.

1.1.2 PHP

PHP je rekurzivní zkratkou pro PHP: Hypertext Preprocessor (kde p ůvodní význam zkratky PHP je Per-sonal Home Page). Zakladatelem PHP je Rasmus Lerdofr, který v roce 1995 vytvo řil jednoduchou sadu skript ů jazyka Perl pro vlastní ú čely. Když byla pot řeba v ětší funk čnost, napsal rozsáhlejší implementaci jazyka C, která byla schopna komunikovat s databází, a umožnila uživatel ům vytvá řet jednoduché dynamické webové aplikace. Zpo čátku byl tento jazyk znám jako PHP/FI.

V roce 1997, kdy bylo PHP/FI 2.0, m ěla komunita n ěkolik tisíc p říznivc ů na celém sv ětě, kte ří tento jazyk aplikovali na 50 000 domén, to v té dob ě znamenalo 1% z celkového po čtu domén. Krátce poté vznikla první alfa verze PHP 3.0.

- 7 - PHP 3.0 byla první verze, která velmi p řipomínala dnešní podobu jazyka, jak ji nyní známe. Vytvo řili ho a jako kompletní před ělání jádra PHP/FI 2.0, jelikož jim p řipadlo málo schopné pro vytvá ření komer čních projekt ů, na kterých spolu pracovali. Úsiln ě spolupracovali a za čali pracovat pod již vytvo řeným uživatelským základem PHP/FI, kdy se Andi, Zeev a Rasmus rozhodli spolupracovat a vzniklo PHP 3.0 jako nástupce PHP/FI 2.0, jehož vývoj byl zastaven.

Jedna z nejv ětších výhod PHP 3.0 byla jeho schopnost rozší řitelnosti. P řínosem byla dobrá infrastruktura pro hodn ě databází, protokol ů a r ůzných API. Jeho rozší řitelnost přitáhla spousty vývojá řů a vznikaly nové rozši řující moduly. Další klí čová vylepšení byla objektov ě orientovaná syntaxe, výkon a lepší konzistence syntaxe. Koncem roku 1998 využívalo PHP desítky tisíc uživatel ů a na stovkách tisíc webových stránek bylo použito, což byl celkový nár ůst na 10% z celého internetu.

Krátce poté, co oficiáln ě vyšlo PHP 3.0, Andi Gutmans a Zeev Suraski za čali pracovat na p řed ělání jádra. Hlavními výhodami bylo zlepšit výkon komplexních aplikací a zlepšit modularitu základního kódu. Nové jádro, nazvané (vzniklo spojením slov Zeev a Andi) bylo prvn ě p ředstaveno v roce 1999. PHP 4.0 bylo založeno na tomto jád ře a spolu s nep řeberným množství nových vlastností bylo vydáno v roce 2000. Krom ě zvýšené výkonnosti p řineslo PHP 4.0 několik dalších podstatných zm ěn, jako nap ř. HTTP sessions, podporu pro mnoho web server ů, lepší ochrana vstupních dat a n ěkolik nových jazykových konstruktor ů. Tato verze se postupn ě rozší řila až na 20% internetu, což skýtalo n ěkolik milión ů webových stránek.

Nejnov ějším p řír ůstkem je PHP 5.0, které bylo vydáno 13. července 2004. Op ět přineslo n ěkolik vylepšení, ale jedno je mimo řádného významu: PHP 5 výrazn ě zlepšuje objektov ě orientovanou syntaxi. P řibyly výjimky, konstruktory, destruktory a mnoho dalších jazykových rozší ření. Mezi další podstatná rozší ření pat ří nap ř. přepracovaná podpora XML, podpora COMu a technologie .NET, lepší podpora MySQL a další. Nyní je PHP ve verzi 5.2.9 a pomalu se již blíží verze PHP 6.0.

- 8 - PHP se stalo velmi oblíbeným p ředevším díky jednoduchosti použití a tomu, že kombinuje vlastnosti více programovacích jazyk ů a nechává tak vývojá ři částe čnou svobodu v syntaxi. Softwarovými programátory bývá často zatracováno kv ůli jeho jednoduché základní syntaxi a d říve malé podpory objektov ě orientovaného programování. P řispívá k tomu také fakt, že základy PHP se nau čí studenti již na st řední škole a pyšní se svými programátorskými schopnostmi.

Klady • Multiplatformní řešení. M ůžeme jej provozovat jak Linuxu, tak na Windows. Pro Windows ale není p říliš doporu čován kv ůli rychlosti, stabilit ě a podpo ře. • Jednoduché nastavení, které se provádí v jednom souboru PHP.INI, který případn ě jen sta čí p řehrát jinam a nemusí se vše nastavovat znovu. • Nízké nároky na výkon hardware. Pro základní testovací provoz sta čí tém ěř jakýkoliv hardware. • Mnoho open-source řešení p římo ke stažení z internetu. • Velká zahrani ční, tak i česká komunita. • Od verze 5.0, kdy dostalo dobrou podporu objektov ě orientovaného programování, se p řibližuje plnohodnotným programovacím jazyk ům. Od verze 6 se má podpora objektového programování ješt ě více zlepšit. • Velké množství webhosting ů nebo free webhosting ů.

Zápory • Není t řeba alokovat/deklarovat prom ěnné. Sice to vypadá jako výhoda, ale u rozsáhlejších projekt ů je to nevýhoda. V případ ě p řeklepu v názvu prom ěnné vznikne nová prom ěnná a programátor nezjistí, že ud ělal chybu. Samoz řejm ě těmto chybám se m ůžeme n ěkolika zp ůsoby vyhnout. Zaprvé m ůžeme nastavit, aby nám PHP vypisovalo veškeré chyby v kódu, kde je i zaznamenáno, že daná prom ěnná nebyla deklarována. Toto varování dostaneme ale pouze v případ ě, kdy chceme danou prom ěnnou n ěkde použít, pokud bychom cht ěli do dané špatné prom ěnné p řiřadit n ějakou hodnotu tak nám to žádnou chybu nezobrazí. Zadruhé je možnost využívat kvalitní vývojové prostředí ur čené pro PHP, které

- 9 - při vytvá ření kódu a psaní prom ěnných nabízí již vytvo řené prom ěnné a tak nám to urychlí práci a p ředejdeme p řeklep ům. • Implicitn ě není odd ěleno PHP od HTML kódu. Tam kde vyžadujeme jejich oddělení, musíme si sami ur čit programovou strukturu, jakou to budeme psát, nap říklad MVC. Zárove ň to m ůže sloužit jako výhoda, že si člov ěk m ůže používat zápisy, jak sám uzná za vhodné. Problém m ůže nastat v případ ě, kdy se před ělává již existující kód anebo p ři spolupráci více programátor ů. • Není jednotné pravidlo pro názvy funkcí. N ěkteré víceslovné funkce jsou odd ěleny podtržítky, n ěkdy jsou spojené. • Při zm ěně verze mohou nastat problémy s některými funkcemi, které částe čně zm ěnily svoji funkci. Je proto n ěkdy pot řeba zm ěnit části kódu v celém projektu. Pokud si tyto zm ěny nezjistí programátor p řed použitím na nové verzi, mohou nemile nastat ne čekané problémy a pak dlouhé dohledávání jejich p říčiny. • PHP není kompilováno, ale interpretováno. Jeho spušt ění je tedy náro čnější na rychlost. Pokud se n ěkde v kódu vyskytuje n ějaká chyba, tak se na ni p řijde až v moment ě, kdy se prochází tou konkrétní částí kódu. P ři neúplném testování aplikace mohou pozd ěji nastat problémy, o kterých se d říve nev ědělo. Je zde tedy nutné provád ět pe člivé testování, i když to by se m ělo provád ět v každém případ ě.

1.1.3 Shrnutí

I když srovnávat ASP.NET a PHP moc nejde, jelikož ASP.NET je platforma a PHP je skriptovací jazyk, je pot řeba se rozhodnout , kterou cestou se dát.

ASP.NET nabízí velkou možnost vývoje aplikací, a to nejen webových aplikací, ale také softwaru. Tato možnost je ale úzce vázána na platformu Windows. Nechci se zde zabývat srovnáním kvality Linuxu nebo Windows, tím by se mohla zabývat kompletn ě samostatná práce. Bohužel pohodlí ve ě Windows je kompenzováno vyššími náklady. Nejenže by provoz serveru vyšel mnohem dráž, ale bylo by pot řeba zakoupit kvalitní vývojové prost ředí, nap říklad VisualStudio, a také se zú častnit n ěkolika školeních. Celkové náklady by ur čit ě p řesáhly sto tisíc. Z důvodu neznalosti žádného programovacího jazyka, ve kterém bych mohl tyto aplikace vyvíjet, bych se musel od

- 10 - za čátku n ějaký nau čit a časov ě by to bylo náro čnější, než by se funk ční aplikace povedla vytvo řit.

PHP je zato vázáno na platformu Linux, i když ne striktn ě, dá se použít i na platform ě Windows. Nízké náklady související s tímto jazykem jsou mnohem p řív ětiv ější, převážn ě pokud jedinec/spole čnost nemá velké finan ční možnosti. V PHP jsem za čínal již v roce 2001 a tak vyvíjet v něm rozsáhlejší aplikaci je pro m ě p řív ětiv ější. Při řešení problému se mohu obrátit na n ěkterou komunitu, diskusní fórum, nebo i n ěkteré hotové řešení.

V kone čné fázi se tedy p řikláním k řešení pomocí PHP. O čekávám, že to nebude krok špatným sm ěrem a celá aplikace bude vyhovovat všem požadavk ům.

1.2 Databázové systémy

Volba vhodného databázového systému je stejn ě d ůležitá, jako výb ěr vhodného programovacího prost ředí. Databáze nám umož ňuje, aby data nebyla izolována v samostatných soubor, ale zajiš ťuje nám organizování dat v komplexn ě centráln ě zpracované struktu ře. Centrální správa databáze, tzn. všechny implementa ční programy, jsou realizovány prost řednictvím speciálního programového vybavení, které se nazývá systém řízení báze dat SŘBD (database management system, DBMS). Ten spolu s databází tvo ří databázový systém DBS (database system).

Komunikace mezi aplikací a databázovým systémem je zajiš ťována pomocí jazyka SQL. Historie jazyka SQL spadá do 70. a 80. let. První standard byl p řijat v roce 1986, ozna čován jako SQL86. Časem se však projevily n ěkteré nedostatky. Opravená verze je z roku 1992 a je ozna čována jako SQL92. Ten je v oblasti rela čních databází standardem dodnes. Zkratka SQL zna čí Structured Query Language. Jazyk v sob ě zahrnuje nástroje pro tvorbu databází a dále nástroje na manipulaci s daty. SQL pat ří mezi tzv. deklarativní programovací jazyky, což v praxi znamená, že kód jazyka SQL nepíšeme v žádném samostatném programu, jako by tomu bylo nap ř. u jazyka C nebo Pascal, ale vkládáme jej do jiného programovacího jazyka, který je již procedurální. Se samotným jazykem SQL m ůžeme pracovat pouze v p řípad ě, že se terminálem p řipojíme

- 11 - na SQL server a na p říkazový řádek bychom zadávali p římo p říkazy jazyka SQL. Jak už jsem se zmínil, SQL se skládá z n ěkolika částí. N ěkteré části jsou ur čeny pro administrátory a návrhá ře databázových systém ů, jiné pak pro koncové uživatele a programátory. První částí jazyka SQL je jazyk DDL (data definition language). Jedná se o jazyk pro vytvá ření databázových schémat a katalog ů. Zp ůsob ukládání tabulek definuje jazyk SDL (storage definition language). Třetí částí pro návrhá ře a správce je jazyk VDL (view definition language), ur čující vytvá ření pohled ů. Poslední částí je jazyk DML (data manipulation language), který obsahuje základní p říkazy. S jazykem DML pracují nejvíce koncoví uživatelé a programáto ři databázových aplikací.

Dále se pokusím vypsat nejpoužívan ější databázové systémy, stru čně je popsat a vybrat z nich ten nejvhodn ější pro tento projekt.

1.2.1 MS SQL

V roce 1988 MS SQL za čalo jako sou část aplikace Sybase pro použití v OS/2. To byl po čáte ční vstup firmy Microsoft na databázový trh. První verze, která byla použita pro Windows, byla vydána v roce 1993 a byla to první verze SQL Serveru naprogramována pro NT. V roce 1994 následovalo rozd ělení od Sybase a MS SQL si šlo vlastní cestou.

Databázová tabulka zná p římo typ XML, do kterého lze XML dokument uložit. Je možné kontrolovat validitu t ěchto XML dat a také je možné p římo XML indexovat. Díky tomu se lze nad XML daty dob ře vyhledávat. Umož ňuje velmi dobrou integraci do opera čního systému. Nap říklad ve sledování výkonu lze velmi p ěkn ě sledovat nebo zobrazovat velké množství informací o provozu MS SQL. Je možné u MS SQL sledovat mnoho údaj ů o výkonu a efektivit ě tohoto serveru a nap říklad správn ě nastavených index ů. Nové možnosti nabízí typ sloupce uniqueidentifier. Jde o 16 bajtový GUID (globally unique identifier), který by m ěl být jedine čný v celé databázi a možná, že i dokonce na celém širokém sv ětě. GUID je ve formátu 936DA01F-9ABD-4d9d-80C7- 02AF85C822A8. Na GUID je p říjemné to, že ve skute čnosti jde o číslo a ne o řet ězec, jak vypadá na první pohled. Práce s čísly je u databází mnohem levn ější než s řet ězci. Navíc je zde možnost u takového typu sloupce nastavit automatické generování

- 12 - hodnoty. To je jako ekvivalent timestamp, který MS SQL samoz řejm ě také umí. Je to velmi užite čné, pokud v databázi pot řebujeme mít jedine čnou hodnotu p řes více tabulek, nebo pot řebujeme mít dokonce jedine čnou hodnotu p řes více databází. Nap říklad p ři pobo čkovém zpracování dat.

MS SQL nezná p říkaz INSERT INTO (sloupec1, sloupec2) VALUES (hodnota1, hodnota2), (hodnota3, hodnota4). Je tedy nutné pro každý řádek použít nový p říkaz INSET. To je zbyte čné jak programátorsky, tak to musí mít i negativní dopad na výkon.

1.2.2 Oracle

V roce 1977 spole čnost Relational Software Incorporated vyvíjí databázový systém nazvaný Oracle. V roce 1982 vyšla verze 3, která byla pro sálové po číta če, minipo číta če i stolní po číta če, kde již byla implementována podpora transak čního zpracování. Ve verzi 5 z roku 1985 byla již architektura klient - server a podpora distribuovaného zpracování. V letech 1992 – 1994 byla vytvo řena verze 7 pro platformy Unix a PC. Již v roce 1998 ve verzi 8 byla podpora rozsáhlých databází, nových datových typ ů pro ukládání obrazových a multimediálních dat a podpora objektov ě orientovaných technologií.

Oracle pat ří mezi nejznám ější databázové systémy a dokonce se dá tvrdit, že i mezi nejrozší řen ější databázové systémy používaná pro velké nasazení jako nap říklad v bankovním sektoru nebo velké nadnárodní spole čnosti. Tomu napomáhá zp řístupn ění pro celou řadu provozních platforem s tím, že z jednotlivých hardwarových produkt ů je vyt ěženo maximum, nap říklad v oblasti paralelního zpracování a nep řetržité dostupnosti. Nejv ětším konkurentem je samotný Oracle, kdy s každou verzí se snaží překonat tu stávající a držet se tímto stále na vrcholu. Kladen je také d ůraz na problematické zákoutí národních prost ředí a zvyklostí. Nejedná se pouze o znakové sady, ale například také o správnou práci s časem v různých lokalitách. Výhodou Oracle je komplexní sada produkt ů spojená s tímto databázovým systémem. Není zde tedy nutné využívat r ůzných řešení t řetích stran. Zde je jedinou výjimkou opera ční systém, ale díky multiplatformní podpo ře to není problém.

- 13 - Velkým kladem je jeho bezpe čnost, v jeho prosp ěch mluví spln ění podmínek mezinárodn ě uznávaných bezpe čnostních certifikát ů. Procesy související s uznáním certifikátu jsou dosti obtížn ě a je tedy možné toto považovat za bezpe čnostní kvalitu tohoto systému. Další nemén ě d ůležitou výhodou je vysoký výkon. Ten je dosažen díky konceptu gridu. Grid spo čívá v rozložení výpo četní kapacity mezi vzájemn ě propojenými po číta či. Vývojá ř se nemusí zabývat rozd ělením tohoto výkonu, ale celé to zajiš ťuje grid. Je jedno, zda jsou po číta če propojení stále nebo jen do časn ě. Na systém je kladen dotaz a ten je okamžit ě zpracován, a to p římo ve chvíli, kdy jej pot řebujeme provést a ne až v moment ě, kdy má dostupný po číta č volný výpo četní výkon. Rozložením výpo četního systému a maximálním využití dostupných výpo četních zdroj ů umož ňuje snižovat celkové náklady na celý výpo četní systém a snižuje se tímto pot řeba budovat stále větších systému. Oracle také nabízí nástroje pro audit celého systému. To umož ňuje sledování a analýzu systému bezpe čnostních hrozeb. Jeho dopl ňkem je také Oracle Database Vault. Ten umož ňuje administrátorovi databáze odebrat práva nad provozními daty, má tedy možnost pracovat jen s daty pro b ěžný provoz. Tímto se m ůžeme vyvarovat vnit řním bezpe čnostním chybám. Dále komprese dat nám pom ůže p ři velkém množství dat. Tato komprese je tak optimalizována, že nemá negativní dopad na vyhledávání. To nám celé umožní snižovat náklady na datové sklady. Dalším dopl ňkem je systém pro obnovu dat. Ten dokáže v případ ě ztráty dat doporu čit nejlepší postup, jak minimalizovat dopady nedostupnosti databázového prost ředí.

1.2.3 DB2

DB2 má velmi dlouhou historii a je považováno za nejstarší databázový produkt. Jméno DB2 dostalo v roce 1983, kdy ho IBM vydalo na své MVS platform ě. Dokonce i dalo za vznik nového jazyka SQL, které vzniklo z původního SEQUEL. Po n ěkolik let bylo DB2, jako plnohodnotný databázový systém, jako jediné dostupné na sálových po číta čích IBM. Pozd ěji IBM p řineslo DB2 to dalších platforem, v četn ě IS/2, Unix, Windows, Linux a PDA.

- 14 - Databázový systém DB2 se vyzna čuje vysokým výkonem a vysokou dostupností. Nechybí podpora paralelního zpracování, k dispozici je vícedimenzionálního clusteringu nebo automatické prost ředky pro správu a výkonnostní lad ění. Sou částí systému je technologie pro zotavení systému v případ ě havárie, možnost d ělení databáze do n ěkolika oddíl ů v případ ě v ětší databáze. V případ ě velkých tabulek je považována za výhodu podpora on-line reorganizace databáze s mechanismem p řesunu reorganizovaných blok ů dat bez nutnosti alokace dodate čného prostoru a časových nárok ů zpomalující b ěžný provoz. Nechybí zde ani možnosti komprese dat. P řináší to jak finan ční úsporu v nákladech na uchovávání dat, ale také zvýšení výkonu díky menšímu množství p řenášených dat. Výhodou je i možnost efektivního využití pam ěti v některých typech zpracování, když není t řeba dekomprimovat všechna zpracovávaná data. V případ ě rozsáhlého systému, kdy je infrastruktura rozmíst ěna ve více lokalitách, přichází vhod replika ční technologie. Tak jako u p ředešlých databázových systém ů, ani zde nechybí podpora XML dat. Umož ňuje nativní uložení v četn ě rychlého zpracování nebo zm ěn jednotlivých částí XML dokumentu a ne jen jako celku. K dispozici je podpora nestrukturovaných dat, jako nap říklad obrázky, multimediální data nebo videa. Sou částí jsou také rozší ření pot řebná pro práci s prostorovými daty. K dispozici je propojení libovolných dat s prostorovými, lze využít rychlé a prostorové indexy nebo mapová projekce. Je tedy vhodné pro analytická řešení, a tedy i často nasazováno pro datové sklady. Má také podporu integrace do VisualStudia nebo podporu distribuovaného lad ění. V rámci bezpe čnosti jde ud ělovat práva až na jednotlivé záznamy nebo sloupce.

1.2.4 PostgreSQL

PostgreSQL je rela ční databázový systém s otev řeným zdrojovým kódem. Je ší řen pod licencí BSD, která umož ňuje volné spojování otev řeného kódu s uzav řeným. Často je srovnáván s další rozší řenou otev řenou databází MySQL. Předch ůdcem byl systém Ingres vyvinutý v letech 1977 – 1985 na kalifornské univerzit ě v Berkley. Jeho nástupce byl vyvíjen jako objektov ě-rela ční databázový server pod názvem Postgres. Pozd ěji byl dopln ěn o podporu jazyka SQL a byl ozna čen Postgres95. V lét ě 1996 byl sestaven tým

- 15 - lidí, kte ří pokra čovali na vývoji jako open-source a nezávisle na univerzit ě. Na konci roku 1996 byl projekt p řejmenován na PostgreSQL.

Je to multiplatformní systém, tedy lze jej provozovat na opera čních systémech Linux, Unix, Windows, Mac OS X a další. I p řes to, že má podporu pro Windows, tak na tomto systému nefunguje na 100%. Mnoho vývojá řů , kte ří se snažili nasadit PostgreSQL na Windows a velmi brzy museli bu ď p řejít na jiný databázový systém, nebo použít PostgreSQL na jiném opera čním systému, kde je nejvíce doporu čován Linux/Unix. PostgreSQL umož ňuje b ěh uložených procedur napsaných v několika programovacích jazycích, v Perlu, v Pythonu, v jazyku C nebo v speciálním PL/pgSQL, který vychází z PL/SQL vytvo řený firmou Oracle. Předností systému PostgreSQL je rozší řitelnost. Systém m ůže být bezproblémov ě rozši řován o nové datové typy, funkce, operátory, agrega ční funkce, procedurální jazyky. Díky tomu mohla vzniknout spousta rozší ření, n ěkterá jsou i voln ě ke stažení na internetu. I p řesto, že je konkuren ční MySQL rychlejší než PostgreSQL, tak to platí pouze u menší zát ěže serveru a základních p říkaz ů. P ři vyšší náro čnosti se vyrovná v rychlosti s MysSQL, n ěkdy dokonce je i rychlejší. Replikace databáze je zde stejn ě možná, jako u komer čních databázových systém ů. Není p římo jeho sou částí, ale je t řeba ji doplnit pomocí rozší ření. Rozší ření pro replikaci je n ěkolik a nejpoužívan ější je asi Slony. Stejným zp ůsobem je zde podporován i clustering.

1.2.5 MySQL

MySQL je databázový systém, který p ůvodn ě vznikl v roce 1996 vytvo řen firmou TcX, nyní vyvíjen švédskou firmou MySQL AB, kterou nedávno koupila firma Sun Microsystems. Je považován za úsp ěšného pr ůkopníka dvojího licencování. Je k dispozici jak pod bezplatnou licencí GPL, tak pod komer ční placenou licencí.

MySQL je plnohodnotný multiplatformní systém. Oproti PostgreSQL se dá bezproblémov ě použít jak na Linuxu, tak na Windows.

- 16 - Je řazen mezi nejrychlejší databázové systémy. Ur čit ě se nedá jeho výkon srovnávat s Oracle a jeho grid technologií, ale firma Google by ur čit ě mohla potvrdit, že je reálné ho využít na projektu s obrovským množství dat, jelikož sami jej používají pro mezinárodní internetový vyhledava č Google a jeho výsledky b ěhem vyhledávání jsou zpracovány opravdu rychle. V Česku je to nejrozší řen ější databázový systém, p řevážn ě mezi za čínajícími vývojá ři, nízkonákladové firmy a studenty. P řispívá k tomu také fakt, že p řevážná v ětšina českých free webhosting ů a placených webhosting ů používá práv ě databázový systém MySQL. MySQL není tolik náro čné na instalaci a konfiguraci, tudíž mnohem jednodušší pro provozovatele webhosting ů. Díky takové oblíbenosti je v Česku komunita kolem MySQL mnohem v ětší než kolem ostatních databázových systém ů. Také hodn ě tutoriál ů, návod ů nebo open-source aplikací týkající se p řevážn ě webových aplikací nebo programovacím jazyk ům, používají práv ě MySQL. Tedy spousta za čínajících vývojá řů za čínají na MySQL a mnohdy u n ěj také z ůstanou. Je to také zap říčin ěno bezplatnou licencí. Dříve bohužel nepodporovalo pohledy, triggery a uložené procedury, které našt ěstí jsou již v posledních letech podporovány. Jelikož tato podpora se objevila mnohem pozd ěji než u ostatních nejrozší řen ějších databázových systém ů, p řišlo tak MySQL o spoustu svých p říznivc ů, kte ří takto p řešli na jiný databázový systém.

1.2.6 Shrnutí

Databázový systém MS SQL je ur čit ě kvalitn ě provedený systém s dobrými funkcemi. Jeho výhoda oproti konkurenci jsou p řevážn ě dobré nástroje na sledování a analýzu chodu celého databázového systému. Bohužel je vázáno na opera ční systém Windows. Na první pohled to m ůže být také jeho výhoda, jelikož s propojením s dalšími aplikacemi od firmy Microsoft m ůže vzniknout spolehlivý a výkonný webhosting, bohužel tato možnost p řipadá v úvahu pouze p ři použití ASP.NET.

Shledávám Oracle jako nejkvalitn ější produkt na poli databázových systém ů. Jeho výhody a síla oproti ostatním systém ům je z řejmá. Bohužel jeho velké finan ční nároky jak na jeho zakoupení, tak i provoz, jsou obrovské. Pro využití tohoto databázového

- 17 - systému bych se rozhodl v případ ě, kdybych ho cht ěl použít na rozsáhlý projekt provozovaný na v ětším množství serverových stanic a velkým finan čním kapitálem.

DB2 se mi nezdá jako nejlepší řešení pro nasazování na b ěžné projekty. Pat ří mezi pouze komer ční produkty a pro b ěžné projekty nep řinese nic závratného. Opakem by bylo, kdyby bylo pot řeba mít datový sklad. V tomto p řípad ě bych volil práv ě DB2, kde je podpora prostorových dat a index ů, mapové projekce a další možnosti, které jsou pro datové sklady p řínosem.

Mezi nekomer čními databázovými systémy bezpochyby vládne PostgreSQL. I když samotný systém nemá funkce, kterými by vynikal, jeho rozší ření z něj mohou ud ělat silný nástroj, mnohdy je uvád ěno, že se blíží k systému Oracle. Databázový systém Oracle se mi jeví jako nejlepší řešení pro st ředn ě velké projekty, kdy se už využívá i více databázových serveru napojených na sebe. Velkou výhodou je samoz řejm ě také jeho bezplatná licence.

MySQL je nejv ětším rivalem PostgreSQL. MySQL se našt ěstí p řed pár lety vzpamatovalo a doplnilo si funkce, za které bylo kritizováno, že mu scházejí. Tím se může znovu srovnávat s ostatními kvalitními databázovými systémy. Volba mezi MySQL a PostgreSQL závisí na konkrétním projektu, který se má realizovat. Pro tento projekt je ale MySQL po stránce funkcionality zcela dosta čující a navíc oproti PostgreSQL vykazje rychlejší výkonnostní časy, kdy tuto vlastnost uvítám. Nep ředpokládám u tohoto projektu složité dotazy na databázový systém a tak MySQL zůstane pro nás stále rychlejším řešením.

1.3 Cíl práce

V předchozích kapitolách jsme si p ředstavily možné programovací jazyky pro vývoj webových aplikací a databázové systémy. V dalších částech práce se budu zabývat řešením aplikace, naprogramovaným pomocí PHP, využívající databázový systém MySQL a to celé pob ěží na opera čním systému Linux, kde mají oba dva stoprocentní podporu.

- 18 - 2 Analýza problému a sou časná situace

První možnost, která p řipadá v úvahu je využití open-source systému. Tato možnost se zdá být výhodn ější než vytvá ření celého systému úpln ě od za čátku.

Všechny systémy, kterými se budu zabývat, budou ší řeny pod licencí GNU GPL. GNU GPL licence dává každému právo instalace softwaru za úplatu a jde spolu s administrací asi o nej čast ější placený úkon spojený s „GPL softwarem“. Je zde také právo na poplatek za distribuci tohoto software, což je jedním ze základ ů „free“ softwaru (nap ř. u freewaru nesmí být poplatek ani za distribuci). Proto m ůžeme za distribuci vyžadovat peníze, nesmí to být ovšem cena za program. Kdokoliv m ůže tyto zdrojové programy z licence GNU GPL p řeložit na p říslušnou platformu, lokalizovat, p řidat manuály, instala ční program, zabalit a prodat. V cen ě nesmí být zahrnuty zdrojové programy použité z licence GNU GPL. Dále platí, že uživatel, který daný software jakýmkoliv zp ůsobem obdrží, by ť za úhradu, ho m ůže dále modifikovat, kopírovat a dále nabízet ke stažení zdarma či za poplatek popsaný výše. Licence GNU GPL se vztahuje pouze na software pod ní ší řený, autorská práva na grafický design, texty a t řeba fotografie, tedy obsah stránek je stále v držení jeho autora. Licenci softwaru nelze m ěnit. Pokud je jakýkoliv software ší řen pod licencí GNU GPL, musí takto být ší řen nadále.

Dalším, samoz řejm ě také d ůležitým kritériem bylo, aby všechny systémy byly vytvo řeny v jazyce PHP a využívaly databázový systém MySQL.

Open-source systém pro e-shop je mohutné nástroje. Obsahuje stovky funkcí a nastavení. Kategorie zboží a jejich obsah umož ňuje neomezený po čet jazykových mutací, grafické návrhy a možnost vlastních úprav vzhledu a funk čnosti, nastavení zp ůsobu prodeje, objednávek, doru čení a plateb. U n ěkterých systém ů má každý zákazník má vlastní administra ční prost ředí, kde p řehledn ě vidí svou historii objednávek, jejich stav zpracování, veškerou komunikaci mezi ním a vámi.

Systém samoz řejm ě umož ňuje evidenci skladových zásob, upozornění na podlimitní stav, zboží na cest ě, výprodej, slevy a další nutné funkce pro každý e-shop.

- 19 - Přehledná správa objednávek a jejich stav vy řízení. Informace o zákaznících, rozesílání novinek a hromadnou korespondenci. Umož ňuje také vést e-shop v n ěkolika měnách a automaticky p řevádí ceny podle zadaných kurz ů. Umož ňuje hromadnou aktualizaci zboží nap říklad importem excelovských tabulek a podobn ě. Pro pot řebu dalších funkcí a nastavení existují tisíce zásuvných modul ů, které e-shop rozši řují a umož ňují tak další funkce, nap říklad reklamní bannery, zálohování, export XML soubor ů do seznam ů katalog ů, SEO nástroje a podobn ě.

Software zvládá od jednotlivých produkt ů až po webové servery s desítkami tisíc položek (zde již bývají velké hardwarové požadavky a doba vykonávání skript ů). Pro všechny tyto funkce a možnosti je to oblíbený nástroj pro miliony spokojených uživatel ů po celém sv ětě další miliony jejich spokojených zákazník ů. Rozsáhlá komunita uživatel ů již vy řešila mnohé možnosti a možné i nemožné problémy spojené s internetovým prodejem a na specializovaných fórech v ěnovaných danému systému se dají nalézt informace o jakémkoliv nastavení a možnostech toto software.

2.1 ZenCart

ZenCart je kompletní e-shop se vším všudy – kategorie zboží, detaily zboží s řadou fotek, možnosti r ůzných variant zboží (nap ř. barva, velikosti), samoz řejm ě košík, r ůzné zp ůsoby zaplacení, nastavení poštovného podle hodnoty objednávek a mnoho dalších možností.

ZenCart je jeden s nejvíce rozší řených e-shop systém ů. Popularity se více do čkal v zahrani čních zemí než v Česku, a to p řevážn ě z důvodu d říve nepodporované češtiny. Nyní má tento systém u nás českou komunitu v četn ě diskusního fóra, kde mohou registrovaní uživatelé řešit své problémy s instalací a úpravami. O oblíbenosti ZenCartu sv ědčí jeho vysoká používanost, což lze považovat za jednu z nevýhod.

Klady • Česká komunita, v četn ě diskusního fóra. • Podpora českého prost ředí a česká lokalizace. • Spousta grafických šablon, a to jak zdarma, tak i placené.

- 20 -

Zápory • Velká náro čnost na databázový server. P ři jednom znovuna čtení stránky se provede p řibližn ě 500 – 800 SQL dotaz ů na databázi. Po čet dotaz ů se dále zvyšuje s nar ůstajícím množství záznam ů. • Složité zápisy zdrojového kódu. To zap říčiňuje velmi staré jádro systému. Toto je velká slabina v rámci využívání tohoto systému pro komer ční nasazování tohoto systému. Je to tedy vhodné nasadit pouze pro zájemce, kterým vyhovují sou časné možnosti systému, anebo jeho zásuvných modul ů. • Pro správce systému je zpo čátku složité spravovat samotný e-shop, a to z důvodu složitého administra čního prost ředí, které obsahuje spoustu mnohdy nepot řebných nastavení a možností. • S novou verzí m ůžete p řijít o vzhled a vlastní doprogramované v ěci

2.2 OpenCart

OpenCart je zajímavým e-shop systémem, který je dobrou alternativou k oblíbeným systém ům jako je nap říklad ZenCart. Oproti nim zatím neobsahuje tolik funkcí a zásuvných modul ů, avšak p ůsobí mnohem elegantn ějším a p řehledn ějším dojmem. Česká lokalizace není standardní sou částí systému.

Klady • OpenCart vypadá jednoduše a p řitom má asi všechno, co menší internetový obchod pot řebuje. Jednoduchý je také v administraci. • Grafické šablony, a to jak zdarma, tak i placené. • Aplikace je napsána objektov ě a snaží se dodržovat odd ělení jednotlivých vrstev architektury.

Zápory • Česká lokalizace není k dispozici. Našt ěstí na českém internetu se dají najít balí čky s českou lokalizací, kterou je možné dodate čně dohrát, a zárove ň je nutné provést menší úpravy v kódu týkající se komunikace PHP s databází (kódování znakové sady).

- 21 - • Česká lokalizace je sice ke sta čení na oficiálních stránkách aplikace, ale má několik problému. Nejv ětší asi je, že není kompletní, jedná se hlavn ě o administrátorskou část. Kdyby texty byly alespo ň v angli čtin ě, tak lze zjistit chyb ějící texty a dod ělat je, problém je, že pokud není nalezen odpovídající text, nezobrazí se nic. • Na problém lokalizace navazuje problém s dopl ňky, ty jsou vázaný na jazyk, takže pokud se poda ří češtinu sehnat, tak zmizí všechny dopl ňky.

2.3 OsCommerce

OsCommerce je e-shop ur čený zejména pro neprofesionály a za čáte čníky. Má jednoduchý kód a jeho instalace je velice rychlá a intuitivní.

Klady • Obsahuje p řehledný systém podpory reklamy. • Grafické šablony, a to jak zdarma, tak i placené. • Obrovská komunita, ale p řevážn ě na zahrani čních serverech.

Zápory • Staré jádro systému. Vhodné pro za čáte čníky v programování v PHP, ale nevhodné pro komer ční využití a jeho vylepšování. • Slabší funkcionalita oproti ZenCartu. • Vyžaduje podobnou náro čnost serveru jako ZenCart.

2.4 VirtueMart (Joomla)

VirtueMart je open-source internetové komer ční řešení, internetový obchod a rozší ření pro redak ční systém Joomla a . Joomla je jeden z nejvíce používaných redak čních open-source systém ů. Historicky se vyvíjí ze svého dnes už konkurenta Mambo. Může se provozovat jako internetový obchod, p řípadn ě poue jako katalog zboží pro web.

- 22 - Klady • Podpora českého prost ředí a česká lokalizace. • Velké množství šablon zdarma. • Velká česká komunita. • Objektov ě orientované programování • Softwarová architektura MVC

Zápory • Nemá všechny pot řebné funkce jako plnohodnotný e-shop systém. • Náro čný na databázový server. Oproti systému ZenCart vykazuje databázové zatížení na po čet dotaz ů pouhých 10%, ale stále je to 10krát více, než by bylo vhodné.

2.5 Magento

Magento je nový profesionální systém pro tvorbu e-shopu, který se rychle rozr ůstá a vyniká p ředevším svou moderností a uživatelskou p říjemností. Funk čně se Magento pln ě vyrovná nejpopulárn ějšímu e-shop systému ZenCart. Jádro systému je postaveno na Zend Frameworku.

Klady • Podpora českého prost ředí a česká lokalizace. • Česká komunita, která se velmi dynamicky rozr ůstá. • Jádro systému je postaveno na Zend Frameworku. • Intuitivní administra ční rozhraní.

Zápory • Spousta částí nedodržuje aplika ční logiku Zend Frameworku. • Pomalejší vykonávání dotazu, v ětší hardwarové nároky. • Na n ěkterém webhostingu se neda ří tento systém úsp ěšn ě funk čně provozovat.

- 23 - 2.6 Shrnutí

Výše uvedené systému se budu snažit charakterizovat do spole čných rys ů.

Velkou výhodou těchto systém ů jsou komunity jak v Česku, tak i v zahrani čí. Jelikož jsou všechny systému zahrani čních vývojá řů , nejv ětší komunity se práv ě objevují na zahrani čních mezinárodních serverech. To také vyžaduje, aby správce systému m ěl znalost anglického jazyka. Další výhodou jsou rozsáhle galerie a seznamy grafických šablon. Bohužel tohle není výhoda, která by se týkala mého p řípadu, kde bych nevyužíval p ředvytvo řených šablon, ale vytvá řely by se zcela unikátní grafické návrhy stránek.

Hlavní nevýhodou všech systém ů je jejich hardwarová náro čnost. U starších systém ů se to projevuje ve velkém zatížení databázového serveru, u nejmladšího systému Magenta je tento problém v náro čnosti vykonání skript ů. V obou p řípadech vznikají problémy na dvou stranách. Zaprvé je pot řeba zajistit výkonný webhosting, a i na výkoném webhostingu to bude zpomalovat celkové zpracování serveru. Zadruhé se problém objevuje na stran ě klienta, kdy klient musí čekat mnohdy i n ěkolik sekund, než se mu stránka na čte. Samoz řejm ě n ěkolik sekund se zdá být jako zanedbatelná doba, ale v dnešní dob ě, kdy v ětšina domácností má vysokorychlostní internet a stránky se jim na čítají pr ůměrn ě za jednu sekundu, tak poznají zpomalení na čítání, které bude několikanásobn ě pomalejší než i jiných stránek a rad ěji p řejdou na jiný internetový obchod, který bude nabízet stejný sortiment.

Záv ěrem bych uvedl, že žádné řešení již hotového open-source systému mi nep řišlo natolik vyhovující, aby na n ěm šly stav ět e-shopy dle mého o čekávání. Volím tedy další možnost, kdy celou aplikaci vytvo řím celou sám a nebudu p řebírat již hotové řešení.

- 24 - 3 Teoretická východiska práce

Databázovým systémem se již v této kapitole zabývat nebudu. Je ale pot řeba se ješt ě blíže v ěnovat programovacímu jazyku.

Dříve p ři vzniku programovacích jazyk ů se po čítalo, že se bude s programovacím jazykem pracovat tak, jak jsou jeho možnosti navrhnuty, a tento zp ůsob je ozna čován jako „procedurální“ programování. Pozd ěji se ukázalo, že je vhodné p ří programování využívat tzv. objekty a z toho vzniklo i objektov ě orientované programování. Tyto objekty daly programování úpln ě jiný sm ěr a umožnilo vznik framework ům.

3.1 Co je to framework?

Framework je balík naprogramovaných objekt ů, kdy je definováno, jakým zp ůsobem se mají objekty používat, popis jejich funkcí, jak je modifikovat, p řípadn ě jak vytvá řet zcela nové. Některá pravidla je nutné dodržet kv ůli základní funk čnosti frameworku, n ěkterá pravidla jsou jen jakýmsi „doporu čením“, kdy to napomáhá při orientování se ve d říve vytvo řených aplikací nebo ve zdrojovém kódu napsaném n ěkým jiným. Samoz řejm ě žádný framework nem ůže m ěnit základní pravidla syntaxe daného programovacího jazyka, ty vždy z ůstávají. Framework nám také m ůže urychlit práci. P ři dob ře definovaných pravidlech a využití vhodné aplika ční architektury nám velmi zkrátí čas na vývoj aplikací. Jsou vytvá řeny 3 typy framework ů. Zaprvé soukromé frameworky, kdy si programátor sám vytvo ří framework pouze pro vlastní využítí. Zde je nevýhoda strávení spoustu času nad jeho vytvá řením, testováním, opravováním, modifikováním nebo rozši řováním. Zadruhé jsou tou frameworky vytvo ření v týmu programátor ů ur čité firmy. Zde se již mohou role na vývoji frameworku rozd ělit mezi jednotlivé programátory. Tyto frameworky bývají striktn ě uchovány v know-how dané firmy a mimo firmu se neší ří. T řetí a nejrozší řenějším řešením jsou frameworky vytvá řeny týmem nezávislých vývojá řů , kte ří ani nemusejí spolu pracovat na stejných projektech, ale spolupracují na vývoji daného frameworku. Tyto frameworky jsou dále voln ě nabízeny spole čnosti, což nabízí velký potenciál hlavn ě pro testování. Týmy se

- 25 - postupn ě rozr ůstají o nové programátory a kolem frameworku vznikají komunity vývojá řů využívající tento framework pro vlastní ú čely. Práv ě tou t řetí možností voln ě ši řitelného frameworku se budu chtít zabývat. Vytvo řím přehled n ěkolika nejpoužívan ějších PHP framework ů a vyberu nejvhodn ější. Výb ěr frameworku bude p řevážn ě m ůj subjektivní názor a vlastní p ředpoklad, která framework se v budoucnu bude nejlépe vyvíjet. Frameworky v PHP jsou celkem mladou záležitostí několika let, a tak řada jich je stále ješt ě ve vývoji a ladí se nalezené problémy a chyby.

3.2 Voln ě ši řitelné PHP frameworky

Zend Framework Mezi nejznám ější PHP framework dozajista pat ří Zend Framawork, podporovaný p římo firmou Zend, která vyvíjí jádro PHP. Jeho za čátky sahají do roku 2005 a nyní je dostupné ve finální verzi 1.8. Celý framework je objektov ě orientovaný a implementovaný v PHP 5. Většina frameworku vznikla za ur čitým ú čelem, kdy postupn ě jak se framework vyvíjel, dospíval k obecn ějšímu použití. Zend Framework byl od po čátku stav ěn pomocí modulárních balí čků, kdy mají t řídy jasn ě strukturované pojmenování a je možné r ůzné balí čky používat také samostatn ě. Částe čné závislosti mezi komponentami avšak existují. Návrhy t říd jsou striktn ě vytvá řeny podle návrhových vzor ů. Je kladen d ůraz na to, aby si programátor mohl t řídy sám rozši řovat. Zend Framework jako celek využívá návrhový vzor MVC, což je aplika ční architektura, odd ělující od sebe model-view-controller. Zend Frameworku je p řevážn ě vy čítána jeho rychlost, kdy zaostává za svou konkurencí.

Prado Prado je komponentový framework, který byl jako jeden z prvních PHP framework ů napsán pro kdysi nové PHP 5, ale p ůvodn ě byl napsán pro PHP 4 v roce 2004 a jeho zakladatelem je Qiang Yue. Aktuáln ě je ve verzi 3.1.4. Obsahuje více než sto tisíc řádk ů kódu a okolo p ěti set t říd. Qiang Yue si nevzal za vzor Runy on Rails jako v ětšina PHP framework ů, ale inspiroval se spíše ASP.NET a Borland . nicmén ě tato inspirace je více vid ět ve starších verzí, nyní již p řibývá mnoho nových komponent ů a m ění se funk čnost. Prado je komponentový framework využívající programování událostí. Komponentový framework se liší oproti ostatním tím, že se nezobrazí uživateli taková

- 26 - stránka, na kterou kladl požadavek, ale jednotlivé komponenty jsou rozmíst ěny na stránce a existují zcela nezávisle. Toho je samoz řejm ě dosaženo za pomocí JavaScriptu a technologii , kdy mezi klientským webovým prohlíže čem a webovým serverem probíhá komunikace, aniž by muselo dojít k znovu načtení celé stránky. Uživateli se tedy zobrazí na daném míst ě pouze ten nový obsah, o který žádal. Prado dále nabízí odd ělení prezentace od aplika ční logiky, konfiguraci pomocí XML soubor ů, modulární architekturu a další, v dnešní dob ě snad už standardní, možnosti jako nap říklad validace vstupních, autorizace nebo autentizace. Celkov ě je Prado pr ůlomovým frameworkem a vytvá ří zcela nový p řístup k vytvá ření PHP aplikací.

Symfony Symfony je PHP framework od firmy Sensio Labs. Je zam ěř en na urychlení vytvá ření a údržby webových aplikací tím, že odstra ňuje opakované psaní kód ů. P řístup Symfony je zas odlišný od ostatních framework ů. Na server se nenahrává pro každou webovou aplikaci vlastní Symfony, ale nahraje se na server mimo dosah webového p řístupu a tak, aby na n ěj m ěly všechny aplikace p řístup, nejlépe nad rámec webových aplikací. Navíc ke v ětšin ě funkcí se dá p řistupovat p řes p říkazovou řádku. V adresá ři webové aplikace je obsah, který má být p řístupny z webu, ale veškerá aplika ční logika, v četn ě konfigurace, je v Symfony. Konfigurace Symfony využívá kaskádový p řístup, tedy nejvyšší je konfigurace frameworku, ta m ůže být p řenastavena konfigurací projektu a dále pokra čuje aplikace a modul. Celá konfigurace j provád ěna pomocí jazyka YAML. Dalším p řínosem od Prado je, že se nemusíte zabývat tvorbou administra čního prost ředí pro danou webovou aplikaci, ale Prado ho automaticky vytvo ří za nás.

CakePHP CakePHP se nechalo také inspirovat po vzoru . Vzniklo v roce 2005, kdy Ruby on Rails získalo svoji popularitu. Nyní je vyvíjeno firmou Cake Software Foundation, Inc. a jeho aktuální verze je 1.2.2.8120. CakePHP není p římo bránou Ruby on Rails do sv ěta PHP, ale p řivlastnilo si n ěkteré jeho postupy. Jako snad jediný PHP framework pat řící mezi nejrozší řen ější není použitelný pouze na PHP 5, ale je také zp ětn ě kompatibilní s PHP 4. Aby se mohlo CakePHP dál vyvíjet, ur čit ě si nebude moct již dlouho podporu PHP 4 udržet, kv ůli nedostate čné podpo ře objektového

- 27 - programování v PHP 4, a navíc zabývat se v dnešní dob ě verzí PHP 4 je bezpředm ětné a neefektivní. CakePHP využívá, tak jako Zend Framework, návrhový vzor aplika ční architektury MVC (model-view-controller). Nabízí také CLI (command-line interface), neboli možnost práce p řes p říkazovou řádku, kde požadavky jsou provád ěny p řes tzv. „cake“ p říkazy. CakePHP není modulární, je tedy nutné vždy využít celkového konceptu CakePHP.

Nette Nette je PHP framework od českého autora Davida. Je napsaný v PHP 5 s plným využitím objektov ě orientovaného programování. A čkoliv vznikl už v roce 2004, teprve nedávno byl uvoln ěn jako open-source a zp řístupn ěn ve řejnosti. Je to řádný p řípad situace, kdy framework vytvo řit jeden programátor pro vlastní použití, ale postupem času vyšlo najevo, že jedin ě jako open-source řešení má možnost se rychleji a lépe rozši řovat o nové funkce. Vyrostla kolem n ěj aktivní skupina českých PHP vývojá řů a už jej využívají i n ěkteré významné české spole čnosti. Nette je koncipováno jako „otev řený“, je tedy možné ho používat i v primitivních webových aplikacích nebo spole čně s jiným otev řeným frameworkem, jako je nap říklad Zend Framework. Zajímavou výhodou je jeho debugovací nástroj zvaný „Lad ěnka“. V klasickém p řípad ě, kdy ud ěláte p ři programování PHP chybu, zobrazí se chybová hláška, kde neznalý programátor v této problematice t ěžce dohledává chybu. P ři zapnutí debugovací nástroje je chování mnohem p řív ětiv ější k vyhledání dané chyby, vypíše to jednoduše, v kterém objektu nastala chyba a také zobrazí část PHP souboru s jeho kódem a zvýrazní kód, kde se chyba vyskytla.

3.3 Výb ěr frameworku

Z výše uvedených PHP framework ů bych vybral pouze 3, o kterých se vyplatí přemýšlet jako o možném řešení. Jedná se tedy o Zend Framework, Prado a Symfony. Ostatní 2 jsou sice také zajímavé, ale nep řinášejí žádné nové funkce, ale jsou spíše menším brat říčkem jiného frameworku.

- 28 - CakePHP má blízko k Zend Frameworku, kdy má sice možnost práce p řes p říkazový řádek, ale kompatibilita s PHP 4 ho posouvá na žeb říčku sm ěrem dol ů, nehled ě na to, že má i mnohem mén ě funkcí.

Nette se svým komponentním zpracováním podobá Prado. V budoucnu m ůže mít potenciál stát se siln ějším nástrojem, ale jeho konkurence je zatím v pokroku dále a to hlavn ě díky delší dob ě, kdy jsou známy pro širokou ve řejnost. Dále je Nette zatím ší řeno jen v Česku, což mu zatím dává také omezení v růstu. I p řes to, musím pochválit jeho debugovací nástroj.

Všechny t ři hlavní frameworky nabízejí rozdílný p řístup k programováním a ur čit ě mají tímto i své výhody, záleží tedy jen na použití, pro které ho chceme využívat. Zde bych vyzvednul u Zend Frameworku jeho obrovský potenciál v komunit ě, Prado má zajímavý p řístup pomocí komponent ů a AJAXu a Symfony šet ří místo a práci díky uložení Symfony na jedno místo pro všechny aplikace a dále kvalitním generováním administra čního rozhraní.

Vít ězem je pro m ě Zend Framework. Velká komunita je pro m ě velkým aspektem, kdy se i jeho potenciál ukazuje na rychlém vývoji, kterým doslova „probíhá“. Má sice slabost, a to v pomalejším výkonu, ale v ěř ím, že tento hendikep bude brzy odstran ěn. Někde se m ůžeme také do číst o jeho složitosti. To bych ale nebral jako nevýhodu a už vůbec ne jako aspekt pro výb ěr frameworku. Je to jako bychom vybírali programovací jazyk podle složitosti, ale p řitom nám jde o to, aby zvládal vše, co pot řebujeme, a v moment ě, kdy se nau číme daný framework správn ě používat, bude velmi mocným nástrojem pro vývoj.

3.4 Bližší seznámení se Zend Frameworkem

Dále se budu snažit blíže p ředstavit Zend Framework. Nebudu se již zabývat teoretickým p řehledem, co umí, ale budu již pojednávat do hloubky jeho funkci.

- 29 - Zend_Controller

Jádrem Zend Frameworku je Zend_Controller. Je to balí ček, který se stará o obsloužení požadavku, vytvo ření modelu a vyrenderování view. Je postaven na návrhovém vzoru aplika ční architektury MVC (model-view-controller) a Front_Controller, který zajiš ťuje aby všechny požadavky šly p řes jeden objekt, který rozhodne, která akce kontroler ů požadavek obslouží.

Obrázek 2 - Základní adresá řová struktura v Zend Framework

Cyklus obsluhy požadavku probíhá následovn ě: 1. V bootstrapu (index.) se zavolá metoda Front_Controlleru run nebo dispatch, která za čne obsluhovat požadavek. Pokud nebyly p ředány instance objekt ů Zend_Controller_Request a Zend_Controller_Response, tak jsou vytvo řeny. 2. Dalším krokem je routování. Routování probíhá na základ ě URL adresy. Defaultn ě se po čítá, že tvar URL bude ve tvaru domena/:modul/:kontroler/:akce , pokud chceme, aby routování probíhalo jiným zp ůsobem, sta čí pro Zend_Controller_Front nadefinovat nová pravidla routování. 3. Nyní vykonává svoji práci Zend_Controller_Dispatcher, který na základ ě názvu kontroleru a jeho akce vytvo ří jeho instanci a zavolá p říslušnou metodu.

- 30 - Dispatcher pracuje s danou konvencí v názvech kontroler ů a akcí. Název kontroleru bude p řeložen na názevkontroleruController a název akce na názevakceAction . 4. V příslušné metod ě kontroleru dojde na napln ěné modelu dat. Tento bod m ůže probíhat i ve smy čce. Je tedy možné z ur čité metody volat další metody, a to i v jiných kontrolerech. 5. Dojde k vyrenderování view a jeho nastavení do objektu Zend_Controller_Response.

Obrázek 3 - Cyklus požadavku v Zend_Controlleru

- 31 - To byl ve zkratce vý čet základních bod ů, kterými prochází obsloužení každého požadavku. Zend Framework dále obsahuje t ři typy objekt ů, které m ůžeme použít p ři obsluhování požadavku: • Pluginy – můžeme je napojit na cyklus obsluhy požadavku a mají p řístup k Zend_Controller_Request a Zend_Controller_Response. Cyklem jsou myšleny následující události: za čátek routování, konec routování, za čátek dispatchování, za čátek dispatchovací smy čky, konec dispatchovací smy čky, konec dispatchování. Na kteroukoliv z těchto událostí se v pluginu m ůžeme napojit a modifikovat ji. • Action Helpery – jsou podobné plugin ům v tom sm ěru, že mají p řístup k událostem. V tomto p řípad ě se ale jedná o jiné události, respektiv ě: inicializace kontroleru, p řed zavoláním metody v kontroleru, po zavoláním metody v kontroleru. M ůžeme k nim p řistupovat staticky nebo p římo v kontroleru. • View Helpery – tyto pomocné skripty slouží pouze pro views. Zde není jejich význam pro zm ěnu p ři zpracování požadavku, ale pouze nám pomáhají p ři zpracování výstupu. Nap říklad se dají použít pro generování formulá řů , opakovan ě zapisované kódy, stránkování, formátování a další.

Zend_DB

Balí ček Zend_Db je brán také jako jádro Zend Frameworku, i když n ěkte ří uživatelé s ním nejsou spokojeni a místo n ěj používají bu ď vlastní t řídy na práci s databází nebo převzatou z jiného frameworku. Zend_Db nabízí abstrakci nad p řístupem k databázi podobn ě jako PDO.

Třída Zend_Db_Select umož ňuje skládat SQL p říkazy a generovat SQL p říkaz podle dialektu použitého databázového systému.

Zend_Db_Table je t řída pracující s tabulkami a řádky tabulky jako se skute čnými objekty. Jedná se o implementaci návrhového vzoru Table Data Gateway a Row Data Gateway u objektu Zend_Db_Table_Row. Bez explicitního mapování lze p řistupovat

- 32 - k sloupc ům tabulky jako kdyby to byly public vlastnosti objekt ů. T řída také umož ňuje namapování tabulek mezi sebou pro spojování tabulek.

Zend Framework zahrnuj ješt ě spoustu dalších balí čků. Ale ty už nejsou vždy pot řeba a záleží jen na konkrétních požadavcích aplikace.

- 33 - 4 Vlastní návrhy řešení, p řínos návrh ů řešení

Tak jsme v předchozích kapitolách vybrali programovací jazyk, k němu také vhodný framework a nesmíme zapomenout na databázový systém. Ani žádné open-source řešení nep řipadá v úvahu jako vhodné. Je tedy na řad ě se vrhnout na vlastní řešení, které bude programované jazykem PHP pomocí Zend Framework a využívající databázový systém MySQL.

4.1 Specifikace aplikace

Je t řeba si na za čátku definovat, jaké má mít aplikace funkce. Nejd říve chci ujasnit, že se nejedná o individuální obchod. Nebudu se tedy zabývat tvorbou front-endu, což je rozhraní pro nakupující zákazníky, ale budu se zabývat back-endem, tedy administra čním rozhraním, který bude sloužit pro správce stránky. Aplikace nemá byt vytvo řena pro jedno použití, ale má se využívat pro tvorbu komer čních internetových obchod ů. Je tedy nejd ůležit ější, aby práv ě administra ční část a systémová logika vyhovovali obecn ě pro tvorbu internetových obchod ů, pokud možno s co nejmenšími modifikacemi na individuální pot řeby klienta.

Navigace Na za čátek by m ěla každá webová aplikace obsahovat alespo ň základní navigaci. U internetových obchod ů se jedná o základní informace o obchodu, p řípadn ě firm ě, která ho provozuje, obchodní podmínky a kontaktní informace. Pot řebujeme tedy, abychom mohli vytvá řet nové položky v navigaci. Každá položka by m ěla mít sv ůj název, po řadí pro zobrazení, pro víceúrov ňovou navigaci uvádět i nad řazenou položku a v neposlední řad ě obsah stránky.

Kategorizace zboží Ur čit ě nem ůžeme mít zboží v obchod ě jen tak rozházené a net říd ěné. Je tedy nutné definovat kategorie, do kterých m ůže libovoln ě zboží řadit a také podle nich je nabízet návšt ěvník ům stránek. Pro kategorii nám bude sta čit definovat název, nad řazenou položku a po řadí pro zobrazení.

- 34 - Produkty Tato část je základním kamenem každého internetového obchodu. Dokonce i bez objednávkového systému bychom se mohli obejít, a to t řeba v případě pouhé prezentace produkt ů nebo by objednání mohlo probíhat pomocí e-mail ů. U produktu budeme definovat jak vlastní specifika, tak u n ěj budeme volit již vytvořené záznamy, jako nap říklad za řazení do dané kategorie. U produkt ů budeme tedy po čítat s následujícími možnostmi: název, obrázek, za řazení do kategorie, kód, výrobce, dodavatel, typ DPH, cena, specifické parametry, p řidružené produkty, expedice, odkaz na produkt na stránkách výrobce, skladové zásoby, popis a v neposlední řad ě n ějaký status.

Dodavatelé Tato část systému slouží pro vlastní pot řeby správce internetového obchodu. Je tedy pohodlné, když se p ředdefinují vlastní dodavatelé a u produktu se ur čí, od kterého je. To se hodí v případ ě, kdy dohled nad internetovými objednávkami má i jiná osoba než osoba řešící nákup zboží. U objednávky a p řehledu objednaných produkt ů si zjistí, od kterých dodavatel ů má dané zboží objednat. V ěř ím, že tuto informaci by ob čas využil i majitel firmy provozující internetový obchod. Zde sta čí uvád ět základní informace o firm ě a rabat, který nám firma poskytuje. Pat ří mezi n ě: název, jméno a p říjmení kontaktní osoby, I Č, DI Č, e-mailová adresa, telefonní číslo, faxová číslo a adresa.

Výrobci Tato část není p říliš podstatná, ale jen dopl ňuje informace o produktech. Mohli bychom tuto informaci uvád ět u názvu produktu, ale takto nám to umožní řadit produkty podle jeho výrobce, p řípadn ě dát možnost návšt ěvníkovi podívat se na stránky výrobce daného produktu. Vysta číme si tedy pouze s názvem a odkazem na internetové stránky.

Zákazníci Můžeme chtít, aby se nám objednávky vytvá řely samotné s údaji od návšt ěvníka stránek, tedy umožnit mu nákup bez registrace, anebo m ůžeme podporovat či vyžadovat registraci návšt ěvníka p řed nakoupením, a tím také získáme informace o zákaznících pro pozd ější použití. U zákazník ů pot řebujeme podrobné informace: název firmy,

- 35 - jméno, p říjmení, I Č, DI Č, e-mailová adresa, telefonní číslo, faxové číslo, heslo, cenová kategorie a adresa.

Objednávky Objednávky nemusím n ějak extra vysv ětlovat. Shromaždují informace jak o objednaném zboží, tak o zákaznících, kte ří objednávku provedli. P řesn ěji pot řebujeme tyto informace: identifika ční číslo objednávky, identifika ční číslo zákazníka, telefonní číslo, e-mailová adresa, zp ůsob platby a dopravy, datum vytvo ření objednávky, status, celková cena objednávky, faktura ční údaje zákazníka, adresa doru čení a p řehled objednaného zboží.

Uživatelé Zde se nejedná o zákazníky, ale o uživatele, kte ří se p řihlašují do administra čního rozhraní a spravují internetový obchod. Nastavují se zde p řihlašovací údaje, hesla, jména a p říjmení uživatel ů a p řípadn ě i jejich práva.

Rozši řující možnosti Sem pat ří dopl ňující moduly, jako jsou novinky, extra stránky (například formulá ře), jazyky a r ůzné nastavení týkající se front-endu (prost ředí pro návšt ěvníky stránek).

Nastavení Tady bychom mohli za řadit definování e-mail ů, které se budou zasílat p ři objednání zboží, obchodní údaje o firm ě provozující internetový obchod, zp ůsoby plateb a dopravy nebo číslování faktur a objednávek.

4.2 Návrh databáze

Nyní provedu kompletní návrh celé databáze. V návrhu budu klást d ůraz na normalizaci, která nám odstraní redundanci dat, omezí složitosti, zabrání aktualiza čním anomáliím, což by m ělo vést k přehledn ější, rozší řiteln ější a výkonn ější databázi.

- 36 -

Obrázek 4 - Schéma databáze - 37 - 4.3 Vývoj aplikace

Databázi máme hotovou, tak se te ď m ůžeme pustit na programování samotného systému. Níže se budu snažit popsat r ůzné nastavení, použité paginy nebo jiné funkce, které jsem p ři programování systému použil.

Bootstrap

Bootstrap neboli index.php je hlavním souborem, na který jsou sm ěrovány veškeré požadavky a to pomocí souboru .htacces , který vše na n ěj p řesm ěrovává.

Na za čátku jsem si hned nadefinoval Zend_Loader::registerAutoload() , což mi umož ňuje vyvolávat t řídy, aniž bych je nejd říve p řidal nap říklad pomocí require_once , nyní se to vše provádí automaticky.

Vytvo řil jsem si vlastní t řídu pro vypisování chybových hlášek a nastavil, aby všechny chyby se zobrazovaly pouze tam. Tím jsem zamezil vyskakování chyb mezi text zobrazované stránky. Blíže použitou t řídu popíši v kapitole o vlastních knihovnách.

Konfigurace pot řebné pro p řipojení k databázi ukládám do externího souboru config.ini , tento soubor na čtu pomocí Zend_Config_Ini , a uložím do pam ěti, abych s tím mohl pozd ěji pracovat.

Nastavil jsem používání layoutu p řes knihovnu Zend_Layout , a dále up řesnil, v kterém adresá ři se nacházejí soubory se šablonami. Využívání layoutu je velmi pohodlné. Umož ňuje to pracovat s ur čitými metodami v kontroleru jako se samostatnými komponentami, které se navzájem nemusejí ovliv ňovat.

Tak jako u konfigurace databáze, tak jsem uložil pravidla routování do samostatného souboru routes.ini a zpracoval jej stejným zp ůsobem. Místo uložení do pam ěti jsem ho předal Zend_Controller_Front .

- 38 - Dále jsem zaregistroval 5 plugin ů: • TimerPlugin – je to jen pomocný pagin, umož ňuji mi sledovat rychlost vykonání celého požadavku klienta. • DbConnectPlugin – v tomto paginu se p řipojím k databázi díky konfiguraci, kterou jsem si d říve uložil do pam ěti. Krom ě klasického p řihlášení zde definuji také typ databáze a znakovou sadu, v které bude PHP komunikovat s databází. V případ ě použití jiného databázového systému by mi sta čilo zm ěnit pouze typ databáze, a celá aplikace by bez problém ů nebo jiných nutných zásah ů dokázala existovat. • ViewHelpersPlugin – zde pouze definuji cesty k adresá řů m pro view helpery. • AclPlugin – v tomto pluginu na čtu soubor acl. , ve kterém jsou uložena autoriza ční práva pro uživatele. • Zend_Wildfire_Channel_HttpHeaders::getInstance – aktivuji mi možnost posílat v hlavi čce data pro prohlíže č. Význam vysv ětlím dále.

Aktivuji Zend_Log_Writer_Firebug . Tato knihovna mi za pomoci posledního pluginu umožní zasílat do prohlíže če data. V prohlíže či je nutní mít nainstalované rozší ření FireBug. Nyní si mohu poslat data jako je n ějaký řet ězec, pole hodnot nebo dokonce i tabulku. Díky tomuto rozší ření si také posílám informace o rychlosti zpracování požadavku. Tento požadavek je poslán pokaždé, takže b ěžného uživatele neobt ěžuje, ale já si ho mohu zobrazit kdykoliv a mít p ředstavu o tom, zda se n ěkde nevyskytuje úzké hrdlo v rámci výkonu aplikace.

Nakonec vyvolám metodu dispatch na Zend_Controller_Front .

Controller

Po vykonání plugin ů je na řad ě kontroler. P ůvodní abstraktní Zend_Controller_Action jsem nahradil vlastním (i když d ědí jeho vlastnosti), kde jsem nadefinoval n ěkolik prom ěnných pro view, v kterých jsou uvedeny cesty k adresá řů m s obrazkáma, kaskádovýma stylama, javascriptama a ostatníma souborama. Tímto je nemusím definovat pokaždé v každém kontroleru znova a ušet řím zápis kódu.

- 39 -

Před každou na čtenou akcí prob ěhne kontrola, zda je uživatel p řihlášený a také se prov ěř í, jestli má na danou akci práva. Pokud není p řihlášen, bude p řesm ěrován na přihlašovací stránku a v případ ě nepovolení práv mu bude zobrazeno zamítnutí p řístupu.

Uvnit ř akce se řídím striktn ě dle pravidel, které definuje Zend Framework. Mohl bych sem vypsat r ůzné akce, ale nebyly by to žádné jiné skripty, než které se objevují v každém jiném zpracování objektov ě orientovaného PHP kódu. P řípadné specifikace knihoven Zend Frameworku a jejich metod je možné si do číst v oficiálním manuálu na stránkách firmy Zend.

4.4 Vlastní knihovny

Níže p ředstavím pár knihoven, které jsem vytvo řil, a uleh čují mi další práci.

Kvik_Image Tato knihovna nám pomáhá pracovat s obrázky, p řesn ěji řečeno zajiš ťuje uložení obrázku do požadovaného adresá ře.

Při použití této t řídy na za čátku nadefinujeme pot řebné parametry. Nejprve zvolíme maximální možnou velikost, kterou m ůže soubor mít, abychom omezili používání s velkými obrázky. Dále nadefinujeme cestu k adresáři kam, se má obrázek uložit a název obrázku. Pokud pot řebujeme z obrázku ud ělat více obrázku, ale t řeba jen s rozdílnými rozm ěry, nemusíme tuto t řídu používat n ěkolikrát, ale sta čí p ři zadávání parametr ů ur čit, kolik má být verzí obrázk ů a nadefinovat jejich parametry. Každý obrázek m ůže byt uložen v jiném adresá ři, mít jiné rozm ěry nebo mít jiné rozm ěry.

Kvik_Db_Table Rodi čem této t řídy je Zend_Db_Table , takže d ědí od ní veškerý vlastnosti. Já její funkce rozší řil o další dv ě metody, a to fetchAllWithJoins a fetchRowWithJoins . Ob ě tyto metody slouží pro výb ěr z databáze, a to bu ď n ěkolik řádk ů anebo jednoho řádku. Rozdíl oproti klasickému výb ěru je v tom, že výsledek nebude pouze řádek(y) z dané tabulky, ale rozší řený dotaz o všechny spojené tabulky pomocí JOIN . Definování

- 40 - spojení tabulek nemusíme d ělat pokaždé, co využíváme tuto funkci, ale musí to být nadefinováno v tříd ě pro danou tabulku, kde p řesn ě uvedeme jaké tabulky jsou s ní spojené spolu s klí či, kterými se na sebe vážou. Zend_Db_Table bohužel nenabízí takovou pohodlnou práci se spojenými tabulkami, tak bylo nejlepší, si takovou metodu sám vytvo řit.

Kvik_ErrorHandler O této t říd ě jsem se zmínil již v bootstrapu. Zajiš ťuje vypisování chybových hlášek.

Původní výpisy chybových hlášek mohou být n ěkdy matoucí (p ředevším pro za čáte čníky) a t ěžko se dohledává, kde je chyba. Já jsem celou chybovou hlášku po češtil a uvedl v takovém po řadí, aby to bylo co nejlépe srozumitelné. Hláška je tedy ve formátu TYP ZPRÝVY + POPIS CHYBY + „na řádku“ + ČÍSLO ŘÁDKY + „v souboru“ + NÁZEV SOUBORU . Dále to mám ješt ě nastavené tak, aby se hlášky neobjevovaly na stránce, ale posílá se mi to p řes hlavi čky do prohlíže če, kde si to p řečtu pomocí rozší ření FireBug. Typ zprávy vyhodnocuji dle čísla chybové hlášky, kterou mi předá PHP funkce set_error_handler .

Kvik_Search V českém jazyce je problém s vyhledáváním, p ředevším kv ůli diakritice. Na vyhledávání se dá standardn ě využít fulltextové vyhledávání v MySQL, bohužel nastává zde problém, pokud uživatel zapíše vyhledávané slovo bez kritiky, nebo je dané slovo uložené v databázi s jinou velikostí po čáte čního písmene.

Při použití mé funkce je t řeba nejprve zadat 3 parametry: seznam sloupc ů pro vyhledávání, výb ěr pro vyhledávání, minimální úrove ň relevance. Seznam sloupc ů je klasické pole se seznam názv ů sloupc ů, v kterých se má daná vyhledávaná fráze hledat. U každého sloupce m ůžeme také uvést bodovou hodnotu, která se p řipo čte, pokud zde bude dané slovo nalezeno a po čítá se to za každý výskyt slova zvláš ť. M ůžeme tímto dát větší relevanci na výskyt v nadpisu článku než v jeho obsahu. Výb ěr pro vyhledávání je výpis s databáze z dané tabulky nebo spojením tabulek, kterých se má vyhledávání týkat. Minimální úrove ň relevance nám zajistí, aby se zobrazily pouze ty výsledky,

- 41 - které mají bodové hodnocení relevance v ětší než dané minimum. Problém v podob ě velikosti písmen nebo diakritiky jsem vy řešil tím, že vyhledávané slovo i každý text, v kterém se vyhledává, p řevedu na malá písmena a odstraním veškerou diakritiku. Výsledkem tohoto vyhledávání je pole záznam ů, které odpovídají danému minimu relevance a jsou se řazeny podle velikosti relevance. Tento zp ůsob vyhledávání se v praxi velmi osv ědčil. Bohužel p ředpokládám, že p ři obsáhlejší databázi, kdy by tabulky skýtaly tisíce záznam ů, mohly nastat problémy s rychlostí výpo čtu tohoto vyhledávání.

4.5 Přínos vlastního řešení

Hlavní výhodou bych uvedl p řesnou znalost celého řešení. U cizích řešení bych mohl narazit na problémy, kdy bych nev ěděl, kde to programátor řešil. Zde, když jsem celý systém vytvá řel od za čátku sám, znám každou drobnost aplikace. Je to také velká výhoda p ři vytvá ření rozší ření.

Celou aplikaci jsem vytvo řil na vlastním návrhu layoutu a grafického řešení. Snažil jsem se, aby to bylo pro klienty co nejvíce p řív ětivé a intuitivní ovládání.

Při vlastním vytvá ření jsem mohl po celou dobu vývoje sledovat výkonovou náro čnost aplikace. Umožnilo mi to vyhnout se chybám, které by aplikaci zbyte čně zpomalovaly.

Se Zend Frameworkem jsem velmi spokojený. Velmi dobře se s ním pracuje také díky dobré dokumentaci. Nemusel jsem se starat o aplika ční logiku aplikace, sta čilo si osvojit postupy Zend Frameworku a veškerý vývoj šel velmi hladce. Pravda je, že pro za čáte čníky mlže být dosti složitý, ale jakmile si na něj zvyknout, zjistí, že práce jim jde mnohem rychleji a následné modifikace jde provád ět mnohem lépe.

- 42 - Záv ěr

Tato práce pojednává o rozhodování p ři vývoji aplikace pro internetové obchody. Nejd říve je probrána problematika výb ěru programovacího jazyka, kde se rozhodovalo mezi ASP.NET a PHP. Vybráno bylo PHP nejen kv ůli velké komunit ě, ale hlavn ě díky nízkým náklad ům pot řebné na vývoj a provoz. Dalším základním kamenem byly databázové systémy. Až na výjimku MS SQL pat řily všechny databázové systémy mezi multiplatformní. V případ ě zm ěny opera čního systému by nám nevznikly problémy a mohli bychom z ůstat u stávajícího databázového systému. Vynikající databázový systém Oracle jsme bohužel museli zamítnout, jelikož po řizovací a provozní náklady by byly tak velké, že by si je žádná menší firma nemohla dovolit. Po výb ěru PHP a MySQL jsme probrali nejrozší řen ější open-source řešení pro e-shopy. Bohužel žádné řešení nevyhovovalo, zejména díky velkým nárok ům na výkon serveru. Předposlední kapitola pojednávala o možnostech frameworku pro PHP. Rozhodování v této části je čist ě subjektivní, a ur čit ě v každém uvedném frameworku by šla aplikace pro e-shopy vytvo řit. P řiklonil jsem se na stranu Zend Framework, kdy jeho vývoj je oproti ostatním velmi rychlý a nabízí snad nejv ětší komunitu. Myslím, že Zend Framework má do budoucna nejv ětší potenciál. Samotný vývoj aplikace p řinesl návrh databázového schématu, který jsme vytvořili na základ ě specifikování požadavk ů systému. Napojení na databázi díky Zend Framework bylo již jednoduché a zabýval jsem se pouze specifickou konfigurací a použití plugin ů. Bylo pot řeba vytvo řit n ěkolik vlastních t říd, které mi v balí čku Zend Framework chyb ěly. Vlastní t řídy mi velmi pomohly p ři práci s databází nebo obrázky, ušet řilo mi to spoustu času. Myslím, že se mi fináln ě poda řila vytvo řit úsp ěšná aplikace, která vyhovuje vše požadavk ům a navíc je na výkon dost rychlá, tedy nenáro čná na zát ěž serveru. V případ ě vývoje dalších aplikací se ur čit ě zase obrátím na kombinaci Zend Framework s MySQL.

- 43 - Seznam obrázk ů

Obrázek 1 - Architektura .NET Frameworku ...... 6 Obrázek 2 - Základní adresá řová struktura v Zend Framework ...... 30 Obrázek 3 - Cyklus požadavku v Zend_Controlleru ...... 31 Obrázek 4 - Schéma databáze ...... 37

- 44 - Literatura

[1]. KOSEK, Ji ří. PHP – Tvorba interaktivních internetových aplikací . Praha: Grada Publishing, 1998. 492 s. ISBN 80-7169-373-1 [2]. SCHLOSSNAGLE, George. Pokro čilé programování v PHP 5 . Brno: Toner Press, 2004. 640 s. ISBN 80-86815-14-5 [3]. MASLAKOWSKI, Mark. Nau čte se MySQL za 21 dní . Brno: Computer Press, 2001. 478 s. ISBN 80-7226-448-6 [4]. ALLEN, Rob, LO, Nick, BROWN Steven. Zend Framework in Action . Manning Publications, 2008. 432s. ISBN 1933988320 [5]. Databázový sv ět. [online] Dostupné z: http:// www.dbsvet.cz [6]. Wikipedia. [online] Dostupné z: http:// www.wikipedia.org [7]. Czech PHP User Group. [online] Dostupné z: http:// blog.php-group.cz

- 45 - Seznam p řílohy

Příloha 1 – Zdrojové kódy vlastních knihoven

- 46 - index.php 1 set('config', $config); 27 28 $locale = new Zend_Locale('cs_CZ'); 29 Zend_Registry::set("Zend_Locale", $locale); 30 Zend_Locale::setDefault('cs_CZ'); 31 32 // setup layout 33 Zend_Layout::startMvc(array('layoutPath' => './application/layouts')); 34 35 // setup controller 36 $frontController = Zend_Controller_Front::getInstance(); 37 $frontController->throwExceptions(true); 38 $frontController->setControllerDirectory( 39 array( 40 'default' => './application/default/controllers', 41 'admin' => './application/admin/controllers' 42 ) 43 ); 44 45 // setup router 46 $router = $frontController->getRouter(); 47 $config_routes = new Zend_Config_Ini('./application/routes.ini', 'general'); 48 $router->addConfig($config_routes, 'routes'); 49 50 // setup database 51 $frontController->registerPlugin(new TimerPlugin()); 52 $frontController->registerPlugin(new DbConnectPlugin($config->db->toArray())); 53 $frontController->registerPlugin(new ViewHelpersPlugin()); 54 $frontController->registerPlugin(new AclPlugin()); 55 $frontController->registerPlugin(Zend_Wildfire_Channel_HttpHeaders::getInstance()); 56 57 // run! 58 $response = new Zend_Controller_Response_Http(); 59 $response->setRawHeader("Expires: " . gmdate("D, d M Y H:i:s") . " GMT"); 60 $response->setRawHeader("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); 61 $response->setRawHeader("Cache-Control: no-store, no-cache, must-revalidate"); 62 $response->setRawHeader("Pragma: no-cache"); 63 64 // firebug init 65 $log = new Zend_Log(); 66 $writer = new Zend_Log_Writer_Firebug(); 67 //$writer = new Zend_Log_Writer_Null(); 68 $log->addWriter($writer); 69 Zend_Registry::set('log',$log); 70 71 $frontController->dispatch(); Image.php 1 _id = $id; 16 } 17 18 public function create($image, array $parameters = array(), $size = false) 19 { 20 $result = array(); 21 22 if ($size) $this->_maxSize = $size; 23 24 if(filesize($image) < $this->_maxSize) 25 { 26 $velikost = getimagesize($image); 27 28 $fileExtension = $this->_getFileExtension($velikost["mime"]); 29 if ($fileExtension == false) return false; 30 31 if ($fileExtension != "swf") 32 { 33 $img = $this->_imageCreateFrom($image); 34 if ($img == false) return false; 35 36 $width = imagesx($img); 37 $height = imagesy($img); 38 } 39 else 40 { 41 $width = $velikost[0]; 42 $height = $velikost[1]; 43 } 44 45 } 46 else return false; 47 48 $i = 0; 49 foreach ($parameters as $par) 50 { 51 if (isset($par["id"])) $this->_id = $par["id"]; 52 53 if (isset($par["size"])) 54 { 55 $this->_maxWidth = $par["size"]["width"]; 56 $this->_maxHeight = $par["size"]["height"]; 57 } 58 59 if (isset($par["path"])) $this->_path = $par["path"]; 60 61 if (isset($par["prefix"])) $this->_prefix = $par["prefix"]; 62 63 if (!$this->_name) 64 { 65 $dir = dir("." . $this->_path); 66 for($x = "a"; $x <= "z"; $x++) 67 { 68 $dir->rewind(); 69 while($file = $dir->read()) 70 { 71 $break = false; Image.php 72 if ($file == "." OR $file == "..") continue; 73 if (!eregi("^" . $this->_id . "-", $file)) continue;

74 75 if ($file == $this->_id . "-" . $x . "." . $fileExtension) 76 { 77 $break = true; 78 break; 79 } 80 } 81 82 if ($break == false) 83 { 84 $this->_name = $this->_id . "-" . $x . "." . $fileExtension; 85 break; 86 } 87 } 88 $dir->close(); 89 } 90 91 $result[$i]["name"] = $this->_prefix . $this->_name; 92 93 $path = "." . $this->_path . $this->_prefix . $this->_name; 94 95 if ($width > $this->_maxWidth OR $height > $this->_maxHeight) 96 { 97 if ($width >= $height AND ($width / $height) >= ($this->_maxWidth / $this->_maxHeight)) 98 { 99 $newWidth = $this->_maxWidth; 100 $percent = $newWidth / $width; 101 $newHeight = round($height * $percent); 102 } 103 elseif ($height > $width OR ($width / $height) < ($this->_maxWidth / $this->_maxHeight)) 104 { 105 $newHeight = $this->_maxHeight; 106 $percent = $newHeight / $height; 107 $newWidth = round($width * $percent); 108 } 109 110 if ($fileExtension != "swf") 111 { 112 $img2 = imagecreatetruecolor($newWidth, $newHeight); 113 imagecopyresampled($img2, $img, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height); 114 115 if($velikost["mime"] == "image/jpeg") 116 { 117 $tmp_result = imagejpeg($img2, $path); 118 } 119 elseif ($velikost["mime"] == "image/gif") 120 { 121 $tmp_result = imagegif($img2, $path); 122 } 123 elseif ($velikost["mime"] == "image/png") 124 { 125 $tmp_result = imagepng($img2, $path); 126 } 127 else 128 { 129 return false; 130 } 131 132 imagedestroy($img2); 133 } 134 else 135 { 136 $newWidth = $width; 137 $newHeight = $height; 138 Image.php 139 $tmp_result = copy($image, $path); 140 } 141 } 142 else 143 { 144 $newWidth = $width; 145 $newHeight = $height; 146 147 $tmp_result = copy($image, $path); 148 } 149 150 $result[$i]["width"] = $newWidth; 151 $result[$i]["height"] = $newHeight; 152 $result[$i]["size"] = filesize($path); 153 154 chmod ($path, 0644); 155 156 $i++; 157 } 158 159 if ($img) imagedestroy($img); 160 161 return $result; 162 } 163 164 public function delete($image, array $parameters = array()) 165 { 166 foreach ($parameters as $par) 167 { 168 if (isset($par["path"])) $this->_path = $par["path"]; 169 170 if (isset($par["prefix"])) $this->_prefix = $par["prefix"]; 171 172 unlink("." . $this->_path . $this->_prefix . $image); 173 } 174 175 return true; 176 } 177 } Table.php 1 _tableAlias; 16 17 return $info; 18 } 19 20 public function fetchAllWithJoins($where = null, $order = null, $count = null, $offset = 21 { 22 $select = $this->_db->select(); 23 24 // prejmenovani sloupcu rodicovske tabulky 25 $colsAliases = array(); 26 $cols = $this->info(); 27 foreach($cols[self::METADATA] as $col) 28 { 29 $colsAliases[$this->_tableAlias . "_" . $col["COLUMN_NAME"]] = $col["COLUMN_NAME 30 } 31 32 // nastaveni vyberu z databaze 33 $select ->from(array($this->_tableAlias => $this->_name), $colsAliases) 34 ->order($order) 35 ->limit($count, $offset); 36 37 if (!is_null($where)) 38 { 39 $select->where($where); 40 } 41 42 if (!is_null($group)) 43 { 44 $select->group($group); 45 } 46 47 // pripojeni dcerinych tabulek 48 49 if(count($this->_referenceMap) > 0) 50 { 51 foreach($this->_referenceMap as $referenceMap) 52 { 53 $dependentTable = new $referenceMap["refTableClass"](); 54 55 $dependentTableInfo = $dependentTable->info(); 56 57 // urceni aliasu dcerine tabulky 58 $table = array($dependentTableInfo[self::TABLEALIAS] => $dependentTableInfo[ 59 60 // urceni relacnich sloupcu 61 $columns = null; 62 for($i = 0; $i < count($referenceMap[self::REF_COLUMNS]); $i++) 63 { 64 $columns .= $this->_tableAlias . "." . $referenceMap[self::REF_COLUMNS][ 65 if ($i + 1 < count($referenceMap[self::REF_COLUMNS])) 66 { 67 $columns .= " AND "; 68 } 69 } 70 71 // prejmenovani sloupcu dcerine tabulky Table.php 67 $columns .= " AND "; 68 } 69 } 70 71 // prejmenovani sloupcu dcerine tabulky 72 $colsAliases = array(); 73 foreach($dependentTableInfo[self::METADATA] as $col) 74 { 75 $colsAliases[$dependentTableInfo[self::TABLEALIAS] . "_" . $col["COLUMN_NAME"]] = $col["COLUMN_NAME"]; 76 } 77 78 // pripojeni relacni tabulky k vyberu 79 $select->joinLeft($table, $columns, $colsAliases); 80 } 81 } 82 83 $stmt = $select->query(); 84 85 $data = array( 86 87 'table' => $this, 88 'data' => $stmt->fetchAll(), 89 'rowClass' => $this->_rowClass, 90 'stored' => true 91 92 ); 93 94 return new $this->_rowsetClass($data); 95 } 96 97 public function fetchRowWithJoins($where = null, $order = null, $count = null, $offset = null) 98 { 99 100 $rows = $this->fetchAllWithJoins($where, $order, 1); 101 102 foreach($rows as $row) 103 { 104 return $row; 105 break; 106 } 107 } 108 109 public function getMaxPrimaryKey ($where = null) 110 { 111 $select = $this->_db->select(); 112 113 $select->from($this->_name, array('max' => 'MAX(' . $this->_primary[1] . ')')); 114 115 if (!is_null($where)) 116 { 117 $select->where($where); 118 } 119 120 return $select->query()->fetchObject()->max; 121 } 122 123 public function CountAllWithJoins ($group = null, $where = null) 124 { 125 $select = $this->_db->select(); 126 127 // nastaveni vyberu z databaze 128 $select->from(array($this->_tableAlias => $this->_name), array('count' => 'COUNT(*)')); 129 130 if (!is_null($group)) 131 { 132 $select->reset(); 133 $select->from(array($this->_tableAlias => $this->_name), array('count' => 'COUNT(' . $group . ')')); Table.php 134 $select->group($group); 135 } 136 137 if (!is_null($where)) 138 { 139 $select->where($where); 140 } 141 142 // pripojeni dcerinych tabulek 143 if(count($this->_referenceMap) > 0) 144 { 145 foreach($this->_referenceMap as $referenceMap) 146 { 147 $dependentTable = new $referenceMap["refTableClass"](); 148 149 $dependentTableInfo = $dependentTable->info(); 150 151 // urceni aliasu dcerine tabulky 152 $table = array($dependentTableInfo[self::TABLEALIAS] => $dependentTableInfo[self::NAME]); 153 154 // urceni relacnich sloupcu 155 $columns = null; 156 for($i = 0; $i < count($referenceMap[self::REF_COLUMNS]); $i++) 157 { 158 $columns .= $this->_tableAlias . "." . $referenceMap[self::REF_COLUMNS][$i] . " = " . $dependentTableInfo[self::TABLEALIAS] . "." . $referenceMap[self::COLUMNS][$i]; 159 if ($i + 1 < count($referenceMap[self::REF_COLUMNS])) 160 { 161 $columns .= " AND "; 162 } 163 } 164 165 // pripojeni relacni tabulky k vyberu 166 $select->joinLeft($table, $columns, array()); 167 } 168 } 169 170 if (!is_null($group)) 171 { 172 return count($select->query()->fetchAll()); 173 } 174 else 175 { 176 return $select->query()->fetchObject()->count; 177 } 178 } 179 180 public function getReferenceMap() 181 { 182 return $this->_referenceMap; 183 } 184 185 } ErrorHandler.php 1 addWriter($writer); 13 $this->_log = $log; 14 } 15 16 function add($cislo, $zprava, $soubor, $radka) 17 { 18 if (!eregi("Loader.php$", $soubor)) 19 { 20 $message = $zprava . " na řádku " . $radka . " v souboru " . $soubor; 21 22 switch ($cislo) 23 { 24 case 1: 25 $this->_log->err("Error: " . $message); 26 break; 27 case 2: 28 $this->_log->warn("Warning: " . $message); 29 break; 30 case 4: 31 $this->_log->warn("Parsing Error: " . $message); 32 break; 33 case 8: 34 $this->_log->notice("Notice: " . $message); 35 break; 36 case 16: 37 $this->_log->err("Core Error: " . $message); 38 break; 39 case 32: 40 $this->_log->warn("Core Warning: " . $message); 41 break; 42 case 64: 43 $this->_log->err("Compile Error: " . $message); 44 break; 45 case 128: 46 $this->_log->warn("Compile Warning: " . $message); 47 break; 48 case 256: 49 $this->_log->err("User Error: " . $message); 50 break; 51 case 512: 52 $this->_log->warn("User Warning: " . $message); 53 break; 54 case 1024: 55 $this->_log->notice("User Notice: " . $message); 56 break; 57 case 2048: 58 $this->_log->notice("Runtime Notice: " . $message); 59 break; 60 case 4096: 61 $this->_log->err("Catchable Fatal Error: " . $message); 62 break; 63 64 default: 65 $this->_log->info("Other: " . $message); 66 break; 67 } 68 } 69 } 70 } 71 Search.php 1 _columns = $params["columns"]; 13 if (isset($params["rowset"])) $this->_rowset = $params["rowset"]; 14 if (isset($params["rankLimit"])) $this->_rankLimit = $params["rankLimit"]; 15 } 16 17 function search($search) 18 { 19 $searchPartial = explode(" ", $this->_convert($search)); 20 21 foreach ($this->_rowset as $row) 22 { 23 $relevance = 0; 24 foreach ($this->_columns as $col => $rel) 25 { 26 foreach ($searchPartial as $searchPart) 27 { 28 $relevance = $relevance + ($this->_compare($searchPart, $this->_convert( 29 } 30 } 31 if ($relevance > $this->_rankLimit) 32 { 33 $subresult = $row->toArray(); 34 $subresult['_relevance'] = $relevance; 35 $this->result[] = $subresult; 36 } 37 } 38 } 39 40 function setRowset($rowset) 41 { 42 if (isset($rowset)) $this->_rowset = $rowset; 43 } 44 45 function setColumns($columns) 46 { 47 if (isset($columns)) $this->_columns = $columns; 48 } 49 50 public function getResult() 51 { 52 $this->result = array_reverse($this->_columnSort($this->result, '_relevance')); 53 54 $tmp_result = array(); 55 foreach ($this->result as $row) 56 { 57 $tmp_result[] = (object)$row; 58 } 59 return $tmp_result; 60 } 61 62 private function _columnSort($unsorted, $column) { 63 $sorted = $unsorted; 64 for ($i = 0; $i < count($sorted) - 1; $i++) 65 { 66 for ($j = 0; $j < count($sorted) - 1 - $i; $j++) 67 { 68 if ($sorted[$j][$column] > $sorted[$j + 1][$column]) 69 { 70 $tmp = $sorted[$j]; 71 $sorted[$j] = $sorted[$j + 1]; Search.php 71 $sorted[$j] = $sorted[$j + 1]; 72 $sorted[$j + 1] = $tmp; 73 } 74 } 75 } 76 return $sorted; 77 } 78 79 private function _convert($string) 80 { 81 $trans = array( 82 "á"=>"a", 83 "ä"=>"a", 84 "č"=>"c", 85 "ď"=>"d", 86 "é"=>"e", 87 "ě"=>"e", 88 "ë"=>"e", 89 "í"=>"i", 90 "ï"=>"i", 91 "ň"=>"n", 92 "ó"=>"o", 93 "ö"=>"o", 94 "ř"=>"r", 95 "š"=>"s", 96 "ť"=>"t", 97 "ú"=>"u", 98 "ů"=>"u", 99 "ü"=>"u", 100 "ý"=>"y", 101 "ÿ"=>"y", 102 "ž"=>"z", 103 "Á"=>"A", 104 "Ä"=>"A", 105 "Č"=>"C", 106 "Ď"=>"D", 107 "É"=>"E", 108 "Ě"=>"E", 109 "Ë"=>"E", 110 "Í"=>"I", 111 "Ï"=>"I", 112 "Ň"=>"N", 113 "Ó"=>"O", 114 "Ö"=>"O", 115 "Ř"=>"R", 116 "Š"=>"S", 117 "Ť"=>"T", 118 "Ú"=>"U", 119 "Ů"=>"U", 120 "Ü"=>"U", 121 "Ý"=>"Y", 122 "Ÿ"=>"Y", 123 "Ž"=>"Z" 124 ); 125 126 return strtolower(strtr($string, $trans)); 127 } 128 129 private function _compare($searchPart, $value) 130 { 131 if (strLen($searchPart) >= 2) { 132 return subStr_count($this->_convert($value), $searchPart); 133 } 134 else { 135 return 0; 136 } 137 } 138 }