When Views caching is turned on for a View with a Views PHP field, functions defined in the Setup Code section of the Views PHP field cannot be used in the Output Code section.

Instead, going to the View shows a white screen with a PHP error like Fatal error: Call to undefined function foo() in sites/all/modules/contrib/views_php/plugins/views/views_php_handler_field.inc(207) : runtime-created function on line 2

Steps to replicate:

  1. Create a View page showing "unformatted fields" for a list of nodes. E.g. show a list of nodes with the "Article" content type, at the URI /article-list.
  2. In the Fields section of the View config, add the Title field, and a Views PHP field. Go to the settings for the Views PHP field.
  3. In the Setup Code section of the Views PHP field settings, define a function. Example code:
    function foo($str) {return $str . ' foo';}
  4. In the Output Code section of the Views PHP field settings, call the function. Example code:
    <?php print foo($row->title); ?>
  5. In the "Advanced" section of the View config, go to "Caching", and set it to "Time-based", use the default "1 hour" cache time.
  6. Save the View.
  7. Browse to the View page URI e.g. /article-list .
  8. You will see a white screen with an error similar to Fatal error: Call to undefined function foo() in sites/all/modules/contrib/views_php/plugins/views/views_php_handler_field.inc(207) : runtime-created function on line 2

Example View producing the error

Below is an exported View of a list of Article nodes, using a Views PHP field, which produces this error.

$view = new view();
$view->name = 'article_list';
$view->description = '';
$view->tag = 'default';
$view->base_table = 'node';
$view->human_name = 'Article list';
$view->core = 7;
$view->api_version = '3.0';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */

/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['title'] = 'Article list';
$handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['access']['type'] = 'perm';
$handler->display->display_options['cache']['type'] = 'time';
$handler->display->display_options['cache']['results_lifespan'] = '3600';
$handler->display->display_options['cache']['results_lifespan_custom'] = '0';
$handler->display->display_options['cache']['output_lifespan'] = '3600';
$handler->display->display_options['cache']['output_lifespan_custom'] = '0';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'full';
$handler->display->display_options['pager']['options']['items_per_page'] = '10';
$handler->display->display_options['style_plugin'] = 'default';
$handler->display->display_options['row_plugin'] = 'fields';
/* Field: Content: Title */
$handler->display->display_options['fields']['title']['id'] = 'title';
$handler->display->display_options['fields']['title']['table'] = 'node';
$handler->display->display_options['fields']['title']['field'] = 'title';
$handler->display->display_options['fields']['title']['label'] = '';
$handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE;
$handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE;
/* Field: Global: PHP */
$handler->display->display_options['fields']['php']['id'] = 'php';
$handler->display->display_options['fields']['php']['table'] = 'views';
$handler->display->display_options['fields']['php']['field'] = 'php';
$handler->display->display_options['fields']['php']['use_php_setup'] = 1;
$handler->display->display_options['fields']['php']['php_setup'] = 'function foo($str) {
  return $str . \' foo\';
}';
$handler->display->display_options['fields']['php']['php_output'] = '<?php
print foo($row->title);
?>';
$handler->display->display_options['fields']['php']['use_php_click_sortable'] = '0';
$handler->display->display_options['fields']['php']['php_click_sortable'] = '';
/* Sort criterion: Content: Post date */
$handler->display->display_options['sorts']['created']['id'] = 'created';
$handler->display->display_options['sorts']['created']['table'] = 'node';
$handler->display->display_options['sorts']['created']['field'] = 'created';
$handler->display->display_options['sorts']['created']['order'] = 'DESC';
/* Filter criterion: Content: Published */
$handler->display->display_options['filters']['status']['id'] = 'status';
$handler->display->display_options['filters']['status']['table'] = 'node';
$handler->display->display_options['filters']['status']['field'] = 'status';
$handler->display->display_options['filters']['status']['value'] = 1;
$handler->display->display_options['filters']['status']['group'] = 1;
$handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
/* Filter criterion: Content: Type */
$handler->display->display_options['filters']['type']['id'] = 'type';
$handler->display->display_options['filters']['type']['table'] = 'node';
$handler->display->display_options['filters']['type']['field'] = 'type';
$handler->display->display_options['filters']['type']['value'] = array(
  'article' => 'article',
);

/* Display: Page */
$handler = $view->new_display('page', 'Page', 'page');
$handler->display->display_options['path'] = 'article-list';
$translatables['article_list'] = array(
  t('Master'),
  t('Article list'),
  t('more'),
  t('Apply'),
  t('Reset'),
  t('Sort by'),
  t('Asc'),
  t('Desc'),
  t('Items per page'),
  t('- All -'),
  t('Offset'),
  t('« first'),
  t('‹ previous'),
  t('next ›'),
  t('last »'),
  t('PHP'),
  t('Page'),
);
CommentFileSizeAuthor
#4 Views cache only rendered output.png37.56 KBeugenesia
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

eugenesia created an issue. See original summary.

eugenesia’s picture

Issue summary: View changes
eugenesia’s picture

The error occurs in views_php_handler_field::render() when it executes the Output Code calling the functions predefined in the Setup Code.

The Setup Code is run and functions defined in views_php_handler_field::php_pre_execute(). I suspect this method is not being run when Views caching is turned on. This causes the "undefined function" PHP error.

An obvious fix would be to run the Setup Code in views_php_handler_field::render() but I'm not sure what the implications will be.

eugenesia’s picture

Workaround: If we cache only the "Rendered output" and not the "Query results" (see attached screenshot), the error disappears.

View cache only rendered output

fizk’s picture

Thanks for looking into this. I'm thinking we need a checkbox under the Setup Code textarea that makes Views PHP run the Setup Code even if query caching is enabled. Thoughts?