Issue by romaninsh
Sunday Jun 08, 2014 at 13:52 GMT
Originally opened as atk4/atk4#551
Cloning Objects
When you use the PHP clone statement the whole object is duplicated
into an independent variable.
$book_archive = clone $book;
$book_archive->addCondition('is_archive',true);
$book->addCondition('is_archive',false);
$this->add('Grid')->setModel('book');
$this->add('Grid')->setModel('book_archive');
This code will display two grids - one for regular books and another for
archived. Because objects are cloned, adding conditions to one will not
affect the other.
But be careful – there's a gotcha when you clone hooks.
To continue the example above, say you have a hook inside Model_Book
to check a value before saving:
// In Model_Book
function init()
{
parent::init();
$this->addField('review');
$this->hasOne('Author');
$this->addHook('beforeSave', array($this,'check'));
}
function check($m)
{
if (strlen($this['review']) < 100) {
throw $this->exception('Review is too short');
}
}
After cloning, $this will be referencing the wrong object! Saving
our Model with $book_archive->save() will call $book->check(),
and $this will validate the value of $book instead of
$book_archive.
You can avoid this problem if you use the Model passed in as $m
instead of $this inside a hook. In the above example, $m will
point to $book_archive.