CakePHP project építés 3. rész

cakephpMiután a modeleket elkészítettük a bake scripttel és pár alapadatot felvittünk a scaffold segítségével itt lesz az ideje, hogy kicsit finomítsunk az alkalmazásunkon. Aki azt gondolja, hogy na jó akkor most már jön a sok-sok gépelés és kódolás, az egyenlőre téved, a CakePHP még tartogat pár kellemes meglepetést a számunkra.

Csináljunk már valamit a nyitóoldallal

Nyitóoldalunk sajnos még mindig az alap Cake üdvözlőképernyőt adja, de ideje lenne változtatni rajta.
nyitólap
Erre két lehetőségünk is van. Az egyik ahogyan a nyitólapon olvashatjuk is, az /app/views/pages/home.thtml és a /app/views/layouts/default.thtml lapok módosítása. A másik pedig az, hogy nyitólapként egy létező, az előbbiekben generált oldalt használunk. Az első változat inkább statikus jellegű nyitóoldalaknál felel meg, míg a második inkább a dinamikus jellegű nyitóoldalakt fogja inkább kiszolgálni. Jelen pillanatban nekünk még egyik sincs, de mondjuk azt, hogy a termékek oldalt akarjuk nyitóként megjeleníteni.

Ehhez annyit kell csupán tennünk, hogy /app/config/routes.php-ban a $Route->connect('/', array('controller' => 'pages', 'action' => 'display', 'home')); sort kicseréljük erre:


$Route->connect('/', array('controller' => 'termekek', 'action' => 'index'));

Itt tulajdonképpen azt csináljuk, hogy a / elérési úthoz hozzákötjük a “termekek” nevű controller “index” függvényét. Ha az action részben két értéket adunk át, akkor a második érték a függvény paramétereként lesz átadva.

Termék controller második nekifutás

Fogjuk rá, hogy a termékcsoportokat annyira ritkán változtatjuk, hogy nem vagyunk hajlandóak a controllert a scaffoldon túlléptetni. A termékekkel azonban más a helyzet, ezeknek jó lenne valami elegánsabb formát adni.
Újra a bake scripthez fordulunk, (illetve a bake_hu scripthez), de előtte szükség lesz a /app/config/inflections.php file módosítására. Mivel a bake script a controllerek gyártásánál az angol nyelvtan szerint többesszámot fog képezni a modellünk nevéből ezt elkerülendő meg kell mondanunk neki, hogy hogyan csinálja. Ezt kivételek hozzáadásával tudjuk megadni. A $irregularPlural tömb elemeinek első eleme az egyes számú mintát, a második elem pedig a többesszámú mintát mutatja. $irregularPlural = array('termek' => 'termekek');, de éppen ilyet is adhattunk volna neki: $irregularPlural = array('termek' => 'termekek', 'jozsibacsi' => 'jozsibacsik');

rrd:~/Sites/tulasi/cake/scripts rrd$ php bake_hu.php 

 ___  __  _  _  ___  __  _  _  __      __   __  _  _  ___ 
|    |__| |_/  |__  |__] |__| |__]    |__] |__| |_/  |__ 
|___ |  | | \_ |___ |    |  | |       |__] |  | | \_ |___ 
---------------------------------------------------------------


Bake -app in /Users/rrd/Sites/tulasi/app (y/n) 
[y] > n

Nem az az alkalmazás elérési útja, mint amit felkínál, így nemet választunk.

What is the full path for this app including the app directory name?
Example: /Users/rrd/Sites/tulasi/myapp  
[/Users/rrd/Sites/tulasi/myapp] > /Users/rrd/Sites/tulasi/

Bake -app in /Users/rrd/Sites/tulasi/ (y/n) 
[y] > 

Megadjuk neki a tényleges elérési utat, és az új kérdésre így már igent válaszolhatunk.

Baking...
---------------------------------------------------------------
Name: app
Path: /Users/rrd/Sites/tulasi/app
---------------------------------------------------------------
[M]odel
[C]ontroller
[V]iew

