diff --git a/core/modules/field/field.api.php b/core/modules/field/field.api.php index 329cf16..51d2287 100644 --- a/core/modules/field/field.api.php +++ b/core/modules/field/field.api.php @@ -461,13 +461,14 @@ function hook_field_presave($entity_type, $entity, $field, $instance, $langcode, */ function hook_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items) { if (variable_get('taxonomy_maintain_index_table', TRUE) && $field['storage']['type'] == 'field_sql_storage' && $entity_type == 'node' && $entity->status) { - $query = db_insert('taxonomy_index')->fields(array('nid', 'tid', 'sticky', 'created', )); + $query = db_insert('taxonomy_index')->fields(array('nid', 'tid', 'sticky', 'created', 'status')); foreach ($items as $item) { $query->values(array( 'nid' => $entity->nid, 'tid' => $item['tid'], 'sticky' => $entity->sticky, 'created' => $entity->created, + 'status' => $entity->status )); } $query->execute(); @@ -505,13 +506,14 @@ function hook_field_update($entity_type, $entity, $field, $instance, $langcode, } // Only save data to the table if the node is published. if ($entity->status) { - $query = db_insert('taxonomy_index')->fields(array('nid', 'tid', 'sticky', 'created')); + $query = db_insert('taxonomy_index')->fields(array('nid', 'tid', 'sticky', 'created', 'status')); foreach ($items as $item) { $query->values(array( 'nid' => $entity->nid, 'tid' => $item['tid'], 'sticky' => $entity->sticky, 'created' => $entity->created, + 'status' => $entity->status, )); } $query->execute(); diff --git a/core/modules/taxonomy/taxonomy.install b/core/modules/taxonomy/taxonomy.install index 3e07259..9719cd4 100644 --- a/core/modules/taxonomy/taxonomy.install +++ b/core/modules/taxonomy/taxonomy.install @@ -196,9 +196,15 @@ function taxonomy_schema() { 'not null' => TRUE, 'default'=> 0, ), + 'status' => array( + 'description' => 'Boolean indicating whether the node is published.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 1, + ), ), 'indexes' => array( - 'term_node' => array('tid', 'sticky', 'created'), + 'term_node' => array('tid', 'sticky', 'created', 'status'), 'nid' => array('nid'), ), 'foreign keys' => array( @@ -245,4 +251,57 @@ function taxonomy_field_schema($field) { */ function taxonomy_update_8000() { db_drop_field('taxonomy_vocabulary', 'module'); +} + +/** + * Add the {taxonomy_index}.status field and add it to the {taxonomy_index} + * term_node index. Add records for unpublished nodes to {taxonomy_index}. + */ +function taxonomy_update_8001(&$sandbox) { + db_add_field('taxonomy_index', 'status', array( + 'description' => 'Boolean indicating whether the node is published.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 1, + )); + db_drop_index('taxonomy_index', 'term_node'); + db_add_index('taxonomy_index', 'term_node', array('tid', 'sticky', 'created', 'status')); + + // Add records to {taxonomy_index} for unpublished nodes. + if (!isset($sandbox['total'])) { + // Initialize state for future calls. + $sandbox['last'] = 0; + $sandbox['count'] = 0; + + $query = db_select('node', 'n') + ->condition('status', NODE_NOT_PUBLISHED); + $sandbox['total'] = $query->countQuery()->execute()->fetchField(); + } + elseif ($sandbox['total']) { + // Operate on every unpublished node (wheee!), in batches. + $batch_size = 100; + $query = db_select('node', 'n'); + $query + ->fields('n', array('nid')) + ->condition('n.nid', $sandbox['last'], '>') + ->condition('status', NODE_NOT_PUBLISHED) + ->orderBy('n.nid', 'ASC') + ->range(0, $batch_size); + $nodes = $query->execute(); + // Build the taxonomy index for each node. + foreach ($nodes as $node) { + $node = node_load($node->nid); + taxonomy_build_node_index($node); + $sandbox['last'] = $node->nid; + } + + $sandbox['count'] += $batch_size; + } + + if ($sandbox['count'] < $sandbox['total']) { + $sandbox['#finished'] = FALSE; + } + else { + $sandbox['#finished'] = TRUE; + } } \ No newline at end of file diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module index 3a9258b..d433e66 100644 --- a/core/modules/taxonomy/taxonomy.module +++ b/core/modules/taxonomy/taxonomy.module @@ -223,6 +223,7 @@ function taxonomy_select_nodes($tid, $pager = TRUE, $limit = FALSE, $order = arr $query = db_select('taxonomy_index', 't'); $query->addTag('node_access'); $query->condition('tid', $tid); + $query->condition('status', NODE_PUBLISHED); if ($pager) { $count_query = clone $query; $count_query->addExpression('COUNT(t.nid)'); @@ -1830,7 +1831,7 @@ function taxonomy_node_insert($node) { */ function taxonomy_build_node_index($node) { // We maintain a denormalized table of term/node relationships, containing - // only data for current, published nodes. + // only data for current nodes. $status = NULL; if (variable_get('taxonomy_maintain_index_table', TRUE)) { // If a node property is not set in the node object when node_save() is @@ -1844,47 +1845,45 @@ function taxonomy_build_node_index($node) { $sticky = (int)(!empty($node->sticky)); } } - // We only maintain the taxonomy index for published nodes. - if ($status) { - // Collect a unique list of all the term IDs from all node fields. - $tid_all = array(); - foreach (field_info_instances('node', $node->type) as $instance) { - $field_name = $instance['field_name']; - $field = field_info_field($field_name); - if ($field['module'] == 'taxonomy' && $field['storage']['type'] == 'field_sql_storage') { - // If a field value is not set in the node object when node_save() is - // called, the old value from $node->original is used. - if (isset($node->{$field_name})) { - $items = $node->{$field_name}; - } - elseif (isset($node->original->{$field_name})) { - $items = $node->original->{$field_name}; - } - else { - continue; - } - foreach (field_available_languages('node', $field) as $langcode) { - if (!empty($items[$langcode])) { - foreach ($items[$langcode] as $item) { - $tid_all[$item['tid']] = $item['tid']; - } + // Collect a unique list of all the term IDs from all node fields. + $tid_all = array(); + foreach (field_info_instances('node', $node->type) as $instance) { + $field_name = $instance['field_name']; + $field = field_info_field($field_name); + if ($field['module'] == 'taxonomy' && $field['storage']['type'] == 'field_sql_storage') { + // If a field value is not set in the node object when node_save() is + // called, the old value from $node->original is used. + if (isset($node->{$field_name})) { + $items = $node->{$field_name}; + } + elseif (isset($node->original->{$field_name})) { + $items = $node->original->{$field_name}; + } + else { + continue; + } + foreach (field_available_languages('node', $field) as $langcode) { + if (!empty($items[$langcode])) { + foreach ($items[$langcode] as $item) { + $tid_all[$item['tid']] = $item['tid']; } } } } - // Insert index entries for all the node's terms. - if (!empty($tid_all)) { - $query = db_insert('taxonomy_index')->fields(array('nid', 'tid', 'sticky', 'created')); - foreach ($tid_all as $tid) { - $query->values(array( - 'nid' => $node->nid, - 'tid' => $tid, - 'sticky' => $sticky, - 'created' => $node->created, - )); - } - $query->execute(); + } + // Insert index entries for all the node's terms. + if (!empty($tid_all)) { + $query = db_insert('taxonomy_index')->fields(array('nid', 'tid', 'sticky', 'created', 'status')); + foreach ($tid_all as $tid) { + $query->values(array( + 'nid' => $node->nid, + 'tid' => $tid, + 'sticky' => $sticky, + 'created' => $node->created, + 'status' => $node->status, + )); } + $query->execute(); } }