Search on non-title fields

Created on 20 April 2018, over 6 years ago
Updated 16 May 2024, 6 months ago

In some special cases, users may want to search on other data other than just the title field.
Currently, in EntityMatcher, there is logic that gets the label key for the entity type.

$label_key = $entity_type->getKey('label');
Which, for node entities, is the title.

Which is then used in the conditions in the ->buildEntityQuery() method.

if ($label_key) {
      // For configuration entities, the condition needs to be CONTAINS as
      // the matcher does not support LIKE.
      if ($entity_type instanceof ConfigEntityTypeInterface) {
        $query->condition($label_key, $search_string, 'CONTAINS');
      }
      else {
        $query->condition($label_key, '%' . $search_string . '%', 'LIKE');
      }

      $query->sort($label_key, 'ASC');
    }

It seems like we could add a custom form element that allows the user to specify what field to use as that key in the condition. It would need to be dynamically worked out based on which entity and bundles were configured in the Matcher.

✨ Feature request
Status

Needs review

Version

7.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States joshua.boltz

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 10.0.7 + Environment: PHP 8.1 & MariaDB 10.3.22
    last update over 1 year ago
    83 pass
  • πŸ‡ΊπŸ‡ΈUnited States jacobbell84

    I had need of this functionality so I put together a patch. Because there's a lot of possible use cases, more then can be handled by a form field, I introduced hooks so that the developer can add support for whatever field they're looking for. One allows for the field to be searched on, the other allows you override the label that gets returned.

  • πŸ‡§πŸ‡·Brazil igorgoncalves

    Ok, i faced a similar situation like many others here, so i will share the step-by-step i made to achieve the solution.

    1 - We have a product content type with a product_id field. So the editor wants to search not only by the product title, but by the product id as well.

    2 - On yours custom module you will need to create a new Linkit Matcher.

    3 - so, o my 'custom_module' i created:

    docroot/modules/custom/custom_module/src/Plugin/Linkit/Matcher/NodeProductsMatcher.php

    4 - and the code below:

    <?php
    namespace Drupal\custom_module\Plugin\Linkit\Matcher;
    use Drupal\linkit\Plugin\Linkit\Matcher\NodeMatcher;
    
    // Those anotations below it is VERY important to follow the patterns from NodeMatcher parent.
    
    /**
     * Provide specific linkit matcher for products CT.
     *
     * @Matcher(
     *   id = "custom_module:node:products",
     *   label = @Translation("Custom Matcher Products"),
     *   target_entity = "node",
     *   provider = "node"
     * )
     */
    class NodeProductsMatcher <strong>extends NodeMatcher</strong> {
      /**
       * {@inheritdoc}
       */
      protected function buildEntityQuery($search_string) {
        $search_string = $this->database->escapeLike($search_string);
        $entity_type = $this->entityTypeManager->getDefinition($this->targetType);
        $nodeQuery = $this->entityTypeManager->getStorage('node')->getQuery();
        $nodeQuery->condition('field_product_id', '%' . $search_string . '%', 'LIKE');
        // Bundle check.
        if (!empty($this->configuration['bundles']) && $bundle_key = $entity_type->getKey('bundle')) {
          $nodeQuery->condition($bundle_key, $this->configuration['bundles'], 'IN');
        }
        if ($this->configuration['limit']) {
          $nodeQuery->range(0, $this->configuration['limit']);
        }
        $this->addQueryTags($nodeQuery);
        return $nodeQuery;
      }
    }
    

    5 - Save, clear your cache, and go back to UI and add your new Custom Matcher at: admin/config/content/linkit/manage/[Your-profile-default]/matchers

    6 - Select the content which have your product_id field, and save.

    7 - long story short here, the new NodeProductsMatcher will be called and the buildEntityQuery function there will look for field_product_id, instead of the $node->label() as the default one. The bundle check and the config['limit'] will heritage what you've selected on step 6.

    8 - thats it, you now have your suggestions updated.

  • πŸ‡ΊπŸ‡ΈUnited States mark_fullmer Tucson
Production build 0.71.5 2024