annotate core/modules/views/views.install @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 /**
Chris@0 4 * @file
Chris@0 5 * Contains install and update functions for Views.
Chris@0 6 */
Chris@0 7
Chris@14 8 use Drupal\Core\Config\Schema\ArrayElement;
Chris@14 9 use Drupal\views\Views;
Chris@14 10
Chris@0 11 /**
Chris@0 12 * Implements hook_install().
Chris@0 13 */
Chris@0 14 function views_install() {
Chris@0 15 module_set_weight('views', 10);
Chris@0 16 }
Chris@0 17
Chris@0 18 /**
Chris@0 19 * Update views field plugins.
Chris@0 20 */
Chris@0 21 function views_update_8001(&$sandbox) {
Chris@0 22 $config_factory = \Drupal::configFactory();
Chris@0 23 $ids = [];
Chris@0 24 $message = NULL;
Chris@0 25 $ago_formats = [
Chris@0 26 'time ago',
Chris@0 27 'time hence',
Chris@0 28 'time span',
Chris@0 29 'raw time ago',
Chris@0 30 'raw time hence',
Chris@0 31 'raw time span',
Chris@0 32 'inverse time span',
Chris@0 33 ];
Chris@0 34
Chris@0 35 foreach ($config_factory->listAll('views.view.') as $view_config_name) {
Chris@0 36 $view = $config_factory->getEditable($view_config_name);
Chris@0 37
Chris@0 38 $displays = $view->get('display');
Chris@0 39
Chris@0 40 foreach ($displays as $display_name => $display) {
Chris@0 41 if (!empty($display['display_options']['fields'])) {
Chris@0 42 foreach ($display['display_options']['fields'] as $field_name => $field) {
Chris@0 43 if (isset($field['entity_type']) && $field['plugin_id'] === 'date') {
Chris@0 44 $ids[] = $view->get('id');
Chris@0 45
Chris@0 46 // Grab the settings we need to move to a different place in the
Chris@0 47 // config schema.
Chris@0 48 $date_format = !empty($field['date_format']) ? $field['date_format'] : 'medium';
Chris@0 49 $custom_date_format = !empty($field['custom_date_format']) ? $field['custom_date_format'] : '';
Chris@0 50 $timezone = !empty($field['timezone']) ? $field['timezone'] : '';
Chris@0 51
Chris@0 52 // Save off the base part of the config path we are updating.
Chris@0 53 $base = "display.$display_name.display_options.fields.$field_name";
Chris@0 54
Chris@0 55 if (in_array($date_format, $ago_formats)) {
Chris@0 56 // Update the field to use the Field API formatter.
Chris@0 57 $view->set($base . '.plugin_id', 'field');
Chris@0 58 $view->set($base . '.type', 'timestamp_ago');
Chris@0 59
Chris@0 60 // Ensure the granularity is an integer, which is defined in the
Chris@0 61 // field.formatter.settings.timestamp_ago schema.
Chris@0 62 $granularity = is_numeric($custom_date_format) ? (int) $custom_date_format : 2;
Chris@0 63
Chris@0 64 // Add the new settings.
Chris@0 65 if ($date_format === 'time ago' || $date_format === 'time hence' || $date_format === 'time span') {
Chris@0 66 $view->set($base . '.settings.future_format', '@interval hence');
Chris@0 67 $view->set($base . '.settings.past_format', '@interval ago');
Chris@0 68 $view->set($base . '.settings.granularity', $granularity);
Chris@0 69 }
Chris@0 70 elseif ($date_format === 'raw time ago' || $date_format === 'raw time hence') {
Chris@0 71 $view->set($base . '.settings.future_format', '@interval');
Chris@0 72 $view->set($base . '.settings.past_format', '@interval');
Chris@0 73 $view->set($base . '.settings.granularity', $granularity);
Chris@0 74 }
Chris@0 75 elseif ($date_format === 'raw time span') {
Chris@0 76 $view->set($base . '.settings.future_format', '@interval');
Chris@0 77 $view->set($base . '.settings.past_format', '-@interval');
Chris@0 78 $view->set($base . '.settings.granularity', $granularity);
Chris@0 79 }
Chris@0 80 elseif ($date_format === 'inverse time span') {
Chris@0 81 $view->set($base . '.settings.future_format', '-@interval');
Chris@0 82 $view->set($base . '.settings.past_format', '@interval');
Chris@0 83 $view->set($base . '.settings.granularity', $granularity);
Chris@0 84 }
Chris@0 85 }
Chris@0 86 else {
Chris@0 87 // Update the field to use the Field API formatter.
Chris@0 88 $view->set($base . '.plugin_id', 'field');
Chris@0 89 $view->set($base . '.type', 'timestamp');
Chris@0 90
Chris@0 91 // Add the new settings, and make sure everything is a string
Chris@0 92 // to conform with the field.formatter.settings.timestamp schema.
Chris@0 93 $view->set($base . '.settings.date_format', (string) $date_format);
Chris@0 94 $view->set($base . '.settings.custom_date_format', (string) $custom_date_format);
Chris@0 95 $view->set($base . '.settings.timezone', (string) $timezone);
Chris@0 96 }
Chris@0 97
Chris@0 98 // Remove the old settings.
Chris@0 99 $view->clear($base . '.date_format');
Chris@0 100 $view->clear($base . '.custom_date_format');
Chris@0 101 $view->clear($base . '.timezone');
Chris@0 102 }
Chris@0 103 }
Chris@0 104 }
Chris@0 105 }
Chris@0 106
Chris@0 107 $view->save(TRUE);
Chris@0 108 }
Chris@0 109
Chris@0 110 if (!empty($ids)) {
Chris@0 111 $message = \Drupal::translation()->translate('Updated field plugins for views: @ids', ['@ids' => implode(', ', array_unique($ids))]);
Chris@0 112 }
Chris@0 113
Chris@0 114 return $message;
Chris@0 115 }
Chris@0 116
Chris@0 117 /**
Chris@0 118 * Updates %1 and !1 tokens to argument tokens.
Chris@0 119 */
Chris@0 120 function views_update_8002() {
Chris@0 121 $config_factory = \Drupal::configFactory();
Chris@0 122 foreach ($config_factory->listAll('views.view.') as $view_config_name) {
Chris@0 123 $view = $config_factory->getEditable($view_config_name);
Chris@0 124
Chris@0 125 $displays = $view->get('display');
Chris@0 126 $argument_map_per_display = _views_update_argument_map($displays);
Chris@0 127
Chris@0 128 $changed = FALSE;
Chris@0 129
Chris@0 130 // Update all the field settings, which support tokens.
Chris@0 131 foreach ($displays as $display_name => &$display) {
Chris@0 132 if (!empty($display['display_options']['fields'])) {
Chris@0 133 $token_values = [
Chris@0 134 'path',
Chris@0 135 'alt',
Chris@0 136 'link_class',
Chris@0 137 'rel',
Chris@0 138 'target',
Chris@0 139 'query',
Chris@0 140 'fragment',
Chris@0 141 'prefix',
Chris@0 142 'suffix',
Chris@0 143 'more_link_text',
Chris@0 144 'more_link_path',
Chris@0 145 'link_attributes',
Chris@0 146 'text',
Chris@0 147 ];
Chris@0 148
Chris@0 149 foreach ($display['display_options']['fields'] as $field_name => &$field) {
Chris@0 150 foreach ($token_values as $token_name) {
Chris@0 151 if (!empty($field['alter'][$token_name])) {
Chris@0 152 if (is_array($field['alter'][$token_name])) {
Chris@0 153 foreach (array_keys($field['alter'][$token_name]) as $key) {
Chris@0 154 $field['alter'][$token_name][$key] = _views_update_8002_token_update($field['alter'][$token_name][$key], $argument_map_per_display[$display_name]);
Chris@0 155 $changed = TRUE;
Chris@0 156 }
Chris@0 157 }
Chris@0 158 else {
Chris@0 159 $field['alter'][$token_name] = _views_update_8002_token_update($field['alter'][$token_name], $argument_map_per_display[$display_name]);
Chris@0 160 $changed = TRUE;
Chris@0 161 }
Chris@0 162 }
Chris@0 163 }
Chris@0 164 }
Chris@0 165 }
Chris@0 166 }
Chris@0 167
Chris@0 168 // Update the area handlers with tokens.
Chris@0 169 foreach ($displays as $display_name => &$display) {
Chris@0 170 $area_types = ['header', 'footer', 'empty'];
Chris@0 171 foreach ($area_types as $area_type) {
Chris@0 172 if (!empty($display['display_options'][$area_type])) {
Chris@0 173 foreach ($display['display_options'][$area_type] as &$area) {
Chris@0 174 switch ($area['plugin_id']) {
Chris@0 175 case 'title':
Chris@0 176 $area['title'] = _views_update_8002_token_update($area['title'], $argument_map_per_display[$display_name]);
Chris@0 177 $changed = TRUE;
Chris@0 178 break;
Chris@0 179 case 'result':
Chris@0 180 $area['content'] = _views_update_8002_token_update($area['content'], $argument_map_per_display[$display_name]);
Chris@0 181 $changed = TRUE;
Chris@0 182 break;
Chris@0 183 case 'text':
Chris@0 184 $area['content']['value'] = _views_update_8002_token_update($area['content']['value'], $argument_map_per_display[$display_name]);
Chris@0 185 $changed = TRUE;
Chris@0 186 break;
Chris@0 187 case 'text_custom':
Chris@0 188 $area['content'] = _views_update_8002_token_update($area['content'], $argument_map_per_display[$display_name]);
Chris@0 189 $changed = TRUE;
Chris@0 190 break;
Chris@0 191 case 'entity':
Chris@0 192 $area['target'] = _views_update_8002_token_update($area['target'], $argument_map_per_display[$display_name]);
Chris@0 193 $changed = TRUE;
Chris@0 194 break;
Chris@0 195 }
Chris@0 196 }
Chris@0 197 }
Chris@0 198 }
Chris@0 199 }
Chris@0 200
Chris@0 201 // Update the argument title settings.
Chris@0 202 foreach ($displays as $display_name => &$display) {
Chris@0 203 if (!empty($display['display_options']['arguments'])) {
Chris@0 204 foreach ($display['display_options']['arguments'] as &$argument) {
Chris@0 205 if (isset($argument['exception']['title'])) {
Chris@0 206 $argument['exception']['title'] = _views_update_8002_token_update($argument['exception']['title'], $argument_map_per_display[$display_name]);
Chris@0 207 $changed = TRUE;
Chris@0 208 }
Chris@0 209 if (isset($argument['title'])) {
Chris@0 210 $argument['title'] = _views_update_8002_token_update($argument['title'], $argument_map_per_display[$display_name]);
Chris@0 211 $changed = TRUE;
Chris@0 212 }
Chris@0 213 }
Chris@0 214 }
Chris@0 215 }
Chris@0 216
Chris@0 217 // Update the display title settings.
Chris@0 218 // Update the more link text and more link URL.
Chris@0 219 foreach ($displays as $display_name => &$display) {
Chris@0 220 if (!empty($display['display_options']['title'])) {
Chris@0 221 $display['display_options']['title'] = _views_update_8002_token_update($display['display_options']['title'], $argument_map_per_display[$display_name]);
Chris@0 222 $changed = TRUE;
Chris@0 223 }
Chris@0 224 if (!empty($display['display_options']['use_more_text'])) {
Chris@0 225 $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 226 $changed = TRUE;
Chris@0 227 }
Chris@0 228 if (!empty($display['display_options']['link_url'])) {
Chris@0 229 $display['display_options']['link_url'] = _views_update_8002_token_update($display['display_options']['link_url'], $argument_map_per_display[$display_name]);
Chris@0 230 $changed = TRUE;
Chris@0 231 }
Chris@0 232 }
Chris@0 233
Chris@0 234 // Update custom classes for row class + grid classes.
Chris@0 235 // Update RSS description field.
Chris@0 236 foreach ($displays as $display_name => &$display) {
Chris@0 237 if (!empty($display['display_options']['style'])) {
Chris@0 238 if (!empty($display['display_options']['style']['options']['row_class_custom'])) {
Chris@0 239 $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 240 $changed = TRUE;
Chris@0 241 }
Chris@0 242 if (!empty($display['display_options']['style']['options']['col_class_custom'])) {
Chris@0 243 $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 244 $changed = TRUE;
Chris@0 245 }
Chris@0 246 if (!empty($display['display_options']['style']['options']['description'])) {
Chris@0 247 $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 248 $changed = TRUE;
Chris@0 249 }
Chris@0 250 }
Chris@0 251 }
Chris@0 252
Chris@0 253 if ($changed) {
Chris@0 254 $view->set('display', $displays);
Chris@0 255 $view->save(TRUE);
Chris@0 256 }
Chris@0 257 }
Chris@0 258 }
Chris@0 259
Chris@0 260 /**
Chris@0 261 * Updates a views configuration string from using %/! to twig tokens.
Chris@0 262 *
Chris@0 263 * @param string $text
Chris@0 264 * Text in which to search for argument tokens and replace them with their
Chris@0 265 * twig representation.
Chris@0 266 * @param array $argument_map
Chris@0 267 * A map of argument machine names keyed by their previous index.
Chris@0 268 *
Chris@0 269 * @return string
Chris@0 270 * The updated token.
Chris@0 271 */
Chris@0 272 function _views_update_8002_token_update($text, array $argument_map) {
Chris@0 273 $text = preg_replace_callback('/%(\d)/', function ($match) use ($argument_map) {
Chris@0 274 return "{{ arguments.{$argument_map[$match[1]]} }}";
Chris@0 275 }, $text);
Chris@0 276 $text = preg_replace_callback('/!(\d)/', function ($match) use ($argument_map) {
Chris@0 277 return "{{ raw_arguments.{$argument_map[$match[1]]} }}";
Chris@0 278 }, $text);
Chris@0 279
Chris@0 280 return $text;
Chris@0 281 }
Chris@0 282
Chris@0 283 /**
Chris@0 284 * Builds an argument map for each Views display.
Chris@0 285 *
Chris@0 286 * @param array $displays
Chris@0 287 * A list of Views displays.
Chris@0 288 *
Chris@0 289 * @return array
Chris@0 290 * The argument map keyed by display id.
Chris@0 291 */
Chris@0 292 function _views_update_argument_map($displays) {
Chris@0 293 $argument_map = [];
Chris@0 294 foreach ($displays as $display_id => $display) {
Chris@0 295 $argument_map[$display_id] = [];
Chris@0 296 if (isset($display['display_options']['arguments'])) {
Chris@0 297 foreach (array_keys($display['display_options']['arguments']) as $number => $name) {
Chris@0 298 $argument_map[$display_id][$number + 1] = $name;
Chris@0 299 }
Chris@0 300 }
Chris@0 301 elseif (isset($displays['default']['display_options']['arguments'])) {
Chris@0 302 foreach (array_keys($displays['default']['display_options']['arguments']) as $number => $name) {
Chris@0 303 $argument_map[$display_id][$number + 1] = $name;
Chris@0 304 }
Chris@0 305 }
Chris@0 306 }
Chris@0 307
Chris@0 308 return $argument_map;
Chris@0 309 }
Chris@0 310
Chris@0 311 /**
Chris@0 312 * Clear caches to fix entity operations field.
Chris@0 313 */
Chris@0 314 function views_update_8003() {
Chris@0 315 // Empty update to cause a cache flush so that views data is rebuilt. Entity
Chris@0 316 // types that don't implement a list builder cannot have the entity operations
Chris@0 317 // field.
Chris@17 318
Chris@17 319 // Use hook_post_update_NAME() instead to clear the cache.The use
Chris@17 320 // of hook_update_N to clear the cache has been deprecated see
Chris@17 321 // https://www.drupal.org/node/2960601 for more details.
Chris@0 322 }
Chris@0 323
Chris@0 324 /**
Chris@0 325 * Clear caches due to updated entity views data.
Chris@0 326 */
Chris@0 327 function views_update_8004() {
Chris@0 328 // Empty update to cause a cache flush so that views data is rebuilt.
Chris@17 329
Chris@17 330 // Use hook_post_update_NAME() instead to clear the cache.The use
Chris@17 331 // of hook_update_N to clear the cache has been deprecated see
Chris@17 332 // https://www.drupal.org/node/2960601 for more details.
Chris@0 333 }
Chris@0 334
Chris@0 335 /**
Chris@0 336 * Clear views data cache.
Chris@0 337 */
Chris@0 338 function views_update_8005() {
Chris@0 339 // Empty update function to rebuild the views data.
Chris@17 340
Chris@17 341 // Use hook_post_update_NAME() instead to clear the cache.The use
Chris@17 342 // of hook_update_N to clear the cache has been deprecated see
Chris@17 343 // https://www.drupal.org/node/2960601 for more details.
Chris@0 344 }
Chris@0 345
Chris@0 346 /**
Chris@0 347 * Clear caches due to updated entity views data.
Chris@0 348 */
Chris@0 349 function views_update_8100() {
Chris@0 350 // Empty update to cause a cache flush so that views data is rebuilt.
Chris@17 351
Chris@17 352 // Use hook_post_update_NAME() instead to clear the cache.The use
Chris@17 353 // of hook_update_N to clear the cache has been deprecated see
Chris@17 354 // https://www.drupal.org/node/2960601 for more details.
Chris@0 355 }
Chris@0 356
Chris@0 357 /**
Chris@0 358 * Set default values for enabled/expanded flag on page displays.
Chris@0 359 */
Chris@0 360 function views_update_8101() {
Chris@0 361 $config_factory = \Drupal::configFactory();
Chris@0 362 foreach ($config_factory->listAll('views.view.') as $view_config_name) {
Chris@0 363 $view = $config_factory->getEditable($view_config_name);
Chris@0 364 $save = FALSE;
Chris@0 365 foreach ($view->get('display') as $display_id => $display) {
Chris@0 366 if ($display['display_plugin'] == 'page') {
Chris@0 367 $display['display_options']['menu']['enabled'] = TRUE;
Chris@0 368 $display['display_options']['menu']['expanded'] = FALSE;
Chris@0 369 $view->set("display.$display_id", $display);
Chris@0 370 $save = TRUE;
Chris@0 371 }
Chris@0 372 }
Chris@0 373 if ($save) {
Chris@0 374 $view->save();
Chris@0 375 }
Chris@0 376 }
Chris@0 377 }
Chris@0 378
Chris@0 379 /**
Chris@0 380 * Rebuild the container to add a new container parameter.
Chris@0 381 */
Chris@0 382 function views_update_8200() {
Chris@0 383 // Empty update to cause a cache rebuild so that the container is rebuilt.
Chris@17 384
Chris@17 385 // Use hook_post_update_NAME() instead to clear the cache.The use
Chris@17 386 // of hook_update_N to clear the cache has been deprecated see
Chris@17 387 // https://www.drupal.org/node/2960601 for more details.
Chris@0 388 }
Chris@0 389
Chris@0 390 /**
Chris@0 391 * Rebuild cache to refresh the views config schema.
Chris@0 392 */
Chris@0 393 function views_update_8201() {
Chris@0 394 // Empty update to cause a cache rebuild so that config schema get refreshed.
Chris@17 395
Chris@17 396 // Use hook_post_update_NAME() instead to clear the cache.The use
Chris@17 397 // of hook_update_N to clear the cache has been deprecated see
Chris@17 398 // https://www.drupal.org/node/2960601 for more details.
Chris@0 399 }
Chris@14 400
Chris@14 401 /**
Chris@14 402 * Update field names for multi-value base fields.
Chris@14 403 */
Chris@14 404 function views_update_8500() {
Chris@14 405 // Find all multi-value base fields for content entities.
Chris@14 406 $entity_type_manager = \Drupal::entityTypeManager();
Chris@14 407 $entity_field_manager = \Drupal::service('entity_field.manager');
Chris@14 408 $table_update_info = [];
Chris@14 409
Chris@14 410 foreach ($entity_type_manager->getDefinitions() as $entity_type_id => $entity_type) {
Chris@14 411 if ($entity_type->hasHandlerClass('views_data')) {
Chris@14 412 $base_field_definitions = $entity_field_manager->getBaseFieldDefinitions($entity_type_id);
Chris@14 413
Chris@14 414 $entity_storage = $entity_type_manager->getStorage($entity_type_id);
Chris@14 415 $table_mapping = $entity_storage->getTableMapping($base_field_definitions);
Chris@14 416
Chris@14 417 foreach ($base_field_definitions as $field_name => $base_field_definition) {
Chris@14 418 $base_field_storage_definition = $base_field_definition->getFieldStorageDefinition();
Chris@14 419
Chris@14 420 // Skip single value and custom storage base fields.
Chris@14 421 if (!$base_field_storage_definition->isMultiple() || $base_field_storage_definition->hasCustomStorage()) {
Chris@14 422 continue;
Chris@14 423 }
Chris@14 424
Chris@14 425 // Get the actual table, as well as the column for the main property
Chris@14 426 // name so we can perform an update later on the views.
Chris@14 427 $table_name = $table_mapping->getFieldTableName($field_name);
Chris@14 428 $main_property_name = $base_field_storage_definition->getMainPropertyName();
Chris@14 429
Chris@14 430 $table_update_info[$table_name][$field_name] = $table_mapping->getFieldColumnName($base_field_storage_definition, $main_property_name);
Chris@14 431 }
Chris@14 432 }
Chris@14 433 }
Chris@14 434
Chris@14 435 if (empty($table_update_info)) {
Chris@14 436 return;
Chris@14 437 }
Chris@14 438
Chris@14 439 $config_factory = \Drupal::configFactory();
Chris@14 440 /** @var \Drupal\Core\Config\TypedConfigManagerInterface $typed_config_manager */
Chris@14 441 $typed_config_manager = \Drupal::service('config.typed');
Chris@14 442 $views_data = Views::viewsData();
Chris@14 443 $handler_types = ['field', 'argument', 'sort', 'relationship', 'filter'];
Chris@14 444
Chris@14 445 $required_cleanup_handlers = [];
Chris@14 446 foreach ($config_factory->listAll('views.view.') as $id) {
Chris@14 447 $view = $config_factory->getEditable($id);
Chris@14 448 $changed = FALSE;
Chris@14 449
Chris@14 450 foreach ($view->get('display') as $display_id => &$display) {
Chris@14 451 foreach ($handler_types as $handler_type_singular) {
Chris@14 452 $handler_type_plural = $handler_type_singular . 's';
Chris@14 453 $handler_data = $view->get("display.$display_id.display_options.$handler_type_plural");
Chris@14 454
Chris@14 455 if (empty($handler_data)) {
Chris@14 456 continue;
Chris@14 457 }
Chris@14 458
Chris@14 459 foreach ($handler_data as $key => $data) {
Chris@14 460 // If this handler has a table we're interested in, update the field
Chris@14 461 // name.
Chris@14 462 $table = $data['table'];
Chris@14 463 if (isset($table_update_info[$table])) {
Chris@14 464 $path_to_handler = "display.$display_id.display_options.$handler_type_plural.$key";
Chris@14 465 $path_field = "{$path_to_handler}.field";
Chris@14 466 $path_plugin_id = "{$path_to_handler}.plugin_id";
Chris@14 467 $original_field_name = $view->get($path_field);
Chris@14 468
Chris@14 469 // Only if the wrong field name is set do we change the field. It
Chris@14 470 // could already be using the correct field. Like
Chris@14 471 // user__roles/roles_target_id.
Chris@14 472 if (isset($table_update_info[$table][$original_field_name])) {
Chris@14 473 $required_cleanup_handlers[$id][] = $path_to_handler;
Chris@14 474
Chris@14 475 // Set both the new table field as well as new 'plugin_id' field.
Chris@14 476 $view->set($path_field, $table_update_info[$table][$original_field_name]);
Chris@14 477 $view->set($path_plugin_id, $views_data->get($table)[$table_update_info[$table][$original_field_name]][$handler_type_singular]['id']);
Chris@14 478
Chris@14 479 $changed = TRUE;
Chris@14 480 }
Chris@14 481 }
Chris@14 482 }
Chris@14 483 }
Chris@14 484 }
Chris@14 485
Chris@14 486 if ($changed) {
Chris@14 487 $view->save(TRUE);
Chris@14 488 }
Chris@14 489 }
Chris@14 490
Chris@14 491 // Beside of updating the field and plugin ID we also need to truncate orphan
Chris@14 492 // keys so he configuration applies to the config schema.
Chris@14 493 // We cannot do that inline in the other code, due to caching issues with
Chris@14 494 // typed configuration.
Chris@14 495 foreach ($required_cleanup_handlers as $id => $paths_to_handlers) {
Chris@14 496 $changed = FALSE;
Chris@14 497 $typed_view = $typed_config_manager->get($id);
Chris@14 498 $view = $config_factory->getEditable($id);
Chris@14 499 foreach ($paths_to_handlers as $path_to_handler) {
Chris@14 500 /** @var \Drupal\Core\Config\Schema\TypedConfigInterface $typed_view */
Chris@14 501
Chris@14 502 /** @var \Drupal\Core\Config\Schema\ArrayElement $typed_config */
Chris@14 503 $typed_config = $typed_view->get($path_to_handler);
Chris@14 504 $config = $typed_config->getValue();
Chris@14 505
Chris@14 506 // Filter values we want to convert from a string to an array.
Chris@14 507 if (strpos($path_to_handler, 'filters') !== FALSE && $typed_config->get('value') instanceof ArrayElement && is_string($config['value'])) {
Chris@14 508 // An empty string casted to an array is an array with one
Chris@14 509 // element.
Chris@14 510 if ($config['value'] === '') {
Chris@14 511 $config['value'] = [];
Chris@14 512 }
Chris@14 513 else {
Chris@14 514 $config['value'] = (array) $config['value'];
Chris@14 515 }
Chris@14 516 }
Chris@14 517
Chris@14 518 // For all the other fields we try to determine the fields using
Chris@14 519 // config schema and remove everything which is not needed.
Chris@14 520 foreach (array_keys($config) as $config_key) {
Chris@14 521 if (!isset($typed_config->getDataDefinition()['mapping'][$config_key])) {
Chris@14 522 unset($config[$config_key]);
Chris@14 523 $changed = TRUE;
Chris@14 524 }
Chris@14 525 }
Chris@14 526 $typed_config->setValue($config);
Chris@14 527 $view->set($path_to_handler, $typed_config->getValue());
Chris@14 528 }
Chris@14 529
Chris@14 530 if ($changed) {
Chris@14 531 $view->save();
Chris@14 532 }
Chris@14 533 }
Chris@14 534 }