This page documents changes between the Webform 3.x version and the Webform 4.x version, including any information you need to know when upgrading from one version to the next.
The most important thing to keep in mind when upgrading from Webform 3.x to 4.x is that you cannot downgrade after update.php has been run, unless you restore a database backup created before the update.php run. Webform 4.x makes several database changes and downgrading after you have upgraded is not possible. Be sure to test your upgrade on a development server or localhost copy before upgrading your production server.
Changes between Webform 3.x and 4.x:
ALPHA1
ALPHA2
- The $submission->data and $form_state['values'] variable structure changed
- Same-page conditionals built into main module require "Webform Conditional" module be uninstalled
ALPHA7
- The $component['mandatory'] property has been renamed to $component['required']
- The theme_webform_components_form() has its variables preprocessed
ALPHA10
- Webform exporter classes now use PHP5-syntax for constructors
- Webform legacy-Excel class renamed and disabled by default
- Webform security functions renamed: _webform_filter_xss(), _webform_filter_descriptions(), and _webform_filter_values()
BETA1
- Webform-enabled content types are now controlled by separate variables instead of the single "webform_enabled_types" variable
- Classes are used instead of IDs whenever possible in Webform's output
RC1
RC5
Detailed Change Instructions
ALPHA1
Token System Replaced with D7-style Tokens
(issue) Webform previously used its own custom token system to provide common tokens such as %title, %username, or %value[key]. In Webform 4.x, we use the token system provided by Drupal 7 core, which uses a format such as [node:title], [current-user:name], or [submission:values:key].
Most tokens will be upgraded for you, however some tokens do not have equivalents and no longer work. These include %post, %request, %cookie, and %session. The %get token (which maps to PHP's $_GET variable) has the equivalent token [current-page:query:key].
As mentioned, most tokens are upgraded for you in any configuration, default values, e-mail templates, etc. However tokens that are hard-coded within things such as node exports or webform-mail.tpl.php files will need to be changed manually. The complete map of replacements is as follows:
%username [current-user:name]
%useremail [current-user:mail]
%uid [current-user:uid]
%date [submission:date:long]
%ip_address [current-user:ip-address]
%site [site:name]
%nid [node:nid]
%title [node:title]
%email_values [submission:values]
%submission_url [submission:url]
%sid [submission:sid]
%server[REQUEST_URI] [current-page:url]
%get[$key] [current-page:query:$key]
%email[$key] [submission:values:$key]
%value[$key] [submission:values:$key:nolabel]
%safe_key[$key] [submission:values:$key:key]
%profile[$key] [current-user:$key]
ALPHA2
The $submission->data and $form_state['values'] variable structure changed
(issue) In Webform 3.x, values within the Webform $submission variable as retrieved by webform_get_submission() had a structure like the following:
Webform 3.x:
$submission->data[$cid]['value'][0] = 'string value';
However in 4.x, the superflous "value" key was eliminated to increase consistency in Webform's internal data structures during form processing.
Webform 4.x:
$submission->data[$cid][0] = 'string value';
Additionally, in Webform 3.x, the $form_state['values'] array was split in two pieces, $form_state['values']['submitted'] and $form_state['values']['submitted_tree']. In Webform 4.x, the $form_state['values']['submitted_tree'] array no longer exists, and the $form_state['values']['submitted'] array is now identical to the structure of a fully loaded $submission array, making the two structures more easily interchangeable.
Same-page conditionals built into main module require "Webform Conditional" module be uninstalled
(issue) Before upgrading to Webform 4.x, if you have installed the "Webform Conditional" module you MUST disable and then uninstall the module using the Drupal uninstaller (admin/module/uninstall).
ALPHA7
The $component['mandatory'] property has been renamed to $component['required']
(issue) Webform 4.x has switched from using the legacy terminology "mandatory" to "required" everywhere in its code. This includes in all components ($component['required']
) and in the database table webform_component
.
Webform 3.x:
$element['#required'] = $component['mandatory'];
Webform 4.x:
$element['#required'] = $component['required'];
The theme_webform_components_form() has its variables preprocessed
(issue) The theme_webform_components_form() used to contain a large amount of logic code. This logic has all been moved to a preprocess function: template_preprocess_webform_components_form(). If you have overridden the theme_webform_components_form() theme function on your site, you will need to remake your overridden version.
Webform 3.x:
See theme_webform_components_form() on drupalcode.org.
Webform 4.x:
See preprocess_webform_components_form() on drupalcode.org.
See theme_webform_components_form() on drupalcode.org.
ALPHA10
Webform exporter classes now use PHP5-syntax for constructors
(issue) Constructors have changed in exporter classes (such as the webform_exporter_excel
and webform_exporter
classes) to use __construct()
instead of functions that match the class name. If you provide a custom exporter for Webform, it will need to be updated to use the PHP5 syntax:
Webform 3.x:
class webform_exporter_excel extends webform_exporter_delimited {
function webform_exporter_excel($options) {
$options['delimiter'] = '\t';
parent::webform_exporter_delimited($options);
}
}
Webform 4.x:
class webform_exporter_excel extends webform_exporter_delimited {
function __construct($options) {
$options['delimiter'] = '\t';
parent::__construct($options);
}
}
Webform legacy-Excel class renamed and disabled by default
(issue) The class webform_exporter_excel
has been renamed to webform_exporter_excel_delimited
. This was done to distinguish the old TSV-based Excel exports from the new native-Excel exporter (which is in the webform_exporter_excel_xlsx
class).
In addition, the new native Excel exporter is the only exporter available in the UI by default. If you need to enable the old Excel exporter, you may do so by setting this hidden variable in your settings.php file:
$conf['webform_excel_legacy_exporter'] = TRUE;
Webform security functions renamed: _webform_filter_xss(), _webform_filter_descriptions(), and _webform_filter_values()
(issue) The Webform security functions have been overhauled to solve several problems: They're now in the public namespace, since 3rd party modules regularly use these functions. The token replacement has been separated from security checking.
In general, you can flip your functions in the following way:
_webform_filter_xss()
=> webform_filter_xss()
_webform_filter_descriptions()
=> webform_filter_descriptions()
_webform_filter_values()
=> webform_replace_tokens()
Note that in 3.x, the last ($strict) parameter for _webform_filter_values() was TRUE by default, meaning it assumed it was being output to HTML and would run check_plain() on the output. In 4.x, the last parameter ($sanitize) is FALSE by default and will not be safe for outputting directly to HTML.
This example is a slimmed down version of a _webform_render_[component]() function that demonstrates all of these changes:
Webform 3.x:
$element = array(
'#type' => 'textfield',
'#title' => $filter ? _webform_filter_xss($component['name']) : $component['name'],
'#default_value' => $filter ? _webform_filter_values($component['value'], $node, NULL, NULL, TRUE) : $component['value'],
'#description' => $filter ? _webform_filter_descriptions($component['extra']['description'], $node) : $component['extra']['description'],
);
Webform 4.x:
$element = array(
'#type' => 'textfield',
'#title' => $filter ? webform_filter_xss($component['name']) : $component['name'],
'#default_value' => $filter ? webform_replace_tokens($component['value'], $node) : $component['value'],
'#description' => $filter ? webform_filter_descriptions($component['extra']['description'], $node) : $component['extra']['description'],
);
Webform-enabled content types are now controlled by separate variables instead of the single "webform_enabled_types" variable
(issue) In order to make Webform-enabled content types more easily exportable and discoverable, the single variable "webform_enabled_types"
variable has been split into separate variables with the name "webform_node_" . $node_type
.
Webform 3.x
if (in_array($node->type, webform_variable_get('webform_node_types'))) {
// Do something.
}
Webform 4.x
if (variable_get('webform_node_' . $node->type, FALSE)) {
// Do something.
}
// OR:
if (in_array($node->type, webform_node_types())) {
// Do something.
}
The first approach is recommended for performance reasons, but the latter should be used if looping through all content types that are Webform-enabled.
Classes are used instead of IDs whenever possible in Webform's output
(issue) In order to make Webform's conditional logic work when the same form is rendered multiple times on the same page and to increase consistency for themers, Webform 4.x reduces the use of HTML "id" attributes in preference of "class" attributes whenever possible.
For example a component with the form key "my_component_key" would be changed as follows:
Webform 3.x
<div class="..." id="webform-component-my-component-key">
<label ...>Field label </label>
<input ...>
<div class="description">Description goes here.</div>
</div>
Webform 4.x
<div class="... webform-component--my-component-key">
<label ...>Field label </label>
<input ...>
<div class="description">Description goes here.</div>
</div>
Note that the new class name has two dashes separating "webform-component" and the form key, this is to avoid conflicts with classes such as "webform-component-textfield" or "webform-component-inline". Any CSS that targeted elements using the HTML "id" attribute will need to be updated to use the new classes instead of the IDs.
RC1
Number of arguments for hook_webform_select_options_info() 's callback function changed
(issue)(issue) As part of adding node tokens to select component option labels the filter argument was removed from the callback call for hook_webform_select_options_info() .
For example webform_options_days changed as follows:
Webform 3.x
webform_options_days($component, $flat, $filter, $arguments)
Webform 4.x
webform_options_days($component, $flat, $arguments)
webform.api.php is already updated accordingly.
RC5
theme_webform_element() needs to be rethemed due to new preprocess function
(issue) In order to reduce code in the theme_webform_element() function and to make it so that modules can alter the list of wrapper classes, the theme_webform_element() function was split up to use a preprprocess function to assign classes and do other logic before the theme function is run. If you have themed Webform form elements in your theme's template.php file, it is recommended to copy/paste the original theme_webform_element() and retheme the output. If this is not done, classes may be output twice on the front-end. This usually does not cause any visual problems, but it does result in redundant output.
Comments
Upgrade Procedure
What is the procedure for upgrading from 3.x to 4.x? I know you need to do a database back up first but are there specific Drush commands to do the upgrade? Can I just do drush dl webform-7.x-4.x ? Do I need to disable and remove the 3.x module completely and then install the 4.x version? I just want to make sure I'm doing it right the first time since you can't downgrade without having to reload the previous database instance.
Very good question
Agree - The online docs should be improved by adding how to perform the update - information which you can find in the README:
Firstly, most of the users are using the GUI to perform module installations or upgrades - in this use case the user does not extract the package, hence he/she would not find the instructions.
Secondly, the instructions are in the README - while they should be in the UPGRADE or INSTALL file.
Anyway, it is as simple as that:
Upgrading via Drush
This is how you do the upgrade from Webform 3.x to 4.x with Drush.
First, make sure you change the below to the latest version of webform. As of today it's webform-7.x-4.10.
This downloads ctools then views which are now required by webform 4.x. Then you enable both. Note here that I'm downloading and enabling safely cause from the first two commands if the modules are already downloaded Drush will tell you and then no need to download them again. Then you specify to Drush you want that specific version of the webform module (otherwise you'd stay on the 3.x branch) and override the older files of webform (properly, i.e., without keeping previous 3.x files) and finally you run updatedb which is similar to running update.php from the web interface.
Cheers.
Now i have used webform 7.x-4
Now i have used webform 7.x-4.2. i want to upgrate to webform 7.x-4.5.
How to upgrade this?
http://www.phponwebsites.com/
So what's the best way to get data values by keys?
In Webform 3 I used keys in submitted tree to get the values. What's the best way to do it now?
Seems running off the topic
The title is about upgrading from 7.3 to 7.4.
But the content is about changes from 7.3 to 7.4.
It's confusing for user when they looking for steps to upgrade from 7.3 to 7.4.
Please create new page for the changes and update the correct info regarding the updating steps.
Update with Drush
If you have Drush installed then you can update to webform 4 easily with Drush commands
To update to latest dev version
drush up webform-4.x
To update to specific version (in this case stable at the time of writing)
drush up webform-4.12
The results will be like:
Migrate existing webforms
I have existing webforms created on version 3. What happens to these after version 4 upgrade? How do I migrate these? Sorry if I am missing anything from the documentation I can't seem to find any on info on this concern. Thanks, mates!
that's what the testing/staging for
I think you should try upgrading it to 4.x in test servers and verify everything works as expected before updating anything in production directly.
In my case, the migration using the above Drush command went smoothly and all the webforms built in 3.x are well migrated in 4.x without losing any functionality and saved results.
The migration was smooth as mango smoothie and works just like before without any issues.
Good to know
Yes, I did test actually locally and on test server, but seems the webforms created before on ver 3 have gone missing. Switching themes did not fix it, ruling out theme display issues. I will test and troubleshoot some more. Good to know though it works, one reason and validation to work on my issues further. Thanks, raj!