MVC w praktyce z composer – tworzymy system artykułów. cz. 2
W drugiej części artykułu o wzorcu MVC stworzymy część aplikacji, odpowiedzialną za obsługę kategorii.
Tworzymy kontroler kategorii
src/Controller/Category.php
<?php namespace RacyMind\MVCWPraktyce\Controller; /** * Kontroler do kategorii. * @package RacyMind\MVCWPraktyce\Controller * @author Łukasz Socha <kontakt@lukasz-socha.pl> * @version 1.0 * @license http://www.gnu.org/copyleft/lesser.html */ class Category extends \RacyMind\MVCWPraktyce\Engine\Controller { /** * Wyświetla listę kategorii */ public function index() { $model = new \RacyMind\MVCWPraktyce\Model\Category(); $categories = $model->getAll(); $view = new \RacyMind\MVCWPraktyce\View\Category(); $view->categories = $categories; $view->renderHTML('index', 'front/category/'); } /** * Wyświetla formularz i dodaje kategorię */ public function add() { $model = new \RacyMind\MVCWPraktyce\Model\Category(); if (!empty($_POST)) { $model->insert($_POST); $this->redirect($this->generateUrl('category/index')); } else { $view = new \RacyMind\MVCWPraktyce\View\Category(); $view->renderHTML('add', 'front/category/'); } } /** * Usuwa kategorię */ public function delete() { $model = new \RacyMind\MVCWPraktyce\Model\Category(); $model->delete($_GET['id']);; $this->redirect($this->generateUrl('category/index')); } }
Kontroler kategorii posiada 3 akcje:
- index() – metoda ta pobiera z modelu wszystkie kategorie i przekazuje je do widoku. Na koniec ładuje szablon HTML
- add() – metoda wyświetla szablon z formularzem dodawania kategorii oraz przekazuje dane z tablicy $_POST do modelu.
- delete() – wywołuje metodę modelu usuwającą kategorię z bazy danych. Następnie przekierowuje użytkownika na listę kategorii.
W jaki sposób wywołać odpowiednie akcje kontrolera?
W mojej przykładowej aplikacji odpowiedzialny jest za to router. W pliku config-router.php znajduje się taki fragment kodu:
$collection->add('category/delete', new \RacyMind\MVCWPraktyce\Engine\Router\Route( HTTP_SERVER.'kategorie/usun/<id>?', array( 'file' => DIR_CONTROLLER.'Category.php', 'method' => 'delete', 'class' => '\RacyMind\MVCWPraktyce\Controller\Category' ), array( 'id' => '\d+' ), array( 'id' => 0 ) )); $collection->add('category/add', new \RacyMind\MVCWPraktyce\Engine\Router\Route( HTTP_SERVER.'kategorie/dodaj', array( 'file' => DIR_CONTROLLER.'Category.php', 'method' => 'add', 'class' => '\RacyMind\MVCWPraktyce\Controller\Category' ) )); $collection->add('category/index', new \RacyMind\MVCWPraktyce\Engine\Router\Route( HTTP_SERVER.'kategorie', array( 'file' => DIR_CONTROLLER.'Category.php', 'method' => 'index', 'class' => '\RacyMind\MVCWPraktyce\Controller\Category' ) ));
Router porównuje adres URL strony z powyższymi regułami. Jeżeli jakaś reguła pasuje do adresu URL wywołuje metodę odpowiedniego kontrolera. Uwaga. Jeżeli skrypt znajdzie pasującą regułę nie sprawdza już kolejnych, a więc najbardziej ogólne reguły adresu URL powinny być na końcu.
Tworzymy model kategorii
Model jest najbardziej istotnym elementem we wzorcu MVC – to on jest odpowiedzialny za logikę aplikacji. Ma za zadanie pobieranie/edycję danych z bazy danych (lub innych źródeł) oraz przetworzenie ich według wymagań skryptu, np: poddać filtracji, wykonać obliczenia itp.
Model kategorii będzie w pliku src/Model/Category.php.
<?php namespace RacyMind\MVCWPraktyce\Model; /** * Model kategorii. * @package RacyMind\MVCWPraktyce\Model * @author Łukasz Socha <kontakt@lukasz-socha.pl> * @version 1.0 * @license http://www.gnu.org/copyleft/lesser.html */ class Category extends \RacyMind\MVCWPraktyce\Engine\Model { /** * Zwraca z bazy danych wszystkie kategorie * @return array|null Tablica z kategoriami */ public function getAll() { $query = $this->pdo->query("SELECT * from categories"); $items = $query->fetchAll(\PDO::FETCH_ASSOC); if (isset($items)) { return $items; } else { return null; } } /** * Dodaje kategorię do bazy * @param $data Dane do zapisu */ public function insert($data) { $ins = $this->pdo->prepare('INSERT INTO categories (name) VALUES (:name)'); $ins->bindValue(':name', $data['name'], \PDO::PARAM_STR); $ins->execute(); } /** * Usuwa kategorię z bazy * @param int $id ID kategorii */ public function delete($id) { $del = $this->pdo->prepare('DELETE FROM categories where id=:id'); $del->bindValue(':id', $id, \PDO::PARAM_INT); $del->execute(); } }
Model ten posiada 3 metody:
- getAll() – pobiera wszystkie rekordy z tabeli categories
- insert() – dodaje nową kategorię do bazy
- delete() – usuwa kategorię o podanym ID z bazy danych
Tworzymy widok kategorii
src/View/Category.php
<?php namespace RacyMind\MVCWPraktyce\View; /** * Widok dla kategorii. * @package RacyMind\MVCWPraktyce\View * @author Łukasz Socha <kontakt@lukasz-socha.pl> * @version 1.0 * @license http://www.gnu.org/copyleft/lesser.html */ class Category extends \RacyMind\MVCWPraktyce\Engine\View{ public function __construct() { } }
Widok ten dziedziczy tylko metody po klasie View. W bardziej zaawansowanych aplikacjach konstrukcja taka umożliwia dopisywanie dodatkowych metod dla poszczególnych modułów.
Tworzymy szablony HTML dla kategorii
Na koniec stworzymy jeszcze dwa szablony HTML.
src/template/front/category/index.html.php
<?php $this->getHeader(); ?> <h1>Lista kategorii</h1> <table> <tbody> <tr> <td>Nazwa</td> <td></td> </tr> <?php foreach($this->categories as $item): ?> <tr> <td><?php echo $item['name']; ?></td> <td><a href="<?php echo $this->generateUrl('category/delete', array('id' => $item['id'])); ?>">usuń</a></td> </tr> <?php endforeach; ?> </tbody> </table> <?php $this->getFooter(); ?>
src/template/front/category/add.html.php
<?php $this->getHeader(); ?> <h1>Dodaj kategorię</h1> <form action="" method="post"> Nazwa kategorii: <input type="text" name="name" /><br /> <input type="submit" value="Dodaj" /> </form> <?php $this->getFooter(); ?>
Oba te szablony korzystają z pól i metod klasy \View\Category.
W ostatniej części cyklu zajmiemy się artykułami :).
Przejdź do trzeciej części cyklu MVC w praktyce z composer