Group Office - vytváříme vlastní modul - část 2.
V předchozím díle jsme si rozebrali, jak vypadá základní struktura modulu v Group Office
. Dnešní díl popíše databázovou strukturu a práci s modely.
Základem návrhu celého modulu (a nejen jeho ale i jakéhokoli jiného projektu), by měla být databázová struktura. Sama o sobě Vám dá představu o tom, co samotný projekt bude dělat, do jakých se bude dělit částí apod.
U Group Office
má databázová struktura nemalou úlohu. Díky novému frameworku ve verzi 4 a PDO dochází k automatickému načítání sloupců v tabulkách, a tedy není nutné vytvářet proměnné popisující samotnou tabulku v rámci jednotlivých tříd a definice relací Vám příjemně zjednoduší práci. Vše si ukážeme na jednoduchých příkladech.
Group Office
v základu používá dva typy tříd, ze kterých modely dědí. V první řadě se jedná o třídu GO_Base_Db_ActiveRecord
, která je základním stavebním kamenem i třídy druhé GO_Base_Model_AbstractUserDefaultModel
.
Nejprve si projdeme třídu AbstractUserDefaultModel, která je používána pro skupiny, adresáře apod., jinými slovy pro takové takové modely, u kterých je definován sloupec user_id
a které mají být automaticky zakládány a mazány spolu se záznamem uživatele. Mezi zajímavé funkce patří getDefault, která je volána automaticky po uložení modelu s uživatelem. Funkci samozřejmě můžete overridovat a tím změnit její funkčnost.
AbstractUserDefaultModel a většina modelů obecně vychází ze třídy ActiveRecord. Tato třída přináší rozsáhlé možnosti mezi které patří například:
- definice primárního klíče
- název tabulky
- relace mezi tabulkami
- a další
Obecně se jedná o základní stavební kámen při komunikaci s databází.
Nyní přejdeme k praktické části, ve které budeme mít k dispozici:
- kategorii záznamu
- záznam
U kategorie počítáme s tím, že bude zakládána pro každého uživatele automaticky.
class GO_Example_Model_Category extends GO_Base_Model_AbstractUserDefaultModel
{
public static function model($className = __CLASS__)
{
return parent::model($className);
}
//u modelu budeme resit opravneni
public function aclField()
{
return 'acl_id';
}
//nazev tabulky
public function tableName()
{
return 'ex_categories';
}
//relace
public function relations()
{
return array(
'records' => array(
'type' => self::HAS_MANY,
'model' => 'GO_Example_Model_Record',
'field' => 'category_id',
'delete' => true
)
);
}
//validace a popis jednotlivych sloupcu
protected function init()
{
//nazev kategorie musi byt unikatni
$this->columns['name']['unique'] = true;
return parent::init();
}
}
Funkce relations vrací pole relací. Relace jsou pak definovány následujícími typy:
- BELONGS_TO - N:1
- HAS_MANY - 1:N
- HAS_ONE - 1:1
- MANY_MANY - M:N
Krom samotného typu relace se u relace mohou vyskytnout následující atributy:
- model - definuje vzdálený model relace
- field - zdrojový nebo cílový sloupec relace v závislosti na relaci. Druhým sloupcem pro relaci je pak primární klíč
- linkModel - pro relaci M:N
- delete = true pro relaci 1:N, čímž říkáme, že při smazání modelu dochází ke smazání i slinkovaných modelů - kaskádově
class GO_Example_Model_Record extends GO_Base_Db_ActiveRecord
{
public static function model($className = __CLASS__)
{
return parent::model($className);
}
protected function init()
{
//sloupec/pole category_id je povinne
$this->columns['category_id']['required'] = true;
return parent::init();
}
public function getLocalizedName()
{
//prelozeny nazev modelu - hledame string record v modulu example
return GO::t('record', 'example');
}
//nazev tabulky
public function tableName()
{
return 'ex_records';
}
//acl field v ramci relace
public function aclField()
{
return 'category.acl_id';
}
//relace
public function relations()
{
return array(
'category' => array(
'type' => self::BELONGS_TO,
'model' => 'GO_Example_Model_Category',
'field' => 'category_id'
)
);
}
}
Tím máme k dispozici dva jednoduché modely kategorie - záznam spolu s oprávněními pro jednotlivé uživatele/skupiny. Samotnou práci s modelem si probereme v rámci dalšího dílu s controllery. Mezi zajímavé funkce, které Vám pomohou vyřešit problémy při práci s modelem patří následující:
- afterSave($wasNew) - funkce volaná po uložení modelu do databáze
- defaultAttributes - v rámci této funkce jsou definovány výchozí hodnoty prázdého modelu
- beforeSave - funkce volaná těsně před uložením modelu
- beforeDelete - funkce volaná před uložením modelu - např pro ověření práv
- afterDbInsert - funkce volaná po zavolání SQL, které vkládá záznam do DB
- hasLinks - definuje zda jsou v rámci modelu povoleny GO linky
- hasFiles - definuje zda jsou použity soubory (je nutné definovat sloupec
files_folder_id
)
Databázová struktura musí existovat ještě před prací se samotnými modelu. Kvůli tomu je zde adresář install se skriptem install.sql, které obsahuje samotnou definice tabulky.