Fixing Drupal bugs in ctools

DrupalI’d like to discuss bugs in one of the most-used modules in Drupal: the “Chaos Tool Suite” – or ctools. The problems are associated with rendering multi-value fields several times in the same panel. (And before I get into the details, a big thanks to the developers who have investigated and addressed this problem, in particular in the Drupal discussion boards “multi-value field offset not working correctly” and “accidentally modifying entities.”)

Here are the steps to reproduce (using Panels) with entity type node:

  1. Create a content type with a field that allows multiple values
  2. Create a node from that content type that contains two values: A and B
  3. Create a panel with the new node as its context
  4. Add the field to the panel with “offset = 0” and “limit = 1”
  5. Add the same field to the panel again with “offset = 1” and “limit = 1”
  6. Add the same field to the panel a third time with “offset = 0” and “limit = 1”

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

Actual 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: function ctools_entity_field_content_type_render

In Drupal 7 we don’t use Classes/Objects very often (think memory usage). Using the operator “=” for simple variables will copy and “=&” – reference to the original value in memory. But for Objects in PHP 5 the operator “=” always creates only a reference to the original value. Inside the function clone is used to create a copy of $entity and then override the cloned fields. But the field is an internal object of the entity and clone creates only a shallow copy.  The next string:

deletes all fields by name value except for index 0. So at the next cycle inside the class Panels_renderer_standard->render_panes panel doesn’t have a second field index of the entity. (You can read more about shallow and deep copying with examples in http://jacob-walker.com/blog/php-clone-and-shallow-vs-deep-copying.html and in the PHP documentation.)

My solution to create a deep copy uses the serialize function:

Good luck!

1 thought on “Fixing Drupal bugs in ctools

  1. Nice article, thanks! Never realized this shallow specifics of clone method. Wonder which PHP version will contain a fix for that?

Comments are closed.