What would you like to Bake? (M/V/C) 
> c

A termék controllert akarjuk létrehozni.

---------------------------------------------------------------
Controller Bake:
---------------------------------------------------------------
Possible Controllers based on your current database:
1. Termekek
2. Termekcsoportok
3. Users

Enter a number from the list above, or type in the name of another controller.  
> 1

Would you like bake to build your controller interactively?
Warning: Choosing no will overwrite  controller if it exist. (y/n) 
[y] > 

Interaktívan,…

Would you like to use scaffolding? (y/n) 
[y] > n

..de nem scaffoldal.

Would you like to include some basic class methods (index(), hozzaad(), mutat(), szerkeszt())? (y/n) 
[n] > y

Noná, hogy akarjuk, pont ezért csináljuk az egészet 🙂 ééééés a kérdésben magyar (lokalizált) függvénynevek vannak, reméljük tényleg azokat kapjuk majd.

Would you like to create the methods for admin routing? (y/n) 
[n] > n

Ez most nem kell nekünk.

Would you like this controller to use other models besides 'Termek'? (y/n) 
[n] > 

Most ez sem kell.

Would you like this controller to use other helpers besides HtmlHelper and FormHelper? (y/n) 
[n] > 

Nem, ez a két helper elég lesz. (A helperek fejlesztés közben segítenek helyes, valid és rövid kódok gyártásában.)

Would you like this controller to use any components? (y/n) 
[n] > 

Egyenlőre nem.

Would you like to use Sessions? (y/n) 
[y] > 

Igen, ez jól fog jönni, mert mindjárt szereténk némi biztonságot is beépíteni.

---------------------------------------------------------------
The following controller will be created:
---------------------------------------------------------------
Controller Name:        Termekek
---------------------------------------------------------------

Look okay? (y/n) 
[y] > 

Igen, jól néz ki, rajta!

Creating file /Users/rrd/Sites/tulasi/app/controllers/termekek_controller.php
Wrote/Users/rrd/Sites/tulasi/app/controllers/termekek_controller.php

Ezt a filet rögtön meg is nyitjuk, had lássuk mit alkotott a Cake.

Cake test suite not installed.  Do you want to bake unit test files anyway? (y/n) 
[y] > n
rrd:~/Sites/tulasi/cake/scripts rrd$ 

A bake script lefutott és megcsinált mindent amit akartunk.

Ha most megnyitjuk az előbb létrehozott controller filet app/controllers/termekek_controller.php, akkor szerencsés esetben valami ilyesmit kellene látnunk (aki nem a bake_hu-t hanem a bake-et használta az egy kicsit mást kap, ne lepődjön meg rajta.):

<?php
class TermekekController extends AppController {

	var $name = 'Termekek';
	var $helpers = array('Html', 'Form' );

	function index() {
		$this->Termek->recursive = 0;
		$this->set('termekek', $this->Termek->findAll());
	}

	function mutat($id = null) {
		if(!$id) {
			$this->Session->setFlash('Invalid id for Termek.');
			$this->redirect('/termekek/index');
		}
		$this->set('termek', $this->Termek->read(null, $id));
	}

	function hozzaad() {
		if(empty($this->data)) {
			$this->set('termekcsoportok', $this->Termek->Termekcsoport->generateList());
			$this->render();
		} else {
			$this->cleanUpFields();
			if($this->Termek->save($this->data)) {
				$this->Session->setFlash('The Termek has been saved');
				$this->redirect('/termekek/index');
			} else {
				$this->Session->setFlash('Please correct errors below.');
				$this->set('termekcsoportok', $this->Termek->Termekcsoport->generateList());
			}
		}
	}

