Aggiungi CRITERI DI FILTRO in Visualizzazioni a livello di codice


18

Voglio aggiungere / modificare un a livello di filter criteriacodice.

Ad esempio, per una vista, ho aggiunto un filtro "Indirizzo e-mail" il cui valore è necessario per cambiare dinamicamente, è necessario impostare l'ID e-mail dell'utente attualmente connesso.

Come raggiungerlo? Si prega di vedere l'immagine allegata per maggiori dettagli. Per favore aiuto.

inserisci qui la descrizione dell'immagine

Risposte:


24

Usa il modulo Develdpm($view) e, dpm($query)dopo aver inserito "test@email.com", nel campo "valore" che trovi nella tua foto. Vedere la struttura oggetto / matrice della vista e interrogare dall'output di sviluppo.

Quindi utilizzare la funzione hook_views_query_alter(&$view, &$query)nel modulo per scegliere come target la condizione del filtro delle condizioni WHERE e impostarla sul valore desiderato.

Qualcosa di simile a:

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;
  }
}

Grazie molto! Puoi per favore dirmi dove devo prima scrivere dpm($view);?
Shafiul,

si crea un modulo personalizzato e si inserisce la funzione sopra in esso. l'hook si attiverà se le viste sono abilitate e vedrai la $ view e la $ query nella parte superiore della pagina dopo aver abilitato il modulo personalizzato e il modulo Devel. Quindi modifica il mio codice per fare in modo che la macchina della tua vista lo chiami in ... e
faccia

Questa è un'ottima risposta. In Drupal 7 in realtà fai: $ query-> dove [1] ['condizioni'] [2] ['valore'] = $ utente-> email
Artur Kędzior

Personalmente penso che la risposta usando i ganci qui sotto sia molto meglio drupal.stackexchange.com/a/200870/9634
kbrinner

6

Ecco un'alternativa:

$view = views_get_view('view_machine_name');
$view->init_display('default');
$view->display_handler->display->display_options['filters']['your_filter_name']['default_value'] = 'your_value';
$view->is_cacheable = FALSE;  
$view->execute();
print $view->render();

So che probabilmente dovresti impostarlo usando un metodo esoterico e contorto, ma se vuoi solo un accesso rapido e sporco senza scherzare questo ti porterà lì.


5

Sarebbe preferibile modificarli negli hook piuttosto che al momento del rendering in modo da non compromettere le prestazioni del sito e la memorizzazione nella cache. Mi ci sono voluti anni per capire che hook_views_pre_build () spara troppo tardi, hai bisogno di hook_views_pre_view () .

Ho trovato un riferimento all'utilizzo di $ view-> add_item () ma ho faticato per esempi, di seguito è stata la mia soluzione per filtrare un insieme di termini di tassonomia per includere solo determinati vocab:

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 filter
      foreach($vids as $vid) {
        $filters['vid']['value'][ $vid ] = $vid;
      }
      $view->display_handler->override_option('filters', $filters);
    }
  }
}

Modifica nota : questo commento su do group mi ha aiutato a capire come ottenere i filtri delle visualizzazioni $view->display_handler->get_option('filters')e come sostituirli utilizzando $view->display_handler->override_option('filters', $filters);.


2

Ho avuto un problema simile, ma dove provare a passare più argomenti a un filtro. Ho usato il metodo "views_get_view", ma passando argomenti alla vista. Spero che aiuti qualcuno. Puoi sostituire qualsiasi tipo di argomento o valore per le tue esigenze:

Ho aggiunto filtri contestuali alla vista stessa (dal set di campi delle impostazioni della vista avanzata). Il primo è un "contenuto: ha ID termine tassonomia". Il secondo è "content: nid" con la casella di controllo "consenti più" e "escludi" selezionata (dal set di campi "altro" nel pop-up del filtro contestuale).

args [] = '1'; // ID termine
args [] = '1 + 2 + 3'; // ID nodo da escludere / includere

$ view = views_get_view ($ view_name);
$ Visualizza-> init ();
$ Visualizza-> set_display ($ display);
$ Visualizza-> set_arguments ($ args);
$ Visualizza-> execute ();
$ Visualizza-> Risultati

Aggiornamento: ho dimenticato di menzionare, all'interno dei valori del filtro contestuale, potrebbe essere necessario selezionare il codice php e restituire gli argomenti della vista passati. Ad esempio:

restituisce $ view-> args [1];

1

In Drupal 8 è possibile utilizzare ViewExecutable::setHandler($display_id, $type, $id, $item)per impostare un filtro a livello di codice.


4
Questa risposta potrebbe essere un po 'più dettagliata sul perché funziona. Spesso mi piace collegare e citare le pagine della documentazione. Ciò aiuterebbe il richiedente a saperne di più sull'API Drupal e aiuterebbe a trovare informazioni per se stesso in futuro.
mradcliffe,

1

Ecco un esempio di come i criteri di filtro possono essere aggiunti a livello di codice in 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(), '=');
  }
}

La query sopra aggiungerà un criterio che filtra i nodi in cui il field_custom_criteriacampo è uguale alla lingua attualmente selezionata.

Ulteriori informazioni sono disponibili nei documenti: hook_views_query_alter


0

Sulla base di @ Duncanmoo 's risposta di cui sopra , che ho sentito è stato migliore, ho aggiunto i seguenti filtri per mio punto di vista - pensavano che questi sarebbero esempi utili nel caso in cui non stavano cercando di filtro basato su un tassonomia di riferimento, ma invece su un soggetto di riferimento o un 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 filter
    if (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
        )
      );
    }
  }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.