PageRenderTime 53ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/system/cms/core/MY_Model.php

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