You are here

class AutocompleteService in Synonyms 8

Synonyms behavior service for autocomplete.

Hierarchy

Expanded class hierarchy of AutocompleteService

1 file declares its use of AutocompleteService
EntityAutocomplete.php in src/Controller/EntityAutocomplete.php
1 string reference to 'AutocompleteService'
synonyms.services.yml in ./synonyms.services.yml
synonyms.services.yml
1 service uses AutocompleteService
synonyms.behavior.autocomplete in ./synonyms.services.yml
Drupal\synonyms\SynonymsService\Behavior\AutocompleteService

File

src/SynonymsService/Behavior/AutocompleteService.php, line 21

Namespace

Drupal\synonyms\SynonymsService\Behavior
View source
class AutocompleteService implements SynonymsBehaviorConfigurableInterface {
  use StringTranslationTrait;

  /**
   * The key value.
   *
   * @var \Drupal\Core\KeyValueStore\KeyValueFactoryInterface
   */
  protected $keyValue;

  /**
   * The entity reference selection handler plugin manager.
   *
   * @var \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface
   */
  protected $selectionManager;

  /**
   * The synonyms behavior service.
   *
   * @var \Drupal\synonyms\SynonymsService\BehaviorService
   */
  protected $behaviorService;

  /**
   * The database connection.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected $database;

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The renderer interface.
   *
   * @var \Drupal\Core\Render\RendererInterface
   */
  protected $renderer;

