coveo-1.0.0-alpha1/modules/coveo_search_api/src/Plugin/search_api/processor/CoveoFileExtractor.php

modules/coveo_search_api/src/Plugin/search_api/processor/CoveoFileExtractor.php
<?php

declare(strict_types=1);

namespace Drupal\coveo_search_api\Plugin\search_api\processor;

use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\EntityReferenceFieldItemListInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\PluginFormInterface;
use Drupal\Core\Utility\Error;
use Drupal\file\Plugin\Field\FieldType\FileFieldItemList;
use Drupal\search_api\Datasource\DatasourceInterface;
use Drupal\search_api\Item\FieldInterface;
use Drupal\search_api\Item\ItemInterface;
use Drupal\search_api\Processor\ProcessorInterface;
use Drupal\search_api\Processor\ProcessorPluginBase;
use Drupal\search_api\Processor\ProcessorProperty;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Provides file fields processor.
 *
 * @todo Limit file types
 * @todo Limit field cardinality? Warn?
 * @todo Limit upload size.
 *
 * @SearchApiProcessor(
 *   id = "coveo_file_attachments",
 *   label = @Translation("Coveo file attachments"),
 *   description = @Translation("Adds the file attachments content to the indexed data."),
 *   stages = {
 *     "add_properties" = 0,
 *   }
 * )
 */
class CoveoFileExtractor extends ProcessorPluginBase implements PluginFormInterface, ProcessorInterface {

  /**
   * Prefix of the properties provided by this module.
   */
  const COVEO_PREFIX = 'c_attachment_';

  /**
   * Name of the "virtual" field for file entity content.
   *
   * This is used to represent the contents of a file when indexing a file
   * entity directly.
   */
  const COVEO_FILE_ENTITY = self::COVEO_PREFIX . 'file_entity';

