Skip to content
Snippets Groups Projects
Commit 2a43a1bd authored by Alex Pott's avatar Alex Pott
Browse files

Issue #1217394 by dawehner, jsacksick, MichaelCole, rutcreate, damiankloip:...

Issue #1217394 by dawehner, jsacksick, MichaelCole, rutcreate, damiankloip: Fixed "Display even if view has no result" not working.
parent 00c06fcf
No related branches found
No related tags found
2 merge requests!7452Issue #1797438. HTML5 validation is preventing form submit and not fully...,!789Issue #3210310: Adjust Database API to remove deprecated Drupal 9 code in Drupal 10
...@@ -49,6 +49,7 @@ protected function defineOptions() { ...@@ -49,6 +49,7 @@ protected function defineOptions() {
$options['block_description'] = array('default' => '', 'translatable' => TRUE); $options['block_description'] = array('default' => '', 'translatable' => TRUE);
$options['block_category'] = array('default' => 'Views', 'translatable' => TRUE); $options['block_category'] = array('default' => 'Views', 'translatable' => TRUE);
$options['block_caching'] = array('default' => DRUPAL_NO_CACHE); $options['block_caching'] = array('default' => DRUPAL_NO_CACHE);
$options['block_hide_empty'] = array('default' => FALSE);
$options['allow'] = array( $options['allow'] = array(
'contains' => array( 'contains' => array(
...@@ -83,11 +84,12 @@ public function execute() { ...@@ -83,11 +84,12 @@ public function execute() {
// Prior to this being called, the $view should already be set to this // Prior to this being called, the $view should already be set to this
// display, and arguments should be set on the view. // display, and arguments should be set on the view.
$element = $this->view->render(); $element = $this->view->render();
if (!empty($this->view->result) || $this->getOption('empty') || !empty($this->view->style_plugin->definition['even empty'])) { if ($this->outputIsEmpty() && $this->getOption('block_hide_empty') && empty($this->view->style_plugin->definition['even empty'])) {
return array();
}
else {
return $element; return $element;
} }
return array();
} }
/** /**
...@@ -137,6 +139,12 @@ public function optionsSummary(&$categories, &$options) { ...@@ -137,6 +139,12 @@ public function optionsSummary(&$categories, &$options) {
'title' => t('Block caching'), 'title' => t('Block caching'),
'value' => $types[$this->getCacheType()], 'value' => $types[$this->getCacheType()],
); );
$options['block_hide_empty'] = array(
'category' => 'other',
'title' => t('Hide block if the view output is empty'),
'value' => $this->getOption('block_hide_empty') ? t('Hide') : t('Show'),
);
} }
/** /**
...@@ -200,6 +208,16 @@ public function buildOptionsForm(&$form, &$form_state) { ...@@ -200,6 +208,16 @@ public function buildOptionsForm(&$form, &$form_state) {
'#default_value' => $this->getCacheType(), '#default_value' => $this->getCacheType(),
); );
break; break;
case 'block_hide_empty':
$form['#title'] .= t('Block empty settings');
$form['block_hide_empty'] = array(
'#title' => t('Hide block if no result/empty text'),
'#type' => 'checkbox',
'#description' => t('Hide the block if there is no result and no empty text and no header/footer which is shown on empty result'),
'#default_value' => $this->getOption('block_hide_empty'),
);
break;
case 'exposed_form_options': case 'exposed_form_options':
$this->view->initHandlers(); $this->view->initHandlers();
if (!$this->usesExposed() && parent::usesExposed()) { if (!$this->usesExposed() && parent::usesExposed()) {
...@@ -237,6 +255,7 @@ public function submitOptionsForm(&$form, &$form_state) { ...@@ -237,6 +255,7 @@ public function submitOptionsForm(&$form, &$form_state) {
case 'block_category': case 'block_category':
case 'block_caching': case 'block_caching':
case 'allow': case 'allow':
case 'block_hide_empty':
$this->setOption($form_state['section'], $form_state['values'][$form_state['section']]); $this->setOption($form_state['section'], $form_state['values'][$form_state['section']]);
break; break;
} }
......
...@@ -106,6 +106,19 @@ public function preRender(array $results) { ...@@ -106,6 +106,19 @@ public function preRender(array $results) {
*/ */
public abstract function render($empty = FALSE); public abstract function render($empty = FALSE);
/**
* Does that area have nothing to show.
*
* This method should be overridden by more complex handlers where the output
* is not static and maybe itself be empty if it's rendered.
*
* @return bool
* Return TRUE if the area is empty, else FALSE.
*/
public function isEmpty() {
return empty($this->options['empty']);
}
/** /**
* Area handlers shouldn't have groupby. * Area handlers shouldn't have groupby.
*/ */
......
...@@ -18,6 +18,16 @@ ...@@ -18,6 +18,16 @@
*/ */
class View extends AreaPluginBase { class View extends AreaPluginBase {
/**
* Stores whether the embedded view is actually empty.
*
* @var bool
*/
protected $isEmpty;
/**
* {@inheritdoc}
*/
protected function defineOptions() { protected function defineOptions() {
$options = parent::defineOptions(); $options = parent::defineOptions();
...@@ -77,14 +87,28 @@ public function render($empty = FALSE) { ...@@ -77,14 +87,28 @@ public function render($empty = FALSE) {
} }
else { else {
if (!empty($this->options['inherit_arguments']) && !empty($this->view->args)) { if (!empty($this->options['inherit_arguments']) && !empty($this->view->args)) {
return $view->preview($display_id, $this->view->args); $output = $view->preview($display_id, $this->view->args);
} }
else { else {
return $view->preview($display_id); $output = $view->preview($display_id);
} }
$this->isEmpty = $view->display_handler->outputIsEmpty();
return $output;
} }
} }
return array(); return array();
} }
/**
* {@inheritdoc}
*/
public function isEmpty() {
if (isset($this->isEmpty)) {
return $this->isEmpty;
}
else {
return parent::isEmpty();
}
}
} }
...@@ -2723,6 +2723,34 @@ public function isIdentifierUnique($id, $identifier) { ...@@ -2723,6 +2723,34 @@ public function isIdentifierUnique($id, $identifier) {
return TRUE; return TRUE;
} }
/**
* Is the output of the view empty.
*
* If a view has no result and neither the empty, nor the footer nor the header
* does show anything return FALSE.
*
* @return bool
* Returns TRUE if the output is empty, else FALSE.
*/
public function outputIsEmpty() {
if (!empty($this->view->result)) {
return FALSE;
}
// Check whether all of the area handlers are empty.
foreach (array('empty', 'footer', 'header') as $type) {
$handlers = $this->getHandlers($type);
foreach ($handlers as $handler) {
// If one is not empty, return FALSE now.
if (!$handler->isEmpty()) {
return FALSE;
}
}
}
return TRUE;
}
/** /**
* Provide the block system with any exposed widget blocks for this display. * Provide the block system with any exposed widget blocks for this display.
*/ */
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
namespace Drupal\views\Tests\Plugin; namespace Drupal\views\Tests\Plugin;
use Drupal\views\Views;
use Drupal\views_test_data\Plugin\views\display\DisplayTest as DisplayTestPlugin; use Drupal\views_test_data\Plugin\views\display\DisplayTest as DisplayTestPlugin;
/** /**
...@@ -19,7 +20,7 @@ class DisplayTest extends PluginTestBase { ...@@ -19,7 +20,7 @@ class DisplayTest extends PluginTestBase {
* *
* @var array * @var array
*/ */
public static $testViews = array('test_filter_groups', 'test_get_attach_displays', 'test_view', 'test_display_more', 'test_display_invalid'); public static $testViews = array('test_filter_groups', 'test_get_attach_displays', 'test_view', 'test_display_more', 'test_display_invalid', 'test_display_empty');
/** /**
* Modules to enable. * Modules to enable.
...@@ -273,4 +274,47 @@ public function testInvalidDisplayPlugins() { ...@@ -273,4 +274,47 @@ public function testInvalidDisplayPlugins() {
$this->assertNoBlockAppears($block); $this->assertNoBlockAppears($block);
} }
/**
* Tests the outputIsEmpty method on the display.
*/
public function testOutputIsEmpty() {
$view = Views::getView('test_display_empty');
$this->executeView($view);
$this->assertTrue(count($view->result) > 0, 'Ensure the result of the view is not empty.');
$this->assertFalse($view->display_handler->outputIsEmpty(), 'Ensure the view output is marked as not empty.');
$view->destroy();
// Add a filter, so the view result is empty.
$view->setDisplay('default');
$item = array(
'table' => 'views_test_data',
'field' => 'id',
'id' => 'id',
'value' => array('value' => 7297)
);
$view->setItem('default', 'filter', 'id', $item);
$this->executeView($view);
$this->assertFalse(count($view->result), 'Ensure the result of the view is empty.');
$this->assertFalse($view->display_handler->outputIsEmpty(), 'Ensure the view output is marked as not empty, because the empty text still appears.');
$view->destroy();
// Remove the empty area, but mark the header area to still appear.
$view->removeItem('default', 'empty', 'area');
$item = $view->getItem('default', 'header', 'area');
$item['empty'] = TRUE;
$view->setItem('default', 'header', 'area', $item);
$this->executeView($view);
$this->assertFalse(count($view->result), 'Ensure the result of the view is empty.');
$this->assertFalse($view->display_handler->outputIsEmpty(), 'Ensure the view output is marked as not empty, because the header text still appears.');
$view->destroy();
// Hide the header on empty results.
$item = $view->getItem('default', 'header', 'area');
$item['empty'] = FALSE;
$view->setItem('default', 'header', 'area', $item);
$this->executeView($view);
$this->assertFalse(count($view->result), 'Ensure the result of the view is empty.');
$this->assertTrue($view->display_handler->outputIsEmpty(), 'Ensure the view output is marked as empty.');
}
} }
base_table: views_test_data
core: '8'
description: ''
status: '1'
display:
default:
display_options:
defaults:
fields: '0'
pager: '0'
pager_options: '0'
sorts: '0'
fields:
id:
field: id
id: id
relationship: none
table: views_test_data
plugin_id: numeric
pager:
options:
offset: '0'
type: none
pager_options: { }
header:
area:
field: area
id: area
table: views
plugin_id: text
empty:
area:
field: area
id: area
table: views
plugin_id: text
display_plugin: default
display_title: Master
id: default
position: '0'
label: ''
langcode: en
id: test_display_empty
tag: ''
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment