/classes/db/DbQuery.php

https://gitlab.com/jslee1/PrestaShop · PHP · 333 lines · 140 code · 37 blank · 156 comment · 20 complexity · ca27c78b320a3b690c1bc2dd5c5b443a MD5 · raw file

  1. <?php
  2. /**
  3. * 2007-2015 PrestaShop
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@prestashop.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
  18. * versions in the future. If you wish to customize PrestaShop for your
  19. * needs please refer to http://www.prestashop.com for more information.
  20. *
  21. * @author PrestaShop SA <contact@prestashop.com>
  22. * @copyright 2007-2015 PrestaShop SA
  23. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  24. * International Registered Trademark & Property of PrestaShop SA
  25. */
  26. /**
  27. * SQL query builder
  28. *
  29. * @since 1.5.0.1
  30. */
  31. class DbQueryCore
  32. {
  33. /**
  34. * List of data to build the query
  35. *
  36. * @var array
  37. */
  38. protected $query = array(
  39. 'type' => 'SELECT',
  40. 'select' => array(),
  41. 'from' => '',
  42. 'join' => array(),
  43. 'where' => array(),
  44. 'group' => array(),
  45. 'having' => array(),
  46. 'order' => array(),
  47. 'limit' => array('offset' => 0, 'limit' => 0),
  48. );
  49. /**
  50. * Sets type of the query
  51. *
  52. * @param string $type SELECT|DELETE
  53. *
  54. * @return DbQuery
  55. */
  56. public function type($type)
  57. {
  58. $types = array('SELECT', 'DELETE');
  59. if (!empty($type) && in_array($type, $types)) {
  60. $this->query['type'] = $type;
  61. }
  62. return $this;
  63. }
  64. /**
  65. * Adds fields to SELECT clause
  66. *
  67. * @param string $fields List of fields to concat to other fields
  68. *
  69. * @return DbQuery
  70. */
  71. public function select($fields)
  72. {
  73. if (!empty($fields)) {
  74. $this->query['select'][] = $fields;
  75. }
  76. return $this;
  77. }
  78. /**
  79. * Sets table for FROM clause
  80. *
  81. * @param string $table Table name
  82. * @param string|null $alias Table alias
  83. *
  84. * @return DbQuery
  85. */
  86. public function from($table, $alias = null)
  87. {
  88. if (!empty($table)) {
  89. $this->query['from'][] = '`'._DB_PREFIX_.$table.'`'.($alias ? ' '.$alias : '');
  90. }
  91. return $this;
  92. }
  93. /**
  94. * Adds JOIN clause
  95. * E.g. $this->join('RIGHT JOIN '._DB_PREFIX_.'product p ON ...');
  96. *
  97. * @param string $join Complete string
  98. *
  99. * @return DbQuery
  100. */
  101. public function join($join)
  102. {
  103. if (!empty($join)) {
  104. $this->query['join'][] = $join;
  105. }
  106. return $this;
  107. }
  108. /**
  109. * Adds a LEFT JOIN clause
  110. *
  111. * @param string $table Table name (without prefix)
  112. * @param string|null $alias Table alias
  113. * @param string|null $on ON clause
  114. *
  115. * @return DbQuery
  116. */
  117. public function leftJoin($table, $alias = null, $on = null)
  118. {
  119. return $this->join('LEFT JOIN `'._DB_PREFIX_.bqSQL($table).'`'.($alias ? ' `'.pSQL($alias).'`' : '').($on ? ' ON '.$on : ''));
  120. }
  121. /**
  122. * Adds an INNER JOIN clause
  123. * E.g. $this->innerJoin('product p ON ...')
  124. *
  125. * @param string $table Table name (without prefix)
  126. * @param string|null $alias Table alias
  127. * @param string|null $on ON clause
  128. *
  129. * @return DbQuery
  130. */
  131. public function innerJoin($table, $alias = null, $on = null)
  132. {
  133. return $this->join('INNER JOIN `'._DB_PREFIX_.bqSQL($table).'`'.($alias ? ' `'.pSQL($alias).'`' : '').($on ? ' ON '.$on : ''));
  134. }
  135. /**
  136. * Adds a LEFT OUTER JOIN clause
  137. *
  138. * @param string $table Table name (without prefix)
  139. * @param string|null $alias Table alias
  140. * @param string|null $on ON clause
  141. *
  142. * @return DbQuery
  143. */
  144. public function leftOuterJoin($table, $alias = null, $on = null)
  145. {
  146. return $this->join('LEFT OUTER JOIN `'._DB_PREFIX_.bqSQL($table).'`'.($alias ? ' `'.pSQL($alias).'`' : '').($on ? ' ON '.$on : ''));
  147. }
  148. /**
  149. * Adds a NATURAL JOIN clause
  150. *
  151. * @param string $table Table name (without prefix)
  152. * @param string|null $alias Table alias
  153. *
  154. * @return DbQuery
  155. */
  156. public function naturalJoin($table, $alias = null)
  157. {
  158. return $this->join('NATURAL JOIN `'._DB_PREFIX_.bqSQL($table).'`'.($alias ? ' `'.pSQL($alias).'`' : ''));
  159. }
  160. /**
  161. * Adds a RIGHT JOIN clause
  162. *
  163. * @param string $table Table name (without prefix)
  164. * @param string|null $alias Table alias
  165. * @param string|null $on ON clause
  166. *
  167. * @return DbQuery
  168. */
  169. public function rightJoin($table, $alias = null, $on = null)
  170. {
  171. return $this->join('RIGHT JOIN `'._DB_PREFIX_.bqSQL($table).'`'.($alias ? ' `'.pSQL($alias).'`' : '').($on ? ' ON '.$on : ''));
  172. }
  173. /**
  174. * Adds a restriction in WHERE clause (each restriction will be separated by AND statement)
  175. *
  176. * @param string $restriction
  177. *
  178. * @return DbQuery
  179. */
  180. public function where($restriction)
  181. {
  182. if (!empty($restriction)) {
  183. $this->query['where'][] = $restriction;
  184. }
  185. return $this;
  186. }
  187. /**
  188. * Adds a restriction in HAVING clause (each restriction will be separated by AND statement)
  189. *
  190. * @param string $restriction
  191. *
  192. * @return DbQuery
  193. */
  194. public function having($restriction)
  195. {
  196. if (!empty($restriction)) {
  197. $this->query['having'][] = $restriction;
  198. }
  199. return $this;
  200. }
  201. /**
  202. * Adds an ORDER BY restriction
  203. *
  204. * @param string $fields List of fields to sort. E.g. $this->order('myField, b.mySecondField DESC')
  205. *
  206. * @return DbQuery
  207. */
  208. public function orderBy($fields)
  209. {
  210. if (!empty($fields)) {
  211. $this->query['order'][] = $fields;
  212. }
  213. return $this;
  214. }
  215. /**
  216. * Adds a GROUP BY restriction
  217. *
  218. * @param string $fields List of fields to group. E.g. $this->group('myField1, myField2')
  219. *
  220. * @return DbQuery
  221. */
  222. public function groupBy($fields)
  223. {
  224. if (!empty($fields)) {
  225. $this->query['group'][] = $fields;
  226. }
  227. return $this;
  228. }
  229. /**
  230. * Sets query offset and limit
  231. *
  232. * @param int $limit
  233. * @param int $offset
  234. *
  235. * @return DbQuery
  236. */
  237. public function limit($limit, $offset = 0)
  238. {
  239. $offset = (int)$offset;
  240. if ($offset < 0) {
  241. $offset = 0;
  242. }
  243. $this->query['limit'] = array(
  244. 'offset' => $offset,
  245. 'limit' => (int)$limit,
  246. );
  247. return $this;
  248. }
  249. /**
  250. * Generates query and return SQL string
  251. *
  252. * @return string
  253. * @throws PrestaShopException
  254. */
  255. public function build()
  256. {
  257. if ($this->query['type'] == 'SELECT') {
  258. $sql = 'SELECT '.((($this->query['select'])) ? implode(",\n", $this->query['select']) : '*')."\n";
  259. } else {
  260. $sql = $this->query['type'].' ';
  261. }
  262. if (!$this->query['from']) {
  263. throw new PrestaShopException('Table name not set in DbQuery object. Cannot build a valid SQL query.');
  264. }
  265. $sql .= 'FROM '.implode(', ', $this->query['from'])."\n";
  266. if ($this->query['join']) {
  267. $sql .= implode("\n", $this->query['join'])."\n";
  268. }
  269. if ($this->query['where']) {
  270. $sql .= 'WHERE ('.implode(') AND (', $this->query['where']).")\n";
  271. }
  272. if ($this->query['group']) {
  273. $sql .= 'GROUP BY '.implode(', ', $this->query['group'])."\n";
  274. }
  275. if ($this->query['having']) {
  276. $sql .= 'HAVING ('.implode(') AND (', $this->query['having']).")\n";
  277. }
  278. if ($this->query['order']) {
  279. $sql .= 'ORDER BY '.implode(', ', $this->query['order'])."\n";
  280. }
  281. if ($this->query['limit']['limit']) {
  282. $limit = $this->query['limit'];
  283. $sql .= 'LIMIT '.($limit['offset'] ? $limit['offset'].', ' : '').$limit['limit'];
  284. }
  285. return $sql;
  286. }
  287. /**
  288. * Converts object to string
  289. *
  290. * @return string
  291. */
  292. public function __toString()
  293. {
  294. return $this->build();
  295. }
  296. }