diff --git a/search_api.plugin_type.yml b/search_api.plugin_type.yml index c1b49c7..1fbd834 100644 --- a/search_api.plugin_type.yml +++ b/search_api.plugin_type.yml @@ -8,6 +8,11 @@ search_api_data_type: plugin_manager_service_id: plugin.manager.search_api.data_type plugin_definition_decorator_class: \Drupal\plugin\PluginDefinition\ArrayPluginDefinitionDecorator +search_api_display: + label: Search API display + plugin_manager_service_id: plugin.manager.search_api.display + plugin_definition_decorator_class: \Drupal\plugin\PluginDefinition\ArrayPluginDefinitionDecorator + search_api_processor: label: Search API processor plugin_manager_service_id: plugin.manager.search_api.processor diff --git a/search_api.services.yml b/search_api.services.yml index 6c1207a..61db9d4 100644 --- a/search_api.services.yml +++ b/search_api.services.yml @@ -18,6 +18,10 @@ services: class: Drupal\search_api\Datasource\DatasourcePluginManager parent: default_plugin_manager + plugin.manager.search_api.display: + class: Drupal\search_api\Display\DisplayPluginManager + parent: default_plugin_manager + plugin.manager.search_api.processor: class: Drupal\search_api\Processor\ProcessorPluginManager arguments: ['@container.namespaces', '@cache.discovery', '@module_handler', '@string_translation'] diff --git a/src/Annotation/SearchApiDisplay.php b/src/Annotation/SearchApiDisplay.php new file mode 100644 index 0000000..4515c9e --- /dev/null +++ b/src/Annotation/SearchApiDisplay.php @@ -0,0 +1,35 @@ +get('entity_type.manager'); + $deriver->setEntityTypeManager($entity_type_manager); + + $translation = $container->get('string_translation'); + $deriver->setStringTranslation($translation); + + return $deriver; + } + + /** + * Retrieves the entity manager. + * + * @return \Drupal\Core\Entity\EntityTypeManager + * The entity manager. + */ + public function getEntityTypeManager() { + return $this->entityTypeManager; + } + + /** + * Sets the entity manager. + * + * @param \Drupal\Core\Entity\EntityTypeManager $entity_type_manager + * The entity manager. + * + * @return $this + */ + public function setEntityTypeManager(EntityTypeManager $entity_type_manager) { + $this->entityTypeManager = $entity_type_manager; + return $this; + } + + /** + * {@inheritdoc} + */ + public function getDerivativeDefinition($derivative_id, $base_plugin_definition) { + $derivatives = $this->getDerivativeDefinitions($base_plugin_definition); + return isset($derivatives[$derivative_id]) ? $derivatives[$derivative_id] : NULL; + } + + /** + * Compares two plugin definitions according to their labels. + * + * @param array $a + * A plugin definition, with at least a "label" key. + * @param array $b + * Another plugin definition. + * + * @return int + * An integer less than, equal to, or greater than zero if the first + * argument is considered to be respectively less than, equal to, or greater + * than the second. + */ + public function compareDerivatives(array $a, array $b) { + return strnatcasecmp($a['label'], $b['label']); + } + +} diff --git a/src/Display/DisplayInterface.php b/src/Display/DisplayInterface.php new file mode 100644 index 0000000..6f60a85 --- /dev/null +++ b/src/Display/DisplayInterface.php @@ -0,0 +1,50 @@ +getPluginDefinition(); + return $plugin_definition['label']; + } + + /** + * {@inheritdoc} + */ + public function isRenderedInCurrentRequest() { + return FALSE; + } + + /** + * {@inheritdoc} + */ + public function getIndex() { + $definition = $this->getPluginDefinition(); + return Index::load($definition['index']); + } + +} diff --git a/src/Display/DisplayPluginManager.php b/src/Display/DisplayPluginManager.php new file mode 100644 index 0000000..ff7739e --- /dev/null +++ b/src/Display/DisplayPluginManager.php @@ -0,0 +1,57 @@ +setCacheBackend($cache_backend, 'search_api_displays'); + } + + /** + * Returns all known displays. + * + * @return \Drupal\search_api\Display\DisplayInterface[] + * An array of display plugins, keyed by type identifier. + */ + public function getInstances() { + if ($this->displays === NULL) { + $this->displays = array(); + + foreach ($this->getDefinitions() as $name => $display_definition) { + if (class_exists($display_definition['class']) && empty($this->displays[$name])) { + $display = $this->createInstance($name); + $this->displays[$name] = $display; + } + } + } + + return $this->displays; + } + +} diff --git a/src/Plugin/search_api/display/ViewsPageDisplay.php b/src/Plugin/search_api/display/ViewsPageDisplay.php new file mode 100644 index 0000000..b1af1fe --- /dev/null +++ b/src/Plugin/search_api/display/ViewsPageDisplay.php @@ -0,0 +1,28 @@ +pluginDefinition['view_id']); + $view->setDisplay($this->pluginDefinition['view_display']); + return Url::fromUserInput('/' . $view->getDisplay()->getPath()); + } + +} diff --git a/src/Plugin/search_api/display/ViewsPageDisplayDeriver.php b/src/Plugin/search_api/display/ViewsPageDisplayDeriver.php new file mode 100644 index 0000000..97200f0 --- /dev/null +++ b/src/Plugin/search_api/display/ViewsPageDisplayDeriver.php @@ -0,0 +1,82 @@ +entityTypeManager->getStorage('view'); + $all_views = $views_storage->loadMultiple(); + } + catch (PluginNotFoundException $e) { + return array(); + } + + if (!isset($this->derivatives[$base_plugin_id])) { + $plugin_derivatives = array(); + + /** @var \Drupal\views\Entity\View $view */ + foreach ($all_views as $view) { + $index = SearchApiQuery::getIndexFromTable($view->get('base_table')); + if ($index) { + $displays = $view->get('display'); + foreach ($displays as $name => $display_info) { + if ($display_info['display_plugin'] == "page") { + $machine_name = $base = $view->id() . '__' . $name; + // Make sure the machine name is unique. (Will almost always be + // the case, unless a view or page ID contains two consecutive + // underscores.) + $i = 0; + while (isset($plugin_derivatives[$machine_name])) { + $machine_name = $base . '_' . ++$i; + } + + $label_arguments = array( + '%view_name' => $view->label(), + '%display_title' => $display_info['display_title'] + ); + $label = $this->t('View %view_name, display %display_title', $label_arguments); + + $plugin_derivatives[$machine_name] = array( + 'id' => $base_plugin_id . PluginBase::DERIVATIVE_SEPARATOR . $machine_name, + 'label' => $label, + 'description' => $view->get('description') ? $this->t('%view_description - Represents the page display %display_title of view %view_name.', array('%view_name' => $view->label(), '%view_description' => $view->get('description'), '%display_title' => $display_info['display_title'])) : $this->t('Represents the page display %display_title of view %view_name.', array('%view_name' => $view->label(), '%display_title' => $display_info['display_title'])), + 'view_id' => $view->id(), + 'view_display' => $name, + 'index' => $index->id(), + ) + $base_plugin_definition; + + $arguments = array( + '%view' => $view->label(), + '%display' => $display_info['display_title'], + ); + $sources[] = $this->t('View name: %view. Display: %display', $arguments); + } + } + } + } + uasort($plugin_derivatives, array($this, 'compareDerivatives')); + + $this->derivatives[$base_plugin_id] = $plugin_derivatives; + } + return $this->derivatives[$base_plugin_id]; + } + +} diff --git a/src/Tests/ViewsTest.php b/src/Tests/ViewsTest.php index 12c529b..d976b7f 100644 --- a/src/Tests/ViewsTest.php +++ b/src/Tests/ViewsTest.php @@ -3,6 +3,7 @@ namespace Drupal\search_api\Tests; use Drupal\Component\Utility\Html; +use Drupal\Core\Url; use Drupal\search_api\Entity\Index; use Drupal\search_api\Utility; @@ -148,6 +149,14 @@ class ViewsTest extends WebTestBase { 'keywords_op' => 'not empty', ); $this->checkResults($query, array(4), 'Search with multiple filters'); + + // Make sure there was a display plugin created for this view. + $displays = \Drupal::getContainer()->get('plugin.manager.search_api.display')->getInstances(); + $display_id = 'views_page:search_api_test_view__page_1'; + $this->assertEqual(array($display_id), array_keys($displays), 'A display plugin was created for the test view.'); + $view_url = Url::fromUserInput('/search-api-test')->toString(); + $this->assertEqual($view_url, $displays[$display_id]->getPath()->toString(), 'Display returns the correct path.'); + $this->assertEqual('database_search_index', $displays[$display_id]->getIndex()->id(), 'Display returns the correct search index.'); } /**