  /**
   * AutocompleteService constructor.
   */
  public function __construct(KeyValueFactoryInterface $key_value, SelectionPluginManagerInterface $selection_plugin_manager, BehaviorService $behavior_service, Connection $database, EntityTypeManagerInterface $entity_type_manager, RendererInterface $renderer) {
    $this->keyValue = $key_value
      ->get('synonyms_entity_autocomplete');
    $this->selectionManager = $selection_plugin_manager;
    $this->behaviorService = $behavior_service;
    $this->database = $database;
    $this->entityTypeManager = $entity_type_manager;
    $this->renderer = $renderer;
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state, array $configuration, SynonymInterface $synonym_config) {
    $replacements = [
      '#theme' => 'item_list',
      '#list_type' => 'ul',
      '#items' => [],
    ];
    foreach ($synonym_config
      ->getProviderPluginInstance()
      ->formatWordingAvailableTokens() as $token => $token_info) {
      $replacements['#items'][] = Html::escape($token) . ': ' . $token_info;
    }
    $replacements = $this->renderer
      ->renderRoot($replacements);
    $wording = isset($configuration['wording']) ? $configuration['wording'] : '';
    $form['wording'] = [
      '#type' => 'textfield',
      '#title' => $this
        ->t('Wording for autocomplete suggestion'),
      '#default_value' => $wording,
      '#description' => $this
        ->t('Specify the wording with which the autocomplete suggestion should be presented. Available replacement tokens are: @replacements', [
        '@replacements' => $replacements,
      ]),
      '#required' => TRUE,
    ];
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateConfigurationForm(array &$form, FormStateInterface $form_state, SynonymInterface $synonym_config) {
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state, SynonymInterface $synonym_config) {
    return [
      'wording' => $form_state
        ->getValue('wording'),
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getTitle() {
    return $this
      ->t('Autocomplete');
  }

  /**
   * Execute synonym-friendly lookup of entities by a given keyword.
   *
   * @param string $keyword
   *   Keyword to search for.
   * @param string $key_value_key
   *   Key under which additional settings about the lookup are stored in
   *   key-value storage.
   *
   * @return array
   *   Array of looked up suggestions. Each array will have the following
   *   structure:
   *   - entity_id: (int) ID of the entity which this entry represents
   *   - entity_label: (string) Label of the entity which this entry represents
   *   - wording: (string) Wording with which this entry should be shown to the
   *     end user on the UI
   */
  public function autocompleteLookup($keyword, $key_value_key) {
    $suggestions = [];
    if ($this->keyValue
      ->has($key_value_key)) {
      $settings = $this->keyValue
        ->get($key_value_key);
      $suggested_entity_ids = [];
      $target_bundles = $settings['target_bundles'];
      $options = [
        'target_type' => $settings['target_type'],
        'handler' => 'default',
      ];
      if (!empty($target_bundles)) {
        $options['target_bundles'] = $target_bundles;
      }
      elseif (!$this->entityTypeManager
        ->getDefinition($settings['target_type'])
        ->hasKey('bundle')) {
        $target_bundles = [
          $settings['target_type'],
        ];
      }
      $handler = $this->selectionManager
        ->getInstance($options);
      foreach ($handler
        ->getReferenceableEntities($keyword, $settings['match'], $settings['suggestion_size']) as $suggested_entities) {
        foreach ($suggested_entities as $entity_id => $entity_label) {
          $suggestions[] = [
            'entity_id' => $entity_id,
            'entity_label' => $entity_label,
            'wording' => $entity_label,
          ];
          if ($settings['suggest_only_unique']) {
            $suggested_entity_ids[] = $entity_id;
          }
        }
      }
      if (count($suggestions) < $settings['suggestion_size']) {
        foreach ($this->behaviorService
          ->getSynonymConfigEntities('synonyms.behavior.autocomplete', $settings['target_type'], $target_bundles) as $behavior_service) {
          $plugin_instance = $behavior_service
            ->getProviderPluginInstance();
          $condition = new Condition('AND');
          switch ($settings['match']) {
            case 'CONTAINS':
              $condition
                ->condition(SynonymsFindProviderInterface::COLUMN_SYNONYM_PLACEHOLDER, '%' . $this->database
                ->escapeLike($keyword) . '%', 'LIKE');
              break;
            case 'STARTS_WITH':
              $condition
                ->condition(SynonymsFindProviderInterface::COLUMN_SYNONYM_PLACEHOLDER, $this->database
                ->escapeLike($keyword) . '%', 'LIKE');
              break;
          }
          if (!empty($suggested_entity_ids)) {
            $condition
              ->condition(SynonymsFindProviderInterface::COLUMN_ENTITY_ID_PLACEHOLDER, $suggested_entity_ids, 'NOT IN');
          }
          foreach ($plugin_instance
            ->synonymsFind($condition) as $row) {
            if (!in_array($row->entity_id, $suggested_entity_ids)) {
              $suggestions[] = [
                'entity_id' => $row->entity_id,
                'entity_label' => NULL,
                'synonym' => $row->synonym,
                'synonym_config_entity' => $behavior_service,
                'wording' => NULL,
              ];
            }
            if ($settings['suggest_only_unique']) {
              $suggested_entity_ids[] = $row->entity_id;
            }
            if (count($suggestions) == $settings['suggestion_size']) {
              break 2;
            }
          }
        }
      }
      $ids = [];
      foreach ($suggestions as $suggestion) {
        if (!$suggestion['entity_label']) {
          $ids[] = $suggestion['entity_id'];
        }
      }
      $ids = array_unique($ids);
      if (!empty($ids)) {
        $entities = $this->entityTypeManager
          ->getStorage($settings['target_type'])
          ->loadMultiple($ids);
        foreach ($suggestions as $k => $suggestion) {
          if (!$suggestion['entity_label']) {
            $suggestions[$k]['entity_label'] = $entities[$suggestion['entity_id']]
              ->label();
            $suggestions[$k]['wording'] = $suggestion['synonym_config_entity']
              ->getProviderPluginInstance()
              ->synonymFormatWording($suggestion['synonym'], $entities[$suggestion['entity_id']], $suggestion['synonym_config_entity']);
          }
        }
      }
    }
    return $suggestions;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
AutocompleteService::$behaviorService protected property The synonyms behavior service.
AutocompleteService::$database protected property The database connection.
AutocompleteService::$entityTypeManager protected property The entity type manager.
AutocompleteService::$keyValue protected property The key value.
AutocompleteService::$renderer protected property The renderer interface.
AutocompleteService::$selectionManager protected property The entity reference selection handler plugin manager.
AutocompleteService::autocompleteLookup public function Execute synonym-friendly lookup of entities by a given keyword.
AutocompleteService::buildConfigurationForm public function Build configuration form. Overrides SynonymsBehaviorConfigurableInterface::buildConfigurationForm
AutocompleteService::getTitle public function Get human readable title of this behavior. Overrides SynonymsBehaviorInterface::getTitle
AutocompleteService::submitConfigurationForm public function Process submitted values and generate new configuration. Overrides SynonymsBehaviorConfigurableInterface::submitConfigurationForm
AutocompleteService::validateConfigurationForm public function Validate submitted values into your configuration form. Overrides SynonymsBehaviorConfigurableInterface::validateConfigurationForm
AutocompleteService::__construct public function AutocompleteService constructor.
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.