| Project: | Content Construction Kit (CCK) |
| Version: | 5.x-1.x-dev |
| Component: | nodereference.module |
| Category: | bug report |
| Priority: | critical |
| Assigned: | Unassigned |
| Status: | closed (duplicate) |
Issue Summary
How to reproduce the bug:
1. Create content type with select nodereference component using with example options (set as required!).
2. Create content using this type and select some values.
3. Edit this content.
4. Before Updating the content, please set component to read-only (disabled).
I.E. using the Firebug in Firefox, you can run from console:
$x('//*[@class="form-select required"]')[0].disabled=true
to disable it.
You can't update when component is read-only, because it not passing the reference validation.
There is an error:
This post can't be referenced.
Explanation:
When you have read-only component, it's not submitting value via _POST, it's getting it's default value (copying #default_value to #value).
Difference between normal select and nodereference select is that you receiving an array instead of string (no matter if it's multiple or not)
nodereference.module
function nodereference_widget()
...
case 'prepare form values':
$items_transposed = content_transpose_array_rows_cols($items);
$items['default nids'] = $items_transposed['nid'];So this array is copied in form_builder() to #value
Later in nodereference_field() function (nodereference.module) you checking if array exists in array instead of string in array, so it's returning FALSE instead of TRUE.
2.5333 10116848 +648 -> in_array(array (0 => '7'), array (0 => 5, 1 => 6, 2 => 7, 3 => 8, 4 => 3)) C:\Users\bronek\workspace\websites\drupal57\modules\cck\nodereference.module:121
>=> FALSEEven if pass this validation, you will have other problems during update the node using the array on non-multiple select.
Comments
#1
See attachment.
#2
It's similar problem also with multi-select component (without nodereference) and checkboxes.
For multi-select issue there is a patch here: http://drupal.org/node/236672
#3
Trace of using array instead of string during update the field:
7.2965 10190872 +0 -> db_query('UPDATE {content_type_test_ref_content} SET field_ref2_nid = %d WHERE vid = %d AND nid = %d', array (0 => array (0 => '5'), 1 => '7', 2 => '7')) C:\Users\bronek\workspace\websites\drupal-test\sites\all\modules\cck\content.module:4797.2972 10191360 +488 -> func_get_args() C:\Users\bronek\workspace\websites\drupal-test\includes\database.inc:193
>=> array (0 => 'UPDATE {content_type_test_ref_content} SET field_ref2_nid = %d WHERE vid = %d AND nid = %d', 1 => array (0 => array (0 => '5'), 1 => '7', 2 => '7'))
7.2973 10191976 +616 -> array_shift(array (0 => 'UPDATE {content_type_test_ref_content} SET field_ref2_nid = %d WHERE vid = %d AND nid = %d', 1 => array (0 => array (0 => '5'), 1 => '7', 2 => '7'))) C:\Users\bronek\workspace\websites\drupal-test\includes\database.inc:194
>=> 'UPDATE {content_type_test_ref_content} SET field_ref2_nid = %d WHERE vid = %d AND nid = %d'
7.2975 10191832 -144 -> db_prefix_tables('UPDATE {content_type_test_ref_content} SET field_ref2_nid = %d WHERE vid = %d AND nid = %d') C:\Users\bronek\workspace\websites\drupal-test\includes\database.inc:195
7.2975 10192808 +976 -> is_array('') C:\Users\bronek\workspace\websites\drupal-test\includes\database.inc:62
>=> FALSE
7.2976 10193040 +232 -> strtr('UPDATE {content_type_test_ref_content} SET field_ref2_nid = %d WHERE vid = %d AND nid = %d', array ('{' => '', '}' => '')) C:\Users\bronek\workspace\websites\drupal-test\includes\database.inc:79
>=> 'UPDATE content_type_test_ref_content SET field_ref2_nid = %d WHERE vid = %d AND nid = %d'
>=> 'UPDATE content_type_test_ref_content SET field_ref2_nid = %d WHERE vid = %d AND nid = %d'
7.2978 10192088 -952 -> is_array(array (0 => array (0 => '5'), 1 => '7', 2 => '7')) C:\Users\bronek\workspace\websites\drupal-test\includes\database.inc:196
>=> TRUE
7.2979 10191928 -160 -> _db_query_callback(array (0 => array (0 => '5'), 1 => '7', 2 => '7'), TRUE) C:\Users\bronek\workspace\websites\drupal-test\includes\database.inc:199
>=> NULL
7.2980 10192120 +192 -> preg_replace_callback('/(%d|%s|%%|%f|%b)/', '_db_query_callback', 'UPDATE content_type_test_ref_content SET field_ref2_nid = %d WHERE vid = %d AND nid = %d') C:\Users\bronek\workspace\websites\drupal-test\includes\database.inc:200
7.2981 10192576 +456 -> _db_query_callback(array (0 => '%d', 1 => '%d'), ???) C:\Users\bronek\workspace\websites\drupal-test\includes\database.inc:0
7.2982 10193096 +520 -> array_shift(array (0 => array (0 => '5'), 1 => '7', 2 => '7')) C:\Users\bronek\workspace\websites\drupal-test\includes\database.inc:151
>=> array (0 => '5')
>=> 1
7.2983 10192616 -480 -> _db_query_callback(array (0 => '%d', 1 => '%d'), ???) C:\Users\bronek\workspace\websites\drupal-test\includes\database.inc:0
7.2984 10193080 +464 -> array_shift(array (0 => '7', 1 => '7')) C:\Users\bronek\workspace\websites\drupal-test\includes\database.inc:151
>=> '7'
>=> 7
7.2985 10192520 -560 -> _db_query_callback(array (0 => '%d', 1 => '%d'), ???) C:\Users\bronek\workspace\websites\drupal-test\includes\database.inc:0
7.2986 10192984 +464 -> array_shift(array (0 => '7')) C:\Users\bronek\workspace\websites\drupal-test\includes\database.inc:151
>=> '7'
>=> 7
Array: array (0 => array (0 => '5'), 1 => '7', 2 => '7')
is translated via db_query() to invalid values 1, 7, 7 instead of 5, 7, 7
#4
After patch, select are updating successfully (tested also on multi-select nodereferences).
Also in this patch there is another fix of some other bug, when values are copied from #default_value to #value they are not parsed via drupal_map_assoc() function in form_builder so they are in different format (array(0 => option1, 1=> option2, ...) instead of array(option1 => option1, option2 => option2, ...), so the first value will be always deleted
See nodereference_widget() function:
case 'process form values':...
// drop the 'none' options if other items were also selected
elseif (count($items['nids']) > 1) {
unset($items['nids'][0]);
}
it's resolved by adding additional empty key (array_unshift).
#5
this is a general problem with disabled fields. see http://drupal.org/node/227966. please reopen if this problem is not a dupe of that one.
#6
I was able to work around this by setting the disabled field's value to it's default value in hook_form_alter.
<?php$form['field_example']['nids']['#disabled'] = true;
$form['field_example']['nids']['#value'] = $form['field_example']['nids']['#default_value'][0];
?>
It passes validation and doesn't wipe out the original value.
#7
To do the same thing for userreference fields:
<?php$form['field_example']['uids']['#disabled'] = TRUE;
$form['field_example']['uids']['#value'] = $form['field_example']['uids']['#default_value'][0];
?>