I am running 6.x-29 and when I switched to PHP 5.4 I started getting an error on my one node add form for a field thats Granularity is set to year and the default value is set to now with no "To Date".
I did some searching and I could not find another issue that seems to be related.
It looks like _form_set_value
is expecting form_values to be an array and is receiving a date formated string EG: '2013-05-26 13:41:06'.
I tried to trace the root of the problem but I was unsuccessful.
Any help or direction would be greatly appreciated.
Comment | File | Size | Author |
---|---|---|---|
#26 | date-illegal-string-offset-2004508-26.patch | 1.56 KB | roderik |
#15 | illegal_string_offset_date_fix.patch | 4.18 KB | pvgoran |
Comments
Comment #1
EvaldsUrtans CreditAttribution: EvaldsUrtans commentedIt can be fixed using patches from this thread https://drupal.org/node/1808416
Comment #2
davidhk CreditAttribution: davidhk commentedI have the same problem since updating to php 5.4. Have you found any way to solve the problem?
The suggestion at #1 refers to the date_popup module. That module is disabled on my site.
I see the same error message when I edit a node that has a date field with granularity set to year. However, the error isn't displayed when I create a node, perhaps because I do not have any default date set.
A backtrace shows the same problem you describe. (Apologies if I get the syntax wrong below, but I hope the message is clear) As _form_set_value(&$form_values, $form_item, $parents, $value) is building up $form_values, the first time it is called on the date field, $parents is:
So it is trying to build up [field_date_completed][0][value][date]
But when it is building [field_date_completed][0], it is assigned an array
Note that [field_date_completed][0] now has an array element [value], that is a string.
When _form_set_value recurses down to the final line of $parents, "[3] => date", it runs the code:
$form_values[$parent] = $value;
That's trying to set:
[field_date_completed][0][value]['date']= "1897-01-01 00:00:00"
at which point it throws the error, because [field_date_completed][0][value] is already a string.
The strange thing is that it still works - I can create / view / edit / update the node ok but it displays red warning messages to users. I'm wondering if there is some bug hidden in the code that just got handled ok by accident with php 5.3?
I'm not sure where to look next. Any pointers welcome.
Comment #3
davidhk CreditAttribution: davidhk commentedI've edited _form_set_value in form.inc to change
to
It just masks the problem rather than solving it, but that's all I need for now until I can upgrade to D7.
Comment #4
nekobul CreditAttribution: nekobul commentedHi David,
The modification you've made in form.inc was the right move. I did review the D7 implementation of drupal_array_set_nested_value function and decided to make _form_set_value function similar and lo and behold it works fine now. The newer implementation is actually better because it doesn't use recursion to accomplish the same result. Here is the modified function:
Comment #5
jennifer.chang CreditAttribution: jennifer.chang commentedSame here.
Comment #6
rakun CreditAttribution: rakun commentedWill this be included in the new release?
Comment #7
mtcs CreditAttribution: mtcs commented#4 works for me. Thanks.
Comment #8
SocialNicheGuru CreditAttribution: SocialNicheGuru commentedComment #9
akbardhedhi CreditAttribution: akbardhedhi commentedThe issue seems to be as davidhk describes, therefore I have modified the field to return an array of date parts. Please find attached patch.
Comment #10
SocialNicheGuru CreditAttribution: SocialNicheGuru commentedComment #12
rooby CreditAttribution: rooby commentedThat patch doesn't apply with "patch -p1" and it also has a space at the front of the file name.
Comment #13
japerryHere is a re-roll of that patch.
Comment #15
pvgoran CreditAttribution: pvgoran as a volunteer commentedI'm using Drupal 6, and while upgrading PHP from 5.3 to 5.5/5.6 I encountered this problem. I applied the patch from the comments above, but it broke the date functionality for me. So I ended up reworking it with a different approach: enclosing date_text/date_select element #value's in an array rather than converting them to DATE_ARRAY type. (I [b]hope[/b] this makes at least some sense to anyone; I have almost no idea of how Drupal widgets/forms/CCK work, and I don't know how to call things properly.)
The patch against the 6.x-2.x branch is attached. It works fine for my use cases (a text widget and a select widget, both single-value, without "date to" component). If anyone tries it and it turns out to break things, please let me know.
Comment #16
texas-bronius CreditAttribution: texas-bronius commented@pvgoran - Thanks for the 6.x patch! What date module version are you using? I had what appears to be the same issue using date 6.x-2.7 on php 5.6, but updating to date 6.x-2.10 shows the date values again (see https://www.drupal.org/node/70963/release?api_version%5B%5D=87) sans patch.
Comment #17
pvgoran CreditAttribution: pvgoran as a volunteer commentedI'm using 6.x-2.10. I didn't have problems with date values not being shown; I had warning that were shown at the top of "edit node" pages, and the patch is supposed to fix these warnings.
Comment #18
Fernando Iglesias CreditAttribution: Fernando Iglesias commentedUnfortunately the patch in #15 doesn't seem to fix the issue for me (Date 6x-2.10). I'm seeing the errors when trying to use an exposed date filter in views.
I'll try and fix it, will report back with a patch if I figure it out.
Comment #19
kliker CreditAttribution: kliker as a volunteer commented#3 works for me, tested with select widgets on create/edit nodes.
#15 worked for all but 'timezone':
warning: Illegal string offset 'timezone' in /includes/form.inc on line 1429.
PHP 5.5
Drupal 6.38
Date 6.x-2.10
Comment #20
GoldI was just about to reroll this patch against 7.x-2.x and in the process of verifying that it's still an issue I found I couldn't replicate the errors.
Can someone else test the 7.x-2.x branch and verify that the errors no longer appear?
Comment #21
DamienMcKennaI don't like nesting the default value like this, it seems unnecessary.
Comment #22
izmeez CreditAttribution: izmeez commentedWith the latest date module 2.11 version, with or without the patch from comment #15, there is a residual warning as described in comment #19
The suggestions in both comment #3 and #4 work to eliminate the warning but may be masking the warning as suggested in comment #3. Doing so may be useful for D6 LTS to address other contrib modules #3026754: [core] form.inc helper function commit needs work and may also be a satisfactory solution for the timezone warning or it may be possible to fix the source where it is coming from possibly in the date module.
Comment #23
izmeez CreditAttribution: izmeez commentedThere may be very few people left interested in this issue or the related issue #2090389: Date: warning: Illegal string offset in form.inc on line 1345..
Here's my take after recently poking around here, again.
This issue thread covers 3 items.
1. In comment #3 and #4 were suggestions for a fix at the form.inc helper function rather than at the source of origin. There was concern this would just mask the issue at origin. However, in comment #4 an improvement to the helper function is included that eliminates recursion and is modeled along drupal 7 lines. It also includes brief comments to explain the php behaviour and this could be adjusted. Since the form.inc helper function has also been modified in the D6LTS project I have opened #3026754: [core] form.inc helper function commit needs work for further discussion.
2. The issue warning: Illegal string offset 'date' in /includes/form.inc
This is also described in #2090389: Date: warning: Illegal string offset in form.inc on line 1345. which has the identical patch as in comment #15 of this thread and has been closed as a duplicate although it included observation of issues export and cloning.
As described in that issue, the warning is seen when using the date select widget either in a content type or a views exposed filter.
To reproduce the warning(s) create or edit a content type that includes a datetime field with the date select widget, such as an event.
The patch in #15 is no longer needed with date 2.11 even though it can be applied. I am unable to reproduce the warning in tests I have done.
With date-2.11 warnings are not seen with php 5.6 or 7.2 and the fix may be the result of recent commits, https://github.com/d6lts/date/commits/6.x-2.x
3. The timezone, warning: illegal string offset described in comment #19 above was observed when the patch in #15 was applied and is still present with date-2.11 without the patch and would be masked if the solutions in item 1 were used.
Again, this can be reproduced as above for the date warning when creating or editing content type with date select widget that also includes the timezone select widget.
The fix for this is an easy drupal configuration in the field settings, change field time zone handling as described https://www.freelock.com/blog/john-locke/2014-12/drupal-dates-timezone-o...
Looking at the settings that were present and seeing it was set to Date's timezone, changing it to Site's timezone, or User's timezone, eliminates the warning. It is worth noting the Drupal UI warns that changing this can result in loss of existing data so do this on a test server! And the blog post goes on to explain the need and how to update the database.
The whole issue of Drupal's handling of date timezones has been ongoing for years, in several issues, and recently a fix advanced for Drupal 8.5 #2627512: Datetime Views plugins don't support timezones and is ongoing for drupal 7 #998076: Problem with timezone handling (caused by date_get_timezone_db returning only UTC), there maybe something there that can help. In particular the comment #998076-7: Problem with timezone handling (caused by date_get_timezone_db returning only UTC) includes a patch and insightful comments.
Hope this helps.
Comment #24
benkewell CreditAttribution: benkewell commentedFor those who need a simple fix to get rid of the illegal string offset warning without digging deep into codes is to simply replace function _form_set_value() in Drupal file includes/form.inc with this version:
This is the latest PHP7 compatible version from D6LTS (https://github.com/d6lts/drupal/),
with a small change to rewrite "$form_values[$parent] =" as "@$form_values[$parent] =",
to hide the anonying warning message produced by date_select element.
Date 2.11 release from D6LTS does not solve the issue for me.
This version of _form_set_value() on PHP 5.4+ will behave identically to Drupal 6 default on PHP 5.3, tested on production website.
Comment #25
roderikThis warning in PHP5.4 is now turning into a fatal error in PHP8.
This error does not happen in D7 anymore... because
form_set_value() -> drupal_array_set_nested_value()
has been changed in D7 to bluntly override form values set in the below way. (The change occurred as a side effect in #745590-24: #managed_file element does not work when #extended not TRUE, or when ancestor element doesn't have #tree=TRUE and I cannot find anyone commenting on this behavior change. It arguably obfuscates potential errors, but it's no use arguing that by now.)Because of this / the fact that my patch won't have benefits for D7, I'm changing project / title.
Problem description
The date module has an 'interesting' way of nesting form items, which creates trouble.
For example if the date input is a text element,
Why does this throw an error? It instructs the form API to (during form build) first set $form_state['values']['field_<name>'][0]['date'] to the date (string) value, and after that, set $form_state['values']['field_<name>'][0]['date']['date'] to that same string value. That is obviously going to go wrong: the form API is explicitly instructed to use a string value as an array.
(
Why does the date module do it like this? Apparently because
This has all kinds of interesting effects for form/element validation which we luckily don't need to go into.
)
How to fix the error:
We can hack the #process functions to remove the parent element's
$element['#value']
if it is a string, just after it has been copied into the child elements and just before it gets passed intoform_set_value()
. We are sure that immediately after that, all child elements' values get passed intoform_set_value()
too, so this doesn't really have side effects besides getting rid of the error.The code in element validate functions makes implicitly clear that
$element['#value']
is only a string when the form is first built, not when it is submitted. This figures, because otherwise, form validation would likely have seen errors after theform_set_value()
calls had strange results. Also... this is lucky for us, because if we had needed to empty out$element['#value']
during form submission... there would be many more places to fix. (I tested. It's a rabbit hole.)Comment #26
roderikActually, after significantly reducing some code changes I'd done while testing... I think these 3 copies of code comments are just overkill. Stripping them down.
(Edit: that six-line comment still reads crappily. I can trim it down or reword it it a reviewer/committer wants me to.)
Comment #27
DamienMcKennaComment #28
izmeez CreditAttribution: izmeez commented@roderik Thank you for your investigation and detailed comments. It has been a couple of years since I looked at this issue.
In my last comment #23 it appeared as though with date 6.x-2.11 item #3
was the residual problem and the solution was to review the timezone setting and if it is set to the Date's timezone
although this may require updating the database as described in the blog post referenced in that comment.
I have not had time to review and test your patch to confirm if it addresses the timezone issue in particular. I'm not even sure if I have a test site configured with the Date's timezone to test this.
Comment #29
roderik@izmeez my patch addresses the issue with the 'timezone' element/warning too; it has the same cause. (I forgot to explicitly mention that, after going in a few circles around the solution.)
Comment #30
izmeez CreditAttribution: izmeez commentedThe patch in #26 applies without difficulty to D6LTS date-6.x-2.11 and appears to be working fine. The patch looks remarkably simple but I would defer, and hope, that maybe @DamienMcKenna might comment on the code as a maintainer of the date module, although he may not be actively doing that for the 6.x branch.
Comment #31
DamienMcKennaI cannot speak to the 6.x-2.x branch, it has been far too long since I last looked at D6's Field API to comment on the patch, I defer to roderik's research on the matter.
Comment #32
izmeez CreditAttribution: izmeez commentedWell, I guess it's back to me. Testing this patch reveals no problems, the code looks remarkably simple and the explanation in #25 is illuminating. Changing status to RTBC.
Comment #33
roderikRe. #31 just for completeness: this is plain Form API (which hasn't changed between D6-D7). Regardless of whatever changed between CCK and FieldAPI, here's the summary:
I dived into it more, but in the end was happy to conclude that the fix could tiptoe around all the interesting string-vs-array manipulations in those element #process / #validate functions.
The patch should also apply to D7, but D7's form_set_value() is modified and doesn't warn/fail, so there's no real difference there.
Comment #34
dsnopekWow, thanks, everyone! @roderik's patch works great in my testing.
I've committed it to https://github.com/d6lts/date:
https://github.com/d6lts/date/commit/f368386a2d3b66c03c6deb21b2f3a99ff7c...