Quelle est la meilleure façon, par programme, d'itérer les résultats d'une vue?

12

Étant donné une vue, nommée 'Children' (avec deux champs: child_node_id et a birth_order_value), quelle est la meilleure façon, par programme, d'itérer à travers l'ensemble de résultats des vues étant donné un display_id de 'default' et un argument qui contient l'ID du nœud parent?

Auparavant, j'ai utilisé la vue dans un bloc en utilisant un code similaire au suivant:

if ( arg(0) == 'node' && is_numeric(arg(1)) && ! arg(2)) {
   $node = node_load(arg(1));
   $args = array($node->nid);
   $view = views_get_view('Children');
   print $view->preview('default', $args);
}

Cependant, dans un autre bloc, je veux effectuer une logique basée sur les valeurs trouvées dans la vue. Vous pourriez être en mesure de deviner que la logique métier basée sur ma dernière exigence: je veux que le bloc de code prenant en charge la vue («Enfants») soit appelé plusieurs fois. En parcourant les résultats de l'ensemble de données de vue, je souhaite parcourir de manière récursive les nœuds enfants interrogeant leurs enfants.

clsturgeon
la source
Votre approche semble correcte. Si vous le mettez dans une réponse, les gens peuvent voter et l'approuver. Une chose que vous pouvez essayer est de ne pas modifier la vue à chaque fois. Faites un $ view-> clone_view () avant l'exécution. Le chargement de la vue est assez lourd et cela peut aider la mémoire et les performances.
Jeremy French
Pardonnez-moi si je suis hors de la base ici, mais est-ce le genre de chose que vous pouvez accomplir en utilisant des relations et des regroupements sur un champ de la table parent. Je ne suis pas sûr que vous ayez encore besoin de recourir au code. Il peut également être plus simple d'appeler la sous-vue et la logique à partir du remplacement du modèle parent.
Jason Smith
Vous devriez considérer à la foreach place de for (.. sizeof ()), il fonctionne beaucoup mieux (car c'est C au lieu de PHP).
berkes
Une chose à noter, au lieu de le faire if (arg(0) == 'node' && is_numeric(arg(1)) && ! arg(2)), il pourrait être préférable d'utiliser if ($node = menu_get_object()).
Chris Pliakas
J'ai supprimé la réponse de la question et l'ai publiée comme réponse. De cette façon, il est plus clair pour les utilisateurs du site que cette question a une réponse.
Jeremy French

Réponses:

2

En jouant un peu avec Views, il me semble avoir élaboré une approche. Cependant, je voudrais laisser ma question ouverte à d'autres réponses et à de meilleures solutions.

<?php
if ( arg(0) == 'node' && is_numeric(arg(1)) && ! arg(2) ) {
   $node = node_load(arg(1));
   $args = array($node->nid );
   unset($view);
   $view = views_get_view('Children');
   $view->set_display('default');  
   $view->set_arguments($args);
   $view->set_items_per_page(20);
   $view->execute();
   $newarg = array();
   for ($i=0; $i<sizeof($view->result); $i++) {
      $newarg[$i] = $view->render_field('nid_1', $i);
   }
   for ($i=0; $i<sizeof($newarg); $i++) {
      unset($view);
      $view = views_get_view('Children');
      $view->set_display('default');  
      $view->set_arguments($newarg[$i]);
      $view->set_items_per_page(20);
      $view->execute();
      ....
   }
}
?>

La clé pour exécuter la vue plusieurs fois était pour moi de désactiver ($ view) lorsque j'en avais fini avec le jeu de résultats.

Jeremy French
la source
1

J'ai obtenu un bon kilométrage de la fonction suivante. La valeur de retour est un tableau de tous les enregistrements de vue. L'appel de dsm ($ return_value) vous donnera une bonne idée de la structure de votre vue particulière.

function _get_view_data($view_name, $args, $page = NULL, $page_size = 0 ) {
    $view = views_get_view($view_name);
    $view->pager['items_per_page'] = $page_size;
    $view->set_arguments($args);
    if ($page) {
        $view->build($page);
        $view->execute($page);
    }
    else {
        $view->execute();
    }
    return $view->result;
}
thêta-poisson
la source
1

Voici une fonction d'aide déjà intégrée à l'API Drupal. (J'ai passé un certain temps à fouiller dans les Drupal Docs, et je l'ai finalement trouvé. Il semble que beaucoup d'autres ont également produit des solutions qui n'utilisent pas cet assistant, et aussi que cet assistant fasse une étape intéressante que les autres solutions ne font pas .. . pour appeler pre_render sur l'objet $ view avant de l'exécuter).

Je ne peux pas garantir que cela fonctionne bien ou non, mais au moins c'est un endroit spécifique pour signaler les problèmes avec ces approches.

Pour D6 http://api.drupal.org/api/views/views.module/function/views_get_view_result/6

Et pour D7 http://api.drupal.org/api/views/views.module/function/views_get_view_result/7

Christian Nally
la source