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

/vendor/cakephp/cakephp/src/Database/IdentifierQuoter.php

https://gitlab.com/vannh/portal_training
PHP | 258 lines | 140 code | 25 blank | 93 comment | 16 complexity | e90e4fc9b538b5001bee81b398929e07 MD5 | raw file
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @link http://cakephp.org CakePHP(tm) Project
  12. * @since 3.0.0
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Database;
  16. use Cake\Database\ExpressionInterface;
  17. use Cake\Database\Expression\FieldInterface;
  18. use Cake\Database\Expression\IdentifierExpression;
  19. use Cake\Database\Expression\OrderByExpression;
  20. /**
  21. * Contains all the logic related to quoting identifiers in a Query object
  22. *
  23. * @internal
  24. */
  25. class IdentifierQuoter
  26. {
  27. /**
  28. * The driver instance used to do the identifier quoting
  29. *
  30. * @var \Cake\Database\Driver
  31. */
  32. protected $_driver;
  33. /**
  34. * Constructor
  35. *
  36. * @param \Cake\Database\Driver $driver The driver instance used to do the identifier quoting
  37. */
  38. public function __construct(Driver $driver)
  39. {
  40. $this->_driver = $driver;
  41. }
  42. /**
  43. * Iterates over each of the clauses in a query looking for identifiers and
  44. * quotes them
  45. *
  46. * @param \Cake\Database\Query $query The query to have its identifiers quoted
  47. * @return \Cake\Database\Query
  48. */
  49. public function quote(Query $query)
  50. {
  51. $binder = $query->valueBinder();
  52. $query->valueBinder(false);
  53. if ($query->type() === 'insert') {
  54. $this->_quoteInsert($query);
  55. } elseif ($query->type() === 'update') {
  56. $this->_quoteUpdate($query);
  57. } else {
  58. $this->_quoteParts($query);
  59. }
  60. $query->traverseExpressions([$this, 'quoteExpression']);
  61. $query->valueBinder($binder);
  62. return $query;
  63. }
  64. /**
  65. * Quotes identifiers inside expression objects
  66. *
  67. * @param \Cake\Database\ExpressionInterface $expression The expression object to walk and quote.
  68. * @return void
  69. */
  70. public function quoteExpression($expression)
  71. {
  72. if ($expression instanceof FieldInterface) {
  73. $this->_quoteComparison($expression);
  74. return;
  75. }
  76. if ($expression instanceof OrderByExpression) {
  77. $this->_quoteOrderBy($expression);
  78. return;
  79. }
  80. if ($expression instanceof IdentifierExpression) {
  81. $this->_quoteIdentifierExpression($expression);
  82. return;
  83. }
  84. }
  85. /**
  86. * Quotes all identifiers in each of the clauses of a query
  87. *
  88. * @param \Cake\Database\Query $query The query to quote.
  89. * @return void
  90. */
  91. protected function _quoteParts($query)
  92. {
  93. foreach (['distinct', 'select', 'from', 'group'] as $part) {
  94. $contents = $query->clause($part);
  95. if (!is_array($contents)) {
  96. continue;
  97. }
  98. $result = $this->_basicQuoter($contents);
  99. if ($result) {
  100. $query->{$part}($result, true);
  101. }
  102. }
  103. $joins = $query->clause('join');
  104. if ($joins) {
  105. $joins = $this->_quoteJoins($joins);
  106. $query->join($joins, [], true);
  107. }
  108. }
  109. /**
  110. * A generic identifier quoting function used for various parts of the query
  111. *
  112. * @param array $part the part of the query to quote
  113. * @return array
  114. */
  115. protected function _basicQuoter($part)
  116. {
  117. $result = [];
  118. foreach ((array)$part as $alias => $value) {
  119. $value = !is_string($value) ? $value : $this->_driver->quoteIdentifier($value);
  120. $alias = is_numeric($alias) ? $alias : $this->_driver->quoteIdentifier($alias);
  121. $result[$alias] = $value;
  122. }
  123. return $result;
  124. }
  125. /**
  126. * Quotes both the table and alias for an array of joins as stored in a Query
  127. * object
  128. *
  129. * @param array $joins The joins to quote.
  130. * @return array
  131. */
  132. protected function _quoteJoins($joins)
  133. {
  134. $result = [];
  135. foreach ($joins as $value) {
  136. $alias = null;
  137. if (!empty($value['alias'])) {
  138. $alias = $this->_driver->quoteIdentifier($value['alias']);
  139. $value['alias'] = $alias;
  140. }
  141. if (is_string($value['table'])) {
  142. $value['table'] = $this->_driver->quoteIdentifier($value['table']);
  143. }
  144. $result[$alias] = $value;
  145. }
  146. return $result;
  147. }
  148. /**
  149. * Quotes the table name and columns for an insert query
  150. *
  151. * @param \Cake\Database\Query $query The insert query to quote.
  152. * @return void
  153. */
  154. protected function _quoteInsert($query)
  155. {
  156. list($table, $columns) = $query->clause('insert');
  157. $table = $this->_driver->quoteIdentifier($table);
  158. foreach ($columns as &$column) {
  159. if (is_string($column)) {
  160. $column = $this->_driver->quoteIdentifier($column);
  161. }
  162. }
  163. $query->insert($columns)->into($table);
  164. }
  165. /**
  166. * Quotes the table name for an update query
  167. *
  168. * @param \Cake\Database\Query $query The update query to quote.
  169. * @return void
  170. */
  171. protected function _quoteUpdate($query)
  172. {
  173. $table = $query->clause('update')[0];
  174. if (is_string($table)) {
  175. $query->update($this->_driver->quoteIdentifier($table));
  176. }
  177. }
  178. /**
  179. * Quotes identifiers in expression objects implementing the field interface
  180. *
  181. * @param \Cake\Database\Expression\FieldInterface $expression The expression to quote.
  182. * @return void
  183. */
  184. protected function _quoteComparison(FieldInterface $expression)
  185. {
  186. $field = $expression->getField();
  187. if (is_string($field)) {
  188. $expression->setField($this->_driver->quoteIdentifier($field));
  189. } elseif (is_array($field)) {
  190. $quoted = [];
  191. foreach ($field as $f) {
  192. $quoted[] = $this->_driver->quoteIdentifier($f);
  193. }
  194. $expression->setField($quoted);
  195. } elseif ($field instanceof ExpressionInterface) {
  196. $this->quoteExpression($field);
  197. }
  198. }
  199. /**
  200. * Quotes identifiers in "order by" expression objects
  201. *
  202. * Strings with spaces are treated as literal expressions
  203. * and will not have identifiers quoted.
  204. *
  205. * @param \Cake\Database\Expression\OrderByExpression $expression The expression to quote.
  206. * @return void
  207. */
  208. protected function _quoteOrderBy(OrderByExpression $expression)
  209. {
  210. $expression->iterateParts(function ($part, &$field) {
  211. if (is_string($field)) {
  212. $field = $this->_driver->quoteIdentifier($field);
  213. return $part;
  214. }
  215. if (is_string($part) && strpos($part, ' ') === false) {
  216. return $this->_driver->quoteIdentifier($part);
  217. }
  218. return $part;
  219. });
  220. }
  221. /**
  222. * Quotes identifiers in "order by" expression objects
  223. *
  224. * @param \Cake\Database\Expression\IdentifierExpression $expression The identifiers to quote.
  225. * @return void
  226. */
  227. protected function _quoteIdentifierExpression(IdentifierExpression $expression)
  228. {
  229. $expression->setIdentifier(
  230. $this->_driver->quoteIdentifier($expression->getIdentifier())
  231. );
  232. }
  233. }