rdf_sync-1.x-dev/rdf_sync.module

rdf_sync.module
<?php

/**
 * @file
 * Hook implementations for RDF Sync module.
 */

declare(strict_types=1);

use Drupal\Core\Config\Entity\ThirdPartySettingsInterface;
use Drupal\Core\Entity\BundleEntityFormBase;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\field_ui\Form\FieldConfigEditForm;
use Drupal\rdf_sync\BundleFieldDefinition;
use Drupal\rdf_sync\Form\Alter\BundleEntityFormAlter;
use Drupal\rdf_sync\Form\Alter\FieldConfigFormAlter;
use Drupal\rdf_sync\Model\ColumnMapping;
use Drupal\rdf_sync\Model\SyncMethod;
use Drupal\rdf_sync\RdfSyncUriFieldItemList;

/**
 * Implements hook_entity_bundle_info_alter().
 */
function rdf_sync_entity_bundle_info_alter(array &$bundles): void {
  $entityTypeManager = \Drupal::entityTypeManager();
  $entityFieldManager = \Drupal::getContainer()->get('entity_field.manager');

  foreach ($entityTypeManager->getDefinitions() as $entityTypeId => $entityType) {
    if (!$entityType->entityClassImplements(ContentEntityInterface::class) || !($bundleEntityTypeId = $entityType->getBundleEntityType())) {
      // Filter out config entities or entities without bundle as config entity.
      continue;
    }
    $bundleStorage = $entityTypeManager->getStorage($bundleEntityTypeId);
    /** @var \Drupal\Core\Config\Entity\ConfigEntityInterface&\Drupal\Core\Config\Entity\ThirdPartySettingsInterface $bundle */
    foreach ($bundleStorage->loadMultiple() as $bundleId => $bundle) {
      if ($rdfSyncSettings = $bundle->getThirdPartySettings('rdf_sync')) {
        if (empty($rdfSyncSettings['type'])) {
          // Malformed mapping.
          throw new \Exception("Mapping $entityTypeId:$bundleId is missing the 'type' value");
        }

        // Add bundle level mappings.
        $rdfSyncSettings += ['fields' => []];
        array_walk($rdfSyncSettings['fields'], 'rdf_sync_check_column_mappings', [$entityTypeId, $bundleId]);
        $bundles[$entityTypeId][$bundleId]['rdf_sync'] = $rdfSyncSettings;

        // Add configurable fields mappings.
        foreach ($entityFieldManager->getFieldDefinitions($entityTypeId, $bundleId) as $fieldName => $fieldDefinition) {
          if (!$fieldDefinition instanceof ThirdPartySettingsInterface) {
            continue;
          }

          $columns = $fieldDefinition->getThirdPartySettings('rdf_sync');
          rdf_sync_check_column_mappings($columns, $fieldName, [$entityTypeId, $bundleId]);
          foreach ($columns as $columnName => $mapping) {
            $bundles[$entityTypeId][$bundleId]['rdf_sync']['fields'][$fieldName][$columnName] = $mapping;
          }
        }
      }
    }
  }
}

/**
 * Checks the mapped columns from a field.
 *
 * @param array $columns
 *   The mapped columns of a given field.
 * @param string $fieldName
 *   The field name.
 * @param array $entityTypeAndBundle
 *   A tuple:
 *     0: the entity type ID,
 *     1: the bundle.
 *
 * @throws \Exception
 *   Various exceptions when the mappings have errors.
 */
function rdf_sync_check_column_mappings(array $columns, string $fieldName, array $entityTypeAndBundle): void {
  [$entityTypeId, $bundleId] = $entityTypeAndBundle;

  foreach ($columns as $columnName => $mapping) {
    if (empty($mapping['predicate'])) {
      throw new \Exception("Mapping of $entityTypeId:$bundleId:$fieldName:$columnName is missing the 'predicate' value");
    }
    if (!array_key_exists('type', $mapping)) {
      throw new \Exception("Mapping of $entityTypeId:$bundleId:$fieldName:$columnName is missing the 'type' value");
    }
    if ($mapping['type'] !== NULL && !in_array($mapping['type'], ColumnMapping::ALLOWED_TYPES, TRUE)) {
      throw new \Exception("The 'type' key of $entityTypeId:$bundleId:$fieldName:$columnName mapping should be NULL or one of '" . implode("', '", ColumnMapping::ALLOWED_TYPES) . "'");
    }

    // @todo The 'type' can be NULL only on translatable string fields. Find a
    //   way to check this early. Getting here the field definition to check
    //   whether is translatable will call rdf_sync_entity_bundle_field_info()
    //   which will call RdfSyncMapper::isMappedBundle() but the bundle info is
    //   not yet prepared (we're in the middle of the process).
  }
}

