5 * Post update functions for Views.
8 use Drupal\Core\StringTranslation\TranslatableMarkup;
9 use Drupal\views\Entity\View;
10 use Drupal\views\Views;
13 * Update the cacheability metadata for all views.
15 function views_post_update_update_cacheability_metadata() {
17 $views = \Drupal::entityManager()->getStorage('view')->loadMultiple();
19 /* @var \Drupal\views\Entity\View[] $views */
20 foreach ($views as $view) {
21 $displays = $view->get('display');
22 foreach (array_keys($displays) as $display_id) {
23 $display =& $view->getDisplay($display_id);
24 // Unset the cache_metadata key, so all cacheability metadata for the
25 // display is recalculated.
26 unset($display['cache_metadata']);
34 * Update some views fields that were previously duplicated.
36 function views_post_update_cleanup_duplicate_views_data() {
37 $config_factory = \Drupal::configFactory();
42 $revision_tables = [];
43 $entities_by_table = [];
44 $duplicate_fields = [];
45 $handler_types = Views::getHandlerTypes();
47 /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager */
48 $entity_type_manager = \Drupal::service('entity_type.manager');
49 // This will allow us to create an index of all entity types of the site.
50 foreach ($entity_type_manager->getDefinitions() as $entity_type_id => $entity_type) {
51 // Store the entity keyed by base table. If it has a data table, use that as
53 if ($data_table = $entity_type->getDataTable()) {
54 $entities_by_table[$data_table] = $entity_type;
56 if ($base_table = $entity_type->getBaseTable()) {
57 $entities_by_table[$base_table] = $entity_type;
60 // The following code basically contains the same kind of logic as
61 // \Drupal\Core\Entity\Sql\SqlContentEntityStorage::initTableLayout() to
62 // prefetch all tables (base, data, revision, and revision data).
63 $base_tables[$entity_type_id] = $entity_type->getBaseTable() ?: $entity_type->id();
64 $revisionable = $entity_type->isRevisionable();
68 $revision_table = $entity_type->getRevisionTable() ?: $entity_type->id() . '_revision';
70 $revision_tables[$entity_type_id] = $revision_table;
72 $translatable = $entity_type->isTranslatable();
74 // For example the data table just exists, when the entity type is
77 $data_table = $entity_type->getDataTable() ?: $entity_type->id() . '_field_data';
79 $data_tables[$entity_type_id] = $data_table;
81 $duplicate_fields[$entity_type_id] = array_intersect_key($entity_type->getKeys(), array_flip(['id', 'revision', 'bundle']));
84 foreach ($config_factory->listAll('views.view.') as $view_config_name) {
86 $view = $config_factory->getEditable($view_config_name);
88 $displays = $view->get('display');
89 if (isset($entities_by_table[$view->get('base_table')])) {
90 $entity_type = $entities_by_table[$view->get('base_table')];
91 $entity_type_id = $entity_type->id();
92 $data_table = $data_tables[$entity_type_id];
93 $base_table = $base_tables[$entity_type_id];
94 $revision_table = $revision_tables[$entity_type_id];
97 foreach ($displays as $display_name => &$display) {
98 foreach ($handler_types as $handler_type) {
99 if (!empty($display['display_options'][$handler_type['plural']])) {
100 foreach ($display['display_options'][$handler_type['plural']] as $field_name => &$field) {
101 $table = $field['table'];
102 if (($table === $base_table || $table === $revision_table) && in_array($field_name, $duplicate_fields[$entity_type_id])) {
103 $field['table'] = $data_table;
114 $view->set('display', $displays);
116 $ids[] = $view->get('id');
120 $message = new TranslatableMarkup('Updated tables for field handlers for views: @ids', ['@ids' => implode(', ', array_unique($ids))]);
127 * Include field formatter dependencies in a view when the formatter is used.
129 function views_post_update_field_formatter_dependencies() {
130 $views = View::loadMultiple();
131 array_walk($views, function (View $view) {
137 * Fix views with dependencies on taxonomy terms that don't exist.
139 function views_post_update_taxonomy_index_tid() {
140 $views = View::loadMultiple();
141 array_walk($views, function (View $view) {
142 $old_dependencies = $view->getDependencies();
143 $new_dependencies = $view->calculateDependencies()->getDependencies();
144 if ($old_dependencies !== $new_dependencies) {
151 * Fix views with serializer dependencies.
153 function views_post_update_serializer_dependencies() {
154 $views = View::loadMultiple();
155 array_walk($views, function (View $view) {
156 $old_dependencies = $view->getDependencies();
157 $new_dependencies = $view->calculateDependencies()->getDependencies();
158 if ($old_dependencies !== $new_dependencies) {
165 * Set all boolean filter values to strings.
167 function views_post_update_boolean_filter_values() {
168 $config_factory = \Drupal::configFactory();
169 foreach ($config_factory->listAll('views.view.') as $view_config_name) {
170 $view = $config_factory->getEditable($view_config_name);
172 foreach ($view->get('display') as $display_name => $display) {
173 if (isset($display['display_options']['filters'])) {
174 foreach ($display['display_options']['filters'] as $filter_name => $filter) {
175 if (isset($filter['plugin_id']) && $filter['plugin_id'] === 'boolean') {
177 // Update all boolean and integer values to strings.
178 if ($filter['value'] === TRUE || $filter['value'] === 1) {
181 elseif ($filter['value'] === FALSE || $filter['value'] === 0) {
184 if ($new_value !== FALSE) {
185 $view->set("display.$display_name.display_options.filters.$filter_name.value", $new_value);
199 * Rebuild caches to ensure schema changes are read in.
201 function views_post_update_grouped_filters() {
202 // Empty update to cause a cache rebuild so that the schema changes are read.
206 * Fix table names for revision metadata fields.
208 function views_post_update_revision_metadata_fields() {
209 // The table names are fixed automatically in
210 // \Drupal\views\Entity\View::preSave(), so we just need to re-save all views.
211 $views = View::loadMultiple();
212 array_walk($views, function (View $view) {