rabbit_hole-8.x-1.x-dev/rabbit_hole.install

rabbit_hole.install
<?php

/**
 * @file
 * Install, update and uninstall functions for the Rabbit Hole module.
 */

use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Site\Settings;
use Drupal\field\Entity\FieldConfig;
use Drupal\rabbit_hole\BehaviorSettingsManager;
use Drupal\rabbit_hole\Entity\BehaviorSettings;

/**
 * Install redirect_fallback_action field.
 */
function rabbit_hole_update_8100() {
  $rh_definitions = \Drupal::service('plugin.manager.rabbit_hole_entity_plugin')->getDefinitions();
  $update_manager = \Drupal::entityDefinitionUpdateManager();

  $rh_redirect_fallback_field = BaseFieldDefinition::create('string')
    ->setName('rh_redirect_fallback_action')
    ->setLabel(t('Rabbit Hole redirect fallback action'))
    ->setDescription(t('Specifies the action that should be used when the redirect path is invalid or empty.'));

  foreach ($rh_definitions as $rh_module => $definition) {
    $entity_type_id = $definition['entityType'];
    $field_storage_definition = $update_manager->getFieldStorageDefinition('rh_redirect_fallback_action', $entity_type_id);
    if (empty($field_storage_definition)) {
      $update_manager->installFieldStorageDefinition('rh_redirect_fallback_action', $entity_type_id, $rh_module, $rh_redirect_fallback_field);
    }
  }
}

/**
 * Update redirect_fallback_action field default values.
 */
function rabbit_hole_update_8101() {
  /** @var \Drupal\Core\Config\ConfigFactoryInterface $configFactory */
  $configFactory = \Drupal::configFactory();
  /** @var \Drupal\Core\Config\StorageInterface $configStorage */
  $configStorage = \Drupal::service('config.storage');

  foreach ($configStorage->listAll('rabbit_hole.behavior_settings') as $configName) {
    $config = $configFactory->getEditable($configName);
    if (!$config->get('redirect_fallback_action')) {
      $config->set('redirect_fallback_action', 'access_denied')->save();
    }
  }
}

/**
 * Create rabbit hole settings with enabled entity types.
 */
function rabbit_hole_update_8103() {
  $config = \Drupal::configFactory()->getEditable('rabbit_hole.settings');
  // Skip if already configured.
  if (!empty($config->get('enabled_entity_types'))) {
    return;
  }

  $entity_types = \Drupal::service('plugin.manager.rabbit_hole_entity_plugin')->loadSupportedEntityTypes();
  $config->set('enabled_entity_types', $entity_types)
    ->save();
}

/**
 * Create new rabbit hole field to keep rabbit hole settings.
 */
function rabbit_hole_update_8104() {
  /** @var \Drupal\rabbit_hole\EntityHelper $rh_entity_helper */
  $rh_entity_helper = \Drupal::service('rabbit_hole.entity_helper');
  /** @var \Drupal\rabbit_hole\BehaviorSettingsManagerInterface $rh_behavior_settings_manager */
  $rh_behavior_settings_manager = \Drupal::service('rabbit_hole.behavior_settings_manager');

  $field_name = BehaviorSettingsManager::FIELD_NAME;
  // Go through all rh supported entities and skip not enabled ones.
  foreach ($rh_entity_helper->getSupportedEntityTypes() as $entity_type_id => $entity_type) {
    if (!$rh_behavior_settings_manager->entityTypeIsEnabled($entity_type_id)) {
      continue;
    }

    // Get through all bundles of the entity types and skip bundles with
    // disabled allow_override setting.
    foreach ($rh_entity_helper->getBundleInfo($entity_type_id) as $bundle_name => $bundle_info) {
      $behavior_settings = $rh_behavior_settings_manager->getBehaviorSettings($entity_type_id, $bundle_name);
      if (empty($behavior_settings['allow_override'])) {
        continue;
      }

      if (FieldConfig::loadByName($entity_type_id, $bundle_name, $field_name)) {
        continue;
      }

      $rh_entity_helper->createRabbitHoleField($entity_type_id, $bundle_name);
    }
  }
}

/**
 * Move redirect settings into new "configuration" property.
 */
