korzystając z frameworka Kohana brakowało mi możliwości stosowania komponentów (często wykorzystywałem je przy pracy z Symfony). W związku z tym jakiś czas temu napisałem sobie rozszerzenie, które (moim zdaniem) nieźle spełnia funkcję komponentów w Kohana.
application/helpers/symfony.php
<?php /** * Helper zawierający metody rodem z Symfony ;) * * @package helpers */ class symfony { /** * Renderuje wskazany komponent. * * @param string $name Nazwa komponentu. * @param string $action Wywoływana akcja. * @param array $params Tablica przekazywanych parametrów. */ require_once(APPPATH.Component::COMPONENTS_DIRECTORY.'/'.$name.'.php'); $obj = new $class($name, $action, $params); $obj->$action(); } } ?>
application/libraries/Component.php
<?php /** * Klasa definiująca komponent. * * Komponent to "podwidok" posiadający własną logikę. * * @package libraries */ class Component { /** * Nazwa komponentu. * * @var string */ private $name; /** * Wywoływana akcja. * * @var string */ private $action; /** * Zbiór parametrów przekazywanych do komponentu. * * @var array */ private $params; /** * Obiekt widoku danego komponentu. * * @var View */ protected $view; /** * Tworzy nowy obiekt komponentu. * * @param string $name Nazwa komponentu. * @param string $action Wywoływana akcja. * @param array $params Tablica przekazywanych parametrów. */ $this->name = $name; $this->action = $action; $this->params = $params; $this->view = new View($name.'/'.$action.self::VIEWS_SUFFIX); } /** * Pobiera wartość parametru przekazanego do komponentu. * * W przypadku gdy wartość nie zostanie odnaleziona zwraca wartość domyślną ($default). * * @param string $param Nazwa parametru. * @param mixed $default Wartość domyślna. * @return mixed */ protected function getParam($param, $default = null) { } /** * Renderuje oraz zwraca szablon komponentu. * * @return string Szablon komponentu. */ public function render() { return $this->view->render(); } /** * Nazwa podkatalogu w katalogu application, w którym zlokalizowane będą klasy komponentów. */ const COMPONENTS_DIRECTORY = 'components'; /** * Suffix dołączany do nazwy komponentu w celu utworzenia nazwy klasy. * * Nazwa klasy komponentu składa się z jego nazwy rozpoczynającej się od wielkiej litery * oraz od poniższego suffixu [nazwa_komponentu][SUFFIX], np. * class Category_Component {} */ const CLASS_SUFFIX = '_Component'; /** * Suffix dla pliku widoku komponentu. * * Widoki należy umieszczać w folderze application/views jako [nazwa_komponentu]/[akcja][SUFFIX], * np. application/category/menu_component.php */ const VIEWS_SUFFIX = '_component'; } ?>
Aby dodać komponent do widoku (w moim przypadku jest to application/views/template.php) należy:
application/components/user.php
<?php class User_Component extends Component { public function test() { // przypisanie aktualnego czasu do widoku // utworzenie modelu użytkownika $mdlUser = new User_Model(); // pobranie danych z bazy na podstawie przekazanego parametru $user = $mdlUser->get($this->getParam('userId')); // przypisanie pobranych danych do widoku $this->view->set('user', $user); } } ?>
application/views/user/test_component.php
<p>Oto przykładowy komponent.</p> <p>Czas: <?= $time ?>.</p> <p>User: <?= $user['username'] ?></p>
application/views/template.php
Bardziej życiowy przykład zastosowania: wyświetlanie panelu użytkownika. Jeżeli użytkownik nie jest zalogowany to wyświetlany jest formularz logowania, natomiast jeśli jest już zalogowany to wyświetlane jest info powitalne i link do wylogowania.
application/components/user.php
<?php class User_Component extends Component { public function panel() { $session = Session::instance(); $isUserAuthenticated = $session->isUserAuthenticated(); $this->view->set('isUserAuthenticated', $isUserAuthenticated); if ($isUserAuthenticated === true) { $this->view->set('username', $session->getUserData('username')); $this->view->set('isActive', $session->getUserData('is_active')); } } } ?>
application/views/user/panel_component.php
<?php if ($isUserAuthenticated === true): ?> <p>Witaj <strong><?= html::anchor('user/profile', $username) ?></strong>! <?= html::anchor('authentication/logout', 'Wyloguj »') ?></p> <?php if ($isActive == 'f'): ?> <p><strong>Konto nieaktywowane!</strong></p> <?php endif; ?> <?php else: ?> <?= form::open('authentication/login') ?> <fieldset> <ul> <li> <label for="header_authentication_username">Nazwa użytkownika:</label> <?= form::input('authentication[username]', '', 'id="header_authentication_username"') ?> </li> <li> <label for="header_authentication_password">Hasło dostępu:</label> <?= form::password('authentication[password]', '', 'id="header_authentication_password"') ?> </li> <li> <input type="submit" value="Zaloguj" /> </li> </ul> </fieldset> <?= form::close() ?> <?php endif; ?>
Wczytanie komponentu w application/views/template.php:
<?php symfony::include_component('user', 'panel') ?>
Prosiłbym o opinie oraz ewentualne uwagi czy sugestie.
pion