RTFB!
12 Dec
Kar nekajkrat sem že zasledil da folk moti ker nam findAll(), in vse ostale funkcije modela, vrnejo array. Z Set::map() funkcijo lahko zadevo pretvorimo v objekte.
Recimo da imamo modele User, Profile in pa Comment. Med njimi imamo relacije. User ima en Profil (User $hasOne Profile, Profile $belongsTo User, Comment $belongsTo User, User $hasMany Comments).
V primeru da sedaj hočemo pogledati vse podatke od enega uporabnika z funkcijo:
$this->set('userData', Set::map($userData)); // Podamo podatke v template oz. view
Sedaj bomo v template dobili namesto arraya objekt. In sicer:
$userData->id; // User id $userData->Profile->id; // Profile id $userData->Comment->id; // Comment id
Seveda spremenljivke objektov lahko uporabite katerekoli, pač imena polj v tabelah… Hotel sem povedati, da glavni objekt User ne kličemo recimo $userData->User->id ampak samo $userData->id, kar se mi zdi tudi logično.
Sicer mogoče tole vse skup ni kaj posebenga ampak mogoče pa komu pride prav
iNobl: 40% [?]
4 Aug
Tokrat bom opisal eno preprosto uporabo pagerja v CakePHP aplikaciji. Primer bom navedel za novice. Recimo da hočemo na eni strani po 5 novic razvrščenih po datumu.
Na svežo si skopiramo nekam najnovejšo različico CakePHP frameworka. Jaz sem si dal zadevo v direktorij “cakephp”. Kam boste dali sami je vaša odločitev.
V app/config/core.php spremenimo vrednost konstante CAKE_SESSION_STRING v nek drug poljuben random string. To nam sistem tudi napiše. Imeti morate tudi pisljiv app/tmp direktorij.
Gremo k bistvu. Naredimo bazo. V bazi naredimo tabelo news z naslednjimi polji:
CREATE TABLE `news` ( `id` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(35) NOT NULL, `flash` text NOT NULL, `content` text NOT NULL, `hidden` tinyint(1) NOT NULL, `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), FULLTEXT KEY `content` (`content`), FULLTEXT KEY `flash` (`flash`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
Lahko bi uporabil samo id, title, content, created polja vendar sem zaradi nadlanjih zapisov tabelo malce razširil da se nebo treba takrat matrati
Sedaj preimenujemo app/config/database.php.default v database.php. V database.php nastavite vse potrebne podatke za povezavo do vaše baze.
Primer:
class DATABASE_CONFIG { 'driver' => 'mysql', 'persistent' => false, 'host' => 'localhost', 'login' => 'username_za_dostop_do_vase_baze', 'password' => 'geslo', 'database' => 'ime_vase_baze', 'prefix' => '' ); }
F5 in sistem bi vam moral izpisati da se je uspešno povezal do vaše baze => “Your database configuration file is present.”. V primeru napake vam bo to sistem lepo povedal
Naredimo file app/app_controller.php. In dodamo vanj naslednje:
< ?php class AppController extends Controller { public $ext = '.tpl'; } ?>
Kaj nam app_controller.php omogoča ? Omogoča nam da v aplikaciji nastavimo neke nastavitve na neko vrednost ki jo hočemo da je veljavna povsod in ne samo v določenem kontrolerju. S spremenljivko $ext nastavimo končnico za template “.tpl”. Po defaultu uporablja sistem .ctp. Ta korak vam ni treba narediti vendar morate template ustvariti z .ctp končnico namesto .tpl.
Naredimo kontroler. app/controllers/news_controller.php
V news_controller.php file damo naslednje:
< ?php class NewsController extends AppController { public $name = 'News'; public function index() { } } ?>
Naredimo model models/news.php. Dodamo naslednje:
< ?php class News extends AppModel { public $name = 'News'; } ?>
Naredimo tepmlate za prvo stran pri novicah app/views/news/index.tpl. Sedaj gremo na http://vas.host.name/direktorij_kjer_je_cakephp/news/. Če je kaj pravice na svetu potem nebi smeli dobiti nobenega error-ja.
Dodajmo nekaj vnosov v tabelo news.
INSERT INTO `news` VALUES (1, 'Novica 1', 'Uvod za novico 1', 'Glavno besedilo za novico 1', 0, '2007-08-04 19:31:53'); INSERT INTO `news` VALUES (2, 'Novica 2', 'Uvod za novico 1', 'Glavno besedilo za novico 2', 0, '2007-08-04 19:31:53'); INSERT INTO `news` VALUES (3, 'Novica 3', 'Uvod za novico 3', 'Glavni opis za novico 3', 0, '2007-08-04 19:32:52'); INSERT INTO `news` VALUES (4, 'Novica 4', 'Uvod za novico 4', 'Glavni opis za novico 4', 0, '2007-08-01 19:32:52'); INSERT INTO `news` VALUES (5, 'Novica 5', 'Uvod za novico 5', 'Glavni opis za novico 5', 0, '2007-08-01 19:33:53'); INSERT INTO `news` VALUES (6, 'Novica 6', 'Uvod za novico 6', 'Glavni opis za novico 6', 0, '2007-08-04 19:33:53'); INSERT INTO `news` VALUES (7, 'Novica 7', 'Uvod za novico 7', 'Glavno besedilo za novico 7', 0, '2007-07-04 19:31:53'); INSERT INTO `news` VALUES (8, 'Novica 8', 'Uvod za novico 8', 'Glavno besedilo za novico 8', 0, '2007-08-04 19:31:53'); INSERT INTO `news` VALUES (9, 'Novica 9', 'Uvod za novico 9', 'Glavni opis za novico 9', 0, '2007-08-04 19:32:52'); INSERT INTO `news` VALUES (10, 'Novica 10', 'Uvod za novico 10', 'Glavni opis za novico 10', 0, '2007-06-04 19:32:52'); INSERT INTO `news` VALUES (11, 'Novica 11', 'Uvod za novico 11', 'Glavni opis za novico 11', 0, '2007-08-02 19:33:53'); INSERT INTO `news` VALUES (12, 'Novica 12', 'Uvod za novico 12', 'Glavni opis za novico 12', 0, '2007-08-03 19:33:53');
V kontrolerju pridobimo podatke in vključimo pager in nato prikažimo zapise v index.tpl.
V news_controller.php dodajmo:
V index() funkcijo dodajmo naslednje:
$this->set('News', $this->paginate('News'));
V prvi vrstici povemo pager-ju da naj rezultate sortira po polju created v padajočem načinu. V drugi vrstici pridobimo podatke iz baze in jih podamo v template index.tpl. V index.tpl bodo novice v $News spremenljivki.
Sedaj bi moral news_controller.php izgledati nekako takole:
< ?php class NewsController extends AppController { public $name = 'News'; public function index() { $this->set('News', $this->paginate('News')); } } ?>
Prikažimo podatke in pager v index.tpl.
V index.tpl:
<table cellpadding="0" cellspacing="0" width="50%"> <tr style="font-weight: bold;"> <td>Naslov</td> <td>Uvod</td> <td>Dodano</td> </tr> < ?php foreach ($News as $Item) { ?> <tr> </tr> < ?php }} ?> </table> <div style="text-align: center;"> </div>
Evo, to je cela umetnost
Mislim da vsi štekate kaj sem nareidl v index.tpl ? I hope so
Naslednjič bomo o dodajanju in urejanju novic, zato zadevo le shranite da nebo treba še enkrat delat
Zadevo si lahko ogledate na http://www.linux-si.org/cakephp/news/
Uporabil:
PHP 5.2.3
MySQL 5
CakePHP cake_1.2.0.5427alpha
http://www.linux-si.org/cakephp/news/
P.S. Ne me jebat za kake morebitne slovnične napake
iNobl: 31% [?]
1 Jul
Ravno v neki zadevi ki jo delam sem imel primer kjer sem moral dobiti iz baze nek podatek združen iz dveh polj. Kako to storiti brez da bi uporabil svoj SQL stavek in pa CONCAT ipd. kar bi ga seveda lahko ampak zakaj bi če imamo za to funkcijo ki nam naredi z podatki kar želimo.
Funkcija afterFind() nam omogoči da z podatki ki jih dobimo iz baze naredimo kar hočemo, še predno podatki pridejo v view (template).
Recimo en primer. Rabim dobiti v select box (generateList() funkcija) podatek mesta in pa poštne številke kot value in kot key imam seveda id mesta….
class Citys extends AppModel { var $name = 'Citys'; function afterFind($results) { foreach ($results as $key =>; $val) { $results[$key]['Citys']['NameAndPostalCode'] = $val['Citys']['name'].' ('.$val['Citys']['postal_code'].')'; } return $results; } }
$this->set('Citys', $this->Citys->generateList( 'domain' => $this->Session->read('domain')), null, null, '{n}.Citys.city_id', '{n}.Citys.NameAndPostalCode' ) );
Zadeva je dokaj uporabna in pisanja svojega SQL stavka zato bi bilo nesmiselno. Zakaj ? Zato ker bi ga moral pisati na večih mestih in iz tega potem pride zmeda. Tukaj naredim to na enem mestu in imam povsod iste podatke.
Seveda v tej funkciji lahko naredimo poljubno z podatki…
Upam da pride kakšnemu peku prav
iNobl: 22% [?]
3 Mar
Kaj je CakePHP ? CakePHP je PHP framework ki uporablja MVC arhitekturo. MVC je Model Controller View. Kaj to pomeni. To pomeni da imamo strukturo strani ločeno po Model-ih View-ih in Controller-jih.
Kaj vse omogoča ta zadeva sem kar skopiral iz njihove strani …
/* * Model, View, Controller Architecture * View Helpers for AJAX, Javascript, HTML Forms and more * Built-in Validation * Application Scaffolding * Application and CRUD code generation via Bake * Access Control Lists * Data Sanitization * Security, Session, and Request Handling Components * Flexible View Caching * And More... */
Struktura CakePHP frameworka:
/app
../models -> Z modeli ločimo template od engina strani.
../controlers -> Kontrolerji nam pomagajo pri upravljanju neke sekcije na strani (blog, galerija,…)
../views -> Templati za stran, modele, itd.
../plugins -> Plugini so dodatki za CakePHP framework. Recimo naredite neko aplikacijo in jo potem date kot plugin. Plugin je ubistvu celoten site. Recimo Blog plugin ipd. Plugini imajo isto sturkturo kot tu ki jo sedaj opisujem. Primer: /app/plugins/ime_plugina/controllers …
../vendors -> Mapa kamor damo knjižnice ki niso od CakePHP frameworka. PEAR, PHPMailer,…
Za začetek naredite naslednje. V ‘app/config/routes.php’ zamenjajte vrstico:
< ?php class AppController extends Controller { var $ext = '.tpl'; var $layout = 'default'; } ?>
Z app_controller.php sistemu nastavimo default nastavitve.
$ext pomeni kakšne končnice bomo uporabljaji za template.
Z $layout spremenljivko povemo sistemu da naj uporablja default.tpl template za našo stran. To lahko spremenimo v vsakem kontrolerju z istim načinom kot tu. Tu zato definiramo da nam ni treba v vsakem kontrolerju to ponavljati.
Models
Modeli nam omogočajo da ločimo logiko (engine, ne najdem prave besede) strani od templatov. Z modeli recimo dostopamo do baze in delamo operacije na njej… Naj poudarim da cake kliče tabele v bazi v množini!! Recimo da imamo model Product v tem modelu bo cake sam od sebe klical tabelo v bazi ‘prefix_products’! ‘prefix_’ se seveda doda le v primeru če smo ga nastavili v configu. Seveda v samem modelu lahko tudi nastavimo kateri primary key se bo uporabil (po defaultu je to polje ‘id’) in katero tabelo naj cake vzame v primeru če naša tabela v bazi ni v množini.
Primer kako bi izgledal Model Product:
Model: app/models/product.php
Tabela: products
Polja: product_id (int:auto_increment), name (varchar:25), description(text), hidden(boolean)
< ?php /* app/models/product.php */ class Product extends AppModel { var $name = 'Product'; var $primaryKey = 'product_id'; // primary key } ?>
Controllers
Kontrolerji nam pomagajo da upravljamo neko sekcijo na strani. Naj nadaljujem kar z primerom Products. Imamo app/controllers/products_controller.php. Ko gremo na stran www.nasadomena.com/products/ se pokliče omenjeni kontroler in v njem index fukncija. V prve nam bo javilo napako ker še nismo naredili templata za index funkcijo. Naredi file ‘app/views/products/index.tpl’ in stem se znebimo omenjenega error-ja.
Primer:
< ?php /* app/controllers/products_controller.php */ class ProductsController extends AppController { function index() { $this->set('products', $this->Product->findAll('hidden=0', '*')); } } ?>
< ?php /* app/controllers/products_controller.php */ class ProductsController extends AppController { function index() { $this->set('products', $this->Product->findAll('hidden=0', '*')); } function view() { $this->set('product', $this->Product->find(array('hidden=0', 'product_id='.$this->params['url']['id']) , '*')); } } ?>
Kaj je $this->set() in pa $this->Product->findAll() ?
$this->set(): funkcija ki nam nastavi parametre za v template. Recimo $this->set(’test’, ‘Testni parameter’); bomo v templatu klicali kot $test.
$this->Product->findAll(): ->Product pomeni ime Modela ki ga kličemo. Uporabljamo namreč model Product! ->findAll() je predefinirana fukncija frameworka ki nam je na razpolago v vsakem Modelu ki ga naredimo. findAll() potegne podatke iz baze glede na podane parametre.
Tako kot modeli imajo tudi kontrolerji že pred definirane funkcije in spremenljivke. KLIK
Ko naredimo to funkcijo in gremo zopet na omenjeni naslov www.mojadomena.com/products/view/?id=1 nam bo javilo napako da template za view() funkcijo ne obatsaja. Naredimo ga. Naredite file ‘app/views/products/view.tpl’ in zadeva bo šla skozi.
V ‘app/views/products/index.tpl’ dodajmo naslednje:
<ul> < ?php foreach($products as $product): ?> <li><a href="view/?id=<?php echo $product['Product']['product_id'] ?>">< ?php echo $product['Product']['name'] ?></a></li> < ?php endforeach; ?> </ul>
Če view na koncu url naslova ni podam potem se po defaultu kliče funkcija index(). To lahko spremenimo in nastavimo na kaj drugega. V ‘app/config/’ direktoriju imate file routes.php in dodamo naslednjo vrstico:
V mojem primeru sem naredil v test() funkciji intreni forward na index() funkcijo:
function test() { $this->setAction('index'); }
$this->setAction() je funkcija ki naredi interni forward na eno od funkcij ki jih imamo v kontrolerju. Zelo uporabna zadeva!
Če ste opazili smo pozabili dodati IndexController. Dodajmo ga. Postpek je isti kot za ProductsController.
Naredimo file ‘app/controllers/index_controller.php’ in dodajmo naslednje v njega:
< ?php class IndexController extends AppController { function index() { $this->pageTitle = 'Naša prva stran'; } } ?>
function index() { $this->pageTitle .= '123'; }
Prva stran ki se kliče iz kontrolerja index_controller.php. Funkcija index()
< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <link href="favicon.ico" rel="shortcut icon" type="image/x-icon" /> <p style="border: 1px dotted silver; float: left; margin-right: 20px; width: 150px"> Menu </ul> </p><p style="border: 1px solid black; float: left"> < ?php echo $content_for_layout ?></p>
Ne pozabite da mora biti ‘app/tmp’ direktorij pisljiv za web server! celoten tmp/ direktorij in pod direktoriji!
Jaz sem uporabil CakePHP iz SVN-ja. 1.2Nightly build verzijo. Delal sem na PHP 5.2.1, MySQL 5.0.24a, Apache/2.0.55
V naslednjih dneh pričakujte nadaljvenja. In sicer, pisalo se bo o naslednjih funkcionalnostih.
- Zakaj uporabiti helperje
- Uporaba HTML helperja
- Uporaba Ajax helperja
- Uporaba scaffoldinga
- …
Seveda bomo z primeri nadgradili kar smo že začeli….
iNobl: 21% [?]
13 Apr
Pred nekaj dnevi sem našel na netu zlo hud framework ki se skriva pod imenom Qcodo. WTF je framework? (se najde kak debl
ki neve kaj je to).
Framework je sklop knjižni? ki nam pomagajo pri izdelavi aplikacije. Veliko hitreje naredimo neko aplikacijo kot pa ?e jo pišemo na suho. Npr. framework ima že knjižnice za komuniciranje z bazo, izdelava vnosnih form, ipd. ?e ni jasno potem KLIK
Qcodo nam zgenerira vse filete glede na strukturo baze. Bom pokazal (slike) in opisal kako se da z qcodo-m narediti simple zadevoco za vnos novi?k.
Za inštalacijo qcoda si preberite readme. Ni težko! Nastavi se samo poti in pa uname pa pass za bazo.
Gremo z browserjem na lokacijo kjer ima qcodo nastavljeno za PAGE_ROOT. V tej fazi se nam bo prikazala stran kjer nam bo napisalo da framework deluje in pa nekaj informacij in nastavitev ki jih ima qcodo. ?e qcodo nebo zadovoln z vsemi nastavitvami vam bo to zelo lepo povedal, namre? ima zelo zelo dober error reporting sistem. Pa gremo. Odprete phpMyAdmin ali pa MySQL Administrator al pa kej druzga ?e je pr rok (macolo?
). Se konektas na bazo kero bo uporablu qcodo. Nardiš tabelo news in v tabeli polja news_id, title, content. Ko narediš tabelo greš v browser in greš na link codegen ki ti ga je prej qcodo podal.
Po pravilih bi moglo vse delat. Qcodo je zgeneriral zadeve in gremo lahko nazaj in kliknemo na link form_drafts. Evo Novice nam delujejo. Klikneš na List all in dobiš prazno tabelo
Pod tabelo maš link create a new News. S klikom na link se nam prikaže forma za vnos. Jo nafilamo in kliknemo Sejv ;). Evo in prva novica je že dodana. Imamo paging in pa tudi sorting po vseh columnih. ?e želimo da naprimer polje title ali pa content nista obvezna samo v bazi na željenem polju nastavimo not_null na false in ?ao pepo ![]()
To naj bi bilo to v grobem. Za to zadevo sem porabil 5 min. Sicer je ?ista osnova pa vendar.
Ps: qcodo DOCUMENT_ROOT mora imet nujno privilegije za pisanje (chown -R www ime_direktorija) < --- odvisno od sistema! To velja samo za takrat ko delate na projektu in to nevelja za takrat ko je zadeva na produkcijski mašini!!!!!
{gallery}pictures/qcodo{/gallery}
?e bo zanimanje, drugi? napišem še kaj ve? o tem in pokažem kakšen malo bolj konkreten primer.
Link do Qcodo frameworka: Qcodo
lp
iNobl: 14% [?]