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?
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).
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
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();
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()
);
};
}
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.
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:
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é.
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.