search_api-8.x-1.15/src/Plugin/views/row/SearchApiRow.php
src/Plugin/views/row/SearchApiRow.php
<?php namespace Drupal\search_api\Plugin\views\row; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\search_api\LoggerTrait; use Drupal\Core\TypedData\ComplexDataInterface; use Drupal\search_api\Plugin\views\query\SearchApiQuery; use Drupal\search_api\SearchApiException; use Drupal\views\Plugin\views\display\DisplayPluginBase; use Drupal\views\Plugin\views\row\RowPluginBase; use Drupal\views\ViewExecutable; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Provides a row plugin for displaying a result as a rendered item. * * @ViewsRow( * id = "search_api", * title = @Translation("Rendered entity"), * help = @Translation("Displays entity of the matching search API item"), * ) * * @see search_api_views_plugins_row_alter() */ class SearchApiRow extends RowPluginBase { use LoggerTrait; /** * The search index. * * @var \Drupal\search_api\IndexInterface */ protected $index; /** * The entity type manager. * * @var \Drupal\Core\Entity\EntityTypeManagerInterface */ protected $entityTypeManager; /** * {@inheritdoc} */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { /** @var static $row */ $row = parent::create($container, $configuration, $plugin_id, $plugin_definition); $row->setEntityTypeManager($container->get('entity_type.manager')); $row->setLogger($container->get('logger.channel.search_api')); return $row; } /** * Retrieves the entity type manager. * * @return \Drupal\Core\Entity\EntityTypeManagerInterface * The entity type manager. */ public function getEntityTypeManager() { return $this->entityTypeManager ?: \Drupal::entityTypeManager(); } /** * Sets the entity type manager. * * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager * The new entity type manager. * * @return $this */ public function setEntityTypeManager(EntityTypeManagerInterface $entity_type_manager) { $this->entityTypeManager = $entity_type_manager; return $this; } /** * {@inheritdoc} */ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) { parent::init($view, $display, $options); $base_table = $view->storage->get('base_table'); $this->index = SearchApiQuery::getIndexFromTable($base_table, $this->getEntityTypeManager()); if (!$this->index) { $view_label = $view->storage->label(); throw new \InvalidArgumentException("View '$view_label' is not based on Search API but tries to use its row plugin."); } } /** * {@inheritdoc} */ protected function defineOptions() { $options = parent::defineOptions(); $options['view_modes'] = ['default' => []]; return $options; } /** * {@inheritdoc} */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); /** @var \Drupal\search_api\Datasource\DatasourceInterface $datasource */ foreach ($this->index->getDatasources() as $datasource_id => $datasource) { $datasource_label = $datasource->label(); $bundles = $datasource->getBundles(); if (!$datasource->getViewModes()) { $form['view_modes'][$datasource_id] = [ '#type' => 'item', '#title' => $this->t('View mode for datasource %name', ['%name' => $datasource_label]), '#description' => $this->t("This datasource doesn't have any view modes available. It is therefore not possible to display results of this datasource using this row plugin."), ]; continue; } foreach ($bundles as $bundle_id => $bundle_label) { $title = $this->t('View mode for datasource %datasource, bundle %bundle', ['%datasource' => $datasource_label, '%bundle' => $bundle_label]); $view_modes = $datasource->getViewModes($bundle_id); if (!$view_modes) { $form['view_modes'][$datasource_id][$bundle_id] = [ '#type' => 'item', '#title' => $title, '#description' => $this->t("This bundle doesn't have any view modes available. It is therefore not possible to display results of this bundle using this row plugin."), ]; continue; } $form['view_modes'][$datasource_id][$bundle_id] = [ '#type' => 'select', '#options' => $view_modes, '#title' => $title, '#default_value' => key($view_modes), ]; if (isset($this->options['view_modes'][$datasource_id][$bundle_id])) { $form['view_modes'][$datasource_id][$bundle_id]['#default_value'] = $this->options['view_modes'][$datasource_id][$bundle_id]; } } } } /** * {@inheritdoc} */ public function preRender($result) { // Load all result objects at once, before rendering. $items_to_load = []; foreach ($result as $i => $row) { if (empty($row->_object)) { $items_to_load[$i] = $row->search_api_id; } } $items = $this->index->loadItemsMultiple($items_to_load); foreach ($items_to_load as $i => $item_id) { if (isset($items[$item_id])) { $result[$i]->_object = $items[$item_id]; $result[$i]->_item->setOriginalObject($items[$item_id]); } } } /** * {@inheritdoc} */ public function render($row) { $datasource_id = $row->search_api_datasource; if (!($row->_object instanceof ComplexDataInterface)) { $context = [ '%item_id' => $row->search_api_id, '%view' => $this->view->storage->label(), ]; $this->getLogger()->warning('Failed to load item %item_id in view %view.', $context); return ''; } if (!$this->index->isValidDatasource($datasource_id)) { $context = [ '%datasource' => $datasource_id, '%view' => $this->view->storage->label(), ]; $this->getLogger()->warning('Item of unknown datasource %datasource returned in view %view.', $context); return ''; } // Always use the default view mode if it was not set explicitly in the // options. $view_mode = 'default'; $bundle = $this->index->getDatasource($datasource_id)->getItemBundle($row->_object); if (isset($this->options['view_modes'][$datasource_id][$bundle])) { $view_mode = $this->options['view_modes'][$datasource_id][$bundle]; } try { $build = $this->index->getDatasource($datasource_id) ->viewItem($row->_object, $view_mode); // Add the excerpt to the render array to allow adding it to view modes. if (isset($row->search_api_excerpt)) { $build['#search_api_excerpt'] = $row->search_api_excerpt; } return $build; } catch (SearchApiException $e) { $this->logException($e); return ''; } } /** * {@inheritdoc} */ public function query() {} }