This issue could be fixed in CTools or here and I'm not sure which is the correct place. To describe the issue:-
- Using CTools and Panels with a multi-valued field which is then given a starting point and length (offset & length) so you can display just a subset of the field. This is done in the field configution when setting up a field via Panels (add field, choose settings, continue, enter value under 'Skip the first x items')
- Theme the field through field.tpl.php or an override and loop through the $items array to render each item individually.
- When displaying not all the items show consistently
The reason for this is that CTools has the following function in ctools/plugins/content_types/entity_context/entity_field.inc on line 144. This is as follows:-
if (isset($conf['delta_limit'])) {
$offset = intval($conf['delta_offset']);
$limit = !empty($conf['delta_limit']) ? $conf['delta_limit'] : NULL;
$all_values = array_slice($all_values, $offset, $limit, TRUE);
}The $all_values keeps the keys in the final array which eventually passes through to the field rendering. When the function
field_default_view($entity_type, $entity, $field, $instance, $langcode, $items, $display)
is called in modules/field/field.default.inc, there is an array merge of arrays which contain strings and integers. The integers are reset (which makes them different from the CTools list). On line 231:
$addition[$field['field_name']] = array_merge($info, $elements);
Then in the file /field/field.module, the function template_preprocess_field(&$variables, $hook) does a check to match the two arrays created above (the CTools $all_values and the data coming back from field_default_view. This happens on line 1044:
foreach ($element['#items'] as $delta => $item) {
if (!empty($element[$delta])) {
$variables['items'][$delta] = $element[$delta];
}
}The issue is that the $element[$delta] has a different set of keys to the $element['#items']. The fix for this should be quite simple. Line 231 of field.default.inc needs to be:-
$addition[$field['field_name']] = $info + $elements;
I'm going to create a patch now - but this is my first for core, so I'm not 100% sure how to do this correctly. Apologies if I mess it up.
| Comment | File | Size | Author |
|---|---|---|---|
| #1 | drupal_core-multivalue-field-ctools-range-fix-2456573-0.patch | 501 bytes | christoph |
Comments
Comment #1
christoph commentedComment #2
dcam commentedThank you for your contribution! There are at least two things you need to know about submitting core patches:
1. Setting the issue status to Needs review will cause your patch to be automatically tested by Testbot.
2. Always set the issue version to the current *-dev version.
The third thing to know would be that changes must always happen in the upstream development version, currently Drupal 8, before they can be backported to Drupal 7. That's assuming that the code in D8 hasn't changed so much that the change is irrelevant. Unfortunately, you have such a specific use case involving multiple contributed modules that right now it may be impossible to check to see whether this bug still exists in D8 or not. If you feel like digging into the D8 code, you could at least try to check and see if the array_merge() is still in it.
For now, however, we can go ahead and let Testbot see if this change would break D7 in any way.
Comment #3
christoph commentedSorry for the delay in getting round to this.
I've been through the Drupal 8 code. It's changed pretty significantly and there isn't any array_merge either in the fields module or in any other core module that appears to be relevant (I assume the code hasn't moved elsewhere, but I searched all of core just in case). Unfortunately CTools and Panels have also changed a lot and aren't quite ready to test this particular use case in a way that I could find.
It does seem that this may be a Drupal 7 specific issue for the present. Not sure which status to assign to get this to the next step.