Commit 716deec5 authored by Mikko Rantanen's avatar Mikko Rantanen Committed by Thomas Seiber
Browse files

Issue #3228382 by mikran, drunken monkey: Added an "Entity type" field.

parent c5e23042
Loading
Loading
Loading
Loading
+1 −0
Changes for CHANGELOG.txt: 1 added line, 0 removed lines.
Original line number Diff line number Diff line
Search API 1.x, dev (xxxx-xx-xx):
---------------------------------
- #3228382 by mikran, drunken monkey: Added an "Entity type" field.
- #3222644 by johne, drunken monkey: Made
  ContentEntityTrackingManager::filterValidItemIds() public.
- #3256114 by drunken monkey: Fixed wrong static method calls in
+69 −0
Changes for src/Plugin/search_api/processor/EntityType.php: 69 added lines, 0 removed lines.
Original line number Diff line number Diff line
<?php

namespace Drupal\search_api\Plugin\search_api\processor;

use Drupal\Core\Entity\EntityInterface;
use Drupal\search_api\Datasource\DatasourceInterface;
use Drupal\search_api\Item\ItemInterface;
use Drupal\search_api\Processor\ProcessorPluginBase;
use Drupal\search_api\Processor\ProcessorProperty;
use Drupal\search_api\SearchApiException;

/**
 * Adds entity type to the indexed data.
 *
 * @SearchApiProcessor(
 *   id = "entity_type",
 *   label = @Translation("Entity type"),
 *   description = @Translation("Adds the item's entity type to the indexed data."),
 *   stages = {
 *     "add_properties" = 0,
 *   },
 *   locked = true,
 *   hidden = true,
 * )
 */
class EntityType extends ProcessorPluginBase {

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

    if (!$datasource) {
      $definition = [
        'label' => $this->t('Entity type'),
        'description' => $this->t("The indexed item's entity type"),
        'type' => 'string',
        'processor_id' => $this->getPluginId(),
      ];
      $properties['search_api_entity_type'] = new ProcessorProperty($definition);
    }

    return $properties;
  }

  /**
   * {@inheritdoc}
   */
  public function addFieldValues(ItemInterface $item) {
    try {
      $entity = $item->getOriginalObject()->getValue();
    }
    catch (SearchApiException $e) {
      return;
    }
    if (!($entity instanceof EntityInterface)) {
      return;
    }

    $fields = $item->getFields();
    $fields = $this->getFieldsHelper()
      ->filterForPropertyPath($fields, NULL, 'search_api_entity_type');
    foreach ($fields as $field) {
      $field->addValue($entity->getEntityTypeId());
    }
  }

}
+1 −0
Changes for tests/src/Functional/ProcessorIntegrationTest.php: 1 added line, 0 removed lines.
Original line number Diff line number Diff line
@@ -100,6 +100,7 @@ class ProcessorIntegrationTest extends SearchApiBrowserTestBase {
    $enabled = [
      'add_url',
      'aggregated_field',
      'entity_type',
      'language_with_fallback',
      'rendered_item',
    ];
+121 −0
Changes for tests/src/Kernel/Processor/EntityTypeTest.php: 121 added lines, 0 removed lines.
Original line number Diff line number Diff line
<?php

namespace Drupal\Tests\search_api\Kernel\Processor;

use Drupal\comment\CommentInterface;
use Drupal\comment\Entity\Comment;
use Drupal\comment\Entity\CommentType;
use Drupal\comment\Tests\CommentTestTrait;
use Drupal\node\Entity\Node;
use Drupal\node\Entity\NodeType;
use Drupal\search_api\Item\Field;
use Drupal\search_api\Utility\Utility;
use Drupal\Tests\search_api\Kernel\PostRequestIndexingTrait;

/**
 * Tests the entity type property.
 *
 * @group search_api
 *
 * @coversDefaultClass \Drupal\search_api\Plugin\search_api\processor\EntityType
 */
class EntityTypeTest extends ProcessorTestBase {

  use PostRequestIndexingTrait;
  use CommentTestTrait;

  /**
   * The nodes created for testing.
   *
   * @var \Drupal\node\Entity\Node[]
   */
  protected $nodes;

  /**
   * The comments created for testing.
   *
   * @var \Drupal\comment\Entity\Comment[]
   */
  protected $comments;

  /**
   * {@inheritdoc}
   */
  public function setUp($processor = NULL) {
    parent::setUp('entity_type');

    NodeType::create([
      'type' => 'test_node_bundle',
    ])->save();

    $entity_type_field = new Field($this->index, 'entity_type');
    $entity_type_field->setType('string');
    $entity_type_field->setPropertyPath('search_api_entity_type');
    $entity_type_field->setLabel('Entity type');
    $this->index->addField($entity_type_field);
    $this->index->setOption('index_directly', TRUE);
    $this->index->save();
  }

  /**
   * Tests that field values are added correctly.
   *
   * @covers ::addFieldValues
   */
  public function testAddFieldValues() {
    $this->nodes[0] = Node::create([
      'title' => 'Test',
      'type' => 'test_node_bundle',
    ]);
    $this->nodes[0]->save();

    $this->triggerPostRequestIndexing();
    $expected[Utility::createCombinedId('entity:node', $this->nodes[0]->id() . ':en')] = ['node'];
    $this->assertEquals($expected, $this->getEntityTypeValues(), 'Added node entity type is indexed correctly.');

    $comment_type = CommentType::create([
      'id' => 'comment',
      'target_entity_type_id' => 'node',
    ]);
    $comment_type->save();

    $this->installConfig(['comment']);
    $this->addDefaultCommentField('node', 'test_node_bundle');

    $this->comments[0] = Comment::create([
      'status' => CommentInterface::PUBLISHED,
      'entity_type' => 'node',
      'entity_id' => $this->nodes[0]->id(),
      'field_name' => 'comment',
      'body' => 'test body',
      'comment_type' => $comment_type->id(),
    ]);
    $this->comments[0]->save();

    $this->triggerPostRequestIndexing();
    $expected[Utility::createCombinedId('entity:comment', $this->comments[0]->id() . ':en')] = ['comment'];
    $this->assertEquals($expected, $this->getEntityTypeValues(), 'Added comment entity type is indexed correctly.');
  }

  /**
   * Retrieves the indexed values.
   *
   * @return string[][]
   *   The indexed "entity_type" field values for all indexed items,
   *   keyed by item ID.
   */
  protected function getEntityTypeValues(): array {
    $query = $this->index->query();
    // We don't need a query condition as we have only one node anyway.
    $results = $query->execute();
    $values = [];
    /** @var \Drupal\search_api\Item\ItemInterface $result */
    foreach ($results as $result) {
      $field_values = $result->getField('entity_type')->getValues();
      sort($field_values);
      $values[$result->getId()] = $field_values;
    }
    return $values;
  }

}