11.07.2015 Views

Seminarski rad na praksi

Seminarski rad na praksi

Seminarski rad na praksi

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>Semi<strong>na</strong>rski</strong> <strong>rad</strong> <strong>na</strong> <strong>praksi</strong>Tema: CakePHP, MVC (Model – View – Controller)Juli, 2007Mentor:Student:Mustafa Hodžić Jasmi<strong>na</strong> Šero


SADRŽAJ<strong>Semi<strong>na</strong>rski</strong> <strong>rad</strong> <strong>na</strong> <strong>praksi</strong> ...................................................................................................... 1SADRŽAJ ............................................................................................................................ 21. Uvod ................................................................................................................................. 32. MVC (Models – Views – Controllers) ............................................................................. 42.1. Model ........................................................................................................................ 52.1.1. Definiranje i upit sa hasOne: ............................................................................. 72.1.2. Definiranje i upit sa belongsTo .......................................................................... 82.1.3. Definiranje i upit sa hasMany ............................................................................ 92.1.4. Definiranje i upit sa hasAndBelongsToMany (HABTM) ............................... 112.2. View ....................................................................................................................... 202.3. Controller ................................................................................................................ 232.3.2. Controller callback ........................................................................................... 27Možemo kreirati callback u <strong>na</strong>šem aplikacijskom Model-u ili Controller file-u. U ovomprimjeru šaljemo email iz Model-a .................................................................................... 273. Helper ............................................................................................................................. 283.1. HTML Helper ........................................................................................................ 283.2. TimeHelper ............................................................................................................ 313.3. NumberHelper ......................................................................................................... 324. Scaffolding ..................................................................................................................... 345. Data Validation ............................................................................................................. 356. Components ................................................................................................................... 377. Servis “Anketa” ............................................................................................................. 397.1. Tabele servisa .......................................................................................................... 397.2. MVC servisa ........................................................................................................... 417.2.1. Model .............................................................................................................. 417.2.2. View ................................................................................................................. 427.2.3. Controller ......................................................................................................... 467. 3. Upustvo za servis .................................................................................................. 52ZAKLJUČAK .................................................................................................................... 59LITERATURA .................................................................................................................. 602


1. UvodCakePHP je open source web aplikacijski framework <strong>na</strong>pisan za PHP, distribuiran odMIT license. Razvoj Cake-a počinje u 2005-oj godini od tada je <strong>na</strong>stalo nekolikoprojekata i još uvijek se <strong>rad</strong>i <strong>na</strong> razvoju novih.CakePHP je dobro dokumentovan framework, inspiriran konceptom predstavljenim uRoR-u (Ruby on Rails), koji može biti primjenjen u PHP4 – PHP5. Cake olakšavakomunikaciju user interface-a sa bazom podataka, brz je, koristi MVC ( Model – View –Controller ) arhitekturu, te time forsira objektno i uredno programiranje. Ima podršku zacashe, ajax, RSS Helper, a uskoro bi trebao dobiti još “masu” stvari. Kod testiranja idebagiranja aplikacije bilo koji developer koji primjenjuje CakePHP strukturu će bitisposoban da locira i ispravi grešku bez z<strong>na</strong>nja svih detalja o kodu.Neke osobine CakePHP- a:- Kompatibilan je sa PHP4 i PHP5- Fleksibalan View Cashing- Application Scaffolding- Access Control List- View Helpers za AJAX, Javascript, HTML forme,...- Radi iz bilo kojeg website poddirektorija- Brz, fleksibilan template (PHP sintaksa sa Helper metodama)- Ugrađe<strong>na</strong> validacija- Website directory nezavisan- View cachingDa bi koristili CakePHP moramo imati HTTP sever (wamp, apache), PHP 4 ili 5,database engine (MaSQL, PostgreSQL).Instalacija Cake-a: downloadujemo jednu od verzija CakePHP-a (www.cakephp.org,www.forgephp.org ). Otpakujemo folder i snimimo <strong>na</strong> web server u webroot direktorij( wamp, apache,…npr. C:\wamp\www), zatim učitamo stranicu kao localhost u webbrowser-u. Indexnu stranu podešavamo u /app/config/routes.php file-u, detalje opodešavanju i instalaciji CakePHP-a možemo <strong>na</strong>ći u CakePHP Manual dokumentu,(www.cakephp.org ).3


2. MVC (Models – Views – Controllers)MVC je arhitekturalni patern koji se koristi u softverskom inžinjeringu, u kompleksnimkompjuterskim aplikacijama koje predstavljaju dugi niz korisničkih podataka. Developeričesto žele odvojiti podatke (model) od korisničkog interfejsa (view), tako da mijenjajukorisnički interfejs koji ne daje podatke i podaci mogu biti reorganizovani bezmijenjanja interfejsa. MVC rješava ovaj problem odvajanjem pristupa podacima odbiznis logike iz prezentacijskih podataka i korisničkog interfejsa, uključujući komponentucontroller.MVC često vidimo u web aplikacijama, gdje je view ustvari HTML stranica, a controllerje kod koji skuplja di<strong>na</strong>mičke podatke i generira sadržaj sa HTML-om. Model jepredstavljen stvarnim sadržajem, koji je obićno smješten u bazu podataka ili XML fajl.MVC je software dizajn patern koji pomaže u logičkom odvajanju koda, to je kaokonceptual<strong>na</strong> pa<strong>rad</strong>igma, koja postoji kao veza između tri objekta: Model, View iController. Svi <strong>na</strong>ši entiteti (Models), funkcije ovih entiteta (Controllers), korisničkiinterfejs (Views) smješteni su u odvojenim fajlovima, tako da nećemo mijenjati Contollerako želimo promijeniti izgled nekog input polja,… Controller i View zavise od Model-a,zato što zahtijevaju podatke iz Model-a, bilo koji input dolazi preko Controllera, kojizatim odabire View za prikaz rezultata tj, Controller prima svaki HTTP zahtijev, a Viewgenerira HTTP odgovor, kao što možemo vidjeti <strong>na</strong> sljedećoj sliciInput -> Processing -> OutputController -> Model -> View4


- Model enkapsulira aplikacijeske podatke, aplikacijski flow i business logic- View ekstraktuje podatke iz Modela i formatira ih za prezentaciju- Controller pristupa aplikacijskom flow, prima ulaze (zahtijeve) i prevodi ih zaModel i ViewModeli, views (pogledi) i kontroleri <strong>na</strong>laze se u predefinisanom direktoriju sa CakePHP–ovom direktori strukturom, kao što se može vidjeti u sljedećem primjeru:• app/o config/o controllers/o models/o plugins/o tmp/o vendors/o views/o webroot/• cake/o config/o docs/o libs/• vendors/2.1. Model5


