Пишу модуль на Drupal для управления фильтрами вьюса
В процессе создания очередного сайта на Drupal стала задача написать что-то вроде простого двухшагового мастера, который на самом деле будет просто навороченным views'ом.
Дано:
Есть мега-вьюс, который собирает данные из нескольких CCK, попутно для некоторых из полей в теме подключая подчинённые вьюсы.
Требуется:
На первом шаге вьюса вывалить посетителю disclamer, в котором будет показано некоторое количество текста с галочками и два из четырёх фильтра вьюса. Причём эти два фильтра нужно запомнить и пропускать первый шаг с дикламером для посетителей, которые что-либо там выбрали. Во второй части вьюса нужно в идеале скрыть два фильтра с первого шага и показать 2 дополнительных фильтра от views'а. На время наполнения контентом было-бы неплохо предусмотреть тумблер для отключения запоминания выбора.
Решение:
Оформляю это дело как модуль - давно хотел попробовать, но никак не доводилось.
Придумываю название модулю и создаю ему папку в месте, где живут все модуля. Пускай это будет модуль mydisclamer.
Оформляю под него mydisclamer.info:
name = My Disclamer
description = My Disclamer.
package = My Disclamer
version = VERSION
core = 6.x
Следом начинаю работать с mydisclamer.module. Поскольку для вывода фильтра над views'ами используется form api, то хукерить буду именно через него. Использую хук hook_form_FORM_ID_alter.
Кратко как это работает:
Проверяю на каком свете у меня находится форма (первый if). Если значения не определены (значения фильтров views'ов добываются из $form_state['view']->exposed_input['my_field_name']) или равны дефолтным, то пользователь пришёл первый раз и ему нужно показать disclamer (тут можно disclamer text вбить гвоздями в модуль, подгрузить из другой ноды или попыпаться оформить как редактируемые параметры модуля) и убрать совсем пару ненужных фильтров. Иначе (else) выкидываю все значения, кроме выбранных пользователем из 2-х первых фильтров (убирать совсем нельзя, т.к. всё сломается дальше и придётся городить альтернативный метод хранения данных пользователя, потом спрячу совсем ccs'ом) и не убиваю оставшиеся фильтры.
Хранение данных между визитами юзера делаю на базовом функционале views'ов - в свойствах фильтра тупо ставлю галочку помнить. На время наполнения контентом и тестирование модуль очень легко отключается из панели управления модулями.
<?php
function mydisclamer_form_views_exposed_form_alter(&$form, $form_state) {
if(!isset($form_state['view']->exposed_input['term_node_field_name_1'])
or !isset($form_state['view']->exposed_input['field_name_2'])
or $form['term_node_field_name_1']['#default_value']==$form_state['view']->exposed_input['term_node_field_name_1']
or $form['field_name_2']['#default_value']==$form_state['view']->exposed_input['field_name_2']){
unset($form['field_name_3']);
unset($form['#info']['filter-field_name_3']);
unset($form['field_name_4']);
unset($form['#info']['filter-field_name_4']);
$view = views_get_current_view();
$view->set_display('page_1');
$view->display_handler->set_option('header', t('Disclamer text'));
$view->display_handler->set_option('header_empty', 1);
}else{ //disclamer accepted
foreach($form['term_node_field_name_1']['#options'] as $key=>$value){
if($key!=$form_state['view']->exposed_input['term_node_field_name_1']){
unset($form['term_node_field_name_1']['#options'][$key]);
}
}
foreach($form['field_name_2']['#options'] as $key=>$value){
if($key!=$form_state['view']->exposed_input['field_name_2']){
unset($form['field_name_2']['#options'][$key]);
}
}
}
}
PS: Не забываю поставить проверку на название вьюса, что-бы он в пустую не работал на всех вьюсах с фильтрами. Сам вьюс хранится в $form_state['view'], его название в $form_state['view']->name, а текущее отображение (display) в $form_state['view']->current_display.


