D8 Sistema de Búsqueda (Search) - pierregermain/MyDrupal GitHub Wiki

Módulo Search

Tablas:

  • 'search_dataset': Elementos a ser buscados. Si el campo "reindex" es 0 significa que el elemento no debe ser reindexado.
  • 'search_index': Asocia Elementos de search_dataset con palabras
  • 'search_total'. Almacena la "cantidad" de apariciones de cada palabra del índice.

Usando hooks para búsqueda de nodos

Hooks asociados a la búsqueda de nodos:

  • hook_node_update_index()

  • hook_node_search_result()

  • tendremos que implementar estos hooks cuando se desea indexar información no visible.

A) hook_node_update_index

Ejemplo: Queremos modificar la busqueda de tal forma cuando un nodo tenga la popiedad "Promoted" activada, y busquemos la cadena "promocionado" salgan en el resultado de búsquedas dichos nodos. Mola!

/**
 * Implements hook_node_update_index().
 */
function mymodule_node_update_index(\Drupal\node\NodeInterface $node) {
  if($node->isPromoted()) {
    return 'promocionado';
  }
}

OJO: Para que tome los cambios hay que reindexar y ejecutar el cron!

B) hook_node_search_result()

Ejemplo: Añadir un texto a los resultados de búsqueda

/**
 * Implements hook_node_search_result().
 */
function mymodule_node_search_result(\Drupal\node\NodeInterface $node) {
  if($node->isPromoted()) {
    return ['promoted_content' => t('Promoted content')];
  }
}

Modificación del twig

  • Fichero origin: /core/modules/search/templates/search-result.html.twig
  • Podemos acceder ahora a {{ info_split.promoted_content }}
  • Se copiaría a nuestro tema activo
...
  {% if (info_split.promoted_content) %}
    <span class="info-promoted-content">
      [{{ info_split.promoted_content }}]
    </span>
  {% endif %}
...

Páginas de búsquedas personalizadas

  • Tipo de Plugin: @SearchPlugin

Se puede extender una de las siguientes dos clases:

Búsqueda simple con SearchPluginBase

  • Sólo necesitamos implementar el execute
  • Ubicación: /src/Plugin/Search
  • con PagerSelectExtender paginamos los resultados en la select
  • con limit(3) limitamos los resultados por cada página.

Ejemplo: Ejecutar una búsqueda de usuarios con el rol "client".

Definimos el routing en /config/install/search.page.mymodule_clients_search.yml

langcode: en
status: true
dependencies:
  module:
    - mymodule
id: mymodule_clients_search
label: Clients
path: clients
weight: 1
plugin: mymodule_clients_search
configuration: { }

Definimos el Plugin

<?php

namespace Drupal\mymodule\Plugin\Search;

use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\search\Plugin\SearchPluginBase;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Executes a seach on users with role 'client'.
 *
 * @SearchPlugin(
 *
id = "mymodule_clients_search",
 *
title = @Translation("Clients search")
 * )
 */
class MymoduleClientsSearch extends SearchPluginBase {

  protected $database;

  protected $entityManager;

  public function __construct(Connection $database,
                              EntityTypeManagerInterface $entity_manager, array $configuration,
                              $plugin_id, $plugin_definition) {
    $this->database = $database;
    $this->entityManager = $entity_manager;
    parent::__construct($configuration, $plugin_id, $plugin_definition);
  }

  static public function create(ContainerInterface $container,
                                array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $container->get('database'),
      $container->get('entity.manager'),
      $configuration,
      $plugin_id,
      $plugin_definition
    );
  }

  /**
   * Execute the search.
   *
   * @return array
   *
   * A structured list of search results
   */
  public function execute() {
    $results = [];
    if (!$this->isSearchExecutable()) {
      return $results;
    }
    $keys = $this->keywords;
    $query = $this->database
      ->select('users_field_data', 'ufd')
      ->extend('Drupal\Core\Database\Query\PagerSelectExtender');
    $query->fields('ufd', ['uid']);
    $query->condition('default_langcode', 1);
    $query->condition('name', '%' . $keys . '%', 'LIKE')
      ->condition('status', 1);
    $query->join('user__roles', 'ur', 'ufd.uid = ur.entity_id');
    $query->condition('ur.roles_target_id', 'client');
    $uids = $query
      ->limit(3)
      ->execute()
      ->fetchCol();
    $accounts = $this->entityManager->getStorage('user')->loadMultiple($uids);
    foreach ($accounts as $account) {
      $result = [
        'title' => $account->getDisplayName() . ' ('
          . $account->getEmail() . ')',
        'link' => $account->url('canonical', ['absolute' => TRUE]),
      ];
      $results[] = $result;
    }
    return $results;
  }

}

Una vez instalado tendremos la oportunidad de configurar la búsqueda desde la UI en /admin/config/search/pages/ y las búsquedas se hacen desde /search/clients

Otras funcionalidades para páginas de búsquedas

Métodos

  • buildResults(). Permite modificar la salida, devolviendo un array
  • renderizable con los resultados de la búsqueda.
  • suggestedTitle(). Permite modificar el título de la página de resultados.
  • getHelp(). Devuelve información de ayuda.
  • searchFormAlter(). Permite modificar el formulario de búsqueda.

Búsquedas con configuraciones avanzadas

Ver: /core/modules/search/tests/modules/search_extra_type

Métodos:

  • buildConfigurationForm(). En este método definiremos los campos del formulario.
  • submitConfigurationForm(). Permite almacenar los valores de configuración desde el formulario.
  • defaultConfiguration(). Permite establecer valores iniciales de configuración.

Indexar Búsquedas

Ver: https://api.drupal.org/api/drupal/core!modules!node!src!Plugin!Search!NodeSearch.php/class/NodeSearch/8

Usa: https://api.drupal.org/api/drupal/core!modules!search!src!Plugin!SearchIndexingInterface.php/interface/SearchIndexingInterface/8

Se debe implementar los siguientes métodos:

  • indexClear(). Limpia el índice de búsquedas para este plugin.
  • indexStatus(). Devuelve información sobre el estado de indexación.
  • markForReindex(). Indica que el índice debe ser reindexado.
  • updateIndex(). Actualiza el índice de búsquedas. Aquí es donde se indexan los elementos que maneja nuestro plugin de búsquedas.

Consola

Drush

drush search-status
drush search-index
drush search-reindex
drush search-reindex --immediate

drush core-cron

Drupal Console

drupal cron:execute
drupal cron:execute search
drupal cron:debug
drupal cron:release
⚠️ **GitHub.com Fallback** ⚠️