web-dev-qa-db-fra.com

Comment créer une union de deux vues?

J'essaie d'obtenir une union des nœuds et des commentaires d'un utilisateur triés par "date de publication". Ce post liens vers des projets sandbox pour D6 mais il n'y a rien pour 7.

Ce post a un exemple d'utilisation de hook_views_pre_execute () et d'un SQL UNION dans D6. Cela ne fonctionne pas pour D7 avec vues 3.

Je suis tombé sur merlinofchaos ' commentaire

Parce que nous utilisons maintenant le nouveau générateur de requêtes de Drupal, la requête est un objet SelectQuery que vous devrez modifier ou remplacer. Recherchez Drupal 7 nouvelle couche de base de données pour plus d'informations.

Quelqu'un at-il un exemple de la façon de procéder ou de toute autre solution pour combiner deux vues?

36
uwe

Voici un exemple fonctionnel et testé:

/**
 * Implements hook_views_pre_execute().
 */
function mymodule_views_pre_execute(view &$view) {
  if ($view->name == 'my_view') {
    $query1 = &$view->build_info['query'];

    // Basic setup of the second query.
    $query2 = db_select('another_table', 'at')
      ->condition('some_field', 0, '>')
      ->condition('some_other_field', 12345);

    // The number of fields (and their aliases) must match query1.
    // Get the details with:
    // dpm($query1->getFields());
    $query2->addField('at', 'some_field', 'alias1');
    $query2->addField('at', 'some_other_field', 'alias2');
    $query2->addField('at', 'some_other_field2', 'alias3');
    $query2->addField('at', 'some_other_field3', 'alias4');

    // Verify that queries are very similar.
    // dpq($query1);
    // dpq($query2);

    // Matrimony.
    $query1 = $query2->union($query1, 'UNION ALL');

    // Manual test.
    // dpm($query1->execute()->fetchAll());

  }
}

Cela fonctionne pour la plupart des vues. Cependant, certains plugins de style peuvent faire des choses fantaisistes qui ne fonctionneront pas avec cette technique (module Calendrier, je vous regarde).

15
Dalin

Vous pouvez utiliser le module de gestionnaires supplémentaires Vues pour générer des requêtes SQL UNION à partir de deux vues/affichages différents.

Un tutoriel détaillé sur drupal.org ici

https://www.drupal.org/project/views_extra_handlers screenshot of views alter settings

3
TechNikh

J'ai fini par utiliser db_query () pour créer les SQL UNIONs, puis les rendre dans une disposition de table comprenant des pagers utilisant la fonction theme ().

Pour l'utilisateur, cela ressemble à des vues par défaut. L'autre avantage était que je pouvais beaucoup optimiser la requête. Je montre "les activités de mon ami" et si vous utilisiez des vues pour cela, cela créerait une liste de vos amis et l'utiliserait dans une clause SQL "IN" qui est très lente si vous avez plus de 50 ou 100 enregistrements.

Je pourrais restreindre cette liste d'amis à ceux qui ont été connectés au site au cours des x derniers jours.

Ceci est un exemple de code:

  // Two queries are required (friendships can be represented in 2 ways in the
  // same table). No point making two db calls though so a UNION it is.

  // Build up the first query.
  $query = db_select('flag_friend', 'f')
    ->condition('f.uid', $account->uid)
    ->condition('u.login', $timestamp, '>');
  $query->addExpression('f.friend_uid', 'uid');
  $query->innerJoin('users', 'u', 'u.uid = f.friend_uid');

  // Build up the second query.
  $query2 = db_select('flag_friend', 'f')
    ->condition('f.friend_uid', $account->uid)
    ->condition('u.login', $timestamp, '>');
  $query2->addExpression('f.uid', 'uid');
  $query2->innerJoin('users', 'u', 'u.uid = f.uid');

  // Return the results of the UNIONed queries.
  return $query->union($query2)->execute()->fetchCol();
2
uwe

Pour référence future, voici comment j'ai combiné deux vues en se basant sur la même table ensemble. Les mêmes principes devraient également s'appliquer aux vues basées sur différentes tables avec la même quantité de champs.

Dans le cas ci-dessous, seul id est sélectionné car le format est défini sur entité rendue. Mais si vous utilisez des champs, vous pouvez toujours ajouter des champs fictifs supplémentaires à la requête qui contient moins de champs comme j'ai ajouté l'horodatage ci-dessous.

/**
 * Implements hook_views_pre_execute().
 */
function MY_MODULE_views_pre_execute(&$view) {
  if ($view->name == 'VIEW_1' && $view->current_display == 'DISPLAY_OF_VIEW_1') {

    $view2 = views_get_view('VIEW_2');
    $view2->build('DISPLAY_OF_VIEW_2');

    $view->build_info['query']
    ->fields('table_alias', array('timestamp'))
    ->union(
        $view2->build_info['query']
        ->range()
        ->fields('table_alias', array('timestamp'))
        ->orderBy('timestamp', 'DESC')
    );

    $view->build_info['count_query']
    ->union(
        $view2->build_info['count_query']
        ->range()
    );
  };
}
1
duru

Je suis tombé sur un module appelé Views Field View , qui vous permet d'incorporer une vue en tant que champ dans une autre vue. Je n'ai pas encore essayé cela moi-même, mais cela pourrait vous être utile.

0
Marijke Luttekes

J'imagine que c'est quelque chose dans ce sens:

/** 
* Implements hook_views_pre_execute().
*/     
function mymodule_views_pre_execute(&$view) {
  if ($view->name == 'myview') {
    $query = $view->query;
    $other_view = views_get_view('otherview');
    $other_query = $other_view->query;
    $query = $query->union($other_query);
    $view->query = $query;
  }
}

Bien que je ne l'ai pas testé.

Quelques liens qui peuvent vous aider:

http://api.drupal.org/api/drupal/includes!database!select.inc/function/SelectQueryInterface%3A%3Aunion/7

http://drupal.org/node/557318#comment-199191

0
cam8001

Le EntityFieldQuery Views Backend prend en charge l'interrogation de plusieurs types d'entités en même temps. Il devrait donc être possible d'interroger les nœuds et les commentaires. Les deux types d'entités utilisent une propriété uid pour se lier à leur auteur, donc au niveau de l'API EntityFieldQuery :: propertyCondition () devrait être utilisable pour sélectionner les nœuds et les commentaires d'un seul utilisateur. Je suppose que le backend de vues offre la même fonctionnalité.

0
Pierre Buyle

Une approche différente pourrait être de créer flux de nœuds et de commentaires (avec un filtre contextuel de l'identifiant de l'utilisateur dans l'URL), puis de combiner les deux flux dans un nouveau flux et de l'afficher par date de publication.

0
Sam Wilson