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