diff --git a/core/modules/taxonomy/taxonomy.install b/core/modules/taxonomy/taxonomy.install index bcf64aca5d..b58b6d710c 100644 --- a/core/modules/taxonomy/taxonomy.install +++ b/core/modules/taxonomy/taxonomy.install @@ -248,3 +248,48 @@ function taxonomy_update_8702(&$sandbox) { } $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['current'] / $sandbox['max']); } + +/** + * Add unpublished nodes to the taxonomy index table. + */ +function taxonomy_update_8703(&$sandbox) { + if (!isset($sandbox['total'])) { + // Initialize state for future calls. + $sandbox['last'] = 0; + $sandbox['count'] = 0; + + $query = db_select('node_field_data', 'n') + ->condition('n.status', NODE_NOT_PUBLISHED); + $sandbox['total'] = $query->countQuery()->execute()->fetchField(); + } + + if ($sandbox['total']) { + // Operate on every unpublished node, in batches. + $batch_size = 100; + $query = db_select('node_field_data', 'n'); + $query + ->fields('n', array('nid')) + ->condition('n.nid', $sandbox['last'], '>') + ->condition('n.status', NODE_NOT_PUBLISHED) + ->orderBy('n.nid', 'ASC') + ->range(0, $batch_size); + $records = $query->execute(); + // Build the taxonomy index for each node. + foreach ($records as $record) { + $node = node_load($record->nid); + + // Delete node index to avoid integrity constraint violation errors. + taxonomy_delete_node_index($node); + taxonomy_build_node_index($node); + $sandbox['last'] = $record->nid; + } + $sandbox['count'] += $batch_size; + } + // Finish after all the unpublished nodes have been processed. + if ($sandbox['count'] < $sandbox['total']) { + $sandbox['#finished'] = FALSE; + } + else { + $sandbox['#finished'] = TRUE; + } +} diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module index f027bb462d..34296b87d3 100644 --- a/core/modules/taxonomy/taxonomy.module +++ b/core/modules/taxonomy/taxonomy.module @@ -11,6 +11,7 @@ use Drupal\Core\Render\Element; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Url; +use Drupal\node\NodeInterface; use Drupal\taxonomy\Entity\Term; use Drupal\taxonomy\Entity\Vocabulary; use Drupal\taxonomy\TermInterface; @@ -489,20 +490,21 @@ function taxonomy_node_insert(EntityInterface $node) { * The index lists all terms that are related to a given node entity, and is * therefore maintained at the entity level. * - * @param \Drupal\node\Entity\Node $node + * @param \Drupal\node\NodeInterface $node * The node entity. */ -function taxonomy_build_node_index($node) { +function taxonomy_build_node_index(NodeInterface $node) { // We maintain a denormalized table of term/node relationships, containing // only data for current, published nodes. if (!\Drupal::config('taxonomy.settings')->get('maintain_index_table') || !(\Drupal::entityManager()->getStorage('node') instanceof SqlContentEntityStorage)) { return; } - $status = $node->isPublished(); - $sticky = (int) $node->isSticky(); - // We only maintain the taxonomy index for published nodes. - if ($status && $node->isDefaultRevision()) { + // We only maintain the taxonomy index for the default node revision. + if ($node->isDefaultRevision()) { + $status = (int) $node->isPublished(); + $sticky = (int) $node->isSticky(); + // Collect a unique list of all the term IDs from all node fields. $tid_all = []; $entity_reference_class = 'Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem'; @@ -525,7 +527,7 @@ function taxonomy_build_node_index($node) { $connection = \Drupal::database(); foreach ($tid_all as $tid) { $connection->merge('taxonomy_index') - ->key(['nid' => $node->id(), 'tid' => $tid, 'status' => $node->isPublished()]) + ->key(['nid' => $node->id(), 'tid' => $tid, 'status' => $status]) ->fields(['sticky' => $sticky, 'created' => $node->getCreatedTime()]) ->execute(); } diff --git a/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php b/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php index 64588c05f7..469c15caaf 100644 --- a/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php +++ b/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php @@ -108,6 +108,21 @@ public function testTaxonomyIndex() { ])->fetchField(); $this->assertEqual(1, $index_count, 'Term 1 is indexed once.'); + // Check that the node status is stored correctly. + $node_status = (int) db_query('SELECT status FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [ + ':nid' => $node->id(), + ':tid' => $term_1->id(), + ])->fetchField(); + $this->assertEqual(1, $node_status, 'Term 1 is index once with the node status published.'); + + // Un publish the article, this should update the register. + $node->setUnpublished()->save(); + $node_status = (int) db_query('SELECT status FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [ + ':nid' => $node->id(), + ':tid' => $term_1->id(), + ])->fetchField(); + $this->assertEqual(0, $node_status, 'Term 1 is index once with the node status unpublished.'); + // Update the article to change one term. $edit["{$this->fieldName1}[]"] = $term_2->id(); $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));