Witam,
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.
*/
public static function include_component
($name, $action, array $params = array()) { $class = ucfirst($name).Component
::CLASS_SUFFIX;
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.
*/
public function __construct
($name, $action, array $params = array()) { $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) {
return isset($this->params[$param]) ?
$this->params[$param] : $default; }
/**
* 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
$this->view->set('time', time());
// 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<?php symfony
::include_component('user', 'test', array('userId' => 1)) ?>
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