You are here

protected function EntityHandlerBase::setEntityValues in CMS Content Sync 8

Same name and namespace in other branches
  1. 2.1.x src/Plugin/EntityHandlerBase.php \Drupal\cms_content_sync\Plugin\EntityHandlerBase::setEntityValues()
  2. 2.0.x src/Plugin/EntityHandlerBase.php \Drupal\cms_content_sync\Plugin\EntityHandlerBase::setEntityValues()

Set the values for the pulled entity.

Parameters

\Drupal\cms_content_sync\SyncIntent $intent:

\Drupal\Core\Entity\FieldableEntityInterface $entity: The translation of the entity

Return value

bool Returns TRUE when the values are set

Throws

\Drupal\Component\Plugin\Exception\PluginNotFoundException

\Drupal\cms_content_sync\Exception\SyncException

See also

Flow::PULL_*

4 calls to EntityHandlerBase::setEntityValues()
DefaultMenuLinkContentHandler::setEntityValues in src/Plugin/cms_content_sync/entity_handler/DefaultMenuLinkContentHandler.php
Set the values for the pulled entity.
DefaultNodeHandler::setEntityValues in src/Plugin/cms_content_sync/entity_handler/DefaultNodeHandler.php
Set the values for the pulled entity.
DefaultTaxonomyHandler::pull in src/Plugin/cms_content_sync/entity_handler/DefaultTaxonomyHandler.php
Pull the remote entity.
EntityHandlerBase::pull in src/Plugin/EntityHandlerBase.php
Pull the remote entity.
2 methods override EntityHandlerBase::setEntityValues()
DefaultMenuLinkContentHandler::setEntityValues in src/Plugin/cms_content_sync/entity_handler/DefaultMenuLinkContentHandler.php
Set the values for the pulled entity.
DefaultNodeHandler::setEntityValues in src/Plugin/cms_content_sync/entity_handler/DefaultNodeHandler.php
Set the values for the pulled entity.

File

src/Plugin/EntityHandlerBase.php, line 505

Class

EntityHandlerBase
Common base class for entity handler plugins.

Namespace

Drupal\cms_content_sync\Plugin

Code

