Updated all the contrib modules to their latest versions.
[yaffs-website] / web / modules / contrib / metatag / metatag.install
1 <?php
2
3 /**
4  * @file
5  * Install, update and uninstall functions for the metatag module.
6  */
7
8 /**
9  * Implements hook_install().
10  */
11 function metatag_install() {
12   // Don't display the message during site installation, it looks funny.
13   if (!drupal_installation_attempted()) {
14     drupal_set_message(t("To adjust global defaults, go to admin/config/search/metatag. If you need to set meta tags for a specific entity, edit its bundle and add the Metatag field."));
15   }
16 }
17
18 /**
19  * Implements hook_requirements().
20  */
21 function metatag_requirements($phase) {
22   $requirements = [];
23
24   if ($phase == 'runtime') {
25     // Recommend the Schema.org Metatag module.
26     if (!\Drupal::moduleHandler()->moduleExists('schema_metatag')) {
27       $requirements['metatag_schema'] = [
28         'severity' => REQUIREMENT_INFO,
29         'title' => 'Metatag',
30         'value' => t('Schema.org Metatag is recommended'),
31         'description' => t('The <a href="@module">Schema.org Metatag</a> module is highly recommended to add <a href="@jsonld">JSON-LD</a> -formatted <a href="@schema">schema.org</a> compatible data structures to the site.', [
32           '@module' => 'https://www.drupal.org/project/schema_metatag',
33           '@jsonld' => 'https://json-ld.org',
34           '@schema' => 'http://schema.org',
35         ]),
36       ];
37     }
38     else {
39       $requirements['metatag_schema'] = [
40         'severity' => REQUIREMENT_OK,
41         'title' => 'Metatag',
42         'value' => t('Schema.org Metatag is installed'),
43         'description' => t('The <a href="@module">Schema.org Metatag</a> module is installed.', [
44           '@module' => 'https://www.drupal.org/project/schema_metatag',
45         ]),
46       ];
47     }
48   }
49
50   return $requirements;
51 }
52
53 /**
54  * Remove tags in field storage that match default or are empty.
55  */
56 function metatag_update_8101() {
57   // Get all of the field storage entities of type metatag.
58   $field_storage_configs = \Drupal::entityTypeManager()
59     ->getStorage('field_storage_config')
60     ->loadByProperties(['type' => 'metatag']);
61
62   foreach ($field_storage_configs as $field_storage) {
63     $field_name = $field_storage->getName();
64
65     // Get the individual fields (field instances) associated with bundles.
66     $fields = \Drupal::entityTypeManager()
67       ->getStorage('field_config')
68       ->loadByProperties(['field_name' => $field_name]);
69
70     // For each of the fields, delete all records that match the defaults.
71     foreach ($fields as $field) {
72       // Get the bundle this field is attached to.
73       $bundle = $field->getTargetBundle();
74
75       // Get the default value for this field on this bundle.
76       $field_default_tags_value = $field->getDefaultValueLiteral();
77       $field_default_tags_value = $field_default_tags_value[0]['value'];
78
79       // Determine the table and "value" field names.
80       $field_table = "node__" . $field_name;
81       $field_value_field = $field_name . "_value";
82
83       // Delete all records where the field value and default are identical.
84       \Drupal::database()->delete($field_table)
85         ->condition('bundle', $bundle, '=')
86         ->condition($field_value_field, $field_default_tags_value, '=')
87         ->execute();
88     }
89   }
90
91   return t('Removed all default meta tag records so they can be automatically inherited when the page is loaded.');
92 }
93
94 /**
95  * Remove tags in field storage that match default or are empty.
96  */
97 function metatag_update_8102(&$sandbox) {
98   // This whole top section only needs to be done the first time.
99   if (!isset($sandbox['records_processed'])) {
100     $sandbox['records_processed'] = 0;
101     $sandbox['total_records'] = 0;
102     $sandbox['current_field'] = 0;
103     $sandbox['current_record'] = 0;
104
105     // Counter to enumerate the fields so we can access them in the array
106     // by number rather than name.
107     $field_counter = 0;
108
109     // Get all of the field storage entities of type metatag.
110     $field_storage_configs = \Drupal::entityTypeManager()
111       ->getStorage('field_storage_config')
112       ->loadByProperties(['type' => 'metatag']);
113
114     foreach ($field_storage_configs as $field_storage) {
115       $field_name = $field_storage->getName();
116
117       // Get the individual fields (field instances) associated with bundles.
118       $fields = \Drupal::entityTypeManager()
119         ->getStorage('field_config')
120         ->loadByProperties(['field_name' => $field_name]);
121
122       // For each of the fields, do the mass delete of exact matches but
123       // store the overridden records in the sandbox to be batch processed.
124       foreach ($fields as $field) {
125         // Get the bundle this field is attached to.
126         $bundle = $field->getTargetBundle();
127
128         // Get the default value for this field on this bundle.
129         $field_default_tags_value = $field->getDefaultValueLiteral();
130         $field_default_tags_value = $field_default_tags_value[0]['value'];
131         $field_default_tags = unserialize($field_default_tags_value);
132
133         // Determine the table and "value" field names.
134         $field_table = "node__" . $field_name;
135         $field_value_field = $field_name . "_value";
136
137         // Get all records where the field data does not match the default.
138         $query = \Drupal::database()->select($field_table);
139         $query->addField($field_table, 'entity_id');
140         $query->addField($field_table, 'revision_id');
141         $query->addField($field_table, 'langcode');
142         $query->addField($field_table, $field_value_field);
143         $query->condition('bundle', $bundle, '=');
144         $result = $query->execute();
145         $records = $result->fetchAll();
146
147         // Fill in all the sandbox information so we can batch the individual
148         // record comparing and updating.
149         $sandbox['fields'][$field_counter]['field_table'] = $field_table;
150         $sandbox['fields'][$field_counter]['field_value_field'] = $field_value_field;
151         $sandbox['fields'][$field_counter]['field_default_tags'] = $field_default_tags;
152         $sandbox['fields'][$field_counter]['records'] = $records;
153
154         $sandbox['total_records'] += count($sandbox['fields'][$field_counter]['records'] = $records);
155         $field_counter++;
156       }
157     }
158   }
159
160   if ($sandbox['total_records'] == 0) {
161     // No partially overridden fields so we can skip the whole batch process.
162     $sandbox['#finished'] = 1;
163   }
164   else {
165     // Begin the batch processing of individual field records.
166     $max_per_batch = 10;
167     $counter = 1;
168
169     $current_field = $sandbox['current_field'];
170     $current_field_records = $sandbox['fields'][$current_field]['records'];
171     $current_record = $sandbox['current_record'];
172
173     $field_table = $sandbox['fields'][$current_field]['field_table'];
174     $field_value_field = $sandbox['fields'][$current_field]['field_value_field'];
175     $field_default_tags = $sandbox['fields'][$current_field]['field_default_tags'];
176
177     // Loop through the field(s) and remove any field data that matches the
178     // field default for that bundle. Because the ability to override a default
179     // with "nothing" didn't exist prior to this and because any tag that had
180     // a default of "nothing" would have that also in the field data, we are
181     // removing those as well.
182     while ($counter <= $max_per_batch && $record = $current_field_records[$current_record]) {
183       // Strip any empty tags or ones matching the field's defaults and leave
184       // only the overridden tags in $new_tags.
185       $current_tags = unserialize($record->$field_value_field);
186       $new_tags = [];
187       foreach ($current_tags as $key => $tag) {
188         if (!empty($tag) && $field_default_tags[$key] != $tag) {
189           $new_tags[$key] = $tag;
190         }
191       }
192
193       if (empty($new_tags)) {
194         // All tags were either empty or matched the default so the record can
195         // be deleted.
196         \Drupal::database()->delete($field_table)
197           ->condition('entity_id', $record->entity_id)
198           ->condition('revision_id', $record->revision_id)
199           ->condition('langcode', $record->langcode)
200           ->execute();
201       }
202       else {
203         // There are some overridden tags so update the record with just those.
204         $tags_string = serialize($new_tags);
205         \Drupal::database()->update($field_table)
206           ->fields([
207             $field_value_field => $tags_string,
208           ])
209           ->condition('entity_id', $record->entity_id)
210           ->condition('revision_id', $record->revision_id)
211           ->condition('langcode', $record->langcode)
212           ->execute();
213       }
214
215       $counter++;
216       $current_record++;
217     }
218
219     // We ran out of records for the field so start the next batch out with the
220     // next field.
221     if (!isset($current_field_records[$current_record])) {
222       $current_field++;
223       $current_record = 0;
224     }
225
226     // We have finished all the fields. All done.
227     if (!isset($sandbox['fields'][$current_field])) {
228       $sandbox['records_processed'] += $counter - 1;
229       $sandbox['#finished'] = 1;
230     }
231     // Update the sandbox values to prepare for the next round.
232     else {
233       $sandbox['current_field'] = $current_field;
234       $sandbox['current_record'] = $current_record;
235       $sandbox['records_processed'] += $counter - 1;
236       $sandbox['#finished'] = $sandbox['records_processed'] / $sandbox['total_records'];
237     }
238   }
239
240   if ($sandbox['total_records'] > 0) {
241     return (string) t('Processed @processed of @total overridden Metatag records.', [
242       '@processed' => $sandbox['records_processed'],
243       '@total' => $sandbox['total_records'],
244     ]);
245   }
246   else {
247     return (string) t("There were no overridden Metatag records.");
248   }
249 }
250
251 /**
252  * Move field defaults to Metatag Defaults.
253  */
254 function metatag_update_8103() {
255   $config_installer = \Drupal::service('config.installer');
256   $entity_manager = \Drupal::entityTypeManager();
257
258   // 1. Install cofiguration.
259   $sync_status = $config_installer->isSyncing();
260   if ($sync_status) {
261     $source_storage = $config_installer->getSourceStorage();
262   }
263
264   // Clear plugin manager caches.
265   \Drupal::getContainer()->get('plugin.cache_clearer')->clearCachedDefinitions();
266   // Install default configuration of the module.
267   if ($sync_status) {
268     $config_installer
269       ->setSyncing(TRUE)
270       ->setSourceStorage($source_storage);
271   }
272
273   // Install new configuration for Metatag.
274   $config_installer->installDefaultConfig('module', 'metatag');
275
276   // Apply all entity definition changes.
277   \Drupal::entityDefinitionUpdateManager()->applyUpdates();
278
279   // 2. Extract Metatag field defaults.
280   $entity_info = $entity_manager->getDefinitions();
281   $tags = [];
282
283   // Get all of the field storage entities of type metatag.
284   $field_storage_configs = $entity_manager
285     ->getStorage('field_storage_config')
286     ->loadByProperties(['type' => 'metatag']);
287
288   foreach ($field_storage_configs as $field_storage) {
289     $field_name = $field_storage->getName();
290
291     // Get the individual fields (field instances) associated with bundles.
292     $fields = $entity_manager->getStorage('field_config')
293       ->loadByProperties(['field_name' => $field_name]);
294     foreach ($fields as $field) {
295       // Adjust the config id depending on whether these are entity defaults
296       // or bundle defaults.
297       $entity_type = $field->getTargetEntityTypeId();
298       $bundle = $field->getTargetBundle();
299       $metatag_defaults_id = $entity_type;
300       if ($entity_type != $bundle) {
301         // This is a bundle override.
302         $metatag_defaults_id = $entity_type . '__' . $bundle;
303       }
304       // Extract field default values.
305       $field_default_tags_value = $field->getDefaultValueLiteral();
306       $field_default_tags_value = unserialize($field_default_tags_value[0]['value']);
307       $field_default_tags_value = array_filter($field_default_tags_value);
308       // Don't bother copying empty values.
309       if (!empty($field_default_tags_value)) {
310         $tags[$metatag_defaults_id] = $field_default_tags_value;
311       }
312     }
313   }
314
315   // 3. Create Config entities with field default values.
316   if (!empty($tags)) {
317     $bundleInfoManager = \Drupal::service('entity_type.bundle.info');
318     foreach ($tags as $metatag_defaults_id => $values) {
319       list($entity_type, $entity_bundle) = explode('__', $metatag_defaults_id);
320       $entity_label = (string) $entity_info[$entity_type]->get('label');
321       $bundle_info = $bundleInfoManager->getBundleInfo($entity_type);
322       $bundle_label = $bundle_info[$entity_bundle]['label'];
323       $label = $entity_label . ': ' . $bundle_label;
324
325       $metatags_global_manager = $entity_manager->getStorage('metatag_defaults');
326
327       $entity = $metatags_global_manager->load($metatag_defaults_id);
328       if ($entity) {
329         // These are defaults for an existing config entity, such as User.
330         $entity->set('tags', $values);
331       }
332       else {
333         // These are bundle overrides.
334         $entity = $metatags_global_manager->create([
335           'id' => $metatag_defaults_id,
336           'label' => $label,
337           'tags' => $values,
338         ]);
339       }
340       $entity->save();
341     }
342     return (string) t("@count Metatag field defaults have been converted to using global entity defaults.", ['@count' => count($tags)]);
343   }
344   else {
345     return (string) t("There were Metatag field configurations that needed to be converted.");
346   }
347 }
348
349 /**
350  * Rebuild routes after moving Metatag admin from Structure to Config.
351  */
352 function metatag_update_8104() {
353   \Drupal::service('router.builder')->setRebuildNeeded();
354 }
355
356 /**
357  * Rebuild routes after renaming.
358  */
359 function metatag_update_8105() {
360   \Drupal::service('router.builder')->setRebuildNeeded();
361 }
362
363 /**
364  * Add the metatag_defaults config entity to the site.
365  */
366 function metatag_update_8106() {
367   \Drupal::entityDefinitionUpdateManager()->applyUpdates();
368 }
369
370 /**
371  * Enable the new metatag_open_graph module.
372  */
373 function metatag_update_8107() {
374   \Drupal::service('module_installer')->install(['metatag_open_graph']);
375   return (string) t("The new Metatag: Open Graph module has been enabled.");
376 }