You are here

function pathauto_update_8100 in Pathauto 8

Converts patterns from configuration objects to configuration entities.

File

./pathauto.install, line 58
Install, update, and uninstall functions for Pathauto.

Code

function pathauto_update_8100() {
  \Drupal::service('module_installer')
    ->install([
    'ctools',
  ]);
  $messages = [];

  /** @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_bundle_info */
  $entity_bundle_info = \Drupal::service('entity_type.bundle.info');
  $entity_type_manager = \Drupal::entityTypeManager();
  $language_manager = \Drupal::languageManager();
  $entity_type_manager
    ->clearCachedDefinitions();
  \Drupal::service('plugin.manager.alias_type')
    ->clearCachedDefinitions();
  $entity_types = $entity_type_manager
    ->getDefinitions();

  // 1. Load all patterns.
  $config = \Drupal::configFactory()
    ->getEditable('pathauto.pattern');
  $patterns = $config
    ->get('patterns');

  // 2. Create a configuration entity per pattern.
  foreach ($patterns as $entity_type => $entity_patterns) {
    if (!array_key_exists($entity_type, $entity_types)) {

      // We found an unknown entity type. Report it.
      $messages[] = t('Entity of type @type was not processed. It defines the following patterns: @patterns', [
        '@type' => $entity_type,
        '@patterns' => print_r($entity_patterns, TRUE),
      ]);
      continue;
    }
    $entity_label = $entity_types[$entity_type]
      ->getLabel();
    if (!empty($entity_patterns['default'])) {

      // This is a pattern for an entity type, such as "node".
      $pattern = PathautoPattern::create([
        'id' => $entity_type,
        'label' => $entity_label,
        'type' => 'canonical_entities:' . $entity_type,
        'pattern' => $entity_patterns['default'],
        'weight' => 0,
      ]);
      $pattern
        ->save();
    }

    // Loop over bundles and create patterns if they have a value.
    // Bundle keys may have a language suffix for language-dependant patterns.
    if (isset($entity_patterns['bundles'])) {
      $bundle_info = $entity_bundle_info
        ->getBundleInfo($entity_type);
      foreach ($entity_patterns['bundles'] as $bundle => $bundle_patterns) {
        if (empty($bundle_patterns['default'])) {

          // This bundle does not define a pattern. Move on to the next one.
          continue;
        }
        if (isset($bundle_info[$bundle])) {

          // This is a pattern for a bundle, such as "node_article".
          $pattern = PathautoPattern::create([
            'id' => $entity_type . '_' . $bundle,
            'label' => $entity_label . ' ' . $bundle_info[$bundle]['label'],
            'type' => 'canonical_entities:' . $entity_type,
            'pattern' => $bundle_patterns['default'],
            'weight' => -5,
          ]);

          // Add the bundle condition.
          $pattern
            ->addSelectionCondition([
            'id' => 'entity_bundle:' . $entity_type,
            'bundles' => [
              $bundle => $bundle,
            ],
            'negate' => FALSE,
            'context_mapping' => [
              $entity_type => $entity_type,
            ],
          ]);
          $pattern
            ->save();
        }
        else {

          // This is either a language dependent pattern such as "article_es" or
          // an unknown bundle or langcode. Let's figure it out.
          $matches = NULL;
          $langcode = NULL;
          $extracted_bundle = NULL;
          $language = NULL;
          preg_match('/^(.*)_([a-z-]*)$/', $bundle, $matches);
          if (count($matches) == 3) {
            list(, $extracted_bundle, $langcode) = $matches;
            $language = $language_manager
              ->getLanguage($langcode);
          }

          // Validate bundle, langcode and language.
          if (!isset($bundle_info[$extracted_bundle]) || $langcode == NULL || $language == NULL) {
            $messages[] = t('Unrecognized entity bundle @entity:@bundle was not processed. It defines the following patterns: @patterns', [
              '@entity' => $entity_type,
              '@bundle' => $bundle,
              '@patterns' => print_r($entity_patterns, TRUE),
            ]);
            continue;
          }

          // This is a pattern for a bundle and a language, such as
          // "node_article_es".
          $pattern = PathautoPattern::create([
            'id' => $entity_type . '_' . $extracted_bundle . '_' . str_replace('-', '_', $langcode),
            'label' => $entity_label . ' ' . $bundle_info[$extracted_bundle]['label'] . ' ' . $language
              ->getName(),
            'type' => 'canonical_entities:' . $entity_type,
            'pattern' => $bundle_patterns['default'],
            'weight' => -10,
          ]);

          // Add the bundle condition.
          $pattern
            ->addSelectionCondition([
            'id' => 'entity_bundle:' . $entity_type,
            'bundles' => [
              $extracted_bundle => $extracted_bundle,
            ],
            'negate' => FALSE,
            'context_mapping' => [
              $entity_type => $entity_type,
            ],
          ]);

          // Add the language condition.
          $language_mapping = $entity_type . ':' . $entity_type_manager
            ->getDefinition($entity_type)
            ->getKey('langcode') . ':language';
          $pattern
            ->addSelectionCondition([
            'id' => 'language',
            'langcodes' => [
              $langcode => $langcode,
            ],
            'negate' => FALSE,
            'context_mapping' => [
              'language' => $language_mapping,
            ],
          ]);

          // Add the context relationship for this language.
          $pattern
            ->addRelationship($language_mapping, 'Language');
          $pattern
            ->save();
        }
      }
    }
  }

  // 3. Delete the old configuration object that stores patterns.
  $config
    ->delete();

  // 4. Print out messages.
  if (!empty($messages)) {
    return implode('</br>', $messages);
  }
}