Adicionar critérios de filtro em modos de exibição programaticamente
18
Quero adicionar / modificar um filter criteriaprogramaticamente.
Por exemplo, para uma visualização, adicionei um filtro "Endereço de email" cujo valor é necessário para alterar dinamicamente, é necessário definir o ID de email do usuário conectado no momento.
Como conseguir isso? Por favor, veja a imagem em anexo para mais detalhes. Por favor ajude.
Use o módulo Develdpm($view) e dpm($query)depois de colocar como "[email protected]" no campo "value" encontrado na sua foto. Veja a estrutura do objeto / matriz da visualização e consulta da saída devel.
Em seguida, use a função hook_views_query_alter(&$view, &$query)em seu módulo para direcionar a condição do filtro de condição WHERE e defina-a com o valor desejado.
Algo como:
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// '[email protected]' 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;}}
Muito Obrigado! Você pode, por favor, me dizer onde eu primeiro escrevo dpm($view);?
Shafiul 25/03/12
você cria um módulo personalizado e coloca a função acima. O gancho será acionado se as visualizações estiverem ativadas e você verá as $ view e $ query na parte superior da página depois de ativar o módulo personalizado e o módulo Devel. Em seguida, basta alterar o código para ter o nome de máquina do seu ponto de vista, em ... e fazendo a valores de consulta $ trabalho com sua consulta exata ...
Tenken
Essa é uma ótima resposta. No Drupal 7 você realmente faz: $ query-> where [1] ['conditions'] [2] ['value'] = $ user-> email
Eu sei que você provavelmente deve definir isso usando algum método esotérico e complicado, mas se você quiser apenas um acesso rápido e sujo sem mexer com isso, você chegará lá.
Seria preferível alterá-los nos ganchos, e não no tempo de renderização, para que você não comprometa o desempenho e o cache do site. Levei idade para descobrir que o hook_views_pre_build () é acionado tarde demais, você precisa do hook_views_pre_view () .
Encontrei referência ao uso de $ view-> add_item (), mas lutei por exemplos. Abaixo estava minha solução para filtrar um conjunto de termos de taxonomia para incluir apenas determinados vocabs:
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);}}}
Nota de edição : este comentário no grupo me ajudou a descobrir como obter os filtros de visualizações usando $view->display_handler->get_option('filters')e depois substituí-los usando $view->display_handler->override_option('filters', $filters);.
Eu tive um problema semelhante, mas onde tentando passar vários argumentos para um filtro. Eu usei o método "views_get_view", mas passando argumentos para a exibição. Eu espero que isso ajude alguém. Você pode substituir qualquer tipo ou valor de argumento para suas necessidades:
Adicionei filtros contextuais à própria exibição (no conjunto de campos das configurações avançadas da exibição). O primeiro é um "conteúdo: possui ID do termo de taxonomia". O segundo é "content: nid" com a caixa de seleção "permitir vários" marcada e "excluir" (a partir do conjunto de campos 'more' no pop-up de filtro contextual).
args [] = '1'; // ID do termo
args [] = '1 + 2 + 3'; // IDs do nó a serem excluídos / incluídos
$ view = views_get_view ($ view_name);
$ view-> init ();
$ view-> set_display ($ display);
$ view-> set_arguments ($ args);
$ view-> execute ();
$ view-> resultado
Atualização: esqueci de mencionar, dentro dos valores contextuais do filtro, você pode precisar selecionar o código php e retornar os argumentos de exibição passados. Por exemplo:
Esta resposta pode ser um pouco mais detalhada sobre por que isso funciona. Muitas vezes, gosto de vincular e citar as páginas de documentação. Isso ajudaria o solicitante a aprender mais sobre a API Drupal e a encontrar informações para si no futuro.
Mrclcliffe 02/09/19
1
Aqui está um exemplo de como os critérios de filtro podem ser adicionados programaticamente no 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(),'=');}}
A consulta acima adicionará um critério que filtra os nós onde o field_custom_criteriacampo é igual ao idioma atualmente selecionado.
Baseado em @ Duncanmoo 's resposta acima que eu sentia era melhor, eu adicionei os seguintes filtros para meu ponto de vista - pensei que estes seriam exemplos úteis no caso de você não estavam tentando filtro baseado em uma taxonomia referenciados, mas em vez disso, uma entidade referenciado ou um 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);
?Aqui está uma alternativa:
Eu sei que você provavelmente deve definir isso usando algum método esotérico e complicado, mas se você quiser apenas um acesso rápido e sujo sem mexer com isso, você chegará lá.
fonte
Seria preferível alterá-los nos ganchos, e não no tempo de renderização, para que você não comprometa o desempenho e o cache do site. Levei idade para descobrir que o hook_views_pre_build () é acionado tarde demais, você precisa do hook_views_pre_view () .
Encontrei referência ao uso de $ view-> add_item (), mas lutei por exemplos. Abaixo estava minha solução para filtrar um conjunto de termos de taxonomia para incluir apenas determinados vocabs:
Nota de edição : este comentário no grupo me ajudou a descobrir como obter os filtros de visualizações usando
$view->display_handler->get_option('filters')
e depois substituí-los usando$view->display_handler->override_option('filters', $filters);
.fonte
Eu tive um problema semelhante, mas onde tentando passar vários argumentos para um filtro. Eu usei o método "views_get_view", mas passando argumentos para a exibição. Eu espero que isso ajude alguém. Você pode substituir qualquer tipo ou valor de argumento para suas necessidades:
Adicionei filtros contextuais à própria exibição (no conjunto de campos das configurações avançadas da exibição). O primeiro é um "conteúdo: possui ID do termo de taxonomia". O segundo é "content: nid" com a caixa de seleção "permitir vários" marcada e "excluir" (a partir do conjunto de campos 'more' no pop-up de filtro contextual).
Atualização: esqueci de mencionar, dentro dos valores contextuais do filtro, você pode precisar selecionar o código php e retornar os argumentos de exibição passados. Por exemplo:
fonte
No Drupal 8, você pode usar
ViewExecutable::setHandler($display_id, $type, $id, $item)
para definir um filtro programaticamente.fonte
Aqui está um exemplo de como os critérios de filtro podem ser adicionados programaticamente no Drupal 8:
A consulta acima adicionará um critério que filtra os nós onde o
field_custom_criteria
campo é igual ao idioma atualmente selecionado.Mais informações podem ser encontradas nos documentos: hook_views_query_alter
fonte
Baseado em @ Duncanmoo 's resposta acima que eu sentia era melhor, eu adicionei os seguintes filtros para meu ponto de vista - pensei que estes seriam exemplos úteis no caso de você não estavam tentando filtro baseado em uma taxonomia referenciados, mas em vez disso, uma entidade referenciado ou um NID:
fonte