I observed this problem with D6 with cck build modes but realized that this problem exists with D7 as well. The issue is complicated and I have struggled with the right way to describe it, so here goes.
If we have a page view that does node_view() (say the /node) and we have a block that does node_view() but with a different build mode. The content array will be preserved for the block rendering, so all $node->content that was put there for node_view('teaser') will be there for node_view('block_build_mode').
This patch makes it so $node->content() is always rebuilt for each call to node_build_content(). Which makes sense semantically, calling node_build_content() means that we are building from scratch.
(marked as critical cause I really believe this is. I know most people don't have node_view() on the same node on the same page. I know node_loads() are bad for performance, but we should be able to handle this case).
Attached is a fix for D6 as well.
| Comment | File | Size | Author |
|---|---|---|---|
| #54 | drupal-recursive-error-when-rebuilding-node-build-564642-54.patch | 1.15 KB | xtfer |
| #37 | 564642_comment_rebuild_test.patch | 1.29 KB | dave reid |
| #35 | 564642_comment_rebuild_test.patch | 1.29 KB | Scott Reynolds |
| #25 | drupal_564642.patch | 3.18 KB | Scott Reynolds |
| #23 | drupal_564642.patch | 3.14 KB | Scott Reynolds |
Comments
Comment #1
Scott Reynolds commentedrelated #564632: Cruft in $page due to node_build, comment_build, etc.
Comment #2
moshe weitzman commentedmakes perfect sense. you can delete that $node->content = array() line and let $node->content = field_attach_view(). Slightly less verbose. after that, is rtbc.
Comment #3
Scott Reynolds commentedhaha good call. Was running out the door for lunch...
Comment #5
moshe weitzman commentedComment #6
moshe weitzman commentedActually, comment_build_content() and user_build_content() suffer from the same bug. Could you patch those too? Terms do not have this problem.
Comment #7
moshe weitzman commentedEwww. Failures in poll tests. Have fun with that :)
Comment #8
simeWould it work to add 'rebuild' parameter to node_build_content? This could be TRUE by default, then modify poll module call to not rebuild it.
Comment #9
damien tournoud commentedLet's test doing it this way.
Comment #10
damien tournoud commentedWe will need a small test for that.
Comment #11
moshe weitzman commentedLooks like right approach. Would love similar fix for user and comment
Comment #12
matt2000 commentedDoesn't look like user needs it, but this patch covers comment as well.
Comment #13
moshe weitzman commentedIndeed you are right. Users already zero our the content property when building.
Comment #15
matt2000 commentedchasing HEAD...
Comment #16
moshe weitzman commentedComment #17
webchickCommitted to HEAD. Thanks!
Sounds like this needed to be ported to D6 as well?
Comment #18
Scott Reynolds commentedYes, it is a bug that exists in 6 as well, though a little more obscure as 6 Core doesn't have many build modes. Still a bug, and becomes apparent when using CCK build modes.
Also missing a test still right?
Comment #19
webchickD'oh. :) Yes.
Comment #20
Scott Reynolds commentedAs you have already committed the patch, here are two simple test for node and comment.
They follow the same structure, load the object, add something to content, then check for that something after a call to object_build().
Comment #21
matt2000 commentedLooks good. This test will confirm that the preceding patch has does it's job.
Comment #22
webchickAwesome, thanks! Just some minor things.
This needs PHPDoc. Also, this doesn't need to be a public function. Just plain ol' function will do.
This is a lot of dense code. It'd be nice to break it up with an inline comment or two for easier scanning.
Comments should "Start with a capital, end with a period." Also, wrap at 80 chars.
PHPDoc.
Same comment as the earlier one on the detail of assertion message.
I'm on crack. Are you, too?
Comment #23
Scott Reynolds commentedOk heres a re-roll.
Comment #24
catchComment #25
Scott Reynolds commentedHeres another reroll, with added periods for the test description, and better assertion messages.
Comment #26
catchLooks good.
Comment #27
dries commentedCommitted to CVS HEAD. Thanks.
Comment #28
Scott Reynolds commentedAs per Webchick #17, I think this bug can be fixed in D6 as well. I posted a patch on the node already.
http://drupal.org/files/issues/content-d6.patch
Comment #29
Scott Reynolds commentedforgot to change the Issue fields.
Comment #30
int commentedI think that this issue are breaking the testbot..
http://qa.drupal.org/pifr/test/32
Comment #31
catchVery, very odd that those tests passed in the queue but fail now, we should rollback then investigate.
Comment #32
dave reidAn AJAX HTTP error occurred. HTTP Result Code: 200 Debugging information follows. Path: /batch?id=104&op=do StatusText: OK ResponseText: Fatal error: Call to undefined function comment_build() in /home/dave/Projects/www/drupal7dev/modules/comment/comment.test on line 1226 Call Stack: 0.0001 65992 1. {main}() /home/dave/Projects/www/drupal7dev/index.php:0 0.2395 17111692 2. menu_execute_active_handler() /home/dave/Projects/www/drupal7dev/index.php:22 0.2468 17933444 3. call_user_func_array() /home/dave/Projects/www/drupal7dev/includes/menu.inc:466 0.2468 17933712 4. system_batch_page() /home/dave/Projects/www/drupal7dev/includes/menu.inc:0 0.2468 17933812 5. _batch_page() /home/dave/Projects/www/drupal7dev/modules/system/system.admin.inc:2267 0.2469 17937624 6. _batch_do() /home/dave/Projects/www/drupal7dev/includes/batch.inc:81 0.2469 17937664 7. _batch_process() /home/dave/Projects/www/drupal7dev/includes/batch.inc:163 0.2483 18020240 8. call_user_func_array() /home/dave/Projects/www/drupal7dev/includes/batch.inc:286 0.2483 18020380 9. _simpletest_batch_operation() /home/dave/Projects/www/drupal7dev/includes/batch.inc:0 0.2586 19493852 10. DrupalTestCase->run() /home/dave/Projects/www/drupal7dev/modules/simpletest/simpletest.module:192 6.3158 28085352 11. CommentContentRebuild->testCommentRebuild() /home/dave/Projects/www/drupal7dev/modules/simpletest/drupal_web_test_case.php:442There is no comment_build function in D7. Might be looking for comment_build_content()?
Powered by Dreditor.
Comment #33
Scott Reynolds commentedComment build used to exist. Can't find where we changed it.
#523950: Update comment rendering ? I don't know whatever, working on fixing.
Comment #34
dave reidIt was renamed to comment_view in #658364: Does build/view/formatter terminology make sense?
Comment #35
Scott Reynolds commentedCool so here is the fix. Test didn't pass before, passes now.
And a comment was too long.
Comment #36
catchcomment_view should be comment_view(), otherwise looks great as long as testbot is happy.
Comment #37
dave reidConfirmed patch in #35 fixes the test failures. Fixed the documentation and RTBC'ing.
Comment #38
dries commentedCommitted to CVS HEAD. That should fix the tests.
Comment #39
int commentedand now, return to D6
Comment #40
Scott Reynolds commentedPatch attached to the issue node.
Comment #42
Scott Reynolds commentedthe poor testing bot is confused. Its not up for D7 its up for D6 review.
Comment #43
emdalton commentedDid this ever get fixed in D6? We have a bad apache memory leak I'm trying to track down.
Comment #44
alan d. commentedErr: I just come across this from #564632: Cruft in $page due to node_build, comment_build, etc.. A D8 patch is in that queue, but I will close it once the test bot has run.
Use-case: A node view references something that also renders nodes through the node system. One of these nodes is the parental container itself, meaning that the $node->content array is reset and the parents build information is rendered NULL. This leads to a fatal error:
Fatal error: Unsupported operand types in modules/node/node.module on line 1362
So this was my workaround.
A Drupal 7 patch is attached.
For D8: Note unlike that other comments, rather than rebuilding from scratch, I would suggest adding in the context of the view mode to the content array and not resetting. Thus caching a copy and enabling reuse rather than rebuilding each time it is required. Only common use-case would be on listings that allow duplicates, like events with multiple sessions, where the same listing can show multiple times.
[Edit] This is one of the reasons why calendars in Drupal always appear so slow :( [/Edit]
Comment #45
alan d. commentedI removed the white space before the semi-colon.
Comment #47
alan d. commented#45: drupal-recursive-error-when-rebuilding-node-build-564642-45.patch queued for re-testing.
Comment #48
xjmI'm a little confused by #44. We need to whatever bug still exists in D8 first, even if we come up with a better fix later. Also, let's get an automated test that demonstrates the functional bug.
Comment #49
alan d. commentedI think the easiest way would be to create a simple filter tag that renders a node teaser. Then enable this filter on a node body field. Edit a node and insert this tag with the nid of the node being edited. It is a really obscure bug!
I triggered it by embedding an insert_view tag into the content of a node. This showed a teaser listing of recently updated content. If the node that had this tag was rendered in this listing, the fatal error occurred. [Mind you there were bigger bugs to resolve in the insert_view module to even get this far - recursive rendering of the same view tag, I've posted a patch in that modules issue queue to prevent this.]
Comment #50
hefox commented(#45 is working nicely for those that just need to fix it)
Comment #51
hefox commentedDoes anyone know if d8 has this bug?
Got bitten by this again
Comment #53
xtfer commentedI'm going to go out on a limb and suggest that this is not relevant for D8 because of the way it handles multiple builds within the entity controller.
Comment #54
xtfer commentedRerolled #45 against 7.x-dev and queued for testing.
Comment #57
donquixote commentedComment #58
fabianx commentedRTBC - though I think we really should write a test for it, so I probably will need to put it to CNW next when I review the RTBC queue with my maintainer head on ;).
I just want to signal that I think that this is ready.
Comment #60
fabianx commentedWe indeed will need a test for this, setting to Needs work for that.