web-dev-qa-db-fra.com

Ajouter des CRITÈRES DE FILTRE dans les vues par programme

Je veux ajouter/modifier un filter criteria par programme.

Par exemple, pour une vue, j'ai ajouté un filtre "Adresse e-mail" dont la valeur est nécessaire pour changer dynamiquement, il est nécessaire de définir l'ID de messagerie de l'utilisateur actuellement connecté.

Comment y parvenir? Veuillez voir l'image ci-jointe pour plus de détails. Veuillez aider.

enter image description here

18
Shafiul

Utilisez le module Devel et dpm($view) et dpm($query) après avoir mis comme "[email protected]" dans le champ "valeur" trouvé sur votre photo. Voir la structure objet/tableau de la vue et de la requête à partir de la sortie devel.

Utilisez ensuite la fonction hook_views_query_alter(&$view, &$query) dans votre module pour cibler la condition du filtre de condition WHERE et la définir sur la valeur souhaitée.

Quelque chose comme:

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

Voici une alternative:

$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();

Je sais que vous devriez probablement définir cela en utilisant une méthode ésotérique et alambiquée, mais si vous voulez juste un accès rapide et sale sans déconner, cela vous y mènera.

7
rix

Il serait préférable de les modifier dans les hooks plutôt qu'au moment du rendu afin de ne pas compromettre les performances et la mise en cache du site. Cela m'a pris de l'âge pour comprendre que hook_views_pre_build () se déclenche trop tard, vous avez besoin hook_views_pre_view () .

J'ai trouvé une référence à l'utilisation de $ view-> add_item () mais j'ai eu du mal à trouver des exemples, voici ma solution pour filtrer un ensemble de termes de taxonomie pour n'inclure que certains vocabulaires:

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

Modifier la note : Ce commentaire sur le groupe do m'a aidé à comprendre comment obtenir les filtres de vues en utilisant $view->display_handler->get_option('filters') et ensuite les remplacer à l'aide de $view->display_handler->override_option('filters', $filters);.

6
Duncanmoo

J'ai eu un problème similaire, mais où j'essayais de passer plusieurs arguments à un filtre. J'ai utilisé la méthode "views_get_view", mais en passant des arguments à la vue. J'espère que ça aide quelqu'un. Vous pouvez substituer n'importe quel type ou valeur d'argument à vos besoins:

J'ai ajouté des filtres contextuels à la vue elle-même (à partir du jeu de champs des paramètres de vue avancés). Le premier est un "contenu: a un ID de terme de taxonomie". Le second est "content: nid" avec la case "autoriser plusieurs" cochée et la case "exclure" cochée (du jeu de champs "plus" dans la fenêtre contextuelle du filtre contextuel).

 args [] = '1'; // ID de terme 
 Args [] = '1 + 2 + 3'; // Node ID à exclure/inclure 
 
 $ View = views_get_view ($ view_name); 
 $ View-> init (); 
 $ view-> set_display ($ display); 
 $ view-> set_arguments ($ args); 
 $ view-> execute (); 
 $ view- > résultat 

Mise à jour: j'ai oublié de mentionner, dans les valeurs du filtre contextuel, vous devrez peut-être sélectionner le code php et renvoyer les arguments de vue transmis. Par exemple:

 return $ view-> args [1]; 
3
Seb

Dans Drupal 8, vous pouvez utiliser ViewExecutable::setHandler($display_id, $type, $id, $item) pour définir un filtre par programme.

2
vlledo

Voici un exemple sur la façon dont les critères de filtre peuvent être ajoutés par programme dans 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 requête ci-dessus ajoutera un critère qui filtre les nœuds où le field_custom_criteria champ est égal à la langue actuellement sélectionnée.

Plus d'informations peuvent être trouvées dans les documents: hook_views_query_alter

1
estrar

Sur la base de @ Duncanmoo 's réponse ci-dessus que je jugeais le mieux, j'ai ajouté les filtres suivants à ma vue - pensant que ce seraient des exemples utiles au cas où vous n'essaieriez pas pour filtrer en fonction d'une taxonomie référencée mais plutôt sur une entité référencée ou 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
        )
      );
    }
  }
}
1
kbrinner