View source
<?php
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 Symfony\Component\DependencyInjection\ContainerInterface;
class RenderedItem extends ProcessorPluginBase {
use LoggerTrait;
protected $accountSwitcher;
protected $renderer;
protected $themeManager;
protected $themeInitialization;
protected $configFactory;
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$plugin = parent::create($container, $configuration, $plugin_id, $plugin_definition);
$plugin
->setAccountSwitcher($container
->get('account_switcher'));
$plugin
->setRenderer($container
->get('renderer'));
$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;
}
public function getAccountSwitcher() {
return $this->accountSwitcher ?: \Drupal::service('account_switcher');
}
public function setAccountSwitcher(AccountSwitcherInterface $current_user) {
$this->accountSwitcher = $current_user;
return $this;
}
public function getRenderer() {
return $this->renderer ?: \Drupal::service('renderer');
}
public function setRenderer(RendererInterface $renderer) {
$this->renderer = $renderer;
return $this;
}
protected function getThemeManager() {
return $this->themeManager ?: \Drupal::theme();
}
protected function setThemeManager(ThemeManagerInterface $theme_manager) {
$this->themeManager = $theme_manager;
return $this;
}
protected function getThemeInitializer() {
return $this->themeInitialization ?: \Drupal::service('theme.initialization');
}
protected function setThemeInitializer(ThemeInitializationInterface $theme_initialization) {
$this->themeInitialization = $theme_initialization;
return $this;
}
protected function getConfigFactory() {
return $this->configFactory ?: \Drupal::configFactory();
}
protected function setConfigFactory(ConfigFactoryInterface $config_factory) {
$this->configFactory = $config_factory;
return $this;
}
public function getPropertyDefinitions(DatasourceInterface $datasource = NULL) {
$properties = [];
if (!$datasource) {
$definition = [
'label' => $this
->t('Rendered HTML output'),
'description' => $this
->t('The complete HTML which would be displayed when viewing the item'),
'type' => 'search_api_html',
'processor_id' => $this
->getPluginId(),
];
$properties['rendered_item'] = new RenderedItemProperty($definition);
}
return $properties;
}
public function addFieldValues(ItemInterface $item) {
$active_theme = $this
->getThemeManager()
->getActiveTheme();
$default_theme = $this
->getConfigFactory()
->get('system.theme')
->get('default');
$default_theme = $this
->getThemeInitializer()
->getActiveThemeByName($default_theme);
$this
->getThemeManager()
->setActiveTheme($default_theme);
$unset_view_modes = [];
$fields = $this
->getFieldsHelper()
->filterForPropertyPath($item
->getFields(), NULL, 'rendered_item');
foreach ($fields as $field) {
$configuration = $field
->getConfiguration();
$this
->getAccountSwitcher()
->switchTo(new UserSession([
'roles' => $configuration['roles'],
]));
$datasource_id = $item
->getDatasourceId();
$datasource = $item
->getDatasource();
$bundle = $datasource
->getItemBundle($item
->getOriginalObject());
if (empty($configuration['view_mode'][$datasource_id][$bundle])) {
if (!isset($configuration['view_mode'][$datasource_id][$bundle])) {
$unset_view_modes[$field
->getFieldIdentifier()] = $field
->getLabel();
}
continue;
}
$view_mode = (string) $configuration['view_mode'][$datasource_id][$bundle];
try {
$build = $datasource
->viewItem($item
->getOriginalObject(), $view_mode);
if ($build) {
$build['#search_api_excerpt'] = $item
->getExcerpt();
$value = (string) $this
->getRenderer()
->renderPlain($build);
if ($value) {
$field
->addValue($value);
}
}
} catch (\Exception $e) {
$variables = [
'%item_id' => $item
->getId(),
'%view_mode' => $view_mode,
'%index' => $this->index
->label(),
];
$this
->logException($e, '%type while trying to render item %item_id with view mode %view_mode for search index %index: @message in %function (line %line of %file).', $variables);
}
}
$this
->getAccountSwitcher()
->switchBack();
$this
->getThemeManager()
->setActiveTheme($active_theme);
if ($unset_view_modes > 0) {
foreach ($unset_view_modes as $field_id => $field_label) {
$url = new Url('entity.search_api_index.field_config', [
'search_api_index' => $this->index
->id(),
'field_id' => $field_id,
]);
$context = [
'%index' => $this->index
->label(),
'%field_id' => $field_id,
'%field_label' => $field_label,
'link' => (new Link($this
->t('Field settings'), $url))
->toString(),
];
$this
->getLogger()
->warning('The field %field_label (%field_id) on index %index is missing view mode configuration for some datasources or bundles. Please review (and re-save) the field settings.', $context);
}
}
}
public function calculateDependencies() {
$this->dependencies = parent::calculateDependencies();
$fields = $this
->getFieldsHelper()
->filterForPropertyPath($this->index
->getFields(), NULL, 'rendered_item');
foreach ($fields as $field) {
$view_modes = $field
->getConfiguration()['view_mode'];
foreach ($this->index
->getDatasources() as $datasource_id => $datasource) {
if (($entity_type_id = $datasource
->getEntityTypeId()) && !empty($view_modes[$datasource_id])) {
foreach ($view_modes[$datasource_id] as $view_mode) {
if ($view_mode) {
$view_mode_entity = EntityViewMode::load($entity_type_id . '.' . $view_mode);
if ($view_mode_entity) {
$this
->addDependency($view_mode_entity
->getConfigDependencyKey(), $view_mode_entity
->getConfigDependencyName());
}
}
}
}
}
}
return $this->dependencies;
}
public function onDependencyRemoval(array $dependencies) {
$fields = $this
->getFieldsHelper()
->filterForPropertyPath($this->index
->getFields(), NULL, 'rendered_item');
foreach ($fields as $field) {
$field_config = $field
->getConfiguration();
$view_modes = $field_config['view_mode'];
foreach ($this->index
->getDatasources() as $datasource_id => $datasource) {
$entity_type_id = $datasource
->getEntityTypeId();
if (!$entity_type_id) {
continue;
}
foreach ($view_modes[$datasource_id] ?? [] as $bundle => $view_mode_id) {
if ($view_mode_id) {
$view_mode = EntityViewMode::load($entity_type_id . '.' . $view_mode_id);
if ($view_mode) {
$dependency_key = $view_mode
->getConfigDependencyKey();
$dependency_name = $view_mode
->getConfigDependencyName();
if (!empty($dependencies[$dependency_key][$dependency_name])) {
unset($view_modes[$datasource_id][$bundle]);
}
}
}
}
}
$field_config['view_mode'] = $view_modes;
$field
->setConfiguration($field_config);
}
return TRUE;
}
}