search_api_meilisearch-1.0.x-dev/src/Converter/Item/ItemConverter.php

src/Converter/Item/ItemConverter.php
<?php

namespace Drupal\search_api_meilisearch\Converter\Item;

use Drupal\search_api\Item\FieldInterface;
use Drupal\search_api\Item\ItemInterface;
use Drupal\search_api\SearchApiException;
use Drupal\search_api_meilisearch\Backend\SpecialFieldsInterface;
use Drupal\search_api_meilisearch\Converter\Field\FieldConverterInterface;

/**
 * Provides converting search api item to a Meilisearch document array.
 */
final class ItemConverter implements ItemConverterInterface {

  /**
   * The list of applicable field converters.
   *
   * @var \Drupal\search_api_meilisearch\Converter\Field\FieldConverterInterface[]
   */
  private array $fieldConverters = [];

  /**
   * The list of sorted field converters.
   *
   * @var \Drupal\search_api_meilisearch\Converter\Field\FieldConverterInterface[]
   */
  private ?array $sortedFieldConverters = NULL;

  /**
   * {@inheritdoc}
   */
  public function convertToDocuments(array $items): array {
    if ($this->sortedFieldConverters === NULL) {
      $this->sortedFieldConverters = $this->sortFieldConverters();
    }

    $convertedItems = [];
    foreach ($items as $item) {
      $convertedItems[] = $this->convertToDocument($item);
    }

    return $convertedItems;
  }

  /**
   * Appends a field converter to the list.
   *
   * @param \Drupal\search_api_meilisearch\Converter\Field\FieldConverterInterface $parser
   *   The field converter to be appended to the list.
   * @param int $priority
   *   The priority of the field converter being added.
   *
   * @return $this
   */
  public function addFieldConverter(FieldConverterInterface $parser, int $priority = 0): self {
    $this->fieldConverters[$priority][] = $parser;
    $this->sortedFieldConverters = NULL;

    return $this;
  }

  /**
   * Sorts field converters by priority.
   *
   * @return \Drupal\search_api_meilisearch\Converter\Field\FieldConverterInterface[]
   *   A sorted array of field converter objects.
   */
  private function sortFieldConverters(): array {
    krsort($this->fieldConverters);

    return array_merge([], ...$this->fieldConverters);
  }

  /**
   * Converts a search api item to a meilisearch document.
   *
   * @return array
   *   The converted meilisearch document.
   */
  private function convertToDocument(ItemInterface $item): array {
    $convertedItem = [];

    $fields = $this->getSpecialFields($item) + $item->getFields();
    foreach ($fields as $field) {
      if (empty($field->getValues())) {
        continue;
      }

      $values = $this->getFieldValues($field);
      if (count($values) <= 1) {
        $values = reset($values);
      }

      $convertedItem[$field->getFieldIdentifier()] = $values;
    }

    return $convertedItem;
  }

  /**
   * Extracts the value from a search api field.
   *
   * @param \Drupal\search_api\Item\FieldInterface $field
   *   The search api field.
   *
   * @return array
   *   The extracted values.
   */
  private function getFieldValues(FieldInterface $field): array {
    foreach ($this->sortedFieldConverters as $fieldConverter) {
      if ($fieldConverter->supports($field)) {
        return $fieldConverter->toValues($field);
      }
    }

    return $field->getValues();
  }

  /**
   * Retrieves backend special fields of an item.
   *
   * @param \Drupal\search_api\Item\ItemInterface $item
   *   The search api item.
   *
   * @return \Drupal\search_api\Item\FieldInterface[]
   *   A list of special fields.
   */
  private function getSpecialFields(ItemInterface $item): array {
    try {
      $server = $item->getIndex()->getServerInstance();
      if (!$server) {
        return [];
      }

      $backend = $server->getBackend();
      if (!$backend instanceof SpecialFieldsInterface) {
        return [];
      }

      return $backend->getItemSpecialFields($item);
    }
    catch (SearchApiException $exception) {
      return [];
    }
  }

}

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

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