Commit 196a64e2 authored by borisson_'s avatar borisson_ Committed by borisson_
Browse files

Issue #2678486 by borisson_, Leksat, Nick_vh: Views block display support

parent c3fdeff4
......@@ -95,9 +95,9 @@ class CoreNodeSearchFacetSource extends FacetSourcePluginBase implements CoreSea
$request = \Drupal::requestStack()->getMasterRequest();
$search_page = $request->attributes->get('entity');
if ($search_page instanceof SearchPageInterface) {
return 'search/' . $search_page->getPath();
return '/search/' . $search_page->getPath();
}
return '';
return '/';
}
/**
......
......@@ -11,7 +11,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Derives a facet source plugin definition for every Search API view.
*
* @see \Drupal\facets\Plugin\facets\facet_source\SearchApiViewsPage
* @see \Drupal\facets\Plugin\facets\facet_source\SearchApiViews
*/
class CoreNodeSearchFacetSourceDeriver extends FacetSourceDeriverBase {
......
......@@ -341,6 +341,8 @@ class FacetForm extends EntityForm {
$view->setDisplay($display);
$view->display_handler->overrideOption('cache', ['type' => 'none']);
$view->save();
$display_plugin = $view->getDisplay()->getPluginId();
}
if ($is_new) {
......@@ -349,6 +351,10 @@ class FacetForm extends EntityForm {
drupal_set_message($message);
$form_state->setRedirect('entity.facets_facet.display_form', ['facets_facet' => $facet->id()]);
}
if (isset($view_id) && $display_plugin === 'block') {
$facet->setOnlyVisibleWhenFacetSourceIsVisible(FALSE);
}
}
else {
drupal_set_message(t('Facet %name has been updated.', ['%name' => $facet->getName()]));
......
......@@ -6,17 +6,21 @@ use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\facets\FacetSource\SearchApiFacetSourceInterface;
use Drupal\search_api\Plugin\views\query\SearchApiQuery;
use Drupal\search_api\Query\ResultSetInterface;
use Drupal\views\Entity\View;
use Drupal\views\Views;
/**
* Represents a facet source which represents the Search API views.
* A facet source to support search api views.
*
* This facet source only supports views that have a search api index as a base,
* and only those displays that are a block or a page.
*
* @FacetsFacetSource(
* id = "search_api_views",
* deriver = "Drupal\facets\Plugin\facets\facet_source\SearchApiViewsPageDeriver"
* deriver = "Drupal\facets\Plugin\facets\facet_source\SearchApiViewsDeriver"
* )
*/
class SearchApiViewsPage extends SearchApiBaseFacetSource implements SearchApiFacetSourceInterface {
class SearchApiViews extends SearchApiBaseFacetSource implements SearchApiFacetSourceInterface {
use DependencySerializationTrait;
......@@ -75,9 +79,17 @@ class SearchApiViewsPage extends SearchApiBaseFacetSource implements SearchApiFa
* {@inheritdoc}
*/
public function getPath() {
$view = Views::getView($this->pluginDefinition['view_id']);
$view->setDisplay($this->pluginDefinition['view_display']);
return $view->getDisplay()->getPath();
$display = View::load($this->pluginDefinition['view_id'])->getDisplay($this->pluginDefinition['view_display']);
switch ($display['display_plugin']) {
case 'page':
$view = Views::getView($this->pluginDefinition['view_id']);
$view->setDisplay($this->pluginDefinition['view_display']);
return '/' . $view->getDisplay()->getPath();
case 'block':
default:
return \Drupal::service('path.current')->getPath();
}
}
/**
......@@ -123,13 +135,25 @@ class SearchApiViewsPage extends SearchApiBaseFacetSource implements SearchApiFa
* {@inheritdoc}
*/
public function isRenderedInCurrentRequest() {
$request = \Drupal::requestStack()->getMasterRequest();
if ($request->attributes->get('_controller') === 'Drupal\views\Routing\ViewPageController::handle') {
list(, $search_api_view_id, $search_api_view_display) = explode(':', $this->getPluginId());
if ($request->attributes->get('view_id') == $search_api_view_id && $request->attributes->get('display_id') == $search_api_view_display) {
return TRUE;
}
$display = View::load($this->pluginDefinition['view_id'])->getDisplay($this->pluginDefinition['view_display']);
switch ($display['display_plugin']) {
case 'page':
$request = \Drupal::requestStack()->getMasterRequest();
if ($request->attributes->get('_controller') === 'Drupal\views\Routing\ViewPageController::handle') {
list(, $search_api_view_id, $search_api_view_display) = explode(':', $this->getPluginId());
if ($request->attributes->get('view_id') == $search_api_view_id && $request->attributes->get('display_id') == $search_api_view_display) {
return TRUE;
}
}
return FALSE;
case 'block':
// There is no way to know if a block is embedded on a page, because
// blocks can be rendered in isolation (see big_pipe, esi, ...). To be
// sure we're not disclosing information we're not sure about, we always
// return false.
return FALSE;
}
return FALSE;
}
......
......@@ -9,9 +9,12 @@ use Drupal\facets\FacetSource\FacetSourceDeriverBase;
/**
* Derives a facet source plugin definition for every Search API view.
*
* @see \Drupal\facets\Plugin\facets\facet_source\SearchApiViewsPage
* This facet source only supports views that have a search api index as a base,
* and only those displays that are a block or a page.
*
* @see \Drupal\facets\Plugin\facets\facet_source\SearchApiViews
*/
class SearchApiViewsPageDeriver extends FacetSourceDeriverBase {
class SearchApiViewsDeriver extends FacetSourceDeriverBase {
/**
* {@inheritdoc}
......@@ -36,16 +39,27 @@ class SearchApiViewsPageDeriver extends FacetSourceDeriverBase {
// Hardcoded usage of Search API views, for now.
if (strpos($view->get('base_table'), 'search_api_index') !== FALSE) {
$displays = $view->get('display');
foreach ($displays as $name => $display_info) {
if ($display_info['display_plugin'] == "page") {
$machine_name = $view->id() . PluginBase::DERIVATIVE_SEPARATOR . $name;
foreach ($displays as $display_id => $display_info) {
// We only support pages and blocks because those are the ones that
// we've tested. They are also the only ones that support for
// ::isRenderedInCurrentRequest() and ::getPath().
if (in_array($display_info['display_plugin'], ['page', 'block'])) {
$machine_name = $view->id() . PluginBase::DERIVATIVE_SEPARATOR . $display_id;
$label_arguments = [
'%view_name' => $view->label(),
'%display_title' => $display_info['display_title'],
'%display_type' => $display_info['display_plugin'],
];
$plugin_derivatives[$machine_name] = [
'id' => $base_plugin_id . PluginBase::DERIVATIVE_SEPARATOR . $machine_name,
'label' => $this->t('Search API view: %view_name, display: %display_title', ['%view_name' => $view->label(), '%display_title' => $display_info['display_title']]),
'label' => $this->t('Search API view: %view_name, display: %display_title (%display_type)',
$label_arguments
),
'description' => $this->t('Provides a facet source.'),
'view_id' => $view->id(),
'view_display' => $name,
'view_display' => $display_id,
] + $base_plugin_definition;
$sources[] = $this->t(
......
......@@ -63,7 +63,7 @@ class QueryString extends UrlProcessorPluginBase {
$request = $this->request;
if ($facet->getFacetSource()->getPath()) {
$request = Request::create('/' . $facet->getFacetSource()->getPath());
$request = Request::create($facet->getFacetSource()->getPath());
}
$url = Url::createFromRequest($request);
$url->setOption('attributes', ['rel' => 'nofollow']);
......
......@@ -86,15 +86,13 @@ class IntegrationTest extends WebTestBase {
// Verify that facet blocks appear as expected.
$this->assertFacetBlocksAppear();
// Show the facet only when the facet source is visible.
// @TODO Only for SearchApiViewsPage for the moment.
// Verify that the facet only shows when the facet source is visible.
$this->setOptionShowOnlyWhenFacetSourceVisible($facet_name);
$this->goToDeleteFacetPage($facet_name);
$this->assertNoText('item');
$this->assertNoText('article');
// Do not show the block on empty behaviors.
// Remove data from index.
$this->clearIndex();
$this->drupalGet('search-api-test-fulltext');
......@@ -116,6 +114,58 @@ class IntegrationTest extends WebTestBase {
$this->checkEmptyOverview();
}
/**
* Tests that a block view also works.
*/
public function testBlockView() {
$facet_name = "Block view facet";
$facet_id = 'bvf';
// Add a new facet.
$facet_add_page = '/admin/config/search/facets/add-facet';
$this->drupalGet($facet_add_page);
$form_values = [
'id' => $facet_id,
'status' => 1,
'url_alias' => $facet_id,
'name' => $facet_name,
'weight' => 2,
'facet_source_id' => 'search_api_views:search_api_test_view:block_1',
'facet_source_configs[search_api_views:search_api_test_view:block_1][field_identifier]' => 'type',
];
$this->drupalPostForm(NULL, ['facet_source_id' => 'search_api_views:search_api_test_view:block_1'], $this->t('Configure facet source'));
$this->drupalPostForm(NULL, $form_values, $this->t('Save'));
$facet = Facet::load($facet_id);
$this->assertEqual($facet_name, $facet->label());
$this->assertEqual(FALSE, $facet->getOnlyVisibleWhenFacetSourceIsVisible());
// Place the views block in the footer of all pages.
$block_settings = [
'region' => 'footer',
'id' => 'view_block',
];
$this->drupalPlaceBlock('views_block:search_api_test_view-block_1', $block_settings);
// By default, the view should show all entities.
$this->drupalGet('<front>');
$this->assertText('Displaying 5 search results', 'The search view displays the correct number of results.');
$this->assertText('Fulltext test index', 'The search view displays the correct number of results.');
// Create and place a block for the test facet.
$this->createFacetBlock($facet_id);
// Verify that the facet results are correct displayed.
$this->drupalGet('<front>');
$this->assertText('item');
$this->assertText('article');
// Click the item link, and test that filtering of results actually works.
$this->clickLink('item');
$this->assertText('Displaying 3 search results', 'The search view displays the correct number of results.');
}
/**
* Tests renaming of a facet.
*
......@@ -576,6 +626,10 @@ class IntegrationTest extends WebTestBase {
// The list overview has Field: field_name as description. This tests on the
// absence of that.
$this->assertNoText('Field:');
// Check that the expected facet sources are shown.
$this->assertText('search_api_views:search_api_test_view:block_1');
$this->assertText('search_api_views:search_api_test_view:page_1');
}
/**
......
......@@ -87,7 +87,7 @@ class UrlIntegrationTest extends WebTestBase {
// Go to the only enabled facet source's config and change the filter key.
$this->drupalGet('admin/config/search/facets');
$this->clickLink($this->t('Configure'));
$this->clickLink($this->t('Configure'), 1);
$edit = [
'filter_key' => 'y',
......@@ -110,7 +110,7 @@ class UrlIntegrationTest extends WebTestBase {
// Go to the only enabled facet source's config and change the url
// processor.
$this->drupalGet('admin/config/search/facets');
$this->clickLink($this->t('Configure'));
$this->clickLink($this->t('Configure'), 1);
$edit = [
'filter_key' => 'y',
......
......@@ -69,8 +69,8 @@ abstract class UrlProcessorPluginBase extends ProcessorPluginBase implements Url
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
/** @var Request $request */
$request = $container->get('request_stack')->getCurrentRequest();
/** @var \Symfony\Component\HttpFoundation\Request $request */
$request = $container->get('request_stack')->getMasterRequest();
return new static($configuration, $plugin_id, $plugin_definition, $request);
}
......
......@@ -84,7 +84,7 @@ class DummyQuery extends UrlProcessorPluginBase {
$result_get_params->set($this->filterKey, $filter_params);
$request = $this->request;
if ($facet->getFacetSource()->getPath()) {
$request = Request::create('/' . $facet->getFacetSource()->getPath());
$request = Request::create($facet->getFacetSource()->getPath());
}
$url = Url::createFromRequest($request);
$url->setOption('query', $result_get_params->all());
......
......@@ -187,6 +187,13 @@ display:
position: 1
display_options:
path: search-api-test-fulltext
block_1:
display_plugin: block
id: block_1
display_title: Block
position: 2
display_options:
display_extenders: { }
label: 'Search API Test Fulltext search view'
module: views
id: search_api_test_view
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment