• статья
  • pantey

Учим раскрытый фильтр views принимать множественные значения

27.08.2015

Думаю многие из вас, на своих проектах, не раз использовали «всемогучий» views. Относительная простота его использования и достаточно легкая темизация сделали его одним из самых скачиваемых модулей на drupal.org, а в 8ю версию Drupal даже включили в ядро. Но иногда и его возможностей нам бывает мало.

Одним из таких не хватающих возможностей, является его невозможность (я имею ввиду из админки) обрабатывать множественные значения.

Давайте все разберем на конкретном примере. Создадим раскрытый фильтр views, который будет принимать NID ноды. Вы можете создать свой фильтр или использовать экспорт представления, который используется в примере:

Экспорт views:
  1. $view = new view();
  2. $view->name = 'filter_nid';
  3. $view->description = '';
  4. $view->tag = 'default';
  5. $view->base_table = 'node';
  6. $view->human_name = 'Filter nid';
  7. $view->core = 7;
  8. $view->api_version = '3.0';
  9. $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
  10.  
  11. /* Display: Master */
  12. $handler = $view->new_display('default', 'Master', 'default');
  13. $handler->display->display_options['title'] = 'Filter nid';
  14. $handler->display->display_options['use_more_always'] = FALSE;
  15. $handler->display->display_options['access']['type'] = 'perm';
  16. $handler->display->display_options['cache']['type'] = 'none';
  17. $handler->display->display_options['query']['type'] = 'views_query';
  18. $handler->display->display_options['exposed_form']['type'] = 'basic';
  19. $handler->display->display_options['pager']['type'] = 'full';
  20. $handler->display->display_options['pager']['options']['items_per_page'] = '10';
  21. $handler->display->display_options['style_plugin'] = 'default';
  22. $handler->display->display_options['row_plugin'] = 'node';
  23. /* Field: Content: Title */
  24. $handler->display->display_options['fields']['title']['id'] = 'title';
  25. $handler->display->display_options['fields']['title']['table'] = 'node';
  26. $handler->display->display_options['fields']['title']['field'] = 'title';
  27. $handler->display->display_options['fields']['title']['label'] = '';
  28. $handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE;
  29. $handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE;
  30. /* Sort criterion: Content: Nid */
  31. $handler->display->display_options['sorts']['nid']['id'] = 'nid';
  32. $handler->display->display_options['sorts']['nid']['table'] = 'node';
  33. $handler->display->display_options['sorts']['nid']['field'] = 'nid';
  34. /* Filter criterion: Content: Published */
  35. $handler->display->display_options['filters']['status']['id'] = 'status';
  36. $handler->display->display_options['filters']['status']['table'] = 'node';
  37. $handler->display->display_options['filters']['status']['field'] = 'status';
  38. $handler->display->display_options['filters']['status']['value'] = 1;
  39. $handler->display->display_options['filters']['status']['group'] = 1;
  40. $handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
  41. /* Filter criterion: Content: Nid */
  42. $handler->display->display_options['filters']['nid']['id'] = 'nid';
  43. $handler->display->display_options['filters']['nid']['table'] = 'node';
  44. $handler->display->display_options['filters']['nid']['field'] = 'nid';
  45. $handler->display->display_options['filters']['nid']['exposed'] = TRUE;
  46. $handler->display->display_options['filters']['nid']['expose']['operator_id'] = 'nid_op';
  47. $handler->display->display_options['filters']['nid']['expose']['label'] = 'Nid';
  48. $handler->display->display_options['filters']['nid']['expose']['operator'] = 'nid_op';
  49. $handler->display->display_options['filters']['nid']['expose']['identifier'] = 'nid';
  50. $handler->display->display_options['filters']['nid']['expose']['remember_roles'] = array(
  51. 2 => '2',
  52. 1 => 0,
  53. 3 => 0,
  54. );
  55.  
  56. /* Display: Page */
  57. $handler = $view->new_display('page', 'Page', 'page');
  58. $handler->display->display_options['path'] = 'multiple-filter';

Как вы можете видеть, данное представление создает страницу с раскрытым фильтром

Созданное представление

Сам фильтр, в качестве значения принимает NID ноды и формирует его тизер.

Результаты работы фильтра по умолчанию

Как мы видим, все у нас прекрасно работает. Но давайте введем несколько значений в наш фильтр и посмотрим результат:

Фильтр не обработал множественные значения

Видим, что фильтр не обработал множественные значения, а для обработки забрал лишь первый NID ноды.

Давайте исправим это дело. По сути, все, что нам нужно сделать – это изменить запрос views, для этого есть hook_views_query_alter.

Создадим модуль, у меня он будет называться multiple_value

Файл multiple_value.info
  1. name = Multiple value
  2. description = Multiple value for exposed filter in views
  3. package = Other
  4. core = 7.x
  5. version = 7.x-1.0
Файл multiple_value.module
  1. <?php
  2.  
  3. /**
  4.  * Implements hook_views_query_alter
  5.  */
  6. function multiple_value_views_query_alter(&$view, &$query) {
  7.  
  8. if ($view->name == 'filter_nid' && isset($query->where[1]['conditions'][1])) {
  9.  
  10. $query->group_operator = 'OR'; // Изменяем групповой оператор, для получения множественных значений
  11. $nids = explode(',', $query->where[1]['conditions'][1]['value']); // Получаем список NID из поля
  12. unset($query->where[1]); // Избавляемся от дубля NID
  13.  
  14. foreach($nids as $nid){ // Формируем запросы
  15. $query->where[] = array(
  16. 'conditions' => array(
  17. 0 => array(
  18. 'field' => 'node.status',
  19. 'value' => 1,
  20. 'operator' => '=',
  21. ),
  22. 1 => array(
  23. 'field' => 'node.nid',
  24. 'value' => $nid,
  25. 'operator' => '=',
  26. ),
  27. ),
  28. 'args'=>'',
  29. 'type' => 'AND',
  30. );
  31. }
  32. }
  33.  
  34. }

Думаю из кода вам должно быть все ясно. Мы изменили групповой оператор, для возможности получить множественные значения и далее через цикл сформировали запросы для каждого NID, которое было введено в поле.

Активируем модуль и смотрим результат.

Результат работы фильтра после включения модуля

Как мы видим, теперь наш фильтр может обрабатывать множественные значения. Скачать сам модуль в примере можно здесь. На этом можно считать, что с задачей справились.

-->
Узнавай о новых статьях сайта - первым. Просто подпишись на рассылку.