This is a rather complex issue, with a simple solution.
I have just startet to use Mailhandler, and are creating nodes from mails. I'm setting cck fields, and most of the time it's no problem, however yesterday I had real troubles setting an optionwidget value from mailhandler submit. After some debugging I find an interesting and inconsistence problem, which can cause troubles for other modules. The problem lies in the nature of node submit handling in mailhandler. Compared to node.module, where a new node is based on a form array, the mailhandler creates an object of the node. In node.module the conversion of the node form array to a node object is done in $node = node_submit($node). This is not the case for mailhandler, and I suppose other modules.The problem is that mailhandler is calling both node_validate and node_submit with an object, and the content.module is handling these calls the same way; calling some_field_widget ($op = 'pocess form values') in _content_widget_invoke. Therefore this task is done twice, and in the case with the optionwidget module, which are manipulating the $items reference array, the new values are remembered, when an object is sent as argument. In difference to normal node submit, where an array is checked with node_validate. On line 639 in content.module this check is_object($node) actually sets the new variables from some_field_widget, and the next time this function is called there are already manipulated values in the $node->field_some_field variable. I don't know if this is an issue with the Mailhandler module, which should not call node_validate with an object. However I do have a simple fix for this issue in optionwidget.
On line 167:
$items = content_transpose_array_rows_cols(array('value' => $values));
Here is the $items array converted. The value syntax of custom submit to optionwidget is array('key' => 'some value'). But if the $items array already is converted we get an empty $items array, cause this function could be called twice.
The simple solution:
Replace the above line with:
if (!empty($values)){
$items = content_transpose_array_rows_cols(array('value' => $values));
}
Then the converstion is done only when no values are found - the array is already transposed by node_validate.
This opens/solves another issue to: Why not use the same syntax for adding content as other cck components? As mentioned above the optionwidget allows you to add items to fields by adding $node->filed_some_fiels -> array('key'=>'some_value') to the node object before node_submit, when i.e. nodereference and other components have this syntax: $node->filed_some_fiels -> array(array('value'=>'some_value')). With the above tweak it is actually possible to add values to optionwidget fields this way to, cause this is the format content_transpose_array_rows_cols tranpose the 'key' array to. Therefore by checking if $values has values, we don't reset the $items array when no 'key' array is found.
Ok, hope this is some kind of understandable. An issue which is not that easy to explain.
Comments
Comment #1
marcp commentedI'm having the same problem -- using mailhandler and wanting to set some CCK fields in my custom module's
hook_mailhandler(). I hadn't gotten as far as you in debugging this. Did you come up with another solution other than patching optionwidgets.module?Comment #2
karens commentedThe D5 version is no longer being supported. Sorry.