Chris@0: listAll('views.view.') as $view_config_name) { Chris@0: $view = $config_factory->getEditable($view_config_name); Chris@0: Chris@0: $displays = $view->get('display'); Chris@0: Chris@0: foreach ($displays as $display_name => $display) { Chris@0: if (!empty($display['display_options']['fields'])) { Chris@0: foreach ($display['display_options']['fields'] as $field_name => $field) { Chris@0: if (isset($field['entity_type']) && $field['plugin_id'] === 'date') { Chris@0: $ids[] = $view->get('id'); Chris@0: Chris@0: // Grab the settings we need to move to a different place in the Chris@0: // config schema. Chris@0: $date_format = !empty($field['date_format']) ? $field['date_format'] : 'medium'; Chris@0: $custom_date_format = !empty($field['custom_date_format']) ? $field['custom_date_format'] : ''; Chris@0: $timezone = !empty($field['timezone']) ? $field['timezone'] : ''; Chris@0: Chris@0: // Save off the base part of the config path we are updating. Chris@0: $base = "display.$display_name.display_options.fields.$field_name"; Chris@0: Chris@0: if (in_array($date_format, $ago_formats)) { Chris@0: // Update the field to use the Field API formatter. Chris@0: $view->set($base . '.plugin_id', 'field'); Chris@0: $view->set($base . '.type', 'timestamp_ago'); Chris@0: Chris@0: // Ensure the granularity is an integer, which is defined in the Chris@0: // field.formatter.settings.timestamp_ago schema. Chris@0: $granularity = is_numeric($custom_date_format) ? (int) $custom_date_format : 2; Chris@0: Chris@0: // Add the new settings. Chris@0: if ($date_format === 'time ago' || $date_format === 'time hence' || $date_format === 'time span') { Chris@0: $view->set($base . '.settings.future_format', '@interval hence'); Chris@0: $view->set($base . '.settings.past_format', '@interval ago'); Chris@0: $view->set($base . '.settings.granularity', $granularity); Chris@0: } Chris@0: elseif ($date_format === 'raw time ago' || $date_format === 'raw time hence') { Chris@0: $view->set($base . '.settings.future_format', '@interval'); Chris@0: $view->set($base . '.settings.past_format', '@interval'); Chris@0: $view->set($base . '.settings.granularity', $granularity); Chris@0: } Chris@0: elseif ($date_format === 'raw time span') { Chris@0: $view->set($base . '.settings.future_format', '@interval'); Chris@0: $view->set($base . '.settings.past_format', '-@interval'); Chris@0: $view->set($base . '.settings.granularity', $granularity); Chris@0: } Chris@0: elseif ($date_format === 'inverse time span') { Chris@0: $view->set($base . '.settings.future_format', '-@interval'); Chris@0: $view->set($base . '.settings.past_format', '@interval'); Chris@0: $view->set($base . '.settings.granularity', $granularity); Chris@0: } Chris@0: } Chris@0: else { Chris@0: // Update the field to use the Field API formatter. Chris@0: $view->set($base . '.plugin_id', 'field'); Chris@0: $view->set($base . '.type', 'timestamp'); Chris@0: Chris@0: // Add the new settings, and make sure everything is a string Chris@0: // to conform with the field.formatter.settings.timestamp schema. Chris@0: $view->set($base . '.settings.date_format', (string) $date_format); Chris@0: $view->set($base . '.settings.custom_date_format', (string) $custom_date_format); Chris@0: $view->set($base . '.settings.timezone', (string) $timezone); Chris@0: } Chris@0: Chris@0: // Remove the old settings. Chris@0: $view->clear($base . '.date_format'); Chris@0: $view->clear($base . '.custom_date_format'); Chris@0: $view->clear($base . '.timezone'); Chris@0: } Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: $view->save(TRUE); Chris@0: } Chris@0: Chris@0: if (!empty($ids)) { Chris@0: $message = \Drupal::translation()->translate('Updated field plugins for views: @ids', ['@ids' => implode(', ', array_unique($ids))]); Chris@0: } Chris@0: Chris@0: return $message; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Updates %1 and !1 tokens to argument tokens. Chris@0: */ Chris@0: function views_update_8002() { Chris@0: $config_factory = \Drupal::configFactory(); Chris@0: foreach ($config_factory->listAll('views.view.') as $view_config_name) { Chris@0: $view = $config_factory->getEditable($view_config_name); Chris@0: Chris@0: $displays = $view->get('display'); Chris@0: $argument_map_per_display = _views_update_argument_map($displays); Chris@0: Chris@0: $changed = FALSE; Chris@0: Chris@0: // Update all the field settings, which support tokens. Chris@0: foreach ($displays as $display_name => &$display) { Chris@0: if (!empty($display['display_options']['fields'])) { Chris@0: $token_values = [ Chris@0: 'path', Chris@0: 'alt', Chris@0: 'link_class', Chris@0: 'rel', Chris@0: 'target', Chris@0: 'query', Chris@0: 'fragment', Chris@0: 'prefix', Chris@0: 'suffix', Chris@0: 'more_link_text', Chris@0: 'more_link_path', Chris@0: 'link_attributes', Chris@0: 'text', Chris@0: ]; Chris@0: Chris@0: foreach ($display['display_options']['fields'] as $field_name => &$field) { Chris@0: foreach ($token_values as $token_name) { Chris@0: if (!empty($field['alter'][$token_name])) { Chris@0: if (is_array($field['alter'][$token_name])) { Chris@0: foreach (array_keys($field['alter'][$token_name]) as $key) { Chris@0: $field['alter'][$token_name][$key] = _views_update_8002_token_update($field['alter'][$token_name][$key], $argument_map_per_display[$display_name]); Chris@0: $changed = TRUE; Chris@0: } Chris@0: } Chris@0: else { Chris@0: $field['alter'][$token_name] = _views_update_8002_token_update($field['alter'][$token_name], $argument_map_per_display[$display_name]); Chris@0: $changed = TRUE; Chris@0: } Chris@0: } Chris@0: } Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: // Update the area handlers with tokens. Chris@0: foreach ($displays as $display_name => &$display) { Chris@0: $area_types = ['header', 'footer', 'empty']; Chris@0: foreach ($area_types as $area_type) { Chris@0: if (!empty($display['display_options'][$area_type])) { Chris@0: foreach ($display['display_options'][$area_type] as &$area) { Chris@0: switch ($area['plugin_id']) { Chris@0: case 'title': Chris@0: $area['title'] = _views_update_8002_token_update($area['title'], $argument_map_per_display[$display_name]); Chris@0: $changed = TRUE; Chris@0: break; Chris@0: case 'result': Chris@0: $area['content'] = _views_update_8002_token_update($area['content'], $argument_map_per_display[$display_name]); Chris@0: $changed = TRUE; Chris@0: break; Chris@0: case 'text': Chris@0: $area['content']['value'] = _views_update_8002_token_update($area['content']['value'], $argument_map_per_display[$display_name]); Chris@0: $changed = TRUE; Chris@0: break; Chris@0: case 'text_custom': Chris@0: $area['content'] = _views_update_8002_token_update($area['content'], $argument_map_per_display[$display_name]); Chris@0: $changed = TRUE; Chris@0: break; Chris@0: case 'entity': Chris@0: $area['target'] = _views_update_8002_token_update($area['target'], $argument_map_per_display[$display_name]); Chris@0: $changed = TRUE; Chris@0: break; Chris@0: } Chris@0: } Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: // Update the argument title settings. Chris@0: foreach ($displays as $display_name => &$display) { Chris@0: if (!empty($display['display_options']['arguments'])) { Chris@0: foreach ($display['display_options']['arguments'] as &$argument) { Chris@0: if (isset($argument['exception']['title'])) { Chris@0: $argument['exception']['title'] = _views_update_8002_token_update($argument['exception']['title'], $argument_map_per_display[$display_name]); Chris@0: $changed = TRUE; Chris@0: } Chris@0: if (isset($argument['title'])) { Chris@0: $argument['title'] = _views_update_8002_token_update($argument['title'], $argument_map_per_display[$display_name]); Chris@0: $changed = TRUE; Chris@0: } Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: // Update the display title settings. Chris@0: // Update the more link text and more link URL. Chris@0: foreach ($displays as $display_name => &$display) { Chris@0: if (!empty($display['display_options']['title'])) { Chris@0: $display['display_options']['title'] = _views_update_8002_token_update($display['display_options']['title'], $argument_map_per_display[$display_name]); Chris@0: $changed = TRUE; Chris@0: } Chris@0: if (!empty($display['display_options']['use_more_text'])) { Chris@0: $display['display_options']['use_more_text'] = _views_update_8002_token_update($display['display_options']['use_more_text'], $argument_map_per_display[$display_name]); Chris@0: $changed = TRUE; Chris@0: } Chris@0: if (!empty($display['display_options']['link_url'])) { Chris@0: $display['display_options']['link_url'] = _views_update_8002_token_update($display['display_options']['link_url'], $argument_map_per_display[$display_name]); Chris@0: $changed = TRUE; Chris@0: } Chris@0: } Chris@0: Chris@0: // Update custom classes for row class + grid classes. Chris@0: // Update RSS description field. Chris@0: foreach ($displays as $display_name => &$display) { Chris@0: if (!empty($display['display_options']['style'])) { Chris@0: if (!empty($display['display_options']['style']['options']['row_class_custom'])) { Chris@0: $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]); Chris@0: $changed = TRUE; Chris@0: } Chris@0: if (!empty($display['display_options']['style']['options']['col_class_custom'])) { Chris@0: $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]); Chris@0: $changed = TRUE; Chris@0: } Chris@0: if (!empty($display['display_options']['style']['options']['description'])) { Chris@0: $display['display_options']['style']['options']['description'] = _views_update_8002_token_update($display['display_options']['style']['options']['description'], $argument_map_per_display[$display_name]); Chris@0: $changed = TRUE; Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: if ($changed) { Chris@0: $view->set('display', $displays); Chris@0: $view->save(TRUE); Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Updates a views configuration string from using %/! to twig tokens. Chris@0: * Chris@0: * @param string $text Chris@0: * Text in which to search for argument tokens and replace them with their Chris@0: * twig representation. Chris@0: * @param array $argument_map Chris@0: * A map of argument machine names keyed by their previous index. Chris@0: * Chris@0: * @return string Chris@0: * The updated token. Chris@0: */ Chris@0: function _views_update_8002_token_update($text, array $argument_map) { Chris@0: $text = preg_replace_callback('/%(\d)/', function ($match) use ($argument_map) { Chris@0: return "{{ arguments.{$argument_map[$match[1]]} }}"; Chris@0: }, $text); Chris@0: $text = preg_replace_callback('/!(\d)/', function ($match) use ($argument_map) { Chris@0: return "{{ raw_arguments.{$argument_map[$match[1]]} }}"; Chris@0: }, $text); Chris@0: Chris@0: return $text; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Builds an argument map for each Views display. Chris@0: * Chris@0: * @param array $displays Chris@0: * A list of Views displays. Chris@0: * Chris@0: * @return array Chris@0: * The argument map keyed by display id. Chris@0: */ Chris@0: function _views_update_argument_map($displays) { Chris@0: $argument_map = []; Chris@0: foreach ($displays as $display_id => $display) { Chris@0: $argument_map[$display_id] = []; Chris@0: if (isset($display['display_options']['arguments'])) { Chris@0: foreach (array_keys($display['display_options']['arguments']) as $number => $name) { Chris@0: $argument_map[$display_id][$number + 1] = $name; Chris@0: } Chris@0: } Chris@0: elseif (isset($displays['default']['display_options']['arguments'])) { Chris@0: foreach (array_keys($displays['default']['display_options']['arguments']) as $number => $name) { Chris@0: $argument_map[$display_id][$number + 1] = $name; Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: return $argument_map; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Clear caches to fix entity operations field. Chris@0: */ Chris@0: function views_update_8003() { Chris@0: // Empty update to cause a cache flush so that views data is rebuilt. Entity Chris@0: // types that don't implement a list builder cannot have the entity operations Chris@0: // field. Chris@0: } Chris@0: Chris@0: /** Chris@0: * Clear caches due to updated entity views data. Chris@0: */ Chris@0: function views_update_8004() { Chris@0: // Empty update to cause a cache flush so that views data is rebuilt. Chris@0: } Chris@0: Chris@0: /** Chris@0: * Clear views data cache. Chris@0: */ Chris@0: function views_update_8005() { Chris@0: // Empty update function to rebuild the views data. Chris@0: } Chris@0: Chris@0: /** Chris@0: * Clear caches due to updated entity views data. Chris@0: */ Chris@0: function views_update_8100() { Chris@0: // Empty update to cause a cache flush so that views data is rebuilt. Chris@0: } Chris@0: Chris@0: /** Chris@0: * Set default values for enabled/expanded flag on page displays. Chris@0: */ Chris@0: function views_update_8101() { Chris@0: $config_factory = \Drupal::configFactory(); Chris@0: foreach ($config_factory->listAll('views.view.') as $view_config_name) { Chris@0: $view = $config_factory->getEditable($view_config_name); Chris@0: $save = FALSE; Chris@0: foreach ($view->get('display') as $display_id => $display) { Chris@0: if ($display['display_plugin'] == 'page') { Chris@0: $display['display_options']['menu']['enabled'] = TRUE; Chris@0: $display['display_options']['menu']['expanded'] = FALSE; Chris@0: $view->set("display.$display_id", $display); Chris@0: $save = TRUE; Chris@0: } Chris@0: } Chris@0: if ($save) { Chris@0: $view->save(); Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Rebuild the container to add a new container parameter. Chris@0: */ Chris@0: function views_update_8200() { Chris@0: // Empty update to cause a cache rebuild so that the container is rebuilt. Chris@0: } Chris@0: Chris@0: /** Chris@0: * Rebuild cache to refresh the views config schema. Chris@0: */ Chris@0: function views_update_8201() { Chris@0: // Empty update to cause a cache rebuild so that config schema get refreshed. Chris@0: }