diff --git a/modules/field/field.attach.inc b/modules/field/field.attach.inc index 7434dda..2d274a5 100644 --- modules/field/field.attach.inc +++ modules/field/field.attach.inc @@ -1036,10 +1036,17 @@ function field_attach_delete_revision($entity_type, $entity) { /** * Prepare field data prior to display. * - * This function must be called before field_attach_view(). It lets field - * types and formatters load additional data needed for display, and - * therefore accepts an array of entities to allow query optimisation when - * displaying lists of entities. + * This function lets field types and formatters load additional data + * needed for display that is not automatically loaded during + * field_attach_load(). It accepts an array of entities to allow query + * optimisation when displaying lists of entities. + * + * field_attach_prepare_view() and field_attach_view() are two halves + * of the same operation. It is safe to call + * field_attach_prepare_view() multiple times on the same entity + * before calling field_attach_view() on it, but calling any Field + * API operation on an entity between passing that entity to these two + * functions may yield incorrect results. * * @param $entity_type * The type of $entities; e.g. 'node' or 'user'. @@ -1077,8 +1084,12 @@ function field_attach_prepare_view($entity_type, $entities, $view_mode) { * Each field is displayed according to the display options specified in the * $instance definition for the given $view_mode. * - * The entity must have run through field_attach_prepare_view() beforehands. - * @see field_attach_prepare_view() + * field_attach_prepare_view() and field_attach_view() are two halves + * of the same operation. It is safe to call + * field_attach_prepare_view() multiple times on the same entity + * before calling field_attach_view() on it, but calling any Field + * API operation on an entity between passing that entity to these two + * functions may yield incorrect results. * * Sample structure: * @code diff --git a/modules/node/node.pages.inc b/modules/node/node.pages.inc index c5a8307..285dd58 100644 --- modules/node/node.pages.inc +++ modules/node/node.pages.inc @@ -315,6 +315,9 @@ function node_form_build_preview($form, &$form_state) { */ function node_preview($node) { if (node_access('create', $node) || node_access('update', $node)) { + // Previewing alters $node so it needs to be cloned. + $node = clone $node; + _field_invoke_multiple('load', 'node', array($node->nid => $node)); // Load the user's name when needed. if (isset($node->name)) { @@ -339,11 +342,9 @@ function node_preview($node) { field_attach_prepare_view('node', $nodes, 'full'); // Display a preview of the node. - // Previewing alters $node so it needs to be cloned. if (!form_get_errors()) { - $cloned_node = clone $node; - $cloned_node->in_preview = TRUE; - $output = theme('node_preview', array('node' => $cloned_node)); + $node->in_preview = TRUE; + $output = theme('node_preview', array('node' => $node)); } drupal_set_title(t('Preview'), PASS_THROUGH); diff --git a/modules/node/node.test b/modules/node/node.test index 1e5d539..437bda1 100644 --- modules/node/node.test +++ modules/node/node.test @@ -387,6 +387,16 @@ class PagePreviewTestCase extends DrupalWebTestCase { } /** + * Create a node, preview it, and make sure the node is unchanged. + */ + function testPagePreviewNodeEqual() { + $node = $this->drupalCreateNode(); + $before = clone $node; + node_preview($node); + $this->assertTrue($node == $before, 'Node unchanged by preview.'); + } + + /** * Check the node preview functionality, when using revisions. */ function testPagePreviewWithRevisions() {