Search by specific date programmatically

Last updated on
23 July 2024

A sample code implementation for a specific case when there is an exposed filter that is created by a certain search API view.

Let's say that you need to filter by a specific date.

First thing is to provide the exposed filter and with the operator is equal to.

Then, for the end-user the filter will be shown like this: 

The common issue is that the date filter will filter by the time which is now and not the desired date. Basically, we'll need a date range filter like: 05.16.2022 00:00:0005.16.2022 23:59:59.

In order to make it happen, we'll need a custom implementation (alongside the exposed filter default configuration):

use Drupal\search_api\Query\QueryInterface;
use Drupal\Core\Datetime\DrupalDateTime;

/**
 * Implements hook_search_api_query_alter().
 */
function modulename_search_api_query_alter(QueryInterface $query) {
  if ($query->getIndex()->id() == 'some_index_id' && $query->getsearchId() == 'some_search_id') {
    $condition_groups = &$query->getConditionGroup()->getConditions();
    $field_published = 'field_published';
    // Set a loop for all group of conditions and conditions in order to find
    // the date field and adjust the filter.
    foreach ($condition_groups as &$condition_group) {
      $conditions = &$condition_group->getConditions();
      foreach ($conditions as $i => $condition) {
        if ($condition->getField() == $field_published) {
          // Unset the current filter because it's not working as it should.
          unset($conditions[$i]);
          // Get the GET date param value.
          $published = \Drupal::request()->query->get($field_published);
          if (!$published) {
            continue;
          }
          $created_from = (new DrupalDateTime($published, 'UTC'))->setTime(0, 0, 0)->getTimestamp();
          $created_to = (new DrupalDateTime($published, 'UTC'))->setTime(23, 59, 59)->getTimestamp();
          // Add a date range conditions for a certain date.
          $condition_group->addCondition($field_published, $created_from, '>=');
          $condition_group->addCondition($field_published, $created_to, '<=');
        }
      }
    }
  }
}

In the end, the filter will filter all the content by the given date.

Help improve this page

Page status: No known problems

You can: