Initial Kohana install
[speedfreak] / Server / system / libraries / ORM_Versioned.php
1 <?php
2 /**
3  * Object Relational Mapping (ORM) "versioned" extension. Allows ORM objects to
4  * be revisioned instead of updated.
5  *
6  * $Id$
7  *
8  * @package    ORM
9  * @author     Kohana Team
10  * @copyright  (c) 2007-2008 Kohana Team
11  * @license    http://kohanaphp.com/license.html
12  */
13 class ORM_Versioned_Core extends ORM {
14
15         protected $last_version = NULL;
16
17         /**
18          * Overload ORM::save() to support versioned data
19          *
20          * @chainable
21          * @return  ORM
22          */
23         public function save()
24         {
25                 $this->last_version = 1 + ($this->last_version === NULL ? $this->object['version'] : $this->last_version);
26                 $this->__set('version', $this->last_version);
27
28                 parent::save();
29
30                 if ($this->saved)
31                 {
32                         $data = array();
33                         foreach ($this->object as $key => $value)
34                         {
35                                 if ($key === 'id')
36                                         continue;
37
38                                 $data[$key] = $value;
39                         }
40                         $data[$this->foreign_key()] = $this->id;
41
42                         $this->db->insert($this->table_name.'_versions', $data);
43                 }
44
45                 return $this;
46         }
47
48         /**
49          * Loads previous version from current object
50          *
51          * @chainable
52          * @return  ORM
53          */
54         public function previous()
55         {
56                 if ( ! $this->loaded)
57                         return $this;
58
59                 $this->last_version = ($this->last_version === NULL) ? $this->object['version'] : $this->last_version;
60                 $version = $this->last_version - 1;
61
62                 $query = $this->db
63                         ->where($this->foreign_key(), $this->object[$this->primary_key])
64                         ->where('version', $version)
65                         ->limit(1)
66                         ->get($this->table_name.'_versions');
67
68                 if ($query->count())
69                 {
70                         $this->load_values($query->result(FALSE)->current());
71                 }
72
73                 return $this;
74         }
75
76         /**
77          * Restores the object with data from stored version
78          *
79          * @param   integer  version number you want to restore
80          * @return  ORM
81          */
82         public function restore($version)
83         {
84                 if ( ! $this->loaded)
85                         return $this;
86
87                 $query = $this->db
88                         ->where($this->foreign_key(), $this->object[$this->primary_key])
89                         ->where('version', $version)
90                         ->limit(1)
91                         ->get($this->table_name.'_versions');
92
93                 if ($query->count())
94                 {
95                         $row = $query->result(FALSE)->current();
96
97                         foreach ($row as $key => $value)
98                         {
99                                 if ($key === $this->primary_key OR $key === $this->foreign_key())
100                                 {
101                                         // Do not overwrite the primary key
102                                         continue;
103                                 }
104
105                                 if ($key === 'version')
106                                 {
107                                         // Always use the current version
108                                         $value = $this->version;
109                                 }
110
111                                 $this->__set($key, $value);
112                         }
113
114                         $this->save();
115                 }
116
117                 return $this;
118         }
119
120         /**
121          * Overloads ORM::delete() to delete all versioned entries of current object
122          * and the object itself
123          *
124          * @param   integer  id of the object you want to delete
125          * @return  ORM
126          */
127         public function delete($id = NULL)
128         {
129                 if ($id === NULL)
130                 {
131                         // Use the current object id
132                         $id = $this->object[$this->primary_key];
133                 }
134
135                 if ($status = parent::delete($id))
136                 {
137                         $this->db->where($this->foreign_key(), $id)->delete($this->table_name.'_versions');
138                 }
139
140                 return $status;
141         }
142
143 }