Commit ec6ee0e9 authored by Damien McKenna's avatar Damien McKenna
Browse files

Issue #3042590 by phenaproxima, SerShevchyk, chr.fritsch, Berdir, pixlkat,...

Issue #3042590 by phenaproxima, SerShevchyk, chr.fritsch, Berdir, pixlkat, abramm, Cary_Dean, pguillard, gmangones, DamienMcKenna, josephdpurcell, waverate, joshi.rohit100, baikho, valthebald: Drupal 9 compatibility fixes.
parent 486c030f
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -4,6 +4,9 @@ Metatag 8.x-1.x-dev, xxxx-xx-xx
  for D9.
#3123582 by DamienMcKenna: Remove Devel dependency for D9.
#3123577 by DamienMcKenna: Remove RestUI dependency for D9.
#3042590 by phenaproxima, SerShevchyk, chr.fritsch, Berdir, pixlkat, abramm,
  Cary_Dean, pguillard, gmangones, DamienMcKenna, josephdpurcell, waverate,
  joshi.rohit100, baikho, valthebald: Drupal 9 compatibility fixes.


Metatag 8.x-1.12, 2020-03-30
+2 −2
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@
    "drupal/token": "^1.0"
  },
  "require-dev": {
    "drupal/redirect": "^1.0",
    "drupal/page_manager": "^4.0"
    "drupal/redirect": "1.x-dev",
    "drupal/page_manager": "4.x-dev"
  }
}
+1 −2
Original line number Diff line number Diff line
name: Metatag
type: module
description: Manage meta tags for all entities.
core: 8.x
core_version_requirement: '^8 || ^9'
core_version_requirement: '^8.7.7 || ^9'
package: SEO
configure: entity.metatag_defaults.collection
dependencies:
+3 −313
Original line number Diff line number Diff line
@@ -52,320 +52,10 @@ function metatag_requirements($phase) {
}

/**
 * Remove tags in field storage that match default or are empty.
 * Implements hook_update_last_removed().
 */
function metatag_update_8101() {
  // Get all of the field storage entities of type metatag.
  $field_storage_configs = \Drupal::entityTypeManager()
    ->getStorage('field_storage_config')
    ->loadByProperties(['type' => 'metatag']);

  foreach ($field_storage_configs as $field_storage) {
    $field_name = $field_storage->getName();

    // Get the individual fields (field instances) associated with bundles.
    $fields = \Drupal::entityTypeManager()
      ->getStorage('field_config')
      ->loadByProperties(['field_name' => $field_name]);

    // For each of the fields, delete all records that match the defaults.
    foreach ($fields as $field) {
      // Get the bundle this field is attached to.
      $bundle = $field->getTargetBundle();

      // Get the default value for this field on this bundle.
      $field_default_tags_value = $field->getDefaultValueLiteral();
      $field_default_tags_value = $field_default_tags_value[0]['value'];

      // Determine the table and "value" field names.
      $field_table = "node__" . $field_name;
      $field_value_field = $field_name . "_value";

      // Delete all records where the field value and default are identical.
      \Drupal::database()->delete($field_table)
        ->condition('bundle', $bundle, '=')
        ->condition($field_value_field, $field_default_tags_value, '=')
        ->execute();
    }
  }

  return t('Removed all default meta tag records so they can be automatically inherited when the page is loaded.');
}

/**
 * Remove tags in field storage that match default or are empty.
 */