/**
 * Implements hook_entity_bundle_field_info().
 */
function rdf_sync_entity_bundle_field_info(EntityTypeInterface $entityType, string $bundle, array $baseFieldDefinitions): array {
  $fields = [];
  $mapper = \Drupal::getContainer()->get('rdf_sync.mapper');
  if ($bundle && $mapper->isMappedBundle($entityType->id(), $bundle)) {
    $fieldName = $mapper->getRdfUriFieldName($entityType->id(), $bundle);
    $fields[$fieldName] = BundleFieldDefinition::create('uri')
      ->setName($fieldName)
      ->setTargetEntityTypeId($entityType->id())
      ->setTargetBundle($bundle)
      ->setLabel(t('URI'))
      ->setRequired(TRUE)
      ->setComputed(TRUE)
      ->setCustomStorage(TRUE)
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', TRUE)
      ->setRevisionable(FALSE)
      ->setClass(RdfSyncUriFieldItemList::class);
  }
  return $fields;
}

/**
 * Implements hook_form_alter().
 */
function rdf_sync_form_alter(array &$form, FormStateInterface $form_state): void {
  $formObject = $form_state->getFormObject();
  if ($formObject instanceof BundleEntityFormBase) {
    $formAlter = \Drupal::classResolver(BundleEntityFormAlter::class);
  }
  elseif ($formObject instanceof FieldConfigEditForm) {
    $formAlter = \Drupal::classResolver(FieldConfigFormAlter::class);
  }

  /** @var \Drupal\rdf_sync\Form\Alter\FormAlterInterface|NULL $formAlter */
  if (isset($formAlter)) {
    $formAlter->alter($form, $form_state);
  }
}

/**
 * Implements hook_entity_insert().
 */
function rdf_sync_entity_insert(EntityInterface $entity): void {
  $mapper = \Drupal::getContainer()->get('rdf_sync.mapper');
  if ($entity instanceof ContentEntityInterface && $mapper->isMappedEntity($entity)) {
    \Drupal::getContainer()->get('rdf_sync.synchronizer')->synchronize(SyncMethod::INSERT, [$entity]);
  }
}

/**
 * Implements hook_entity_update().
 */
function rdf_sync_entity_update(EntityInterface $entity): void {
  $mapper = \Drupal::getContainer()->get('rdf_sync.mapper');
  if ($entity instanceof ContentEntityInterface && $mapper->isMappedEntity($entity)) {
    \Drupal::getContainer()->get('rdf_sync.synchronizer')->synchronize(SyncMethod::UPDATE, [$entity]);
  }
}

/**
 * Implements hook_entity_delete().
 */
function rdf_sync_entity_delete(EntityInterface $entity): void {
  $mapper = \Drupal::getContainer()->get('rdf_sync.mapper');
  if ($entity instanceof ContentEntityInterface && $mapper->isMappedEntity($entity)) {
    // Compute the URI so that is cached in the field item list to be available
    // in destruction phase.
    $fieldName = \Drupal::getContainer()->get('rdf_sync.mapper')->getRdfUriFieldName(entity: $entity);
    if ($entity->get($fieldName)->value) {
      \Drupal::getContainer()->get('rdf_sync.synchronizer')->synchronize(SyncMethod::DELETE, [$entity]);
    }

    \Drupal::database()->delete('rdf_sync_uri')
      ->condition('entity_type', $entity->getEntityTypeId())
      ->condition('entity_id', $entity->id())
      ->execute();
  }
}

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

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