You are here

class UpdateService in Apigee API Catalog 8.2

Class UpdateService.

Hierarchy

Expanded class hierarchy of UpdateService

1 string reference to 'UpdateService'
apigee_api_catalog.services.yml in ./apigee_api_catalog.services.yml
apigee_api_catalog.services.yml
1 service uses UpdateService
apigee_api_catalog.updates in ./apigee_api_catalog.services.yml
Drupal\apigee_api_catalog\UpdateService

File

src/UpdateService.php, line 37

Namespace

Drupal\apigee_api_catalog
View source
class UpdateService {

  /**
   * Drupal\Component\Uuid\UuidInterface definition.
   *
   * @var \Drupal\Component\Uuid\UuidInterface
   */
  protected $uuid;

  /**
   * Drupal\Core\Config\ConfigFactoryInterface definition.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * Drupal\Core\Extension\ModuleHandlerInterface definition.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * Drupal\Core\Entity\EntityTypeManagerInterface definition.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Drupal\Core\Entity\EntityFieldManagerInterface definition.
   *
   * @var \Drupal\Core\Entity\EntityFieldManagerInterface
   */
  protected $entityFieldManager;

  /**
   * Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface definition.
   *
   * @var \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface
   */
  protected $lastInstalledSchemaRepository;

  /**
   * Constructs a new UpdateService object.
   */
  public function __construct(UuidInterface $uuid, ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, EntityLastInstalledSchemaRepositoryInterface $last_installed_schema_repository) {
    $this->uuid = $uuid;
    $this->configFactory = $config_factory;
    $this->moduleHandler = $module_handler;
    $this->entityTypeManager = $entity_type_manager;
    $this->entityFieldManager = $entity_field_manager;
    $this->lastInstalledSchemaRepository = $last_installed_schema_repository;
  }

  /**
   * Create API Doc node type and fields if updating from 1.x.
   *
   * @return string
   *   A message to display.
   */
  public function update8802() {
    $module = 'apigee_api_catalog';
    $configPath = drupal_get_path('module', $module) . '/config';
    $configToImport['install'] = [
      'node.type.apidoc',
      'core.base_field_override.node.apidoc.title',
      'field.field.node.apidoc.body',
      'core.entity_form_display.node.apidoc.default',
      'core.entity_view_display.node.apidoc.default',
    ];
    if ($this->moduleHandler
      ->moduleExists('views')) {
      $configToImport['optional'][] = 'views.view.api_catalog_admin';
      $configToImport['optional'][] = 'views.view.apigee_api_catalog';
    }
    foreach ($configToImport as $dir => $configs) {
      foreach ($configs as $config) {
        if (!$this->configFactory
          ->listAll($config)) {
          $raw = file_get_contents("{$configPath}/{$dir}/{$config}.yml");
          $data = Yaml::decode($raw);
          $this->configFactory
            ->getEditable($config)
            ->setData($data)
            ->set('uuid', $this->uuid
            ->generate())
            ->save(TRUE);
        }
      }
    }
    $fields = [
      'field_apidoc_spec_md5',
      'field_apidoc_fetched_timestamp',
      'field_apidoc_spec_file_source',
      'field_apidoc_spec',
      'field_apidoc_file_link',
    ];
    $source = new FileStorage("{$configPath}/install");
    foreach ($fields as $field) {
      if (!FieldStorageConfig::loadByName('node', $field)) {
        $contents = $source
          ->read("field.storage.node.{$field}");

        // Somehow it doesn't take allowed_values...
        if ($field == 'field_apidoc_spec_file_source') {
          $contents['settings']['allowed_values'] = [];
        }
        $this->entityTypeManager
          ->getStorage('field_storage_config')
          ->create($contents)
          ->save();
      }
      if (!FieldConfig::loadByName('node', 'apidoc', $field)) {
        $this->entityTypeManager
          ->getStorage('field_config')
          ->create($source
          ->read("field.field.node.apidoc.{$field}"))
          ->save();
      }
    }

    // Add back allowed_values to field_apidoc_spec_file_source.
    if ($field = FieldStorageConfig::loadByName('node', 'field_apidoc_spec_file_source')) {
      $field
        ->setSetting('allowed_values', [
        'file' => 'File',
        'url' => 'URL',
      ])
        ->save();
    }
    $this->entityTypeManager
      ->clearCachedDefinitions();
    return 'Created API Doc node type and fields.';
  }

