Version 1
[yaffs-website] / web / core / modules / views / views.install
1 <?php
2
3 /**
4  * @file
5  * Contains install and update functions for Views.
6  */
7
8 /**
9  * Implements hook_install().
10  */
11 function views_install() {
12   module_set_weight('views', 10);
13 }
14
15 /**
16  * Update views field plugins.
17  */
18 function views_update_8001(&$sandbox) {
19   $config_factory = \Drupal::configFactory();
20   $ids = [];
21   $message = NULL;
22   $ago_formats = [
23     'time ago',
24     'time hence',
25     'time span',
26     'raw time ago',
27     'raw time hence',
28     'raw time span',
29     'inverse time span',
30   ];
31
32   foreach ($config_factory->listAll('views.view.') as $view_config_name) {
33     $view = $config_factory->getEditable($view_config_name);
34
35     $displays = $view->get('display');
36
37     foreach ($displays as $display_name => $display) {
38       if (!empty($display['display_options']['fields'])) {
39         foreach ($display['display_options']['fields'] as $field_name => $field) {
40           if (isset($field['entity_type']) && $field['plugin_id'] === 'date') {
41             $ids[] = $view->get('id');
42
43             // Grab the settings we need to move to a different place in the
44             // config schema.
45             $date_format = !empty($field['date_format']) ? $field['date_format'] : 'medium';
46             $custom_date_format = !empty($field['custom_date_format']) ? $field['custom_date_format'] : '';
47             $timezone = !empty($field['timezone']) ? $field['timezone'] : '';
48
49             // Save off the base part of the config path we are updating.
50             $base = "display.$display_name.display_options.fields.$field_name";
51
52             if (in_array($date_format, $ago_formats)) {
53               // Update the field to use the Field API formatter.
54               $view->set($base . '.plugin_id', 'field');
55               $view->set($base . '.type', 'timestamp_ago');
56
57               // Ensure the granularity is an integer, which is defined in the
58               // field.formatter.settings.timestamp_ago schema.
59               $granularity = is_numeric($custom_date_format) ? (int) $custom_date_format : 2;
60
61               // Add the new settings.
62               if ($date_format === 'time ago' || $date_format === 'time hence' || $date_format === 'time span') {
63                 $view->set($base . '.settings.future_format', '@interval hence');
64                 $view->set($base . '.settings.past_format', '@interval ago');
65                 $view->set($base . '.settings.granularity', $granularity);
66               }
67               elseif ($date_format === 'raw time ago' || $date_format === 'raw time hence') {
68                 $view->set($base . '.settings.future_format', '@interval');
69                 $view->set($base . '.settings.past_format', '@interval');
70                 $view->set($base . '.settings.granularity', $granularity);
71               }
72               elseif ($date_format === 'raw time span') {
73                 $view->set($base . '.settings.future_format', '@interval');
74                 $view->set($base . '.settings.past_format', '-@interval');
75                 $view->set($base . '.settings.granularity', $granularity);
76               }
77               elseif ($date_format === 'inverse time span') {
78                 $view->set($base . '.settings.future_format', '-@interval');
79                 $view->set($base . '.settings.past_format', '@interval');
80                 $view->set($base . '.settings.granularity', $granularity);
81               }
82             }
83             else {
84               // Update the field to use the Field API formatter.
85               $view->set($base . '.plugin_id', 'field');
86               $view->set($base . '.type', 'timestamp');
87
88               // Add the new settings, and make sure everything is a string
89               // to conform with the field.formatter.settings.timestamp schema.
90               $view->set($base . '.settings.date_format', (string) $date_format);
91               $view->set($base . '.settings.custom_date_format', (string) $custom_date_format);
92               $view->set($base . '.settings.timezone', (string) $timezone);
93             }
94
95             // Remove the old settings.
96             $view->clear($base . '.date_format');
97             $view->clear($base . '.custom_date_format');
98             $view->clear($base . '.timezone');
99           }
100         }
101       }
102     }
103
104     $view->save(TRUE);
105   }
106
107   if (!empty($ids)) {
108     $message = \Drupal::translation()->translate('Updated field plugins for views: @ids', ['@ids' => implode(', ', array_unique($ids))]);
109   }
110
111   return $message;
112 }
113
114 /**
115  * Updates %1 and !1 tokens to argument tokens.
116  */
117 function views_update_8002() {
118   $config_factory = \Drupal::configFactory();
119   foreach ($config_factory->listAll('views.view.') as $view_config_name) {
120     $view = $config_factory->getEditable($view_config_name);
121
122     $displays = $view->get('display');
123     $argument_map_per_display = _views_update_argument_map($displays);
124
125     $changed = FALSE;
126
127     // Update all the field settings, which support tokens.
128     foreach ($displays as $display_name => &$display) {
129       if (!empty($display['display_options']['fields'])) {
130         $token_values = [
131           'path',
132           'alt',
133           'link_class',
134           'rel',
135           'target',
136           'query',
137           'fragment',
138           'prefix',
139           'suffix',
140           'more_link_text',
141           'more_link_path',
142           'link_attributes',
143           'text',
144         ];
145
146         foreach ($display['display_options']['fields'] as $field_name => &$field) {
147           foreach ($token_values as $token_name) {
148             if (!empty($field['alter'][$token_name])) {
149               if (is_array($field['alter'][$token_name])) {
150                 foreach (array_keys($field['alter'][$token_name]) as $key) {
151                   $field['alter'][$token_name][$key] = _views_update_8002_token_update($field['alter'][$token_name][$key], $argument_map_per_display[$display_name]);
152                   $changed = TRUE;
153                 }
154               }
155               else {
156                 $field['alter'][$token_name] = _views_update_8002_token_update($field['alter'][$token_name], $argument_map_per_display[$display_name]);
157                 $changed = TRUE;
158               }
159             }
160           }
161         }
162       }
163     }
164
165     // Update the area handlers with tokens.
166     foreach ($displays as $display_name => &$display) {
167       $area_types = ['header', 'footer', 'empty'];
168       foreach ($area_types as $area_type) {
169         if (!empty($display['display_options'][$area_type])) {
170           foreach ($display['display_options'][$area_type] as &$area) {
171             switch ($area['plugin_id']) {
172               case 'title':
173                 $area['title'] = _views_update_8002_token_update($area['title'], $argument_map_per_display[$display_name]);
174                 $changed = TRUE;
175                 break;
176               case 'result':
177                 $area['content'] = _views_update_8002_token_update($area['content'], $argument_map_per_display[$display_name]);
178                 $changed = TRUE;
179                 break;
180               case 'text':
181                 $area['content']['value'] = _views_update_8002_token_update($area['content']['value'], $argument_map_per_display[$display_name]);
182                 $changed = TRUE;
183                 break;
184               case 'text_custom':
185                 $area['content'] = _views_update_8002_token_update($area['content'], $argument_map_per_display[$display_name]);
186                 $changed = TRUE;
187                 break;
188               case 'entity':
189                 $area['target'] = _views_update_8002_token_update($area['target'], $argument_map_per_display[$display_name]);
190                 $changed = TRUE;
191                 break;
192             }
193           }
194         }
195       }
196     }
197
198     // Update the argument title settings.
199     foreach ($displays as $display_name => &$display) {
200       if (!empty($display['display_options']['arguments'])) {
201         foreach ($display['display_options']['arguments'] as &$argument) {
202           if (isset($argument['exception']['title'])) {
203             $argument['exception']['title'] = _views_update_8002_token_update($argument['exception']['title'], $argument_map_per_display[$display_name]);
204             $changed = TRUE;
205           }
206           if (isset($argument['title'])) {
207             $argument['title'] = _views_update_8002_token_update($argument['title'], $argument_map_per_display[$display_name]);
208             $changed = TRUE;
209           }
210         }
211       }
212     }
213
214     // Update the display title settings.
215     // Update the more link text and more link URL.
216     foreach ($displays as $display_name => &$display) {
217       if (!empty($display['display_options']['title'])) {
218         $display['display_options']['title'] = _views_update_8002_token_update($display['display_options']['title'], $argument_map_per_display[$display_name]);
219         $changed = TRUE;
220       }
221       if (!empty($display['display_options']['use_more_text'])) {
222         $display['display_options']['use_more_text'] = _views_update_8002_token_update($display['display_options']['use_more_text'], $argument_map_per_display[$display_name]);
223         $changed = TRUE;
224       }
225       if (!empty($display['display_options']['link_url'])) {
226         $display['display_options']['link_url'] = _views_update_8002_token_update($display['display_options']['link_url'], $argument_map_per_display[$display_name]);
227         $changed = TRUE;
228       }
229     }
230
231     // Update custom classes for row class + grid classes.
232     // Update RSS description field.
233     foreach ($displays as $display_name => &$display) {
234       if (!empty($display['display_options']['style'])) {
235         if (!empty($display['display_options']['style']['options']['row_class_custom'])) {
236           $display['display_options']['style']['options']['row_class_custom'] = _views_update_8002_token_update($display['display_options']['style']['options']['row_class_custom'], $argument_map_per_display[$display_name]);
237           $changed = TRUE;
238         }
239         if (!empty($display['display_options']['style']['options']['col_class_custom'])) {
240           $display['display_options']['style']['options']['col_class_custom'] = _views_update_8002_token_update($display['display_options']['style']['options']['col_class_custom'], $argument_map_per_display[$display_name]);
241           $changed = TRUE;
242         }
243         if (!empty($display['display_options']['style']['options']['description'])) {
244           $display['display_options']['style']['options']['description'] = _views_update_8002_token_update($display['display_options']['style']['options']['description'], $argument_map_per_display[$display_name]);
245           $changed = TRUE;
246         }
247       }
248     }
249
250     if ($changed) {
251       $view->set('display', $displays);
252       $view->save(TRUE);
253     }
254   }
255 }
256
257 /**
258  * Updates a views configuration string from using %/! to twig tokens.
259  *
260  * @param string $text
261  *   Text in which to search for argument tokens and replace them with their
262  *   twig representation.
263  * @param array $argument_map
264  *   A map of argument machine names keyed by their previous index.
265  *
266  * @return string
267  *   The updated token.
268  */
269 function _views_update_8002_token_update($text, array $argument_map) {
270   $text = preg_replace_callback('/%(\d)/', function ($match) use ($argument_map) {
271     return "{{ arguments.{$argument_map[$match[1]]} }}";
272   }, $text);
273   $text = preg_replace_callback('/!(\d)/', function ($match) use ($argument_map) {
274     return "{{ raw_arguments.{$argument_map[$match[1]]} }}";
275   }, $text);
276
277   return $text;
278 }
279
280 /**
281  * Builds an argument map for each Views display.
282  *
283  * @param array $displays
284  *   A list of Views displays.
285  *
286  * @return array
287  *   The argument map keyed by display id.
288  */
289 function _views_update_argument_map($displays) {
290   $argument_map = [];
291   foreach ($displays as $display_id => $display) {
292     $argument_map[$display_id] = [];
293     if (isset($display['display_options']['arguments'])) {
294       foreach (array_keys($display['display_options']['arguments']) as $number => $name) {
295         $argument_map[$display_id][$number + 1] = $name;
296       }
297     }
298     elseif (isset($displays['default']['display_options']['arguments'])) {
299       foreach (array_keys($displays['default']['display_options']['arguments']) as $number => $name) {
300         $argument_map[$display_id][$number + 1] = $name;
301       }
302     }
303   }
304
305   return $argument_map;
306 }
307
308 /**
309  * Clear caches to fix entity operations field.
310  */
311 function views_update_8003() {
312   // Empty update to cause a cache flush so that views data is rebuilt. Entity
313   // types that don't implement a list builder cannot have the entity operations
314   // field.
315 }
316
317 /**
318  * Clear caches due to updated entity views data.
319  */
320 function views_update_8004() {
321   // Empty update to cause a cache flush so that views data is rebuilt.
322 }
323
324 /**
325  * Clear views data cache.
326  */
327 function views_update_8005() {
328   // Empty update function to rebuild the views data.
329 }
330
331 /**
332  * Clear caches due to updated entity views data.
333  */
334 function views_update_8100() {
335   // Empty update to cause a cache flush so that views data is rebuilt.
336 }
337
338 /**
339  * Set default values for enabled/expanded flag on page displays.
340  */
341 function views_update_8101() {
342   $config_factory = \Drupal::configFactory();
343   foreach ($config_factory->listAll('views.view.') as $view_config_name) {
344     $view = $config_factory->getEditable($view_config_name);
345     $save = FALSE;
346     foreach ($view->get('display') as $display_id => $display) {
347       if ($display['display_plugin'] == 'page') {
348         $display['display_options']['menu']['enabled'] = TRUE;
349         $display['display_options']['menu']['expanded'] = FALSE;
350         $view->set("display.$display_id", $display);
351         $save = TRUE;
352       }
353     }
354     if ($save) {
355       $view->save();
356     }
357   }
358 }
359
360 /**
361  * Rebuild the container to add a new container parameter.
362  */
363 function views_update_8200() {
364   // Empty update to cause a cache rebuild so that the container is rebuilt.
365 }
366
367 /**
368  * Rebuild cache to refresh the views config schema.
369  */
370 function views_update_8201() {
371   // Empty update to cause a cache rebuild so that config schema get refreshed.
372 }