web-dev-qa-db-fra.com

Requête personnalisée dans les vues?

À 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 remplacé views_pre_execute et a 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.

23
Mad Scientist

Vous pouvez également utiliser hook_views_query_alter() pour modifier la requête avant son exécution. Je pense que cela ressemble à 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.

25
Chaulky

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 () . La mauvaise chose à propos de hook_views_query_alter() 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' => '=',
          );
        }
      }
    }
  }
}
4
Daniel Wehner

J'ai utilisé la hook_views_query_alter() pour modifier une requête vues mysql. L'exemple suivant est testé sous Drupal 7 avec 7.x-3.0, Il ajoute une clause ORDER BY 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'
     );
   }
 }
3
Cyclonecode

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.

1
EricSchaefer