  /**
   * Recreate other fields added to API Doc entity onto the API Doc node type.
   *
   * @return string
   *   A message to display.
   */
  public function update8803() {
    $this->entityFieldManager
      ->clearCachedFieldDefinitions();
    $fieldStorageConfig = $this->entityTypeManager
      ->getStorage('field_storage_config');
    $fieldConfig = $this->entityTypeManager
      ->getStorage('field_config');

    // Get the last known state of the API Doc entity type.
    $apidocFieldDefs = $this->lastInstalledSchemaRepository
      ->getLastInstalledFieldStorageDefinitions('apidoc');
    foreach ($apidocFieldDefs as $fieldName => $definition) {

      // Only look for field starting with "field_", as those were added
      // through the UI.
      if (substr($fieldName, 0, 6) === 'field_') {

        // Namespace this custom field to avoid collisions.
        // Machine names have a maximum length of 32 characters https://www.drupal.org/node/2232665
        $newFieldName = substr($fieldName . '_apidoc', 0, 32);
        if (!FieldStorageConfig::loadByName('node', $newFieldName)) {
          $fieldStorageConfig
            ->create([
            'entity_type' => 'node',
            'field_name' => $newFieldName,
            'type' => $definition
              ->getType(),
            'cardinality' => $definition
              ->getCardinality(),
            'settings' => $definition
              ->getSettings(),
            'label' => $definition
              ->getLabel(),
          ])
            ->save();
        }
        if (!FieldConfig::loadByName('node', 'apidoc', $newFieldName)) {
          $fieldConfig
            ->create([
            'field_name' => $newFieldName,
            'entity_type' => 'node',
            'bundle' => 'apidoc',
            'label' => $definition
              ->getLabel(),
            'description' => $definition
              ->getDescription(),
            'settings' => $definition
              ->getSettings(),
          ])
            ->save();
        }
        $this
          ->addToFieldMap($fieldName, $newFieldName);
      }
    }
    return 'Recreated custom fields (if any) added to the API Doc entity onto the API Doc node type.';
  }

  /**
   * Convert API Doc entities to nodes, migrating data.
   *
   * @param array|null $sandbox
   *   The sandbox for batch operations.
   */
  public function update8804(&$sandbox) {

    // If 1.x was never installed, there is no apidoc entity saved previously.
    $entity_update_manager = \Drupal::entityDefinitionUpdateManager();
    if (!$entity_update_manager
      ->getEntityType('apidoc')) {
      $sandbox['#finished'] = 1;
      return 'No API Doc entities found, no data migration needed.';
    }
    $fieldMap = $this
      ->getFieldMap();
    $nodeStorage = $this->entityTypeManager
      ->getStorage('node');
    $apidocStorage = $this->entityTypeManager
      ->getStorage('apidoc');
    if (!isset($sandbox['progress'])) {
      $query = $apidocStorage
        ->getQuery();
      $total = $query
        ->count()
        ->execute();
      $sandbox['progress'] = 0;
      $sandbox['total'] = $total;
    }
    if (empty($sandbox['total'])) {
      $sandbox['#finished'] = 1;
      return 'No API Doc entities found, no data migration needed.';
    }

    // Migrate in chunks of 20.
    $query = $apidocStorage
      ->getQuery()
      ->sort('id')
      ->range($sandbox['progress'], 20);
    $ids = $query
      ->execute();
    $apidocs = $apidocStorage
      ->loadMultiple($ids);
    foreach ($apidocs as $apidoc) {
      $values = [
        'type' => 'apidoc',
        'title' => $apidoc
          ->label(),
        'body' => [
          'value' => $apidoc->description->value,
          'format' => 'full_html',
        ],
        'status' => $apidoc->status->value,
        'created' => $apidoc->created->value,
        'changed' => $apidoc->changed->value,
        'field_apidoc_spec_file_source' => $apidoc->spec_file_source->value,
        'field_apidoc_spec_md5' => $apidoc->spec_md5->value,
        'field_apidoc_fetched_timestamp' => $apidoc->fetched_timestamp->value,
        'field_apidoc_spec' => $apidoc->spec
          ->getValue(),
        'field_apidoc_file_link' => $apidoc->file_link
          ->getValue(),
      ];
      foreach ($fieldMap as $old => $new) {
        $values[$new] = $apidoc->{$old}
          ->getValue();
      }
      $node = $nodeStorage
        ->create($values);
      $node
        ->save();
      $apidoc
        ->delete();
      $sandbox['progress']++;
    }
    $sandbox['#finished'] = $sandbox['progress'] / $sandbox['total'];
    return 'Converted API Doc entities to nodes, migrating data.';
  }

