Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / web / core / lib / Drupal / Core / Entity / Query / Sql / QueryAggregate.php
1 <?php
2
3 namespace Drupal\Core\Entity\Query\Sql;
4
5 use Drupal\Core\Entity\Query\QueryAggregateInterface;
6
7 /**
8  * The SQL storage entity query aggregate class.
9  */
10 class QueryAggregate extends Query implements QueryAggregateInterface {
11
12   /**
13    * Stores the sql expressions used to build the sql query.
14    *
15    * @var array
16    *   An array of expressions.
17    */
18   protected $sqlExpressions = [];
19
20   /**
21    * {@inheritdoc}
22    */
23   public function execute() {
24     return $this
25       ->prepare()
26       ->addAggregate()
27       ->compile()
28       ->compileAggregate()
29       ->addGroupBy()
30       ->addSort()
31       ->addSortAggregate()
32       ->finish()
33       ->result();
34   }
35
36   /**
37    * {@inheritdoc}
38    */
39   public function prepare() {
40     parent::prepare();
41     // Throw away the id fields.
42     $this->sqlFields = [];
43     return $this;
44   }
45
46   /**
47    * {@inheritdoc}
48    */
49   public function conditionAggregateGroupFactory($conjunction = 'AND') {
50     $class = static::getClass($this->namespaces, 'ConditionAggregate');
51     return new $class($conjunction, $this, $this->namespaces);
52   }
53
54   /**
55    * {@inheritdoc}
56    */
57   public function existsAggregate($field, $function, $langcode = NULL) {
58     return $this->conditionAggregate->exists($field, $function, $langcode);
59   }
60
61   /**
62    * {@inheritdoc}
63    */
64   public function notExistsAggregate($field, $function, $langcode = NULL) {
65     return $this->conditionAggregate->notExists($field, $function, $langcode);
66   }
67
68
69   /**
70    * Adds the aggregations to the query.
71    *
72    * @return \Drupal\Core\Entity\Query\Sql\QueryAggregate
73    *   Returns the called object.
74    */
75   protected function addAggregate() {
76     if ($this->aggregate) {
77       foreach ($this->aggregate as $aggregate) {
78         $sql_field = $this->getSqlField($aggregate['field'], $aggregate['langcode']);
79         $this->sqlExpressions[$aggregate['alias']] = $aggregate['function'] . "($sql_field)";
80       }
81     }
82     return $this;
83   }
84
85   /**
86    * Builds the aggregation conditions part of the query.
87    *
88    * @return \Drupal\Core\Entity\Query\Sql\QueryAggregate
89    *   Returns the called object.
90    */
91   protected function compileAggregate() {
92     $this->conditionAggregate->compile($this->sqlQuery);
93     return $this;
94   }
95
96   /**
97    * Adds the groupby values to the actual query.
98    *
99    * @return \Drupal\Core\Entity\Query\Sql\QueryAggregate
100    *   Returns the called object.
101    */
102   protected function addGroupBy() {
103     foreach ($this->groupBy as $group_by) {
104       $field = $group_by['field'];
105       $sql_field = $this->getSqlField($field, $group_by['langcode']);
106       $this->sqlGroupBy[$sql_field] = $sql_field;
107       list($table, $real_sql_field) = explode('.', $sql_field);
108       $this->sqlFields[$sql_field] = [$table, $real_sql_field, $this->createSqlAlias($field, $real_sql_field)];
109     }
110
111     return $this;
112   }
113
114   /**
115    * Builds the aggregation sort part of the query.
116    *
117    * @return \Drupal\Core\Entity\Query\Sql\QueryAggregate
118    *   Returns the called object.
119    */
120   protected function addSortAggregate() {
121     if (!$this->count) {
122       foreach ($this->sortAggregate as $alias => $sort) {
123         $this->sqlQuery->orderBy($alias, $sort['direction']);
124       }
125     }
126     return $this;
127   }
128
129
130   /**
131    * Overrides \Drupal\Core\Entity\Query\Sql\Query::finish().
132    *
133    * Adds the sql expressions to the query.
134    */
135   protected function finish() {
136     foreach ($this->sqlExpressions as $alias => $expression) {
137       $this->sqlQuery->addExpression($expression, $alias);
138     }
139     return parent::finish();
140   }
141
142   /**
143    * Builds a sql alias as expected in the result.
144    *
145    * @param string $field
146    *   The field as passed in by the caller.
147    * @param string $sql_field
148    *   The sql field as returned by getSqlField.
149    * @return string
150    *   The SQL alias expected in the return value. The dots in $sql_field are
151    *   replaced with underscores and if a default fallback to .value happened,
152    *   the _value is stripped.
153    */
154   public function createSqlAlias($field, $sql_field) {
155     $alias = str_replace('.', '_', $sql_field);
156     // If the alias contains of field_*_value remove the _value at the end.
157     if (substr($alias, 0, 6) === 'field_' && substr($field, -6) !== '_value' && substr($alias, -6) === '_value') {
158       $alias = substr($alias, 0, -6);
159     }
160     return $alias;
161   }
162
163   /**
164    * Overrides \Drupal\Core\Entity\Query\Sql\Query::result().
165    *
166    * @return array|int
167    *   Returns the aggregated result, or a number if it's a count query.
168    */
169   protected function result() {
170     if ($this->count) {
171       return parent::result();
172     }
173     $return = [];
174     foreach ($this->sqlQuery->execute() as $row) {
175       $return[] = (array) $row;
176     }
177     return $return;
178   }
179
180 }