function metatag_update_8102(&$sandbox) {
  // This whole top section only needs to be done the first time.
  if (!isset($sandbox['records_processed'])) {
    $sandbox['records_processed'] = 0;
    $sandbox['total_records'] = 0;
    $sandbox['current_field'] = 0;
    $sandbox['current_record'] = 0;

    // Counter to enumerate the fields so we can access them in the array
    // by number rather than name.
    $field_counter = 0;

    // Get all of the field storage entities of type metatag.
    $field_storage_configs = \Drupal::entityTypeManager()
      ->getStorage('field_storage_config')
      ->loadByProperties(['type' => 'metatag']);

    foreach ($field_storage_configs as $field_storage) {
      $field_name = $field_storage->getName();

      // Get the individual fields (field instances) associated with bundles.
      $fields = \Drupal::entityTypeManager()
        ->getStorage('field_config')
        ->loadByProperties(['field_name' => $field_name]);

      // For each of the fields, do the mass delete of exact matches but
      // store the overridden records in the sandbox to be batch processed.
      foreach ($fields as $field) {
        // Get the bundle this field is attached to.
        $bundle = $field->getTargetBundle();

        // Get the default value for this field on this bundle.
        $field_default_tags_value = $field->getDefaultValueLiteral();
        $field_default_tags_value = $field_default_tags_value[0]['value'];
        $field_default_tags = unserialize($field_default_tags_value);

        // Determine the table and "value" field names.
        $field_table = "node__" . $field_name;
        $field_value_field = $field_name . "_value";

        // Get all records where the field data does not match the default.
        $query = \Drupal::database()->select($field_table);
        $query->addField($field_table, 'entity_id');
        $query->addField($field_table, 'revision_id');
        $query->addField($field_table, 'langcode');
        $query->addField($field_table, $field_value_field);
        $query->condition('bundle', $bundle, '=');
        $result = $query->execute();
        $records = $result->fetchAll();

        // Fill in all the sandbox information so we can batch the individual
        // record comparing and updating.
        $sandbox['fields'][$field_counter]['field_table'] = $field_table;
        $sandbox['fields'][$field_counter]['field_value_field'] = $field_value_field;
        $sandbox['fields'][$field_counter]['field_default_tags'] = $field_default_tags;
        $sandbox['fields'][$field_counter]['records'] = $records;

        $sandbox['total_records'] += count($sandbox['fields'][$field_counter]['records'] = $records);
        $field_counter++;
      }
    }
  }

  if ($sandbox['total_records'] == 0) {
    // No partially overridden fields so we can skip the whole batch process.
    $sandbox['#finished'] = 1;
  }
  else {
    // Begin the batch processing of individual field records.
    $max_per_batch = 10;
    $counter = 1;

    $current_field = $sandbox['current_field'];
    $current_field_records = $sandbox['fields'][$current_field]['records'];
    $current_record = $sandbox['current_record'];

    $field_table = $sandbox['fields'][$current_field]['field_table'];
    $field_value_field = $sandbox['fields'][$current_field]['field_value_field'];
    $field_default_tags = $sandbox['fields'][$current_field]['field_default_tags'];

    // Loop through the field(s) and remove any field data that matches the
    // field default for that bundle. Because the ability to override a default
    // with "nothing" didn't exist prior to this and because any tag that had
    // a default of "nothing" would have that also in the field data, we are
    // removing those as well.
    while ($counter <= $max_per_batch && $record = $current_field_records[$current_record]) {
      // Strip any empty tags or ones matching the field's defaults and leave
      // only the overridden tags in $new_tags.
      $current_tags = unserialize($record->$field_value_field);
      $new_tags = [];
      foreach ($current_tags as $key => $tag) {
        if (!empty($tag) && $field_default_tags[$key] != $tag) {
          $new_tags[$key] = $tag;
        }
      }

      if (empty($new_tags)) {
        // All tags were either empty or matched the default so the record can
        // be deleted.
        \Drupal::database()->delete($field_table)
          ->condition('entity_id', $record->entity_id)
          ->condition('revision_id', $record->revision_id)
          ->condition('langcode', $record->langcode)
          ->execute();
      }
      else {
        // There are some overridden tags so update the record with just those.
        $tags_string = serialize($new_tags);
        \Drupal::database()->update($field_table)
          ->fields([
            $field_value_field => $tags_string,
          ])
          ->condition('entity_id', $record->entity_id)
          ->condition('revision_id', $record->revision_id)
          ->condition('langcode', $record->langcode)
          ->execute();
      }

      $counter++;
      $current_record++;
    }

    // We ran out of records for the field so start the next batch out with the
    // next field.
    if (!isset($current_field_records[$current_record])) {
      $current_field++;
      $current_record = 0;
    }

    // We have finished all the fields. All done.
    if (!isset($sandbox['fields'][$current_field])) {
      $sandbox['records_processed'] += $counter - 1;
      $sandbox['#finished'] = 1;
    }
    // Update the sandbox values to prepare for the next round.
    else {
      $sandbox['current_field'] = $current_field;
      $sandbox['current_record'] = $current_record;
      $sandbox['records_processed'] += $counter - 1;
      $sandbox['#finished'] = $sandbox['records_processed'] / $sandbox['total_records'];
    }
  }

  if ($sandbox['total_records'] > 0) {
    return (string) t('Processed @processed of @total overridden Metatag records.', [
      '@processed' => $sandbox['records_processed'],
      '@total' => $sandbox['total_records'],
    ]);
  }
  else {
    return (string) t("There were no overridden Metatag records.");
  }
}

/**
 * Move field defaults to Metatag Defaults.
 */
