There are a lot of changes to text formats in Drupal 7, and the Webform module needs to be updated for them.

Without these changes, the text format selectors (e.g. on the confirmation message) are basically broken.

These are mostly straightforward changes following the guidelines at http://drupal.org/update/modules/6/7. The one that might not be is this change:

-  return strlen($string) == 0 ? '' : check_markup(_webform_filter_values($string, $node, $submission, NULL, FALSE));
+  return strlen($string) == 0 ? '' : _webform_filter_xss(_webform_filter_values($string, $node, $submission, NULL, FALSE));

I did that because when check_markup() is called without a provided format in Drupal 7, it uses the fallback format (plain text) instead, which didn't seem like what we wanted here.

I've lightly tested the patch and it seems to work OK. I did not test the upgrade path, but it's mostly a copy/paste of code from other places. Note that in theory, markup components store text formats too, as part of a serialized array in the 'extra' column, so they may need a similar database update. I didn't have the energy to write that though :)

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

quicksketch’s picture

Thanks David. I'm lost on a few of these changes. Why do you have change like this in the patch?

-    'confirmation_format' => filter_default_format(),
+    'confirmation_format' => NULL,

And then later do checking like this (which seems entirely unnecessary):

-    '#format' => $node->webform['confirmation_format'],
+    '#format' => isset($node->webform['confirmation_format']) ? $node->webform['confirmation_format'] : NULL,

Setting a default filter value that matches the user's default format seems like it's correct. After this patch the default format is NULL, until the user visits node/x/webform/settings and saves, then it will be set to whatever their default is unless they change it manually.

David_Rothstein’s picture

Status: Needs review » Needs work

The NULL allows you to tell the difference between content that doesn't have a format vs content that happens to already have the filter_default_format() assigned. For example, if someone writes a hook_form_alter() to change the default selected format, they should only be doing that for #format = NULL (i.e. for content where it has never been selected before).

Also, you might have a programmatic node_save(); in that case you don't want to store the default format of whichever user triggered the node_save(), because that might be completely wrong.

However, I think you are right that we don't need the additional isset() check in the form builder functions. I was mostly just copying that pattern from existing examples in core, but in this case it seems the functions only ever expect to receive a webform-enabled node or an already-populated component -- so it sounds like we can assume that it has the array elements we're looking for already defined.

quicksketch’s picture

Also, you might have a programmatic node_save(); in that case you don't want to store the default format of whichever user triggered the node_save(), because that might be completely wrong.

If you're doing a programmatic node_save(), you should set the $node->webform['confirmation_format'] directly anyway. If you haven't set any webform properties or the $node->webform['confirmation'] field, then it doesn't even matter at all what the confirmation format is because there's not even a message at all.

All nodes should have a confirmation format no matter what. The idea that you'd have "NULL" confirmation format very confusing. Does that really mean "plain text" if the format is NULL and there's a confirmation message? It's much more clear to just have one set all the time.

David_Rothstein’s picture

If you haven't set any webform properties or the $node->webform['confirmation'] field, then it doesn't even matter at all what the confirmation format is because there's not even a message at all.

It can matter. Let's say it's the administrator as the current user during the node_save() operation, and they have Full HTML as their default format. So Full HTML would get automatically saved with the webform. But that means some other lower-level person won't be able to edit it, even though its content is empty and isn't actually Full HTML.

The idea that you'd have "NULL" confirmation format very confusing. Does that really mean "plain text" if the format is NULL and there's a confirmation message?

I think NULL makes sense because it means "no format yet" - which is exactly the case. The person saving the node or building up the form array is saying that the content doesn't exist yet and therefore doesn't have a format (because it's only when you decide what the content is that it makes any sense to decide what format it needs to be displayed in). It's totally neutral; i.e. no preference is being pre-assumed before the content exists.

If you wind up with content in the confirmation message but the format still NULL, that would be a bug in whatever code caused that to happen. In that case, check_markup() does treat it as plain text, yes, but only because that's the safest fallback.... I've started to wonder if check_markup() shouldn't reject it altogether (like it now rejects content stored with a format that doesn't exist), but it's too late for that idea in D7.

quicksketch’s picture

If you wind up with content in the confirmation message but the format still NULL, that would be a bug in whatever code caused that to happen.

I don't see how you're arguing that NULL should be the default for node_save(), yet not specifying one would be a bug. If you're using node_save() (as administrator) you can just set $node->webform['confirmation_format'] to whatever you want. If you were an administrator creating a node through the interface, obviously the administrator's default would be used at the default in that situation also.

My point here is that all nodes have a format set at all times for the body field and all other fields, it shouldn't be any different with Webform.

David_Rothstein’s picture

I'm saying that if you specify something for $node->webform['confirmation'] and don't also specify something for $node->webform['confirmation_format'], that's a bug. But it's fine not to specify either.

In core, fields and everything else are now using NULL as the default value for the #format (for fields, see http://api.drupal.org/api/drupal/modules--field--modules--text--text.mod...). It's been like that for a while in some places, but #358437: Filter system security fixes from SA-2008-073 not applied to Drupal 7.x was the issue where it got completely standardized. So this patch doesn't introduce anything new that is only happening in Webform; it all mirrors the current pattern in D7 core, AFAIK.

