You are here

class LinkItemNormalizer in Replication 8

Same name and namespace in other branches
  1. 8.2 src/Normalizer/LinkItemNormalizer.php \Drupal\replication\Normalizer\LinkItemNormalizer

Hierarchy

Expanded class hierarchy of LinkItemNormalizer

1 string reference to 'LinkItemNormalizer'
replication.services.yml in ./replication.services.yml
replication.services.yml
1 service uses LinkItemNormalizer
replication.normalizer.link_item in ./replication.services.yml
Drupal\replication\Normalizer\LinkItemNormalizer

File

src/Normalizer/LinkItemNormalizer.php, line 15

Namespace

Drupal\replication\Normalizer
View source
class LinkItemNormalizer extends FieldItemNormalizer {

  /**
   * The interface or class that this Normalizer supports.
   *
   * @var string
   */
  protected $supportedInterfaceOrClass = 'Drupal\\link\\Plugin\\Field\\FieldType\\LinkItem';

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

  /**
   * @var \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface|null
   */
  private $selectionManager;

  /**
   * @var \Drupal\Core\Path\AliasManagerInterface
   */
  private $aliasManager;

  /**
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   * @param \Drupal\Core\Path\AliasManagerInterface $alias_manager
   * @param \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface|null $selection_manager
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager, AliasManagerInterface $alias_manager, SelectionPluginManagerInterface $selection_manager = NULL) {
    $this->entityTypeManager = $entity_type_manager;
    $this->selectionManager = $selection_manager;
    $this->aliasManager = $alias_manager;
  }

  /**
   * {@inheritdoc}
   */
  public function normalize($object, $format = NULL, array $context = []) {
    $attributes = [];
    foreach ($object
      ->getProperties(TRUE) as $name => $field) {
      $attributes[$name] = $this->serializer
        ->normalize($field, $format, $context);
    }

    // For some reasons the options field is not normalized correctly if it
    // has more information like attributes added by menu_attributes module.
    // The field data will be empty after normalization, so we add missing data
    // here.
    if (!empty($object
      ->getValue()['options']) && empty($attributes['options'])) {
      $attributes['options'] = $object
        ->getValue()['options'];
    }

    // Use the entity UUID instead of ID in urls like internal:/node/1.
    if (isset($attributes['uri'])) {
      $scheme = parse_url($attributes['uri'], PHP_URL_SCHEME);
      if (!in_array($scheme, [
        'internal',
        'entity',
      ])) {
        return $attributes;
      }
      $path = parse_url($attributes['uri'], PHP_URL_PATH);

      // This service is not injected to avoid circular reference error when
      // installing page_manager contrib module.
      $url = \Drupal::service('path.validator')
        ->getUrlIfValidWithoutAccessCheck($path);
      if ($url instanceof Url) {
        $internal_path = ltrim($url
          ->getInternalPath(), '/');
        $path = ltrim($path, '/');

        // Return attributes as they are if uri is an alias.
        if ($path != $internal_path) {
          return $attributes;
        }
        $route_name = $url
          ->getRouteName();
        $route_name_parts = explode('.', $route_name);
        if ($route_name_parts[0] === 'entity' && $this
          ->isMultiversionableEntityType($route_name_parts[1])) {
          $entity_type = $route_name_parts[1];
          $entity_id = $url
            ->getRouteParameters()[$entity_type];
        }
        else {
          return $attributes;
        }
      }
      else {
        return $attributes;
      }
      $entity = $this->entityTypeManager
        ->getStorage($entity_type)
        ->load($entity_id);
      if ($entity instanceof EntityInterface) {
        $entity_uuid = $entity
          ->uuid();
        $attributes['uri'] = str_replace($entity_id, $entity_uuid, $attributes['uri']);
        $attributes['_entity_uuid'] = $entity_uuid;
        $attributes['_entity_type'] = $entity_type;
        $bundle_key = $entity
          ->getEntityType()
          ->getKey('bundle');
        $bundle = $entity
          ->bundle();
        if ($bundle_key && $bundle) {
          $attributes[$bundle_key] = $bundle;
        }
      }
    }
    return $attributes;
  }

  /**
   * {@inheritdoc}
   */
  public function denormalize($data, $class, $format = NULL, array $context = []) {
    if (isset($data['uri'])) {
      $scheme = parse_url($data['uri'], PHP_URL_SCHEME);
      if (!in_array($scheme, [
        'internal',
        'entity',
      ]) || !isset($data['_entity_uuid']) || !isset($data['_entity_type'])) {
        return parent::denormalize($data, $class, $format, $context);
      }
      $entity_uuid = $data['_entity_uuid'];
      $entity_type = $data['_entity_type'];
      $entity = NULL;
      if (isset($context['workspace']) && $context['workspace'] instanceof WorkspaceInterface) {
        $entities = $this->entityTypeManager
          ->getStorage($entity_type)
          ->useWorkspace($context['workspace']
          ->id())
          ->loadByProperties([
          'uuid' => $entity_uuid,
        ]);
        $entity = reset($entities);
      }
      if (!$entity instanceof ContentEntityInterface) {
        $bundle_key = $this->entityTypeManager
          ->getStorage($entity_type)
          ->getEntityType()
          ->getKey('bundle');
        if (isset($data[$bundle_key])) {

          /** @var \Drupal\Core\Entity\EntityReferenceSelection\SelectionWithAutocreateInterface $selection_instance */
          $selection_instance = $this->selectionManager
            ->getInstance([
            'target_type' => $entity_type,
          ]);

          // We use a temporary label and entity owner ID as this will be
          // backfilled later anyhow, when the real entity comes around.
          $entity = $selection_instance
            ->createNewEntity($entity_type, $data[$bundle_key], rand(), 1);

          // Set the target workspace if we have it in context.
          if (isset($context['workspace']) && $context['workspace'] instanceof WorkspaceInterface && $entity
            ->getEntityType()
            ->get('workspace') !== FALSE) {
            $entity->workspace->target_id = $context['workspace']
              ->id();
          }

          // Set the UUID to what we received to ensure it gets updated when
          // the full entity comes around later.
          $entity->uuid->value = $entity_uuid;

          // Indicate that this revision is a stub.
          $entity->_rev->is_stub = TRUE;
          $entity
            ->save();
        }
      }
      if ($entity instanceof EntityInterface) {
        $data['uri'] = str_replace($entity_uuid, $entity
          ->id(), $data['uri']);
        unset($data['_entity_uuid']);
        unset($data['_entity_type']);
        $bundle_key = $entity
          ->getEntityType()
          ->getKey('bundle');
        $bundle = $entity
          ->bundle();
        if ($bundle_key && $bundle) {
          unset($data[$bundle_key]);
        }
      }
    }
    return parent::denormalize($data, $class, $format, $context);
  }

