diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/filter/BooleanOperator.php b/core/modules/views/lib/Drupal/views/Plugin/views/filter/BooleanOperator.php index dfdd23b4f15..77519fea5c0 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/filter/BooleanOperator.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/filter/BooleanOperator.php @@ -38,6 +38,42 @@ class BooleanOperator extends FilterPluginBase { // Whether to accept NULL as a false value or not var $accept_null = FALSE; + + + /** + * {@inheritdoc} + */ + public function operatorOptions($which = 'title') { + $options = array(); + foreach ($this->operators() as $id => $info) { + $options[$id] = $info[$which]; + } + + return $options; + } + + /** + * Returns an array of operator information. + * + * @return array + */ + protected function operators() { + return array( + '=' => array( + 'title' => t('Is equal to'), + 'method' => 'queryOpBoolean', + 'short' => t('='), + 'values' => 1, + ), + '!=' => array( + 'title' => t('Is not equal to'), + 'method' => 'queryOpBoolean', + 'short' => t('!='), + 'values' => 1, + ), + ); + } + /** * Overrides \Drupal\views\Plugin\views\filter\FilterPluginBase::init(). */ @@ -96,10 +132,6 @@ class BooleanOperator extends FilterPluginBase { return $options; } - protected function operatorForm(&$form, &$form_state) { - $form['operator'] = array(); - } - protected function valueForm(&$form, &$form_state) { if (empty($this->value_options)) { // Initialize the array of possible values for this filter. @@ -136,7 +168,7 @@ class BooleanOperator extends FilterPluginBase { } protected function valueValidate($form, &$form_state) { - if ($form_state['values']['options']['value'] == 'All' && !empty($form_state['values']['options']['expose']['required'])) { + if (isset($form_state['values']['options']['value']) && $form_state['values']['options']['value'] == 'All' && !empty($form_state['values']['options']['expose']['required'])) { form_set_error('value', t('You must select a value unless this is an non-required exposed filter.')); } } @@ -165,10 +197,26 @@ class BooleanOperator extends FilterPluginBase { $this->options['expose']['required'] = TRUE; } + /** + * {@inheritdoc} + */ public function query() { $this->ensureMyTable(); $field = "$this->tableAlias.$this->realField"; + $info = $this->operators(); + if (!empty($info[$this->operator]['method'])) { + call_user_func(array($this, $info[$this->operator]['method']), $field); + } + } + + /** + * Adds a where condition to the query for a boolean value. + * + * @param string $field + * The field name to add the where condition for. + */ + protected function queryOpBoolean($field) { if (empty($this->value)) { if ($this->accept_null) { $or = db_or() diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/filter/FilterPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/filter/FilterPluginBase.php index 9455174fd38..ec65d2ce5f4 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/filter/FilterPluginBase.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/filter/FilterPluginBase.php @@ -1002,7 +1002,7 @@ abstract class FilterPluginBase extends HandlerBase { } if ($without_children) { - if (!empty($this->options['group_info']['group_items'][$item_id]['value'])) { + if (isset($this->options['group_info']['group_items'][$item_id]['value']) && $this->options['group_info']['group_items'][$item_id]['value'] != '') { $row['value']['#default_value'] = $this->options['group_info']['group_items'][$item_id]['value']; } } @@ -1339,8 +1339,6 @@ abstract class FilterPluginBase extends HandlerBase { return FALSE; } } - - if (isset($value)) { $this->value = $value; if (empty($this->always_multiple) && empty($this->options['expose']['multiple'])) { diff --git a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterBooleanOperatorTest.php b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterBooleanOperatorTest.php new file mode 100644 index 00000000000..d354f0f8065 --- /dev/null +++ b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterBooleanOperatorTest.php @@ -0,0 +1,102 @@ + 'id', + ); + + public static function getInfo() { + return array( + 'name' => 'Filter: Boolean operator', + 'description' => 'Test the core Drupal\views\Plugin\views\filter\BooleanOperator handler.', + 'group' => 'Views Handlers', + ); + } + + protected function setUp() { + parent::setUp(); + + $this->installSchema('system', array('menu_router', 'variable', 'key_value_expire')); + } + + /** + * Tests the BooleanOperator filter. + */ + public function testFilterBooleanOperator() { + $view = views_get_view('test_view'); + $view->setDisplay(); + + // Add a the status boolean filter. + $view->displayHandlers->get('default')->overrideOption('filters', array( + 'status' => array( + 'id' => 'status', + 'field' => 'status', + 'table' => 'views_test_data', + 'value' => 0, + ), + )); + $this->executeView($view); + + $expected_result = array( + array('id' => 2), + array('id' => 4), + ); + + $this->assertEqual(2, count($view->result)); + $this->assertIdenticalResultset($view, $expected_result, $this->column_map); + + $view->destroy(); + $view->setDisplay(); + + // Add the status boolean filter. + $view->displayHandlers->get('default')->overrideOption('filters', array( + 'status' => array( + 'id' => 'status', + 'field' => 'status', + 'table' => 'views_test_data', + 'value' => 1, + ), + )); + $this->executeView($view); + + $expected_result = array( + array('id' => 1), + array('id' => 3), + array('id' => 5), + ); + + $this->assertEqual(3, count($view->result)); + $this->assertIdenticalResultset($view, $expected_result, $this->column_map); + } + +} + diff --git a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterCombineTest.php b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterCombineTest.php index 89696d0c9b4..e49acdb5bcc 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterCombineTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterCombineTest.php @@ -96,6 +96,7 @@ class FilterCombineTest extends ViewUnitTestBase { 'age' => 25, 'job' => NULL, 'created' => gmmktime(0, 0, 0, 1, 2, 2000), + 'status' => 1, ); return $data_set; } diff --git a/core/modules/views/lib/Drupal/views/Tests/Handler/SortRandomTest.php b/core/modules/views/lib/Drupal/views/Tests/Handler/SortRandomTest.php index 57906253730..2fabc212cf3 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Handler/SortRandomTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Handler/SortRandomTest.php @@ -40,6 +40,7 @@ class SortRandomTest extends ViewUnitTestBase { 'age' => $i, 'job' => 'job_' . $i, 'created' => rand(0, time()), + 'status' => 1, ); } return $data; diff --git a/core/modules/views/lib/Drupal/views/Tests/ViewTestData.php b/core/modules/views/lib/Drupal/views/Tests/ViewTestData.php index 3f2bfd1dd39..a86e2b32bcf 100644 --- a/core/modules/views/lib/Drupal/views/Tests/ViewTestData.php +++ b/core/modules/views/lib/Drupal/views/Tests/ViewTestData.php @@ -112,6 +112,13 @@ class ViewTestData { 'not null' => TRUE, 'default' => 0, ), + 'status' => array( + 'description' => "The status of this record", + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), ), 'primary key' => array('id'), 'unique keys' => array( @@ -219,6 +226,19 @@ class ViewTestData { 'id' => 'date', ), ); + $data['views_test_data']['status'] = array( + 'title' => t('Status'), + 'help' => t('The status of this record'), + 'field' => array( + 'id' => 'boolean', + ), + 'filter' => array( + 'id' => 'boolean', + ), + 'sort' => array( + 'id' => 'standard', + ), + ); return $data; } @@ -232,30 +252,35 @@ class ViewTestData { 'age' => 25, 'job' => 'Singer', 'created' => gmmktime(0, 0, 0, 1, 1, 2000), + 'status' => 1, ), array( 'name' => 'George', 'age' => 27, 'job' => 'Singer', 'created' => gmmktime(0, 0, 0, 1, 2, 2000), + 'status' => 0, ), array( 'name' => 'Ringo', 'age' => 28, 'job' => 'Drummer', 'created' => gmmktime(6, 30, 30, 1, 1, 2000), + 'status' => 1, ), array( 'name' => 'Paul', 'age' => 26, 'job' => 'Songwriter', 'created' => gmmktime(6, 0, 0, 1, 1, 2000), + 'status' => 0, ), array( 'name' => 'Meredith', 'age' => 30, 'job' => 'Speaker', 'created' => gmmktime(6, 30, 10, 1, 1, 2000), + 'status' => 1, ), ); } diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Tests/FilterBooleanWebTest.php b/core/modules/views_ui/lib/Drupal/views_ui/Tests/FilterBooleanWebTest.php new file mode 100644 index 00000000000..4463ef1e404 --- /dev/null +++ b/core/modules/views_ui/lib/Drupal/views_ui/Tests/FilterBooleanWebTest.php @@ -0,0 +1,64 @@ + 'Filter: Boolean', + 'description' => 'Tests the boolean filter UI.', + 'group' => 'Views UI', + ); + } + + /** + * Tests the filter boolean UI. + */ + public function testFilterBooleanUI() { + $this->drupalPost('admin/structure/views/nojs/add-item/test_view/default/filter', array('name[views_test_data.status]' => TRUE), t('Add and configure @handler', array('@handler' => t('filter criteria')))); + + $this->drupalPost(NULL, array(), t('Expose filter')); + $this->drupalPost(NULL, array(), t('Grouped filters')); + + $edit = array(); + $edit['options[group_info][group_items][1][title]'] = 'Published'; + $edit['options[group_info][group_items][1][operator]'] = '='; + $edit['options[group_info][group_items][1][value]'] = 1; + $edit['options[group_info][group_items][2][title]'] = 'Not published'; + $edit['options[group_info][group_items][2][operator]'] = '='; + $edit['options[group_info][group_items][2][value]'] = 0; + $edit['options[group_info][group_items][3][title]'] = 'Not published2'; + $edit['options[group_info][group_items][3][operator]'] = '!='; + $edit['options[group_info][group_items][3][value]'] = 1; + + $this->drupalPost(NULL, $edit, t('Apply')); + + $this->drupalGet('admin/structure/views/nojs/config-item/test_view/default/filter/status'); + + $result = $this->xpath('//input[@name="options[group_info][group_items][1][value]"]'); + $this->assertEqual((int) $result[1]->attributes()->checked, 'checked'); + $result = $this->xpath('//input[@name="options[group_info][group_items][2][value]"]'); + $this->assertEqual((int) $result[2]->attributes()->checked, 'checked'); + $result = $this->xpath('//input[@name="options[group_info][group_items][3][value]"]'); + $this->assertEqual((int) $result[1]->attributes()->checked, 'checked'); + } + +}