quicksketch’s picture

After reviewing the D7 changes I have to agree you're right. It's just a little weird to me that confirmation_format stays NULL until the user goes to edit the node. It does make sense... but it's just a bit different in thinking. So anyway that all looks fine to me. Let's just get the unnecessary isset() check out and everything else looks fine.

David_Rothstein’s picture

Status: Needs work » Needs review
FileSize
5.77 KB

OK, great. Here is the updated patch.

fietserwin’s picture

Status: Needs review » Needs work

I ran this patch against the 7.x 3.6 version.

- the update numbers (7306 and 7307 need to be increased, as 7306 is already in use now.)
- after changing them, the update ran successful
- I tested the "form settings" form (node/%nid/webform/configure)
- before: the text format for the "Confirmation message" would not be saved (trying to store a text in a tiny int)
- after running the patch and update, the text format for the "Confirmation message" is saved and used as expected

So for me this patch worked fine, as far as running into the issue of that text format not being saved,

David_Rothstein’s picture

Status: Needs work » Needs review
FileSize
5.77 KB

Rerolled the patch with the latest update function numbers.

thetechguide’s picture

Status: Needs review » Reviewed & tested by the community

I tested this patch and it did solve the text format change not being saved problem, and also the problem reported at http://drupal.org/node/1011668 as well. Thanks for the patch!

jim_at_miramontes’s picture

Thanks much -- the patch also worked for me. Reminder to future visitors: You'll need to run update.php after installing the patch, since a big part of the patch is a database update.

quicksketch’s picture

Version: 7.x-3.x-dev » 7.x-3.6
Status: Reviewed & tested by the community » Fixed

Thanks David, committed!

Frits1980’s picture

Hmm, using webform 3.6 on D7.
After this patch I get this:
PDOException: SQLSTATE[HY000]: General error: 1366 Incorrect integer value: 'plain_text' for column 'confirmation_format' at row 1: UPDATE {webform} SET confirmation=:db_update_placeholder_0, confirmation_format=:db_update_placeholder_1, redirect_url=:db_update_placeholder_2, status=:db_update_placeholder_3, block=:db_update_placeholder_4, teaser=:db_update_placeholder_5, allow_draft=:db_update_placeholder_6, submit_notice=:db_update_placeholder_7, submit_text=:db_update_placeholder_8, submit_limit=:db_update_placeholder_9, submit_interval=:db_update_placeholder_10 WHERE (nid = :db_condition_placeholder_0) ; Array ( [:db_update_placeholder_0] => Bedankt [:db_update_placeholder_1] => plain_text [:db_update_placeholder_2] => <confirmation> [:db_update_placeholder_3] => 1 [:db_update_placeholder_4] => 0 [:db_update_placeholder_5] => 0 [:db_update_placeholder_6] => 0 [:db_update_placeholder_7] => 0 [:db_update_placeholder_8] => Verstuur je aanvraag [:db_update_placeholder_9] => -1 [:db_update_placeholder_10] => -1 [:db_condition_placeholder_0] => 4 ) in drupal_write_record() (line 6776 of /includes/common.inc).

David_Rothstein’s picture

@Frits1980: You probably need to run update.php.

Frits1980’s picture

I take it back... I was looking with the wrong set of eyes or something... :S
Was still running 3.4-beta.

Sorry for the inconveniance.

quicksketch’s picture

This change isn't yet in 3.6 yet anyway, it'll be in 3.7.

blackdog’s picture

Sorry to hog a fixed issue, but this is badly needed, so any ideas when can we expect a new release? Or maybe publish a dev release?

bwill’s picture

I am having the issue described by this ticket and I tried to apply the patch provided in #10 using Patch.exe, but it is failing. I tried to get help in the forum after reading the manual on patching but was only referred back to the manual. I am not familiar with patching at all. In the form settings, I try to save the conf message as full HTML and set the advanced option to show the form in a teaser and get error: Notice: Undefined index: 0 in ckeditor_profiles_compile() (line 424 of C:\wamp\www\JustRightBiking\sites\all\modules\ckeditor\includes\ckeditor.lib.inc).

I don't know if this is a windows7 (64 bit) issue. Can you point me to a good patching tool or just a patched module folder?

quicksketch’s picture

Sorry to hog a fixed issue, but this is badly needed, so any ideas when can we expect a new release? Or maybe publish a dev release?

You can always get the dev release by clicking "View all releases". I'll be making a new official release in the next week or so.

Status: Fixed » Closed (fixed)

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

sweo’s picture

Version: 7.x-3.6 » 7.x-3.9
Status: Closed (fixed) » Needs work

While Updating webform module to 7.x-3.11 get this error again in update 7307:

PDOException: SQLSTATE[HY000]: General error: 1366 Incorrect integer value: 'plain_text' for column 'confirmation_format' at row 1: ALTER TABLE {webform} CHANGE `confirmation_format` `confirmation_format` INT unsigned NULL DEFAULT NULL COMMENT 'The filter_format.format of the confirmation message.'; Array ( )