  /**
   * {@inheritdoc}
   */
  public function supportsDenormalization($data, $type, $format = NULL) {
    if (in_array($type, [
      'Drupal\\link\\Plugin\\Field\\FieldType\\LinkItem',
    ])) {
      return TRUE;
    }
    return FALSE;
  }

  /**
   * @param string $entity_type_id
   *
   * @return bool
   */
  protected function isMultiversionableEntityType($entity_type_id) {
    try {
      $storage = $this->entityTypeManager
        ->getStorage($entity_type_id);
    } catch (InvalidPluginDefinitionException $exception) {
      return FALSE;
    }
    $entity_type = $storage
      ->getEntityType();
    if (is_subclass_of($entity_type
      ->getStorageClass(), 'Drupal\\multiversion\\Entity\\Storage\\ContentEntityStorageInterface')) {
      return TRUE;
    }
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  protected function checkFormat($format = NULL) {

    // Don't support HAL normalization because that expects a different format.
    // @see \Drupal\hal\Normalizer\FieldItemNormalizer::normalize()
    if ($format == 'hal_json') {
      return FALSE;
    }
    return parent::checkFormat($format);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
CacheableNormalizerInterface::SERIALIZATION_CONTEXT_CACHEABILITY constant Name of key for bubbling cacheability metadata via serialization context.
FieldableEntityNormalizerTrait::$entityFieldManager protected property The entity field manager.
FieldableEntityNormalizerTrait::$entityTypeRepository protected property The entity type repository.
FieldableEntityNormalizerTrait::constructValue protected function Build the field item value using the incoming data. 7
FieldableEntityNormalizerTrait::denormalizeFieldData protected function Denormalizes entity data by denormalizing each field individually.
FieldableEntityNormalizerTrait::determineEntityTypeId protected function Determines the entity type ID to denormalize as.
FieldableEntityNormalizerTrait::extractBundleData protected function Denormalizes the bundle property so entity creation can use it.
FieldableEntityNormalizerTrait::getEntityFieldManager protected function Returns the entity field manager.
FieldableEntityNormalizerTrait::getEntityTypeDefinition protected function Gets the entity type definition.
FieldableEntityNormalizerTrait::getEntityTypeManager protected function Returns the entity type manager.
FieldableEntityNormalizerTrait::getEntityTypeRepository protected function Returns the entity type repository.
LinkItemNormalizer::$aliasManager private property
LinkItemNormalizer::$entityTypeManager protected property Overrides FieldableEntityNormalizerTrait::$entityTypeManager
LinkItemNormalizer::$selectionManager private property
LinkItemNormalizer::$supportedInterfaceOrClass protected property The interface or class that this Normalizer supports. Overrides FieldItemNormalizer::$supportedInterfaceOrClass
LinkItemNormalizer::checkFormat protected function Checks if the provided format is supported by this normalizer. Overrides NormalizerBase::checkFormat
LinkItemNormalizer::denormalize public function Denormalizes data back into an object of the given class. Overrides FieldItemNormalizer::denormalize
LinkItemNormalizer::isMultiversionableEntityType protected function
LinkItemNormalizer::normalize public function Normalizes an object into a set of arrays/scalars. Overrides ComplexDataNormalizer::normalize
LinkItemNormalizer::supportsDenormalization public function Implements \Symfony\Component\Serializer\Normalizer\DenormalizerInterface::supportsDenormalization() Overrides NormalizerBase::supportsDenormalization
LinkItemNormalizer::__construct public function
NormalizerBase::$format protected property List of formats which supports (de-)normalization. 3
NormalizerBase::addCacheableDependency protected function Adds cacheability if applicable.
NormalizerBase::supportsNormalization public function Checks whether the given class is supported for normalization by this normalizer. 1
SerializedColumnNormalizerTrait::checkForSerializedStrings protected function Checks if there is a serialized string for a column.
SerializedColumnNormalizerTrait::dataHasStringForSerializeColumn protected function Checks if the data contains string value for serialize column.
SerializedColumnNormalizerTrait::getCustomSerializedPropertyNames protected function Gets the names of all properties the plugin treats as serialized data.
SerializedColumnNormalizerTrait::getSerializedPropertyNames protected function Gets the names of all serialized properties.