function rabbit_hole_update_8105() {
  $config_factory = \Drupal::configFactory();
  foreach ($config_factory->listAll('rabbit_hole.behavior_settings.') as $rh_config_name) {
    $config = $config_factory->getEditable($rh_config_name);
    $action = $config->get('action');
    $redirect = $config->get('redirect');

    $configuration = [];
    $redirect_properties = [
      'redirect', 'redirect_code', 'redirect_fallback_action',
    ];

    // Handle actions that have either "redirect" type or were extended from
    // redirect and have other action name, but same properties.
    if (!empty($redirect)) {
      foreach ($redirect_properties as $property) {
        $config_value = $config->get($property);
        // We preserve configuration if main property "redirect" is not empty and
        // other properties are not NULL.
        if (isset($config_value)) {
          $configuration[$property] = $config_value;
        }
        $config->clear($property);
      }
    }
    // Handle any other potential custom actions that could have some custom
    // configuration.
    elseif ($action && $action !== 'page_redirect') {
      // Remove redirect configuration from other actions that existed for no
      // reason.
      foreach ($redirect_properties as $property) {
        $config->clear($property);
      }

      $fields = [];
      \Drupal::service('plugin.manager.rabbit_hole_behavior_plugin')
        ->createInstance($action)
        ->alterExtraFields($fields);

      // There is no direct relation between base fields and config properties,
      // so we can only guess.
      foreach ($fields as $field_name => $field_definition) {
        $config_field_key = substr($field_name, 3);
        $config_value = $config->get($config_field_key);
        if (isset($config_value)) {
          $configuration[$config_field_key] = $config_value;
        }
        $config->clear($config_field_key);
      }
    }

    // Save all action-related configuration into "configuration" property.
    $config->set('configuration', $configuration);
    $config->save(TRUE);
  }
}

/**
 * Move data from previous "rh_" base fields to new "Rabbit Hole" field.
 */
function rabbit_hole_update_8106(&$sandbox) {
  $items_per_pass = Settings::get('entity_update_batch_size') ?? 50;

  // Get entity types that might have overridden values.
  if (empty($sandbox['entity_types'])) {
    $sandbox['entity_types'] = [];
    $sandbox['progress'] = 0;
    $sandbox['max'] = 0;

    $entity_helper = \Drupal::service('rabbit_hole.entity_helper');
    $settings_manager = \Drupal::service('rabbit_hole.behavior_settings_manager');
    foreach ($entity_helper->getSupportedEntityTypes() as $entity_type_id => $entity_type) {
      $is_enabled = $settings_manager->entityTypeIsEnabled($entity_type_id);
      if (!$is_enabled) {
        continue;
      }

      foreach ($entity_helper->getBundleInfo($entity_type_id) as $bundle_name => $bundle_info) {
        $settings = $settings_manager->getBehaviorSettings($entity_type_id, $bundle_name);
        if (($settings['allow_override'] ?? NULL)) {
          $sandbox['entity_types'][$entity_type_id]['bundles'][] = $bundle_name;
        }
      }
    }

    foreach ($sandbox['entity_types'] as $entity_type_id => $entity_type_data) {
      if (empty($entity_type_data['bundles'])) {
        continue;
      }

      $storage = \Drupal::entityTypeManager()->getStorage($entity_type_id);
      $max_query = $storage->getQuery()
        ->accessCheck(FALSE)
        ->exists('rh_action')
        ->count();

      $bundle_key = $storage->getEntityType()->getKey('bundle');
      if ($bundle_key) {
        $max_query->condition($bundle_key, $entity_type_data['bundles'], 'IN');
      }

      // Set initial values for entity type.
      $sandbox['entity_types'][$entity_type_id]['progress'] = 0;
      $sandbox['entity_types'][$entity_type_id]['current'] = 0;
      $sandbox['entity_types'][$entity_type_id]['finished'] = FALSE;
      $sandbox['max'] += $sandbox['entity_types'][$entity_type_id]['max'] = $max_query->execute();
    }
  }

  // Stop process if there are no entity types available, or there are no
  // items to process.
  if (empty($sandbox['entity_types']) || empty($sandbox['max'])) {
    $sandbox['#finished'] = 1;
    return t('There are no entities to be updated.');
  }

  // Get the first unprocessed entity type.
  foreach ($sandbox['entity_types'] as $entity_type_id => $entity_type_data) {
    if ($entity_type_data['progress'] < $entity_type_data['max']) {
      break;
    }
  }

  $storage = \Drupal::entityTypeManager()->getStorage($entity_type_id);
  $id_key = $storage->getEntityType()->getKey('id');
  $bundle_key = $storage->getEntityType()->getKey('bundle');

  $iteration_query = $storage->getQuery()
    ->accessCheck(FALSE)
    ->condition($id_key, $sandbox['entity_types'][$entity_type_id]['current'], '>')
    ->sort($id_key)
    ->exists('rh_action')
    ->range(0, $items_per_pass);
  if ($bundle_key) {
    $iteration_query->condition($bundle_key, $sandbox['entity_types'][$entity_type_id]['bundles'], 'IN');
  }
  $ids = $iteration_query->execute();

  // Process entities.
  if (!empty($ids)) {
    /** @var \Drupal\Core\Entity\ContentEntityInterface[] $entities */
    $entities = $storage->loadMultiple(array_values($ids));
    foreach ($entities as $entity) {
      if ($entity->hasField('rabbit_hole__settings') && $entity->hasField('rh_action')) {
        // Handle entity translations if available.
        foreach ($entity->getTranslationLanguages() as $langcode => $language) {
          $entity_translated = $entity->getTranslation($langcode);

          $action = $entity_translated->get('rh_action')->value;
          $value = [
            'action' => $action,
          ];

          $known_actions = [
            'access_denied',
            'display_page',
            'page_not_found',
            'page_redirect',
            'bundle_default',
          ];
          // Configuration exists only in "page_redirect" contrib action.
          if ($action === 'page_redirect') {
            $redirect_fields = [
              'rh_redirect' => 'redirect',
              'rh_redirect_response' => 'redirect_code',
              'rh_redirect_fallback_action' => 'redirect_fallback_action',
            ];

            foreach ($redirect_fields as $prev_field => $new_property) {
              if ($entity_translated->hasField($prev_field)) {
                $value['settings'][$new_property] = $entity_translated->get($prev_field)->value;
                $entity_translated->set($prev_field, NULL);
              }
            }
          }
          // If action is custom one, then we're loading defined fields.
          elseif (!in_array($action, $known_actions, TRUE)) {
            $fields = [];
            \Drupal::service('plugin.manager.rabbit_hole_behavior_plugin')
              ->createInstance($action)
              ->alterExtraFields($fields);

            foreach ($fields as $prev_field => $field_definition) {
              $new_property = $prev_field;
              if (preg_match('/^rh_.*/', $prev_field)) {
                $new_property = substr($prev_field, 3);
              }
              if ($entity_translated->hasField($prev_field)) {
                $value['settings'][$new_property] = $entity_translated->get($prev_field)->value;
                $entity_translated->set($prev_field, NULL);
              }
            }

            // If we have "redirect_response" property, then most likely the
            // custom action is extending "Page Redirect". In that case, we should
            // replace it with "redirect_code".
            if (!empty($value['settings']['redirect_response'])) {
              $value['settings']['redirect_code'] = $value['settings']['redirect_response'];
              unset($value['settings']['redirect_response']);
            }
          }
          $entity_translated->set('rabbit_hole__settings', $value);
          $entity_translated->save();
        }
      }

      // Track the progress.
      $sandbox['progress']++;
      $sandbox['entity_types'][$entity_type_id]['progress']++;
      $sandbox['entity_types'][$entity_type_id]['current'] = $entity->id();
    }
  }

  $sandbox['#finished'] = $sandbox['progress'] / $sandbox['max'];
}

