diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/style/Table.php b/core/modules/views/lib/Drupal/views/Plugin/views/style/Table.php index 6b5e483586c68ade7e8d5b54404d64d964b67fdb..28327c1c9d067ff1582fec305201ad0684be1160 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/style/Table.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/style/Table.php @@ -101,9 +101,7 @@ protected function defineOptions() { } /** - * Determine if we should provide sorting based upon $_GET inputs - * - * @return bool + * {@inheritdoc} */ function build_sort() { $order = $this->request->query->get('order'); diff --git a/core/modules/views/lib/Drupal/views/Tests/Plugin/StyleTableUnitTest.php b/core/modules/views/lib/Drupal/views/Tests/Plugin/StyleTableUnitTest.php new file mode 100644 index 0000000000000000000000000000000000000000..38e67b4fe0f5fe74950c836d3c01d4bcf95d6ac8 --- /dev/null +++ b/core/modules/views/lib/Drupal/views/Tests/Plugin/StyleTableUnitTest.php @@ -0,0 +1,161 @@ +<?php + +/** + * @file + * Contains \Drupal\views\Tests\Plugin\StyleTableUnitTest. + */ + +namespace Drupal\views\Tests\Plugin; + +use Drupal\views\ViewExecutable; +use Symfony\Component\HttpFoundation\Request; + +/** + * Tests the table style plugin. + * + * @see \Drupal\views\Plugin\views\style\Table + */ +class StyleTableUnitTest extends PluginUnitTestBase { + + /** + * Views used by this test. + * + * @var array + */ + public static $testViews = array('test_table'); + + public static function getInfo() { + return array( + 'name' => 'Style: Table (Unit Test)', + 'description' => 'Tests the table style plugin.', + 'group' => 'Views Plugins', + ); + } + + /** + * Tests the table style. + */ + public function testTable() { + $view = views_get_view('test_table'); + + $view->setDisplay('default'); + $view->initStyle(); + $view->initHandlers(); + $view->initQuery(); + $style_plugin = $view->style_plugin; + + // Test the build_sort() method. + $request = new Request(); + $this->container->enterScope('request'); + $this->container->set('request', $request); + + $style_plugin->options['override'] = FALSE; + + $style_plugin->options['default'] = ''; + $this->assertTrue($style_plugin->build_sort(), 'If no order and no default order is specified, the normal sort should be used.'); + + $style_plugin->options['default'] = 'id'; + $this->assertTrue($style_plugin->build_sort(), 'If no order but a default order is specified, the normal sort should be used.'); + + $request->attributes->set('order', $this->randomName()); + $this->assertTrue($style_plugin->build_sort(), 'If no valid field is chosen for order, the normal sort should be used.'); + + $request->attributes->set('order', 'id'); + $this->assertTrue($style_plugin->build_sort(), 'If a valid order is specified but the table is configured to not override, the normal sort should be used.'); + + $style_plugin->options['override'] = TRUE; + + $this->assertFalse($style_plugin->build_sort(), 'If a valid order is specified and the table is configured to override, the normal sort should not be used.'); + + // Test the build_sort_post() method. + $request = new Request(); + $this->container->enterScope('request'); + $this->container->set('request', $request); + + // Setup no valid default. + $this->prepareView($view); + $style_plugin = $view->style_plugin; + $style_plugin->options['default'] = ''; + $style_plugin->build_sort_post(); + $this->assertIdentical($style_plugin->order, NULL, 'No sort order was set, when no order was specified and no default column was selected.'); + $this->assertIdentical($style_plugin->active, NULL, 'No sort field was set, when no order was specified and no default column was selected.'); + $view->destroy(); + + // Setup a valid default + column specific default sort order. + $this->prepareView($view); + $style_plugin = $view->style_plugin; + $style_plugin->options['default'] = 'id'; + $style_plugin->options['info']['id']['default_sort_order'] = 'desc'; + $style_plugin->build_sort_post(); + $this->assertIdentical($style_plugin->order, 'desc', 'Fallback to the right default sort order.'); + $this->assertIdentical($style_plugin->active, 'id', 'Fallback to the right default sort field.'); + $view->destroy(); + + // Setup a valid default + table default sort order. + $this->prepareView($view); + $style_plugin = $view->style_plugin; + $style_plugin->options['default'] = 'id'; + $style_plugin->options['info']['id']['default_sort_order'] = NULL; + $style_plugin->options['order'] = 'asc'; + $style_plugin->build_sort_post(); + $this->assertIdentical($style_plugin->order, 'asc', 'Fallback to the right default sort order.'); + $this->assertIdentical($style_plugin->active, 'id', 'Fallback to the right default sort field.'); + $view->destroy(); + + // Use an invalid field. + $this->prepareView($view); + $style_plugin = $view->style_plugin; + $request->query->set('sort', 'asc'); + $random_name = $this->randomName(); + $request->query->set('order', $random_name); + $style_plugin->build_sort_post(); + $this->assertIdentical($style_plugin->order, 'asc', 'No sort order was set, when invalid sort order was specified.'); + $this->assertIdentical($style_plugin->active, NULL, 'No sort field was set, when invalid sort order was specified.'); + $view->destroy(); + + // Use a existing field, and sort both ascending and descending. + foreach (array('asc', 'desc') as $order) { + $this->prepareView($view); + $style_plugin = $view->style_plugin; + $request->query->set('sort', $order); + $request->query->set('order', 'id'); + $style_plugin->build_sort_post(); + $this->assertIdentical($style_plugin->order, $order, 'Ensure the right sort order was set.'); + $this->assertIdentical($style_plugin->active, 'id', 'Ensure the right order was set.'); + $view->destroy(); + } + + $view->destroy(); + + // Render a non empty result, and ensure that the empty area handler is not + // rendered. + $this->executeView($view); + $output = $view->preview(); + $output = drupal_render($output); + + $this->assertFalse(strpos($output, 'custom text') !== FALSE, 'Empty handler was not rendered on a non empty table.'); + + // Render an empty result, and ensure that the area handler is rendered. + $view->setDisplay('default'); + $view->executed = TRUE; + $view->result = array(); + $output = $view->preview(); + $output = drupal_render($output); + + $this->assertTrue(strpos($output, 'custom text') !== FALSE, 'Empty handler got rendered on an empty table.'); + } + + /** + * Prepares a view executable by initializing everything which is needed. + * + * @param \Drupal\views\ViewExecutable $view + * The executable to prepare. + */ + protected function prepareView(ViewExecutable $view) { + $view->setDisplay(); + $view->initStyle(); + $view->initHandlers(); + $view->initQuery(); + } + +} diff --git a/core/modules/views/tests/views_test_config/test_views/views.view.test_table.yml b/core/modules/views/tests/views_test_config/test_views/views.view.test_table.yml new file mode 100644 index 0000000000000000000000000000000000000000..49ae0e9d465aa61d98541a76eba23b8233d48430 --- /dev/null +++ b/core/modules/views/tests/views_test_config/test_views/views.view.test_table.yml @@ -0,0 +1,104 @@ +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: + age: + field: age + id: age + relationship: none + table: views_test_data + plugin_id: numeric + id: + field: id + id: id + relationship: none + table: views_test_data + plugin_id: numeric + name: + field: name + id: name + relationship: none + table: views_test_data + plugin_id: string + pager: + options: + offset: '0' + type: none + pager_options: { } + sorts: + id: + field: id + id: id + order: ASC + relationship: none + table: views_test_data + plugin_id: numeric + style: + type: table + options: + grouping: { } + row_class: '' + default_row_class: '1' + row_class_special: '1' + override: '1' + sticky: '0' + summary: '' + columns: + age: age + id: id + name: name + info: + age: + sortable: '0' + default_sort_order: asc + align: '' + separator: '' + empty_column: '0' + responsive: '' + id: + sortable: '1' + default_sort_order: desc + align: '' + separator: '' + empty_column: '0' + responsive: '' + name: + sortable: '1' + default_sort_order: asc + align: '' + separator: '' + empty_column: '0' + responsive: '' + default: 'id' + empty_table: '1' + row: + type: fields + empty: + area_text_custom: + id: area_text_custom + table: views + field: area_text_custom + relationship: none + group_type: group + admin_label: '' + label: '' + empty: '1' + content: 'custom text' + tokenize: '0' + plugin_id: text_custom + display_plugin: default + display_title: Master + id: default + position: '0' +label: '' +id: test_table +tag: '' diff --git a/core/modules/views/views.theme.inc b/core/modules/views/views.theme.inc index 0bae0fc39ca56a6f46ffbc37be712f51f27d26db..4178bacf979e4c1d7326a54831d140e1a87b25f0 100644 --- a/core/modules/views/views.theme.inc +++ b/core/modules/views/views.theme.inc @@ -617,6 +617,7 @@ function template_preprocess_views_view_table(&$vars) { } $count = 0; + $vars['row_classes'] = array(); foreach ($vars['rows'] as $num => $row) { $vars['row_classes'][$num] = array(); if ($row_class_special) { @@ -636,7 +637,9 @@ function template_preprocess_views_view_table(&$vars) { $vars['attributes']['class'][] = 'views-table'; if (empty($vars['rows']) && !empty($options['empty_table'])) { - $vars['rows'][0][0] = $view->display_handler->renderArea('empty'); + $build = $view->display_handler->renderArea('empty'); + $vars['rows'][0][0] = drupal_render($build); + $vars['row_classes'][0] = new Attribute(); // Calculate the amounts of rows with output. $vars['field_classes'][0][0] = new Attribute(array( 'colspan' => count($vars['header']),