Model je objekt MVC arhitekture, sadrži aplikacijske podatke i logiku, po<strong>na</strong>ša se kaoprimarni drajver u aplikaciji, nema nikakve prezentacijske osobine i nikakvu odgovornostprema HTTP zahtijevima,tj. odvaja prezentacijku logiku od aplikacijske. Omogućavapristup bazi podataka i tabelama u bazi. Po defaultnu ime<strong>na</strong> modela su u jednini i imajuime isto kao i tabela u bazi, s tim da je ime tabele u množini, npr. ako imamo tabelu“answers”, trebamo imati i model “Answer”. Primjer:Answer model se treba snimiti u app/models/answer.phpDomain Model je layer objekt koji apstraktnu logiku, podatke i probleme aplikacijeodvaja. Može se klasificirati u dvije kategorije:- Simple Domain Model ima one – to – one odgovornost između business objekatai tabela u bazi podataka- Rich Domain Model uključuje kompleksne web objekte i mnoge dizajn paterneKoji model ćemo koristiti zavisi od konteksta aplikacije.Jed<strong>na</strong> od <strong>na</strong>jmočniji osobi<strong>na</strong> CakePHP je veza između modela. Postoje četiri tipa veza:- hasOne- hasMany- belongsTo- hasAndBelongsToManyKada je veza između modela definisa<strong>na</strong>, Cake automatski povezuje modele. Za korektnokorištenje asocijacije <strong>na</strong>jbolje je slijediti CakePHP konvenciju imenovanja. Ukolikokoristimo CakePHP konvenciju imenovanja, možemo koristiti scaffolding dapredstavimo sebi aplikacijske podatke, jer scaffolding pro<strong>na</strong>lazi i koristi asocijacijeizmeđu modela. Naravno, možemo uvijek podesiti model asocijacije da <strong>rad</strong>e bezCakePHP konvencije imenovanja.CakePHP konvencija imenovanja odnosi se <strong>na</strong> foreign (strani) ključ, ime modela i imetabele:- Foreign (strani) ključ: [ime modela u jednini]_id, npr. strani ključ u “authors”tabeli za povezivanje sa Post modelom koristi asocijaciju Authors belongs to,starni ključ u “authors” tabeli bi trabao biti “post_id”.- Ime tabele: [ime objekta u množini], npr. ako želimo snimiti informacije o blogpostu i autorima, ime<strong>na</strong> tabela trebaju biti “posts” i “authors”.- Ime modela: [ime tabele u jednini], ime modela za tabelu “posts” je “Post”, a imemodela za tabelu ”authors” je “Author”.6


CakePHP scaffolding očekuje asocijacije u istom poretku kao i kolo<strong>na</strong>, tako ako imamoArticle koji belongsTo (pripada) modelima: Author, Editor i Publisher. Trebamo i triključa: author_id, editor_id, publisher_id. Scaffolding očekuje asocijacije u istom poretkukao što su ključevi u tabeli, npr. prva Author, druga Editor i posljednja Publisher.Primjer: Ako želimo kreirati jednostavni user me<strong>na</strong>đment sistem za blog, svaki user imajedinstven profil što omogućava asocijaciju hasOne (User hasOne Profile). Međutimuser-i mogu dodavati i komentare pa imamo asocijaciju hasMany (User hasManyComments). Kada želimo da user sistem <strong>rad</strong>i dozvolit ćemo Posts koji će biti povezan saTag objektima, tako da imamo asocijaciju hasAndBelongToMany (PosthasAndBelongToMany Tags).2.1.1. Definiranje i upit sa hasOne:


- zavisnost: ukoliko je podeše<strong>na</strong> <strong>na</strong> true, pridruženi model je uništen kada je uništenpredhodni- forgeinKey: ime stranog ključa koji povezuje odgovarajući modelKada izvršimo find() ili findAll() poziva korišteni Profile model, trebali bi vidjetiasocijaciju User modela, kao što je:$user = $this->User->read(null, '25');print_r($user);//output:Array([User] => Array([id] => 25[first_<strong>na</strong>me] => John[last_<strong>na</strong>me] => Anderson[user<strong>na</strong>me] => psychic[password] => c4k3roxx))[Profile] => Array([id] => 4[<strong>na</strong>me] => Cool Blue[header_color] => aquamarine[user_id] = 25)2.1.2. Definiranje i upit sa belongsToMeđutim User može zahtijevati da vidi Profil, to ćemo omogućiti pomoću asocijacijebelongsTo koju kreiramo u modelu Profil, primjer, putanja : /app/models/profile.php


$belongsTo niz Cake koristi da poveže modele Profil i User.Kada izvršimo find() ili findAll() poziv Profil modela, trebali bi vidjeti pridruženi Usermodel kao što je:$profile = $this->Profile->read(null, '4');print_r($profile);//output:Array([Profile] => Array([id] => 4[<strong>na</strong>me] => Cool Blue[header_color] => aquamarine[user_id] = 25))[User] => Array([id] => 25[first_<strong>na</strong>me] => John[last_<strong>na</strong>me] => Anderson[user<strong>na</strong>me] => psychic[password] => c4k3roxx)2.1.3. Definiranje i upit sa hasManySada kada su User i Profile model povezani i <strong>rad</strong>e, treba <strong>na</strong>praviti sistem da User arhivupoveže sa Comment arhivom. U User model trebamo dodati:


Cake koristi $hasMany niz da <strong>na</strong>pravi vezu User i Comment modela. Svaki ključ u nizudozvoljava dalju konfiguraciju veze:- className: ime modela koji želimo povezati- uslovi: SQL fragmenti stanja (uslova) koji definišu taj odnos.Možemo koristiti uslov da kažemo Cake-u da poveže samo Comment koji je ograničen,npr. “Comment.modereted = 1”- redoslijed: redoslijed povezani modela, ako želimo povezati modele u određeniredoslijed, postavimo vrijednost ključa da koristi SQL redoslijed, npr. “Comment.createdDESC”- limit (ograničenje)- maksimalan broj veza modela, koji želimo da <strong>na</strong>m Cake dohvati, uovom primjeru nismo htjeli sve komentare, već samo 5- foreignKey: ime stranog ključa koji povezuje pridruženi model- exclusive: ako je posatvljeno <strong>na</strong> true, svi povezani objekti će biti obrisani u jednoj SQLizjavi bez da se beforeDelete callback pokrene- finderQuery: specifikacija kompletne SQL izjave za dohvat veze, ovo je dobar <strong>na</strong>čin zakompleksne asocijacije koje ovise o više tabelaKada izvršimo find() ili findAll() poziv User modela, trebali bi vidjeti povezaneComment modele, kao što je:$user = $this->User->read(null, '25');print_r($user);//output:Array([User] => Array([id] => 25[first_<strong>na</strong>me] => John[last_<strong>na</strong>me] => Anderson[user<strong>na</strong>me] => psychic[password] => c4k3roxx)[Profile] => Array([id] => 4[<strong>na</strong>me] => Cool Blue[header_color] => aquamarine[user_id] = 25)10


[Comment] => Array([0] => Array([id] => 247[user_id] => 25[body] => The hasMany assocation is nice to have.)[1] => Array([id] => 256[user_id] => 25[body] => The hasMany assocation is really nice to have.)[2] => Array([id] => 269[user_id] => 25[body] => The hasMany assocation is really, really nice to have.)[3] => Array([id] => 285[user_id] => 25[body] => The hasMany assocation is extremely nice to have.)[4] => Array([id] => 286[user_id] => 25[body] => The hasMany assocation is super nice to have.)))Dobra ideja je definirati “Comment belongsTo User” asocijaciju, tako da oba modelamogu vidjeti jedan drugi. Ne definiranje asocijacija iz oba modela je često uobičaj<strong>na</strong>greška kada pokušamo koristiti scaffolding.2.1.4. Definiranje i upit sa hasAndBelongsToMany (HABTM)HasAndBelongsToMany je <strong>na</strong>jteži za “pravljenje”, ali je takođe i <strong>na</strong>jvišekorišten,koristan je kad imamo dva modela koja su poveza<strong>na</strong> zajedno sa pridruženimtabelama. Pridružene tabele sadrže individualne redove koji su povezani jedan sa drugim.Razlika između hasMany I hasAndBelongsToMany je ta što sa hasMany, asocijacija11


modela nije dijelje<strong>na</strong> (shared). Ako imamo User hasMany Comments, samo je userpovezan sa komentarima, sa HABTM, asocijacije modela su dijeljene.HABTM pridružene tabele, jednostavni modeli i pridruže<strong>na</strong> im ime<strong>na</strong> tabela:- Posts i Tags: posts_tag- Monkeys i IceCubes: ice_cubes_monkeys- Categories i Articles: articles_categoriesHABTM da poveže tabele treba <strong>na</strong>jmanje dva stra<strong>na</strong> ključa modela koji su povezani. Za<strong>na</strong>š primjer to su “post_id” i “tag_id”. Primjer Posts HABTM Tags:---- Table structure for table `posts`--CREATE TABLE `posts` (`id` int(10) unsigned NOT NULL auto_increment,`user_id` int(10) default NULL,`title` varchar(50) default NULL,`body` text,`created` datetime default NULL,`modified` datetime default NULL,`status` tinyint(1) NOT NULL default '0',PRIMARY KEY (`id`)) TYPE=MyISAM;-- ------------------------------------------------------------ Table structure for table `posts_tags`--CREATE TABLE `posts_tags` (`post_id` int(10) unsigned NOT NULL default '0',`tag_id` int(10) unsigned NOT NULL default '0',PRIMARY KEY (`post_id`,`tag_id`)) TYPE=MyISAM;-- ------------------------------------------------------------ Table structure for table `tags`--CREATE TABLE `tags` (`id` int(10) unsigned NOT NULL auto_increment,`tag` varchar(100) default NULL,PRIMARY KEY (`id`)) TYPE=MyISAM;12


