PageRenderTime 25ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/code/ice/model.php

https://github.com/dgmike/Ice-Baby
PHP | 394 lines | 229 code | 31 blank | 134 comment | 41 complexity | 2879bc7b96152bd353a843ae659bed59 MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. require_once 'model_result.php';
  3. /**
  4. * Model
  5. *
  6. * Extends this Model for each table you use
  7. *
  8. * @package
  9. * @version $id$
  10. * @copyright 1997-2005 The PHP Group
  11. * @author Michael Granados <michaelgranados@gmail.com>
  12. * @license PHP Version 3.0 {@link http://www.php.net/license/3_0.txt}
  13. */
  14. class Model
  15. {
  16. static $_pdo = null;
  17. public $_table = null;
  18. public $_key = null;
  19. public $_str = null;
  20. public $_hasMany = array(); // deprecated
  21. public $_multipleJoin = array(); // usa tabela tercearia
  22. public $_relatedJoin = array(); // um para um
  23. public $_allow_html = array(); // array com o nome dos campos que não serão limpos pelo limpa_html
  24. public function __get($key)
  25. {
  26. return (property_exists($this, $key)) ? $this->$key : '';
  27. }
  28. /**
  29. * __construct - creates the Model Object
  30. *
  31. * @param string $dns String to connect @see PDO
  32. * @param string $username Username to connect on database @see PDO
  33. * @param string $password Password to connect on database @see PDO
  34. * @param array $driver_options Driver options @see PDO
  35. * @access public
  36. * @return void
  37. */
  38. public function __construct($dns=null, $username=null, $password=null, array $driver_options = array())
  39. {
  40. if (!$this->_table) {
  41. $this->_table = strtolower(get_class($this));
  42. }
  43. if (!$this->_key) {
  44. $this->_key = 'id_'.$this->_table;
  45. }
  46. if (!$this->_str) {
  47. $this->_str = ":id_{$this->_table}:";
  48. }
  49. $items = array('dns', 'username', 'password', 'driver_options');
  50. foreach ($items as $item) {
  51. if (null==$$item) {
  52. $item = strtoupper($item);
  53. if (defined("DB_$item")) {
  54. if ($item == 'DRIVER_OPTIONS') {
  55. $driver_options = unserialize(DB_DRIVER_OPTIONS);
  56. } else {
  57. ${strtolower($item)} = constant("DB_$item");
  58. }
  59. }
  60. }
  61. }
  62. if (!self::$_pdo) {
  63. self::$_pdo = new PDO($dns, $username, $password, $driver_options);
  64. }
  65. }
  66. /**
  67. * __call - Redirect to PDO
  68. *
  69. * If you needs a PDO method, just use this object
  70. *
  71. * @param mixed $method
  72. * @param mixed $params
  73. * @access public
  74. * @return PDO_result
  75. */
  76. public function __call($method, $params)
  77. {
  78. return call_user_func_array(array(self::$_pdo, $method), $params);
  79. }
  80. /**
  81. * get - Get a row of table
  82. *
  83. * @TODO id will accept array where the $this->_key is an array
  84. *
  85. * @param int $id ID you want to select
  86. * @access public
  87. * @return Model_Result
  88. */
  89. public function get($id, $oneLevel = true)
  90. {
  91. $sql = 'SELECT * FROM '.$this->_table.' WHERE '.$this->_key.' = ?';
  92. $stmt = self::$_pdo->prepare($sql);
  93. $stmt->setFetchMode(PDO::FETCH_CLASS,
  94. 'Model_Result', array($stmt, $this, $oneLevel));
  95. $stmt->execute(array($id));
  96. #Tratando os erros de SQL
  97. $error = $stmt->errorInfo();
  98. if(isset($error[1])){
  99. throw new Exception ("<h1>SQL Error</h1> ({$error[1]}) {$error[2]}");
  100. }
  101. return $stmt->fetch();
  102. }
  103. /**
  104. * _where - Makes a where string
  105. *
  106. * Makes a where string to helper the queries. You just need
  107. * to pass an associative array or the where string.
  108. *
  109. * Eg:
  110. * $table->_where(array(
  111. * 'name LIKE' => 'Mike',
  112. * 'age' => 25,
  113. * 'OR age' => 30,
  114. * ));
  115. * $table->_where('name LIKE "%Mike%" AND age = 25 OR age = 25');
  116. *
  117. * @param array|string $where Where params
  118. * @access public
  119. * @return void
  120. */
  121. public function _where($where = array())
  122. {
  123. $_where = array();
  124. if ('string'==gettype($where)) {
  125. $_where[] = $where;
  126. } elseif (!is_scalar($where)) {
  127. foreach ($where as $key=>$value) {
  128. // @TODO englobe array $value`s
  129. // if ('array' === gettype($value)) {
  130. // $_where[] = '(' . $this->_where($value) . ')';
  131. // }
  132. $key = trim($key);
  133. if (strpos(trim($key), ' ')===false AND !is_null($value)) {
  134. $key .= ' = ';
  135. }
  136. if ($_where AND !preg_match('@^(and|or)\b@i', $key)) {
  137. $key = "AND $key";
  138. }
  139. if($value !== null) {
  140. self::$_pdo->quote($value);
  141. $_where[] = "$key '$value'";
  142. } else {
  143. $value = 'is NULL';
  144. $_where[] = "$key $value";
  145. }
  146. }
  147. }
  148. return $_where ? ' WHERE '.implode(' ', $_where) : '';
  149. }
  150. public function find($where = array(), $fields = '*', $limit = null,
  151. $offset = null, $order = null)
  152. {
  153. return $this->select($where, $fields, $limit, $offset, $order, 'all');
  154. }
  155. /**
  156. * select - Do a simple select
  157. *
  158. * It just select a resultset from a table
  159. *
  160. * @param array $where An where to select @see $this->_where
  161. * @param string $fields Fields to select, allways select the $this->_key
  162. * @param int $limit Limit to your select
  163. * @param int $offset Offset to your select
  164. * @access public
  165. * @return void
  166. */
  167. public function select($where = array(), $fields = '*', $limit = null,
  168. $offset = null, $order = null, $fetch = null)
  169. {
  170. if (!$fields) {
  171. $fields = '*';
  172. }
  173. if (in_array(gettype($fields), array('object', 'array'))) {
  174. $fields = implode(', ', (array) $fields);
  175. }
  176. $where = is_null($where)?array():$where;
  177. $sql = 'SELECT '.$fields.' FROM '.$this->_table;
  178. $sql .= $this->_where($where);
  179. if (!is_null($offset)) {
  180. $offset = (int) $offset;
  181. }
  182. if (!is_null($limit)) {
  183. $limit = (int) $limit;
  184. }
  185. if (!is_null($limit) AND !is_null($offset)) {
  186. $offset .= ',';
  187. }
  188. if(!is_null($order)){
  189. $sql .= " ORDER BY {$order}";
  190. }
  191. if (!is_null($offset) OR !is_null($limit)) {
  192. $sql .= " LIMIT $offset$limit";
  193. }
  194. $stmt = self::$_pdo->prepare($sql);
  195. if ($fetch == 'all') {
  196. $stmt->setFetchMode(PDO::FETCH_OBJ);
  197. } elseif ($fetch == 'one') {
  198. $stmt->setFetchMode(PDO::FETCH_CLASS,
  199. 'Model_Result', array($stmt, $this), false);
  200. } else {
  201. $stmt->setFetchMode(PDO::FETCH_CLASS,
  202. 'Model_Result', array($stmt, $this));
  203. }
  204. $stmt->execute();
  205. #Tratando os erros de SQL
  206. $error = $stmt->errorInfo();
  207. if(isset($error[1])){
  208. throw new Exception ("<h1>SQL Error</h1> ({$error[1]}) {$error[2]}");
  209. }
  210. if ($fetch == 'all') {
  211. return $stmt->fetchAll();
  212. }
  213. return $stmt->fetch();
  214. }
  215. /**
  216. * page - Makes a simple select using easy page limit
  217. *
  218. * Its easy to make a paginable result to your project, just use
  219. * this method.
  220. *
  221. * @param string $fields String of fields to select, allways select $this->_key
  222. * @param int $page Page to select
  223. * @param mixed $filter Filter to your select, just a where clause @see $this->_where
  224. * @param int $per_page Quantity per page
  225. * @access public
  226. * @return void
  227. */
  228. public function page($fields = '*', $page = 1, $filter = null, $per_page = 20)
  229. {
  230. $offset = ($page-1) * $per_page;
  231. $limit = $per_page;
  232. $total = $this->select($filter, 'count(*) as C');
  233. if ($total) {
  234. $pages = ceil($total->C/$per_page);
  235. } else {
  236. $pages = 0;
  237. }
  238. $return = $this->select($filter, $fields, $limit, $offset);
  239. if ($return) {
  240. $return->pages($pages);
  241. }
  242. return $return;
  243. }
  244. /**
  245. * insert - Insert a new row on the database
  246. *
  247. * An easy way to insert new row on table, just pass your data as associative array
  248. *
  249. * Eg:
  250. * $this->insert(array(
  251. * 'name' => 'Mike',
  252. * 'age' => 25,
  253. * ));
  254. *
  255. * @param array $data An array to insert
  256. * @param string $table Pass the table if your object does not have a table
  257. * @access public
  258. * @return void
  259. */
  260. public function insert($data = array(), $table = null)
  261. {
  262. $data = limpa_html($data, $this->_allow_html);
  263. $sql = 'INSERT INTO %s (%s) VALUES (%s)';
  264. $data = (array) $data;
  265. if (null === $table) {
  266. $table = $this->_table;
  267. }
  268. $keys = implode(', ', array_keys($data));
  269. $data = array_values($data);
  270. $vals = implode(', ', array_fill(0, count($data), '?'));
  271. $sql = sprintf($sql, $table, $keys, $vals);
  272. $stmt = self::$_pdo->prepare($sql);
  273. $error = $stmt->errorInfo();
  274. if(isset($error[1])){
  275. throw new Exception ("<h1>SQL Error</h1> ({$error[1]}) {$error[2]}");
  276. }
  277. return $stmt->execute($data);
  278. }
  279. /**
  280. * update - Updates rows of table
  281. *
  282. * Pass the associative array to update one or more rows on the database
  283. *
  284. * Eg:
  285. * $this->update(array(
  286. * 'name' => 'Rodrigo',
  287. * ), array('id' => 21));
  288. *
  289. * @param mixed $data The data to put on
  290. * @param array $where The where to update @see $this->_where
  291. * @param mixed $table Table to update, optional. By default @use $this->_table
  292. * @access public
  293. * @return void
  294. */
  295. public function update($data, array $where=array(), $table = null)
  296. {
  297. $data = limpa_html($data, $this->_allow_html);
  298. $sql = "UPDATE %s SET %s %s"; # table, key=value, where
  299. if (!$table) {
  300. $table = $this->_table;
  301. }
  302. $data = (array) $data;
  303. $_data = array();
  304. if (isset($data[$this->_key])) {
  305. $where[$this->_key] = $data[$this->_key];
  306. unset($data[$this->_key]);
  307. }
  308. foreach ($data as $key => $value) {
  309. $_data[] = "$key = ?";
  310. }
  311. $where = $this->_where($where);
  312. $sql = sprintf($sql, $table, implode(', ', $_data), $where);
  313. $stmt = self::$_pdo->prepare($sql);
  314. $data = array_values($data);
  315. $stmt->execute($data);
  316. #Tratando os erros de SQL
  317. $error = $stmt->errorInfo();
  318. if(isset($error[1]) AND !is_null($error[1])){
  319. throw new Exception ("<h1>SQL Error</h1> ({$error[1]}) {$error[2]}");
  320. }
  321. }
  322. /**
  323. * save - Saves the data on table. Updating or inserting data
  324. *
  325. * Pass an associative array, if the array has the $this->_key value, just update
  326. * else create a new record.
  327. *
  328. * @param array $data
  329. * @param array $where
  330. * @param mixed $table
  331. * @access public
  332. * @return void
  333. */
  334. public function save($data, array $where = array(), $table = null)
  335. {
  336. if (isset($data[$this->_key])) {
  337. $this->update($data, $where, $table);
  338. } else {
  339. $this->insert($data, $table);
  340. }
  341. }
  342. public function remove($where)
  343. {
  344. $sql = 'DELETE FROM '.$this->_table.$this->_where($where);
  345. $stmt = self::$_pdo->prepare($sql);
  346. $stmt->execute();
  347. $error = $stmt->errorInfo();
  348. if(isset($error[1])){
  349. throw new Exception ("<h1>SQL Error</h1> ({$error[1]}) {$error[2]}");
  350. }
  351. return $stmt->fetch();
  352. }
  353. public function delete($id)
  354. {
  355. $sql = 'DELETE FROM '.$this->_table.' WHERE '.$this->_key.' = ?';
  356. $stmt = self::$_pdo->prepare($sql);
  357. $error = $stmt->errorInfo();
  358. if(isset($error[1])){
  359. throw new Exception ("<h1>SQL Error</h1> ({$error[1]}) {$error[2]}");
  360. }
  361. return $stmt->execute(array($id));
  362. }
  363. }