replication-8.x-1.x-dev/src/Normalizer/LinkItemNormalizer.php

src/Normalizer/LinkItemNormalizer.php
<?php

namespace Drupal\replication\Normalizer;

use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Path\AliasManagerInterface;
use Drupal\Core\Url;
use Drupal\multiversion\Entity\WorkspaceInterface;
use Drupal\serialization\Normalizer\FieldItemNormalizer;

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);
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc