How can you contact us

2By phone at +40 749 014 360

If you still have problems, please let us know, by sending an email to info@westweb-solutions.com Thank you!

OFFICE HOURS

Mon-Fri 9:00AM - 6:00AM
Sat - 9:00AM - 1:00PM
Sundays by appointment only!

Drupal 8 - Search API and custom processors

/ / Drupal 8

In this article, we'll talk about the Search API module.

Given the structure below, it's pretty clear that we cannot use the standard Drupal search if we want to add some filters and other custom processors.

This is where the Search API module comes in really handy.

 

1. Requirements

In order to use this module in your application, you will need to choose a server for your index (Search API DB - this one is already available in the Search API module - and Search API SOLR are the most used).
In this example, we'll be using the first one as a server for our index.
Start by navigating to "/admin/config/search/search-api" and click on "+ Add server".

Now, that we have the server created, we'll need to add the index. So, start by clicking the "+ Add index" link. In the newly opened popup, add the index name and select which type of entity should be used and its bundle(s).

The next step consists of adding the fields to our newly created index.

Let's update the index and create a search view. In the "view settings" select the index you want to use.

Let's add the exposed filters

Now, let's configure the "fulltext search". Here you can select in which fields are searchable by given keywords. Make sure that the fields you want to use in this setting are set to "Fulltext" in the search api fields tab. This setting will allow you to search for some parts of strings (e.g. you have a node and its title is "lorem ipsum dolor"; you will be able to find that node just by searching "ipsum").

We now have a functional search.

 

2. Custom processors

Let's alter the view and set the "Fulltext search" filter operator to "Contains all of these words".

Although the booleans that are used for "sale" and "lease" are obvious, we want to allow the user to find a car by also adding the "sale" / "lease" strings in the "Fulltext search" exposed filter.
To achieve this we'll have to index the boolean fields as a "fulltext" type. This can be done by creating custom processor plugins.
In our custom module, in the "/src/Plugin/search_api/processor" folder we will create the following processors:

2.1. AddLeaseAsText.php

<?php

namespace Drupal\custom_search\Plugin\search_api\processor;

use Drupal\search_api\Datasource\DatasourceInterface;
use Drupal\search_api\Item\ItemInterface;
use Drupal\search_api\Processor\ProcessorPluginBase;
use Drupal\search_api\Processor\ProcessorProperty;

/**
 * Adds the item's URL to the indexed data.
 *
 * @SearchApiProcessor(
 *   id = "add_lease_as_text",
 *   label = @Translation("Lease (text) field"),
 *   description = @Translation("Adds the item's Lease to the indexed data."),
 *   stages = {
 *     "add_properties" = 0,
 *   },
 *   locked = true,
 *   hidden = true,
 * )
 */
class AddLeaseAsText extends ProcessorPluginBase {

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

    if (!$datasource) {
      $definition = [
        'label' => $this->t('Lease (text)'),
        'description' => $this->t('Car for Lease'),
        'type' => 'string',
        'processor_id' => $this->getPluginId(),
      ];
      $properties['custom_search_lease'] = new ProcessorProperty($definition);
    }

    return $properties;
  }

  /**
   * {@inheritdoc}
   */
  public function addFieldValues(ItemInterface $item) {

    $node = $item->getOriginalObject()->getValue();
    $field_lease = $node->get('field_available_for_lease')->getValue();

    if ($field_lease[0]['value']) {
      // Lease checked.

      $fields = $this->getFieldsHelper()
        ->filterForPropertyPath($item->getFields(), NULL, 'custom_search_lease');
      foreach ($fields as $field) {
        $field->addValue('for lease');
      }
    }
  }
}

2.2. AddSaleAsText.php

<?php

namespace Drupal\custom_search\Plugin\search_api\processor;

use Drupal\search_api\Datasource\DatasourceInterface;
use Drupal\search_api\Item\ItemInterface;
use Drupal\search_api\Processor\ProcessorPluginBase;
use Drupal\search_api\Processor\ProcessorProperty;

/**
 * Adds the item's URL to the indexed data.
 *
 * @SearchApiProcessor(
 *   id = "add_sale_as_text",
 *   label = @Translation("Sale (text) field"),
 *   description = @Translation("Adds the item's Sale to the indexed data."),
 *   stages = {
 *     "add_properties" = 0,
 *   },
 *   locked = true,
 *   hidden = true,
 * )
 */
class AddSaleAsText extends ProcessorPluginBase {

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

    if (!$datasource) {
      $definition = [
        'label' => $this->t('Sale (text)'),
        'description' => $this->t('Car for Sale'),
        'type' => 'string',
        'processor_id' => $this->getPluginId(),
      ];
      $properties['custom_search_sale'] = new ProcessorProperty($definition);
    }

    return $properties;
  }

  /**
   * {@inheritdoc}
   */
  public function addFieldValues(ItemInterface $item) {

    $node = $item->getOriginalObject()->getValue();
    $field_sale = $node->get('field_available_for_sale')->getValue();

    if ($field_sale[0]['value']) {
      // Sale checked.

      $fields = $this->getFieldsHelper()
        ->filterForPropertyPath($item->getFields(), NULL, 'custom_search_sale');
      foreach ($fields as $field) {
        $field->addValue('for sale');
      }
    }
  }

}

2.3. Add custom fields

 

Don't forget to reindex the content.

Now, let's update the search view.

Let's take a look at the result.

This is just a basic example, in a similar way you can add more complex precessors according to your requirements.

Sign in your account to have access to different features

Forgot your details?

TOP