Orm
Orm is short for Object
Relational Mapper which does 2 things: it maps your database table rows to objects and it allows you
to esteblish relations between those objects.
It follows closely the
Active Record Pattern, but was also influenced by other systems.
Observers
An event based system to allow you to add behavior to specific events. When an event is observed the Orm will automaticly call all the added observers to see if there's anything for them to do.
Adding observers to your model
You can add observers in 2 ways: just add the name to have the observer called for all events or with
the observer as name and an array of specific events for which the observer is called.
When the Observer is in the same namespace as the Model and prefixed with Observer_ you can
leave out the "Observer_" prefix. In all other cases you have to provide the full classname.
class Model_Article {
protected static $_observers = array(
'example', // will call Observer_Example class for all events
'Orm\\Observer_CreatedOn' => array('before_insert'), // will only call Orm\Observer_CreatedOn at before_insert event
);
}
Included observers
Observer_CreatedAt
This observer acts only upon before_insert and expects your model to have a created_at property which will be set to the Unix timestamp when saving for the first time.
// Just add the Observer
protected static $_observers = array('Orm\\Observer_CreatedAt');
// But adding it just for before_insert is enough
protected static $_observers = array('Orm\\Observer_CreatedAt' => array('before_insert'));
You can change the default property expected and use a mySQL timestamp instead of the defaults:
// Use mySQL timestamp instead of Unix timestamp
Orm\Observer_CreatedAt::$mysql_timestamp = true;
// Use property called just "updated" instead of "updated_at"
Orm\Observer_CreatedAt::$property = 'updated';
Observer_UpdatedAt
This observer acts only upon before_save and expects your model to have a updated_at property which will be set to the Unix timestamp when saving (also during the first time).
// Just add the Observer
protected static $_observers = array('Orm\\Observer_UpdatedAt');
// But adding it just for before_insert is enough
protected static $_observers = array('Orm\\Observer_UpdatedAt' => array('before_save'));
You can change a $mysql_timestamp and $property value on this observer just like on the CreatedAt observer.
Observer_Validation
To be written.
// Just add the Observer
protected static $_observers = array('Orm\\Observer_Validation');
// But adding it just for before_insert is enough
protected static $_observers = array('Orm\\Observer_Validation' => array('before_save'));
Observer_Typing
To be written.
// Just add the Observer
protected static $_observers = array('Orm\\Observer_Typing');
// But adding it just for these specific events is enough
protected static $_observers = array('Orm\\Observer_Typing' => array('before_save', 'after_save', 'after_load'));
Creating your own Observers
You can add any class as an observer by adding the full classname (namespace included) to the Observers property of your model. There's 2 ways of creating classes that can be used as observers:
Extend the Orm\Observer class
Create a new class that extends Orm\Observer and create methods for the events upon which you want your Observer to act. In the example below you want it to act upon after_insert. The method will be passed the Model instance it is acting upon.
class Observer_Something extends Orm\Observer {
public function after_insert(Model $model)
{
\Log::info('Succesfully created new object of class '.get_class($model));
}
}
Extensions of the type Orm\Observer are singletons by default, as such you can't use a method instance() or property $_instance or it won't work anymore. Because of this methods may be both static or non-static.
Have an orm_notify() method
When you extend the Orm\Observer class it inherits an orm_notify() method that will check if there's a method that matches the event and call it when possible. But you can use any class as an observer as long as it has an orm_notify() method. That will be called on events and be passed the event name and a Model instance.
class Some_Other_Class {
// it may have many methods and properties before or after the orm_notify method
public static function orm_notify(Model $model, $event)
{
\Log::info('I was notified of the event '.$event.' on a Model of class '.get_class($model));
}
}
Event names
- after_create, called by the __construct() method once the object was created
- after_load, called by the __construct() method once an object was loaded from the database
- before_save, called by the save() method before anything is done
- after_save, called by the save() method after it has completed
- before_insert, called when an object is first saved to the database
- after_insert, called after an object is first saved to the database
- before_update, called when an object is saved to the database (except for the first time)
- after_update, called after an object is saved to the database (except for the first time)
- before_delete, called when you delete an object from the database
- after_delete, called after you delete an object from the database
- after_clone, called after an object was succesfully cloned