Requête personnalisée dans les vues?

24

À un moment donné, j'ai trouvé la nécessité de modifier une requête SQL générée par Views, à la fin j'ai views_pre_executeremplacé et modifié la requête pour cette vue spécifique.

Cela ressemble à un vilain piratage pour moi et je me demande s'il y a une façon plus élégante et maintenable de le faire. L'idéal serait un moyen qui me permettrait de modifier directement la requête à partir de l'interface utilisateur des vues.

Scientifique fou
la source
1
Cela dépend de la façon dont vous souhaitez modifier cette requête. Qu'essayiez-vous exactement d'accomplir?
Jason Smith
@Jason J'ai posté la question à SO à ce moment-là: stackoverflow.com/questions/3147916/… Mais ce problème est résolu maintenant, je cherche juste un moyen élégant de modifier n'importe quelle requête Views si je le dois.
Mad Scientist
Je ne suis pas convaincu que vous ne pouvez pas accomplir ce que vous essayez de faire dans l'autre thread en utilisant simplement des vues. Cela dit, il y a bien plus d'une façon d'écorcher ce chat.
Jason Smith
Si l'une des réponses ci-dessous correspond à ce que vous cherchiez, vous devez en accepter une (cliquez sur la coche sous le décompte des votes)
Chaulky
hook_views_pre_execute n'est peut-être pas le plus élégant, mais il a sa place pour les remplacements de requêtes complexes (voir les requêtes Custom Views 3 dans Drupal 7 )
mrP

Réponses:

25

Vous pouvez également utiliser hook_views_query_alter()pour modifier la requête avant son exécution. Je pense que cela est similaire à hook_views_pre_execute, mais facilite la modification de la requête. Vous avez essentiellement accès à chaque partie de la requête via un tableau à clés. Je n'ai pas trouvé beaucoup de documentation officielle, mais il y en a un assez bon exemple sur https://www.appnovation.com/blog/using-hook-views-query-alter . C'est également l'approche que j'ai dû utiliser pour corriger un bogue de date dans le module Calendrier.

Chaulky
la source
Cela fonctionnera-t-il également avec Views-3?
markdorison
@markdorison Je le crois, mais je n'ai pas confirmé cela
Chaulky
3
J'ai confirmé que cela fonctionne dans Views-3.
markdorison
1
@Fabian, vous devriez accepter cette réponse si elle vous a été utile, ou commenter pourquoi elle ne l'a pas été afin que nous puissions l'améliorer
Chaulky
Un autre exemple de référence pour les requêtes Custom Views 3 dans Drupal 7 à l' aide hook_views_pre_execute()d'un module personnalisé simple.
mRP
4

En général, cela dépend de votre cas d'utilisation.

Si vous voulez avoir un champ / filtre / argument qui devrait se comporter d'une certaine manière, il est recommandé d'écrire un gestionnaire pour cela. Voir l'aide avancée des vues pour plus d'informations.

Si vous souhaitez modifier certaines parties de la requête, vous pouvez également utiliser hook_views_query_alter () . Le mauvais côté, hook_views_query_alter()c'est que vous ne pouvez pas vraiment réutiliser le code là-bas.

Il s'agit de l'exemple de code illustré dans la documentation. Il donne un exemple de ce que le crochet peut faire.

function mymodule_views_query_alter(&$view, &$query) {
  // (Example assuming a view with an exposed filter on node title.)
  // If the input for the title filter is a positive integer, filter against
  // node ID instead of node title.
  if ($view->name == 'my_view' && is_numeric($view->exposed_raw_input['title']) && $view->exposed_raw_input['title'] > 0) {
    // Traverse through the 'where' part of the query.
    foreach ($query->where as &$condition_group) {
      foreach ($condition_group['conditions'] as &$condition) {
        // If this is the part of the query filtering on title, chang the
        // condition to filter on node ID.
        if ($condition['field'] == 'node.title') {
          $condition = array(
            'field' => 'node.nid', 
            'value' => $view->exposed_raw_input['title'], 
            'operator' => '=',
          );
        }
      }
    }
  }
}
Daniel Wehner
la source
3

J'ai utilisé le hook_views_query_alter()pour modifier une requête mysql de vues. L'exemple suivant est testé sous Drupal 7 avec 7.x-3.0, il ajoute une ORDER BYclause personnalisée à la requête:

 function MYTHEME_views_query_alter(&$view, &$query) {
   // check so it's the correct view
   if($view->name == 'product_view') {
     // set a custom 'ORDER BY' clause in the query
     $query->orderby[0] = array(
       'field' => 'SUBSTR(taxonomy_term_data_name,3,4)',
       'direction' => 'ASC'
     );
     $query->orderby[1] = array(
       'field' => 'SUBSTR(taxonomy_term_data_name,1,2)',
       'direction' => 'ASC'
     );
   }
 }
Cyclonecode
la source
1

Je ne sais pas si vous pouvez directement changer le sql, mais vous pouvez écrire votre propre gestionnaire de champs et créer votre propre requête.

EricSchaefer
la source