/**
 * Remove useless "rabbit_hole.behavior_settings.default_bundle" config.
 */
function rabbit_hole_update_8107() {
  \Drupal::configFactory()
    ->getEditable('rabbit_hole.behavior_settings.default_bundle')
    ->delete();
}

/**
 * Remove "allow_override" config from existing settings.
 */
function rabbit_hole_update_8108() {
  $config_factory = \Drupal::configFactory();
  foreach ($config_factory->listAll('rabbit_hole.behavior_settings.') as $rh_config_name) {
    $config = $config_factory->getEditable($rh_config_name);
    $config->clear('allow_override');
    $config->save();
  }
}

/**
 * Remove useless "rabbit_hole.behavior_settings.default" config.
 */
function rabbit_hole_update_8109() {
  \Drupal::configFactory()
    ->getEditable('rabbit_hole.behavior_settings.default')
    ->delete();
}

/**
 * Add "no_bypass" settings to existing configuration.
 */
function rabbit_hole_update_8110() {
  $config_factory = \Drupal::configFactory();
  $configs = $config_factory->listAll('rabbit_hole.behavior_settings');

  foreach ($configs as $config) {
    $config = $config_factory->getEditable($config);
    // Skip configs that already have "no_bypass" values.
    if ($config->get('no_bypass') !== NULL) {
      continue;
    }
    $config->set('no_bypass', FALSE);
    $config->save(TRUE);
  }
}

/**
 * Add "bypass_message" settings to existing configuration.
 */
function rabbit_hole_update_8111() {
  $config_factory = \Drupal::configFactory();
  $configs = $config_factory->listAll('rabbit_hole.behavior_settings');

  foreach ($configs as $config) {
    $config = $config_factory->getEditable($config);
    $config->set('bypass_message', FALSE);
    $config->save(TRUE);
  }
}

/**
 * Update "rabbit_hole.behavior_settings.*" configurations.
 */
function rabbit_hole_update_8112() {
  $entity_type_manager = \Drupal::entityTypeManager();
  /** @var \Drupal\rabbit_hole\BehaviorSettingsInterface[] $behavior_settings */
  $behavior_settings = $entity_type_manager->getStorage('behavior_settings')
    ->loadMultiple();

  foreach ($behavior_settings as $behavior_setting) {
    $entity_type_name = $behavior_setting->get('entity_type_id');
    if (empty($entity_type_name)) {
      continue;
    }
    $entity_type_id = $entity_type_manager->getStorage($entity_type_name)->getEntityType()->getBundleOf() ?? $entity_type_name;
    $bundle = $behavior_setting->get('entity_id');

    $behavior_setting->set('id', $entity_type_id . '.' . ($bundle ?? $entity_type_id));
    $behavior_setting->set('targetEntityType', $entity_type_id);
    $behavior_setting->set('bundle', $bundle ?? $entity_type_id);
    $behavior_setting->save();
  }
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc