Hey,

I'm using OpenAtrium, which uses Panelizer, which uses Panes. Additionally I'm using Features Overrides.
Given the nature of Features Overrides, it outputs panel exports with non-continous pane positions.
What does that mean?

Imagine a default panel like sidebar = [0,1,2] where 0,1,2 are the panes A, B and C.
If you feature these, than later put C on top, remove A and add a new pane D at the end, Feature Overrides will only note the differences, so it will export something like sidebar = [0,2] where these are C and D.

If you hand the resulting display, which is representing all this correctly, to panels_export_display() the result will be wrong.

panels_export_display() is just counting the panes per panel and puts these as position, while at the same time still storing the position noted originally in the pane as is and finally adding all this to output as it comes along.

The has the following effects:

- position as noted in the pane and as stated in the display differ
- the order of the panes as defined by pane->position is ignored
- the output is inconsistent with respect to itself as well as the diplay object handed to it

and this in turn makes features marked as overriden, where they are not.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

ChristianAdamski’s picture

And here is a patch. It's working fine with our OpenAtrium, which is a fairly complex panels situation.

It's a complex problem and I tried to comment reasonably.

ChristianAdamski’s picture

Slighly cleaned up version

ChristianAdamski’s picture

Status: Active » Needs review

Updating status.

Would be good if somebody could confirm, if this is actually a problem.

mglaman’s picture

Status: Needs review » Needs work

ChristianAdamski, this is an issue only when using Features Override to override a Panels display exported by another module, correct?

+++ b/panels.module
@@ -329,9 +329,7 @@ function panels_permission() {
 function panels_flush_caches() {
-  if (db_table_exists('cache_panels')) {
-    return array('cache_panels');
-  }
+  return array('cache_panels');
 }

Why did the table check get removed from flush cache hook?

ChristianAdamski’s picture

Hey mglaman,

1.) No idea why that table check got removed. Seems like a debug leftover or something.

2.) You could probably argue, that Features Override is the only candidate to cause this, but the basic problem is with the panels export function:
The panel panes handed over can have a position set, and the export will ignore these and replace them with an arbitrary enumeration. It's not what an export function should do. Also, under the presumption that my patch is working correctly, there is no downside to using this as far as I can tell.

ChristianAdamski’s picture

Status: Needs work » Needs review
FileSize
3.56 KB

Rerolled patch with #4 in mind.
Small typo in a comment and an unnecessary empty line as well.

moonray’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
3.54 KB

This patch needed to be rerolled, but once applied it worked like a charm. No more mini panels always stuck in overridden mode.
Attached patch doesn't change any code compared to #6.

japerry’s picture

Status: Reviewed & tested by the community » Needs review
Issue tags: +Needs tests

Needs more tests before committing.

Jorrit’s picture

@moonray: did it following occur for you in practice that positions were conflicting? I am referring to the situation that is handled in code near the comment // Determine if position already defined and not conflicting..

That piece of code lets a pane take over a position when there are conflicting position. I am just reading the patch and it seems to me that one conflict may lead to more: while iterating over the panes one conflicted pane may take over the position of the next pane, which then becomes conflicted too.

It seems panels lets the database decide what happens when multiple panes have the same position, see panels_load_displays(). Maybe it is better for this patch to sort on $pane->position and then on $pane->id if there are duplicates to match that behavior in a deterministic way. Perhaps the panels maintainers can be convinced to add pid to the list of columns to sort on. But then again, I don't know how often this occurs.

Also:

foreach ($output_panes as $position => $output_pane) {
  $output .= $output_pane;
}

can be simplified to

$output = implode('', $output_panes);

Jorrit’s picture

Please see the attached patch for my solution to this problem, which is, in my opinion, a cleaner and simpler execution of the same idea.

@ChristianAdamski : I am curious to hear your opinion on my approach.

ChristianAdamski’s picture

Hey @Jorrit,

I can't provide useful input, I haven't used this in years.

Good luck!

Jorrit’s picture

Thanks for your quick response.

I have found a small bug in my patch as I broke the handling of $title_pid.