Commit 801ec648 authored by April Sides's avatar April Sides Committed by Thomas Seidl
Browse files

Issue #3320841 by weekbeforenext, drunken monkey: Fixed indexing of "Processed text" fields.

parent 329dac1e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
Search API 1.x, dev (xxxx-xx-xx):
---------------------------------
- #3320841 by weekbeforenext, drunken monkey: Fixed indexing of "Processed text"
  fields.
- #3273159 by naveenvalecha, drunken monkey: Added the "Custom value" processor
  property.
- #3296477 by abramm, drunken monkey: Fixed results when only one value is
+10 −1
Original line number Diff line number Diff line
@@ -54,7 +54,12 @@ services:

  search_api.fields_helper:
    class: Drupal\search_api\Utility\FieldsHelper
    arguments: ['@entity_type.manager', '@entity_field.manager', '@entity_type.bundle.info', '@search_api.data_type_helper']
    arguments:
      - '@entity_type.manager'
      - '@entity_field.manager'
      - '@entity_type.bundle.info'
      - '@search_api.data_type_helper'
      - '@search_api.theme_switcher'

  search_api.index_task_manager:
    class: Drupal\search_api\Task\IndexTaskManager
@@ -86,6 +91,10 @@ services:
    class: Drupal\search_api\Task\TaskManager
    arguments: ['@entity_type.manager', '@event_dispatcher', '@string_translation', '@messenger']

  search_api.theme_switcher:
    class: Drupal\search_api\Utility\ThemeSwitcher
    arguments: ['@theme.manager', '@theme.initialization', '@config.factory']

  search_api.tracking_helper:
    class: Drupal\search_api\Utility\TrackingHelper
    arguments: ['@entity_type.manager', '@language_manager', '@event_dispatcher', '@search_api.fields_helper', '@cache.default']
+17 −99
Original line number Diff line number Diff line
@@ -2,20 +2,18 @@

namespace Drupal\search_api\Plugin\search_api\processor;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\Entity\EntityViewMode;
use Drupal\Core\Link;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Session\AccountSwitcherInterface;
use Drupal\Core\Session\UserSession;
use Drupal\Core\Theme\ThemeInitializationInterface;
use Drupal\Core\Theme\ThemeManagerInterface;
use Drupal\Core\Url;
use Drupal\search_api\Datasource\DatasourceInterface;
use Drupal\search_api\Item\ItemInterface;
use Drupal\search_api\LoggerTrait;
use Drupal\search_api\Plugin\search_api\processor\Property\RenderedItemProperty;
use Drupal\search_api\Processor\ProcessorPluginBase;
use Drupal\search_api\Utility\ThemeSwitcherInterface;
use Drupal\user\RoleInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

@@ -54,25 +52,11 @@ class RenderedItem extends ProcessorPluginBase {
  protected $renderer;

  /**
   * Theme manager service.
   * The theme switcher.
   *
   * @var \Drupal\Core\Theme\ThemeManagerInterface
   * @var \Drupal\search_api\Utility\ThemeSwitcherInterface|null
   */
  protected $themeManager;

  /**
   * Theme initialization service.
   *
   * @var \Drupal\Core\Theme\ThemeInitializationInterface
   */
  protected $themeInitialization;

  /**
   * Theme settings config.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;
  protected $themeSwitcher;

  /**
   * {@inheritdoc}
@@ -83,10 +67,8 @@ class RenderedItem extends ProcessorPluginBase {

    $plugin->setAccountSwitcher($container->get('account_switcher'));
    $plugin->setRenderer($container->get('renderer'));
    $plugin->setThemeSwitcher($container->get('search_api.theme_switcher'));
    $plugin->setLogger($container->get('logger.channel.search_api'));
    $plugin->setThemeManager($container->get('theme.manager'));
    $plugin->setThemeInitializer($container->get('theme.initialization'));
    $plugin->setConfigFactory($container->get('config.factory'));

    return $plugin;
  }
@@ -138,71 +120,25 @@ class RenderedItem extends ProcessorPluginBase {
  }

  /**
   * Retrieves the theme manager.
   *
   * @return \Drupal\Core\Theme\ThemeManagerInterface
   *   The theme manager.
   */
  protected function getThemeManager() {
    return $this->themeManager ?: \Drupal::theme();
  }

  /**
   * Sets the theme manager.
   *
   * @param \Drupal\Core\Theme\ThemeManagerInterface $theme_manager
   *   The theme manager.
   *
   * @return $this
   */
  protected function setThemeManager(ThemeManagerInterface $theme_manager) {
    $this->themeManager = $theme_manager;
    return $this;
  }

  /**
   * Retrieves the theme initialization service.
   *
   * @return \Drupal\Core\Theme\ThemeInitializationInterface
   *   The theme initialization service.
   */
  protected function getThemeInitializer() {
    return $this->themeInitialization ?: \Drupal::service('theme.initialization');
  }

  /**
   * Sets the theme initialization service.
   *
   * @param \Drupal\Core\Theme\ThemeInitializationInterface $theme_initialization
   *   The theme initialization service.
   *
   * @return $this
   */
  protected function setThemeInitializer(ThemeInitializationInterface $theme_initialization) {
    $this->themeInitialization = $theme_initialization;
    return $this;
  }

  /**
   * Retrieves the config factory service.
   * Retrieves the theme switcher.
   *
   * @return \Drupal\Core\Config\ConfigFactoryInterface
   *   The config factory.
   * @return \Drupal\search_api\Utility\ThemeSwitcherInterface
   *   The theme switcher.
   */
  protected function getConfigFactory() {
    return $this->configFactory ?: \Drupal::configFactory();
  public function getThemeSwitcher(): ThemeSwitcherInterface {
    return $this->themeSwitcher ?: \Drupal::service('search_api.theme_switcher');
  }

  /**
   * Sets the config factory service.
   * Sets the theme switcher.
   *
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The config factory.
   * @param \Drupal\search_api\Utility\ThemeSwitcherInterface $theme_switcher
   *   The new theme switcher.
   *
   * @return $this
   */
  protected function setConfigFactory(ConfigFactoryInterface $config_factory) {
    $this->configFactory = $config_factory;
  public function setThemeSwitcher(ThemeSwitcherInterface $theme_switcher): self {
    $this->themeSwitcher = $theme_switcher;
    return $this;
  }

@@ -234,20 +170,7 @@ class RenderedItem extends ProcessorPluginBase {
  public function addFieldValues(ItemInterface $item) {
    // Switch to the default theme in case the admin theme (or any other theme)
    // is enabled.
    $active_theme = $this->getThemeManager()->getActiveTheme();
    $default_theme = $this->getConfigFactory()
      ->get('system.theme')
      ->get('default');
    $default_theme = $this->getThemeInitializer()
      ->getActiveThemeByName($default_theme);
    $active_theme_switched = FALSE;
    if ($default_theme->getName() !== $active_theme->getName()) {
      $this->getThemeManager()->setActiveTheme($default_theme);
      // Ensure that static cached default variables are set correctly,
      // especially the directory variable.
      drupal_static_reset('template_preprocess');
      $active_theme_switched = TRUE;
    }
    $previous_theme = $this->getThemeSwitcher()->switchToDefault();

    // Fields for which some view mode config is missing.
    $unset_view_modes = [];
@@ -313,12 +236,7 @@ class RenderedItem extends ProcessorPluginBase {
    $this->getAccountSwitcher()->switchBack();

    // Restore the original theme if themes got switched before.
    if ($active_theme_switched) {
      $this->getThemeManager()->setActiveTheme($active_theme);
      // Ensure that static cached default variables are set correctly,
      // especially the directory variable.
      drupal_static_reset('template_preprocess');
    }
    $this->getThemeSwitcher()->switchBack($previous_theme);

    if ($unset_view_modes > 0) {
      foreach ($unset_view_modes as $field_id => $field_label) {
+32 −4
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ use Drupal\search_api\Processor\ConfigurablePropertyInterface;
use Drupal\search_api\Processor\ProcessorInterface;
use Drupal\search_api\Processor\ProcessorPropertyInterface;
use Drupal\search_api\SearchApiException;
use Drupal\text\TextProcessed;
use Symfony\Component\DependencyInjection\Container;

/**
@@ -62,6 +63,13 @@ class FieldsHelper implements FieldsHelperInterface {
   */
  protected $dataTypeHelper;

  /**
   * The theme switcher.
   *
   * @var \Drupal\search_api\Utility\ThemeSwitcherInterface
   */
  protected $themeSwitcher;

  /**
   * Cache for the field type mapping.
   *
@@ -91,12 +99,21 @@ class FieldsHelper implements FieldsHelperInterface {
   *   The entity type bundle info service.
   * @param \Drupal\search_api\Utility\DataTypeHelperInterface $dataTypeHelper
   *   The data type helper service.
   * @param \Drupal\search_api\Utility\ThemeSwitcherInterface $themeSwitcher
   *   The theme switcher service.
   */
  public function __construct(EntityTypeManagerInterface $entityTypeManager, EntityFieldManagerInterface $entityFieldManager, EntityTypeBundleInfoInterface $entityBundleInfo, DataTypeHelperInterface $dataTypeHelper) {
  public function __construct(
    EntityTypeManagerInterface $entityTypeManager,
    EntityFieldManagerInterface $entityFieldManager,
    EntityTypeBundleInfoInterface $entityBundleInfo,
    DataTypeHelperInterface $dataTypeHelper,
    ThemeSwitcherInterface $themeSwitcher
  ) {
    $this->entityTypeManager = $entityTypeManager;
    $this->entityFieldManager = $entityFieldManager;
    $this->entityBundleInfo = $entityBundleInfo;
    $this->dataTypeHelper = $dataTypeHelper;
    $this->themeSwitcher = $themeSwitcher;
  }

  /**
@@ -126,7 +143,7 @@ class FieldsHelper implements FieldsHelperInterface {
    $nestedFields = [];
    foreach (array_keys($fields) as $key) {
      if (strpos($key, ':') !== FALSE) {
        list($direct, $nested) = explode(':', $key, 2);
        [$direct, $nested] = explode(':', $key, 2);
        $nestedFields[$direct][$nested] = $fields[$key];
      }
      else {
@@ -173,12 +190,23 @@ class FieldsHelper implements FieldsHelperInterface {
   * {@inheritdoc}
   */
  public function extractField(TypedDataInterface $data, FieldInterface $field) {
    // Switch to the default theme for TextProcessed rendering.
    $active_theme = NULL;
    if ($data instanceof TextProcessed) {
      $active_theme = $this->themeSwitcher->switchToDefault();
    }

    $values = $this->extractFieldValues($data);

    foreach ($values as $i => $value) {
      $field->addValue($value);
    }
    $field->setOriginalType($data->getDataDefinition()->getDataType());

    // Restore the original theme if themes got switched before.
    if ($active_theme) {
      $this->themeSwitcher->switchBack($active_theme);
    }
  }

  /**
@@ -352,7 +380,7 @@ class FieldsHelper implements FieldsHelperInterface {
   * {@inheritdoc}
   */
  public function retrieveNestedProperty(array $properties, $propertyPath) {
    list($key, $nestedPath) = Utility::splitPropertyPath($propertyPath, FALSE);
    [$key, $nestedPath] = Utility::splitPropertyPath($propertyPath, FALSE);
    if (!isset($properties[$key])) {
      return NULL;
    }
@@ -475,7 +503,7 @@ class FieldsHelper implements FieldsHelperInterface {
   * {@inheritdoc}
   */
  public function getNewFieldId(IndexInterface $index, $propertyPath) {
    list(, $suggestedId) = Utility::splitPropertyPath($propertyPath);
    [, $suggestedId] = Utility::splitPropertyPath($propertyPath);

    // Avoid clashes with reserved IDs by removing the reserved "search_api_"
    // from our suggested ID.
+103 −0
Original line number Diff line number Diff line
<?php

declare(strict_types = 1);

namespace Drupal\search_api\Utility;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Theme\ActiveTheme;
use Drupal\Core\Theme\MissingThemeDependencyException;
use Drupal\Core\Theme\ThemeInitializationInterface;
use Drupal\Core\Theme\ThemeManagerInterface;

/**
 * Provides simple theme switching for use during indexing.
 */
class ThemeSwitcher implements ThemeSwitcherInterface {

  /**
   * The theme manager service.
   *
   * @var \Drupal\Core\Theme\ThemeManagerInterface
   */
  protected $themeManager;

  /**
   * The theme initializer service.
   *
   * @var \Drupal\Core\Theme\ThemeInitializationInterface
   */
  protected $themeInitializer;

  /**
   * The config factory service.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * Constructs a new class instance.
   *
   * @param \Drupal\Core\Theme\ThemeManagerInterface $themeManager
   *   The theme manager service.
   * @param \Drupal\Core\Theme\ThemeInitializationInterface $themeInitializer
   *   The theme initializer service.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
   *   The config factory service.
   */
  public function __construct(
    ThemeManagerInterface $themeManager,
    ThemeInitializationInterface $themeInitializer,
    ConfigFactoryInterface $configFactory
  ) {
    $this->themeManager = $themeManager;
    $this->themeInitializer = $themeInitializer;
    $this->configFactory = $configFactory;
  }

  /**
   * {@inheritdoc}
   */
  public function switchToDefault(): ?ActiveTheme {
    // Switch to the default theme in case the admin theme (or any other theme)
    // is enabled.
    $activeTheme = $this->themeManager->getActiveTheme();
    $defaultTheme = $this->configFactory
      ->get('system.theme')
      ->get('default');
    try {
      $defaultTheme = $this->themeInitializer
        ->getActiveThemeByName($defaultTheme);
    }
    catch (MissingThemeDependencyException $e) {
      // It is highly unlikely that the default theme cannot be initialized, but
      // in this case the site will have far larger problems than incorrect
      // indexing. Just act like all is fine.
      return NULL;
    }
    if ($defaultTheme->getName() === $activeTheme->getName()) {
      return NULL;
    }

    $this->themeManager->setActiveTheme($defaultTheme);
    // Ensure that statically cached default variables are reset correctly,
    // especially the directory variable.
    drupal_static_reset('template_preprocess');
    // Return the previously active theme, for switching back.
    return $activeTheme;
  }

  /**
   * {@inheritdoc}
   */
  public function switchBack(?ActiveTheme $previousTheme): void {
    if ($previousTheme === NULL
        || $previousTheme === $this->themeManager->getActiveTheme()) {
      return;
    }
    $this->themeManager->setActiveTheme($previousTheme);
    drupal_static_reset('template_preprocess');
  }

}
Loading