diff --git a/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlock.php b/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlock.php index c749a195af7..d3cada45820 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlock.php +++ b/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlock.php @@ -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. * diff --git a/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlockBase.php b/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlockBase.php new file mode 100644 index 00000000000..b90b3e67aa4 --- /dev/null +++ b/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlockBase.php @@ -0,0 +1,124 @@ +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); + } + } + +} diff --git a/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsExposedFilterBlock.php b/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsExposedFilterBlock.php index 577caa55f6d..3ef4ecdfad3 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsExposedFilterBlock.php +++ b/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsExposedFilterBlock.php @@ -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; } diff --git a/core/modules/views/lib/Drupal/views/Tests/Plugin/ExposedFormTest.php b/core/modules/views/lib/Drupal/views/Tests/Plugin/ExposedFormTest.php index d491d1b0e1c..05b70354596 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Plugin/ExposedFormTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Plugin/ExposedFormTest.php @@ -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); + } + } diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_block.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_block.yml new file mode 100644 index 00000000000..0528a1d14cb --- /dev/null +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_block.yml @@ -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: ''