13

Given a view, named 'Children' (with two fields: child_node_id and a birth_order_value) what is the best way, programmatically, to iterate through the views results set given a display_id of 'default' and an argument that contains the parent node id?

Previously, I have used the View in a block using code similar to the following:

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

However, in another block I want to perform some logic based on the values found in the view. You might be able guess that business logic based on my final requirement: I want the block of code supporting the view ('Children') be called multiple times. As I iterate through the view dataset results, I want to recursively iterate through the children nodes querying for their children.

5
  • Your approach looks ok. If you put it in an answer people can vote on it and approve. One thing you may try is rather than unsetting the view each time. Do a $view->clone_view() prior to execution. View loading is quite heavy and this may help memory and performance. Commented Jul 5, 2011 at 14:08
  • Pardon if I'm off base here, but is this the sort of thing you can accomplish using relationships and grouping on a field in the parent table. I'm not sure you need to resort to code yet. It may also be simpler to call the subview and logic from the parent template override. Commented Jul 9, 2011 at 1:37
  • You should consider foreach instead of for(..sizeof()), it performs a lot better (because it is C instead of PHP).
    – berkes
    Commented Jul 13, 2011 at 14:36
  • One thing to note, instead of doing if (arg(0) == 'node' && is_numeric(arg(1)) && ! arg(2)), it might be better to use if ($node = menu_get_object()). Commented Jul 17, 2011 at 15:57
  • I've trimmed the answer from the question and posted it as an answer. That way it is clearer to users of the site that this question has an answer. Commented Jul 21, 2011 at 8:33

3 Answers 3

2

Playing around with Views a bit I seem to have worked out an approach. However, I'd like to leave my question open to other answers and better 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();
      ....
   }
}
?>

The key to executing the view multiple times was for me to unset($view) when I was done with the result set.

1

I've gotten good mileage out of the following function. The return value is an array of all the view records. Calling dsm($return_value) will give you a good idea of the structure of your particular view.

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

Here is a helper function already built in to the Drupal API. (I spent a while flailing around in the Drupal Docs, and eventually found it. It seems many others have also produced solutions that don't use this helper, and also that this helper does one interesting step that other solutions don't... to call pre_render on the $view object before execute).

I can't vouch for whether it works well or not, but at least it's a specific place to call out issues with these approaches.

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

And for D7 http://api.drupal.org/api/views/views.module/function/views_get_view_result/7

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.