Skip to content

Commit

Permalink
ORM_Versioned and ORM_Tree added
Browse files Browse the repository at this point in the history
Signed-off-by: jheathco <jheathco@gmail.com>
  • Loading branch information
biakaveron authored and jheathco committed Jul 22, 2009
1 parent 16ee6e0 commit 19374d8
Show file tree
Hide file tree
Showing 2 changed files with 221 additions and 0 deletions.
76 changes: 76 additions & 0 deletions classes/orm/tree.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php defined('SYSPATH') OR die('No direct access allowed.');
/**
* Object Relational Mapping (ORM) "tree" extension. Allows ORM objects to act
* as trees, with parents and children.
*
* $Id: ORM_Tree.php 3769 2008-12-15 00:48:56Z zombor $
*
* @package ORM
* @author Kohana Team
* @copyright (c) 2007-2008 Kohana Team
* @license http://kohanaphp.com/license.html
*/
class ORM_Tree extends ORM {

// Name of the child
protected $children;

// Parent keyword name
protected $parent_key = 'parent_id';

/**
* Overload ORM::__get to support "parent" and "children" properties.
*
* @param string column name
* @return mixed
*/
public function __get($column)
{
if ($column === 'parent')
{
if (empty($this->related[$column]))
{
// Load child model
$model = ORM::factory(inflector::singular($this->children));

if (isset($this->object[$this->parent_key]))
{
// Find children of this parent
$model->where($model->primary_key, $this->object[$this->parent_key])->find();
}

$this->related[$column] = $model;
}

return $this->related[$column];
}
elseif ($column === 'children')
{
if (empty($this->related[$column]))
{
$model = ORM::factory(inflector::singular($this->children));

if ($this->children === $this->table_name)
{
// Load children within this table
$this->related[$column] = $model
->where($this->parent_key, $this->object[$this->primary_key])
->find_all();
}
else
{
// Find first selection of children
$this->related[$column] = $model
->where($this->foreign_key(), $this->object[$this->primary_key])
->where($this->parent_key, NULL)
->find_all();
}
}

return $this->related[$column];
}

return parent::__get($column);
}

} // End ORM Tree
145 changes: 145 additions & 0 deletions classes/orm/versioned.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<?php
/**
* Object Relational Mapping (ORM) "versioned" extension. Allows ORM objects to
* be revisioned instead of updated.
*
* $Id$
*
* @package ORM
* @author Kohana Team
* @copyright (c) 2007-2008 Kohana Team
* @license http://kohanaphp.com/license.html
*/
class ORM_Versioned extends ORM {

protected $last_version = NULL;

/**
* Overload ORM::save() to support versioned data
*
* @chainable
* @return ORM
*/
public function save()
{
$this->last_version = 1 + ($this->last_version === NULL ? $this->object['version'] : $this->last_version);
$this->__set('version', $this->last_version);

parent::save();

if ($this->saved)
{
$data = array();
foreach ($this->object as $key => $value)
{
if ($key === 'id')
continue;

$data[$key] = $value;
}
$data[$this->foreign_key()] = $this->id;

DB::insert($this->table_name.'_versions', $data)
->execute($this->db);
}

return $this;
}

/**
* Loads previous version from current object
*
* @chainable
* @return ORM
*/
public function previous()
{
if ( ! $this->loaded)
return $this;

$this->last_version = ($this->last_version === NULL) ? $this->object['version'] : $this->last_version;
$version = $this->last_version - 1;

$query = $this->db_builder
->where($this->foreign_key(), $this->object[$this->primary_key])
->where('version', $version)
->limit(1)
->get($this->table_name.'_versions');

if ($query->count())
{
$this->load_values($query->current());
}

return $this;
}

/**
* Restores the object with data from stored version
*
* @param integer version number you want to restore
* @return ORM
*/
public function restore($version)
{
if ( ! $this->loaded)
return $this;

$query = $this->db_builder
->where($this->foreign_key(), $this->object[$this->primary_key])
->where('version', $version)
->limit(1)
->get($this->table_name.'_versions');

if ($query->count())
{
$row = $query->current();

foreach ($row as $key => $value)
{
if ($key === $this->primary_key OR $key === $this->foreign_key())
{
// Do not overwrite the primary key
continue;
}

if ($key === 'version')
{
// Always use the current version
$value = $this->version;
}

$this->__set($key, $value);
}

$this->save();
}

return $this;
}

/**
* Overloads ORM::delete() to delete all versioned entries of current object
* and the object itself
*
* @param integer id of the object you want to delete
* @return ORM
*/
public function delete($id = NULL)
{
if ($id === NULL)
{
// Use the current object id
$id = $this->object[$this->primary_key];
}

if ($status = parent::delete($id))
{
DB::delete($this->table_name.'_versions')->where($this->foreign_key(), "=", $id)->execute();
//$this->db_builder->where($this->foreign_key(), $id)->delete($this->table_name.'_versions');
}

return $status;
}

}

0 comments on commit 19374d8

Please sign in to comment.