annotate core/modules/views/views.post_update.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents af1871eacc83
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 /**
Chris@0 4 * @file
Chris@0 5 * Post update functions for Views.
Chris@0 6 */
Chris@0 7
Chris@17 8 use Drupal\Core\Config\Entity\ConfigEntityUpdater;
Chris@0 9 use Drupal\Core\StringTranslation\TranslatableMarkup;
Chris@0 10 use Drupal\views\Entity\View;
Chris@14 11 use Drupal\views\Plugin\views\filter\NumericFilter;
Chris@14 12 use Drupal\views\Plugin\views\filter\StringFilter;
Chris@0 13 use Drupal\views\Views;
Chris@0 14
Chris@0 15 /**
Chris@0 16 * Update the cacheability metadata for all views.
Chris@0 17 */
Chris@0 18 function views_post_update_update_cacheability_metadata() {
Chris@0 19 // Load all views.
Chris@0 20 $views = \Drupal::entityManager()->getStorage('view')->loadMultiple();
Chris@0 21
Chris@0 22 /* @var \Drupal\views\Entity\View[] $views */
Chris@0 23 foreach ($views as $view) {
Chris@0 24 $displays = $view->get('display');
Chris@0 25 foreach (array_keys($displays) as $display_id) {
Chris@0 26 $display =& $view->getDisplay($display_id);
Chris@0 27 // Unset the cache_metadata key, so all cacheability metadata for the
Chris@0 28 // display is recalculated.
Chris@0 29 unset($display['cache_metadata']);
Chris@0 30 }
Chris@0 31 $view->save();
Chris@0 32 }
Chris@0 33
Chris@0 34 }
Chris@0 35
Chris@0 36 /**
Chris@0 37 * Update some views fields that were previously duplicated.
Chris@0 38 */
Chris@0 39 function views_post_update_cleanup_duplicate_views_data() {
Chris@0 40 $config_factory = \Drupal::configFactory();
Chris@0 41 $ids = [];
Chris@0 42 $message = NULL;
Chris@0 43 $data_tables = [];
Chris@0 44 $base_tables = [];
Chris@0 45 $revision_tables = [];
Chris@0 46 $entities_by_table = [];
Chris@0 47 $duplicate_fields = [];
Chris@0 48 $handler_types = Views::getHandlerTypes();
Chris@0 49
Chris@0 50 /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager */
Chris@0 51 $entity_type_manager = \Drupal::service('entity_type.manager');
Chris@0 52 // This will allow us to create an index of all entity types of the site.
Chris@0 53 foreach ($entity_type_manager->getDefinitions() as $entity_type_id => $entity_type) {
Chris@0 54 // Store the entity keyed by base table. If it has a data table, use that as
Chris@0 55 // well.
Chris@0 56 if ($data_table = $entity_type->getDataTable()) {
Chris@0 57 $entities_by_table[$data_table] = $entity_type;
Chris@0 58 }
Chris@0 59 if ($base_table = $entity_type->getBaseTable()) {
Chris@0 60 $entities_by_table[$base_table] = $entity_type;
Chris@0 61 }
Chris@0 62
Chris@0 63 // The following code basically contains the same kind of logic as
Chris@0 64 // \Drupal\Core\Entity\Sql\SqlContentEntityStorage::initTableLayout() to
Chris@0 65 // prefetch all tables (base, data, revision, and revision data).
Chris@0 66 $base_tables[$entity_type_id] = $entity_type->getBaseTable() ?: $entity_type->id();
Chris@0 67 $revisionable = $entity_type->isRevisionable();
Chris@0 68
Chris@0 69 $revision_table = '';
Chris@0 70 if ($revisionable) {
Chris@0 71 $revision_table = $entity_type->getRevisionTable() ?: $entity_type->id() . '_revision';
Chris@0 72 }
Chris@0 73 $revision_tables[$entity_type_id] = $revision_table;
Chris@0 74
Chris@0 75 $translatable = $entity_type->isTranslatable();
Chris@0 76 $data_table = '';
Chris@0 77 // For example the data table just exists, when the entity type is
Chris@0 78 // translatable.
Chris@0 79 if ($translatable) {
Chris@0 80 $data_table = $entity_type->getDataTable() ?: $entity_type->id() . '_field_data';
Chris@0 81 }
Chris@0 82 $data_tables[$entity_type_id] = $data_table;
Chris@0 83
Chris@0 84 $duplicate_fields[$entity_type_id] = array_intersect_key($entity_type->getKeys(), array_flip(['id', 'revision', 'bundle']));
Chris@0 85 }
Chris@0 86
Chris@0 87 foreach ($config_factory->listAll('views.view.') as $view_config_name) {
Chris@0 88 $changed = FALSE;
Chris@0 89 $view = $config_factory->getEditable($view_config_name);
Chris@0 90
Chris@0 91 $displays = $view->get('display');
Chris@0 92 if (isset($entities_by_table[$view->get('base_table')])) {
Chris@0 93 $entity_type = $entities_by_table[$view->get('base_table')];
Chris@0 94 $entity_type_id = $entity_type->id();
Chris@0 95 $data_table = $data_tables[$entity_type_id];
Chris@0 96 $base_table = $base_tables[$entity_type_id];
Chris@0 97 $revision_table = $revision_tables[$entity_type_id];
Chris@0 98
Chris@0 99 if ($data_table) {
Chris@0 100 foreach ($displays as $display_name => &$display) {
Chris@0 101 foreach ($handler_types as $handler_type) {
Chris@0 102 if (!empty($display['display_options'][$handler_type['plural']])) {
Chris@0 103 foreach ($display['display_options'][$handler_type['plural']] as $field_name => &$field) {
Chris@0 104 $table = $field['table'];
Chris@0 105 if (($table === $base_table || $table === $revision_table) && in_array($field_name, $duplicate_fields[$entity_type_id])) {
Chris@0 106 $field['table'] = $data_table;
Chris@0 107 $changed = TRUE;
Chris@0 108 }
Chris@0 109 }
Chris@0 110 }
Chris@0 111 }
Chris@0 112 }
Chris@0 113 }
Chris@0 114 }
Chris@0 115
Chris@0 116 if ($changed) {
Chris@0 117 $view->set('display', $displays);
Chris@0 118 $view->save();
Chris@0 119 $ids[] = $view->get('id');
Chris@0 120 }
Chris@0 121 }
Chris@0 122 if (!empty($ids)) {
Chris@0 123 $message = new TranslatableMarkup('Updated tables for field handlers for views: @ids', ['@ids' => implode(', ', array_unique($ids))]);
Chris@0 124 }
Chris@0 125
Chris@0 126 return $message;
Chris@0 127 }
Chris@0 128
Chris@0 129 /**
Chris@0 130 * Include field formatter dependencies in a view when the formatter is used.
Chris@0 131 */
Chris@0 132 function views_post_update_field_formatter_dependencies() {
Chris@0 133 $views = View::loadMultiple();
Chris@0 134 array_walk($views, function (View $view) {
Chris@0 135 $view->save();
Chris@0 136 });
Chris@0 137 }
Chris@0 138
Chris@0 139 /**
Chris@0 140 * Fix views with dependencies on taxonomy terms that don't exist.
Chris@0 141 */
Chris@0 142 function views_post_update_taxonomy_index_tid() {
Chris@0 143 $views = View::loadMultiple();
Chris@0 144 array_walk($views, function (View $view) {
Chris@0 145 $old_dependencies = $view->getDependencies();
Chris@0 146 $new_dependencies = $view->calculateDependencies()->getDependencies();
Chris@0 147 if ($old_dependencies !== $new_dependencies) {
Chris@0 148 $view->save();
Chris@0 149 }
Chris@0 150 });
Chris@0 151 }
Chris@0 152
Chris@0 153 /**
Chris@0 154 * Fix views with serializer dependencies.
Chris@0 155 */
Chris@0 156 function views_post_update_serializer_dependencies() {
Chris@0 157 $views = View::loadMultiple();
Chris@0 158 array_walk($views, function (View $view) {
Chris@0 159 $old_dependencies = $view->getDependencies();
Chris@0 160 $new_dependencies = $view->calculateDependencies()->getDependencies();
Chris@0 161 if ($old_dependencies !== $new_dependencies) {
Chris@0 162 $view->save();
Chris@0 163 }
Chris@0 164 });
Chris@0 165 }
Chris@0 166
Chris@0 167 /**
Chris@0 168 * Set all boolean filter values to strings.
Chris@0 169 */
Chris@0 170 function views_post_update_boolean_filter_values() {
Chris@0 171 $config_factory = \Drupal::configFactory();
Chris@0 172 foreach ($config_factory->listAll('views.view.') as $view_config_name) {
Chris@0 173 $view = $config_factory->getEditable($view_config_name);
Chris@0 174 $save = FALSE;
Chris@0 175 foreach ($view->get('display') as $display_name => $display) {
Chris@0 176 if (isset($display['display_options']['filters'])) {
Chris@0 177 foreach ($display['display_options']['filters'] as $filter_name => $filter) {
Chris@0 178 if (isset($filter['plugin_id']) && $filter['plugin_id'] === 'boolean') {
Chris@0 179 $new_value = FALSE;
Chris@0 180 // Update all boolean and integer values to strings.
Chris@0 181 if ($filter['value'] === TRUE || $filter['value'] === 1) {
Chris@0 182 $new_value = '1';
Chris@0 183 }
Chris@0 184 elseif ($filter['value'] === FALSE || $filter['value'] === 0) {
Chris@0 185 $new_value = '0';
Chris@0 186 }
Chris@0 187 if ($new_value !== FALSE) {
Chris@0 188 $view->set("display.$display_name.display_options.filters.$filter_name.value", $new_value);
Chris@0 189 $save = TRUE;
Chris@0 190 }
Chris@0 191 }
Chris@0 192 }
Chris@0 193 }
Chris@0 194 }
Chris@0 195 if ($save) {
Chris@0 196 $view->save();
Chris@0 197 }
Chris@0 198 }
Chris@0 199 }
Chris@0 200
Chris@0 201 /**
Chris@0 202 * Rebuild caches to ensure schema changes are read in.
Chris@0 203 */
Chris@0 204 function views_post_update_grouped_filters() {
Chris@0 205 // Empty update to cause a cache rebuild so that the schema changes are read.
Chris@0 206 }
Chris@0 207
Chris@0 208 /**
Chris@0 209 * Fix table names for revision metadata fields.
Chris@16 210 *
Chris@16 211 * @see https://www.drupal.org/node/2831499
Chris@0 212 */
Chris@0 213 function views_post_update_revision_metadata_fields() {
Chris@0 214 // The table names are fixed automatically in
Chris@0 215 // \Drupal\views\Entity\View::preSave(), so we just need to re-save all views.
Chris@0 216 $views = View::loadMultiple();
Chris@0 217 array_walk($views, function (View $view) {
Chris@0 218 $view->save();
Chris@0 219 });
Chris@0 220 }
Chris@14 221
Chris@14 222 /**
Chris@14 223 * Add additional settings to the entity link field and convert node_path usage
Chris@14 224 * to entity_link.
Chris@14 225 */
Chris@14 226 function views_post_update_entity_link_url() {
Chris@14 227 // Load all views.
Chris@14 228 $views = \Drupal::entityTypeManager()->getStorage('view')->loadMultiple();
Chris@14 229
Chris@14 230 /* @var \Drupal\views\Entity\View[] $views */
Chris@14 231 foreach ($views as $view) {
Chris@14 232 $displays = $view->get('display');
Chris@14 233 $changed = FALSE;
Chris@14 234 foreach ($displays as $display_name => &$display) {
Chris@14 235 if (isset($display['display_options']['fields'])) {
Chris@14 236 foreach ($display['display_options']['fields'] as $field_name => &$field) {
Chris@14 237 if (isset($field['plugin_id']) && $field['plugin_id'] === 'entity_link') {
Chris@14 238 // Add any missing settings for entity_link.
Chris@14 239 if (!isset($field['output_url_as_text'])) {
Chris@14 240 $field['output_url_as_text'] = FALSE;
Chris@14 241 $changed = TRUE;
Chris@14 242 }
Chris@14 243 if (!isset($field['absolute'])) {
Chris@14 244 $field['absolute'] = FALSE;
Chris@14 245 $changed = TRUE;
Chris@14 246 }
Chris@14 247 }
Chris@14 248 elseif (isset($field['plugin_id']) && $field['plugin_id'] === 'node_path') {
Chris@14 249 // Convert the use of node_path to entity_link.
Chris@14 250 $field['plugin_id'] = 'entity_link';
Chris@14 251 $field['field'] = 'view_node';
Chris@14 252 $field['output_url_as_text'] = TRUE;
Chris@14 253 $changed = TRUE;
Chris@14 254 }
Chris@14 255 }
Chris@14 256 }
Chris@14 257 }
Chris@14 258 if ($changed) {
Chris@14 259 $view->set('display', $displays);
Chris@14 260 $view->save();
Chris@14 261 }
Chris@14 262 }
Chris@14 263 }
Chris@14 264
Chris@14 265 /**
Chris@14 266 * Update dependencies for moved bulk field plugin.
Chris@14 267 */
Chris@14 268 function views_post_update_bulk_field_moved() {
Chris@14 269 $views = View::loadMultiple();
Chris@14 270 array_walk($views, function (View $view) {
Chris@14 271 $old_dependencies = $view->getDependencies();
Chris@14 272 $new_dependencies = $view->calculateDependencies()->getDependencies();
Chris@14 273 if ($old_dependencies !== $new_dependencies) {
Chris@14 274 $view->save();
Chris@14 275 }
Chris@14 276 });
Chris@14 277 }
Chris@14 278
Chris@14 279 /**
Chris@14 280 * Add placeholder settings to string or numeric filters.
Chris@14 281 */
Chris@14 282 function views_post_update_filter_placeholder_text() {
Chris@14 283 // Load all views.
Chris@14 284 $views = \Drupal::entityTypeManager()->getStorage('view')->loadMultiple();
Chris@14 285 /** @var \Drupal\views\Plugin\ViewsHandlerManager $filter_manager */
Chris@14 286 $filter_manager = \Drupal::service('plugin.manager.views.filter');
Chris@14 287
Chris@14 288 /* @var \Drupal\views\Entity\View[] $views */
Chris@14 289 foreach ($views as $view) {
Chris@14 290 $displays = $view->get('display');
Chris@14 291 $save = FALSE;
Chris@14 292 foreach ($displays as $display_name => &$display) {
Chris@14 293 if (isset($display['display_options']['filters'])) {
Chris@14 294 foreach ($display['display_options']['filters'] as $filter_name => &$filter) {
Chris@14 295 // Any of the children of the modified classes will also be inheriting
Chris@14 296 // the new settings.
Chris@14 297 $filter_instance = $filter_manager->getHandler($filter);
Chris@14 298 if ($filter_instance instanceof StringFilter) {
Chris@14 299 if (!isset($filter['expose']['placeholder'])) {
Chris@14 300 $filter['expose']['placeholder'] = '';
Chris@14 301 $save = TRUE;
Chris@14 302 }
Chris@14 303 }
Chris@14 304 elseif ($filter_instance instanceof NumericFilter) {
Chris@14 305 if (!isset($filter['expose']['placeholder'])) {
Chris@14 306 $filter['expose']['placeholder'] = '';
Chris@14 307 $save = TRUE;
Chris@14 308 }
Chris@14 309 if (!isset($filter['expose']['min_placeholder'])) {
Chris@14 310 $filter['expose']['min_placeholder'] = '';
Chris@14 311 $save = TRUE;
Chris@14 312 }
Chris@14 313 if (!isset($filter['expose']['max_placeholder'])) {
Chris@14 314 $filter['expose']['max_placeholder'] = '';
Chris@14 315 $save = TRUE;
Chris@14 316 }
Chris@14 317 }
Chris@14 318 }
Chris@14 319 }
Chris@14 320 }
Chris@14 321 if ($save) {
Chris@14 322 $view->set('display', $displays);
Chris@14 323 $view->save();
Chris@14 324 }
Chris@14 325 }
Chris@14 326 }
Chris@14 327
Chris@14 328 /**
Chris@14 329 * Include views data table provider in views dependencies.
Chris@14 330 */
Chris@14 331 function views_post_update_views_data_table_dependencies(&$sandbox = NULL) {
Chris@14 332 $storage = \Drupal::entityTypeManager()->getStorage('view');
Chris@14 333 if (!isset($sandbox['views'])) {
Chris@14 334 $sandbox['views'] = $storage->getQuery()->accessCheck(FALSE)->execute();
Chris@14 335 $sandbox['count'] = count($sandbox['views']);
Chris@14 336 }
Chris@14 337
Chris@14 338 // Process 10 views at a time.
Chris@14 339 $views = $storage->loadMultiple(array_splice($sandbox['views'], 0, 10));
Chris@14 340 foreach ($views as $view) {
Chris@14 341 $original_dependencies = $view->getDependencies();
Chris@14 342 // Only re-save if dependencies have changed.
Chris@14 343 if ($view->calculateDependencies()->getDependencies() !== $original_dependencies) {
Chris@14 344 // We can trust the data because we've already recalculated the
Chris@14 345 // dependencies.
Chris@14 346 $view->trustData();
Chris@14 347 $view->save();
Chris@14 348 }
Chris@14 349 }
Chris@14 350
Chris@14 351 $sandbox['#finished'] = empty($sandbox['views']) ? 1 : ($sandbox['count'] - count($sandbox['views'])) / $sandbox['count'];
Chris@14 352 }
Chris@14 353
Chris@14 354 /**
Chris@14 355 * Fix cache max age for table displays.
Chris@14 356 */
Chris@14 357 function views_post_update_table_display_cache_max_age(&$sandbox = NULL) {
Chris@17 358 \Drupal::classResolver(ConfigEntityUpdater::class)->update($sandbox, 'view', function ($view) {
Chris@17 359 /** @var \Drupal\views\ViewEntityInterface $view */
Chris@17 360 $displays = $view->get('display');
Chris@17 361 foreach ($displays as $display_name => &$display) {
Chris@17 362 if (isset($display['display_options']['style']['type']) && $display['display_options']['style']['type'] === 'table') {
Chris@17 363 return TRUE;
Chris@14 364 }
Chris@14 365 }
Chris@17 366 return FALSE;
Chris@17 367 });
Chris@14 368 }
Chris@18 369
Chris@18 370 /**
Chris@18 371 * Update exposed filter blocks label display to be disabled.
Chris@18 372 */
Chris@18 373 function views_post_update_exposed_filter_blocks_label_display(&$sandbox = NULL) {
Chris@18 374 \Drupal::classResolver(ConfigEntityUpdater::class)->update($sandbox, 'block', function ($block) {
Chris@18 375 /** @var \Drupal\block\BlockInterface $block */
Chris@18 376 if (strpos($block->getPluginId(), 'views_exposed_filter_block:') === 0) {
Chris@18 377 $block->getPlugin()->setConfigurationValue('label_display', '0');
Chris@18 378 return TRUE;
Chris@18 379 }
Chris@18 380
Chris@18 381 return FALSE;
Chris@18 382 });
Chris@18 383 }
Chris@18 384
Chris@18 385 /**
Chris@18 386 * Rebuild cache to allow placeholder texts to be translatable.
Chris@18 387 */
Chris@18 388 function views_post_update_make_placeholders_translatable() {
Chris@18 389 // Empty update to cause a cache rebuild to allow placeholder texts to be
Chris@18 390 // translatable.
Chris@18 391 }