Oh my god, this bug cost me hours and nerves:
Importing a correct panel page, when I hit submit on the general settings page (first step after import), I'm seeing three warnings:
* warning: Invalid argument supplied for foreach() in C:\xampp\htdocs\drupal5\sites\all\modules\panels\includes\plugins.inc on line 583.
* user warning: Duplicate entry '0' for key 1 query: INSERT INTO panels_display (did, layout, layout_settings, panel_settings, cache, title, hide_title) VALUES (0, '', 'N;', 'N;', 'N;', '', 0) in C:\xampp\htdocs\drupal5\includes\database.mysqli.inc on line 151.
* warning: Invalid argument supplied for foreach() in C:\xampp\htdocs\drupal5\sites\all\modules\panels\includes\plugins.inc on line 583.
This also means that the display has not been correctly saved. Debugging shows that panels_save_display() is called with an empty $display object. What's wrong here???
A dprint_r($_SESSION['pp_import']) gives me the following dump:
.
.
.
[display] => __PHP_Incomplete_Class Object
(
[__PHP_Incomplete_Class_Name] => panels_display
[args] => Array
(
)
[content] => Array
(
)
[panels] => Array
(
)
[incoming_content] =>
[css_id] =>
[context] => Array
(
[argument_term_3] => __PHP_Incomplete_Class Object
(
[__PHP_Incomplete_Class_Name] => panels_context
[type] => term
[data] =>
[title] => Unknown context
[page_title] =>
[identifier] => Taxonomy term 3
[argument] =>
[keyword] => term_2
[plugin] => term
)
[argument_nid_1] => __PHP_Incomplete_Class Object
(
[__PHP_Incomplete_Class_Name] => panels_context
[type] => node
[data] =>
[title] => Unknown context
[page_title] =>
[identifier] => Node ID
[argument] =>
[keyword] => node
[plugin] => node
)
[context_node_1] => __PHP_Incomplete_Class Object
(
[__PHP_Incomplete_Class_Name] => panels_context
[type] => node
[data] => stdClass Object
(
[nid] => 2
[vid] => 2
[type] => story
[status] => 1
[created] => 1211226950
[changed] => 1211226964
[comment] => 2
[promote] => 1
[sticky] => 0
[revision_timestamp] => 1211226964
[title] => Teststory
[body] =>
[teaser] =>
[log] =>
[format] => 1
[uid] => 1
[name] => admin
[picture] =>
[data] => a:0:{}
[last_comment_timestamp] => 1211226964
[last_comment_name] =>
[comment_count] => 0
[taxonomy] => Array
(
)
[files] => Array
(
)
)
[title] => Teststory
[page_title] =>
[identifier] => Node
[argument] => 2
[keyword] => node_1
[plugin] => node
)
)
[title] =>
[hide_title] => 0
[did] => new
[name] =>
[layout] => onecol
[layout_settings] =>
[panel_settings] =>
)
[displays] => Array
(
[argument_4-default] => Array
(
[title] => Taxonomy term 3 Default
[argument_id] => 4
[display] => __PHP_Incomplete_Class Object
(
[__PHP_Incomplete_Class_Name] => panels_display
[args] => Array
(
)
[content] => Array
(
)
[panels] => Array
(
)
[incoming_content] =>
[css_id] =>
[context] => Array
(
)
[title] =>
[hide_title] => 0
[did] => new
[name] =>
[layout] =>
[layout_settings] =>
[panel_settings] =>
)
)
)
.
.
.
Some research on the subject (see comments on http://de3.php.net/unserialize) revealed that while a session is active, we cannot add custom class objects to the session variable, as classes need to be initialized before the session is started. That's why we are getting this "__PHP_Incomplete_Class".
The common workaround is: serialize object before storing to the session variable and unserialize it after retrieving.
I did this for panels_page and panels_mini, and voilà, everything works correctly now.
I'm curious though whether this bug appears on both PHP4 and 5, and when it has been introduced, as the import functionality hasn't always been broken.
| Comment | File | Size | Author |
|---|---|---|---|
| fix_import.patch | 2.4 KB | pancho |
Comments
Comment #1
panchoThis is really weird!
Without the patch: Why the hell does the $_SESSION variable contain display->context, when it is only added to the $panel_page variable in panels_page_edit_form??? Does $_SESSION take the $page variable as a reference somehow??? I don't get this.
With the patch the dump is correct though. unserialize($_SESSION['pp_import']) doesn't contain display->context, while $panel_page does. A dprint_r($panel_page) gives me the following, correct output:
Note that in both cases I used dprint_r() in panels_page_edit_form_submit() on line 369, right before $_SESSION['pp_import'] is unset.
While the patch seems to correctly fix the bug, it would probably be a good idea to find out what is really going on here. Any ideas? Sam? Earl?
Comment #2
merlinofchaos commentedSince we added more classes to the view, this is happening. I think older exports should still work, since they still use stdClass.
The patch looks like it should be fine.
Comment #3
merlinofchaos commentedI think we could use a solution that does not use $_SESSION. That said, working is better than not working; ideal can wait. Committed.
Comment #4
panchoThanks for committing!
Just some additional info for the records: The bug fixed by this patch shows up only with PHP5, as PHP5 always takes objects by reference. This explains both:
- that the class needs to be initialized before the $_SESSION variable is created, which is not possible in Drupal.
- why $_SESSION['pp_import'] is being mysteriously changed.
I posted a followup task to replace this ugly muddling with the session variable by using our panels_object_cache table: #264868: Store imported $page/$mini in cache not in $_SESSION
Comment #5
panchoSorry.
Comment #6
Anonymous (not verified) commentedAutomatically closed -- issue fixed for two weeks with no activity.