35453c1172dd991b4ce5d15386e96ef668519ac2
[yaffs-website] / web / core / modules / views / src / Plugin / views / query / QueryPluginBase.php
1 <?php
2
3 namespace Drupal\views\Plugin\views\query;
4
5 use Drupal\Core\Cache\Cache;
6 use Drupal\Core\Cache\CacheableDependencyInterface;
7 use Drupal\Core\Form\FormStateInterface;
8 use Drupal\views\Plugin\views\PluginBase;
9 use Drupal\views\ViewExecutable;
10 use Drupal\views\Views;
11
12 /**
13  * @defgroup views_query_plugins Views query plugins
14  * @{
15  * Plugins for views queries.
16  *
17  * Query plugins generate and execute a built query object against a
18  * particular storage backend, converting the Views query object into an
19  * actual query. Although query plugins need not necessarily use SQL, most
20  * other handler plugins that affect the query (fields, filters, etc.)
21  * implicitly assume that the query is using SQL.
22  *
23  * Query plugins extend \Drupal\views\Plugin\views\query\QueryPluginBase.
24  * They must be annotated with \Drupal\views\Annotation\ViewsQuery
25  * annotation, and they must be in namespace directory Plugin\views\query.
26  *
27  * @ingroup views_plugins
28  * @see plugin_api
29  */
30
31 /**
32  * Base plugin class for Views queries.
33  */
34 abstract class QueryPluginBase extends PluginBase implements CacheableDependencyInterface {
35
36   /**
37    * A pager plugin that should be provided by the display.
38    *
39    * @var views_plugin_pager
40    */
41   public $pager = NULL;
42
43   /**
44    * Stores the limit of items that should be requested in the query.
45    *
46    * @var int
47    */
48   protected $limit;
49
50   /**
51    * Generate a query and a countquery from all of the information supplied
52    * to the object.
53    *
54    * @param $get_count
55    *   Provide a countquery if this is true, otherwise provide a normal query.
56    */
57   public function query($get_count = FALSE) {}
58
59   /**
60    * Let modules modify the query just prior to finalizing it.
61    *
62    * @param view $view
63    *   The view which is executed.
64    */
65   public function alter(ViewExecutable $view) {}
66
67   /**
68    * Builds the necessary info to execute the query.
69    *
70    * @param view $view
71    *   The view which is executed.
72    */
73   public function build(ViewExecutable $view) {}
74
75   /**
76    * Executes the query and fills the associated view object with according
77    * values.
78    *
79    * Values to set: $view->result, $view->total_rows, $view->execute_time,
80    * $view->pager['current_page'].
81    *
82    * $view->result should contain an array of objects. The array must use a
83    * numeric index starting at 0.
84    *
85    * @param view $view
86    *   The view which is executed.
87    */
88   public function execute(ViewExecutable $view) {}
89
90   /**
91    * Add a signature to the query, if such a thing is feasible.
92    *
93    * This signature is something that can be used when perusing query logs to
94    * discern where particular queries might be coming from.
95    *
96    * @param view $view
97    *   The view which is executed.
98    */
99   public function addSignature(ViewExecutable $view) {}
100
101   /**
102    * Get aggregation info for group by queries.
103    *
104    * If NULL, aggregation is not allowed.
105    */
106   public function getAggregationInfo() {}
107
108   public function validateOptionsForm(&$form, FormStateInterface $form_state) {}
109
110   public function submitOptionsForm(&$form, FormStateInterface $form_state) {}
111
112   public function summaryTitle() {
113     return $this->t('Settings');
114   }
115
116   /**
117    * {@inheritdoc}
118    */
119   public function calculateDependencies() {
120     $dependencies = [];
121
122     foreach ($this->getEntityTableInfo() as $entity_type => $info) {
123       if (!empty($info['provider'])) {
124         $dependencies['module'][] = $info['provider'];
125       }
126     }
127
128     return $dependencies;
129   }
130
131   /**
132    * Set a LIMIT on the query, specifying a maximum number of results.
133    */
134   public function setLimit($limit) {
135     $this->limit = $limit;
136   }
137
138   /**
139    * Set an OFFSET on the query, specifying a number of results to skip
140    */
141   public function setOffset($offset) {
142     $this->offset = $offset;
143   }
144
145   /**
146    * Returns the limit of the query.
147    */
148   public function getLimit() {
149     return $this->limit;
150   }
151
152   /**
153    * Create a new grouping for the WHERE or HAVING clause.
154    *
155    * @param $type
156    *   Either 'AND' or 'OR'. All items within this group will be added
157    *   to the WHERE clause with this logical operator.
158    * @param $group
159    *   An ID to use for this group. If unspecified, an ID will be generated.
160    * @param $where
161    *   'where' or 'having'.
162    *
163    * @return
164    *   The group ID generated.
165    */
166   public function setWhereGroup($type = 'AND', $group = NULL, $where = 'where') {
167     // Set an alias.
168     $groups = &$this->$where;
169
170     if (!isset($group)) {
171       $group = empty($groups) ? 1 : max(array_keys($groups)) + 1;
172     }
173
174     // Create an empty group
175     if (empty($groups[$group])) {
176       $groups[$group] = ['conditions' => [], 'args' => []];
177     }
178
179     $groups[$group]['type'] = strtoupper($type);
180     return $group;
181   }
182
183   /**
184    * Control how all WHERE and HAVING groups are put together.
185    *
186    * @param $type
187    *   Either 'AND' or 'OR'
188    */
189   public function setGroupOperator($type = 'AND') {
190     $this->groupOperator = strtoupper($type);
191   }
192
193   /**
194    * Loads all entities contained in the passed-in $results.
195    *.
196    * If the entity belongs to the base table, then it gets stored in
197    * $result->_entity. Otherwise, it gets stored in
198    * $result->_relationship_entities[$relationship_id];
199    *
200    * Query plugins that don't support entities can leave the method empty.
201    */
202   public function loadEntities(&$results) {}
203
204   /**
205    * Returns a Unix timestamp to database native timestamp expression.
206    *
207    * @param string $field
208    *   The query field that will be used in the expression.
209    *
210    * @return string
211    *   An expression representing a timestamp with time zone.
212    */
213   public function getDateField($field) {
214     return $field;
215   }
216
217   /**
218    * Set the database to the current user timezone,
219    *
220    * @return string
221    *   The current timezone as returned by drupal_get_user_timezone().
222    */
223   public function setupTimezone() {
224     return drupal_get_user_timezone();
225   }
226
227   /**
228    * Creates cross-database date formatting.
229    *
230    * @param string $field
231    *   An appropriate query expression pointing to the date field.
232    * @param string $format
233    *   A format string for the result, like 'Y-m-d H:i:s'.
234    * @param bool $string_date
235    *   For certain databases, date format functions vary depending on string or
236    *   numeric storage.
237    *
238    * @return string
239    *   A string representing the field formatted as a date in the format
240    *   specified by $format.
241    */
242   public function getDateFormat($field, $format, $string_date = FALSE) {
243     return $field;
244   }
245
246   /**
247    * Returns an array of all tables from the query that map to an entity type.
248    *
249    * Includes the base table and all relationships, if eligible.
250    *
251    * Available keys for each table:
252    * - base: The actual base table (i.e. "user" for an author relationship).
253    * - relationship_id: The id of the relationship, or "none".
254    * - alias: The alias used for the relationship.
255    * - entity_type: The entity type matching the base table.
256    * - revision: A boolean that specifies whether the table is a base table or
257    *   a revision table of the entity type.
258    *
259    * @return array
260    *   An array of table information, keyed by table alias.
261    */
262   public function getEntityTableInfo() {
263     // Start with the base table.
264     $entity_tables = [];
265     $views_data = Views::viewsData();
266     $base_table = $this->view->storage->get('base_table');
267     $base_table_data = $views_data->get($base_table);
268
269     if (isset($base_table_data['table']['entity type'])) {
270       $entity_tables[$base_table_data['table']['entity type']] = [
271         'base' => $base_table,
272         'alias' => $base_table,
273         'relationship_id' => 'none',
274         'entity_type' => $base_table_data['table']['entity type'],
275         'revision' => $base_table_data['table']['entity revision'],
276       ];
277
278       // Include the entity provider.
279       if (!empty($base_table_data['table']['provider'])) {
280         $entity_tables[$base_table_data['table']['entity type']]['provider'] = $base_table_data['table']['provider'];
281       }
282     }
283
284     // Include all relationships.
285     foreach ((array) $this->view->relationship as $relationship_id => $relationship) {
286       $table_data = $views_data->get($relationship->definition['base']);
287       if (isset($table_data['table']['entity type'])) {
288
289         // If this is not one of the entity base tables, skip it.
290         $entity_type = \Drupal::entityTypeManager()->getDefinition($table_data['table']['entity type']);
291         $entity_base_tables = [$entity_type->getBaseTable(), $entity_type->getDataTable(), $entity_type->getRevisionTable(), $entity_type->getRevisionDataTable()];
292         if (!in_array($relationship->definition['base'], $entity_base_tables)) {
293           continue;
294         }
295
296         $entity_tables[$relationship_id . '__' . $relationship->tableAlias] = [
297           'base' => $relationship->definition['base'],
298           'relationship_id' => $relationship_id,
299           'alias' => $relationship->alias,
300           'entity_type' => $table_data['table']['entity type'],
301           'revision' => $table_data['table']['entity revision'],
302         ];
303
304         // Include the entity provider.
305         if (!empty($table_data['table']['provider'])) {
306           $entity_tables[$relationship_id . '__' . $relationship->tableAlias]['provider'] = $table_data['table']['provider'];
307         }
308       }
309     }
310
311     // Determine which of the tables are revision tables.
312     foreach ($entity_tables as $table_alias => $table) {
313       $entity_type = \Drupal::entityManager()->getDefinition($table['entity_type']);
314       if ($entity_type->getRevisionTable() == $table['base']) {
315         $entity_tables[$table_alias]['revision'] = TRUE;
316       }
317     }
318
319     return $entity_tables;
320   }
321
322   /**
323    * {@inheritdoc}
324    */
325   public function getCacheMaxAge() {
326     return Cache::PERMANENT;
327   }
328
329   /**
330    * {@inheritdoc}
331    */
332   public function getCacheContexts() {
333     $contexts = [];
334     if (($views_data = Views::viewsData()->get($this->view->storage->get('base_table'))) && !empty($views_data['table']['entity type'])) {
335       $entity_type_id = $views_data['table']['entity type'];
336       $entity_type = \Drupal::entityManager()->getDefinition($entity_type_id);
337       $contexts = $entity_type->getListCacheContexts();
338     }
339     return $contexts;
340   }
341
342   /**
343    * {@inheritdoc}
344    */
345   public function getCacheTags() {
346     return [];
347   }
348
349 }
350
351 /**
352  * @}
353  */