Qual é a melhor maneira, programaticamente, de iterar através dos resultados de uma exibição?

12

Em uma visualização, denominada 'Filhos' (com dois campos: child_node_id e um birth_order_value), qual é a melhor maneira, programaticamente, de iterar pelo conjunto de resultados das visualizações, dado um display_id de 'default' e um argumento que contém o ID do nó pai?

Anteriormente, eu usei a View em um bloco usando um código semelhante ao seguinte:

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

No entanto, em outro bloco, quero executar alguma lógica com base nos valores encontrados na exibição. Você pode adivinhar que a lógica comercial com base no meu requisito final: desejo que o bloco de código que suporta a exibição ('Filhos') seja chamado várias vezes. À medida que percorre os resultados do conjunto de dados da exibição, desejo percorrer recursivamente os nós filhos que estão procurando por seus filhos.

clsturgeon
fonte
Sua abordagem parece bem. Se você colocar em uma resposta, as pessoas poderão votar e aprovar. Uma coisa que você pode tentar é, em vez de desabilitar a exibição toda vez. Faça um $ view-> clone_view () antes da execução. O carregamento da visualização é bastante pesado e isso pode ajudar na memória e no desempenho.
Jeremy French
Perdoe se eu estiver fora da base aqui, mas esse é o tipo de coisa que você pode realizar usando relacionamentos e agrupamentos em um campo na tabela pai. Não tenho certeza se você precisa recorrer ao código ainda. Também pode ser mais simples chamar a subvisão e a lógica da substituição do modelo pai.
Jason Smith
Você deve considerar, em foreach vez de para (.. sizeof ()), ele tem um desempenho muito melhor (porque é C em vez de PHP).
berkes
Uma coisa a observar, em vez de fazer if (arg(0) == 'node' && is_numeric(arg(1)) && ! arg(2)), pode ser melhor usar if ($node = menu_get_object()).
21711 Chris Pliakas
Recortei a resposta da pergunta e a postei como resposta. Dessa forma, fica mais claro para os usuários do site que esta pergunta tem uma resposta.
Jeremy French

Respostas:

2

Brincando um pouco com o Views, pareço ter elaborado uma abordagem. No entanto, gostaria de deixar minha pergunta em aberto para outras respostas e soluções melhores.

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

A chave para executar a visualização várias vezes era para eu desmarcar ($ view) quando eu terminava o conjunto de resultados.

Jeremy French
fonte
1

Eu obtive uma boa milhagem da função a seguir. O valor de retorno é uma matriz de todos os registros de exibição. Chamar dsm ($ return_value) fornecerá uma boa idéia da estrutura de sua visualização específica.

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;
}
peixe teta
fonte
1

Aqui está uma função auxiliar já incorporada à API Drupal. (Passei um tempo folheando o Drupal Docs e finalmente o encontrei. Parece que muitos outros também produziram soluções que não usam esse ajudante e também que esse ajudante faz um passo interessante que outras soluções não. para chamar pre_render no objeto $ view antes de executar).

Não posso garantir se funciona bem ou não, mas pelo menos é um local específico para discutir problemas com essas abordagens.

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

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

Christian Nally
fonte