PageRenderTime 28ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/core/lib/Drupal/Core/Database/Query/SelectExtender.php

http://github.com/drupal/drupal
PHP | 548 lines | 241 code | 77 blank | 230 comment | 4 complexity | cd91fe4b5fdd621e4826f77f83738321 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. namespace Drupal\Core\Database\Query;
  3. use Drupal\Core\Database\Connection;
  4. /**
  5. * The base extender class for Select queries.
  6. */
  7. class SelectExtender implements SelectInterface {
  8. /**
  9. * The Select query object we are extending/decorating.
  10. *
  11. * @var \Drupal\Core\Database\Query\SelectInterface
  12. */
  13. protected $query;
  14. /**
  15. * The connection object on which to run this query.
  16. *
  17. * @var \Drupal\Core\Database\Connection
  18. */
  19. protected $connection;
  20. /**
  21. * A unique identifier for this query object.
  22. *
  23. * @var string
  24. */
  25. protected $uniqueIdentifier;
  26. /**
  27. * The placeholder counter.
  28. *
  29. * @var int
  30. */
  31. protected $placeholder = 0;
  32. public function __construct(SelectInterface $query, Connection $connection) {
  33. $this->uniqueIdentifier = uniqid('', TRUE);
  34. $this->query = $query;
  35. $this->connection = $connection;
  36. }
  37. /**
  38. * {@inheritdoc}
  39. */
  40. public function uniqueIdentifier() {
  41. return $this->uniqueIdentifier;
  42. }
  43. /**
  44. * {@inheritdoc}
  45. */
  46. public function nextPlaceholder() {
  47. return $this->placeholder++;
  48. }
  49. /**
  50. * {@inheritdoc}
  51. */
  52. public function addTag($tag) {
  53. $this->query->addTag($tag);
  54. return $this;
  55. }
  56. /**
  57. * {@inheritdoc}
  58. */
  59. public function hasTag($tag) {
  60. return $this->query->hasTag($tag);
  61. }
  62. /**
  63. * {@inheritdoc}
  64. */
  65. public function hasAllTags() {
  66. return call_user_func_array([$this->query, 'hasAllTags'], func_get_args());
  67. }
  68. /**
  69. * {@inheritdoc}
  70. */
  71. public function hasAnyTag() {
  72. return call_user_func_array([$this->query, 'hasAnyTag'], func_get_args());
  73. }
  74. /**
  75. * {@inheritdoc}
  76. */
  77. public function addMetaData($key, $object) {
  78. $this->query->addMetaData($key, $object);
  79. return $this;
  80. }
  81. /**
  82. * {@inheritdoc}
  83. */
  84. public function getMetaData($key) {
  85. return $this->query->getMetaData($key);
  86. }
  87. /**
  88. * {@inheritdoc}
  89. */
  90. public function condition($field, $value = NULL, $operator = '=') {
  91. $this->query->condition($field, $value, $operator);
  92. return $this;
  93. }
  94. /**
  95. * {@inheritdoc}
  96. */
  97. public function &conditions() {
  98. return $this->query->conditions();
  99. }
  100. /**
  101. * {@inheritdoc}
  102. */
  103. public function arguments() {
  104. return $this->query->arguments();
  105. }
  106. /**
  107. * {@inheritdoc}
  108. */
  109. public function where($snippet, $args = []) {
  110. $this->query->where($snippet, $args);
  111. return $this;
  112. }
  113. /**
  114. * {@inheritdoc}
  115. */
  116. public function compile(Connection $connection, PlaceholderInterface $queryPlaceholder) {
  117. return $this->query->compile($connection, $queryPlaceholder);
  118. }
  119. /**
  120. * {@inheritdoc}
  121. */
  122. public function compiled() {
  123. return $this->query->compiled();
  124. }
  125. /**
  126. * {@inheritdoc}
  127. */
  128. public function havingCondition($field, $value = NULL, $operator = '=') {
  129. $this->query->havingCondition($field, $value, $operator);
  130. return $this;
  131. }
  132. /**
  133. * {@inheritdoc}
  134. */
  135. public function &havingConditions() {
  136. return $this->query->havingConditions();
  137. }
  138. /**
  139. * {@inheritdoc}
  140. */
  141. public function havingArguments() {
  142. return $this->query->havingArguments();
  143. }
  144. /**
  145. * {@inheritdoc}
  146. */
  147. public function having($snippet, $args = []) {
  148. $this->query->having($snippet, $args);
  149. return $this;
  150. }
  151. /**
  152. * {@inheritdoc}
  153. */
  154. public function havingCompile(Connection $connection) {
  155. return $this->query->havingCompile($connection);
  156. }
  157. /**
  158. * {@inheritdoc}
  159. */
  160. public function havingIsNull($field) {
  161. $this->query->havingIsNull($field);
  162. return $this;
  163. }
  164. /**
  165. * {@inheritdoc}
  166. */
  167. public function havingIsNotNull($field) {
  168. $this->query->havingIsNotNull($field);
  169. return $this;
  170. }
  171. /**
  172. * {@inheritdoc}
  173. */
  174. public function havingExists(SelectInterface $select) {
  175. $this->query->havingExists($select);
  176. return $this;
  177. }
  178. /**
  179. * {@inheritdoc}
  180. */
  181. public function havingNotExists(SelectInterface $select) {
  182. $this->query->havingNotExists($select);
  183. return $this;
  184. }
  185. /**
  186. * {@inheritdoc}
  187. */
  188. public function extend($extender_name) {
  189. $class = $this->connection->getDriverClass($extender_name);
  190. return new $class($this, $this->connection);
  191. }
  192. /* Alter accessors to expose the query data to alter hooks. */
  193. /**
  194. * {@inheritdoc}
  195. */
  196. public function &getFields() {
  197. return $this->query->getFields();
  198. }
  199. /**
  200. * {@inheritdoc}
  201. */
  202. public function &getExpressions() {
  203. return $this->query->getExpressions();
  204. }
  205. /**
  206. * {@inheritdoc}
  207. */
  208. public function &getOrderBy() {
  209. return $this->query->getOrderBy();
  210. }
  211. /**
  212. * {@inheritdoc}
  213. */
  214. public function &getGroupBy() {
  215. return $this->query->getGroupBy();
  216. }
  217. /**
  218. * {@inheritdoc}
  219. */
  220. public function &getTables() {
  221. return $this->query->getTables();
  222. }
  223. /**
  224. * {@inheritdoc}
  225. */
  226. public function &getUnion() {
  227. return $this->query->getUnion();
  228. }
  229. /**
  230. * {@inheritdoc}
  231. */
  232. public function escapeLike($string) {
  233. return $this->query->escapeLike($string);
  234. }
  235. /**
  236. * {@inheritdoc}
  237. */
  238. public function escapeField($string) {
  239. $this->query->escapeField($string);
  240. return $this;
  241. }
  242. /**
  243. * {@inheritdoc}
  244. */
  245. public function getArguments(PlaceholderInterface $queryPlaceholder = NULL) {
  246. return $this->query->getArguments($queryPlaceholder);
  247. }
  248. /**
  249. * {@inheritdoc}
  250. */
  251. public function isPrepared() {
  252. return $this->query->isPrepared();
  253. }
  254. /**
  255. * {@inheritdoc}
  256. */
  257. public function preExecute(SelectInterface $query = NULL) {
  258. // If no query object is passed in, use $this.
  259. if (!isset($query)) {
  260. $query = $this;
  261. }
  262. return $this->query->preExecute($query);
  263. }
  264. /**
  265. * {@inheritdoc}
  266. */
  267. public function execute() {
  268. // By calling preExecute() here, we force it to preprocess the extender
  269. // object rather than just the base query object. That means
  270. // hook_query_alter() gets access to the extended object.
  271. if (!$this->preExecute($this)) {
  272. return NULL;
  273. }
  274. return $this->query->execute();
  275. }
  276. /**
  277. * {@inheritdoc}
  278. */
  279. public function distinct($distinct = TRUE) {
  280. $this->query->distinct($distinct);
  281. return $this;
  282. }
  283. /**
  284. * {@inheritdoc}
  285. */
  286. public function addField($table_alias, $field, $alias = NULL) {
  287. return $this->query->addField($table_alias, $field, $alias);
  288. }
  289. /**
  290. * {@inheritdoc}
  291. */
  292. public function fields($table_alias, array $fields = []) {
  293. $this->query->fields($table_alias, $fields);
  294. return $this;
  295. }
  296. /**
  297. * {@inheritdoc}
  298. */
  299. public function addExpression($expression, $alias = NULL, $arguments = []) {
  300. return $this->query->addExpression($expression, $alias, $arguments);
  301. }
  302. /**
  303. * {@inheritdoc}
  304. */
  305. public function join($table, $alias = NULL, $condition = NULL, $arguments = []) {
  306. return $this->query->join($table, $alias, $condition, $arguments);
  307. }
  308. /**
  309. * {@inheritdoc}
  310. */
  311. public function innerJoin($table, $alias = NULL, $condition = NULL, $arguments = []) {
  312. return $this->query->innerJoin($table, $alias, $condition, $arguments);
  313. }
  314. /**
  315. * {@inheritdoc}
  316. */
  317. public function leftJoin($table, $alias = NULL, $condition = NULL, $arguments = []) {
  318. return $this->query->leftJoin($table, $alias, $condition, $arguments);
  319. }
  320. /**
  321. * {@inheritdoc}
  322. */
  323. public function rightJoin($table, $alias = NULL, $condition = NULL, $arguments = []) {
  324. return $this->query->rightJoin($table, $alias, $condition, $arguments);
  325. }
  326. /**
  327. * {@inheritdoc}
  328. */
  329. public function addJoin($type, $table, $alias = NULL, $condition = NULL, $arguments = []) {
  330. return $this->query->addJoin($type, $table, $alias, $condition, $arguments);
  331. }
  332. /**
  333. * {@inheritdoc}
  334. */
  335. public function orderBy($field, $direction = 'ASC') {
  336. $this->query->orderBy($field, $direction);
  337. return $this;
  338. }
  339. /**
  340. * {@inheritdoc}
  341. */
  342. public function orderRandom() {
  343. $this->query->orderRandom();
  344. return $this;
  345. }
  346. /**
  347. * {@inheritdoc}
  348. */
  349. public function range($start = NULL, $length = NULL) {
  350. $this->query->range($start, $length);
  351. return $this;
  352. }
  353. /**
  354. * {@inheritdoc}
  355. */
  356. public function union(SelectInterface $query, $type = '') {
  357. $this->query->union($query, $type);
  358. return $this;
  359. }
  360. /**
  361. * {@inheritdoc}
  362. */
  363. public function groupBy($field) {
  364. $this->query->groupBy($field);
  365. return $this;
  366. }
  367. /**
  368. * {@inheritdoc}
  369. */
  370. public function forUpdate($set = TRUE) {
  371. $this->query->forUpdate($set);
  372. return $this;
  373. }
  374. /**
  375. * {@inheritdoc}
  376. */
  377. public function countQuery() {
  378. return $this->query->countQuery();
  379. }
  380. /**
  381. * {@inheritdoc}
  382. */
  383. public function isNull($field) {
  384. $this->query->isNull($field);
  385. return $this;
  386. }
  387. /**
  388. * {@inheritdoc}
  389. */
  390. public function isNotNull($field) {
  391. $this->query->isNotNull($field);
  392. return $this;
  393. }
  394. /**
  395. * {@inheritdoc}
  396. */
  397. public function exists(SelectInterface $select) {
  398. $this->query->exists($select);
  399. return $this;
  400. }
  401. /**
  402. * {@inheritdoc}
  403. */
  404. public function notExists(SelectInterface $select) {
  405. $this->query->notExists($select);
  406. return $this;
  407. }
  408. /**
  409. * {@inheritdoc}
  410. */
  411. public function alwaysFalse() {
  412. $this->query->alwaysFalse();
  413. return $this;
  414. }
  415. /**
  416. * {@inheritdoc}
  417. */
  418. public function __toString() {
  419. return (string) $this->query;
  420. }
  421. /**
  422. * {@inheritdoc}
  423. */
  424. public function __clone() {
  425. $this->uniqueIdentifier = uniqid('', TRUE);
  426. // We need to deep-clone the query we're wrapping, which in turn may
  427. // deep-clone other objects. Exciting!
  428. $this->query = clone($this->query);
  429. }
  430. /**
  431. * Magic override for undefined methods.
  432. *
  433. * If one extender extends another extender, then methods in the inner extender
  434. * will not be exposed on the outer extender. That's because we cannot know
  435. * in advance what those methods will be, so we cannot provide wrapping
  436. * implementations as we do above. Instead, we use this slower catch-all method
  437. * to handle any additional methods.
  438. */
  439. public function __call($method, $args) {
  440. $return = call_user_func_array([$this->query, $method], $args);
  441. // Some methods will return the called object as part of a fluent interface.
  442. // Others will return some useful value. If it's a value, then the caller
  443. // probably wants that value. If it's the called object, then we instead
  444. // return this object. That way we don't "lose" an extender layer when
  445. // chaining methods together.
  446. if ($return instanceof SelectInterface) {
  447. return $this;
  448. }
  449. else {
  450. return $return;
  451. }
  452. }
  453. /**
  454. * {@inheritdoc}
  455. */
  456. public function conditionGroupFactory($conjunction = 'AND') {
  457. return new Condition($conjunction);
  458. }
  459. /**
  460. * {@inheritdoc}
  461. */
  462. public function andConditionGroup() {
  463. return $this->conditionGroupFactory('AND');
  464. }
  465. /**
  466. * {@inheritdoc}
  467. */
  468. public function orConditionGroup() {
  469. return $this->conditionGroupFactory('OR');
  470. }
  471. }