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

18

Je veux ajouter / modifier un filter criteriaprogramme.

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.

entrez la description de l'image ici

Shafiul
la source

Réponses:

24

Utilisez le module Devel et dpm($view)et dpm($query)après avoir mis comme "[email protected]" dans le champ "valeur" trouvé dans 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)de votre module pour cibler la condition du filtre de condition WHERE et définissez-la 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;
  }
}
tenken
la source
Merci beaucoup! Pouvez-vous s'il vous plaît me dire où dois-je d'abord écrire dpm($view);?
Shafiul
vous créez un module personnalisé et placez la fonction ci-dessus dedans. Le crochet se déclenchera si les vues sont activées et vous verrez la requête $ view et $ en haut de la page une fois que vous aurez activé le module personnalisé et le module Devel. Ensuite, changez simplement mon code pour que la machine de votre vue le nomme ... et que les valeurs de la requête $ fonctionnent avec votre requête exacte ...
tenken
Voilà une excellente réponse. Dans Drupal 7, vous effectuez en fait: $ query-> where [1] ['conditions'] [2] ['value'] = $ user-> email
Artur Kędzior
Personnellement, je pense que la réponse en utilisant les crochets ci-dessous est bien meilleure drupal.stackexchange.com/a/200870/9634
kbrinner
6

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 compliquée, mais si vous voulez juste un accès rapide et sale sans déconner, cela vous y mènera.

rix
la source
5

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 de 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 de tâches m'a aidé à comprendre comment obtenir les filtres de vues à l'aide $view->display_handler->get_option('filters'), puis les remplacer à l'aide $view->display_handler->override_option('filters', $filters);.

Duncanmoo
la source
2

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 deuxième 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'; // Identifiant du terme
args [] = '1 + 2 + 3'; // ID de noeud à 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];
Seb
la source
1

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

vlledo
la source
4
Cette réponse pourrait être un peu plus détaillée sur la raison pour laquelle cela fonctionne. Souvent, j'aime lier et citer les pages de documentation. Cela aiderait le demandeur à en savoir plus sur l'API Drupal et à trouver des informations pour lui-même à l'avenir.
mradcliffe
1

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_criteriachamp est égal à la langue actuellement sélectionnée.

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

estrar
la source
0

Basé sur @ Duncanmoo de réponse ci - dessus que je me sentais était le meilleur, j'ai ajouté les filtres suivants à mon avis - pensaient que ces exemples seraient utiles dans le cas où vous n'essayaient pas de filtre basé sur 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
        )
      );
    }
  }
}
kbrinner
la source