You are here

public function Importer::importContent in Default Content for D8 2.0.x

Same name and namespace in other branches
  1. 8 src/Importer.php \Drupal\default_content\Importer::importContent()

Imports default content from a given module.

Parameters

string $module: The module to create the default content from.

Return value

\Drupal\Core\Entity\EntityInterface[] An array of created entities keyed by their UUIDs.

Overrides ImporterInterface::importContent

File

src/Importer.php, line 131

Class

Importer
A service for handling import of default content.

Namespace

Drupal\default_content

Code

public function importContent($module) {
  $created = [];
  $folder = drupal_get_path('module', $module) . "/content";
  if (file_exists($folder)) {
    $root_user = $this->entityTypeManager
      ->getStorage('user')
      ->load(1);
    $this->accountSwitcher
      ->switchTo($root_user);
    $file_map = [];
    foreach ($this->entityTypeManager
      ->getDefinitions() as $entity_type_id => $entity_type) {
      $reflection = new \ReflectionClass($entity_type
        ->getClass());

      // We are only interested in importing content entities.
      if ($reflection
        ->implementsInterface(ConfigEntityInterface::class)) {
        continue;
      }
      if (!file_exists($folder . '/' . $entity_type_id)) {
        continue;
      }
      $files = $this->contentFileStorage
        ->scan($folder . '/' . $entity_type_id);

      // Default content uses drupal.org as domain.
      // @todo Make this use a uri like default-content:.
      $this->linkManager
        ->setLinkDomain($this->linkDomain);

      // Parse all of the files and sort them in order of dependency.
      foreach ($files as $file) {
        $contents = $this
          ->parseFile($file);
        $extension = pathinfo($file->uri, PATHINFO_EXTENSION);

        // Decode the file contents.
        if ($extension == 'json') {
          $decoded = $this->serializer
            ->decode($contents, 'hal_json');

          // Get the link to this entity.
          $item_uuid = $decoded['uuid'][0]['value'];
        }
        else {
          $decoded = Yaml::decode($contents);

          // Get the UUID to this entity.
          $item_uuid = $decoded['_meta']['uuid'];
        }

        // Throw an exception when this UUID already exists.
        if (isset($file_map[$item_uuid])) {

          // Reset link domain.
          $this->linkManager
            ->setLinkDomain(FALSE);
          throw new \Exception(sprintf('Default content with uuid "%s" exists twice: "%s" "%s"', $item_uuid, $file_map[$item_uuid]->uri, $file->uri));
        }

        // Store the entity type with the file.
        $file->entity_type_id = $entity_type_id;

        // Store the file in the file map.
        $file_map[$item_uuid] = $file;

        // Create a vertex for the graph.
        $vertex = $this
          ->getVertex($item_uuid);
        $this->graph[$vertex->id]['edges'] = [];
        if ($extension == 'json') {
          if (empty($decoded['_embedded'])) {

            // No dependencies to resolve.
            continue;
          }

          // Here we need to resolve our dependencies:
          foreach ($decoded['_embedded'] as $embedded) {
            foreach ($embedded as $item) {
              $uuid = $item['uuid'][0]['value'];
              $edge = $this
                ->getVertex($uuid);
              $this->graph[$vertex->id]['edges'][$edge->id] = TRUE;
            }
          }
        }
        else {
          if (empty($decoded['_meta']['depends'])) {

            // No dependencies to resolve.
            continue;
          }

          // Here we need to resolve our dependencies:
          foreach (array_keys($decoded['_meta']['depends']) as $uuid) {
            $edge = $this
              ->getVertex($uuid);
            $this->graph[$vertex->id]['edges'][$edge->id] = TRUE;
          }
        }
      }
    }

    // @todo what if no dependencies?
    $sorted = $this
      ->sortTree($this->graph);
    foreach ($sorted as $link => $details) {
      if (!empty($file_map[$link])) {
        $file = $file_map[$link];
        $entity_type_id = $file->entity_type_id;
        $class = $this->entityTypeManager
          ->getDefinition($entity_type_id)
          ->getClass();
        $contents = $this
          ->parseFile($file);
        $extension = pathinfo($file->uri, PATHINFO_EXTENSION);
        if ($extension == 'json') {
          $entity = $this->serializer
            ->deserialize($contents, $class, 'hal_json', [
            'request_method' => 'POST',
          ]);
        }
        else {
          $entity = $this->contentEntityNormalizer
            ->denormalize(Yaml::decode($contents));
        }
        $entity
          ->enforceIsNew(TRUE);

        // Ensure that the entity is not owned by the anonymous user.
        if ($entity instanceof EntityOwnerInterface && empty($entity
          ->getOwnerId())) {
          $entity
            ->setOwner($root_user);
        }

        // If a file exists in the same folder, copy it to the designed
        // target URI.
        if ($entity instanceof FileInterface) {
          $file_source = \dirname($file->uri) . '/' . $entity
            ->getFilename();
          if (\file_exists($file_source)) {
            $target_directory = dirname($entity
              ->getFileUri());
            \Drupal::service('file_system')
              ->prepareDirectory($target_directory, FileSystemInterface::CREATE_DIRECTORY);
            $new_uri = \Drupal::service('file_system')
              ->copy($file_source, $entity
              ->getFileUri());
            $entity
              ->setFileUri($new_uri);
          }
        }
        $entity
          ->save();
        $created[$entity
          ->uuid()] = $entity;
      }
    }
    $this->eventDispatcher
      ->dispatch(DefaultContentEvents::IMPORT, new ImportEvent($created, $module));
    $this->accountSwitcher
      ->switchBack();
  }

  // Reset the tree.
  $this
    ->resetTree();

  // Reset link domain.
  $this->linkManager
    ->setLinkDomain(FALSE);
  return $created;
}