¿Cuál es la mejor manera, mediante programación, para recorrer los resultados de una vista?

12

Dada una vista, llamada 'Hijos' (con dos campos: child_node_id y birth_order_value), ¿cuál es la mejor manera, mediante programación, de recorrer en iteración el conjunto de resultados de vistas dado un display_id de 'default' y un argumento que contiene la identificación del nodo padre?

Anteriormente, he usado la Vista en un bloque usando un código similar al siguiente:

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);
}

Sin embargo, en otro bloque quiero realizar alguna lógica basada en los valores encontrados en la vista. Es posible que adivine esa lógica empresarial basada en mi requisito final: quiero que el bloque de código que admite la vista ('Hijos') se llame varias veces. A medida que itero a través de los resultados del conjunto de datos de la vista, quiero iterar recursivamente a través de los nodos hijos que consultan por sus hijos.

clsturgeon
fuente
Tu enfoque se ve bien. Si lo pones en una respuesta, la gente puede votarlo y aprobarlo. Una cosa que puede intentar es en lugar de desarmar la vista cada vez. Haga un $ view-> clone_view () antes de la ejecución. La carga de la vista es bastante pesada y esto puede ayudar a la memoria y al rendimiento.
Jeremy French
Disculpe si estoy fuera de la base aquí, pero ¿es este el tipo de cosas que puede lograr usando relaciones y agrupaciones en un campo en la tabla principal? No estoy seguro de que necesites recurrir al código todavía. También puede ser más simple llamar a la subvista y la lógica desde la anulación de la plantilla principal.
Jason Smith
Debería considerar en foreach lugar de for (.. sizeof ()), funciona mucho mejor (porque es C en lugar de PHP).
berkes
Una cosa a tener en cuenta, en lugar de hacerlo if (arg(0) == 'node' && is_numeric(arg(1)) && ! arg(2)), podría ser mejor usar if ($node = menu_get_object()).
Chris Pliakas
Recorté la respuesta de la pregunta y la publiqué como respuesta. De esta manera, es más claro para los usuarios del sitio que esta pregunta tiene una respuesta.
Jeremy French

Respuestas:

2

Jugando un poco con Views, parece que he elaborado un enfoque. Sin embargo, me gustaría dejar mi pregunta abierta a otras respuestas y mejores soluciones.

<?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 clave para ejecutar la vista varias veces fue desarmar ($ view) cuando terminé con el conjunto de resultados.

Jeremy French
fuente
1

Obtuve un buen rendimiento de la siguiente función. El valor de retorno es una matriz de todos los registros de vista. Llamar a dsm ($ return_value) le dará una buena idea de la estructura de su vista particular.

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;
}
pez theta
fuente
1

Aquí hay una función auxiliar ya integrada en la API de Drupal. (Pasé un tiempo revoloteando en Drupal Docs, y finalmente lo encontré. Parece que muchos otros también han producido soluciones que no usan este ayudante, y también que este ayudante da un paso interesante que otras soluciones no ... . para llamar a pre_render en el objeto $ view antes de ejecutar).

No puedo garantizar si funciona bien o no, pero al menos es un lugar específico para señalar problemas con estos enfoques.

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

Y para D7 http://api.drupal.org/api/views/views.module/function/views_get_view_result/7

Christian Nally
fuente