  /**
   * {@inheritdoc}
   */
  public function __construct(
    array $configuration,
    $plugin_id,
    array $plugin_definition,
    private EntityTypeManagerInterface $entityTypeManager,
    private LoggerInterface $logger,
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);

  }

  /**
   * {@inheritdoc}
   */
  public static function create(
    ContainerInterface $container,
    array $configuration,
    $plugin_id,
    $plugin_definition,
  ) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('entity_type.manager'),
      $container->get('logger.channel.coveo'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getPropertyDefinitions(?DatasourceInterface $datasource = NULL) {
    $properties = [];

    if ($datasource === NULL) {
      // Add properties for all index available file fields and for file entity.
      foreach ($this->getFileFieldsAndFileEntityItems() as $field_name => $label) {
        $properties[static::COVEO_PREFIX . $field_name] = new ProcessorProperty([
          'label' => $this->t(
            'Coveo Attachment: @label',
            ['@label' => $label]
          ),
          'description' => $this->t(
            'Coveo Attachment: @label',
            ['@label' => $label]
          ),
          'type' => 'coveo_file',
          'processor_id' => $this->getPluginId(),
        ]);
      }
    }

    return $properties;
  }

  /**
   * {@inheritdoc}
   */
  public function addFieldValues(ItemInterface $item) {
    $item_fields = $item->getFields();
    $entity = $item->getOriginalObject()->getValue();
    foreach ($item_fields as $item_field) {
      $field_name = str_replace(self::COVEO_PREFIX, '', $item_field->getPropertyPath());
      if ($item_field->getType() === 'coveo_file') {
        if ($entity->hasField($field_name)) {
          $type = $entity->get($field_name)->getFieldDefinition()->getType();
          if ($type === 'file') {
            $this->extractFile($item_field, $entity->get($field_name));
          }
          elseif ($type == 'entity_reference') {
            $this->extractMedia($item_field, $entity->get($field_name));
          }
        }
      }
    }
  }

  /**
   * Get the file fields of indexed bundles and an entity file general item.
   *
   * @return array
   *   An array of file field with field name as key and label as value and
   *   an element for generic file entity item.
   */
  private function getFileFieldsAndFileEntityItems() {
    $file_elements = [];

    // Retrieve file fields of indexed bundles.
    foreach ($this->getIndex()->getDatasources() as $datasource) {
      if ($datasource->getPluginId() == 'entity:file') {
        $file_elements[static::COVEO_FILE_ENTITY] = $this->t('File entity');
      }
      foreach ($datasource->getPropertyDefinitions() as $property) {
        if ($property instanceof FieldDefinitionInterface) {
          if ($property->getType() == 'file') {
            $file_elements[$property->getName()] = $property->getLabel();
          }
          if ($property->getType() == "entity_reference") {
            if ($property->getSetting('target_type') === 'media') {
              $settings = $property->getItemDefinition()->getSettings();
              if (isset($settings['handler_settings']['target_bundles'])) {
                // For each media bundle allowed, check if the source field is a
                // file field.
                foreach ($settings['handler_settings']['target_bundles'] as $bundle_name) {
                  try {
                    $type = $this->entityTypeManager
                      ->getStorage('media_type')
                      ->load($bundle_name);
                    if (!empty($type)) {
                      $bundle_configuration = $this->entityTypeManager
                        ->getStorage('media_type')
                        ->load($bundle_name)->toArray();
                      if (isset($bundle_configuration['source_configuration']['source_field'])) {
                        $source_field = $bundle_configuration['source_configuration']['source_field'];
                        if ($field_config = $this->entityTypeManager
                          ->getStorage('field_storage_config')
                          ->load(sprintf('media.%s', $source_field))) {
                          $field_config = $field_config->toArray();
                          // @todo Should we allow other media types like image?
                          if (isset($field_config['type']) && $field_config['type'] === 'file') {
                            $file_elements[$property->getName()] = $property->getLabel();
                          }
                        }
                      }
                    }
                  }
                  catch (InvalidPluginDefinitionException $e) {
                    Error::logException($this->logger, $e);
                    continue;
                  }
                  catch (PluginNotFoundException $e) {
                    Error::logException($this->logger, $e);
                    continue;
                  }
                }
              }
            }
          }
        }
      }
    }
    return $file_elements;
  }

  /**
   * {@inheritDoc}
   */
  #[\Override]
  public function buildConfigurationForm(
    array $form,
    FormStateInterface $form_state,
  ): array {
    return $form;
  }

  /**
   * {@inheritDoc}
   */
  #[\Override]
  public function validateConfigurationForm(
    array &$form,
    FormStateInterface $form_state,
  ): void {
    // @todo Implement validateConfigurationForm() method.
  }

  /**
   * {@inheritDoc}
   */
  #[\Override]
  public function submitConfigurationForm(
    array &$form,
    FormStateInterface $form_state,
  ): void {
    // @todo Implement submitConfigurationForm() method.
  }

  /**
   * Extract files from files fields.
   *
   * @param \Drupal\search_api\Item\FieldInterface $item_field
   *   Search API field to add values to.
   * @param \Drupal\file\Plugin\Field\FieldType\FileFieldItemList $field_list
   *   File list field.
   */
  private function extractFile(FieldInterface $item_field, FileFieldItemList $field_list): void {
    foreach ($field_list->filterEmptyItems()->referencedEntities() as $file) {
      /** @var \Drupal\file\Entity\File $file */
      $item_field->addValue($file);
    }
  }

  /**
   * Extract files from media fields.
   *
   * @param \Drupal\search_api\Item\FieldInterface $item_field
   *   Search API field to add values to.
   * @param \Drupal\Core\Field\EntityReferenceFieldItemListInterface $field_list
   *   List of media fields.
   */
  private function extractMedia(FieldInterface $item_field, EntityReferenceFieldItemListInterface $field_list): void {
    $field_def = $field_list->getFieldDefinition();
    if ($field_def->getItemDefinition()->getSetting('target_type') === 'media') {
      /** @var \Drupal\media\Entity\Media $media */
      foreach ($field_list->filterEmptyItems()->referencedEntities() as $media) {
        $bundle_configuration = $media->getSource()->getConfiguration();
        if (isset($bundle_configuration['source_field'])) {
          $media_field = $media->get($bundle_configuration['source_field']);
          if ($media_field instanceof FileFieldItemList) {
            $this->extractFile($item_field, $media_field);
          }
        }
      }
    }
  }

}

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

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