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