5 * Contains install and update functions for Views.
9 * Implements hook_install().
11 function views_install() {
12 module_set_weight('views', 10);
16 * Update views field plugins.
18 function views_update_8001(&$sandbox) {
19 $config_factory = \Drupal::configFactory();
32 foreach ($config_factory->listAll('views.view.') as $view_config_name) {
33 $view = $config_factory->getEditable($view_config_name);
35 $displays = $view->get('display');
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');
43 // Grab the settings we need to move to a different place in the
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'] : '';
49 // Save off the base part of the config path we are updating.
50 $base = "display.$display_name.display_options.fields.$field_name";
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');
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;
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);
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);
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);
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);
84 // Update the field to use the Field API formatter.
85 $view->set($base . '.plugin_id', 'field');
86 $view->set($base . '.type', 'timestamp');
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);
95 // Remove the old settings.
96 $view->clear($base . '.date_format');
97 $view->clear($base . '.custom_date_format');
98 $view->clear($base . '.timezone');
108 $message = \Drupal::translation()->translate('Updated field plugins for views: @ids', ['@ids' => implode(', ', array_unique($ids))]);
115 * Updates %1 and !1 tokens to argument tokens.
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);
122 $displays = $view->get('display');
123 $argument_map_per_display = _views_update_argument_map($displays);
127 // Update all the field settings, which support tokens.
128 foreach ($displays as $display_name => &$display) {
129 if (!empty($display['display_options']['fields'])) {
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]);
156 $field['alter'][$token_name] = _views_update_8002_token_update($field['alter'][$token_name], $argument_map_per_display[$display_name]);
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']) {
173 $area['title'] = _views_update_8002_token_update($area['title'], $argument_map_per_display[$display_name]);
177 $area['content'] = _views_update_8002_token_update($area['content'], $argument_map_per_display[$display_name]);
181 $area['content']['value'] = _views_update_8002_token_update($area['content']['value'], $argument_map_per_display[$display_name]);
185 $area['content'] = _views_update_8002_token_update($area['content'], $argument_map_per_display[$display_name]);
189 $area['target'] = _views_update_8002_token_update($area['target'], $argument_map_per_display[$display_name]);
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]);
206 if (isset($argument['title'])) {
207 $argument['title'] = _views_update_8002_token_update($argument['title'], $argument_map_per_display[$display_name]);
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]);
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]);
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]);
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]);
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]);
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]);
251 $view->set('display', $displays);
258 * Updates a views configuration string from using %/! to twig tokens.
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.
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]]} }}";
273 $text = preg_replace_callback('/!(\d)/', function ($match) use ($argument_map) {
274 return "{{ raw_arguments.{$argument_map[$match[1]]} }}";
281 * Builds an argument map for each Views display.
283 * @param array $displays
284 * A list of Views displays.
287 * The argument map keyed by display id.
289 function _views_update_argument_map($displays) {
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;
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;
305 return $argument_map;
309 * Clear caches to fix entity operations field.
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
318 * Clear caches due to updated entity views data.
320 function views_update_8004() {
321 // Empty update to cause a cache flush so that views data is rebuilt.
325 * Clear views data cache.
327 function views_update_8005() {
328 // Empty update function to rebuild the views data.
332 * Clear caches due to updated entity views data.
334 function views_update_8100() {
335 // Empty update to cause a cache flush so that views data is rebuilt.
339 * Set default values for enabled/expanded flag on page displays.
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);
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);
361 * Rebuild the container to add a new container parameter.
363 function views_update_8200() {
364 // Empty update to cause a cache rebuild so that the container is rebuilt.
368 * Rebuild cache to refresh the views config schema.
370 function views_update_8201() {
371 // Empty update to cause a cache rebuild so that config schema get refreshed.