diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module index 2833779d96..d46bfc26e9 100644 --- a/core/modules/forum/forum.module +++ b/core/modules/forum/forum.module @@ -12,6 +12,7 @@ use Drupal\Core\Url; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Routing\RouteMatchInterface; +use Drupal\node\NodeInterface; use Drupal\taxonomy\VocabularyInterface; use Drupal\user\Entity\User; @@ -147,7 +148,7 @@ function forum_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $ent * * Assigns the forum taxonomy when adding a topic from within a forum. */ -function forum_node_presave(EntityInterface $node) { +function forum_node_presave(NodeInterface $node) { if (\Drupal::service('forum_manager')->checkNodeType($node)) { // Make sure all fields are set properly: $node->icon = !empty($node->icon) ? $node->icon : ''; @@ -157,7 +158,10 @@ function forum_node_presave(EntityInterface $node) { if (!$node->isNew()) { $old_tid = \Drupal::service('forum.index_storage')->getOriginalTermId($node); if ($old_tid && isset($node->forum_tid) && ($node->forum_tid != $old_tid) && !empty($node->shadow)) { - // A shadow copy needs to be created. Retain new term and add old term. + // A shadow copy needs to be created. Retain new term and add old + // term. This requires a new revision, as {forum} is keyed by revision + // ID. + $node->setNewRevision(TRUE); $node->taxonomy_forums[count($node->taxonomy_forums)] = ['target_id' => $old_tid]; } } @@ -331,6 +335,7 @@ function forum_form_node_form_alter(&$form, FormStateInterface $form_state, $for '#description' => t('If you move this topic, you can leave a link in the old forum to the new forum.'), ]; $form['forum_tid'] = ['#type' => 'value', '#value' => $node->forum_tid]; + $form['#entity_builders'][] = 'forum_node_form_entity_builder'; } if (isset($form['taxonomy_forums'])) { @@ -348,6 +353,15 @@ function forum_form_node_form_alter(&$form, FormStateInterface $form_state, $for } } +/** + * Entity builder for the node edit form. + * + * @see forum_form_node_form_alter() + */ +function forum_node_form_entity_builder($entity_type, NodeInterface $node, &$form, FormStateInterface $form_state) { + $node->shadow = $form_state->getValue('shadow'); +} + /** * Implements hook_preprocess_HOOK() for block templates. */ diff --git a/core/modules/forum/src/ForumIndexStorage.php b/core/modules/forum/src/ForumIndexStorage.php index 244c223ba6..df541a91c1 100644 --- a/core/modules/forum/src/ForumIndexStorage.php +++ b/core/modules/forum/src/ForumIndexStorage.php @@ -81,10 +81,23 @@ public function deleteRevision(NodeInterface $node) { * {@inheritdoc} */ public function update(NodeInterface $node) { - $this->database->update('forum') - ->fields(['tid' => $node->forum_tid]) - ->condition('vid', $node->getRevisionId()) - ->execute(); + if (count($node->forum_tid) > 1) { + // If there is more than one value, we're leaving a shadow. + // Create a new record. + $this->database->insert('forum') + ->fields(array( + 'tid' => $node->forum_tid, + 'vid' => $node->getRevisionId(), + 'nid' => $node->id(), + )) + ->execute(); + } + else { + $this->database->update('forum') + ->fields(['tid' => $node->forum_tid]) + ->condition('vid', $node->getRevisionId()) + ->execute(); + } } /** diff --git a/core/modules/forum/tests/src/Functional/ForumTest.php b/core/modules/forum/tests/src/Functional/ForumTest.php index af331916b9..438531a276 100644 --- a/core/modules/forum/tests/src/Functional/ForumTest.php +++ b/core/modules/forum/tests/src/Functional/ForumTest.php @@ -650,15 +650,21 @@ private function verifyForums(EntityInterface $node, $admin, $response = 200) { $this->assertText(t('Forum topic @title has been updated.', ['@title' => $edit['title[0][value]']]), 'Forum node was edited'); // Verify topic was moved to a different forum. - $forum_tid = $this->container + $forum_tids = $this->container ->get('database') ->select('forum', 'f') ->fields('f', ['tid']) ->condition('nid', $node->id()) ->condition('vid', $node->getRevisionId()) ->execute() - ->fetchField(); - $this->assertTrue($forum_tid == $this->rootForum['tid'], 'The forum topic is linked to a different forum'); + ->fetchCol(); + $expected = [$this->rootForum['tid'], $this->forum['tid']]; + $difference = array_diff($expected, $forum_tids); + $this->assertEmpty($difference, 'The forum topic is linked to a different forum and the shadow remains'); + + // Verify the shadow topic title is shown. + $this->drupalGet('forum/' . $this->forum['tid']); + $this->assertSession()->responseContains($edit['title[0][value]'], 'Shadow topic title is shown'); // Delete forum node. $this->drupalPostForm('node/' . $node->id() . '/delete', [], t('Delete'));