5 * Install, update and uninstall functions for the metatag module.
9 * Implements hook_install().
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 metatags for a specific entity, edit its bundle and add the Metatag field."));
19 * Remove tags in field storage that match default or are empty.
21 function metatag_update_8101() {
22 // Get all of the field storage entities of type metatag.
23 $field_storage_configs = \Drupal::entityTypeManager()
24 ->getStorage('field_storage_config')
25 ->loadByProperties(['type' => 'metatag']);
27 foreach ($field_storage_configs as $key => $field_storage) {
28 $field_name = $field_storage->getName();
30 // Get the individual fields (field instances) associated with bundles.
31 $fields = \Drupal::entityTypeManager()
32 ->getStorage('field_config')
33 ->loadByProperties(['field_name' => $field_name]);
35 // For each of the fields, delete all records that match the defaults.
36 foreach ($fields as $field) {
37 // Get the bundle this field is attached to.
38 $bundle = $field->getTargetBundle();
40 // Get the default value for this field on this bundle.
41 $field_default_tags_value = $field->getDefaultValueLiteral();
42 $field_default_tags_value = $field_default_tags_value[0]['value'];
43 $field_default_tags = unserialize($field_default_tags_value);
45 // Determine the table and "value" field names.
46 $field_table = "node__$field_name";
47 $field_value_field = "$field_name" . "_value";
49 // Delete all records where the field value and default are identical.
50 db_delete($field_table)
51 ->condition('bundle', $bundle, '=')
52 ->condition($field_value_field, $field_default_tags_value, '=')
57 return t('Removed all default meta tag records so they can be automatically inherited when the page is loaded.');
61 * Remove tags in field storage that match default or are empty.
63 function metatag_update_8102(&$sandbox) {
64 // This whole top section only needs to be done the first time.
65 if (!isset($sandbox['records_processed'])) {
66 $sandbox['records_processed'] = 0;
67 $sandbox['total_records'] = 0;
68 $sandbox['current_field'] = 0;
69 $sandbox['current_record'] = 0;
71 // Counter to enumerate the fields so we can access them in the array
72 // by number rather than name.
75 // Get all of the field storage entities of type metatag.
76 $field_storage_configs = \Drupal::entityTypeManager()
77 ->getStorage('field_storage_config')
78 ->loadByProperties(['type' => 'metatag']);
80 foreach ($field_storage_configs as $key => $field_storage) {
81 $field_name = $field_storage->getName();
83 // Get the individual fields (field instances) associated with bundles.
84 $fields = \Drupal::entityTypeManager()
85 ->getStorage('field_config')
86 ->loadByProperties(['field_name' => $field_name]);
88 // For each of the fields, do the mass delete of exact matches but
89 // store the overridden records in the sandbox to be batch processed.
90 foreach ($fields as $field) {
91 // Get the bundle this field is attached to.
92 $bundle = $field->getTargetBundle();
94 // Get the default value for this field on this bundle.
95 $field_default_tags_value = $field->getDefaultValueLiteral();
96 $field_default_tags_value = $field_default_tags_value[0]['value'];
97 $field_default_tags = unserialize($field_default_tags_value);
99 // Determine the table and "value" field names.
100 $field_table = "node__$field_name";
101 $field_value_field = "$field_name" . "_value";
103 // Get all records where the field data does not match the default.
104 $query = db_select($field_table);
105 $query->addField($field_table, 'entity_id');
106 $query->addField($field_table, 'revision_id');
107 $query->addField($field_table, 'langcode');
108 $query->addField($field_table, $field_value_field);
109 $query->condition('bundle', $bundle, '=');
110 $result = $query->execute();
111 $records = $result->fetchAll();
113 // Fill in all the sandbox information so we can batch the individual
114 // record comparing and updating.
115 $sandbox['fields'][$field_counter]['field_table'] = $field_table;
116 $sandbox['fields'][$field_counter]['field_value_field'] = $field_value_field;
117 $sandbox['fields'][$field_counter]['field_default_tags'] = $field_default_tags;
118 $sandbox['fields'][$field_counter]['records'] = $records;
120 $sandbox['total_records'] += count($sandbox['fields'][$field_counter]['records'] = $records);
126 if ($sandbox['total_records'] == 0) {
127 // No partially overridden fields so we can skip the whole batch process.
128 $sandbox['#finished'] = 1;
131 // Begin the batch processing of individual field records.
135 $current_field = $sandbox['current_field'];
136 $current_field_records = $sandbox['fields'][$current_field]['records'];
137 $current_record = $sandbox['current_record'];
139 $field_table = $sandbox['fields'][$current_field]['field_table'];
140 $field_value_field = $sandbox['fields'][$current_field]['field_value_field'];
141 $field_default_tags = $sandbox['fields'][$current_field]['field_default_tags'];
143 // Loop through the field(s) and remove any field data that matches the
144 // field default for that bundle. Because the ability to override a default
145 // with "nothing" didn't exist prior to this and because any tag that had
146 // a default of "nothing" would have that also in the field data, we are
147 // removing those as well.
148 while ($counter <= $max_per_batch && $record = $current_field_records[$current_record]) {
149 // Strip any empty tags or ones matching the field's defaults and leave
150 // only the overridden tags in $new_tags.
151 $current_tags = unserialize($record->$field_value_field);
153 foreach ($current_tags as $key => $tag) {
154 if (!empty($tag) && $field_default_tags[$key] != $tag) {
155 $new_tags[$key] = $tag;
159 if (empty($new_tags)) {
160 // All tags were either empty or matched the default so the record can
162 db_delete($field_table)
163 ->condition('entity_id', $record->entity_id)
164 ->condition('revision_id', $record->revision_id)
165 ->condition('langcode', $record->langcode)
169 // There are some overridden tags so update the record with just those.
170 $tags_string = serialize($new_tags);
171 db_update($field_table)
173 $field_value_field => $tags_string,
175 ->condition('entity_id', $record->entity_id)
176 ->condition('revision_id', $record->revision_id)
177 ->condition('langcode', $record->langcode)
185 if (!isset($current_field_records[$current_record])) {
186 // We ran out of records for the field so start the next batch out with
192 if (!isset($sandbox['fields'][$current_field])) {
193 // We have finished all the fields. All done.
194 $sandbox['records_processed'] += $counter-1;
195 $sandbox['#finished'] = 1;
198 // Update the sandbox values to prepare for the next round.
199 $sandbox['current_field'] = $current_field;
200 $sandbox['current_record'] = $current_record;
201 $sandbox['records_processed'] += $counter-1;
202 $sandbox['#finished'] = $sandbox['records_processed'] / $sandbox['total_records'];
206 if ($sandbox['total_records'] > 0) {
207 return (string) t('Processed @processed of @total overridden Metatag records.', [
208 '@processed' => $sandbox['records_processed'],
209 '@total' => $sandbox['total_records']
213 return (string) t("There were no overridden Metatag records.");
218 * Move field defaults to Metatag Defaults.
220 function metatag_update_8103() {
221 $config_installer = \Drupal::service('config.installer');
222 $entity_manager = \Drupal::entityTypeManager();
225 * 1. Install cofiguration.
227 $sync_status = $config_installer->isSyncing();
229 $source_storage = $config_installer->getSourceStorage();
232 // Clear plugin manager caches.
233 \Drupal::getContainer()->get('plugin.cache_clearer')->clearCachedDefinitions();
234 // Install default configuration of the module.
238 ->setSourceStorage($source_storage);
241 // Install new configuration for Metatag.
242 $config_installer->installDefaultConfig('module', 'metatag');
244 // Apply all entity definition changes.
245 \Drupal::entityDefinitionUpdateManager()->applyUpdates();
248 * 2. Extract Metatag field defaults.
250 $entity_info = $entity_manager->getDefinitions();
253 // Get all of the field storage entities of type metatag.
254 $field_storage_configs = $entity_manager
255 ->getStorage('field_storage_config')
256 ->loadByProperties(['type' => 'metatag']);
258 foreach ($field_storage_configs as $key => $field_storage) {
259 $field_name = $field_storage->getName();
261 // Get the individual fields (field instances) associated with bundles.
262 $fields = $entity_manager->getStorage('field_config')
263 ->loadByProperties(['field_name' => $field_name]);
264 foreach ($fields as $field) {
265 // Adjust the config id depending on whether these are entity defaults
266 // or bundle defaults.
267 $entity_type = $field->getTargetEntityTypeId();
268 $bundle = $field->getTargetBundle();
269 $metatag_defaults_id = $entity_type;
270 if ($entity_type != $bundle) {
271 // This is a bundle override.
272 $metatag_defaults_id = $entity_type . '__' . $bundle;
274 // Extract field default values.
275 $field_default_tags_value = $field->getDefaultValueLiteral();
276 $field_default_tags_value = unserialize($field_default_tags_value[0]['value']);
277 $field_default_tags_value = array_filter($field_default_tags_value);
278 // Don't bother copying empty values.
279 if (!empty($field_default_tags_value)) {
280 $tags[$metatag_defaults_id] = $field_default_tags_value;
286 * 3. Create Config entities with field default values.
289 $bundleInfoManager = \Drupal::service('entity_type.bundle.info');
290 foreach ($tags as $metatag_defaults_id => $values) {
291 list($entity_type, $entity_bundle) = explode('__', $metatag_defaults_id);
292 $entity_label = (string) $entity_info[$entity_type]->get('label');
293 $bundle_info = $bundleInfoManager->getBundleInfo($entity_type);
294 $bundle_label = $bundle_info[$entity_bundle]['label'];
295 $label = $entity_label . ': ' . $bundle_label;
297 $metatags_global_manager = $entity_manager->getStorage('metatag_defaults');
299 $entity = $metatags_global_manager->load($metatag_defaults_id);
301 // These are defaults for an existing config entity, such as User.
302 $entity->set('tags', $values);
305 // These are bundle overrides.
306 $entity = $metatags_global_manager->create([
307 'id' => $metatag_defaults_id,
314 return (string) t("@count Metatag field defaults have been converted to using global entity defaults.", ['@count' => count($tags)]);
317 return (string) t("There were Metatag field configurations that needed to be converted.");
322 * Rebuild routes after moving Metatag admin from Structure to Config.
324 function metatag_update_8104() {
325 \Drupal::service('router.builder')->setRebuildNeeded();
329 * Rebuild routes after renaming.
331 function metatag_update_8105() {
332 \Drupal::service('router.builder')->setRebuildNeeded();
336 * Add the metatag_defaults config entity to the site.
338 function metatag_update_8106() {
339 \Drupal::entityDefinitionUpdateManager()->applyUpdates();
343 * Enable the new metatag_open_graph module.
345 function metatag_update_8107() {
346 \Drupal::service('module_installer')->install(['metatag_open_graph']);
347 return (string) t("The new Metatag: Open Graph module has been enabled.");