  /**
   * Delete API Doc entity definition.
   */
  public function update8805() {

    // Get the last known state of the API Doc entity type.
    $entity_update_manager = \Drupal::entityDefinitionUpdateManager();
    if ($entity_type = $entity_update_manager
      ->getEntityType('apidoc')) {
      $entity_update_manager
        ->uninstallEntityType($entity_type);

      // Clear all caches.
      drupal_flush_all_caches();
    }
    return 'The API Doc deprecated entity type has been removed from the system.';
  }

  /**
   * Recreate API Doc entity definition.
   *
   * Rollback update8805().
   */
  public function update8806() {
    \Drupal::entityTypeManager()
      ->clearCachedDefinitions();
    $entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager();
    $entity_definition_update_manager
      ->installEntityType(\Drupal::entityTypeManager()
      ->getDefinition('apidoc'));

    // Clear all caches.
    drupal_flush_all_caches();
    return 'Installed API Doc deprecated entity type.';
  }

  /**
   * This will set the field field_apidoc_spec_file_source as not required.
   */
  public function update8807() {
    $field = FieldConfig::loadByName('node', 'apidoc', 'field_apidoc_spec_file_source');
    $field
      ->set('required', FALSE)
      ->save();

    // Clear all caches.
    drupal_flush_all_caches();
    return 'Updated field_apidoc_spec_file_source required attribute to false.';
  }

  /**
   * Get the field map from apidoc fields to node fields.
   *
   * @return array
   *   The field mapping.
   */
  protected function getFieldMap() : array {
    $map = \Drupal::state()
      ->get('apigee_api_catalog_update_8803_fieldmap', []);
    return $map;
  }

  /**
   * Add a field to the field map.
   *
   * @param string $old
   *   The apidoc field name.
   * @param string $new
   *   The node field name.
   */
  protected function addToFieldMap(string $old, string $new) {
    $map = $this
      ->getFieldMap();
    $map[$old] = $new;
    \Drupal::state()
      ->set('apigee_api_catalog_update_8803_fieldmap', $map);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
UpdateService::$configFactory protected property Drupal\Core\Config\ConfigFactoryInterface definition.
UpdateService::$entityFieldManager protected property Drupal\Core\Entity\EntityFieldManagerInterface definition.
UpdateService::$entityTypeManager protected property Drupal\Core\Entity\EntityTypeManagerInterface definition.
UpdateService::$lastInstalledSchemaRepository protected property Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface definition.
UpdateService::$moduleHandler protected property Drupal\Core\Extension\ModuleHandlerInterface definition.
UpdateService::$uuid protected property Drupal\Component\Uuid\UuidInterface definition.
UpdateService::addToFieldMap protected function Add a field to the field map.
UpdateService::getFieldMap protected function Get the field map from apidoc fields to node fields.
UpdateService::update8802 public function Create API Doc node type and fields if updating from 1.x.
UpdateService::update8803 public function Recreate other fields added to API Doc entity onto the API Doc node type.
UpdateService::update8804 public function Convert API Doc entities to nodes, migrating data.
UpdateService::update8805 public function Delete API Doc entity definition.
UpdateService::update8806 public function Recreate API Doc entity definition.
UpdateService::update8807 public function This will set the field field_apidoc_spec_file_source as not required.
UpdateService::__construct public function Constructs a new UpdateService object.