|
13 Březen 2010
Posted in
Dokumentace -
Komponenty
Controller
Začneme samozřejmě v ovladači nebo-li controlleru. Pro každou tabulku máme obvykle jeden ovladač, ve kterém definujeme, co se má provést při zadaných akcích(v URL tomu odpovídá parametr
task). Nic víc do ovladače nepatří. Hlavní práci totiž odvádí model. Dneska budeme v ovladači pracovat s výchozí metodou display(), která se používá právě pro vytvoření seznamu.defined('_JEXEC') or die('Restricted access'); jimport('joomla.application.component.controller'); class simpleForumControllersections extends JController { function __construct($config=array()) { parent::__construct($config); } function display() { JRequest::setVar('view','sections'); parent::display(); } }
Tento controller obsahuje dvě metody a to povinné volání konstruktoru a také metodu
display(). Jak vidíme, tak se moc neliší od výchozího controlleru popsaného v předchozím díle. Pouze u metody display() nastavujeme jenom pohled a rozvržení můžeme tentokrát vynechat, protože výchozí je právě seznam.Model
Hlavní práce nás ale čeká právě v modelu. Zde musíme zpracovat stránkování a řazení, případně filtrování jak si ukážeme později a hlavně předat data do pohledu Joomly. Zde se tedy vaří všechno podstatné. Hlavní práci za nás ale opět udělá framework Joomly.
defined('_JEXEC') or die('Restricted access'); jimport('joomla.application.component.model'); class simpleforumModelsections extends JModel { private $_limitstart=null; private $_limit=null; private $_orderBy=null; private $_orderDir=null; function __construct() { parent::__construct(); $app=JFactory::getApplication(); $option=JRequest::getCmd('option'); $this->_limitstart=$app->getUserStateFromRequest($option.'limitstart','limitstart',0,'int'); $this->_limit=$app->getUserStateFromRequest($option.'limit','limit',$app->getCfg('list_limit'),'int'); $this->_orderBy=$app->getUserStateFromRequest($option.'filter_order','filter_order','title','string'); $this->_orderDir=$app->getUserStateFromRequest($option.'filter_orderDir','filter_orderDir','','string'); } private function _setQuery() { $query="SELECT * FROM ".$this->getTable('section')->getTableName()." \n"; $query.="ORDER BY ".$this->_orderBy." ".$this->_orderDir." \n"; return $query; } function getData() { return $this->_getList($this->_setQuery(),$this->_limitstart,$this->_limit); } function getPagination() { jimport('joomla.html.pagination'); return new JPagination($this->_getListCount($this->_setQuery()),$this->_limitstart,$this->_limit); } function getLists() { $lists["limitstart"]=$this->_limitstart; $lists["limit"]=$this->_limit; $lists["orderBy"]=$this->_orderBy; $lists["orderDir"]=$this->_orderDir; return $lists; } }
Základem je opět konstrukror. Tentokrát ale bez jakýchkoliv parametrů. Nesmíme ale v něm zapomenout nejprve zavolat konstruktor předchozí základní třídy, jinak se můžeme dočkat nečekaných chyb. Dále si je nutné nadefinovat dvě pomocné proměnné a to $app - do které si uložíme hlavní třídu Joomly. a potom také $option - kde máme parametr option, z URL, tedy vlastně jméno naší komponenty. Toto jméno je důležité v následujících čtyřech metodách a umožňuje nám rozlišit v proměnných uložených v SESSION, ke které komponentě patří.
Jedná se o metody getUserStateFromRequest() jejichž prací je načtení dat z požadavků(GET,POST) a jejich uložení právě do SESSION, aby je měly k dispozici příště. Pokud se totiž v GET/POST nic nenajde, tak se data načtou ze SESSION. Tyto metody mají 4 parametry a jsou jími popořadě jméno proměnné v SESSION, jméno v GET/POST požadavku, výchozí hodnota a datový typ, kde použijeme int pro číslo a string pro řetězec.
Následně jelikož budeme SQL dotaz potřebovat ve dvou následnicích metodách si jej vytvoříme jako samostatnou metodu, kterou pojmenujeme třeba _setQuery(). V ní nás může zarazit pouze volání $this->getTable('section')->getTableName() což je pouze profesionálnější získání jména tabulky. Pokud nepředpokládáte, že byste někdy v budoucnosti potřebovali měnit název tabulky můžete použít i obyčejnější zápis s názvem naší tabulky #__sf_categories. Následně musíme získat data, která předáme k zobrazení. V tomto nám Joomla metodou _getList() ulehčí situaci, že se nemusíme zabývat předáváním stránkování do SQL dotazu. Stačí této metodě předat SQL dotaz a začátek limitu a počet záznamů na stránku, které nám vlastně Joomla předpřipravila a zjistili jsme je v konstruktoru.
Objekt stránkování, který využijeme pro zobrazení dolní lišty získáme stejně jednoduše. Třída pro stránkování ale není vkládána do modelu automaticky a tak se o to postaráme voláním jimportu a již nám níc nebrání vytvoření stránkování, mezi jehož parametry patří počet položek v tabulce, které zjistíme metodou JModelu _getListCount(té musíme samozřejmé také předat SQL dotaz) a pak také vymezení aktuální oblasti(proměnné limitstart a limit).
Poslední věcí, kterou musíme v modelu udělat je předání zjištěných hodnot stránkování a řazení zpět do pohledu.
Pohled
Pohled má dvě části. V první z nich získáváme data z modelu a druhá se stará o samotné zobrazení dat. Obě části jsou php soubory. Joomla tedy nepoužívá žádný šablonovací systém. Soubor pro získáváni dat umístíne do adresáře categories/ do souboru view.html.php v adresáři pohledů v administračním adresáři Joomly(/admin/view//categories/view.html.php):
defined('_JEXEC') or die('Restricted access'); jimport('joomla.application.component.view'); class simpleforumViewsections extends JView { function display($tpl=null) { $data=$this->get('data'); $this->assignRef('data',$data); $this->assignRef('pagination',$this->get('pagination')); $this->assignRef('lists',$this->get('lists')); $this->assignRef('user',JFactory::getUser()); JToolbarHelper::title(JText::_('Sections')); JToolbarHelper::addNewX('edit'); if(count($data)) { JToolbarHelper::editListX(); JToolbarHelper::deleteListX(); } parent::display($tpl); } }
Zde se jak vidíme všechno odehrává v jediné funkci - display(). Data přiřázujeme do pohledu pomocí metody assignRef mezi jejiž parametry patří jméno proměnné a pak samotná data. Ty z modelu získáme pomocí metody get(). Ta má v parametru jméno metody bez části get, takže název data odpovídá getData(), pagination zase getPagination(), atd. Mezi proměnné, které je nutné získat patří jak uvidíme dále také objekt uživatele, který využijeme ve druhé části pohledu ke zjištění, jestli není daná položka právě někým upravována. Závěr přípravy pohledu patří zobrazení panelu s ikonami
Nejprve se postaráme o zobrazení titulku, kde využívám překladového systému Joomly pomocí metody JText::_, ke které se dostaneme v našem seriálu o něco později. Dále zařizuji, aby se při kliknutí na tlačítko pro přidání nové kategorie spustila akce edit, což bych mohl řešit i pomocí mapování akcí v modelu, ale takto mi to přijde přehlednější. Na závěr ještě skryji tlačítka pro editaci a mazání v případě, že ještě nemáme k dipozici žádné položky k editaci a zavolám metody předka k vyvolání šablony.
Šablonu nalezneme v podadresáři tmpl se jménem default.php, nebo-li rozvrzeni.php.
<form action="index.php" method="post" name="adminForm" id="adminForm">
<div id="editcell">
<table class="adminlist">
<thead>
<tr>
<th width="5">
<?php echo JText::_('NUM'); ?>
</th>
<th width="5">
<input class="inputbox" type="checkbox" name="toggle" value="0" onclick="checkAll('<?php echo count($this->data); ?>')" />
</th>
<th>
<?php echo JText::_('Title'); ?>
</th>
</thead>
<tbody>
<?php
$k=0;
for($i=0;$i<count($this->data);$i++) {
$row=$this->data[$i];
$link='index.php?option=com_simpleforum&controller=sections&task=edit&layout=form&cid[]='.$row->id;
?>
<tr class="row<?php echo $k; ?>">
<td><?php echo $this->pagination->getRowOffset($i); ?></td>
<td><?php echo JHTML::_('grid.checkedout',$row,$i); ?></td>
<td><?php if(JTable::isCheckedOut($this->user->get('id'),$row->checked_out)) {
echo $row->title;
} else {
?>
<a href="/<?php echo $link; ?>"><?php echo $row->title; ?></a>
<?php
}
?></td>
</tr>
<?php
$k=1-$k;
}
?>
</tbody>
<tfoot>
<tr>
<td colspan="3">
<?php echo $this->pagination->getListFooter(); ?>
</td>
</tfoot>
</table>
</div>
<input type="hidden" name="option" value="com_simpleforum" />
<input type="hidden" name="controller" value="sections" />
<input type="hidden" name="task" value="" />
<input type="hidden" name="hidemainmenu" value="0" />
<input type="hidden" name="boxchecked" value="0" />
</form>
V záhlaví tabulky řešíme pouze zatržení všech položek po kliknutí na checkbox v záhlaví pomocí js funkce checkAll(). Pro začátek si musíme vyrobit vhodný odkaz pro editaci a zde přijde ke slovu druhý tvar URL, který se používá právě v administraci. Tato URL má tvar:
index.php?option=com_componenta&controller=ovladac[&task=akce[&layout=rozvrzeni[&cid[]=$id]]]
Pomocí hranatých závorek jsem naznačil nepovinné parametry. V případě neuvedení akce, se použije akce display. Jestliže neuvedeme rozvržení, tak se použije default a v případě cid[](id záznamu) bude hodnota 0. Pro editaci ale potřebujeme všechny parametry a tak je nastavíme.
Daleko zajímavější je samotný výpis dat. V prvním sloupci zobrazujeme pořadové číslo řádku. Pozor neplést si jej s ID záznamu v tabulce, jedná se o dvě naprosto odlišné věci. Druhý sloupec obsahuje zaškrtávátko, které využijeme ve spojení s panelem ikon. Tento checkbox zobrazíme pomocí methody JHTML::_, která přebírá tak trošku podivný první parametr. Metoda _ je vlastně jakýmsi obalečem všech pro práci s HTML kódem. I když to na první pohled vypadé složitě, jedná se vlastně o stejnou hříčku, jakou jsme poznali s metodou get v první části pohledu. Tedy, že se jedná vlastně o metodu checkedout třídy JHTMLGrid. Když si to shrneme dostaneme, že před tečkou je název třídy z API Joomly bez JHTML a za tečkou je metoda této třídy. Následují parametry dané metody. Mezi ně patří řádek tabulky a jeho aktuální pozice v tabulce, která se použije pro vygenerování příslušného parametru id tagu v checkboxu. O to, aby se u editovaného záznamu checkbox nezobrazil, se nemusíme starat, to za náš udělá Joomla samotná.
V případě titulku už tolik štěstí mít nebudeme a naprogramování jestli se mí zobrazit jako odkaz, nebo ne zůstává na náš. Naštěstí se nejedná o nic složitého. Pouze v ifu pomocí metody JTable::isCheckedOut() s parametry aktuálně přihlášeného uživatele a id uživatele editujícího daný článek(je uložené v poli checked_out) rozhodněme jestli je daná položka editována, nebo nikoliv. Mezi velké plus těchto vestavěných metod patří to, že otestujou také jestli je uživatel uvedený v checked_out přihlášený a daný záznam zamknout pouze v případě jeho přihlášení.
Trošku divné šoupání s proměnnou $k($k=1-$k) řeší pouze odlišení lichých a sudých řádků. Jednoduché, ale efektivní. V zápatí tabulky nám ještě zbývá vykreslit stránkování. S tím nám pomůže metoda getListFooter(). Pod tabulkou se ještě nachází několik skrytých údajů, které potřebujeme, jestliže formulář odesíláme metodou POST - klikneme-li na nějakou ikonku. První tři položky by nám již měly být jasné. Následující 2 položky poskytují místo k uložení interní informace Joomly o skrytí hlavního menu(hidemainmenu) a položka boxchecked slouží k uložení počtu zaškrtnutých checkboxů z prvního sloupce - potřebuje je javascript Joomly.
Příště
Tímto máme první pohled na naše data hotový. Ještě ale neumíme vložit žádná data, takže se nám nic nezobrazí a co je podstatnější nevíme jak vytvořit instalační balíček do Joomly, abychom mohli náš první větší kus kódu mohli vyzkoušet. Nebote se, na obojí se dostane hned v následujícím díle.
Články



Pekny clanek,
prvni sveho druhu, co doopravdy popisuje jednoduchou implementaci MVC v Joomle.
Jenom skoda ze dokumentace k Joomle je na takove spatne urovni.