I've just encountered an issue where the validation of the Source code for a webform fails to catch a misconfiguration on a Radio element resulting in a PHP error. It looks like this misconfiguration isn't being caught when validating the source code after saving.
It seems to happen only when adding the element to the Source view rather than adding it as an element and then editing it in Source view. I have not tested whether the issue also occurs on other element types.
I encountered this issue on a site with beta19, and then recreated it on another site with beta23.
To recreate the error, try adding the following element via Source to an existing form.
charges:
'#type': radios
'#title': Charges
'#options':
if_free: 'I want this item only if it is free'
check_first: 'Please advise me of any cost'
will_pay: 'I will pay any cost'
'#required': true
It seems that with the '#required' element being indented 4 spaces instead of 2, it gets treated as another radio option. It is added as the value for the new option (including the #) but the title is left empty.
This causes a 500 error when you visit the form, with this in the log:
PHP Fatal error: Unsupported operand types in /var/www/html/mysite/web/core/lib/Drupal/Core/Render/Element/Radios.php on line 68, referer: http://mysite.com/admin/structure/webform/manage/contact/source
Once this happens, the only way to resolve it is to return to the Elements view and delete the element.
You can't simply fix it in Source view - the error keeps occurring, and editing the element in Elements view doesn't work because it seems that this issue also breaks Drupal's Ajax on the page, meaning that you can't save your changes when editing the element (you also can't edit or add any other elements for that form).
Comment | File | Size | Author |
---|---|---|---|
#8 | source_validation_fails-2922331-8.patch | 2.52 KB | jrockowitz |
| |||
#4 | source_validation_fails-2922331-4.patch | 2.08 KB | jrockowitz |
| |||
#2 | source_validation_fails-2922331-2.patch | 709 bytes | jrockowitz |
|
Comments
Comment #2
jrockowitz CreditAttribution: jrockowitz as a volunteer and at The Big Blue House commentedI was also randomly seeing this issue and did not figure out that is specific to PHP7 until now.
The attached patch should catch the exception being thrown.
Comment #3
millionleaves CreditAttribution: millionleaves as a volunteer and commentedThanks - much appreciated.
However, it looks like the patch only addresses PHP7, which neither of my sites are running. One is on PHP 5.5.9 and the other is on 5.6.31. I tried the patch in the latter, but it didn't fix the issue.
Comment #4
jrockowitz CreditAttribution: jrockowitz as a volunteer and at The Big Blue House commentedThe attached patch still works for PHP7 but I need you to check 5.6.
Comment #5
millionleaves CreditAttribution: millionleaves as a volunteer and commentedThanks again.
I couldn't apply the patch using my normal method - not sure why:
patch -p1 < source_validation_fails-2922331-4.patch
I applied the changes manually, but the behaviour on saving the malformed element is unchanged on PHP5.6.
Comment #6
jrockowitz CreditAttribution: jrockowitz as a volunteer and at The Big Blue House commentedI am not up for downgrading my dev environment to PHP 5.6. Someone is going to have step in and tweak the patch.
I will probably commit the patch because it does improve the overall exception handling because it now uses restore_error_handler() and restore_exception_handler().
Comment #7
millionleaves CreditAttribution: millionleaves as a volunteer and commentedThanks. I have another site on the same server where I can try the patch again later. Otherwise, at least we have the issue understood and a workaround provided.
Comment #8
jrockowitz CreditAttribution: jrockowitz as a volunteer and at The Big Blue House commentedThe attached patch adds more inline comments to help explain what is going on to any reviewing this code and hopefully helping us fix the issue in PHP 5.6.
Comment #10
jrockowitz CreditAttribution: jrockowitz as a volunteer and at The Big Blue House commentedI committed the patch. I am marking this issue as postponed hoping someone with PHP 5.6 can help.
Comment #11
jrockowitz CreditAttribution: jrockowitz as a volunteer and at The Big Blue House commentedComment #12
millionleaves CreditAttribution: millionleaves as a volunteer and commentedSteps to reproduce on a site running PHP 5.6.32, Drupal 8.4.2, Webform 8.x-5.0-beta24.
↵An AJAX HTTP error occurred.↵HTTP Result Code: 500↵Debugging information follows.↵Path: /admin/structure/webform/manage/contact_us/element/message/edit?_wrapper_format=drupal_modal&ajax_form=1↵StatusText: Internal Server Error↵ResponseText: "
I tested this with and without the patch in #8. The only solution appears to be to remove this component.
[edited for formatting]
Comment #13
jrockowitz CreditAttribution: jrockowitz as a volunteer and at The Big Blue House commentedI recommend that everyone start upgrading to PHP 7. @see #2842431: [policy] Remove PHP 5.5, 5.6 support in Drupal 8.7
Patches to support PHP 5.6 are welcome but most Drupal devs are probably using PHP 7
Comment #14
jrockowitz CreditAttribution: jrockowitz as a volunteer and at The Big Blue House commentedComment #15
bucefal91 CreditAttribution: bucefal91 at Websolutions Agency commentedThat's the kind of moment when I praise my Gentoo Linux 8-) Switching PHP versions is dead easy there.
millionleaves, my experience is a little bit different from yours. I am running PHP 5.6.33. Everything I describe below is done on the latest webform 8.x-5.x-dev
So, if I submit the following (let's call it case #1):
It dies with a PHP fatal error, but it does not save the messed up Yaml into database, so just hitting the "back" button gets you back in business as if you never submitted malformed Yaml.
Then I tried (let's call it case#2):
It just shows me a nice form validation error message that reads: Elements (YAML) is not valid. Unable to parse at line 7 (near " '#required': true").
For the case #1: the submitted Yaml syntax is correct, but the way Webform then tries to leverage the parsed Yaml brings to a PHP fatal error. Thus this case contains not a syntax but a logical error (the option
#required
should have a string value but it has a boolean value.) It's not easy to build a logical validator, and basically, it's more of a developer user interface. One is expected to know the rules of the game once he crosses the boundary between a user and a developer. Additionally, catching fatal errors in PHP 5 is barely possible and using my judgment it's not worth the effort in this case.For the case #2: It behaves very good - you supply a malformed Yaml (syntax error) and it warns you in a very user-friendly way.
millionleaves, can you try the 2 cases on the latest webforms? maybe something has changed? Side effects of this bug as you describe definitely should be fixed somehow, but the side effects I've encountered myself while testing seems much less hurtful and are not so easy to fix. So I want to see maybe I am missing something to bring the side effects to the level of yours :)
Comment #16
jrockowitz CreditAttribution: jrockowitz as a volunteer and at The Big Blue House commentedI am marking this as won't fix since PHP 5.6 is not actively supported and this is not a showstopping issue.
@bucefal91 I think the nuance of this bug is some people have the native PHP-YAML add-on installed which Drupal will use. If the PHP-YAML add-on is not installed Drupal falls back to Symfony's built-in YAML parser.