PageRenderTime 40ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/webapp/_lib/model/class.PDODAO.php

https://github.com/unruthless/ThinkUp
PHP | 350 lines | 176 code | 17 blank | 157 comment | 24 complexity | d2dade6033e43f7c049d3ff16cc7b127 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.1
  1. <?php
  2. /**
  3. *
  4. * ThinkUp/webapp/_lib/model/class.PDODAO.php
  5. *
  6. * Copyright (c) 2009-2011 Mark Wilkie, Christoffer Viken, Gina Trapani
  7. *
  8. * LICENSE:
  9. *
  10. * This file is part of ThinkUp (http://thinkupapp.com).
  11. *
  12. * ThinkUp is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
  13. * License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any
  14. * later version.
  15. *
  16. * ThinkUp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
  17. * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  18. * details.
  19. *
  20. * You should have received a copy of the GNU General Public License along with ThinkUp. If not, see
  21. * <http://www.gnu.org/licenses/>.
  22. *
  23. *
  24. * PDO DAO
  25. * Parent class for PDO DAOs
  26. * @license http://www.gnu.org/licenses/gpl.html
  27. * @copyright 2009-2011 Mark Wilkie, Christoffer Viken, Gina Trapani
  28. * @author Christoffer Viken <christoffer@viken.me>
  29. * @author Mark Wilkie
  30. * @author Gina Trapani <ginatrapani[at]gmail[dot]com>
  31. * @author Piyush Mishra <me[at]piyushmishra[dot]com>
  32. */
  33. abstract class PDODAO {
  34. /**
  35. * Logger
  36. * @var Logger Object
  37. */
  38. var $logger;
  39. /**
  40. * Configuration
  41. * @var Config Object
  42. */
  43. var $config;
  44. /**
  45. * PDO instance
  46. * @var PDO Object
  47. */
  48. static $PDO = null;
  49. /**
  50. * Table Prefix
  51. * @var str
  52. */
  53. static $prefix;
  54. /**
  55. * GMT offset
  56. * @var int
  57. */
  58. static $gmt_offset;
  59. /**
  60. *
  61. * @var bool
  62. */
  63. private $profiler_enabled = false;
  64. /**
  65. * Constructor
  66. * @param array $cfg_vals Optionally override config.inc.php vals; needs 'table_prefix', 'GMT_offset', 'db_type',
  67. * 'db_socket', 'db_name', 'db_host', 'db_user', 'db_password'
  68. * @return PDODAO
  69. */
  70. public function __construct($cfg_vals=null){
  71. $this->logger = Logger::getInstance();
  72. $this->config = Config::getInstance($cfg_vals);
  73. if(is_null(self::$PDO)) {
  74. $this->connect();
  75. }
  76. self::$prefix = $this->config->getValue('table_prefix');
  77. self::$gmt_offset = $this->config->getGMTOffset();
  78. $this->profiler_enabled = Profiler::isEnabled();
  79. }
  80. /**
  81. * Connection initiator
  82. */
  83. public final function connect(){
  84. if(is_null(self::$PDO)) {
  85. self::$PDO = new PDO(
  86. self::getConnectString($this->config),
  87. $this->config->getValue('db_user'),
  88. $this->config->getValue('db_password')
  89. );
  90. self::$PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  91. // if THINKUP_CFG var 'set_pdo_charset' is set to true, set the connection charset to utf8
  92. if ($this->config->getValue('set_pdo_charset')) {
  93. self::$PDO->exec('SET CHARACTER SET utf8');
  94. }
  95. }
  96. }
  97. /**
  98. * Generates a connect string to use when creating a PDO object.
  99. * @param Config $config
  100. * @return string PDO connect string
  101. */
  102. public static function getConnectString($config) {
  103. //set default db type to mysql if not set
  104. $db_type = $config->getValue('db_type');
  105. if(! $db_type) { $db_type = 'mysql'; }
  106. $db_socket = $config->getValue('db_socket');
  107. if ( !$db_socket) {
  108. $db_port = $config->getValue('db_port');
  109. if (!$db_port) {
  110. $db_socket = '';
  111. } else {
  112. $db_socket = ";port=".$config->getValue('db_port');
  113. }
  114. } else {
  115. $db_socket=";unix_socket=".$db_socket;
  116. }
  117. $db_string = sprintf(
  118. "%s:dbname=%s;host=%s%s",
  119. $db_type,
  120. $config->getValue('db_name'),
  121. $config->getValue('db_host'),
  122. $db_socket
  123. );
  124. return $db_string;
  125. }
  126. /**
  127. * Disconnector
  128. * Caution! This will disconnect for ALL DAOs
  129. */
  130. protected final function disconnect(){
  131. self::$PDO = null;
  132. }
  133. /**
  134. * Executes the query, with the bound values
  135. * @param str $sql
  136. * @param array $binds
  137. * @return PDOStatement
  138. */
  139. protected final function execute($sql, $binds = array()) {
  140. if ($this->profiler_enabled) {
  141. $start_time = microtime(true);;
  142. }
  143. $sql = preg_replace("/#prefix#/", self::$prefix, $sql);
  144. $sql = preg_replace("/#gmt_offset#/", self::$gmt_offset, $sql);
  145. $stmt = self::$PDO->prepare($sql);
  146. if(is_array($binds) and count($binds) >= 1) {
  147. foreach ($binds as $key => $value) {
  148. if(is_int($value)) {
  149. $stmt->bindValue($key, $value, PDO::PARAM_INT);
  150. } else {
  151. $stmt->bindValue($key, $value, PDO::PARAM_STR);
  152. }
  153. }
  154. }
  155. try {
  156. $stmt->execute();
  157. } catch (PDOException $e) {
  158. $config = Config::getInstance();
  159. $exception_details = 'Database error! ';
  160. if ($config->getValue('debug')) {
  161. $exception_details .= '<br>ThinkUp could not execute the following query:<br> '.
  162. str_replace(chr(10), "", $stmt->queryString) . ' <br>PDOException: '. $e->getMessage();
  163. } else {
  164. $exception_details .=
  165. '<br>To see the technical details of what went wrong, set debug = true in ThinkUp\'s config file.';
  166. }
  167. throw new PDOException ($exception_details);
  168. }
  169. if ($this->profiler_enabled) {
  170. $end_time = microtime(true);
  171. $total_time = $end_time - $start_time;
  172. $profiler = Profiler::getInstance();
  173. $profiler->add($total_time, $stmt->queryString, true, $stmt->rowCount());
  174. }
  175. return $stmt;
  176. }
  177. /**
  178. * Proxy for getUpdateCount
  179. * @param PDOStatement $ps
  180. * @return int Update Count
  181. */
  182. protected final function getDeleteCount($ps){
  183. //Alias for getUpdateCount
  184. return $this->getUpdateCount($ps);
  185. }
  186. /**
  187. * Gets a single row and closes cursor.
  188. * @param PDOStatement $ps
  189. * @return various array,object depending on context
  190. */
  191. protected final function fetchAndClose($ps){
  192. $row = $ps->fetch();
  193. $ps->closeCursor();
  194. return $row;
  195. }
  196. /**
  197. * Gets a multiple rows and closes cursor.
  198. * @param PDOStatement $ps
  199. * @return array of arrays/objects depending on context
  200. */
  201. protected final function fetchAllAndClose($ps){
  202. $rows = $ps->fetchAll();
  203. $ps->closeCursor();
  204. return $rows;
  205. }
  206. /**
  207. * Gets the rows returned by a statement as array of objects.
  208. * @param PDOStatement $ps
  209. * @param str $obj
  210. * @return array numbered keys, with objects
  211. */
  212. protected final function getDataRowAsObject($ps, $obj){
  213. $ps->setFetchMode(PDO::FETCH_CLASS,$obj);
  214. $row = $this->fetchAndClose($ps);
  215. if(!$row){
  216. $row = null;
  217. }
  218. return $row;
  219. }
  220. /**
  221. * Gets the first returned row as array
  222. * @param PDOStatement $ps
  223. * @return array named keys
  224. */
  225. protected final function getDataRowAsArray($ps){
  226. $ps->setFetchMode(PDO::FETCH_ASSOC);
  227. $row = $this->fetchAndClose($ps);
  228. if(!$row){
  229. $row = null;
  230. }
  231. return $row;
  232. }
  233. /**
  234. * Returns the first row as an object
  235. * @param PDOStatement $ps
  236. * @param str $obj
  237. * @return array numbered keys, with Objects
  238. */
  239. protected final function getDataRowsAsObjects($ps, $obj){
  240. $ps->setFetchMode(PDO::FETCH_CLASS,$obj);
  241. $data = $this->fetchAllAndClose($ps);
  242. return $data;
  243. }
  244. /**
  245. * Gets the rows returned by a statement as array with arrays
  246. * @param PDOStatement $ps
  247. * @return array numbered keys, with array named keys
  248. */
  249. protected final function getDataRowsAsArrays($ps){
  250. $ps->setFetchMode(PDO::FETCH_ASSOC);
  251. $data = $this->fetchAllAndClose($ps);
  252. return $data;
  253. }
  254. /**
  255. * Gets the result returned by a count query
  256. * (value of col count on first row)
  257. * @param PDOStatement $ps
  258. * @param int Count
  259. */
  260. protected final function getDataCountResult($ps){
  261. $ps->setFetchMode(PDO::FETCH_ASSOC);
  262. $row = $this->fetchAndClose($ps);
  263. if(!$row or !isset($row['count'])){
  264. $count = 0;
  265. } else {
  266. $count = (int) $row['count'];
  267. }
  268. return $count;
  269. }
  270. /**
  271. * Gets whether a statement returned anything
  272. * @param PDOStatement $ps
  273. * @return bool True if row(s) are returned
  274. */
  275. protected final function getDataIsReturned($ps){
  276. $row = $this->fetchAndClose($ps);
  277. $ret = false;
  278. if ($row && count($row) > 0) {
  279. $ret = true;
  280. }
  281. return $ret;
  282. }
  283. /**
  284. * Gets data "insert ID" from a statement
  285. * @param PDOStatement $ps
  286. * @return int|bool Inserted ID or false if there is none.
  287. */
  288. protected final function getInsertId($ps){
  289. $rc = $this->getUpdateCount($ps);
  290. $id = self::$PDO->lastInsertId();
  291. if ($rc > 0 and $id > 0) {
  292. return $id;
  293. } else {
  294. return false;
  295. }
  296. }
  297. /**
  298. * Proxy for getUpdateCount
  299. * @param PDOStatement $ps
  300. * @return int Insert count
  301. */
  302. protected final function getInsertCount($ps){
  303. //Alias for getUpdateCount
  304. return $this->getUpdateCount($ps);
  305. }
  306. /**
  307. * Get the number of updated rows
  308. * @param PDOStatement $ps
  309. * @return int Update Count
  310. */
  311. protected final function getUpdateCount($ps){
  312. $num = $ps->rowCount();
  313. $ps->closeCursor();
  314. return $num;
  315. }
  316. /**
  317. * Converts any form of "boolean" value to a Database usable one
  318. * @internal
  319. * @param mixed $val
  320. * @return int 0 or 1 (false or true)
  321. */
  322. protected final function convertBoolToDB($val){
  323. return $val ? 1 : 0;
  324. }
  325. /**
  326. * Converts a Database boolean to a PHP boolean
  327. * @param int $val
  328. * @return bool
  329. */
  330. public final static function convertDBToBool($val){
  331. return $val == 0 ? false : true;
  332. }
  333. }