Sa ovim tabelama definišemo asocijaciju u Post modelu:/app/models/post.php hasAndBelongsToMany


))[1] => Array([id] => 256[tag] => Powerful Software)2.1.1. Model funkcijeModeli su klase proširene AppModel klasom, AppModel klasa je orgi<strong>na</strong>lno definisa<strong>na</strong> ucake/ direktoriju, ali ako želimo kreirati vlastitu, treba je smjestiti u /app/app_model.php.Treba da sadrži metode koje su dijeljene između dva ili više modela. Time o<strong>na</strong> proširujeklasu Model koja je standard<strong>na</strong> Cake biblioteka definisa<strong>na</strong> u cake/libs/model.php.Primjer specifične metode u modelu je par metoda za hiding/unhiding post u blogu, kaošto vidimo u sljedećem primjeru:


}}?>U sljedećem primjeru vidimo nekoliko standardni <strong>na</strong>či<strong>na</strong> za dobivanje <strong>na</strong>ših podatakakoristeći model:findAll ($conditions //primjer:$conditions="race='wookie' ANDthermal_deto<strong>na</strong>tors > 3",$fields,$order,$limit,$page,$recursive);string $conditions;array $fields;string $order;int $limit;int $page;int $recursive;Kada je $recursive opcija postavlje<strong>na</strong> <strong>na</strong> vrijednost veću od 1, findAll( ) operacijepokušavaju vratiti odgovarajući model <strong>na</strong>đen sa findAll( ). Ako <strong>na</strong>š property ima viševlasnika koji su uključeni u više ugovora, findAll( ) <strong>na</strong> <strong>na</strong>šem Property modelu će vratitite odgovarajuće modele.find ($conditions$fields,$order,$recursive);string $conditions;array $fields;string $order;int $recursive;Vraća specifično polje iz prvog rekorda koje odgovara $conditions. Ove magičnefunkcije mogu biti korištene kao shortcut za pretragu tabela za redom koji je datodređenim poljem i određenom vrijednošću. Treba samo izabrati ime polja koji želimotražiti, primjer:$this->Post->findByTitle('My First Blog Post');$this->Author->findByLastName('Rogers');$this->Property->findAllByState('AZ');$this->Specimen->findAllByKingdom('Animalia');Povratni rezultat je niz formatiran koji je <strong>na</strong>đen sa find() ili findAll( ).15


findNeighbours ($conditions$field,$value);string $conditions;array $field;string $value;Vraća niz sa susjednim modelom (sa samo <strong>na</strong>vedenim poljima), specifiran sa $field i$value i filtriran sa SQL uslovima, $conditions. Ovo može biti korisno u situaciji kadaželimo 'Previous' i 'Next' linkove koji vode korisnika kroz uređenu sekvencu u <strong>na</strong>šemmodel-u ulaza. Ovo <strong>rad</strong>i samo za numerička i date polja. Primjer:class ImagesController extends AppController{function view($id){// Say we want to show the image...$this->set('image', $this->Image->find("id = $id");// But we also want the previous and next images...$this->set('neighbours', $this->Image->findNeighbours(null, 'id', $id);}}findCount ($conditions);string $conditions;Vraća broj rekorda koji odgovaraju zadanim uslovima.generateList ($conditions,$order,$limit,$keyPath,$valuePath);stringstringintstringstring$conditions;$order;$limit;$keyPath;$valuePath;Ova funkcija je shortcut za dobivanje liste ključnih vrijednosti parova – pogotovopraktič<strong>na</strong> za kreiranje html select tagova iz liste <strong>na</strong>šeg modela. Npr. ako želimo generiratilistu uloga baziranu <strong>na</strong> Role modelu, puni poziv može izgledati kao u sljedećem primjeru:$this->set(16


'Roles',$this->Role->generateList(null, 'role_<strong>na</strong>me ASC', null, '{n}.Role.id','{n}.Role.role_<strong>na</strong>me'));//This would return something like:array('1' => 'Account Ma<strong>na</strong>ger','2' => 'Account Viewer','3' => 'System Ma<strong>na</strong>ger','4' => 'Site Visitor');read ( $fields,$id);string $fields;string $id;Ovu funkciju možemo koristiti da dobijemo polja i vrijednosti polja iz trenutačnoučitanog rekorda ili rekorda specifiranog sa $id.query ($query);string $query;execute ($query);string $query;SQL poziv možemo <strong>na</strong>praviti koristeći model query( ) i execute ( )metode. Razlikaizmeđu query( ) i execute ( ) je ta što, query( ) koristimo da <strong>na</strong>pravimo korisnički SQLupit, a execute( ) koristimo da <strong>na</strong>pravimo korisničke SQL komande.Primjer:Veći<strong>na</strong> model pretraživača uključuju prosljeđivanje uslova u jednom ili u drugom pravcu.Najjednostavniji pristup ovome je pomoću WHERE klauzule iz SQL-a, ali ako <strong>na</strong>m jepotrebno više kontrole možemo koristiti nizove. Korištenje nizova je jednosatvno i lakoza čitanje i jednostavno je za pravljenje upita. Sintaksa odvaja elemente upita u diskretne,17


manipulativne dijelove. Ovo dozvoljava Cake-u da generira <strong>na</strong>jviše moguće efikasneupite, osigurava odgovarajuću SQL sintaksu. Upit baziran <strong>na</strong> nizu izgleda ovako:$conditions = array("Post.title" => "This is a post");//Example usage with a model:$this->Post->find($conditions);Traži bilo koji post gdje <strong>na</strong>slov odgovara stringu “This is a post”, mogli smo koristitisamo “title” kao ime polja. Kada pravimo upite, dobra je praksa uvijek specificirati imemodela, kao poboljšanje jasnoće koda i kao pomoć pri prevenciji kolizija u budućnostiako odlučimo mijenjati <strong>na</strong>šu šemu. I sa drugim komparacijama je isto, npr. ako želimo<strong>na</strong>ći sve postove gdje <strong>na</strong>slov nije “This is a post”.array("Post.title" => " This is a post")Sve što je dodano <strong>na</strong>lazi se između ‘< >’ tagova prije izraza. Cake može ob<strong>rad</strong>iti bilokoju validnu SQL komparaciju operatora uključujući odgovarajuće izraze koristećiLIKE, BETWEEN. Npr. Ako želimo <strong>na</strong>ći post gdje je <strong>na</strong>slov dat kao set vrijednosti:array("Post.title" => array("First post", "Second post", "Third post"))Dodavanje dodatnih filtera uslovima je jednostavno kao dodavanje dodatnih parovavrijednosti /ključeva nizu.array("Post.title" => array("First post", "Second post", "Third post"),"Post.created" => "> " . date('Y-m-d', strtotime("-2 weeks")))Cake prihvata sve validne SQL bool-ove operacije, uključujući AND, OR, NOT,XOR,...i možemo ih pisati malim ili velikim slovima.Po defaultu, Cake pristupa višestrukim uslovima sa bool-ovim AND, što z<strong>na</strong>či, odlomakkoji želimo odgovara samo postu koji je kreiran prije dvije sedmice i <strong>na</strong>slov odgovarajednom u datom setu. Mi možemo jednostavno <strong>na</strong>ći post koji odgovara bilo kojemuslovu:array("or" =>array("Post.title" => array("First post", "Second post", "Third post"),"Post.created" => "> " . date('Y-m-d', strtotime("-2 weeks"))))18


Snimanje podatakaDa bi snimili podatke u <strong>na</strong>š model, trebamo dostaviti podatke koje želimo snimiti, podacikoji se šalju save( ) metodi trebaju biti u sljedećoj formi:Array([ModelName] => Array([field<strong>na</strong>me1] => 'value'[field<strong>na</strong>me2] => 'value'))U redoslijedu slanja podataka controller-u u ovom <strong>na</strong>činu, lakše je koristiti HTML helperza ovo, jer kreira forme eleme<strong>na</strong>ta koje su imenovane <strong>na</strong> <strong>na</strong>čin koji Cake očekuje. Samotrebamo biti sigurni da forme eleme<strong>na</strong>ta imaju ime<strong>na</strong> kao što je data[Model<strong>na</strong>me][field<strong>na</strong>me], koristiti $html->input('Model/field<strong>na</strong>me') je <strong>na</strong>jjednostavnije. Podaci poslaniiz forme se automatski formatiraju i budu smješteni u $this->data u contoller-u, tako da jesnimanje podataka iz web formi brzo. Edit funkcija za svojstvo controller-a možeizgledati ovako:function edit($id){// The property model is automatically loaded for us at $this->Property.// Check to see if we have form data...if (empty($this->data)){$this->Property->id = $id;$this->data = $this->Property->read();//populate the form fields with thecurrent row}else{// Here's where we try to save our data. Automagic validation checkingif ($this->Property->save($this->data['Property'])){//Flash a message and redirect.$this->flash('Your information has been saved.','/properties/view/'.$this->data['Property']['id'], 2);}//if some fields are invalid or save fails the form will render}}Delete funkcija:del ( $id,19


$cascade);string $id;boolean $cascade;Brisanje modela specificiramo sa $id ili sa aktualnim id-om modela. Ako je modelpovezan sa drugim modelima, ova metoda će takođe obrisati povezani model. Ako je$cascade posatvljen <strong>na</strong> true, vraća true pri uspjehu, tj. <strong>na</strong>kon uspješnog brisanja.2.2. ViewView je page template, koji se obično imenuje poslije akcije, npr. view zaPostController::add() <strong>na</strong>lazi se u /app/views/posts/add.thtml.Add Post


Svi pogledi (views) unutar Cake-a se <strong>na</strong>laze u odvojenim fajlovima (*.thtml) koji suslobodni od kompleksnog PHP koda. Cake views su prilično jednostavni PHP file-ovi,<strong>na</strong>jviše view file-ova sadrži HTML. View takođe može biti bilo koji set podataka, npr.XML, image,..Views omogućava sve aspekte prezentacije, eksktaktuje podatke iz Modelai priprema ih kao HTML za web stranicu ili kao XML za web server ili kao tekst zamail. View ima pristup Model-u, ali nije dobro da View poziva metode Model-a kao štoje update, to bi trebalo u<strong>rad</strong>iti preko Controller-a. HTML Helper je po defaultu dostupanu svakom view-u i to je <strong>na</strong>jkorišteniji helper u view-u. Koristan je kod kreiranja formi,uključuje scripte, linkove, mediu…Mnoge funkcije u view-u su dostupne preko helpera,Cake dolazi sa velikim brojem helper-a, a može se kreirati i vlastiti. View ne trebasadržavati puno logike, zato nema puno korištenih javnih funkcija u view-u. Postoje dvadizajn pater<strong>na</strong> koja se koriste u view-u: Template View i Transform View. Razlikaizmeđu Template View-a i Transform View-a je u pristupu data flow-u. U Templatepočinje se sa skeletom outputa i insertuju domain podaci u to, dok u Transform View-upočinje se sa podacima i g<strong>rad</strong>i se output prema tome.Template View je primarni patern koji koristi template file (obično HTML) koji uključujespecijalne markere koji su zamijenjeni sa podacima iz modela kada je Template Viewizvršen. Popularni template Smarty je primjer template-a koji koristi custem syntaxmetodu. Transform View ekstraktuje podatke iz modela i transformiše ih u traženi outputformat.View :- layouts- elements2.2.1. LayoutsLayouts sadrži prezentacijski kod i bilo što što želimo vidjeti u view-u treba bitismješteno u layout-u. Layout file-ovi <strong>na</strong>laze se u /app/views/layouts. Cake-ov defaultnilayout može biti zamijenjen novim defaultnim layout-om kao/app/views/layouts/defaults.thtml. Jednom kada defaultni layout bude kreiran, controllerview kod biva smješten unutar defaultnog layout-a. Kada kreiramo layout treba “reči”Cake gdje se <strong>na</strong>lazi controller. Primjer kako može izgledati defaultni layout...21


...Možemo kreirati koliko hoćemo layout-a u Cake-u samo ih treba smjestiti u/app/views/layouts direktorij.2.2.2. ElementsMnoge aplikacije imaju male blokove prezentacijskog koda koji se treba po<strong>na</strong>vljati <strong>na</strong>više stranica, ponekad u različitim mjestima u layout-u. Cake pomaže da po<strong>na</strong>vljamo diowebsite-a koji <strong>na</strong>m je potreban. Help boksovi, <strong>na</strong>vigacijka kontrola,ekstra meniji suimplementirani u Cake-u kao elementi. Element je bazično mini view koji koji može bitiuključen u drugi View. Elementi se <strong>na</strong>laze u /app/views/elements/ folderu I imaju .thtmlfile ekstenziju. Elementi po defaultu nemaju nikakav pristup podacima, da bi dozvolilipristup podacima šaljemo ih kao imenovani parameter u niz.Primjer: Poziv eleme<strong>na</strong>ta bez parametraPoziv elementa kao niza podataka:U Element file-u sve propuštene varijable su varijable imenovane kao i niz , elementi semogu koristiti da View učine više čitljivim.22


2.3. ControllerController procesira i odgovara <strong>na</strong> događaje, tipič<strong>na</strong> korisnička akcija i poziva promjene<strong>na</strong> modelu.Controller se koristi za logičko upravljanje modelom, ime Controllera u Cake-u je uvijeku množini. Ime controller klase zavrašava sa „Controller“ npr. PeopleController,UsersController, klase AppController-a definisane su u app/app_controller.php i treba dasadrže metode koje su dijeljenene imeđu dva ili više Contoller-a. Ime controller file-apiše se malim slovima i završava sa '_controller', pa ako imamo controller klasu koja sezove PostsController, file controller će biti posts_controller.php, primjeri:people_controller.php, line_items_controller.php, really_nifty_things_controller.php. Dabi zaštitili vidljivost, ime akcije controller-a treba početi sa '-', za privatnu vidljivost,imetreba početi sa '- -'. Manipulacija sa nekoliko specijalnih varijabli u controller-udozvoljava da koristimo neke prednosti extra Cake funkcio<strong>na</strong>lnosti.Imamo dvije vrste Controller-a:- Front Controller- Application ControllerFront Controller često pomaže u centralizaciji aplikacijkog flow-a u jednostavnimtačkama. Centralizacija može pomoći da razumijemo kako kompleksan sistem operira i<strong>na</strong>vodi jednostav<strong>na</strong> mjesta gdje možemo ubaciti globalni kod. Front Controller je odličanza centralizaciju.Application Controller je centar onog čime MVC Controller operira. Primar<strong>na</strong>odgovornost je da odluči šta aplikacija treba odgovoriti <strong>na</strong> traženi zahtijev. Tipičan <strong>na</strong>činimpelmentacije Controller-a je koristeći Command paterne. Command patern enkapsuliraakciju u objekte, tako da možemo parametrizirati upit. U sadržaju web aplikacije koristanje cilj koda koji odvaja koncentrirani Command da brine o <strong>rad</strong>u pojedi<strong>na</strong>čni HTTPzahtijeva.2.3.1. Controller varijable:23


- $uses – ako controller koristi više od jednog modela, FragglesController ćeautomatski učitati $this->Fraggle, ali ako želimo pristupiti $this->Smurf, trebapokušati dodati sljedeću liniju koda u controller: var $uses = array('Fraggle','Smurf');Treba primjetiti da smo uključili Fraggle model u $uses niz, iako je automatski prijebio dostupan.- $helper – ova varijabla se koristi za učitavanje helpera u view. HTML helper seautomatski učitava, ali može se ova varijabla koristiti i za druge helpere npr. var$helpers = array('Html','Ajax','Javascript'). Treba uključiti HtmlHelper u $helpersako ga želimo koristiti, dostupan je po defaultu ali ako definišemo $helper bezHtmlHelpera, dobit ćemo poruku o greški u view-u.- $autoRender - postavljajući ovo <strong>na</strong> false će zaustaviti akciju od automatskogizvođenja- $components – kao $helpers i $uses, ova varijabla koristi se za učitavanjekompone<strong>na</strong>ta koje su <strong>na</strong>m potrebne npr. var $components = array('acl');- $beforeFilter – koristimo ovu varijablu ako želimo da se kod pokreće svaki put kadase akcija pozove . Ova funkcio<strong>na</strong>lnost je veoma dobra za access control- možemovidjeti korisničke permisije prije nego se izvrši bilo koja akcija. Primjer:class ProductsController extends AppController{var $beforeFilter = array('checkAccess');function checkAccess(){//Logic to check user identity and access would go here....}}function index(){//When this action is called, checkAccess() is called first.}2.3.1.Controller parametriController parametri su dostupni preko $this->params u Cake controller-u, ova varijablase koristi da dajemo podatke u controller i omogućava pristup informacijama o tačnomupitu. Najčešće se koristi da se dobiju informacije (podaci) koje su date controller-upreko POST ili GET operatora.$this->dataPrimjer: slanje podataka POST metodom iz HTML Helper-a u controller// A HTML Helper is used to create a form element$html->input('User/first_<strong>na</strong>me');24


When rendered in the HTML would look something like:// And when submitted to the controller via POST,// shows up in $this->data['User']['first_<strong>na</strong>me']Array([data] => Array([User] => Array([user<strong>na</strong>me] => mrrogers[password] => myn3ighb0r[first_<strong>na</strong>me] => Mister[last_<strong>na</strong>me] => Rogers)))Akcija je jedinstve<strong>na</strong> funkcio<strong>na</strong>lnost kontrolera, pokreće se automatski po zahtijevu.- set( ) funkcija je glavni put da uzmemo podatke iz controller-a da bi ih vidjeli,parametri funkcije mogu biti jednostavne vrijednosti, nizovi... set($var,$value), string$var, mixed $value. Funkciju set( ) možemo koristiti da uzmemo bilo šta: jednosatvnevrijednosti, cijele nizove,..Jednom kada koristimo set(), varijablama može se pristupiti uview-u, ako <strong>na</strong>pišemo set('color','blue') , controller <strong>na</strong>pravi varijablu $color dostupnomu view-u.- $this->flash( ) funkcija zove se upravljačka funkcija koja prikazuje korisniku porukunpr. $this->flash ('Your post has been saved.','/posts'); tj. Ispisuje poruku korisniku da jenjegov post snimljen ili $this->flash ('The post with id: '.$id.' has been deleted.', '/posts');ispisuje poruku da je post izbrisan.Save() metoda provjerava greške i neće snimiti podatke ako postoji greška.- validateErrors( ) - vraća broj grešaka koje su generirane pri neuspješnom snimanjupodataka.- render ( ) je funkcija koja se često ne koristi, jer render se automatski poziva <strong>na</strong> krajusvake kontrolne akcije.U sljedećem primjeru imamo Post controller sa četiri funkcije: funkcija index ( ), add ( ),edit ( ) i delete ( ). Funkcija index <strong>na</strong>m prikazuje početnu stranicu tj. stranicu koju smopostavili da bude index<strong>na</strong>, počet<strong>na</strong>, koja prikazuje <strong>na</strong>slov postojeće vijesti. Omogućavadodavanje novih vijesti, edit i delete vijesti koje su <strong>na</strong>laze u bazi.25


26


2.3.2. Controller callbackU Cake-u callback je <strong>na</strong>čin izvršavanja nekog koda prije ili poslije Model ili Contollermetoda. Cake controller omogućava odgovarajući broj callback-ova koji možemoiskoristiti da bi ubacili logiku prije ili poslije z<strong>na</strong>čajnih funkcija controller-a. Trebadeklarisati funkcije u controller-u koristeći parametre i povratne vrijednosti.- beforeFilter ( ); poziva se prije svake controller akcije, koris<strong>na</strong> za provjeru aktivnisesija i provjeru uloga- afterFilter ( ); poziva se <strong>na</strong>kon svake controller akcije- beforeRender ( ); poziva se <strong>na</strong>kon controller logike i prije nego što je view prikazanSljedeće funkcije su dio Cake objekt klase, ali one mogu biti dostupne i u controller-u- requestAction ( $url, $options);string $url;array $options;Ova funkcija poziva controller akciju iz bilo koje lokacije i vraća tj. prikazuje view.$url je Cake URL (/controller<strong>na</strong>me/action<strong>na</strong>me/params), ako $extra niz uključuje'return' , AutoRender automatski postavlja true za controller akciju. Možemo koristitirequestAction da dobijemo podatke iz druge controller akcije ili da dobijemo potpunirender view iz controller-a. Uzimanje podataka iz controller-a je jednostavno, koristise samo upit<strong>na</strong> akcija u view-u u iz kojeg trebamo podatke.{}// Ovdje je jednostavni controllerclass UsersController extends AppControllerfunction getUserList(){}$this->User->findAll();Možemo kreirati callback u <strong>na</strong>šem aplikacijskom Model-u ili Controller file-u. U ovomprimjeru šaljemo email iz Model-a


var $<strong>na</strong>me = 'Bookmark';function afterSave(){// mail me when a new bookmark is addedmail('example@example.com', 'Bookmark saved to database');return true;}}?>3. HelperCake ima nekoliko već kreiranih helpera koje možemo iskoristiti, a to su:- HTML- AJAX- Javacript- Number- Text- Time- CacheSvaka metoda u helperu treba da prihvati argumente u sljedeći <strong>na</strong>čin:helperMethod(mixed $params[, mixed $secondArg = null[, ...]])U svakoj funkciji treba provjeriti je li prvi argument niz, to provjeravamo sa funkcijomis_array ( ), ako je prvi argument niz, treba provjeriti specifični ključ sa funkcijomarray_key_exists ( ).3.1. HTML HelperHTML Helper je jedan od <strong>na</strong>či<strong>na</strong> Cake-a za brži i manje monoton razvoj. HTML Helperima dva cilja:1. Omogućiti ubacivanje često ponovljene sekcije HTML koda2. Omogućiti brzo i jednostavno kreiranje web formiMnoge funkcije u HTML Helper-u koriste HTML tagove definisane u file-utags.ini.php. Ako želimo neke promjene <strong>na</strong>pravimo kopiju /cake/config/tags.ini.php isnimimo je u /cake/config/ folder. HTML Helper funkcije takođe uključuju$htmlAttributes parametre. Ako želimo koristiti Cake za ubacivanje dobro formirani ičesto korištenih eleme<strong>na</strong>ta u HTML kodu, HTML Helper je veoma dobar u tome. Postojefunkcije u ovom helperu koje insertuju mediu, tabele, liste,…Generiranje charset MET-a taga:charset ( $charset,$return );28


string $charset;boolean $return;Kreiranje linka u CSS stylesheet-u :css( $path,$rel=’stylesheet’,rel=vrijednost za tag$htmlAttributes,$return = ‘false’);//$rel parameter dozvoljava kreiranjestring $path;string $rel=’stylesheet’;array $htmlAttributes;boolean $return = ‘false’;HTML HelperiAko <strong>na</strong>pišemo:CakePHP <strong>na</strong>m vraća:koji učitava stil za <strong>na</strong>šu stranicuAko <strong>na</strong>pišemo:Cake <strong>na</strong>m vraća:CakePHP Homekoji vidimo kao CakePHP HomeAko <strong>na</strong>pišemo:Cake <strong>na</strong>m vraća:First Name Last Name Emailšto prikazuje kaoFirst Name Last Name EmailAko <strong>na</strong>pišemo:CakePHP <strong>na</strong>m vraća:29


Dunnottar Ceiteach emailšto prikazuje :Dunnottar Ceiteach emailAko <strong>na</strong>pišemo:CakePHP <strong>na</strong>m vraća:što prikazujePrimjer definicije HtmlHelper::link ( )


}$values = array('href' => $href,'options' => $this->_parseOptions($options),'tagValue' => $title);return $this->assign('link', $values);}?>Form tagovi koje HTML Helper može generirati:- password- submitpassword ($fieldName,$htmlAttributes,$return = false);stringarrayboolean$filedName;$htmlAttributes;$return = false;submit ( $buttonCaption,$htmlAttributes,$return = false);string $buttonCaption;array $htmlAttributes;boolean $return = false;3.2. TimeHelper- trimAko <strong>na</strong>pišemo:CakePHP vraća:Source chara...- niceAko <strong>na</strong>pišemo:31


CakePHP vraća:Mon, Apr 29th 2013, 18:13- dayAsSqlAko <strong>na</strong>pišemo:CakePHP vraća:(created >= '2013-04-29 00:00:00') AND (created CakePHP vraća true ako je dati datum da<strong>na</strong>šnji3.3. NumberHelper- precisionAko <strong>na</strong>pišemo:CakePHP vraća:123.457- toPercentageAko <strong>na</strong>pišemo:CakePHP vraća:98.77%- currencyAko <strong>na</strong>pišemo:CakePHP vraća:$98,765.43- formatAko <strong>na</strong>pišemo:32


CakePHP vraća:98,765.43- toReadableSizeAko <strong>na</strong>pišemo:CakePHP vraća:117.74 MB3.4. Kreiranje vlastitih helperaKonvencija imenovanja je slič<strong>na</strong> kao u modelu:• LinkHelper = class <strong>na</strong>me• link = key in helpers array• link.php = <strong>na</strong>me of php file in /app/views/helpersAko želimo kreirati helper koji će koristiti output CSS style linka koji trebamo uaplikaciji, prvo trebamo kreirati novu klasu u app/views/helpers, npr. da se <strong>na</strong>š helperzove LinkHelper, file php klase trebao bi izgledati ovako:Putanja: /app/views/helpers/link.phpclass LinkHelper extends Helper{function makeEdit($title, $url){// Logic to create specially formatted link goes here...}}Postoji nekoliko funkcija uključenih u Cake helper klase koje možemo iskoristiti:output ( $string,$return = false);string $string;boolean $return = false;Ako koristimo output ( ) za formatiranje <strong>na</strong>ših linkova title i URL i vraćanje ih u view, ulink.php trebamo dodati:Putanja: /app/views/helpers/link.phpclass LinkHelper extends Helper{function makeEdit($title, $url){33


Use the helper's output function to hand formatted// data back to the view:return $this->output("$title");}}Možemo koristiti neke već postojeće funkcio<strong>na</strong>lnosti drugog helpera. Da koristimoprednosti drugi helpera trebamo specificirati helper koji želimo koristiti, $helper nizom,zatim pišemo funkcije kao u controller-u npr.Putanja: /app/views/helpers/link.php ( korištenje drugi helpera)class LinkHelper extends Helper{var $helpers = array('Html');function makeEdit($title, $url){// Use the HTML helper to output// formatted data:$link = $this->Html->link($title, $url, array('class' => 'edit'));}}return $this->output("$link");Kada kreiramo vlastiti helper snimimo ga u /app/views/helpers/ i bit ćemo u mogućnostida ga uključimo u <strong>na</strong>š contoller-u preko specijalne varijable $helpers, npr.class ThingsController{var $helpers = array('Html', 'Link');}4. ScaffoldingScaffolding je dobar <strong>na</strong>čin uzimanja početnog dijela web aplikacije, počet<strong>na</strong> šema baze itema se mijenjaju, što je normalno u početnom dijelu dizaj<strong>na</strong> procesa. Web developeri nevole kreirati forme koje nikad neće “stavrno” koristiti. Da bi smanjili pritisak <strong>na</strong>developere, scaffolding je uključen u Cake. Scaffolding a<strong>na</strong>lizira tabele u bazi i kreirastand<strong>rad</strong>nu listu sa add, delete i edit dugmićima. Strandardnu formu za edit i standardni34


view za provjeru jednostavni item-a u bazi. Za dodavanje scaffoldinga u aplikaciju, ucontroller treba dodati varijablu $scaffold;Scaffold očekuje da bilo koje ime polja koje završava sa “_id” je strani ključ za tabelukoja ima ime koje predhodi “ _”, npr. Ako imamo tabelu category i kolonu parent_id,parent_id je strani ključ za tabelu parent. Kada imamo strani ključ u tabeli (tabela title sacategory_id) i imamo asocijaciju modela, oz<strong>na</strong>čeni box će se automatski popuniti saredom iz strane tabele (category) u show/edit/new view. Da postavimo koje polje ustranoj tabeli će se prikazivati, postavimo varijablu $displayField u strani model. Primjer:Ako želimo nešto drugačiji scaffolding view, možemo kreirati vlastiti. Primjer:Custom scaffolding views for a PostsController should be placed like so:/app/views/posts/scaffold/index.scaffold.thtml/app/views/posts/scaffold/show.scaffold.thtml/app/views/posts/scaffold/edit.scaffold.thtml/app/views/posts/scaffold/new.scaffold.thtmlOsobi<strong>na</strong> koja može koristiti u Cake-u je kod generator: Bake. Bake dozvoljava dageneriramo kodiranu verziju scaffold koda, koju zatim možemo premjestiti imodifikaovati prema zahtijevima aplikacije.5. Data ValidationKreiranje korisnički validacijski pravila pomaže da podaci budu sigurni u Model-u uzpravila aplikacije, npr. lozinka može biti samo osam karaktera, korisničko ime možesadržavati samo slova,…Prvi korak u data validation je kreiranje validacijskih pravila u Model-u. Da bi to u<strong>rad</strong>ilikoristimo Model:: validate array u Model definiciji, primjer:35


Putanja: /app/models/user.phpValidacije se definišu koristeći Perl kompatibilne regularne ekspresije, neke od njih supredefinisane u /lib/validators.php, to su:VALID_NOT_EMPTYVALID_NUMBERVALID_EMAILVALID_YEARAko postoji bilo koja validacija u modelu definicije ($validate array) bit će a<strong>na</strong>lizira<strong>na</strong> iprovjere<strong>na</strong> tokom snimanja (Model:: save() method). Za direktnu validaciju podatakakoristimo Model::validates() (vraća false ako su podaci pogrešni) i Model::invalidFields()(vraća error message kao niz). Ali su obično podaci u kodu controller-a, primjer:/app/controllers/blog_controller.php


}}}?>View za blog može izgledati ovako:/app/views/blog/add.thtmlAdd post to blog


function startup(&$controller){// This method takes a reference to the controller which is loading it.// Perform controller initialization here.}}function doFoo(){$this->someVar = 'foo';}Da bi koristili komponentu trebamo dodati sljedeći kod u definiciju controller-avar $components = array('Foo');Sada u controller-u možemo koristiit:$this->Foo->doFoo();Komponente imaju dozvolu controller-a da se učitaju u startup() metodi, ova metoda sepoziva poslije Controller::beforeFilter(). Ovo <strong>na</strong>m dozvoljava da postavimo osobinekomponente u beforeFilter() metodu koja komponenta će se izvršiti u startup() metodi.Da bi koristili <strong>na</strong>š model u komponenti, trebamo kreitati instancu:$foo =& new Foo();Možemo koristiti i druge komponente u vlastitoj komponenti, jednostavno u <strong>na</strong>šojkomponenti deklariramo koju komponentu želimo kotistiti. Primjer: ako želimo koristitisession komponentu:var $components = array('Session');38


7. Servis “Anketa”7.1. Tabele servisaServis se sastoji od pet tabela:39


1. polls - u tabelu „polls“ smještamo id (primarni ključ tabele), ime ankete (<strong>na</strong>me),ukupno odgovora (ukupno_odg) tj. broj korisnika koliko ih je glasalo i brojodgovora (noq) tj. broj odgovora koliko će imati anketa. Tabela „polls“ je uodnosu 1:1 sa tabelom „questions“ tj. jed<strong>na</strong> anketa može imati samo jednopitanje, a 1:n u odnosu <strong>na</strong> tabelu „results“, jer jed<strong>na</strong> anketa može imati višerezultata.40


}2. poll.phpclass Poll extends AppModel{var $<strong>na</strong>me = 'Poll';}3. answer.phpclass Answer extends AppModel{var $<strong>na</strong>me = 'Answer';}4. result.phpclass Result extends AppModel{var $<strong>na</strong>me = 'Result';}7.2.2. ViewServis „Anketa“ ima view „polls“ koji se sastoji od četiri php file-a:1. admin_index.phpKreirati:42


foreach ($langs as $lang){echo $html->hidden('Pages_'.$lang['Language']['code'].'/poll_id', array('value' => $poll_id));echo $html->hidden('Pages_'.$lang['Language']['code'].'/lang',array('value' => $lang['Language']['id'])); ?>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Pitanje:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Odgovori:&nbsp;&nbsp;44


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U file-u admin_add_qu.php <strong>na</strong>pravili smo formu koja pomoću metode post unesenepodatke prosljeđuje admin_add_an.php file-u. Imamo dvije foreach petlje, prvu foreachpetlju koristimo da izlistamo sve jezike koji se <strong>na</strong>laze u bazi. Drugu foreach petljukoristimo da ispišemo pitanja i odgovore <strong>na</strong> svim jezicima. Tabeli smo u neke redove ikolone dodali boju pozadine, css class, zastavu pored <strong>na</strong>ziva jezika...Koristimo htmlhelper za skriveno „hidden“ polje za provjeru poll_id i coda za jezik, tj. id tabele„languages“, html helper za snimanje/submit i html helper za unos/input.4.admin_add_an.php


cellpadding="0">Hellooooo!!!!


function admin_index(){$this->set('rootPath', 'http://localhost/cake/');$this->set('imgPath', 'http://localhost/cake/img/');}Funkcija admin_index() služi za kreiranje varijeble za prikaz početne strane. U <strong>na</strong>šemprimjeru kreiramo varijablu $rootPath, koju zatim pozivamo u funkcijama kada trebamoprikazati početnu stranu, u <strong>na</strong>šem primjeru 'http://localhost/cake/' i kreiramo varijablu$imgPath za prikaz slika, odnosno loga i slika potrebnih za bolji dizajn strane.function admin_add_qu(){$this->set('rootPath', 'http://localhost/cake/');$this->set('imgPath', 'http://localhost/cake/img/');if ($this->data){$n = $this->data;$<strong>na</strong>me=$n['Poll']['<strong>na</strong>me'];$noq=$n['Poll']['noq'];$ret = $this->Poll->query("SELECT max(id) FROM polls");$ret = $ret[0];$id = $ret[0]['max(id)']+1;if($id == 0)$id = 1;$polls_id = $id;$this->Poll->query("INSERT INTO polls(`id`,`<strong>na</strong>me`, `ukupno_odg`,`noq`)VALUES('$polls_id','$<strong>na</strong>me', '0','$noq')");$ret = $this->Poll->query("SELECT max(id) FROM results");$ret = $ret[0];$id = $ret[0]['max(id)']+1;if($id == 0)$id = 1;for($i=0; $iPoll->query("INSERT INTO results(`id`, `rezultat`, `anketa_id`)VALUES('$id', '0', '$polls_id')");}$this->set('langs', $this->requestAction('/languages/getLanguages'));47


$this->set('poll_id', $polls_id);$this->set('pitanja', $pitanje_id);}}Funkciaj admin_add_qu() provjerava da li postoje podaci. Ako postoje podaci uzimamax id tabele polls i u tabelu polls smješta podatke tj. ime ankete i broj odgovora. Zatimuzima max id od „results“ i prolazi kroz for petlju onoliko puta koliko ima odgovora uanketi i u tabelu „results“ unosi rezultat tj. ukupan broj glasova za svaki odgovor ianketa_id da poveže odgovore sa anketom.function admin_add_an(){$this->set('rootPath', 'http://localhost/cake/');$this->set('imgPath', 'http://localhost/cake/img/');if ($this->data){$ret = $this->Poll->query("SELECT max(id) FROM questions");$ret = $ret[0];$id = $ret[0]['max(id)']+1;if($id == 0)$id = 1;$questions_id = $id;foreach($this->data as $podaci){$this->Poll->query("INSERT INTO questions (`id`, `anketa_id`, `lang_id`,`pitanje`)VALUES('$questions_id','{$podaci['poll_id']}','{$podaci['lang']}','{$podaci['question']}')");$i = 1;while(isset($podaci['answer_'.$i])){$odgovor = $podaci['answer_'.$i];$result_id = $podaci['result_id_'.$i];$this->Poll->query("INSERT INTO answers (`odgovor`, `lang_id`, `pitanja_id`,`rezultati_id`) VALUES('$odgovor', '{$podaci['lang']}', '$questions_id','$result_id')");$i++;}}}$questions_id++;48


Funkcija admin_add_an() provjerava da li postoje podaci. Ako postoje podaci uzima maxid iz tabele „questions“, prolazi kroz foreach petlju dok postoje podaci, upisuje id ankete,id jezika i pitanje u tabelu „questions“, a odgovore, id jezika, id pitanja i id rezultataupisuje u tabelu „answers“. Varijabla $i se inkrementuje onoliko puta koliko imamoodgovora i $questions_id onoliko puta koliko ima jezika u bazi.function rezultati($id ){return $this->Poll->query("SELECT r.rezultat, a.odgovor FROM answers a, results rWHERE a.rezultati_id = r.id AND a.lang_id = '$id'");}Funkcija rezultati() vraća broj glasova za svaki odgovor u anketi.function ukupnoGlasaova($id ){$page = array ('id' => $id);}$ukupno = $this->Poll->findAll($page);return $ukupno[0]['Poll']['ukupno_odg'];Funkcija ukupnoGlasaova() vraća ukupan broj glasova i ispisuje ih <strong>na</strong> indexnu stranu, tj.<strong>na</strong> stranu gdje se <strong>na</strong>lazi anketa.2. results_controller.phpclass ResultsController extends AppController {}var $<strong>na</strong>me = 'Results';function inc($id){$page = array ('id' => $id);49


$rez = $this->Result->findAll($page);$rez_id = $rez[0]['Result']['id'];$this->Result->query("UPDATE `results` SET`rezultat` = `rezultat` + 1WHEREid = '$rez_id'");$this->Result->query("UPDATE `polls` SET`ukupno_odg` = `ukupno_odg` + 1 ");$ip_ = getenv ("REMOTE_ADDR");$this->Result->query("INSERT INTO checkip (`IP`, `poll_code`) VALUES('$ip_', ' ')");setcookie("DNCCMSANKETA", "glasao");}Funkcija inc() inkrementuje broj odgovora i ukupan broj glasova, tj. vrši update tabeleresults i polls. Pomoću funkcije getenv() uzima ip adrese korisnika i snima ih u tabelu“checkip“ i postavlja cookie ako je korisnik glasao.function provjeraGlasanja(){$ip_ = getenv ("REMOTE_ADDR");if($this->Result->query("SELECT poll_code FROM checkip WHERE IP = '$ip_'"))$uslov1 = false;else$uslov1 = true;if(isset($_COOKIE['DNCCMSANKETA']))$uslov2 = false;else$uslov2 = true;50


if(($uslov1) && ($uslov2))return true;elsereturn false;}Funkcija provjeraGlasanja() provjerava da li postoji korisnikova IP adresa u bazi i da liima cookie. Ako ima IP ili cookie ili oboje, prikazuje reultate ankete, a ako ne prikazujeanketu i korisnik ima mogućnost glasanja. Ova funkcija se poziva u /pages/display.phpfile-u.3. answers_controller.php}Controller answers ima samo funkciju odgovori() koja vraća odgovore i rezultati_id kojisu povezani preko anketa_id, pitanje_id i land_id. U <strong>na</strong>šem primjeru anketa_id = 1,land_id = 1 i pitanje_id u tabeli „answers“odgovara id-u u tabeli „questions“.4. questions_controller.phpclass QuestionsController extends AppController {var $<strong>na</strong>me = 'Questions';function admin_index(){$this->set('rootPath', 'http://localhost/cake/');$this->set('imgPath', 'http://localhost/cake/img/');}function view($id = null){51


}$this->Question->id = $id;$this->set('questions', $this->Question->read());}Funkcija admin_index() ima istu funkciju kao u controller-u polls, funkcija view() služiza prikaz pitanja <strong>na</strong> osnovu id-a.function pitanje($id = 1, $lang_id = 1){$pitanje = array ('anketa_id' => $id, 'lang_id' => $lang_id);}$pitanje = $this->Question->findAll($pitanje);return $pitanje[0]['Question']['pitanje'];Funkcija pitanje() služi za ispis pitanja <strong>na</strong> indexnoj strani, poziva se u /pages/display.phpfile-u.7. 3. Upustvo za servisServis „Anketa“ sa aspekta adminstracijskog dijela treba da omogući kreiranje,editovanje i brisanje ankete. Administrator kreira anketu, unosi <strong>na</strong>ziv ankete i brojodgovora, zatim pitanje i odgovore.1. Na admin strani kliknemo <strong>na</strong> link anketa52


2. Zatim se otvara nova stra<strong>na</strong> sa linkom za dodavanje nove ankete3. Admin unosi <strong>na</strong>ziv ankete npr. anketa br.1 i broj odgovora u anketi53


4. Admin unosi pitanje i odgovore <strong>na</strong> više jezika tj. <strong>na</strong> sve jezike kojeima u bazi54


Sa aspekta korisnika:1. Korisnik posjećuje stranu2. Provjerava se korisnikova IP adresa i cookie3. Ako nema u bazi IP adrese i korisnik nema cookie-a, dozvoljava se glasanje,<strong>na</strong>kon klika <strong>na</strong> dugmić “glasati“, prikažu se rezultati glasanja4. Ako postoji IP adresa ili cookie, korisniku se prikazuju rezultati anketeKljučne mogućnosti servisa:- kreiranje ankete- glasanje- pregled rezultata anketeAplikacija dozvoljava da korisnik može samo jednom glasati <strong>na</strong> anketi <strong>na</strong> osnovu IPadrese i cookie-a. Ako korisnik pokuša drugi put glasati, prikazuje mu automatski rezultatankete. Servis je implementiran <strong>na</strong> 3 jezika (bosanski, engleski, njemački) i imamogućnost dodavanja novi jezika. Servis treba biti dostupan 24h svih sedam da<strong>na</strong> u56


sedmici. Servis <strong>na</strong>m treba omogućiti da dobijemo mišljenje korisnika o anketi „temi“koju postavimo.Izvještaji:- prezentacijski dio- administracijski dioUsability:- Lakoća korištenja servisa, potrebno je osnovno poz<strong>na</strong>vanje <strong>rad</strong>a <strong>na</strong> raču<strong>na</strong>ru ( zakriranje ankete) i mogućnosti i z<strong>na</strong>nje korištenja interneta ( za glasanje i pregledrezultata)Kategorije korisnika:- obični korisnici (imaju mogućnost glasanja i pregleda rezultata)- administratori ( imaju mogućnost kreiranja ankete)CASE:Naziv:Cilj:Prioritet:Grupakorisnika:Preduslovi:Sce<strong>na</strong>rio:CASE1- kreiranje anketeKreirati anketu da bi dobili informacije od korisnikaVisokAdminServer mora biti online1. Admin kreira anketu <strong>na</strong> admin dijelu2. Anketa je prikaza<strong>na</strong> <strong>na</strong> prezentacijskom dijeluNaziv:Cilj:Prioritet:Grupakorisnika:CASE2 - glasanjeGlasati <strong>na</strong> anketiVisokGost57


Preduslovi:Sce<strong>na</strong>rio:Server mora biti online, gost mora biti online, posjetiti stranicu, da nijeprije glasao1. Gost posjećuje stranicu2. Provjera gostove IP adrese i cookie-a,3. Na osnovu IP adrese i cookie-a daje se mogućnost glasanja ilipregleda rezultataNaziv:Cilj:Prioritet:Grupakorisnika:Preduslovi:Sce<strong>na</strong>rio:CASE3 – pregled rezultataPregledati rezultate glasanje anketeVisokAdmin, gostServer mora biti online, korisnik mora biti online, posjetiti stranicu zapregled rezultataZa gosta:1. Gost posjećuje stranicu2. Ako prvi put glasa, za pregled treba kliknuti da dugnić„Pregled rezultata“3. Ako je već glasao, automatski se prikazuju rezultatiZa admi<strong>na</strong>:1. Posjećuje stranicu2. A<strong>na</strong>lizira rezultate anketeDokumentacija semi<strong>na</strong>rskog:- osnove CakePHP-a- opis aplikacije- MVC za servis „Anketa“- case-ovi servisa „Anketa“58


ZAKLJUČAKCakePHP je framework koji ima podršku za puno stvari kao što je memcache,xcache, html helperi, ajax,..a uskoro bi trebao dobiti podršku za I18 arhitekturu,CakeAMFPHP za vezivanje <strong>na</strong> flash,..Primarni cilj semi<strong>na</strong>rskog je bio predstavitistrukturu frameworka koji omogućava PHP korisnicima svih nivoa brzi razvoj webaplikacija, bez gubljenja fleksibilnosti. Jedini nedostatak koji sam pročitala tokomistraživanja za semi<strong>na</strong>rski je što se do sada core cakephp mijenjao nekoliko puta, no sverzijom 2.0 bi se to trebalo stabilizirati. MVC framework možemo iskoristiti za većinuaplikacija u PHP-u koje želimo <strong>na</strong> brzinu iskodirati i time sami sebi uštediti vrijeme i<strong>na</strong>tjerati se da se držimo nekih standarda. Svi MVC framework-ovi <strong>na</strong>stoje zadovoljitiiste ciljeve i u MVC filozofiji su pravila jas<strong>na</strong>, tako da ni implementacija ne može bititoliko različita. MVC arhitektura pomaže sa čistim predstavljanjem databasefunkcijalnosti, biznis logike i prezentacije. CakePHP developri <strong>rad</strong>e <strong>na</strong> razvoju preko 100projekata. Cakephp ima <strong>na</strong>pravljene komponente za autentifikaciju, brute forceprotection, pagi<strong>na</strong>tion, automatic layout switcher... Primjenom frameworka se dobivamnogo prednosti: portabilnost, stabilnost, ubrzanje razvoja,višejezičnost,….59


LITERATURA1. CakePHP Manual2. PHP Design Patterns3. ETF Sarajevo, RI, SPIS 20064. CakesheetWeb stranice:www.cakephp.orgwww.forgephp.orgwww.wikipedia.orgwww.mi3dot.orghttp://bakery.cakephp.org60

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!