function metatag_update_8103() {
  $config_installer = \Drupal::service('config.installer');
  $entity_manager = \Drupal::entityTypeManager();

  // 1. Install cofiguration.
  $sync_status = $config_installer->isSyncing();
  if ($sync_status) {
    $source_storage = $config_installer->getSourceStorage();
  }

  // Clear plugin manager caches.
  \Drupal::getContainer()->get('plugin.cache_clearer')->clearCachedDefinitions();
  // Install default configuration of the module.
  if ($sync_status) {
    $config_installer
      ->setSyncing(TRUE)
      ->setSourceStorage($source_storage);
  }

  // Install new configuration for Metatag.
  $config_installer->installDefaultConfig('module', 'metatag');

  // Apply all entity definition changes.
  \Drupal::entityDefinitionUpdateManager()->getChangeList();

  // 2. Extract Metatag field defaults.
  $entity_info = $entity_manager->getDefinitions();
  $tags = [];

  // Get all of the field storage entities of type metatag.
  $field_storage_configs = $entity_manager
    ->getStorage('field_storage_config')
    ->loadByProperties(['type' => 'metatag']);

  foreach ($field_storage_configs as $field_storage) {
    $field_name = $field_storage->getName();

    // Get the individual fields (field instances) associated with bundles.
    $fields = $entity_manager->getStorage('field_config')
      ->loadByProperties(['field_name' => $field_name]);
    foreach ($fields as $field) {
      // Adjust the config id depending on whether these are entity defaults
      // or bundle defaults.
      $entity_type = $field->getTargetEntityTypeId();
      $bundle = $field->getTargetBundle();
      $metatag_defaults_id = $entity_type;
      if ($entity_type != $bundle) {
        // This is a bundle override.
        $metatag_defaults_id = $entity_type . '__' . $bundle;
      }
      // Extract field default values.
      $field_default_tags_value = $field->getDefaultValueLiteral();
      $field_default_tags_value = unserialize($field_default_tags_value[0]['value']);
      $field_default_tags_value = array_filter($field_default_tags_value);
      // Don't bother copying empty values.
      if (!empty($field_default_tags_value)) {
        $tags[$metatag_defaults_id] = $field_default_tags_value;
      }
    }
  }

  // 3. Create Config entities with field default values.
  if (!empty($tags)) {
    $bundleInfoManager = \Drupal::service('entity_type.bundle.info');
    foreach ($tags as $metatag_defaults_id => $values) {
      list($entity_type, $entity_bundle) = explode('__', $metatag_defaults_id);
      $entity_label = (string) $entity_info[$entity_type]->get('label');
      $bundle_info = $bundleInfoManager->getBundleInfo($entity_type);
      $bundle_label = $bundle_info[$entity_bundle]['label'];
      $label = $entity_label . ': ' . $bundle_label;

      $metatags_global_manager = $entity_manager->getStorage('metatag_defaults');

      $entity = $metatags_global_manager->load($metatag_defaults_id);
      if ($entity) {
        // These are defaults for an existing config entity, such as User.
        $entity->set('tags', $values);
      }
      else {
        // These are bundle overrides.
        $entity = $metatags_global_manager->create([
          'id' => $metatag_defaults_id,
          'label' => $label,
          'tags' => $values,
        ]);
      }
      $entity->save();
    }
    return (string) t("@count Metatag field defaults have been converted to using global entity defaults.", ['@count' => count($tags)]);
  }
  else {
    return (string) t("There were Metatag field configurations that needed to be converted.");
  }
}

/**
 * Rebuild routes after moving Metatag admin from Structure to Config.
 */
function metatag_update_8104() {
  \Drupal::service('router.builder')->setRebuildNeeded();
}

/**
 * Rebuild routes after renaming.
 */
function metatag_update_8105() {
  \Drupal::service('router.builder')->setRebuildNeeded();
}

/**
 * Add the metatag_defaults config entity to the site.
 */
function metatag_update_8106() {
  \Drupal::entityDefinitionUpdateManager()->getChangeList();
function metatag_update_last_removed() {
  return 8106;
}

/**
+2 −1
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ use Drupal\taxonomy\Plugin\migrate\source\d7\Term as Term7;
use Drupal\taxonomy\TermInterface;
use Drupal\user\Plugin\migrate\source\d6\User as User6;
use Drupal\user\Plugin\migrate\source\d7\User as User7;
use Drupal\Core\Render\HtmlResponseAttachmentsProcessor;

/**
 * Implements hook_help().
@@ -153,7 +154,7 @@ function metatag_page_attachments(array &$attachments) {

        $href = '<' . Html::escape($attributes['href']) . '>';
        unset($attributes['href']);
        if ($param = drupal_http_header_attributes($attributes)) {
        if ($param = HtmlResponseAttachmentsProcessor::formatHttpHeaderAttributes($attributes)) {
          $href .= ';' . $param;
        }
        $head_links[] = $href;
Loading