Вы здесь

Фильтр событий по дате "Прошедшие/Текущие/Будущие" во views

0

Господа, вроде вопрос банальный, но то ли я гуглом пользоваться разучился, то ли еще что... В общем, есть тип ноды "Событие", у него есть два поля даты: начало и конец. Каким образом можно вывести в Exposed Filters фильтр по этим полям в виде чекбоксов "Показать Прошедшие, Текущие, Будущие"?
Как я понимаю, логика такая:
прошлые - это когда дата конца меньше текущей
текущие - дата начала текущая, или дата начала в прошлом и дата конца сегодня или в будущем
будущие - дата начала больше текущей.
Вот только как эту логику описать...
Имею Drupal 8 + BEF

Версия Drupal: 
8.x
Вопрос задан 03.08.2016 - 16:27

Делал подобное, но только на 7 и с селектами. Пришлось использовать hook_views_query_alter

Как-то так:

/**
 * Implements hook_views_query_alter().
 */
function mymodule_views_query_alter(&$view, &$query) {
  if ($view->name == 'films') {
    if ($view->exposed_raw_input['select_field'] == 'all') {
      $cond = $query->where[1]['conditions'];
      foreach ($cond as $key => $value) {
        if ($value['operator']=='formula') {
          unset($query->where[1]['conditions'][$key]);
        }
      }
    }
    if ($view->exposed_raw_input['select_field'] == 'soon') {
      $cond = $query->where[1]['conditions'];
      foreach ($cond as $key => $value) {
        if ($value['operator']=='formula') {
          unset($query->where[1]['conditions'][$key]);
        }
      }
      $query->add_where(0, "field_data_field_first.field_first_value", date('Y-m-d') , '>');
    }
    if ($view->exposed_raw_input['select_field'] == 'arhive') {
      $cond = $query->where[1]['conditions'];
      foreach ($cond as $key => $value) {
        if ($value['operator']=='formula') {
          unset($query->where[1]['conditions'][$key]);
        }
      }
      $query->add_where(0, "field_data_field_first.field_first_value2", date('Y-m-d') , '<');
    }
  }
}
Комментарий оставлен 04.08.2016 - 12:00

Спасибо за наводку! Решил свою задачу, основываясь на ней. Более подробное описание решения ниже в ответах, если вдруг кому понадобится.
P.S.: Чего-то не разберусь, как вам в комментариях плюсик поставить за верный ответ.

Комментарий оставлен 07.08.2016 - 15:42

Ответы

-1

Спасибо товарищу lukasss за подсказку. Действительно, как-то я упустил hook_query_alter() из виду. Покурив маны по API Drupal 8 родилась вот такая его реализация:
Для начала к нужным материалам добавил поле "Время" тип "Список" и задал ему значения "Прошедший", "Текущий", "Будущий", и срыл его в hook_form_alter() (сначала это было поле на ссылку термина, но тогда к SQL-запросу добавлялись таблицы словарей через JOIN, что мне не нужно). Затем в фильтрах добавил фильтр "Начало" не пусто и "Конец" не пусто, чтобы в запрос добавились эти поля (лень было разбираться с addField() :)). Ну, наконец, и сам код:

<?php
function inno_hooks_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(), позволяющую задавать комплексные условия.

Ответ дан 07.08.2016 - 15:39
-3

**удалил **
решил помочь, а мне минусов насували. правда говорят благими намерениями выложена дорога в ад.

Ответ дан 03.08.2016 - 16:47

В̯͉͙̹̼̘̞͜и͚̥̮͎̮̗͚͈д̳̘͍̻̺̝͜͜и͚̺̬̣̖̰̱͜м̟͉͍̟̜͎̳̱о̰̠̣̩̪̜̖͖,̦͓͕̺̤̙͖̞ ̤̦͉̮̥͔̗̰у̡̳̞̳̫̭͇̬ж̱̥͈̱̫̳͎ͅе̧̩̬͍̦̻̺ͅ ̧̧̹͈͇̤̣͚н̯̳̬̺̥͔̜̩у̡̢̲̪͕̥̬̜ж̡̝̩̜̼̯̠̮н̡̣͇̤͓̠͈͕ы̘̪͈̯̼̳̭͔ ̗̯̻̭̜̳̠͜ф̧̨͚̱̖̮̘͙л̮͔̣͙͉͚̦͕а̡̡̥̘̫̦̭ͅг͈͎̖̜͉̺̥ͅи̲̮̞̖͖̦͍ͅ ̨̦͍͓̳̳̯͜д̢̨̢̧͇̭͖̖л̲͔͚̰̜̯̦̺я̧͖̝̝̺̤̭̘ ͈̫̺̞͕̝͚ͅб̢̢̳̱̲̤͈̞о̹̥̯̝̱̼͙̪р̨̡̳͉̠͓̠ͅь̳̘̬̲̭͔̼͜б̢̡̩̻̼̹̯̞ы̨̪̪̣̳̥̲̠ ̡̨̘̰͙͉͎̘с̫̗͔͇̼͕̯̺о̧͖̼͔͈̝̙̦ ͖̬̳͖̤͇͙̭с̧̨̟͚̭̦͈̞п̮̝̳̬̫̙͈̠а̧̮̲̟͉̱͚͜м̖͖͉̠̹̜͎͜о̢̮̰̯̦͉̠ͅм̣̙̝̲̬͎̤̹.̨̝̖͙̳̱̞̦ ̢̨̰̳͎̪̤͓

Комментарий оставлен 05.08.2016 - 09:54