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