Our webform had three page breaks and was working fine before we upgraded to our most recent version of Drupal. On a recent test of the form, we received this error after trying to move past the first page: Fatal error: Call to undefined function webform_expand_select_ids().

Seeing a similar issue in the #6 post here: http://drupal.org/node/1091354, we removed all page breaks and this solved the problem. We'd like to add the page breaks back in. No custom code in this webform.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

tamarackmedia’s picture

quicksketch’s picture

Thanks, I see that other issue has had quite a few updates to it since I marked it "won't fix", as I thought it was a custom-coding issue.

@ncharalampidis summed it up nicely in that issue:

The problem occurs when we have a multi page form (3 pages) and the first two pages have at least a checkbox while the last one doesn't. So the error: "Fatal error: Call to undefined function webform_expand_checkboxes() in includes/form.inc on line 1748" appears at the last page...

The problem happens because the file "componens/select.inc" is not loaded at the last page, as there is no checkbox component, but "webform_expand_checkboxes" function, which is defined in "select.inc", is called by "form_builder" in form.inc as a process;

So i think that either:

-all functions named "webform_expand_something" should be moved in webform.module so they can be accessible at anytime,
-or all components of the whole form should be included in every page... In this case the "_webform_client_form_rule_check" function should be removed.

I'll look into this problem when I get a chance.

nchar’s picture

I have been working the past 4 hours trying to figure out what is going on there...

So finally i found that (in my case) the problem happens because of the entitycache module. Entity Cache caches the activity of node load hook disabling that way the webform includes!! So the easy fix is to disable the Entity Cache module.

Though i fixed the error with 4 lines of code in webform.module file, that prevents webforms content type from being cached. So i think that this is the best way and here is the patch for this:

nchar’s picture

Status: Active » Patch (to be ported)
Bcwald’s picture

I am having this same issue, I do not have entity cache module enabled, so there must be another module that is causing this issue as well.

quicksketch’s picture

Status: Patch (to be ported) » Active

Well I tried to reproduce this problem but I couldn't get the error to occur. I set up a 3 page webform with a select element on the first two pages but not one on the 3rd page. But the form works just fine. I'll need steps to reproduce this problem from a fresh install.

Though i fixed the error with 4 lines of code in webform.module file, that prevents webforms content type from being cached. So i think that this is the best way and here is the patch for this:

I wasn't able to reproduce the problem with Entity Cache either, but even if I could, I don't think this solution is a good one. Webforms can load hundreds of rows from the database on a long form, being able to use Entity Cache is a huge performance bonus for Webform. Entity Cache only caches the $node object any way, not the rendered content, so we should be able to pull in our .inc files as needed.

-or all components of the whole form should be included in every page... In this case the "_webform_client_form_rule_check" function should be removed.

I can't see why this function wouldn't still be needed. That function checks the conditional logic on the page.