	function szerkeszt($id = null) {
		if(empty($this->data)) {
			if(!$id) {
				$this->Session->setFlash('Invalid id for Termek');
				$this->redirect('/termekek/index');
			}
			$this->data = $this->Termek->read(null, $id);
			$this->set('termekcsoportok', $this->Termek->Termekcsoport->generateList());
		} else {
			$this->cleanUpFields();
			if($this->Termek->save($this->data)) {
				$this->Session->setFlash('The Termek has been saved');
				$this->redirect('/termekek/index');
			} else {
				$this->Session->setFlash('Please correct errors below.');
				$this->set('termekcsoportok', $this->Termek->Termekcsoport->generateList());
			}
		}
	}

	function torol($id = null) {
		if(!$id) {
			$this->Session->setFlash('Invalid id for Termek');
			$this->redirect('/termekek/index');
		}
		if($this->Termek->del($id)) {
			$this->Session->setFlash('The Termek deleted: id '.$id.'');
			$this->redirect('/termekek/index');
		}
  }

}
?>

Ezzel a Cake pontosan 68 sornyi gépeléstől mentett meg bennünket. Megjegyzem, hogy a magyarság pártiaknak még lesz egy pici csiszolnivalójuk a fileon, de előbb lássuk a következő lépést.

Termékek – view

Ok, a modellen nem változtattunk, a controllert most generáltuk le újra, akkor még a view-k hiányoznak, ugye?

rrd:~/Sites/tulasi/cake/scripts rrd$ php bake_hu.php 

 ___  __  _  _  ___  __  _  _  __      __   __  _  _  ___ 
|    |__| |_/  |__  |__] |__| |__]    |__] |__| |_/  |__ 
|___ |  | | \_ |___ |    |  | |       |__] |  | | \_ |___ 
---------------------------------------------------------------


Bake -app in /Users/rrd/Sites/tulasi/app (y/n) 
[y] > n

What is the full path for this app including the app directory name?
Example: /Users/rrd/Sites/tulasi/myapp  
[/Users/rrd/Sites/tulasi/myapp] > /Users/rrd/Sites/tulasi/

Bake -app in /Users/rrd/Sites/tulasi/ (y/n) 
[y] > 


Baking...
---------------------------------------------------------------
Name: app
Path: /Users/rrd/Sites/tulasi/app
---------------------------------------------------------------
[M]odel
[C]ontroller
[V]iew

What would you like to Bake? (M/V/C) 
> v

Ezuttal “V”-t választunk, mert view-t sütünk.

---------------------------------------------------------------
Mutat Bake:
---------------------------------------------------------------
Possible Controllers based on your current database:
1. Termekek
2. Termekcsoportok
3. Users

Enter a number from the list above, or type in the name of another controller.  
> 1

A termékek view-ját.

Would you like bake to build your views interactively?
Warning: Choosing no will overwrite  views if it exist. (y/n) 
[y] > 

Interaktívan akarjuk. Egyébként ha itt nemet választunk akkor minden kérdésre az alaéprtelmezett választ adja a script.

Would you like to create some scaffolded views (index, hozzaad, mutat, edit) for this controller?
NOTE: Before doing so, you'll need to create your controller and model classes (including associated models). (y/n) 
[n] > y

Igen, persze, ezért csináljuk az egészet. És igen! itt is magyarul (lokalizálva) lesz minden ugye?

Would you like to create the views for admin routing? (y/n) 
[n] > 

Ezt már a controllerben sem kértük, itt sem lesz rá szükség.

Creating file /Users/rrd/Sites/tulasi/app/views/termekek/index.thtml
Wrote/Users/rrd/Sites/tulasi/app/views/termekek/index.thtml

Creating file /Users/rrd/Sites/tulasi/app/views/termekek/mutat.thtml
Wrote/Users/rrd/Sites/tulasi/app/views/termekek/mutat.thtml

Creating file /Users/rrd/Sites/tulasi/app/views/termekek/hozzaad.thtml
Wrote/Users/rrd/Sites/tulasi/app/views/termekek/hozzaad.thtml

