Background for the uninitiated:
form_builder_cache_load() is the function kind enough to retrieve the db sync'd copy of the form we're building with form_builder. The function is pretty simple, but as I'm just now starting to hunt this bug, this is my starting point (though I don't think it's the culprit).
For me this manifests within the webform implementation of form builder. As you add/alter elements, the functions that keep these sync'd to the form_builder_cache table seem to get confused. What you expect to be there is still on the screen as expected, however once saved, the screen renders something very different. In many cases I'll lose many fields (often all but the most recently edited). Initially I thought this had something to do with the way webform handles form elements (i.e. they're all stored in $form['submitted']) however, after quite a bit of testing, I think my initial test were just too narrow. Initially I had no difficulties adding new elements moving, saving. Somewhere along the way that's been complicated and I'm now often losing the elements I create. I've run tests on the example module and it has the same problems, so I'm pretty sure it's webform core and not just my own implementation that has this problem.
Priorities:
I'll be testing form_builder_cache_load() and the various field saving/updating mechanisms a bit more intensely to see if I can find what's causing this. Hopefully it's php related, and not js related. I'll be hard pressed at the moment to find the bug if it's in the js.
| Comment | File | Size | Author |
|---|---|---|---|
| #9 | form_builder_key_change.patch | 919 bytes | quicksketch |
Comments
Comment #1
quicksketchI've noticed Form Builder getting confused about form cache early in the development. I haven't been able to reproduce it reliably though. I think it has to do with the creation and deletion of nested Fieldsets, but again, I haven't found the exact cause yet, maybe your problem is something different.
Comment #2
eclipsegc commentedthe email I sent you yesterday outlined how I reproduce the error (fairly reliably) and it does include a nested fieldset. However, I think the issue may be fieldsets in general, and in many cases when I save, I don't end up w/ any fields in the fieldset afterwards.
Comment #3
quicksketchIt shouldn't even be necessary to save, the cache itself is getting messed up. So we should be able to create the problem simply by dropping in a couple of fieldsets, then reloading the page.
Comment #4
eclipsegc commentedafter a bit of playing with this I think I've found the culprit.
Before some of our conversations I didn't have form key altering working. During this time everything was working flawlessly. After enabling form key alterations, I became subject to the same errors that were showing up elsewhere. I didn't immediately put 2 and 2 together, but after looking through the code for a while, I came upon form_builder_set_element() and it's code to change the form key. I'm pretty sure this is our problem:
I just a built a fairly extensive webform w/o altering any of the form keys and had no hiccups at all. Let me know if this is true for you as well.
Eclipse
Comment #5
eclipsegc commentedalso worth noting, a much simpler test that included key changes blew up immediately. I THINK this might be the culprit.
Comment #6
eclipsegc commentedI'm pretty sure it should be:
However, I think there might still be issues with the slicing as this alteration does not fix the bug (though $index is now set to something, as opposed to nothing).
Still trouble shooting, might have to get my debugger working... :-S
Comment #7
tobby commentedI see this issue, and the issue with the cache itself getting messed up when I am dealing with a very large form. The form_builder_cache table is using a blob for the data column, which has a limit of 64k (65,535 bytes). My form, when $form is serialized, is larger than 64k, and so when the table is updated, the serialized string is truncated.
Updating the table to use a mediumblob (16,777,215 bytes) eliminates that problem for me.
Comment #8
quicksketchAs I haven't had any specific reports of this (other than the large cache size, there's a separate issue for that) and there isn't anything actionable in this issue, I'm closing it. As Acquia has been using Form Builder for months now, I don't think this problem still exists. Please open a new issue after I've made the new 1.0 beta releases.
Comment #9
quicksketchI *FOUND* the problem! You were absolutely right! I'm guessing Acquia hasn't run into the problem because they don't allow you to change the form element keys in Gardens. You were spot-on with the problem, which originated in the call to array_search(). What I had intended array_search() to do was to return an integer value, indicating where in the array we should base our offset to do the splicing. However the problem was that we were calling array_search() on an associative array, so it was returning a string offset instead of a numeric one.
For example, let's take this array:
We would call
array_search('field1', $form). I had expected that it would return the integer "1", since field1 is in the 1 position ('#tree' is in 0). But instead, this call would return the string '#tree'! When you added the string '#tree' + 2, you would get the integer '2' (oh... PHP...), essentially the offset was entirely wrong (or in fact, always '2'), causing one field or entire fieldset to get eaten every time a field key was changed.To fix all these problems, I've changed it to the following code:
The real key being calling array_keys() inside of array_search(), to ensure that we get a numeric offset back.
Comment #10
quicksketchThis became apparent in my testing for #1404806: Use #type = 'machine_name' for key fields, in case you're curious why it finally came back up again. I feel so much better finding a blatant programming error, I'd always been suspicious that this problem had gone unfixed. I've committed this fix to both 6.x and 7.x branches.
Comment #11
quicksketchUpdating the title, since this was a problem with form_builder_set_element() rather than form_builder_cache_load().
Comment #12
eclipsegc commentedAWESOME, I am so glad to hear this. Pretty funny to visit a 3 year old issue, but I'm super happy to hear that I had documented some accurate information on this, and I'm really stoked that it's been fixed. I should really try form builder out again, it's been WAY too long.
Thanks for updating this and letting me know.
Kris.