Something else anyone who is experiencing this problem might try: Make sure that the apc.include_once_override is disabled on your server (if running PHP 5.3), as it can cause all kinds of function not found errors (i.e. #807680: APC setting "apc.include_once_override" causes call to undefined function filefield_widget_settings_save()).

quicksketch’s picture

Status: Active » Postponed (maintainer needs more info)
quicksketch’s picture

Status: Postponed (maintainer needs more info) » Needs review
FileSize
1.32 KB

Even though I haven't been able to confirm this problem, I ran into a similar issue while working on #289919: Provide AJAX-based file uploads/Progress Bar for uploads. Even though this patch isn't necessary for that issue, I found that it solved a problem I was having temporarily while working on it.

This patch simply makes it so that any time the form is rendered or built (even from cache_form), all the components of Webform are included on the page. I think this is a better solution than just always loading all components (which seems wasteful) or moving the component-specific functions into the .module file. Because this adds a #process function on the root form itself, it should include all the components on the form before any of the elements within the form call any of the functions that may be in component .inc files. We can't include these includes directly in webform_client_form(), because that function is skipped entirely when loading a form from cache (as when moving between multiple pages in a form).

quicksketch’s picture

Title: Fatal error: Call to undefined function webform_expand_select_ids() » Prevent undefined function calls in component includes
Version: 7.x-3.13 » 7.x-3.15
Status: Needs review » Fixed

I've gone ahead and committed this to both 3.x branches. I don't think it can hurt. Please let me know if this doesn't solve the problem for you. It will be included in the 3.16 version (which is probably a few months away).

Alan D.’s picture

Great work and great solution. I hit this via a strange combination of panel usages (non had caching enabled).

Alan D.’s picture

Sadly this didn't work in our use case. One of the other developers may have more aggressive caching enabled somewhere...

So here is a workaround that could be useful to others. I left the #process code in place, but it didn't appear do anything by itself, but I do not know if they are still needed.

/**
 * Implements hook_form_alter().
 */
function vsb_form_alter(&$form, &$form_state, $form_id) {
  if (strpos($form_id, 'webform_client_form_') === 0) {
    // See http://drupal.org/node/1332100. This should be in the next version
    // of webforms.
    if (!is_array($form['#process'])) {
      $form['#process'] = array();
    }
    if (!in_array('webform_client_form_includes', $form['#process'])) {
      $form['#process'][] = 'vsb_webform_client_form_includes';
    }
    // Never cache!
    $form['#cache'] = FALSE;
    // Do the includes again before the submit, because the webform submit handlers need these, even as
    // the form doesn't cache, there are fatal errors without this.
    $form['#submit'] = array_merge(array('vsb_webform_client_form_includes'), $form['#submit']);
  }
}

/**
 * Process function for webform_client_form().
 *
 * Include all the enabled components for this form to ensure availability.
 */
function vsb_webform_client_form_includes($form, $form_state) {
  // This was a fatal error onsubmit with no form caching in a highly cached environment.
  module_load_include('inc', 'webform', 'includes/webform.components');
  $components = webform_components();
  foreach ($components as $component_type => $component) {
    webform_component_include($component_type);
  }
  return $form;
}
pwolanin’s picture

It seems like D7 provides an API function that's supposed to be used for these cases?

http://api.drupal.org/api/drupal/includes--form.inc/function/form_load_i...

quicksketch’s picture

Status: Fixed » Needs work

Wow, thanks pwolanin! That looks exactly like what we need. So far we've only gotten complaints of this problem on D7, which must be more aggressive in it form caching than D6.

pwolanin’s picture

Status: Needs work » Fixed

Note, I'm seeing this error when a file filed is added to a webform node type in combination with the webform_alt_ui module.

What seems to work is to duplicate webform_component_include() and make a version that calls form_load_include() instead of module_load_include().

pwolanin’s picture

Status: Fixed » Needs work

@quicksketch - didn't mean to cross-post.

Let me see if I can get a patch for webform working.

quicksketch’s picture

Note, I'm seeing this error when a file filed is added to a webform node type in combination with the webform_alt_ui module.

Is this with the new AJAX-upload file element (managed_file) that was added in #289919: Provide AJAX-based file uploads/Progress Bar for uploads?

blasthaus’s picture

On a multi-page form, I also got a similar error for undefined function webform_component_feature()
I am using a few additional webform contrib modules : clientside_validation, fapi_validation, field_validation, webform_multifile, webform_conditional

The latest patch and hook from above @Alan D. (comment #11) didn't resolve the error, so I ended up just adding this to any functions calling webform_component_feature() module_load_include('inc', 'webform', 'includes/webform.components'); Is there any harm in doing that?

Not the best solution I know, but for now I am at least able to view and edit webform submissions.

plach’s picture

I got this same error while writing a custom AJAX component. The workaround I found was a variant of #11:

<?php

/**
 * Implements hook_form_FORM_ID_alter().
 */
function webform_multigroup_form_webform_client_form_alter(&$form, $form_state) {
  $form['#process'][] = 'webform_multigroup_include_components';
}

/**
 * Process callback.
 */
function webform_multigroup_include_components($form, &$form_state) {
  if (!function_exists('webform_component_list')) {
    module_load_include('inc', 'webform', 'includes/webform.components');
    foreach ($form['#node']->webform['components'] as $component) {
      if ($component['page_num'] == $form_state['webform']['page_num']) {
        webform_component_include($component['type']);
      }
    }
  }
  return $form;
}
?>

I guess the solution proposed in #12 should fix my use case too.

quicksketch’s picture

@plach: Do you still have this problem in the dev version of Webform? The changes I made in #8 look almost identical to your changes, but they're not included in the 7.15 version.

plach’s picture

I'll try but IIRC I needed to manually include also webform.components.inc...

plach’s picture

@quicksketch:

It seems that the latest dev fixes my issue already. Only one remark: I ain't sure it is actually valid as I have no time to verify the whole code, but I see no check that components have already been included in the process callback.

quicksketch’s picture

I see no check that components have already been included in the process callback.

The webform_component_inclue() function already has a check:

function webform_component_include($component_type) {
  static $included = array();

  // No need to load components that have already been added once.
  if (!isset($included[$component_type])) {
    ...
  }
}
plach’s picture

Ok, wonderful then :)

quicksketch’s picture

Status: Needs work » Fixed

Re-fixing per #19.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

skrtvm’s picture

Issue summary: View changes

hi nchar..

how to disable the Entity Cache.

I couldnot seen any 'Entity Cache' in my Modules