Creating file /Users/rrd/Sites/tulasi/app/views/termekek/szerkeszt.thtml
Wrote/Users/rrd/Sites/tulasi/app/views/termekek/szerkeszt.thtml

Létrejöttek a view fileok a megfeleő helyen.

---------------------------------------------------------------

Mutat Scaffolding Complete.

rrd:~/Sites/tulasi/cake/scripts rrd$ 

És a script sikerrel kilépett.

Ha most belenézünk a bake script által létrehozott thtml fileokba, akkor ilyesmiket látunk:

<div class="termekek">
<h2>List Termekeks</h2>

<table cellpadding="0" cellspacing="0">
<tr>
  <th>Id</th>
  <th>Termekcsoport</th>
  <th>Termeknev</th>
  <th>Kiskerar</th>
  <th>Leiras</th>
  <th>Kep</th>
  <th>Suly</th>
  <th>Hatas</th>
  <th>Actions</th>
</tr>
<?php foreach ($termekek as $termek): ?>
<tr>
  <td><?php echo $termek['Termek']['id']; ?></td>
  <td> <?php echo $html->link($termek['Termekcsoport']['id'], '/termekcsoportok/mutat/' .$termek['Termekcsoport']['id'])?></td>
  <td><?php echo $termek['Termek']['termeknev']; ?></td>
  <td><?php echo $termek['Termek']['kiskerar']; ?></td>
  <td><?php echo $termek['Termek']['leiras']; ?></td>
  <td><?php echo $termek['Termek']['kep']; ?></td>
  <td><?php echo $termek['Termek']['suly']; ?></td>
  <td><?php echo $termek['Termek']['hatas']; ?></td>
  <td class="actions">
    <?php echo $html->link('Mutat','/termekek/mutat/' . $termek['Termek']['id'])?>
    <?php echo $html->link('Szerkeszt','/termekek/szerkeszt/' . $termek['Termek']['id'])?>
    <?php echo $html->link('Torol','/termekek/torol/' . $termek['Termek']['id'], null, 'Are you sure you want to delete id ' . $termek['Termek']['id'])?>
  </td>
</tr>
<?php endforeach; ?>
</table>

<ul class="actions">
  <li><?php echo $html->link('Uj Termek', '/termekek/hozzaad'); ?></li>
</ul>
</div>

Ez újabb 163 sornyi kód megírásától és kigondolásától mentesített bennünket.

Még egy apró dolgunk maradt. Ha megnézzük a termekek_controller.php filet, akkor a bake beletett egy var $helpers = array('Html', 'Form' ); sort. Mivel mi minden controllerben használni fogjuk ezeket a helpereket ezért ezt a sort nyugodtan kitehetjük a /app/app_controller.php fileba, amit a project építés 1. részében hoztunk létre. Ezzel azt érjük el, hogy nem kell minden controllerbe külön betenni, mindenhol elérhetőek lesznek a helperek.

Ha most kipróbáljuk a böngészőnkkel, akkor minden eddigi URLünknek működnie kell és pontosan úgy kell kinéznie és működnie mint ahogy az a scaffold használatával működött. A scaffold tulajdonképpen ugyanezt csinálja (a lokalizáláson kívül) mint amit mi itt a bake script segítségével megcsináltunk. Akkor meg mi értelme volt az egésznek? Az, hogy most már bele tudunk piszkálni a kódba, tudjuk módosítani, javítani és rontani 🙂

Javítsunk a kódon

Ami leginkább csúnyán néz ki az az, hogy új termék felvitelénél ki tudjuk jelölni, hogy melyik termékcsoportba tartozik, de egy multiple selectet jelenít meg jelenleg az oldal, a termékcsoportok id-jével. Mivel nem számítógépek vagyunk hanem emberek, itt szeretnénk inkább a termékcsoportok neveit látni, illetve mivel egy termék csak egy termékcsoportba tartozhat nekünk elegendő lenne egy sima select is. A hogyanról a következő rész fog szólni.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöljük.