node_update_7006

Versions
mediamosa-21
node_update_7006(&$context)

Convert body and teaser from node properties to fields, and migrate status/comment/promote and sticky columns to the {node_revision} table.

Related topics

Code

modules/node/node.install, line 470

<?php
function node_update_7006(&$context) {
  $context['#finished'] = 0;

  // Get node type info for every invocation.
  drupal_static_reset('_node_types_build');
  $node_types = node_type_get_types();

  if (!isset($context['total'])) {
    // Initial invocation.

    // Re-save node types to create body field instances.
    foreach ($node_types as $type => $info) {
      if ($info->has_body) {
        node_type_save($info);
      }
    }

    // Initialize state for future calls.
    $context['last'] = 0;
    $context['count'] = 0;

    $query = db_select('node', 'n');
    $query->join('node_revision', 'nr', 'n.vid = nr.vid');
    $context['total'] = $query->countQuery()->execute()->fetchField();
  }
  else {
    // Subsequent invocations.

    // Grab the body field ID for field_sql_storage_field_storage_write().
    $body_field = field_info_field('body');
    $body_field_id = $body_field['id'];

    $found = FALSE;
    if ($context['total']) {
      // Operate on every revision of every node (whee!), in batches.
      $batch_size = 200;
      $query = db_select('node_revision', 'nr');
      $query->innerJoin('node', 'n', 'n.vid = nr.vid');
      $query
        ->fields('nr', array('nid', 'vid', 'body', 'teaser', 'format'))
        ->fields('n', array('type', 'status', 'comment', 'promote', 'sticky'))
        ->condition('nr.vid', $context['last'], '>')
        ->orderBy('nr.vid', 'ASC')
        ->range(0, $batch_size);
      $revisions = $query->execute();

      // Load each reversion of each node, set up 'body'
      // appropriately, and save the node's field data.  Note that
      // node_load() will not return the body or teaser values from
      // {node_revision} because those columns have been removed from the
      // schema structure in memory (but not yet from the database),
      // so we get the values from the explicit query of the table
      // instead.
      foreach ($revisions as $revision) {
        $found = TRUE;

        if ($node_types[$revision->type]->has_body) {
          $node = (object) array(
            'nid' => $revision->nid,
            'vid' => $revision->vid,
            'type' => $revision->type,
          );
          if (!empty($revision->teaser) && $revision->teaser != text_summary($revision->body)) {
            $node->body[LANGUAGE_NONE][0]['summary'] = $revision->teaser;
          }
          // Do this after text_summary() above.
          $break = '<!--break-->';
          if (substr($revision->body, 0, strlen($break)) == $break) {
            $revision->body = substr($revision->body, strlen($break));
          }
          $node->body[LANGUAGE_NONE][0]['value'] = $revision->body;
          // Explicitly store the current default text format if the revision
          // did not have its own text format. Similar conversions for other
          // core modules are performed in filter_update_7005(), but we do this
          // one here since we are already migrating the data.
          $node->body[LANGUAGE_NONE][0]['format'] = !empty($revision->format) ? $revision->format : variable_get('filter_default_format', 1);
          // This is a core update and no contrib modules are enabled yet, so
          // we can assume default field storage for a faster update.
          field_sql_storage_field_storage_write('node', $node, FIELD_STORAGE_INSERT, array($body_field_id));
        }

        // Migrate the status columns to the {node_revision} table.
        db_update('node_revision')
          ->fields(array(
            'status' => $revision->status,
            'comment' => $revision->comment,
            'promote' => $revision->promote,
            'sticky' => $revision->sticky,
          ))
          ->condition('vid', $revision->vid)
          ->execute();

        $context['last'] = $revision->vid;
        $context['count'] += 1;
      }

      $context['#finished'] = min(0.99, $context['count'] / $context['total']);
    }

    if (!$found) {
      // All nodes are processed.

      // Remove the now-obsolete body info from node_revision.
      db_drop_field('node_revision', 'body');
      db_drop_field('node_revision', 'teaser');
      db_drop_field('node_revision', 'format');

      // We're done.
      $context['#finished'] = 1;
      return t("!number node body and teaser properties migrated to the 'body' field.", array('!number' => $context['total']));
    }
  }
}
?>