rdf_sync-1.x-dev/src/RdfSyncMapper.php

src/RdfSyncMapper.php
<?php

declare(strict_types=1);

namespace Drupal\rdf_sync;

use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\rdf_sync\Model\ColumnMapping;

/**
 * RDF Sync mapper service.
 */
class RdfSyncMapper implements RdfSyncMapperInterface {

  public function __construct(
    protected EntityTypeBundleInfoInterface $entityTypeBundleInfo,
    protected EntityTypeManagerInterface $entityTypeManager,
    protected Connection $database,
  ) {}

  /**
   * {@inheritdoc}
   */
  public function entityTypeHasMappings(string $entityTypeId): bool {
    foreach ($this->entityTypeBundleInfo->getBundleInfo($entityTypeId) as $bundleId => $bundleInfo) {
      if ($this->isMappedBundle($entityTypeId, $bundleId)) {
        return TRUE;
      }
    }
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function getBundleRdfType(?string $entityTypeId = NULL, ?string $bundle = NULL, ?ContentEntityInterface $entity = NULL): ?string {
    $this->resolveEntityTypeAndBundle($entityTypeId, $bundle, $entity);
    return $this->getBundleMapping($entityTypeId, $bundle)['type'] ?? NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function isMappedBundle(string $entityTypeId, string $bundle): bool {
    return (bool) $this->getBundleRdfType($entityTypeId, $bundle);
  }

  /**
   * {@inheritdoc}
   */
  public function isMappedEntity(EntityInterface $entity): bool {
    return $this->isMappedBundle($entity->getEntityTypeId(), $entity->bundle());
  }

  /**
   * {@inheritdoc}
   */
  public function getMappings(?string $entityTypeId = NULL, ?string $bundle = NULL, ?ContentEntityInterface $entity = NULL): array {
    $this->resolveEntityTypeAndBundle($entityTypeId, $bundle, $entity);

    $mappings = [];
    foreach ($this->getBundleMapping($entityTypeId, $bundle)['fields'] ?? [] as $fieldName => $columns) {
      foreach ($columns as $columnName => $mapping) {
        $mappings[$fieldName][$columnName] = ColumnMapping::createFromArray($mapping);
      }
    }

    return $mappings;
  }

  /**
   * {@inheritdoc}
   */
  public function getRdfUriFieldName(?string $entityTypeId = NULL, ?string $bundle = NULL, ?ContentEntityInterface $entity = NULL): string {
    $this->resolveEntityTypeAndBundle($entityTypeId, $bundle, $entity);
    return $this->getBundleMapping($entityTypeId, $bundle)['uri_field_name'];
  }

  /**
   * {@inheritdoc}
   */
  public function getRdfUriPluginId(string $entityTypeId, string $bundle): ?string {
    return $this->getBundleMapping($entityTypeId, $bundle)['uri_plugin'] ?? NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function getNamespaces(?string $entityTypeId = NULL, ?string $bundle = NULL, ?ContentEntityInterface $entity = NULL): array {
    $this->resolveEntityTypeAndBundle($entityTypeId, $bundle, $entity);
    return $this->getBundleMapping($entityTypeId, $bundle)['namespaces'] ?? [];
  }

  /**
   * {@inheritdoc}
   */
  public function hasBundleMapping(ContentEntityInterface $entity): bool {
    $bundleKey = $entity->getEntityType()->getKey('bundle');
    $fieldMappings = $this->getMappings($entity->getEntityTypeId(), $entity->bundle());
    if (!isset($fieldMappings[$bundleKey])) {
      return FALSE;
    }
    $mainProperty = $entity->getFieldDefinition($bundleKey)->getFieldStorageDefinition()->getMainPropertyName();
    return isset($fieldMappings[$bundleKey][$mainProperty]);
  }

  /**
   * {@inheritdoc}
   */
  public function getEntityByUri(string $uri): ?ContentEntityInterface {
    $row = $this->database->select('rdf_sync_uri')
      ->fields('rdf_sync_uri', ['entity_type', 'entity_id'])
      ->condition('uri', $uri)
      ->execute()
      ->fetch(\PDO::FETCH_NUM);
    if (!$row) {
      return NULL;
    }
    [$entityTypeId, $entityId] = $row;

    return $this->entityTypeManager->getStorage($entityTypeId)->load($entityId);
  }

  /**
   * {@inheritdoc}
   */
  public function getEntitiesByUris(array $uris): array {
    $rows = $this->database->select('rdf_sync_uri')
      ->fields('rdf_sync_uri', ['uri', 'entity_type', 'entity_id'])
      ->condition('uri', $uris, 'IN')
      ->execute()
      ->fetchAll(\PDO::FETCH_NUM);

    $byEntityTypeId = $result = [];
    foreach ($rows as [$uri, $entityTypeId, $entityId]) {
      $byEntityTypeId[$entityTypeId][] = $entityId;
    }

    foreach ($byEntityTypeId as $entityTypeId => $entityIds) {
      foreach ($this->entityTypeManager->getStorage($entityTypeId)->loadMultiple($entityIds) as $entity) {
        assert($entity instanceof ContentEntityInterface);
        $fieldName = $this->getRdfUriFieldName(entity: $entity);
        $result[$entity->get($fieldName)->value] = $entity;
      }
    }

    // Preserve the original URIs order. Reduce first $uris to the loaded list.
    $uris = array_intersect($uris, array_keys($result));
    return array_merge(array_flip($uris), $result);
  }

  /**
   * {@inheritdoc}
   */
  public function getUrisByEntityType(string $entityTypeId, ?string $bundle = NULL): array {
    $query = $this->database->select('rdf_sync_uri')
      ->fields('rdf_sync_uri', ['entity_id', 'uri'])
      ->condition('entity_type', $entityTypeId);
    if ($bundle) {
      $query->condition('bundle', $bundle);
    }
    return $query->execute()->fetchAllKeyed();
  }

  /**
   * Returns the bundle mapping.
   *
   * @param string $entityTypeId
   *   The bundle's entity type ID.
   * @param string $bundle
   *   The bundle.
   *
   * @return array|null
   *   The bundle mapping or NULL if no mapping is defined.
   */
  protected function getBundleMapping(string $entityTypeId, string $bundle): ?array {
    // Cover entity types without bundles.
    $bundle = $bundle ?: $entityTypeId;
    $bundleInfo = $this->entityTypeBundleInfo->getBundleInfo($entityTypeId)[$bundle] ?? [];
    if (!$bundleInfo) {
      return NULL;
    }

    return ($bundleInfo['rdf_sync'] ?? []) + [
      'uri_field_name' => 'uri',
      'uri_plugin' => NULL,
      'fields' => [],
      'namespaces' => [],
    ];
  }

  /**
   * Resolves the entity type ID and the bundle, given the entity.
   *
   * @param string|null $entityTypeId
   *   The entity type ID passed by reference.
   * @param string|null $bundle
   *   The bundle passed by reference.
   * @param \Drupal\Core\Entity\ContentEntityInterface|null $entity
   *   The entity.
   */
  protected function resolveEntityTypeAndBundle(?string &$entityTypeId, ?string &$bundle, ?ContentEntityInterface $entity): void {
    if ($entity) {
      if ($entityTypeId || $bundle) {
        throw new \InvalidArgumentException('Cannot pass $entityTypeId or $bundle when $entity has been passed');
      }
      $entityTypeId = $entity->getEntityTypeId();
      $bundle = $entity->bundle();
    }
    elseif (!($entityTypeId && $bundle)) {
      throw new \InvalidArgumentException('Both, $entityTypeId and $bundle, should be passed when $entity is missed');
    }
  }

}

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

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