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