Security update for Core, with self-updated composer
[yaffs-website] / web / core / modules / views / src / Plugin / views / join / Subquery.php
1 <?php
2
3 namespace Drupal\views\Plugin\views\join;
4
5 /**
6  * Join handler for relationships that join with a subquery as the left field.
7  *
8  * For example:
9  * @code
10  * LEFT JOIN node node_term_data ON ([YOUR SUBQUERY HERE]) = node_term_data.nid
11  * @endcode
12  *
13  * Join definition: same as \Drupal\views\Plugin\views\join\JoinPluginBase,
14  * except:
15  * - left_query: The subquery to use in the left side of the join clause.
16  *
17  * @ingroup views_join_handlers
18  * @ViewsJoin("subquery")
19  */
20 class Subquery extends JoinPluginBase {
21
22   /**
23    * Constructs a Subquery object.
24    */
25   public function __construct(array $configuration, $plugin_id, $plugin_definition) {
26     parent::__construct($configuration, $plugin_id, $plugin_definition);
27
28     $this->left_query = $this->configuration['left_query'];
29   }
30
31   /**
32    * Builds the SQL for the join this object represents.
33    *
34    * @param \Drupal\Core\Database\Query\SelectInterface $select_query
35    *   The select query object.
36    * @param string $table
37    *   The base table to join.
38    * @param \Drupal\views\Plugin\views\query\QueryPluginBase $view_query
39    *   The source views query.
40    */
41   public function buildJoin($select_query, $table, $view_query) {
42     if (empty($this->configuration['table formula'])) {
43       $right_table = "{" . $this->table . "}";
44     }
45     else {
46       $right_table = $this->configuration['table formula'];
47     }
48
49     // Add our join condition, using a subquery on the left instead of a field.
50     $condition = "($this->left_query) = $table[alias].$this->field";
51     $arguments = [];
52
53     // Tack on the extra.
54     // This is just copied verbatim from the parent class, which itself has a
55     //   bug: https://www.drupal.org/node/1118100.
56     if (isset($this->extra)) {
57       if (is_array($this->extra)) {
58         $extras = [];
59         foreach ($this->extra as $info) {
60           // Figure out the table name. Remember, only use aliases provided
61           // if at all possible.
62           $join_table = '';
63           if (!array_key_exists('table', $info)) {
64             $join_table = $table['alias'] . '.';
65           }
66           elseif (isset($info['table'])) {
67             $join_table = $info['table'] . '.';
68           }
69
70           $placeholder = ':views_join_condition_' . $select_query->nextPlaceholder();
71
72           if (is_array($info['value'])) {
73             $operator = !empty($info['operator']) ? $info['operator'] : 'IN';
74             // Transform from IN() notation to = notation if just one value.
75             if (count($info['value']) == 1) {
76               $info['value'] = array_shift($info['value']);
77               $operator = $operator == 'NOT IN' ? '!=' : '=';
78             }
79           }
80           else {
81             $operator = !empty($info['operator']) ? $info['operator'] : '=';
82           }
83
84           $extras[] = "$join_table$info[field] $operator $placeholder";
85           $arguments[$placeholder] = $info['value'];
86         }
87
88         if ($extras) {
89           if (count($extras) == 1) {
90             $condition .= ' AND ' . array_shift($extras);
91           }
92           else {
93             $condition .= ' AND (' . implode(' ' . $this->extraOperator . ' ', $extras) . ')';
94           }
95         }
96       }
97       elseif ($this->extra && is_string($this->extra)) {
98         $condition .= " AND ($this->extra)";
99       }
100     }
101
102     $select_query->addJoin($this->type, $right_table, $table['alias'], $condition, $arguments);
103   }
104
105 }