PageRenderTime 23ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/system/classes/libraries/modeler.php

http://github.com/enormego/EightPHP
PHP | 284 lines | 197 code | 46 blank | 41 comment | 43 complexity | 6137588393ec14064141bc9201154f5f MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * Lightweight ORM Library build on-top of the Model library
  4. *
  5. * @package System
  6. * @subpackage Libraries
  7. * @author EightPHP Development Team
  8. * @copyright (c) 2009-2010 EightPHP
  9. * @license http://license.eightphp.com
  10. */
  11. class Modeler_Core extends Model {
  12. // Database table name
  13. protected $table_name = '';
  14. // Table primary key
  15. protected $primary_key = 'id';
  16. // Column prefix
  17. protected $column_prefix = NULL;
  18. // Table fields and default values
  19. protected $data = array();
  20. // The default database connection to use
  21. public $default_conn = 'default';
  22. // Tells you if the Model was loaded from the DB or not
  23. protected $loaded = FALSE;
  24. // Sets the active class, PHP workaround
  25. protected $active_class = NULL;
  26. // Holds the database connection
  27. public $db = NULL;
  28. // Tells the class we ran the "set" function
  29. public $ran_set = FALSE;
  30. // Run all queries on master db
  31. protected $use_master = FALSE;
  32. public function __construct($data = NULL, $active_class = NULL) {
  33. parent::__construct();
  34. // Bit of a work around to fix this annoying issue with PHP not inheriting correctly
  35. $this->active_class = $active_class;
  36. if($this->active_class == NULL OR empty($this->active_class)) {
  37. $obj = debug_backtrace();
  38. $obj = $obj[0]['object'];
  39. $this->active_class = get_class($obj);
  40. }
  41. $this->db = $this->db();
  42. if ($data != NULL) {
  43. if(!is_array($data)) {
  44. $data = array($this->primary_key => $data);
  45. }
  46. $this->db->use_master($this->use_master);
  47. $new_data = $this->db->getwhere($this->table_name, $data)->result(FALSE);
  48. if(is_object($new_data) && count($new_data) > 0) {
  49. if (count($new_data) == 1 AND $new_data = $new_data->current()) {
  50. $data = $new_data;
  51. $this->loaded = TRUE;
  52. }
  53. } else {
  54. $this->loaded = FALSE;
  55. }
  56. $this->set($data);
  57. } else {
  58. $this->loaded = FALSE;
  59. }
  60. }
  61. /**
  62. * Handles object serialization for class objects
  63. */
  64. public function __sleep() {
  65. // Return all class keys minus db, core and obj
  66. return array_keys(array_diff_key(get_object_vars($this), array('db' => NULL, 'core' => NULL, 'obj' => NULL)));
  67. }
  68. public function __wakeup() {
  69. $this->db = self::db();
  70. }
  71. public function valid() {
  72. if(isset($this->data[$this->primary_key]) && !str::e($this->data[$this->primary_key])) {
  73. $this->loaded = TRUE;
  74. return TRUE;
  75. }
  76. return $this->loaded;
  77. }
  78. public function __destruct() {
  79. return TRUE;
  80. }
  81. public function __get($key) {
  82. if(array_key_exists($key, $this->data)) {
  83. if(method_exists($this, $key)) {
  84. return $this->$key();
  85. } else {
  86. return $this->data[$key];
  87. }
  88. } elseif(array_key_exists($this->column_prefix.$key, $this->data)) {
  89. $key = $this->column_prefix.$key;
  90. if(method_exists($this, $key)) {
  91. return $this->$key();
  92. } else {
  93. return $this->data[$key];
  94. }
  95. } else {
  96. if(method_exists($this, $key)) {
  97. return $this->$key();
  98. } else {
  99. return $this->$key;
  100. }
  101. }
  102. }
  103. public function __set($key, $value) {
  104. if(array_key_exists($key, $this->data)) {
  105. if(method_exists($this, "set_".$key)) {
  106. $this->{"set_".$key}($value);
  107. } else {
  108. $this->data[$key] = $value;
  109. }
  110. } elseif(array_key_exists($this->column_prefix.$key, $this->data)) {
  111. if(method_exists($this, "set_".$this->column_prefix.$key)) {
  112. $this->{"set_".$this->column_prefix.$key}($value);
  113. } else {
  114. $this->data[$this->column_prefix.$key] = $value;
  115. }
  116. } else {
  117. $this->$key = $value;
  118. }
  119. }
  120. public static function factory($model = FALSE, $id = FALSE) {
  121. $model = empty($model) ? __CLASS__ : 'Model_'.ucfirst($model);
  122. $obj = new $model($id);
  123. $obj->active_class = $model;
  124. unset($model, $id);
  125. return $obj;
  126. }
  127. public function set($key, $value="") {
  128. // Tell the class we're running set
  129. $this->ran_set = TRUE;
  130. $data = is_array($key) ? $key : array($key => $value);
  131. foreach($data as $key => $value) {
  132. if(array_key_exists($key, $this->data)) {
  133. $this->$key = $value;
  134. } elseif(array_key_exists($this->column_prefix.$key, $this->data)) {
  135. $this->{$this->column_prefix.$key} = $value;
  136. }
  137. }
  138. return $this;
  139. }
  140. public function save() {
  141. // Do an update or insert?
  142. $this->db->use_master($this->use_master);
  143. if($this->valid()) {
  144. $data = $this->data;
  145. unset($data[$this->primary_key]);
  146. return count($this->db->update($this->table_name, $data, array($this->primary_key => $this->data[$this->primary_key])));
  147. } else {
  148. unset($this->data[$this->primary_key]);
  149. $insert_id = $this->db->insert($this->table_name, $this->data)->insert_id();
  150. $this->data[$this->primary_key] = $insert_id;
  151. return $insert_id;
  152. }
  153. // If all else fails.
  154. return FALSE;
  155. }
  156. /**
  157. * Update
  158. * This is a performance method designed to work statically without
  159. * creating the overhead that is associated with loading a Modeler
  160. * object.
  161. *
  162. * primary key id OR column => value mixed
  163. * column => value array
  164. */
  165. public static function update($primary_key, $data) {
  166. // Check that the supplied data value is an array
  167. if(!is_array($data)) return FALSE;
  168. // Add support for specifying any column => value with an array on the where part of the update or default to primary key => id
  169. if(!is_array($primary_key)) {
  170. $primary_key = array(self::$primary_key => $primary_key);
  171. }
  172. // Add support for column prefixes
  173. foreach($data as $k=>$v) {
  174. if(!array_key_exists($k, self::$data) && in_array(self::$column_prefix.$k, self::$data)) {
  175. $data[self::$column_prefix.$k] = $v;
  176. unset($data[$k]);
  177. }
  178. }
  179. return self::db()->update(self::$table_name, $data, $primary_key);
  180. }
  181. public function delete() {
  182. if ($this->data[$this->primary_key]) {
  183. $this->db->use_master($this->use_master);
  184. $this->db->delete($this->table_name, array($this->primary_key => $this->data[$this->primary_key]));
  185. return $this->__destruct();
  186. }
  187. }
  188. public function fetch_all($orderby = NULL, $direction = 'ASC', $where=array()) {
  189. is_null($orderby) && $orderby = $this->primary_key;
  190. $class = isset($this->active_class) ? $this->active_class : __CLASS__;
  191. $this->db->use_master($this->use_master);
  192. return $this->db->orderby($orderby, $direction)->getwhere($this->table_name, $where)->result_array(TRUE, $class);
  193. }
  194. public function select_list($key, $display, $orderby = NULL, $direction = 'ASC', $where=array()) {
  195. $rows = array();
  196. if(!is_array($display)) {
  197. $display = explode(",", $display);
  198. }
  199. $this->db->use_master($this->use_master);
  200. $results = $this->fetch_all($orderby, $direction, $where);
  201. // Support prefixes...
  202. if(!array_key_exists($key, $this->data)) {
  203. if(array_key_exists($this->column_prefix.$key, $this->data)) {
  204. $key = $this->column_prefix.$key;
  205. }
  206. }
  207. // Prefixes for the display too...
  208. foreach($display as $k=>$d) {
  209. if(!array_key_exists($d, $this->data)) {
  210. if(array_key_exists($this->column_prefix.$d, $this->data)) {
  211. $display[$k] = $this->column_prefix.$d;
  212. }
  213. }
  214. }
  215. foreach($results as $row) {
  216. foreach($display as $d) {
  217. $rows[$row->$key] .= $row->$d . " ";
  218. }
  219. $rows[$row->$key] = trim($rows[$row->$key]);
  220. }
  221. return $rows;
  222. }
  223. public function __to_assoc() {
  224. $assoc = array();
  225. foreach(arr::c($this->data) as $key => $val) {
  226. $key = str_replace($this->column_prefix, "", $key);
  227. $assoc[$key] = $val;
  228. }
  229. return $assoc;
  230. }
  231. public static function db() {
  232. if(!is_a(Eight::instance()->db, 'Database')) {
  233. return Database::instance(Eight::instance()->default_conn);
  234. } else {
  235. return Eight::instance()->db;
  236. }
  237. }
  238. } // End Modeler Class