Добавить критерии фильтра в представления программно
18
Я хочу добавить / изменить filter criteriaпрограммно.
Например, для представления я добавил фильтр «Адрес электронной почты», значение которого необходимо для динамического изменения, его необходимо установить для текущего идентификатора электронной почты пользователя, вошедшего в систему.
Как этого добиться? Пожалуйста, смотрите прикрепленное изображение для более подробной информации. Пожалуйста помоги.
Используйте Devel модуль и dpm($view)и dpm($query)после того, как вы поставите как «test@email.com» в поле «значение» найдено в вашем рис. Посмотрите структуру объекта / массива представления и запроса от вывода devel.
Затем используйте функцию hook_views_query_alter(&$view, &$query)в вашем модуле, чтобы настроить условие фильтра условия WHERE и установить для него нужное значение.
Что-то вроде:
function MYMODULE_views_query_alter(&$view,&$query){global $user;
dpm($view, __FUNCTION__);
dpm($query, __FUNCTION__);if($view->name ==='your_view_machine_name'){// This will only work as-is if you always have something in the filter by// default, I guess. This hook runs always so you could just put// 'test@test.com' as the email to filter by in views and this// will always override it. I'm sure there is a cleaner way to put// the filter dynamically at runtime. But i think thats more complex// php that customizes a view.//// The index 2 below is the index of the condition for the email filter.// Your $query structure may be different in your dpm() of the View $query.
$query->where[1]['conditions'][2]['field']['value']= $user->email;}}
Большое спасибо! Подскажите пожалуйста, где мне сначала написать dpm($view);?
Шафиул
Вы создаете пользовательский модуль и помещаете вышеупомянутую функцию в него. Хук сработает, если представления включены, и вы увидите $ view и $ query вверху страницы, как только вы включите пользовательский модуль и модуль Devel. Затем просто измените мой код, чтобы машина вашего представления
назвала
Это отличный ответ. В Drupal 7 вы фактически делаете: $ query-> где [1] ['условия'] [2] ['значение'] = $ пользователь-> электронная почта
Артур Кендзиор
Лично я думаю, что ответ с использованием описанных
Я знаю, что вы, вероятно, должны установить это, используя какой-нибудь эзотерический, запутанный метод, но если вы просто хотите быстрый и грязный доступ без возни с этим, вы попадете туда.
Было бы предпочтительнее изменять их в хуках, а не во время рендеринга, чтобы не снижать производительность и кеширование сайта. Мне понадобилось время, чтобы понять, что hook_views_pre_build () срабатывает слишком поздно, вам нужна hook_views_pre_view () .
Я нашел ссылку на использование $ view-> add_item (), но изо всех сил пытался найти примеры, ниже было мое решение для фильтрации набора терминов таксономии, чтобы включить только определенные слова:
function MODULENAME_views_pre_view(&$view,&$display_id,&$args){if($view->name =='VIEWNAME'&& $display_id =='DISPLAYID'){// Add all the terms of a vocabulary to the terms listing widget select field
$vids = array();
$vocab = taxonomy_vocabulary_machine_name_load('vocab_name');
$vids[ $vocab->vid ]= $vocab->vid;// Get the existing filters
$filters = $view->display_handler->get_option('filters');if(empty($filters['vid'])){// There is no vid filter so we have to add it
$view->add_item(
$view->current_display,'filter','taxonomy_term_data','vid',
array('operator'=>'in','value'=> $vids,'group'=>1));}else{// Add to pre-existing filterforeach($vids as $vid){
$filters['vid']['value'][ $vid ]= $vid;}
$view->display_handler->override_option('filters', $filters);}}}
Редактировать примечание : Этот комментарий к группе do помог мне понять, как получить фильтры представлений, используя $view->display_handler->get_option('filters')и затем переопределить их, используя $view->display_handler->override_option('filters', $filters);.
У меня была похожая проблема, но когда я пытался передать несколько аргументов фильтру. Я использовал метод "views_get_view", но передавал аргументы представлению. Надеюсь, это кому-нибудь поможет. Вы можете заменить любой тип аргумента или значение для ваших нужд:
Я добавил контекстные фильтры к самому представлению (из набора полей параметров предварительного просмотра). Первый - это «контент: имеет идентификатор термина таксономии». Вторым является «content: nid» с установленным флажком «разрешить несколько» и установленным флажком «исключить» (из набора «еще» во всплывающем окне контекстного фильтра).
Обновление: я забыл упомянуть, что в значениях контекстного фильтра может потребоваться выбрать код php и вернуть переданные аргументы представления. Например:
Этот ответ может быть более подробным о том, почему это работает. Часто мне нравится ссылаться и цитировать страницы документации. Это помогло бы узнать больше об API Drupal и найти информацию для себя в будущем.
Мрадклифф,
1
Вот пример того, как критерии фильтра могут быть добавлены программно в Drupal 8:
/**
* @param ViewExecutable $view
* @param QueryPluginBase $query
*
* Sets a custom custom filter criteria (takes current language into account)
*/function MODULE_views_query_alter(ViewExecutable $view,QueryPluginBase $query){if($view->storage->id()==='my_view_id'){
$query->addWhere(0,'node__field_custom_criteria.field_custom_criteria_value', \Drupal::languageManager()->getCurrentLanguage()->getId(),'=');}}
Приведенный выше запрос добавит критерий, который фильтрует узлы, где field_custom_criteriaполе соответствует выбранному в данный момент языку.
На основе @ Duncanmoo «s ответа выше , что я чувствовал , что лучше всего , я добавил следующие фильтры на мой взгляд , - подумал это было бы полезно примеры в случае , если вы не пытаетесь фильтр на основе ссылочного систематики , но вместо этого на который ссылаются лица или NID:
function[MYMODULE]_views_pre_view(&$view,&$display_id,&$args){if(($view->name =='[your view name]')&&($display_id =='[your display id]')){// Get referenced service - example for entity reference.
$node = menu_get_object();
$node_wrapper = entity_metadata_wrapper('node', $node->nid);
$referenced_service = $node_wrapper->field_service_ref->value();// Add service id as a filter to view.
$filters = $view->display_handler->get_option('filters');if(empty($filters['field_service_ref_target_id'])){// Only display operations nodes that reference the same service.
$view->add_item(
$display_id,'filter','field_data_field_service_ref','field_service_ref_target_id',
array('operator'=>'=','value'=>['value'=> $referenced_service->id],'group'=>1));}// Add nid as a filter to view - example for NID filterif(empty($filters['nid'])){// Don't include current operation in list of related operations.
$view->add_item(
$display_id,'filter','node','nid',
array('operator'=>'!=','value'=>['value'=> $node->nid],'group'=>1));}}}
dpm($view);
?Вот альтернатива:
Я знаю, что вы, вероятно, должны установить это, используя какой-нибудь эзотерический, запутанный метод, но если вы просто хотите быстрый и грязный доступ без возни с этим, вы попадете туда.
источник
Было бы предпочтительнее изменять их в хуках, а не во время рендеринга, чтобы не снижать производительность и кеширование сайта. Мне понадобилось время, чтобы понять, что hook_views_pre_build () срабатывает слишком поздно, вам нужна hook_views_pre_view () .
Я нашел ссылку на использование $ view-> add_item (), но изо всех сил пытался найти примеры, ниже было мое решение для фильтрации набора терминов таксономии, чтобы включить только определенные слова:
Редактировать примечание : Этот комментарий к группе do помог мне понять, как получить фильтры представлений, используя
$view->display_handler->get_option('filters')
и затем переопределить их, используя$view->display_handler->override_option('filters', $filters);
.источник
У меня была похожая проблема, но когда я пытался передать несколько аргументов фильтру. Я использовал метод "views_get_view", но передавал аргументы представлению. Надеюсь, это кому-нибудь поможет. Вы можете заменить любой тип аргумента или значение для ваших нужд:
Я добавил контекстные фильтры к самому представлению (из набора полей параметров предварительного просмотра). Первый - это «контент: имеет идентификатор термина таксономии». Вторым является «content: nid» с установленным флажком «разрешить несколько» и установленным флажком «исключить» (из набора «еще» во всплывающем окне контекстного фильтра).
Обновление: я забыл упомянуть, что в значениях контекстного фильтра может потребоваться выбрать код php и вернуть переданные аргументы представления. Например:
источник
В Drupal 8 вы можете использовать,
ViewExecutable::setHandler($display_id, $type, $id, $item)
чтобы установить фильтр программно.источник
Вот пример того, как критерии фильтра могут быть добавлены программно в Drupal 8:
Приведенный выше запрос добавит критерий, который фильтрует узлы, где
field_custom_criteria
поле соответствует выбранному в данный момент языку.Более подробную информацию можно найти в документации: hook_views_query_alter
источник
На основе @ Duncanmoo «s ответа выше , что я чувствовал , что лучше всего , я добавил следующие фильтры на мой взгляд , - подумал это было бы полезно примеры в случае , если вы не пытаетесь фильтр на основе ссылочного систематики , но вместо этого на который ссылаются лица или NID:
источник