Obsah
Ormion
ORM pro Nette a dibi.
| Zdrojové kódy (github) | http://github.com/janmarek/Ormion |
| Autor | Jan Marek |
| Licence | MIT |
Ormion vyžaduje PHP 5.3 a aktuální vývojovou verzi dibi.
Instalace
Zkopírujte do adresáře libs složku Ormion.
Vytvořte složku %appDir%/models/config, do které
se budou ukládat konfigurační soubory. Před jejich prvním vygenerováním
v této složce musí být povolen zápis.
Připojení k databázi
Ormion\Ormion::connect(Nette\Environment::getConfig("database"));
Funkce Ormion::connect pouze zavolá funkci
dibi::connect. Jen nastavuje výchozí jméno připojení na
ormion. Jméno lze ovlivnit volitelným druhým parametrem.
Vytvoření modelu
Pro základní funkčnost modelu je potřeba jen nastavit jméno tabulky.
class Article extends Ormion\Record
{
protected static $table = "articles";
}
Alternativně lze název tabulky zadat pomocí anotace.
/**
* Article record
*
* @table articles
*/
class Article extends Ormion\Record
{
}
Model bude načítat údaje o databázi z cache (např. typy sloupců, jména klíčů, …). Typ tinyint(1) v databázi je považován za boolean.
Práce se záznamem
Vytvoření záznamu:
$article = new Article;
$article = Article::create();
// s přednastavenými daty
$article = Article::create(array(
"id" => 4,
"name" => "Nový článek",
"text" => "Text článku",
// ...
));
// s přednastaveným primárním klíčem
$article = Article::create(4);
Nastavování a čtení dat záznamu:
// nastavení hodnoty name
$article->name = "Název";
// lze použít ArrayAccess
$article["name"] = "Název";
// čtení
echo $article->name;
// hodnoty jsou automaticky přetypovány
$article->id = "4";
is_int($article->id); // true
// je hodnota nastavena?
isset($article->name);
// je hodnota nastavena nebo je alespoň null?
$article->hasValue("name");
// Čtení nenastavené hodnoty vyvolá výjimku.
// zrušení hodnoty
unset($article->name);
// Hromadný getter a setter lze najít pod metodami getValues, setValues.
Uložení záznamu – jestli je záznam vkládán nebo upravován
ovlivňuje stav nastavitelný pomocí metody setState, případně
přítomnost či nepřítomnost primárního klíče. V případě úpravy
záznamu jsou ukládány jen změněné hodnoty.
$article->save();
Smazání záznamu z databáze:
$article->delete();
Hodnoty záznamu lze procházet pomocí cyklu, takže je možné
nastavit záznam jako výchozí hodnoty
formuláře. $form->setDefaults($article);
Výběr dat
Výběr jednoho záznamu:
// vyhledání pomocí primárního klíče
$article = Article::find(123);
// vyhledání podle jiných hodnot
$article = Article::find(array(
"author" => 4,
"allowed" => true,
));
// nebo alternativně
$article = Article::findByAuthorAndAllowed(4, true);
// také lze využít lazy loadingu, kdy nenačtené hodnoty jsou v případě potřeby doplněny z databáze
$article = Article::create($id);
echo $article->name;
Výběr kolekce záznamů:
// získání všech záznamů
$articles = Article::findAll();
// vyhledání záznamů podle určitých hodnot
$articles = Article::findAll(array(
"author" => 4,
"allowed" => true,
));
// nebo alternativně
$articles = Article::findAllByAuthorAndAllowed(4, true);
Vyhledání více záznamů vrací objekt třídy OrmionCollection. Ten
zatím nemá data načtená (načte je až budou potřeba), protože umožňuje
s kolekcí dále pracovat podobně jako lze upravovat třídu
DibiFluent.
$articles = Article::findAll()->where("[author] = %i", 4)->orderBy("[date] DESC")->limit(10)->offset(0);
Získání počtu záznamů:
$count = count($articles);
Pokud záznamy již nejsou načteny, zavolá se dotaz typu select
count(*) from ....
Třída OrmionCollection také implementuje řadu
fetchovacích funkcí, jaké znáte z dibi.
$collection = Article::findAll();
$articles = $collection->fetchAll();
$limit = 10;
$offset = 0;
$firstTenArticles = $collection->fetchAll($limit, $offset);
$firstArticle = $collection->fetch();
$firstArticleName = $collection->fetchSingle("name");
$articleIds = $collection->fetchColumn("id");
$articleIdNameMap = $collection->fetchPairs("id", "name");
$articlesInGroupsByParent = $collection->fetchAssoc("parent,#");
Kolekce také podporují čtyři agregační funkce (min, max, avg a sum).
// nejvyšší počet návštěv u článku
$value = Article::findAll()->getMax("visits");
// průměrný počet návštěv u článku
$value = Article::findAll()->getAvg("visits");
// nejmenší počet návštěv u článku
$value = Article::findAll()->getMin("visits");
// součet počtů návštěv u článků
$value = Article::findAll()->getSum("visits");
Přizpůsobení OrmionRecordu
Přepsáním metody init lze upravit chování OrmionRecordu.
/**
* @table articles
*/
class Article extends Ormion\Record
{
protected function init()
{
// nastavení výchozích dat
$this->setDefaultValue("text", "Lorem Ipsum, Dorot Sir Ahmed");
// (lze nastavit pouze v této metodě,
// na pozdější nastavování nebude brán zřetel :)
// nastavení aliasů sloupců
$this->setAlias("content", "text");
// nastavení filtrů (callbacky, které berou vstup, upraví ho a vrátí)
$this->addOutputFilter("name", "Nette\String::lower");
// jméno bude při čtení převedeno na malá písmenka
// $this->addInputFilter("name", "Nette\String::lower");
// nastavení komplexních callbacků
$record = $this;
$this->registerGetter("url", function () use ($record) {
return $record->id . "-" . Nette\String::webalize($record->name);
});
// $this->registerSetter(..., ...);
// i pro tyto callbacky jsou zohledněny filtry a konvertování hodnot na správný typ
// nastavení událostí
$this->onBeforeDelete[] = array($this, "deleteComments");
// Existují ještě onAfterDelete, onBeforeInsert, onAfterInsert, onBeforeUpdate, onAfterUpdate
}
public function deleteComments()
{
foreach (Comments::findAllByParent($this->id) as $comment) {
$comment->delete();
}
}
}
Behaviors
Podrobné nastavování modelu lze vyčlenit do třídy implementující
rozhranní
IBehavior a poté používat opakovaně.
V distribuci již některé příklady jsou:
Timestampable při vytvoření nastaví aktuální čas na
sloupci (např.) created, při úpravě aktualizuje čas na sloupci (např.)
updated.
/**
* @table articles
*/
class Article extends Ormion\Record
{
protected function init()
{
$this->addBehavior(new Ormion\Behavior\Timestampable("created", "updated"));
}
}
Sortable udržuje sloupec (např.) order seřazený hezky
lineárně 1, 2, 3, 4, … i při mazání, změně pořadí, vkládání
nových záznamů a podobně. Lze rozkategorizovat podle další hodnoty (např.
parent).
/**
* @table articles
*/
class Article extends Ormion\Record
{
protected function init()
{
$this->addBehavior(new Ormion\Behavior\Sortable("order", "parent"));
}
}
$article1 = Article::create()->save();
$article2 = Article::create()->save();
$article3 = Article::create()->save();
$article4 = Article::create()->save();
echo $article1->order . " " . $article2->order . " " . $article3->order . " " . $article4->order;
// vypíše 1 2 3 4
$article4->order = 2;
$article4->save();
echo $article1->order . " " . $article2->order . " " . $article3->order . " " . $article4->order;
// vypíše 1 3 4 2
Texy umožňuje získávat pod hodnotou (např.)
htmlText cachovaný výstup hodnoty ze zdrojového sloupce (např.)
text.
/**
* @table articles
*/
class Article extends Ormion\Record
{
protected function init()
{
$this->addBehavior(new Ormion\Behavior\Texy("htmlText", "text", "MyTexyClass"));
}
}
Hashable dokáže zahashovat při vkládání hodnoty a při
změně hodnoty zvolený sloupec, např. password.
Komentáře 
jxp | 13. 8. 2010, 14:07 | comment
Je možné používat Ormion v Ne MVC aplikaci?
Honza Marek | 30. 8. 2010, 23:08 | comment
Nevidím důvod, proč by to nešlo.




dj.kure | 15. 7. 2010, 19:10 | bug
do závorek ve function se musí vložit proměnná $record;