Steps to reproduce (using Panels):
- create a content type with a field that allows multiple values
- create a node from that content type that contains two values A and B
- create a panel with the new node as its context
- add the field to the panel with "offset = 0" and "limit = 1"
- add the same field to the panel again with "offset = 1" and "limit = 1"
- add the same field to the panel a third time with "offset = 0" and "limit = 1"

Expected:
Three field panes with values A, B, A

Result:
The first field pane is rendered correctly with value A, but then the entity's field value is permanently limited to only contain the 1st item in the field. The second pane tries to get the 2nd of an array that now contains only one element and the result is naturally empty. The third pane tries to get the 1st item of an array that now contains no elements at all and is also rendered empty.

The Problem:
In file plugins/content_types/entity_context/entity_field.inc

function ctools_entity_field_content_type_render($subtype, $conf, $panel_args, $context) {
...
  $clone = clone $entity;
  $clone->{$field_name}[$language] = $all_values;
  $field_output = field_view_field($entity_type, $clone, $field_name, $field_settings, $language);
...
}

Clone doesn't do what the original developer probably thought it would. It creates a shallow clone of the entity. Consequently, setting the value of $clone->{$field_name}[$language] also changes the value for the original entity. All subsequent access to that field value in the same request returns the modified array. So, in the example from above (and pseudo-code):

orig = [A, B]
// first access
v = orig.filter(0, 1) // orig = v = [A]
// second access
v = orig.filter(1, 1) // orig = v = []
//third access
v = orig.filter(0, 1) // orig = v = []

I have directly attached a patch that (in my tests) fixes the issue without causing any side effects (the patch should also be applicable to the current HEAD). There is probably a more reasonable way of fixing this using Drupal APIs, but I'm still quite new to Drupal and didn't find anything useful.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

getu-lar’s picture

FileSize
1.28 KB

It has been brought to my attention that the "finally" keyword has only just been introduced to PHP 5.5 (seriously.... WTF?!?). So, to keep compatibility to at least a PHP 5.3 level I "downgraded" my patch while keeping the basic functionality the same.

Dave Reid’s picture

Status: Active » Postponed (maintainer needs more info)

I don't think your assumptions are true. The clone seems to work exactly as intended: http://3v4l.org/kPWva

getu-lar’s picture

Well... it's been 7 months - five until the first response. For the life of me I can't seem to reproduce the issue. I've even tried reverting all my sources and modules to the state they had in March with no success. I distinctly remember the issue and reproducing it with a clean install and the "fix" that worked, but something seems to be different now.

And you are of course right, "clone" also copies value arrays. And that's the only possible other explanation I can come up with for what happened back then: I must have (for some reason that may very well have been my own fault) ended up with an array reference on the field level or below.

See: http://3v4l.org/qAt2t

Since I can't reproduce it at this point, I'll close this issue.

getu-lar’s picture

Status: Postponed (maintainer needs more info) » Closed (cannot reproduce)
Sneakyvv’s picture

I had the same problem in 7.x-1.7 and came to the same conclusion. The patch from getu-lar also seemed to fix the entity, so I was about to re-open this issue.

However, my panels still weren't rendered properly. Then, after some more debugging I found that the problem was the issue described in #2456327: Multi-value field offset not working correctly when panel panes are rendered. Surprisingly when I applied the patch from there, the problem of the entity being altered was also no longer occurring.
So, just in case someone is experiencing the same problem, try the patch from #2456327: Multi-value field offset not working correctly when panel panes are rendered.