PageRenderTime 29ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/system/cms/core/MY_Model.php

https://github.com/JamieLomas/pyrocms
PHP | 662 lines | 315 code | 70 blank | 277 comment | 25 complexity | e519572d76dc8799017b5b6b1cab477e MD5 | raw file
  1. <?php
  2. /**
  3. * A base model to provide the basic CRUD
  4. * actions for all models that inherit from it.
  5. *
  6. * @package CodeIgniter
  7. * @subpackage MY_Model
  8. * @license GPLv3 <http://www.gnu.org/licenses/gpl-3.0.txt>
  9. * @link http://github.com/philsturgeon/codeigniter-base-model
  10. * @version 1.3
  11. * @author Jamie Rumbelow <http://jamierumbelow.net>
  12. * @modified Phil Sturgeon <http://philsturgeon.co.uk>
  13. * @modified Dan Horrigan <http://dhorrigan.com>
  14. * @copyright Copyright (c) 2009, Jamie Rumbelow <http://jamierumbelow.net>
  15. */
  16. // CI 2.0 Compatibility
  17. if(!class_exists('CI_Model')) { class CI_Model extends Model { } }
  18. class MY_Model extends CI_Model
  19. {
  20. /**
  21. * The database table to use, only
  22. * set if you want to bypass the magic
  23. *
  24. * @var string
  25. */
  26. protected $_table;
  27. /**
  28. * The primary key, by default set to
  29. * `id`, for use in some functions.
  30. *
  31. * @var string
  32. */
  33. protected $primary_key = 'id';
  34. /**
  35. * An array of functions to be called before
  36. * a record is created.
  37. *
  38. * @var array
  39. */
  40. protected $before_create = array();
  41. /**
  42. * An array of functions to be called after
  43. * a record is created.
  44. *
  45. * @var array
  46. */
  47. protected $after_create = array();
  48. /**
  49. * An array of validation rules
  50. *
  51. * @var array
  52. */
  53. protected $validate = array();
  54. /**
  55. * Skip the validation
  56. *
  57. * @var bool
  58. */
  59. protected $skip_validation = FALSE;
  60. /**
  61. * Wrapper to __construct for when loading
  62. * class is a superclass to a regular controller,
  63. * i.e. - extends Base not extends Controller.
  64. *
  65. * @return void
  66. * @author Jamie Rumbelow
  67. */
  68. public function MY_Model() { $this->__construct(); }
  69. /**
  70. * The class constructer, tries to guess
  71. * the table name.
  72. *
  73. * @author Jamie Rumbelow
  74. */
  75. public function __construct()
  76. {
  77. parent::__construct();
  78. $this->load->helper('inflector');
  79. $this->_fetch_table();
  80. }
  81. public function __call($method, $arguments)
  82. {
  83. $db_method = array($this->db, $method);
  84. if (is_callable($db_method))
  85. {
  86. $result = call_user_func_array($db_method, $arguments);
  87. if (is_object($result) && $result === $this->db)
  88. {
  89. return $this;
  90. }
  91. return $result;
  92. }
  93. throw new Exception("class '" . get_class($this) . "' does not have a method '" . $method . "'");
  94. }
  95. /**
  96. * Get table name
  97. *
  98. * @access public
  99. * @param string $prefix
  100. * @return string
  101. * @author PyroCMS Development Team
  102. */
  103. public function table_name($prefix = TRUE)
  104. {
  105. return $prefix ? $this->db->dbprefix($this->_table) : $this->_table;
  106. }
  107. /**
  108. * Set table name
  109. *
  110. * @access public
  111. * @param string $name
  112. * @return string
  113. * @author PyroCMS Development Team
  114. */
  115. public function set_table_name($name = NULL)
  116. {
  117. return $this->_table = $name;
  118. }
  119. /**
  120. * Get a single record by creating a WHERE clause with
  121. * a value for your primary key
  122. *
  123. * @param string $primary_value The value of your primary key
  124. * @return object
  125. * @author Phil Sturgeon
  126. */
  127. public function get($primary_value)
  128. {
  129. return $this->db->where($this->primary_key, $primary_value)
  130. ->get($this->_table)
  131. ->row();
  132. }
  133. /**
  134. * Get a single record by creating a WHERE clause with
  135. * the key of $key and the value of $val.
  136. *
  137. * @param string $key The key to search by
  138. * @param string $val The value of that key
  139. * @return object
  140. * @author Phil Sturgeon
  141. */
  142. public function get_by()
  143. {
  144. $where =& func_get_args();
  145. $this->_set_where($where);
  146. return $this->db->get($this->_table)
  147. ->row();
  148. }
  149. /**
  150. * Similar to get(), but returns a result array of
  151. * many result objects.
  152. *
  153. * @param string $key The key to search by
  154. * @param string $val The value of that key
  155. * @return array
  156. * @author Phil Sturgeon
  157. */
  158. public function get_many($primary_value)
  159. {
  160. $this->db->where($this->primary_key, $primary_value);
  161. return $this->get_all();
  162. }
  163. /**
  164. * Similar to get_by(), but returns a result array of
  165. * many result objects.
  166. *
  167. * @param string $key The key to search by
  168. * @param string $val The value of that key
  169. * @return array
  170. * @author Phil Sturgeon
  171. */
  172. public function get_many_by()
  173. {
  174. $where =& func_get_args();
  175. $this->_set_where($where);
  176. return $this->get_all();
  177. }
  178. /**
  179. * Get all records in the database
  180. *
  181. * @param string Type object or array
  182. * @return mixed
  183. * @author Jamie Rumbelow
  184. */
  185. public function get_all()
  186. {
  187. return $this->db->get($this->_table)->result();
  188. }
  189. /**
  190. * Similar to get_by(), but returns a result array of
  191. * many result objects.
  192. *
  193. * @param string $key The key to search by
  194. * @param string $val The value of that key
  195. * @return array
  196. * @author Phil Sturgeon
  197. */
  198. public function count_by()
  199. {
  200. $where =& func_get_args();
  201. $this->_set_where($where);
  202. return $this->db->count_all_results($this->_table);
  203. }
  204. /**
  205. * Get all records in the database
  206. *
  207. * @return array
  208. * @author Phil Sturgeon
  209. */
  210. public function count_all()
  211. {
  212. return $this->db->count_all($this->_table);
  213. }
  214. /**
  215. * Insert a new record into the database,
  216. * calling the before and after create callbacks.
  217. * Returns the insert ID.
  218. *
  219. * @param array $data Information
  220. * @return integer
  221. * @author Jamie Rumbelow
  222. * @modified Dan Horrigan
  223. */
  224. public function insert($data, $skip_validation = FALSE)
  225. {
  226. $valid = TRUE;
  227. if($skip_validation === FALSE)
  228. {
  229. $valid = $this->_run_validation($data);
  230. }
  231. if($valid)
  232. {
  233. $data = $this->_run_before_create($data);
  234. $this->db->insert($this->_table, $data);
  235. $this->_run_after_create($data, $this->db->insert_id());
  236. $this->skip_validation = FALSE;
  237. return $this->db->insert_id();
  238. }
  239. else
  240. {
  241. return FALSE;
  242. }
  243. }
  244. /**
  245. * Similar to insert(), just passing an array to insert
  246. * multiple rows at once. Returns an array of insert IDs.
  247. *
  248. * @param array $data Array of arrays to insert
  249. * @return array
  250. * @author Jamie Rumbelow
  251. */
  252. public function insert_many($data, $skip_validation = FALSE)
  253. {
  254. $ids = array();
  255. foreach ($data as $row)
  256. {
  257. $valid = TRUE;
  258. if($skip_validation === FALSE)
  259. {
  260. $valid = $this->_run_validation($data);
  261. }
  262. if($valid)
  263. {
  264. $data = $this->_run_before_create($row);
  265. $this->db->insert($this->_table, $row);
  266. $this->_run_after_create($row, $this->db->insert_id());
  267. $ids[] = $this->db->insert_id();
  268. }
  269. else
  270. {
  271. $ids[] = FALSE;
  272. }
  273. }
  274. $this->skip_validation = FALSE;
  275. return $ids;
  276. }
  277. /**
  278. * Update a record, specified by an ID.
  279. *
  280. * @param integer $id The row's ID
  281. * @param array $array The data to update
  282. * @return bool
  283. * @author Jamie Rumbelow
  284. */
  285. public function update($primary_value, $data, $skip_validation = FALSE)
  286. {
  287. $valid = TRUE;
  288. if($skip_validation === FALSE)
  289. {
  290. $valid = $this->_run_validation($data);
  291. }
  292. if($valid)
  293. {
  294. $this->skip_validation = FALSE;
  295. return $this->db->where($this->primary_key, $primary_value)
  296. ->set($data)
  297. ->update($this->_table);
  298. }
  299. else
  300. {
  301. return FALSE;
  302. }
  303. }
  304. /**
  305. * Update a record, specified by $key and $val.
  306. *
  307. * @param string $key The key to update with
  308. * @param string $val The value
  309. * @param array $array The data to update
  310. * @return bool
  311. * @author Jamie Rumbelow
  312. */
  313. public function update_by()
  314. {
  315. $args =& func_get_args();
  316. $data = array_pop($args);
  317. $this->_set_where($args);
  318. if($this->_run_validation($data))
  319. {
  320. $this->skip_validation = FALSE;
  321. return $this->db->set($data)
  322. ->update($this->_table);
  323. }
  324. else
  325. {
  326. return FALSE;
  327. }
  328. }
  329. /**
  330. * Updates many records, specified by an array
  331. * of IDs.
  332. *
  333. * @param array $primary_values The array of IDs
  334. * @param array $data The data to update
  335. * @return bool
  336. * @author Phil Sturgeon
  337. */
  338. public function update_many($primary_values, $data, $skip_validation)
  339. {
  340. $valid = TRUE;
  341. if($skip_validation === FALSE)
  342. {
  343. $valid = $this->_run_validation($data);
  344. }
  345. if($valid)
  346. {
  347. $this->skip_validation = FALSE;
  348. return $this->db->where_in($this->primary_key, $primary_values)
  349. ->set($data)
  350. ->update($this->_table);
  351. }
  352. else
  353. {
  354. return FALSE;
  355. }
  356. }
  357. /**
  358. * Updates all records
  359. *
  360. * @param array $data The data to update
  361. * @return bool
  362. * @since 1.1.3
  363. * @author Phil Sturgeon
  364. */
  365. public function update_all($data)
  366. {
  367. return $this->db->set($data)
  368. ->update($this->_table);
  369. }
  370. /**
  371. * Delete a row from the database table by the
  372. * ID.
  373. *
  374. * @param integer $id
  375. * @return bool
  376. * @author Jamie Rumbelow
  377. */
  378. public function delete($id)
  379. {
  380. return $this->db->where($this->primary_key, $id)
  381. ->delete($this->_table);
  382. }
  383. /**
  384. * Delete a row from the database table by the
  385. * key and value.
  386. *
  387. * @param string $key
  388. * @param string $value
  389. * @return bool
  390. * @author Phil Sturgeon
  391. */
  392. public function delete_by()
  393. {
  394. $where =& func_get_args();
  395. $this->_set_where($where);
  396. return $this->db->delete($this->_table);
  397. }
  398. /**
  399. * Delete many rows from the database table by
  400. * an array of IDs passed.
  401. *
  402. * @param array $primary_values
  403. * @return bool
  404. * @author Phil Sturgeon
  405. */
  406. public function delete_many($primary_values)
  407. {
  408. return $this->db->where_in($this->primary_key, $primary_values)
  409. ->delete($this->_table);
  410. }
  411. function dropdown()
  412. {
  413. $args =& func_get_args();
  414. if(count($args) == 2)
  415. {
  416. list($key, $value) = $args;
  417. }
  418. else
  419. {
  420. $key = $this->primary_key;
  421. $value = $args[0];
  422. }
  423. $query = $this->db->select(array($key, $value))
  424. ->get($this->_table);
  425. $options = array();
  426. foreach ($query->result() as $row)
  427. {
  428. $options[$row->{$key}] = $row->{$value};
  429. }
  430. return $options;
  431. }
  432. /**
  433. * Orders the result set by the criteria,
  434. * using the same format as CI's AR library.
  435. *
  436. * @param string $criteria The criteria to order by
  437. * @return object $this
  438. * @since 1.1.2
  439. * @author Jamie Rumbelow
  440. */
  441. public function order_by($criteria, $order = 'ASC')
  442. {
  443. $this->db->order_by($criteria, $order);
  444. return $this;
  445. }
  446. /**
  447. * Limits the result set by the integer passed.
  448. * Pass a second parameter to offset.
  449. *
  450. * @param integer $limit The number of rows
  451. * @param integer $offset The offset
  452. * @return object $this
  453. * @since 1.1.1
  454. * @author Jamie Rumbelow
  455. */
  456. public function limit($limit, $offset = 0)
  457. {
  458. $limit =& func_get_args();
  459. $this->_set_limit($limit);
  460. return $this;
  461. }
  462. /**
  463. * Removes duplicate entries from the result set.
  464. *
  465. * @return object $this
  466. * @since 1.1.1
  467. * @author Phil Sturgeon
  468. */
  469. public function distinct()
  470. {
  471. $this->db->distinct();
  472. return $this;
  473. }
  474. /**
  475. * Runs the before create actions.
  476. *
  477. * @param array $data The array of actions
  478. * @return void
  479. * @author Jamie Rumbelow
  480. */
  481. private function _run_before_create($data)
  482. {
  483. foreach ($this->before_create as $method)
  484. {
  485. $data = call_user_func_array(array($this, $method), array($data));
  486. }
  487. return $data;
  488. }
  489. /**
  490. * Runs the after create actions.
  491. *
  492. * @param array $data The array of actions
  493. * @return void
  494. * @author Jamie Rumbelow
  495. */
  496. private function _run_after_create($data, $id)
  497. {
  498. foreach ($this->after_create as $method)
  499. {
  500. call_user_func_array(array($this, $method), array($data, $id));
  501. }
  502. }
  503. /**
  504. * Runs validation on the passed data.
  505. *
  506. * @return bool
  507. * @author Dan Horrigan
  508. */
  509. private function _run_validation($data)
  510. {
  511. if($this->skip_validation)
  512. {
  513. return TRUE;
  514. }
  515. if(!empty($this->validate))
  516. {
  517. foreach($data as $key => $val)
  518. {
  519. $_POST[$key] = $val;
  520. }
  521. $this->load->library('form_validation');
  522. if(is_array($this->validate))
  523. {
  524. $this->form_validation->set_rules($this->validate);
  525. return $this->form_validation->run();
  526. }
  527. else
  528. {
  529. $this->form_validation->run($this->validate);
  530. }
  531. }
  532. else
  533. {
  534. return TRUE;
  535. }
  536. }
  537. /**
  538. * Fetches the table from the pluralised model name.
  539. *
  540. * @return void
  541. * @author Jamie Rumbelow
  542. */
  543. private function _fetch_table()
  544. {
  545. if ($this->_table == NULL)
  546. {
  547. $class = preg_replace('/(_m|_model)?$/', '', get_class($this));
  548. $this->_table = plural(strtolower($class));
  549. }
  550. }
  551. /**
  552. * Sets where depending on the number of parameters
  553. *
  554. * @return void
  555. * @author Phil Sturgeon
  556. */
  557. private function _set_where($params)
  558. {
  559. if(count($params) == 1)
  560. {
  561. $this->db->where($params[0]);
  562. }
  563. else
  564. {
  565. $this->db->where($params[0], $params[1]);
  566. }
  567. }
  568. /**
  569. * Sets limit depending on the number of parameters
  570. *
  571. * @return void
  572. * @author Phil Sturgeon
  573. */
  574. private function _set_limit($params)
  575. {
  576. if(count($params) == 1)
  577. {
  578. if(is_array($params[0]))
  579. {
  580. $this->db->limit($params[0][0], $params[0][1]);
  581. }
  582. else
  583. {
  584. $this->db->limit($params[0]);
  585. }
  586. }
  587. else
  588. {
  589. $this->db->limit( (int) $params[0], (int) $params[1]);
  590. }
  591. }
  592. }