protected function setEntityValues(PullIntent $intent, FieldableEntityInterface $entity = null) {
  if (!$entity) {
    $entity = $intent
      ->getEntity();
  }

  /** @var \Drupal\Core\Entity\EntityFieldManagerInterface $entityFieldManager */
  $entityFieldManager = \Drupal::service('entity_field.manager');
  $type = $entity
    ->getEntityTypeId();
  $bundle = $entity
    ->bundle();
  $field_definitions = $entityFieldManager
    ->getFieldDefinitions($type, $bundle);
  $entity_type = \Drupal::entityTypeManager()
    ->getDefinition($intent
    ->getEntityType());
  $label = $entity_type
    ->getKey('label');
  if ($label && !$intent
    ->shouldMergeChanges() && $this
    ->hasLabelProperty()) {
    $entity
      ->set($label, $intent
      ->getOperation()
      ->getName($intent
      ->getActiveLanguage()));
  }
  $static_fields = $this
    ->getStaticFields();
  $is_translatable = $this
    ->isEntityTypeTranslatable($entity);
  $is_translation = boolval($intent
    ->getActiveLanguage());
  $user = \Drupal::currentUser();
  if (static::USER_PROPERTY && $entity
    ->hasField(static::USER_PROPERTY) && !$intent
    ->getEntityStatus()
    ->isOverriddenLocally()) {
    $entity
      ->set(static::USER_PROPERTY, [
      'target_id' => $user
        ->id(),
    ]);
  }
  if (static::USER_REVISION_PROPERTY && $entity
    ->hasField(static::USER_REVISION_PROPERTY)) {
    $entity
      ->set(static::USER_REVISION_PROPERTY, [
      'target_id' => $user
        ->id(),
    ]);
  }
  if (static::REVISION_TRANSLATION_AFFECTED_PROPERTY && $entity
    ->hasField(static::REVISION_TRANSLATION_AFFECTED_PROPERTY)) {
    $entity
      ->set(static::REVISION_TRANSLATION_AFFECTED_PROPERTY, 1);
  }
  foreach ($field_definitions as $key => $field) {
    $handler = $this->flow
      ->getFieldHandler($type, $bundle, $key);
    if (!$handler) {
      continue;
    }

    // This field cannot be updated.
    if (in_array($key, $static_fields) && SyncIntent::ACTION_CREATE != $intent
      ->getAction()) {
      continue;
    }
    if ($is_translatable && $is_translation && !$field
      ->isTranslatable()) {
      continue;
    }
    if ('image' == $field
      ->getType() || 'file' == $field
      ->getType()) {

      // Focal Point takes information from the image field directly
      // so we have to set it before the entity is saved the first time.
      $data = $intent
        ->getProperty($key);
      foreach ($data as &$value) {

        /**
         * @var \Drupal\file\Entity\File $file
         */
        $file = $intent
          ->loadEmbeddedEntity($value);
        if ($file) {
          if ('image' == $field
            ->getType()) {
            $moduleHandler = \Drupal::service('module_handler');
            if ($moduleHandler
              ->moduleExists('crop') && $moduleHandler
              ->moduleExists('focal_point')) {

              /**
               * @var \Drupal\crop\Entity\Crop $crop
               */
              $crop = Crop::findCrop($file
                ->getFileUri(), 'focal_point');
              if ($crop) {
                $position = $crop
                  ->position();

                // Convert absolute to relative.
                $size = getimagesize($file
                  ->getFileUri());
                $value['focal_point'] = $position['x'] / $size[0] * 100 . ',' . $position['y'] / $size[1] * 100;
              }
            }
          }
        }
      }
      $intent
        ->overwriteProperty($key, $data);
      continue;
    }
    $handler
      ->pull($intent);
  }
  if (PullIntent::PULL_UPDATE_UNPUBLISHED === $this->flow
    ->getEntityTypeConfig($this->entityTypeName, $this->bundleName)['import_updates']) {
    if ($entity instanceof NodeInterface) {
      if ($entity
        ->id()) {
        $entity
          ->isDefaultRevision(false);
      }
      else {
        $entity
          ->setPublished(false);
      }
    }
  }
  try {
    $this
      ->saveEntity($entity, $intent);
  } catch (\Exception $e) {
    throw new SyncException(SyncException::CODE_ENTITY_API_FAILURE, $e);
  }

  // We can't set file fields until the source entity has been saved.
  // Otherwise Drupal will throw Exceptions:
  // Error message is: InvalidArgumentException: Invalid translation language (und) specified.
  // Occurs when using translatable entities referencing files.
  $changed = false;
  foreach ($field_definitions as $key => $field) {
    $handler = $this->flow
      ->getFieldHandler($type, $bundle, $key);
    if (!$handler) {
      continue;
    }

    // This field cannot be updated.
    if (in_array($key, $static_fields) && SyncIntent::ACTION_CREATE != $intent
      ->getAction()) {
      continue;
    }
    if ($is_translatable && $is_translation && !$field
      ->isTranslatable()) {
      continue;
    }
    if ('image' != $field
      ->getType() && 'file' != $field
      ->getType()) {
      continue;
    }
    $handler
      ->pull($intent);
    $changed = true;
  }
  if (!$intent
    ->getActiveLanguage()) {
    $created = $intent
      ->getProperty('created');

    // See https://www.drupal.org/project/drupal/issues/2833378
    if ($created && method_exists($entity, 'getCreatedTime') && method_exists($entity, 'setCreatedTime')) {
      if ($created !== $entity
        ->getCreatedTime()) {
        $entity
          ->setCreatedTime($created);
        $changed = true;
      }
    }
    if ($entity instanceof EntityChangedInterface) {
      $entity
        ->setChangedTime(time());
      $changed = true;
    }
  }
  if ($changed) {
    try {
      $this
        ->saveEntity($entity, $intent);
    } catch (\Exception $e) {
      throw new SyncException(SyncException::CODE_ENTITY_API_FAILURE, $e);
    }
  }
  if ($is_translatable && !$intent
    ->getActiveLanguage()) {
    $languages = $intent
      ->getTranslationLanguages();
    foreach ($languages as $language) {

      /**
       * If the provided entity is fieldable, translations are as well.
       *
       * @var \Drupal\Core\Entity\FieldableEntityInterface $translation
       */
      if ($entity
        ->hasTranslation($language)) {
        $translation = $entity
          ->getTranslation($language);
      }
      else {
        $translation = $entity
          ->addTranslation($language);
      }
      $intent
        ->changeTranslationLanguage($language);
      if (!$this
        ->ignorePull($intent)) {
        $this
          ->setEntityValues($intent, $translation);
      }
    }

    // Delete translations that were deleted on master site.
    if (boolval($this->settings['import_deletion_settings']['import_deletion'])) {
      $existing = $entity
        ->getTranslationLanguages(false);
      foreach ($existing as &$language) {
        $language = $language
          ->getId();
      }
      $languages = array_diff($existing, $languages);
      if (count($languages)) {
        foreach ($languages as $language) {
          $entity
            ->removeTranslation($language);
        }
        try {
          $this
            ->saveEntity($entity, $intent);
        } catch (\Exception $e) {
          throw new SyncException(SyncException::CODE_ENTITY_API_FAILURE, $e);
        }
      }
    }
    $intent
      ->changeTranslationLanguage();
  }
  return true;
}