You are here

private function ImportEntityManager::importRemoteEntityNoDependencies in Acquia Content Hub 8

Saves an Entity without taking care of dependencies.

Parameters

\Drupal\acquia_contenthub\ContentHubEntityDependency $contenthub_entity: The Content Hub Entity.

Return value

\Symfony\Component\HttpFoundation\JsonResponse The Response.

Throws

\Exception Throws exception in certain cases.

1 call to ImportEntityManager::importRemoteEntityNoDependencies()
ImportEntityManager::importRemoteEntityDependencies in src/ImportEntityManager.php
Saves the current Drupal Entity and all its dependencies.

File

src/ImportEntityManager.php, line 615

Class

ImportEntityManager
Provides a service for managing imported entities' actions.

Namespace

Drupal\acquia_contenthub

Code

private function importRemoteEntityNoDependencies(ContentHubEntityDependency $contenthub_entity) {

  // Import the entity.
  $entity_type = $contenthub_entity
    ->getRawEntity()
    ->getType();
  $class = \Drupal::entityTypeManager()
    ->getDefinition($entity_type)
    ->getClass();

  // Check if this dependency has originated in this site or not.
  $site_origin = $this->contentHubEntitiesTracking
    ->getSiteOrigin();
  if ($contenthub_entity
    ->getRawEntity()
    ->getOrigin() == $site_origin) {
    $args = [
      '@type' => $contenthub_entity
        ->getRawEntity()
        ->getType(),
      '@uuid' => $contenthub_entity
        ->getRawEntity()
        ->getUuid(),
      '@origin' => $contenthub_entity
        ->getRawEntity()
        ->getOrigin(),
    ];
    $message = $this
      ->t('Cannot save "@type" entity with uuid="@uuid". It has the same origin as this site: "@origin"', $args);
    $this->loggerFactory
      ->get('acquia_contenthub')
      ->debug($message);
    return $this
      ->jsonErrorResponseMessage($message, FALSE, 400);
  }
  try {
    $entity = $this->serializer
      ->deserialize($contenthub_entity
      ->getRawEntity()
      ->json(), $class, $this->format);
  } catch (\UnexpectedValueException $e) {
    $error = $e
      ->getMessage();
    return $this
      ->jsonErrorResponseMessage($error, FALSE, 400);
  }

  // If the entity cannot be serialized (we detected it cannot be saved
  // because it has missing information) then we should not try to save it.
  if (empty($entity)) {
    $message = $this
      ->t('Entity (type = "%type", uuid = "%uuid") cannot be saved.', [
      '%type' => $entity_type,
      '%uuid' => $contenthub_entity
        ->getUuid(),
    ]);
    $this->loggerFactory
      ->get('acquia_contenthub')
      ->debug($message);
    return new JsonResponse(NULL);
  }

  // Finally Save the Entity.
  $transaction = $this->database
    ->startTransaction();
  try {

    // Add synchronization flag.
    $entity->__contenthub_entity_syncing = TRUE;
    if ($entity instanceof ContentEntityInterface && $entity
      ->hasField('path') && !$this
      ->pathAliasMovedToSeparateModule()) {
      $languages = $entity
        ->getTranslationLanguages();
      foreach ($languages as $language) {
        $entity = $entity
          ->getTranslation($language
          ->getId());
        $path = $entity
          ->get('path')
          ->first()
          ->getValue();
        if (!empty($path['pid']) || !isset($path['alias'])) {
          continue;
        }
        $raw_path = $entity
          ->id() ? '/' . $entity
          ->toUrl()
          ->getInternalPath() : $this
          ->getPathByAlias($path['alias'], $path['langcode']);
        if (!$raw_path) {
          continue;
        }
        $query = \Drupal::database()
          ->select('url_alias', 'ua')
          ->fields('ua', [
          'pid',
        ]);
        $query
          ->condition('ua.source', $raw_path);
        $query
          ->condition('ua.langcode', $language
          ->getId());
        $alias = $query
          ->execute()
          ->fetchObject();
        if (!isset($alias->pid)) {
          continue;
        }
        $path['pid'] = $alias->pid;
        $path['source'] = $raw_path;
        $entity
          ->set('path', [
          $path,
        ]);
      }
    }

    // Check if there exists a local "redirect" entity with the same hash.
    if ($entity
      ->getEntityTypeId() === 'redirect' && $entity
      ->getHash()) {

      /** @var \Drupal\redirect\Entity\Redirect $local_redirect_entity */
      $local_redirect_entity = reset(\Drupal::entityTypeManager()
        ->getStorage('redirect')
        ->loadByProperties([
        'hash' => $entity
          ->getHash(),
      ]));
      if ($local_redirect_entity && $local_redirect_entity
        ->uuid() !== $entity
        ->uuid()) {
        $this->loggerFactory
          ->get('acquia_contenthub')
          ->debug('An existing redirect entity with the same "hash" was found and overwritten by the one coming from Content Hub. Old UUID = "%old_uuid", New UUID = "%new_uuid", source = "%source", old destination = "%old_destination", new destination = "%new_destination".', [
          '%old_uuid' => $local_redirect_entity
            ->uuid(),
          '%new_uuid' => $entity
            ->uuid(),
          '%source' => $local_redirect_entity
            ->getSourceUrl(),
          '%old_destination' => $local_redirect_entity
            ->getRedirectUrl()
            ->toUriString(),
          '%new_destination' => $entity
            ->getRedirectUrl()
            ->toUriString(),
        ]);
        $local_redirect_entity
          ->delete();
      }
    }

    // Save the entity.
    $entity
      ->save();

    // Remove synchronization flag.
    unset($entity->__contenthub_entity_syncing);

    // Save this entity in the tracking for importing entities.
    $is_new_entity = $this
      ->trackImportedEntity($contenthub_entity);

    // If this is a post-dependency (paragraphs or field collections), then
    // we will need to update the host entity ONLY if we are creating this
    // entity for the first time.
    // If we are updating a paragraph, the reference is already set.
    if ($is_new_entity && $contenthub_entity
      ->isEntityDependent()) {
      $this
        ->updateHostEntity($entity);
    }

    // Do we need to create an path alias?
    $moduleHandler = \Drupal::service('module_handler');
    if ($moduleHandler
      ->moduleExists('pathauto')) {

      /** @var \Drupal\Core\Session\AccountSwitcherInterface $accountSwitcher */
      $accountSwitcher = \Drupal::service('account_switcher');
      $roles = \Drupal::entityTypeManager()
        ->getStorage('user_role')
        ->loadByProperties([
        'is_admin' => TRUE,
      ]);
      $role = reset($roles);
      if ($role) {
        $renderUser = new ContentHubUserSession($role
          ->id());
        $accountSwitcher
          ->switchTo($renderUser);
        try {

          /** @var \Drupal\pathauto\AliasStorageHelperInterface $alias_storage_helper */
          $alias_storage_helper = \Drupal::service('pathauto.alias_storage_helper');
          $languages = $entity
            ->getTranslationLanguages();
          foreach ($languages as $language) {
            $entity = $entity
              ->getTranslation($language
              ->getId());
            if ($entity && $entity
              ->hasField('path')) {
              $path = $entity
                ->get('path')
                ->getValue();
              if (!$this
                ->pathAliasMovedToSeparateModule() && ($path = reset($path))) {
                $path['source'] = empty($path['source']) ? '/' . $entity
                  ->toUrl()
                  ->getInternalPath() : $path['source'];
                $path['language'] = isset($path['langcode']) ? $path['langcode'] : $language
                  ->getId();
                $existing_alias = $alias_storage_helper
                  ->loadBySource($path['source'], $language
                  ->getId());
                $existing_alias = !empty($existing_alias) ? $existing_alias : NULL;
                $alias_storage_helper
                  ->save($path, $existing_alias);
              }
            }
          }
        } catch (\Exception $e) {
          $this->loggerFactory
            ->get('acquia_contenthub')
            ->debug('Could not generate path alias for (%entity_type, %entity_id). Error message: %message', [
            '%entity_type' => $entity
              ->getEntityTypeId(),
            '%entity_id' => $entity
              ->id(),
            '%message' => $e
              ->getMessage(),
          ]);
        }
        $accountSwitcher
          ->switchBack();
      }
    }
  } catch (\Exception $e) {
    $transaction
      ->rollback();
    $this->loggerFactory
      ->get('acquia_contenthub')
      ->error($e
      ->getMessage());
    throw $e;
  }
  $serialized_entity = $this->serializer
    ->normalize($entity, 'json');
  return new JsonResponse($serialized_entity);
}