Issue #2057831 by damiankloip: Fixed Exposed filter blocks do not work anymore.
parent
503103058f
commit
917cd10a20
|
@ -7,13 +7,10 @@
|
|||
|
||||
namespace Drupal\views\Plugin\Block;
|
||||
|
||||
use Drupal\block\BlockBase;
|
||||
use Drupal\Component\Annotation\Plugin;
|
||||
use Drupal\Core\Annotation\Translation;
|
||||
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||
use Drupal\Component\Utility\Xss;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\views\ViewExecutableFactory;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
|
@ -26,85 +23,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
|||
* derivative = "Drupal\views\Plugin\Derivative\ViewsBlock"
|
||||
* )
|
||||
*/
|
||||
class ViewsBlock extends BlockBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The View executable object.
|
||||
*
|
||||
* @var \Drupal\views\ViewExecutable
|
||||
*/
|
||||
protected $view;
|
||||
|
||||
/**
|
||||
* The display ID being used for this View.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $displayID;
|
||||
|
||||
/**
|
||||
* Indicates whether the display was successfully set.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $displaySet;
|
||||
|
||||
/**
|
||||
* Constructs a Drupal\Component\Plugin\PluginBase object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param array $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\views\ViewExecutableFactory $executable_factory
|
||||
* The view executable factory.
|
||||
* @param \Drupal\Core\Entity\EntityStorageControllerInterface $storage_controller
|
||||
* The views storage controller.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, array $plugin_definition, ViewExecutableFactory $executable_factory, EntityStorageControllerInterface $storage_controller) {
|
||||
$this->pluginId = $plugin_id;
|
||||
list($plugin, $delta) = explode(':', $this->getPluginId());
|
||||
list($name, $this->displayID) = explode('-', $delta, 2);
|
||||
// Load the view.
|
||||
$view = $storage_controller->load($name);
|
||||
$this->view = $executable_factory->get($view);
|
||||
$this->displaySet = $this->view->setDisplay($this->displayID);
|
||||
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) {
|
||||
return new static(
|
||||
$configuration, $plugin_id, $plugin_definition,
|
||||
$container->get('views.executable'),
|
||||
$container->get('plugin.manager.entity')->getStorageController('view')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\block\BlockBase::access().
|
||||
*/
|
||||
public function access() {
|
||||
return $this->view->access($this->displayID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\block\BlockBase::form().
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, array &$form_state) {
|
||||
$form = parent::buildConfigurationForm($form, $form_state);
|
||||
|
||||
// Set the default label to '' so the views internal title is used.
|
||||
$form['label']['#default_value'] = '';
|
||||
$form['label']['#access'] = FALSE;
|
||||
|
||||
return $form;
|
||||
}
|
||||
class ViewsBlock extends ViewsBlockBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -144,6 +63,8 @@ class ViewsBlock extends BlockBase implements ContainerFactoryPluginInterface {
|
|||
if ($this->displaySet) {
|
||||
return $this->view->display_handler->blockForm($this, $form, $form_state);
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -164,31 +85,6 @@ class ViewsBlock extends BlockBase implements ContainerFactoryPluginInterface {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts Views block content to a renderable array with contextual links.
|
||||
*
|
||||
* @param string|array $output
|
||||
* An string|array representing the block. This will be modified to be a
|
||||
* renderable array, containing the optional '#contextual_links' property (if
|
||||
* there are any contextual links associated with the block).
|
||||
* @param string $block_type
|
||||
* The type of the block. If it's 'block' it's a regular views display,
|
||||
* but 'exposed_filter' exist as well.
|
||||
*/
|
||||
protected function addContextualLinks(&$output, $block_type = 'block') {
|
||||
// Do not add contextual links to an empty block.
|
||||
if (!empty($output)) {
|
||||
// Contextual links only work on blocks whose content is a renderable
|
||||
// array, so if the block contains a string of already-rendered markup,
|
||||
// convert it to an array.
|
||||
if (is_string($output)) {
|
||||
$output = array('#markup' => $output);
|
||||
}
|
||||
// Add the contextual links.
|
||||
views_add_contextual_links($output, $block_type, $this->view, $this->displayID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a views block instance ID.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\views\Plugin\Block\ViewsBlockBase.
|
||||
*/
|
||||
|
||||
namespace Drupal\views\Plugin\Block;
|
||||
|
||||
use Drupal\block\BlockBase;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\views\ViewExecutableFactory;
|
||||
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Base class for Views block plugins.
|
||||
*/
|
||||
abstract class ViewsBlockBase extends BlockBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The View executable object.
|
||||
*
|
||||
* @var \Drupal\views\ViewExecutable
|
||||
*/
|
||||
protected $view;
|
||||
|
||||
/**
|
||||
* The display ID being used for this View.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $displayID;
|
||||
|
||||
/**
|
||||
* Indicates whether the display was successfully set.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $displaySet;
|
||||
|
||||
/**
|
||||
* Constructs a Drupal\Component\Plugin\PluginBase object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param array $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\views\ViewExecutableFactory $executable_factory
|
||||
* The view executable factory.
|
||||
* @param \Drupal\Core\Entity\EntityStorageControllerInterface $storage_controller
|
||||
* The views storage controller.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, array $plugin_definition, ViewExecutableFactory $executable_factory, EntityStorageControllerInterface $storage_controller) {
|
||||
$this->pluginId = $plugin_id;
|
||||
list($plugin, $delta) = explode(':', $this->getPluginId());
|
||||
list($name, $this->displayID) = explode('-', $delta, 2);
|
||||
// Load the view.
|
||||
$view = $storage_controller->load($name);
|
||||
$this->view = $executable_factory->get($view);
|
||||
$this->displaySet = $this->view->setDisplay($this->displayID);
|
||||
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) {
|
||||
return new static(
|
||||
$configuration, $plugin_id, $plugin_definition,
|
||||
$container->get('views.executable'),
|
||||
$container->get('plugin.manager.entity')->getStorageController('view')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access() {
|
||||
return $this->view->access($this->displayID);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, array &$form_state) {
|
||||
$form = parent::buildConfigurationForm($form, $form_state);
|
||||
|
||||
// Set the default label to '' so the views internal title is used.
|
||||
$form['label']['#default_value'] = '';
|
||||
$form['label']['#access'] = FALSE;
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts Views block content to a renderable array with contextual links.
|
||||
*
|
||||
* @param string|array $output
|
||||
* An string|array representing the block. This will be modified to be a
|
||||
* renderable array, containing the optional '#contextual_links' property (if
|
||||
* there are any contextual links associated with the block).
|
||||
* @param string $block_type
|
||||
* The type of the block. If it's 'block' it's a regular views display,
|
||||
* but 'exposed_filter' exist as well.
|
||||
*/
|
||||
protected function addContextualLinks(&$output, $block_type = 'block') {
|
||||
// Do not add contextual links to an empty block.
|
||||
if (!empty($output)) {
|
||||
// Contextual links only work on blocks whose content is a renderable
|
||||
// array, so if the block contains a string of already-rendered markup,
|
||||
// convert it to an array.
|
||||
if (is_string($output)) {
|
||||
$output = array('#markup' => $output);
|
||||
}
|
||||
// Add the contextual links.
|
||||
views_add_contextual_links($output, $block_type, $this->view, $this->displayID);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -20,7 +20,7 @@ use Drupal\Core\Annotation\Translation;
|
|||
* derivative = "Drupal\views\Plugin\Derivative\ViewsExposedFilterBlock"
|
||||
* )
|
||||
*/
|
||||
class ViewsExposedFilterBlock extends ViewsBlock {
|
||||
class ViewsExposedFilterBlock extends ViewsBlockBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -31,7 +31,6 @@ class ViewsExposedFilterBlock extends ViewsBlock {
|
|||
// contextual links.
|
||||
$this->addContextualLinks($output, 'exposed_filter');
|
||||
|
||||
$this->view->destroy();
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
namespace Drupal\views\Tests\Plugin;
|
||||
|
||||
use Drupal\views\Tests\ViewTestBase;
|
||||
use Drupal\views\ViewExecutable;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
* Tests exposed forms.
|
||||
|
@ -19,14 +21,14 @@ class ExposedFormTest extends ViewTestBase {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = array('test_reset_button');
|
||||
public static $testViews = array('test_reset_button', 'test_exposed_block');
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('views_ui');
|
||||
public static $modules = array('views_ui', 'block');
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
|
@ -102,11 +104,45 @@ class ExposedFormTest extends ViewTestBase {
|
|||
$output = $exposed_form->renderExposedForm();
|
||||
$this->drupalSetContent(drupal_render($output));
|
||||
|
||||
$expected_id = drupal_clean_css_identifier('views-exposed-form-' . $view->storage->id() . '-' . $view->current_display);
|
||||
$this->assertFieldByXpath('//form/@id', $expected_id, 'Expected form ID found.');
|
||||
$this->assertFieldByXpath('//form/@id', $this->getExpectedExposedFormId($view), 'Expected form ID found.');
|
||||
|
||||
$expected_action = url($view->display_handler->getUrl());
|
||||
$this->assertFieldByXPath('//form/@action', $expected_action, 'The expected value for the action attribute was found.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the exposed block functionality.
|
||||
*/
|
||||
public function testExposedBlock() {
|
||||
$view = Views::getView('test_exposed_block');
|
||||
$view->setDisplay('page_1');
|
||||
$block = $this->drupalPlaceBlock('views_exposed_filter_block:test_exposed_block-page_1');
|
||||
$this->drupalGet('test_exposed_block');
|
||||
|
||||
// Test there is an exposed form in a block.
|
||||
$xpath = $this->buildXPathQuery('//div[@id=:id]/div/form/@id', array(':id' => 'block-' . $block->get('machine_name')));
|
||||
$this->assertFieldByXpath($xpath, $this->getExpectedExposedFormId($view), 'Expected form found in views block.');
|
||||
|
||||
// Test there is not an exposed form in the view page content area.
|
||||
$xpath = $this->buildXPathQuery('//div[@class="view-content"]/form/@id', array(':id' => 'block-' . $block->get('machine_name')));
|
||||
$this->assertNoFieldByXpath($xpath, $this->getExpectedExposedFormId($view), 'No exposed form found in views content region.');
|
||||
|
||||
// Test there is only one views exposed form on the page.
|
||||
$elements = $this->xpath('//form[@id=:id]', array(':id' => $this->getExpectedExposedFormId($view)));
|
||||
$this->assertEqual(count($elements), 1, 'One exposed form block found.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a views exposed form ID.
|
||||
*
|
||||
* @param \Drupal\views\ViewExecutable $view
|
||||
* The view to create an ID for.
|
||||
*
|
||||
* @return string
|
||||
* The form ID.
|
||||
*/
|
||||
protected function getExpectedExposedFormId(ViewExecutable $view) {
|
||||
return drupal_clean_css_identifier('views-exposed-form-' . $view->storage->id() . '-' . $view->current_display);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
base_table: node
|
||||
core: '8'
|
||||
description: ''
|
||||
status: '1'
|
||||
display:
|
||||
default:
|
||||
display_options:
|
||||
access:
|
||||
type: none
|
||||
cache:
|
||||
type: none
|
||||
exposed_form:
|
||||
options:
|
||||
reset_button: '1'
|
||||
type: basic
|
||||
filters:
|
||||
type:
|
||||
expose:
|
||||
identifier: type
|
||||
label: 'Content: Type'
|
||||
operator_id: type_op
|
||||
reduce: '0'
|
||||
exposed: '1'
|
||||
field: type
|
||||
id: type
|
||||
table: node_field_data
|
||||
plugin_id: node_type
|
||||
provider: views
|
||||
pager:
|
||||
type: full
|
||||
query:
|
||||
options:
|
||||
query_comment: '0'
|
||||
type: views_query
|
||||
style:
|
||||
type: default
|
||||
row:
|
||||
type: 'entity:node'
|
||||
options:
|
||||
comments: '0'
|
||||
links: '1'
|
||||
display_plugin: default
|
||||
display_title: Master
|
||||
id: default
|
||||
position: '0'
|
||||
page_1:
|
||||
display_options:
|
||||
path: test_exposed_block
|
||||
exposed_block: '1'
|
||||
display_plugin: page
|
||||
display_title: Page
|
||||
id: page_1
|
||||
position: '0'
|
||||
label: ''
|
||||
id: test_exposed_block
|
||||
tag: ''
|
Loading…
Reference in New Issue