Problem
The implementation of the theme_textfield hook throws a fatal PHP error when the field is an autocomplete field. The issue exists in the stable version and in the dev version also.
You can reproduce the error submitting a form that contains an autocomplete field. It does not matter if the field is optional or required or if it has been leaved blank o has been filled.
When the function drupal_attributes is called the first time inside the bootstrap_textfield function, it converts de ['#attributes']['class'] array into a string, overwritting its original value (See the &$data below).
function drupal_attributes(array $attributes = array()) {
foreach ($attributes as $attribute => &$data) {
$data = implode(' ', (array) $data);
$data = $attribute . '="' . check_plain($data) . '"';
}
return $attributes ? ' ' . implode(' ', $attributes) : '';
}
This function is called on the line 22 of the /themes/system/textfield.func.php file (Or /templates/system/textfield.php of the dev version).
After this, if the field is an autocomplete field, bootstrap_textfield tries to add a new class to the field on line 27, and the fatal error is thrown, because the ['#attributes']['class'] value is now a string.
Proposed resolution
Assigning the value of $element['#attributes'] to a variable before passing it as a parameter when calling drupal_attributes should fix the issue.
| Comment | File | Size | Author |
|---|---|---|---|
| #5 | bootstrap-textfield_class_fatal_error-2566595-5.patch | 693 bytes | tucho |
| #5 | bootstrap_dev-textfield_class_fatal_error-2566595-5.patch | 709 bytes | tucho |
Comments
Comment #2
markhalliwellThe entire function needs to be refactored. Closing in favor of this related issue.
Comment #3
markhalliwellAlso, I'm not sure why you're getting a "fatal", but it's not because of drupal_attributes(). It doesn't alter the existing attributes array (i.e. it's not a referenced variable). So, it must be a string to begin with (e.g. what you or some module is providing).
Comment #4
tuchoThe problem arraise when drupal_attributes is called.
I just modified the code inside bootstrap_textfield and added some print_r (Yes, that's awful but it works for this ;) ) before and after the call to drupal_attributes on line 22:
And the output before the call is:
And after:
I also remove the function bootstrap_textfield, so the original theme_textfield is executed and the issue is not present.
May be, because on that function drupal_attributes is the last thing to get called?
Finally, I change my PHP version from PHP5.4 to PHP5.2 and the problem is still there.
Comment #5
tuchoI tried assigning $element['#attributes'] to another variable, but the problem persists.
Finally, I create a new array and copy the values from $element['#attributes'] with a foreach loop. Then I call drupal_attributes with the new array.
I attach two patches:
Version 7.x-3.0: bootstrap-textfield_class_fatal_error-2566595-5.patch
Version 7.x-3.x (dev): bootstrap_dev-textfield_class_fatal_error-2566595-5.patch
Comment #6
markhalliwell#4 shouldn't be possible, like at all...
drupal_attributes()does not use $attributes as a reference (source). For example:The actual function signature:
function drupal_attributes(array $attributes = array())Is not:
function drupal_attributes(array &$attributes = array())(notice the
&at the beginning of $attributes).The only thing I can think of is that you've somehow modified drupal_attributes() directly to include this (or there's something else going on here), because core doesn't behave like that out-of-the-box.
http://php.net/manual/en/language.references.pass.php
Comment #7
tuchoI know what you mean, but I'm working on a clean core and the output that I have posted on #4 is the one I'm getting.
My drupal_attributes function is the one of my initial post.
Comment #8
markhalliwell&$dataisn't the culprit as$attributesis never passed by reference in the first place.&$dataonly modifies the$attributescopy only, not$element['#attributes']in the calling function.Furthermore, looking at your "after" output, you'll see that only class is modified, not any of the other attributes. It should have returned for instance:
I imagine that whatever is going on is just a local occurrence as I have never encountered this issue.
Comment #9
tuchoYes, I have seen that too.
I'm making a new deploy to check again why is this happening.
Thank you for your time. I will see #2566541: Update theme_textfield to be in line with core 7.39 now and make a patch for the update, to help a little and pay back for it ;)