Раскрытый фильтр по дате в Drupal 8: прошедшие/текущие/будущие события

На одном из сайтов на Drupal 8 потребовалось выводить список различных культурных мероприятий города (выставки/концерты/конкурсы/и т.д.). Список выводится с помощью модуля Views. У мероприятия есть два поля типа «Дата»: начало мероприятия и конец мероприятия. Используя эти поля, нужно было сделать фильтрацию по текущим/прошлым/предстоящим событиям. Стандартной возможности реализовать такое через Exposed Filters по полям «Дата» я не обнаружил, так что пришлось изобретать свой велосипед.
Для начала к нужным материалам добавил поле «Время» тип «Список» и задал ему значения «Прошедший», «Текущий», «Будущий», и срыл его в hook_form_alter() (сначала это было поле на ссылку термина, но тогда к SQL-запросу добавлялись таблицы словарей через JOIN, что мне не нужно). Затем в фильтрах добавил фильтр «Начало» не пусто и «Конец» не пусто, чтобы в запрос добавились эти поля (лень было разбираться с addField() :)). Ну, наконец, и сам код:

function mymodule_views_query_alter($view, $query) {
 
  if($view->id() == "konkursy_i_vystavki")
  {
    //Скинем все условия фильтра времени
      foreach ($query->where as &$condition_group) {
        unset($condition_group["conditions"][2]);
      }
    //Добавим заного
    $group = $query->setWhereGroup($type = 'OR');
    //Прошедший
    if($view->exposed_raw_input['field_vrema_value'][1] == "1")
    {
      $query->addWhere($group, "node__field_konec.field_konec_value", date('Y-m-d') , '< ' );
    }
    //Будущий
    if($view->exposed_raw_input['field_vrema_value'][3] == "3")
    {
      $query->addWhere($group, "node__field_nacalo.field_nacalo_value", date('Y-m-d') , '>' );
    }
    //Текущий
    if($view->exposed_raw_input['field_vrema_value'][2] == "2")
    {
      $query->addWhereExpression($group, "node__field_nacalo.field_nacalo_value < = '".date('Y-m-d')."'  AND node__field_konec.field_konec_value > '".date('Y-m-d')."'");
    }
  }
}

Так как фильтр времени может иметь множественные значения, я определил его в отдельную группу: $group = $query->setWhereGroup($type = ‘OR’); — все условия, добавленные в эту группу, будут объединятся условием OR. Грубо говоря, если отметить все чекбоксы, то условие будет выглядеть так: прошедший OR текущий OR будущий. Однако у значения «Текущий» есть два условия, которые должны выполнятся (дата начала текущая дата начала в прошлом И дата конца сегодня или в будущем). Поэтому эти условия я определил не через addWhere, а через addWhereExpression(), позволяющую задавать комплексные условия.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *