hook_form_views_exposed_form_alter вызывается дважды

Главные вкладки

Аватар пользователя oploshka oploshka 21 октября 2014 в 13:03

Необходимые модули: Views и BEF (Better Exposed Filters), так же стоит интернет магазин Ubercard.
Выводим товары, и в виде блоков фильтры BEF раскрытые для пользователей (в принципе все просто).
Создаем свой модуль custom и в нем вызываем хук custom_form_views_exposed_form_alter, хук работает, все хорошо кроме одного но... он вызывается дважды... почему не совсем понятно. Есть банальное решение этого вопроса, но оно не совсем интересно

<?php function custom_form_views_exposed_form_alter (&$form, &$form_state) {
  if(!isset(
$form["my_custom_module"])){
    
$form["my_custom_module"]=true;
    
// тут код который в принципе уже выполнится один раз
  
}
}
?>

Комментарии

Аватар пользователя oploshka oploshka 22 октября 2014 в 13:42

В принципе он может вызываться очень много раз... если страница views сделана на ajax. (количество вызовов = количеству ajax запросов + 1). Если страница не использует views ajax то скорее всего будет вызываться 2 раза.
из найденного...

<?php function custom_preprocess_views_exposed_form(&$vars$hook) {
  
drupal_set_message("Form ID : " $vars['zebra']); // odd - что было, even - что сейчас
  
drupal_set_message("Form ID : " $vars['id']);    // 1   - что было, 2    - что сейчас
}?>

из сделанного решения.

<?php function custom_form_views_exposed_form_alter (&$form, &$form_state$form_id) {
  static 
$my_static 0;
  
$my_static++;
  if(
$my_static==2){ /* тут основной код */ }
}
?>

Хотелось бы узнать как сделать так, чтобы вызывался custom_form_views_exposed_even_form_alter к примеру или же передать параметр в custom_form_views_exposed_form_alter в $form.

Аватар пользователя oploshka oploshka 22 октября 2014 в 17:32

У меня тоже пока что нету времени решать эту мелкую загвоздку... но хотелось бы все же узнать решение этой проблемы. Как все это вызывается можно посмотреть вызвав функции описанные выше. Единственное Views использует режим ajax (по моему это имеет большое значение в данной ситуации).

<?php function custom_preprocess_views_exposed_form(&$vars$hook) {
  
drupal_set_message("Form ID : " $vars['zebra']); // или
  
drupal_set_message("Form ID : " $vars['id']);    // вроде отличаются только эти значения
}?>

или

 <?php function custom_form_views_exposed_form_alter (&$form, &$form_state$form_id) {
  static 
$my_static 0;
  
$my_static++;
  
drupal_set_message("Form ID : " $my_static);
}
?>
Аватар пользователя oploshka oploshka 23 октября 2014 в 10:29

ровным счетом ничего полезного Smile немного модифицировал вывод
<?php  drupal_set_message("GET : " print_r($_GET,true) . " my_static : $my_static");?>
просто загрузка страницы:
GET : Array ( [q] => product ) my_static : 1
GET : Array ( [q] => product ) my_static : 2
поиграем с фильтрами (выберем три позиции у одно фильтра и затем обновим страницу, напомню views с включеным ajax):
GET : Array ( [field_category_bus_tid] => Array ( [0] => 1 ) [q] => product ) my_static : 1
GET : Array ( [field_category_bus_tid] => Array ( [0] => 1 [1] => 184 ) [q] => product ) my_static : 1
GET : Array ( [field_category_bus_tid] => Array ( [0] => 1 [1] => 184 [2] => 233 ) [q] => product ) my_static : 1
GET : Array ( [q] => product ) my_static : 1
GET : Array ( [q] => product ) my_static : 2

Аватар пользователя oploshka oploshka 23 октября 2014 в 11:20

реакция на первое изменение филтра
Array ( [0] => view [1] => display [2] => method [3] => no_redirect [4] => always_process [5] => exposed_form_plugin [6] => rebuild [7] => rebuild_info [8] => redirect [9] => build_info [10] => temporary [11] => submitted [12] => executed [13] => programmed [14] => programmed_bypass_access_check [15] => cache [16] => groups [17] => buttons [18] => input [19] => must_validate [20] => exposed [21] => pager_plugin ) my_static : 1
реакция на второе изменение филтра
Array ( [0] => view [1] => display [2] => method [3] => no_redirect [4] => always_process [5] => exposed_form_plugin [6] => rebuild [7] => rebuild_info [8] => redirect [9] => build_info [10] => temporary [11] => submitted [12] => executed [13] => programmed [14] => programmed_bypass_access_check [15] => cache [16] => groups [17] => buttons [18] => input [19] => must_validate [20] => exposed [21] => pager_plugin ) my_static : 1
реакция на третье изменение филтра
Array ( [0] => view [1] => display [2] => method [3] => no_redirect [4] => always_process [5] => exposed_form_plugin [6] => rebuild [7] => rebuild_info [8] => redirect [9] => build_info [10] => temporary [11] => submitted [12] => executed [13] => programmed [14] => programmed_bypass_access_check [15] => cache [16] => groups [17] => buttons [18] => input [19] => must_validate [20] => exposed [21] => pager_plugin ) my_static : 1
тут нажатие на кнопку перезагрузить страницу или если первая загрузка то верхних записей бы небыло
Array ( [0] => view [1] => display [2] => method [3] => no_redirect [4] => always_process [5] => exposed_form_plugin [6] => rebuild [7] => rebuild_info [8] => redirect [9] => build_info [10] => temporary [11] => submitted [12] => executed [13] => programmed [14] => programmed_bypass_access_check [15] => cache [16] => groups [17] => buttons [18] => input [19] => must_validate [20] => exposed [21] => pager_plugin ) my_static : 1
тут соответственно то что нужно
Array ( [0] => view [1] => display [2] => method [3] => rerender [4] => no_redirect [5] => always_process [6] => exposed_form_plugin [7] => rebuild [8] => rebuild_info [9] => redirect [10] => build_info [11] => temporary [12] => submitted [13] => executed [14] => programmed [15] => programmed_bypass_access_check [16] => cache [17] => groups [18] => buttons [19] => input [20] => must_validate [21] => exposed ) my_static : 2

тут просмотрел в принципе все что можно... по этому все глухо...

Аватар пользователя oploshka oploshka 23 октября 2014 в 11:15

могу даже поделится что там есть
view --- куча всего
display --- тут тоже куча
method = get
no_redirect = 1
always_process = 1
exposed_form_plugin
rebuild = пустое
rebuild_info = Array()
redirect = пустое
build_info = [args] => Array() [files] => Array() [form_id] => views_exposed_form
temporary = Array()
submitted = или пустое или 1 не записывал точное значение
executed --- видать тоже много чего то было...
programmed пустое
programmed_bypass_access_check = 1
cache пустое
groups = Array()
buttons = или пустое или 1 не записывал точное значение
input - отличается в одном пустой массив в другом с фильтрами
must_validate = 1
exposed = 1
pager_plugin - длинное.

Аватар пользователя Orion76 Orion76 24 октября 2014 в 14:51

Я намекал на то, что раз функция-конструктор формы вызывается 2 раза, и соответственно form_alter - тоже 2 раза, то надо по передаваемым в form_alter параметрам (скорее всего элементы $form_state) определять, когда ваш код должен отрабатывыать.

Сравните элементы $form_state при "my_static : 1" и "my_static : 2",
и постарайтесь определить, как можно идентифицировать нужный вызов form_alter и выполнить ваш код..

возможно по параметру submitted .. но это предположение..

Аватар пользователя oploshka oploshka 24 октября 2014 в 17:49

"orion76" wrote:
Сравните элементы $form_state
Легко сказать, по факту они идентичны и различий пока найти не удалось и обьем их очень большой. Если просто вывести переменную $form_state, то браузер просто вешается. Тут есть вариант написать функцию которая выведет отличия между двумя этими массивами...
"orion76" wrote:
возможно по параметру submitted
увы, но он одинаковый, это было описано выше. Если что и стоит смотреть так это $form_state['view'], $form_state['display'], $form_state['executed'], $form_state['pager_plugin'] хотя целесообразноть $form_state['pager_plugin'] под большим вопросом.