Issue still there in Version 7.x-3.11.

Here is the solution:

File: webform.install

/**
 * Update the confirmation_format column for default text format changes.
 */
function webform_update_7307() {
  // These changes are modeled after user_update_7010().
  db_change_field('webform', 'confirmation_format', 'confirmation_format', array(
    'description' => 'The {filter_format}.format of the confirmation message.',
    'type' => 'int',
    'unsigned' => TRUE,
    'not null' => FALSE,
  ));

Should be:

/**
 * Update the confirmation_format column for default text format changes.
 */
function webform_update_7307() {
  // These changes are modeled after user_update_7010().
  db_change_field('webform', 'confirmation_format', 'confirmation_format', array(
    'description' => 'The {filter_format}.format of the confirmation message.',
    'type' => 'varchar',
    'length' => 255,
    'not null' => FALSE,
  ));
quicksketch’s picture

Thanks sweo, this problem arises when you update from Drupal 6 to 7, add a new text format (or rename an existing one), then upgrade Webform later. If upgrading Webform immediately after upgrading Drupal core, this problem shouldn't occur.

In any case, still an important thing to fix.

David_Rothstein’s picture

Ah, yes, when I wrote those functions originally it was for the D6->D7 upgrade, but then there was an official D7 Webform release in the interim and I didn't think about the implications of that right before this got in.

I don't think there's any way to make that update function safe for a site that started off on D7. For example, the part that uses variable_get('filter_default_format') makes no sense for a D7-only site since that variable doesn't exist.

Probably the thing to do here is just renumber it to webform_update_7300() instead, so that it only runs for sites upgrading from D6? Or actually, looking at the surrounding functions, possibly just replace the contents of webform_update_7301() with the stuff from 7307 instead. Because the current contents of 7301 aren't needed anymore given what runs afterwards:

function webform_update_7301() {
  db_change_field('webform', 'confirmation_format', 'confirmation_format', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0));
}
podarok’s picture

the same trouble for updating from 3.8 to 3.11

root@ns2:/home/***/public_html# drush updatedb
The following updates are pending:

webform module : 
  7307 -   Update the confirmation_format column for default text format changes. 
  7308 -   Update the confirmation_format column to allow it to store strings. 
  7309 -   Add the ability to auto-save as draft between pages. 
  7310 -   Remove orphaned and unnecessary rows in the webform table. 
  7311 -   Add an index for sid_nid_uid to webform_submissions. 

Do you wish to run all pending updates? (y/n): y
SQLSTATE[HY000]: General error: 1366 Incorrect integer value: 'full_html' for column 'confirmation_format'  [error]
at row 1
Finished performing updates. 

removing 7307 update fix update path
so error is in 7307

quicksketch’s picture

Status: Needs work » Fixed
FileSize
3.13 KB

Although it doesn't seem like this has affected too many users (there are only about 300 sites reporting using a version prior to 3.9 even now), this patch should fix the problem by taking the recommendation of David in #24. Since webform_update_7301() isn't needed in D6->D7 upgrades any more, we can move webform_update_7307() directly into its place since it effectively replaces the need for that change anyway. Then users upgrading from versions prior to 3.9 can upgrade to the latest release without webform_update_7307() throwing errors.

Status: Fixed » Closed (fixed)

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

mshepherd’s picture

Version: 7.x-3.9 » 7.x-3.18
Priority: Major » Normal
Status: Closed (fixed) » Active
FileSize
8.28 KB
3.47 KB

Maybe I'm completely missing something here, but whatever I do, field descriptions seem to be filtered through filtered_html.

On admin/config/content/formats Full html is listed first & I gather that makes it the default. I've also set filter_fallback_format to full_html which makes it the fallback filter format.

From the component field settings page:
component field description setup, with <p>, <h2> and <strong> tags

As rendered:
rendered without <p> and <h2> tags

All but the <strong> tag is filtered out.

David_Rothstein’s picture

Version: 7.x-3.18 » 7.x-3.9
Priority: Normal » Major
Status: Active » Closed (fixed)

That would be a new feature - Webform descriptions don't use the text format system (at least not as far as I know) but rather go through filter_xss(). (And any time something does use text format system, there should always be a text format selector, rather than silently guessing that the first format in the list is the one that should be used; but you can see from above that the text format selector isn't there.)

It looks like you could set the 'webform_allowed_tags' variable if you want to change the default list of tags that it filters by, though.

This issue was about updating the places where Webform actually does use the text format system, e.g. confirmation messages and markup fields and the like.

David_Rothstein’s picture

I've also set filter_fallback_format to full_html which makes it the fallback filter format.

And oh.... never do this! (Or at least, almost never.) The fallback format is automatically available to all users who can create content, so if you have any non-trusted users on this site who are allowed to create content (even comments), by setting this to an unsafe format like Full HTML you've just allowed them all to perform cross-site scripting attacks.

mshepherd’s picture

David, thanks for the tip. I knew that already, I was just trying things out. It's already reset to default.

And on your other point, I've achieved what I needed to do using markup components.

Thanks.