Loading CHANGELOG.txt +2 −0 Original line number Diff line number Diff line Search API 1.x, dev (xxxx-xx-xx): --------------------------------- - #3296477 by abramm, drunken monkey: Fixed results when only one value is entered in a Views date range filter. - #2855447 by edurenye, drunken monkey, alexdoma: Added option to customize the separator used for aggregated fields of type "Fulltext". - #3304560 by recrit, Gertlor, drunken monkey: Fixed problems with "Multiple Loading src/Plugin/views/filter/SearchApiDate.php +33 −11 Original line number Diff line number Diff line Loading @@ -74,9 +74,16 @@ class SearchApiDate extends Date { $return = parent::acceptExposedInput($input); if (!$return) { // Override for the "(not) empty" operators. // The parent class doesn't always handle operators with 0 or 2 values // correctly. $operators = $this->operators(); if ($operators[$this->operator]['values'] == 0) { $num_values = $operators[$this->operator]['values']; if ($num_values == 0) { return TRUE; } // @todo Remove this once we depend on a Core version that fixed #3202489. elseif ($num_values == 2 && (!empty($this->value['min']) || !empty($this->value['max']))) { return TRUE; } } Loading @@ -93,20 +100,35 @@ class SearchApiDate extends Date { // No time was specified, so make the date range inclusive. $this->value['max'] .= ' +1 day'; } if (($this->value['type'] ?? '') == 'offset') { $time = $this->getTimeService()->getRequestTime(); $a = strtotime($this->value['min'], $time); $b = strtotime($this->value['max'], $time); $base_timestamp = $this->value['type'] == 'offset' ? $this->getTimeService()->getRequestTime() : 0; $a = $b = NULL; if (!empty($this->value['min'])) { $a = strtotime($this->value['min'], $base_timestamp); } else { $a = intval(strtotime($this->value['min'], 0)); $b = intval(strtotime($this->value['max'], 0)); if (!empty($this->value['max'])) { $b = strtotime($this->value['max'], $base_timestamp); } $real_field = $this->realField; $operator = strtoupper($this->operator); $group = $this->options['group']; if (isset($a, $b)) { $operator = strtoupper($this->operator); $this->getQuery()->addCondition($real_field, [$a, $b], $operator, $group); } elseif (isset($a)) { // Using >= for BETWEEN and < for NOT BETWEEN. $operator = $this->operator === 'between' ? '>=' : '<'; $this->getQuery()->addCondition($real_field, $a, $operator, $group); } elseif (isset($b)) { // Using <= for BETWEEN and > for NOT BETWEEN. $operator = $this->operator === 'between' ? '<=' : '>'; $this->getQuery()->addCondition($real_field, $b, $operator, $group); } } /** * Filters by a simple operator (=, !=, >, etc.). Loading tests/src/Functional/ViewsTest.php +47 −0 Original line number Diff line number Diff line Loading @@ -121,12 +121,32 @@ class ViewsTest extends SearchApiBrowserTestBase { 'id_op' => 'between', ]; $this->checkResults($query, [2, 3, 4], 'Search with ID "in between" filter'); $query = [ 'id[min]' => 2, 'id_op' => 'between', ]; $this->checkResults($query, [2, 3, 4, 5], 'Search with ID "in between" filter (only min)'); $query = [ 'id[max]' => 4, 'id_op' => 'between', ]; $this->checkResults($query, [1, 2, 3, 4], 'Search with ID "in between" filter (only max)'); $query = [ 'id[min]' => 2, 'id[max]' => 4, 'id_op' => 'not between', ]; $this->checkResults($query, [1, 5], 'Search with ID "not in between" filter'); $query = [ 'id[min]' => 2, 'id_op' => 'not between', ]; $this->checkResults($query, [1], 'Search with ID "not in between" filter (only min)'); $query = [ 'id[max]' => 4, 'id_op' => 'not between', ]; $this->checkResults($query, [5], 'Search with ID "not in between" filter (only max)'); $query = [ 'id[value]' => 2, 'id_op' => '>', Loading Loading @@ -396,6 +416,7 @@ class ViewsTest extends SearchApiBrowserTestBase { * Contains regression tests for previous, fixed bugs. */ protected function regressionTests() { $this->regressionTest3296477(); $this->regressionTest3318187(); $this->regressionTest3187134(); $this->regressionTest2869121(); Loading Loading @@ -787,6 +808,32 @@ class ViewsTest extends SearchApiBrowserTestBase { $this->assertSession()->pageTextContains('2021-01-22'); } /** * Tests that date "in between" filters also work with just one value. * * @see https://www.drupal.org/node/3296477 */ protected function regressionTest3296477(): void { $yesterday = date('Y-m-d', strtotime('-1DAY')); $tomorrow = date('Y-m-d', strtotime('+1DAY')); $query = [ 'created[min]' => $yesterday, 'created[max]' => $tomorrow, 'created_op' => 'between', ]; $this->checkResults($query, [1, 2, 3, 4, 5], 'Search with "Created between TODAY and TOMORROW" filter'); $query = [ 'created[min]' => $tomorrow, 'created_op' => 'between', ]; $this->checkResults($query, [], 'Search with "Created between TOMORROW and *" filter'); $query = [ 'created[max]' => $yesterday, 'created_op' => 'between', ]; $this->checkResults($query, [], 'Search with "Created between * and YESTERDAY" filter'); } /** * Verifies that exposed fulltext fields work correctly. */ Loading Loading
CHANGELOG.txt +2 −0 Original line number Diff line number Diff line Search API 1.x, dev (xxxx-xx-xx): --------------------------------- - #3296477 by abramm, drunken monkey: Fixed results when only one value is entered in a Views date range filter. - #2855447 by edurenye, drunken monkey, alexdoma: Added option to customize the separator used for aggregated fields of type "Fulltext". - #3304560 by recrit, Gertlor, drunken monkey: Fixed problems with "Multiple Loading
src/Plugin/views/filter/SearchApiDate.php +33 −11 Original line number Diff line number Diff line Loading @@ -74,9 +74,16 @@ class SearchApiDate extends Date { $return = parent::acceptExposedInput($input); if (!$return) { // Override for the "(not) empty" operators. // The parent class doesn't always handle operators with 0 or 2 values // correctly. $operators = $this->operators(); if ($operators[$this->operator]['values'] == 0) { $num_values = $operators[$this->operator]['values']; if ($num_values == 0) { return TRUE; } // @todo Remove this once we depend on a Core version that fixed #3202489. elseif ($num_values == 2 && (!empty($this->value['min']) || !empty($this->value['max']))) { return TRUE; } } Loading @@ -93,20 +100,35 @@ class SearchApiDate extends Date { // No time was specified, so make the date range inclusive. $this->value['max'] .= ' +1 day'; } if (($this->value['type'] ?? '') == 'offset') { $time = $this->getTimeService()->getRequestTime(); $a = strtotime($this->value['min'], $time); $b = strtotime($this->value['max'], $time); $base_timestamp = $this->value['type'] == 'offset' ? $this->getTimeService()->getRequestTime() : 0; $a = $b = NULL; if (!empty($this->value['min'])) { $a = strtotime($this->value['min'], $base_timestamp); } else { $a = intval(strtotime($this->value['min'], 0)); $b = intval(strtotime($this->value['max'], 0)); if (!empty($this->value['max'])) { $b = strtotime($this->value['max'], $base_timestamp); } $real_field = $this->realField; $operator = strtoupper($this->operator); $group = $this->options['group']; if (isset($a, $b)) { $operator = strtoupper($this->operator); $this->getQuery()->addCondition($real_field, [$a, $b], $operator, $group); } elseif (isset($a)) { // Using >= for BETWEEN and < for NOT BETWEEN. $operator = $this->operator === 'between' ? '>=' : '<'; $this->getQuery()->addCondition($real_field, $a, $operator, $group); } elseif (isset($b)) { // Using <= for BETWEEN and > for NOT BETWEEN. $operator = $this->operator === 'between' ? '<=' : '>'; $this->getQuery()->addCondition($real_field, $b, $operator, $group); } } /** * Filters by a simple operator (=, !=, >, etc.). Loading
tests/src/Functional/ViewsTest.php +47 −0 Original line number Diff line number Diff line Loading @@ -121,12 +121,32 @@ class ViewsTest extends SearchApiBrowserTestBase { 'id_op' => 'between', ]; $this->checkResults($query, [2, 3, 4], 'Search with ID "in between" filter'); $query = [ 'id[min]' => 2, 'id_op' => 'between', ]; $this->checkResults($query, [2, 3, 4, 5], 'Search with ID "in between" filter (only min)'); $query = [ 'id[max]' => 4, 'id_op' => 'between', ]; $this->checkResults($query, [1, 2, 3, 4], 'Search with ID "in between" filter (only max)'); $query = [ 'id[min]' => 2, 'id[max]' => 4, 'id_op' => 'not between', ]; $this->checkResults($query, [1, 5], 'Search with ID "not in between" filter'); $query = [ 'id[min]' => 2, 'id_op' => 'not between', ]; $this->checkResults($query, [1], 'Search with ID "not in between" filter (only min)'); $query = [ 'id[max]' => 4, 'id_op' => 'not between', ]; $this->checkResults($query, [5], 'Search with ID "not in between" filter (only max)'); $query = [ 'id[value]' => 2, 'id_op' => '>', Loading Loading @@ -396,6 +416,7 @@ class ViewsTest extends SearchApiBrowserTestBase { * Contains regression tests for previous, fixed bugs. */ protected function regressionTests() { $this->regressionTest3296477(); $this->regressionTest3318187(); $this->regressionTest3187134(); $this->regressionTest2869121(); Loading Loading @@ -787,6 +808,32 @@ class ViewsTest extends SearchApiBrowserTestBase { $this->assertSession()->pageTextContains('2021-01-22'); } /** * Tests that date "in between" filters also work with just one value. * * @see https://www.drupal.org/node/3296477 */ protected function regressionTest3296477(): void { $yesterday = date('Y-m-d', strtotime('-1DAY')); $tomorrow = date('Y-m-d', strtotime('+1DAY')); $query = [ 'created[min]' => $yesterday, 'created[max]' => $tomorrow, 'created_op' => 'between', ]; $this->checkResults($query, [1, 2, 3, 4, 5], 'Search with "Created between TODAY and TOMORROW" filter'); $query = [ 'created[min]' => $tomorrow, 'created_op' => 'between', ]; $this->checkResults($query, [], 'Search with "Created between TOMORROW and *" filter'); $query = [ 'created[max]' => $yesterday, 'created_op' => 'between', ]; $this->checkResults($query, [], 'Search with "Created between * and YESTERDAY" filter'); } /** * Verifies that exposed fulltext fields work correctly. */ Loading