Commit 53e59ba8 authored by Vadym Abramchuk's avatar Vadym Abramchuk Committed by Thomas Seidl
Browse files

Issue #3296477 by abramm, drunken monkey: Fixed results when only one value is...

Issue #3296477 by abramm, drunken monkey: Fixed results when only one value is entered in a Views date range filter.
parent 30914cd0
Loading
Loading
Loading
Loading
+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
+33 −11
Original line number Diff line number Diff line
@@ -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;
      }
    }
@@ -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.).
+47 −0
Original line number Diff line number Diff line
@@ -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' => '>',
@@ -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();
@@ -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.
   */