2

I've created a View of all the views that Drupal knows about, whether they reside in code or in the DB. It works great, tells the user about each view, its tags, its displays, its base table, its fields if they exist, and its path.

I'm doing this by overriding execute(&$view) in a custom query handler. A very truncated version of what I'm doing:

foreach(views_get_all_views() as $zview) {
    // Examine each display of each view.
    foreach($zview->display as $display) {
      $row = new stdClass();
      ... // Set the things on $row.
      $view->result[] = $row;
    }
}

Now I also want it to tell the user about each View's query.

If I do this it works (for the last of the many Views):

      $zxview = views_get_view($zview->name);
      $zxview->set_display($display->id);
      $zxview->pre_execute();
      $zxview->execute();
      dpm($zxview->query->query()->__toString());

but I have to do it outside of the foreach() that goes through each view. If I try to do $zxview->execute() inside foreach(views_get_all_views() as $zview) { ... } I get

PHP Fatal error:  Maximum function nesting level of '100' reached, aborting!

This makes sense, sort of. But, so how can I list the query being executed for each view next to the name of each view, within a view? (I'm already excluding views defined by the module defining this view of views.)

2 Answers 2

0

I searched on that error and you can increase the limit from 100 to something larger.

Increase the value of xdebug.max_nesting_level in your php.ini:

xdebug.max_nesting_level

Type: integer, Default value: 100

Controls the protection mechanism for infinite recursion protection. The value of this setting is the maximum level of nested functions that are allowed before the script will be aborted.

Try setting it to 200

xdebug.max_nesting_level = 200

Thanks to Stack Exchange for the answer!

1
  • This doesn't work. 200 isn't enough. I keep increasing the limit until I stop getting the max nesting error and start just getting server errors instead. No dice.
    – beth
    Oct 14, 2013 at 18:14
0

I got around this issue by doing it in the field handler.

First, inside the custom query handler, I set a field in each row to contain an array consisting of the view object and the display ID:

    foreach($zview->display as $display) {
      $row = new stdClass();
      // Since we can't render the query here bc of recursion, pass view &
      // display to a field. We'll use a special field handler to get the
      // query for each display.
      $row->views_query = array(
        'view' => $zview,
        'display_id' => $display->id,
      );

Then, after telling the field to use my custom handler in hook_views_data(), I made my custom field handler:

  function render($values) {
    $value = ($this->get_value($values));
    if (is_object($value['view'])) {
      $view = $value['view'];
      $display_id = $value['display_id'] ? $value['display_id']: NULL;
      $view->set_display($display_id);
      $view->pre_execute();
      $view->execute();
      return($view->query->query()->__toString());
    }
    return 'No View object given in field handler.';
  }
}

Since it's no longer calling $view->execute() from inside $view->execute() (and in render() instead) it's much happier.

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.