cms/drupal/modules/node/node.install
changeset 541 e756a8c72c3d
equal deleted inserted replaced
540:07239de796bb 541:e756a8c72c3d
       
     1 <?php
       
     2 
       
     3 /**
       
     4  * @file
       
     5  * Install, update and uninstall functions for the node module.
       
     6  */
       
     7 
       
     8 /**
       
     9  * Implements hook_schema().
       
    10  */
       
    11 function node_schema() {
       
    12   $schema['node'] = array(
       
    13     'description' => 'The base table for nodes.',
       
    14     'fields' => array(
       
    15       'nid' => array(
       
    16         'description' => 'The primary identifier for a node.',
       
    17         'type' => 'serial',
       
    18         'unsigned' => TRUE,
       
    19         'not null' => TRUE,
       
    20       ),
       
    21       // Defaults to NULL in order to avoid a brief period of potential
       
    22       // deadlocks on the index.
       
    23       'vid' => array(
       
    24         'description' => 'The current {node_revision}.vid version identifier.',
       
    25         'type' => 'int',
       
    26         'unsigned' => TRUE,
       
    27         'not null' => FALSE,
       
    28         'default' => NULL,
       
    29       ),
       
    30       'type' => array(
       
    31         'description' => 'The {node_type}.type of this node.',
       
    32         'type' => 'varchar',
       
    33         'length' => 32,
       
    34         'not null' => TRUE,
       
    35         'default' => '',
       
    36       ),
       
    37       'language' => array(
       
    38         'description' => 'The {languages}.language of this node.',
       
    39         'type' => 'varchar',
       
    40         'length' => 12,
       
    41         'not null' => TRUE,
       
    42         'default' => '',
       
    43       ),
       
    44       'title' => array(
       
    45         'description' => 'The title of this node, always treated as non-markup plain text.',
       
    46         'type' => 'varchar',
       
    47         'length' => 255,
       
    48         'not null' => TRUE,
       
    49         'default' => '',
       
    50       ),
       
    51       'uid' => array(
       
    52         'description' => 'The {users}.uid that owns this node; initially, this is the user that created it.',
       
    53         'type' => 'int',
       
    54         'not null' => TRUE,
       
    55         'default' => 0,
       
    56       ),
       
    57       'status' => array(
       
    58         'description' => 'Boolean indicating whether the node is published (visible to non-administrators).',
       
    59         'type' => 'int',
       
    60         'not null' => TRUE,
       
    61         'default' => 1,
       
    62       ),
       
    63       'created' => array(
       
    64         'description' => 'The Unix timestamp when the node was created.',
       
    65         'type' => 'int',
       
    66         'not null' => TRUE,
       
    67         'default' => 0,
       
    68       ),
       
    69       'changed' => array(
       
    70         'description' => 'The Unix timestamp when the node was most recently saved.',
       
    71         'type' => 'int',
       
    72         'not null' => TRUE,
       
    73         'default' => 0,
       
    74       ),
       
    75       'comment' => array(
       
    76         'description' => 'Whether comments are allowed on this node: 0 = no, 1 = closed (read only), 2 = open (read/write).',
       
    77         'type' => 'int',
       
    78         'not null' => TRUE,
       
    79         'default' => 0,
       
    80       ),
       
    81       'promote' => array(
       
    82         'description' => 'Boolean indicating whether the node should be displayed on the front page.',
       
    83         'type' => 'int',
       
    84         'not null' => TRUE,
       
    85         'default' => 0,
       
    86       ),
       
    87       'sticky' => array(
       
    88         'description' => 'Boolean indicating whether the node should be displayed at the top of lists in which it appears.',
       
    89         'type' => 'int',
       
    90         'not null' => TRUE,
       
    91         'default' => 0,
       
    92       ),
       
    93       'tnid' => array(
       
    94         'description' => 'The translation set id for this node, which equals the node id of the source post in each set.',
       
    95         'type' => 'int',
       
    96         'unsigned' => TRUE,
       
    97         'not null' => TRUE,
       
    98         'default' => 0,
       
    99       ),
       
   100       'translate' => array(
       
   101         'description' => 'A boolean indicating whether this translation page needs to be updated.',
       
   102         'type' => 'int',
       
   103         'not null' => TRUE,
       
   104         'default' => 0,
       
   105       ),
       
   106     ),
       
   107     'indexes' => array(
       
   108       'node_changed'        => array('changed'),
       
   109       'node_created'        => array('created'),
       
   110       'node_frontpage'      => array('promote', 'status', 'sticky', 'created'),
       
   111       'node_status_type'    => array('status', 'type', 'nid'),
       
   112       'node_title_type'     => array('title', array('type', 4)),
       
   113       'node_type'           => array(array('type', 4)),
       
   114       'uid'                 => array('uid'),
       
   115       'tnid'                => array('tnid'),
       
   116       'translate'           => array('translate'),
       
   117       'language'            => array('language'),
       
   118     ),
       
   119     'unique keys' => array(
       
   120       'vid' => array('vid'),
       
   121     ),
       
   122     'foreign keys' => array(
       
   123       'node_revision' => array(
       
   124         'table' => 'node_revision',
       
   125         'columns' => array('vid' => 'vid'),
       
   126       ),
       
   127       'node_author' => array(
       
   128         'table' => 'users',
       
   129         'columns' => array('uid' => 'uid'),
       
   130       ),
       
   131     ),
       
   132     'primary key' => array('nid'),
       
   133   );
       
   134 
       
   135   $schema['node_access'] = array(
       
   136     'description' => 'Identifies which realm/grant pairs a user must possess in order to view, update, or delete specific nodes.',
       
   137     'fields' => array(
       
   138       'nid' => array(
       
   139         'description' => 'The {node}.nid this record affects.',
       
   140         'type' => 'int',
       
   141         'unsigned' => TRUE,
       
   142         'not null' => TRUE,
       
   143         'default' => 0,
       
   144       ),
       
   145       'gid' => array(
       
   146         'description' => "The grant ID a user must possess in the specified realm to gain this row's privileges on the node.",
       
   147         'type' => 'int',
       
   148         'unsigned' => TRUE,
       
   149         'not null' => TRUE,
       
   150         'default' => 0,
       
   151       ),
       
   152       'realm' => array(
       
   153         'description' => 'The realm in which the user must possess the grant ID. Each node access node can define one or more realms.',
       
   154         'type' => 'varchar',
       
   155         'length' => 255,
       
   156         'not null' => TRUE,
       
   157         'default' => '',
       
   158       ),
       
   159       'grant_view' => array(
       
   160         'description' => 'Boolean indicating whether a user with the realm/grant pair can view this node.',
       
   161         'type' => 'int',
       
   162         'unsigned' => TRUE,
       
   163         'not null' => TRUE,
       
   164         'default' => 0,
       
   165         'size' => 'tiny',
       
   166       ),
       
   167       'grant_update' => array(
       
   168         'description' => 'Boolean indicating whether a user with the realm/grant pair can edit this node.',
       
   169         'type' => 'int',
       
   170         'unsigned' => TRUE,
       
   171         'not null' => TRUE,
       
   172         'default' => 0,
       
   173         'size' => 'tiny',
       
   174       ),
       
   175       'grant_delete' => array(
       
   176         'description' => 'Boolean indicating whether a user with the realm/grant pair can delete this node.',
       
   177         'type' => 'int',
       
   178         'unsigned' => TRUE,
       
   179         'not null' => TRUE,
       
   180         'default' => 0,
       
   181         'size' => 'tiny',
       
   182       ),
       
   183     ),
       
   184     'primary key' => array('nid', 'gid', 'realm'),
       
   185     'foreign keys' => array(
       
   186       'affected_node' => array(
       
   187         'table' => 'node',
       
   188         'columns' => array('nid' => 'nid'),
       
   189       ),
       
   190      ),
       
   191   );
       
   192 
       
   193   $schema['node_revision'] = array(
       
   194     'description' => 'Stores information about each saved version of a {node}.',
       
   195     'fields' => array(
       
   196       'nid' => array(
       
   197         'description' => 'The {node} this version belongs to.',
       
   198         'type' => 'int',
       
   199         'unsigned' => TRUE,
       
   200         'not null' => TRUE,
       
   201         'default' => 0,
       
   202       ),
       
   203       'vid' => array(
       
   204         'description' => 'The primary identifier for this version.',
       
   205         'type' => 'serial',
       
   206         'unsigned' => TRUE,
       
   207         'not null' => TRUE,
       
   208       ),
       
   209       'uid' => array(
       
   210         'description' => 'The {users}.uid that created this version.',
       
   211         'type' => 'int',
       
   212         'not null' => TRUE,
       
   213         'default' => 0,
       
   214       ),
       
   215       'title' => array(
       
   216         'description' => 'The title of this version.',
       
   217         'type' => 'varchar',
       
   218         'length' => 255,
       
   219         'not null' => TRUE,
       
   220         'default' => '',
       
   221       ),
       
   222       'log' => array(
       
   223         'description' => 'The log entry explaining the changes in this version.',
       
   224         'type' => 'text',
       
   225         'not null' => TRUE,
       
   226         'size' => 'big',
       
   227       ),
       
   228       'timestamp' => array(
       
   229         'description' => 'A Unix timestamp indicating when this version was created.',
       
   230         'type' => 'int',
       
   231         'not null' => TRUE,
       
   232         'default' => 0,
       
   233       ),
       
   234       'status' => array(
       
   235         'description' => 'Boolean indicating whether the node (at the time of this revision) is published (visible to non-administrators).',
       
   236         'type' => 'int',
       
   237         'not null' => TRUE,
       
   238         'default' => 1,
       
   239       ),
       
   240       'comment' => array(
       
   241         'description' => 'Whether comments are allowed on this node (at the time of this revision): 0 = no, 1 = closed (read only), 2 = open (read/write).',
       
   242         'type' => 'int',
       
   243         'not null' => TRUE,
       
   244         'default' => 0,
       
   245       ),
       
   246       'promote' => array(
       
   247         'description' => 'Boolean indicating whether the node (at the time of this revision) should be displayed on the front page.',
       
   248         'type' => 'int',
       
   249         'not null' => TRUE,
       
   250         'default' => 0,
       
   251       ),
       
   252       'sticky' => array(
       
   253         'description' => 'Boolean indicating whether the node (at the time of this revision) should be displayed at the top of lists in which it appears.',
       
   254         'type' => 'int',
       
   255         'not null' => TRUE,
       
   256         'default' => 0,
       
   257       ),
       
   258     ),
       
   259     'indexes' => array(
       
   260       'nid' => array('nid'),
       
   261       'uid' => array('uid'),
       
   262     ),
       
   263     'primary key' => array('vid'),
       
   264     'foreign keys' => array(
       
   265       'versioned_node' => array(
       
   266         'table' => 'node',
       
   267         'columns' => array('nid' => 'nid'),
       
   268       ),
       
   269       'version_author' => array(
       
   270         'table' => 'users',
       
   271         'columns' => array('uid' => 'uid'),
       
   272       ),
       
   273     ),
       
   274   );
       
   275 
       
   276   $schema['node_type'] = array(
       
   277     'description' => 'Stores information about all defined {node} types.',
       
   278     'fields' => array(
       
   279       'type' => array(
       
   280         'description' => 'The machine-readable name of this type.',
       
   281         'type' => 'varchar',
       
   282         'length' => 32,
       
   283         'not null' => TRUE,
       
   284       ),
       
   285       'name' => array(
       
   286         'description' => 'The human-readable name of this type.',
       
   287         'type' => 'varchar',
       
   288         'length' => 255,
       
   289         'not null' => TRUE,
       
   290         'default' => '',
       
   291         'translatable' => TRUE,
       
   292       ),
       
   293       'base' => array(
       
   294         'description' => 'The base string used to construct callbacks corresponding to this node type.',
       
   295         'type' => 'varchar',
       
   296         'length' => 255,
       
   297         'not null' => TRUE,
       
   298       ),
       
   299       'module' => array(
       
   300         'description' => 'The module defining this node type.',
       
   301         'type' => 'varchar',
       
   302         'length' => 255,
       
   303         'not null' => TRUE,
       
   304       ),
       
   305       'description' => array(
       
   306         'description' => 'A brief description of this type.',
       
   307         'type' => 'text',
       
   308         'not null' => TRUE,
       
   309         'size' => 'medium',
       
   310         'translatable' => TRUE,
       
   311       ),
       
   312       'help' => array(
       
   313         'description' => 'Help information shown to the user when creating a {node} of this type.',
       
   314         'type' => 'text',
       
   315         'not null' => TRUE,
       
   316         'size' => 'medium',
       
   317         'translatable' => TRUE,
       
   318       ),
       
   319       'has_title' => array(
       
   320         'description' => 'Boolean indicating whether this type uses the {node}.title field.',
       
   321         'type' => 'int',
       
   322         'unsigned' => TRUE,
       
   323         'not null' => TRUE,
       
   324         'size' => 'tiny',
       
   325       ),
       
   326       'title_label' => array(
       
   327         'description' => 'The label displayed for the title field on the edit form.',
       
   328         'type' => 'varchar',
       
   329         'length' => 255,
       
   330         'not null' => TRUE,
       
   331         'default' => '',
       
   332         'translatable' => TRUE,
       
   333       ),
       
   334       'custom' => array(
       
   335         'description' => 'A boolean indicating whether this type is defined by a module (FALSE) or by a user via Add content type (TRUE).',
       
   336         'type' => 'int',
       
   337         'not null' => TRUE,
       
   338         'default' => 0,
       
   339         'size' => 'tiny',
       
   340       ),
       
   341       'modified' => array(
       
   342         'description' => 'A boolean indicating whether this type has been modified by an administrator; currently not used in any way.',
       
   343         'type' => 'int',
       
   344         'not null' => TRUE,
       
   345         'default' => 0,
       
   346         'size' => 'tiny',
       
   347       ),
       
   348       'locked' => array(
       
   349         'description' => 'A boolean indicating whether the administrator can change the machine name of this type.',
       
   350         'type' => 'int',
       
   351         'not null' => TRUE,
       
   352         'default' => 0,
       
   353         'size' => 'tiny',
       
   354       ),
       
   355       'disabled' => array(
       
   356         'description' => 'A boolean indicating whether the node type is disabled.',
       
   357         'type' => 'int',
       
   358         'not null' => TRUE,
       
   359         'default' => 0,
       
   360         'size' => 'tiny'
       
   361       ),
       
   362       'orig_type' => array(
       
   363         'description' => 'The original machine-readable name of this node type. This may be different from the current type name if the locked field is 0.',
       
   364         'type' => 'varchar',
       
   365         'length' => 255,
       
   366         'not null' => TRUE,
       
   367         'default' => '',
       
   368       ),
       
   369     ),
       
   370     'primary key' => array('type'),
       
   371   );
       
   372 
       
   373   $schema['block_node_type'] = array(
       
   374     'description' => 'Sets up display criteria for blocks based on content types',
       
   375     'fields' => array(
       
   376       'module' => array(
       
   377         'type' => 'varchar',
       
   378         'length' => 64,
       
   379         'not null' => TRUE,
       
   380         'description' => "The block's origin module, from {block}.module.",
       
   381       ),
       
   382       'delta' => array(
       
   383         'type' => 'varchar',
       
   384         'length' => 32,
       
   385         'not null' => TRUE,
       
   386         'description' => "The block's unique delta within module, from {block}.delta.",
       
   387       ),
       
   388       'type' => array(
       
   389         'type' => 'varchar',
       
   390         'length' => 32,
       
   391         'not null' => TRUE,
       
   392         'description' => "The machine-readable name of this type from {node_type}.type.",
       
   393       ),
       
   394     ),
       
   395     'primary key' => array('module', 'delta', 'type'),
       
   396     'indexes' => array(
       
   397       'type' => array('type'),
       
   398     ),
       
   399   );
       
   400 
       
   401   $schema['history'] = array(
       
   402     'description' => 'A record of which {users} have read which {node}s.',
       
   403     'fields' => array(
       
   404       'uid' => array(
       
   405         'description' => 'The {users}.uid that read the {node} nid.',
       
   406         'type' => 'int',
       
   407         'not null' => TRUE,
       
   408         'default' => 0,
       
   409       ),
       
   410       'nid' => array(
       
   411         'description' => 'The {node}.nid that was read.',
       
   412         'type' => 'int',
       
   413         'unsigned' => TRUE,
       
   414         'not null' => TRUE,
       
   415         'default' => 0,
       
   416       ),
       
   417       'timestamp' => array(
       
   418         'description' => 'The Unix timestamp at which the read occurred.',
       
   419         'type' => 'int',
       
   420         'not null' => TRUE,
       
   421         'default' => 0,
       
   422       ),
       
   423     ),
       
   424     'primary key' => array('uid', 'nid'),
       
   425     'indexes' => array(
       
   426       'nid' => array('nid'),
       
   427     ),
       
   428   );
       
   429 
       
   430   return $schema;
       
   431 }
       
   432 
       
   433 /**
       
   434  * Implements hook_install().
       
   435  */
       
   436 function node_install() {
       
   437   // Populate the node access table.
       
   438   db_insert('node_access')
       
   439     ->fields(array(
       
   440       'nid' => 0,
       
   441       'gid' => 0,
       
   442       'realm' => 'all',
       
   443       'grant_view' => 1,
       
   444       'grant_update' => 0,
       
   445       'grant_delete' => 0,
       
   446     ))
       
   447     ->execute();
       
   448 }
       
   449 
       
   450 /**
       
   451  * Implements hook_update_dependencies().
       
   452  */
       
   453 function node_update_dependencies() {
       
   454   // node_update_7006() migrates node data to fields and therefore must run
       
   455   // after all Field modules have been enabled, which happens in
       
   456   // system_update_7027(). It also needs to query the {filter_format} table to
       
   457   // get a list of existing text formats, so it must run after
       
   458   // filter_update_7000(), which creates that table.
       
   459   $dependencies['node'][7006] = array(
       
   460     'system' => 7027,
       
   461     'filter' => 7000,
       
   462   );
       
   463 
       
   464   // node_update_7008() migrates role permissions and therefore must run after
       
   465   // the {role} and {role_permission} tables are properly set up, which happens
       
   466   // in user_update_7007().
       
   467   $dependencies['node'][7008] = array(
       
   468     'user' => 7007,
       
   469   );
       
   470 
       
   471   return $dependencies;
       
   472 }
       
   473 
       
   474 /**
       
   475  * Utility function: fetch the node types directly from the database.
       
   476  *
       
   477  * This function is valid for a database schema version 7000.
       
   478  *
       
   479  * @ingroup update_api
       
   480  */
       
   481 function _update_7000_node_get_types() {
       
   482   $node_types = db_query('SELECT * FROM {node_type}')->fetchAllAssoc('type', PDO::FETCH_OBJ);
       
   483 
       
   484   // Create default settings for orphan nodes.
       
   485   $all_types = db_query('SELECT DISTINCT type FROM {node}')->fetchCol();
       
   486   $extra_types = array_diff($all_types, array_keys($node_types));
       
   487 
       
   488   foreach ($extra_types as $type) {
       
   489     $type_object = new stdClass();
       
   490     $type_object->type = $type;
       
   491 
       
   492     // In Drupal 6, whether you have a body field or not is a flag in the node
       
   493     // type table. If it's enabled, nodes may or may not have an empty string
       
   494     // for the bodies. As we can't detect what this setting should be in
       
   495     // Drupal 7 without access to the Drupal 6 node type settings, we assume
       
   496     // the default, which is to enable the body field.
       
   497     $type_object->has_body = 1;
       
   498     $type_object->body_label = 'Body';
       
   499     $node_types[$type_object->type] = $type_object;
       
   500   }
       
   501   return $node_types;
       
   502 }
       
   503 
       
   504 /**
       
   505  * @addtogroup updates-6.x-to-7.x
       
   506  * @{
       
   507  */
       
   508 
       
   509 /**
       
   510  * Upgrade the node type table and fix node type 'module' attribute to avoid name-space conflicts.
       
   511  */
       
   512 function node_update_7000() {
       
   513   // Rename the module column to base.
       
   514   db_change_field('node_type', 'module', 'base', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE));
       
   515 
       
   516   db_add_field('node_type', 'module', array(
       
   517     'description' => 'The module defining this node type.',
       
   518     'type' => 'varchar',
       
   519     'default' => '',
       
   520     'length' => 255,
       
   521     'not null' => TRUE,
       
   522   ));
       
   523 
       
   524   db_add_field('node_type', 'disabled', array(
       
   525     'description' => 'A boolean indicating whether the node type is disabled.',
       
   526     'type' => 'int',
       
   527     'not null' => TRUE,
       
   528     'default' => 0,
       
   529     'size' => 'tiny'
       
   530   ));
       
   531 
       
   532   $modules = db_select('system', 's')
       
   533     ->fields('s', array('name'))
       
   534     ->condition('type', 'module');
       
   535   db_update('node_type')
       
   536     ->expression('module', 'base')
       
   537     ->condition('base', $modules, 'IN')
       
   538     ->execute();
       
   539 
       
   540   db_update('node_type')
       
   541     ->fields(array('base' => 'node_content'))
       
   542     ->condition('base', 'node')
       
   543     ->execute();
       
   544 }
       
   545 
       
   546 /**
       
   547  * Rename {node_revisions} table to {node_revision}.
       
   548  */
       
   549 function node_update_7001() {
       
   550   db_rename_table('node_revisions', 'node_revision');
       
   551 }
       
   552 
       
   553 /**
       
   554  * Extend the node_promote_status index to include all fields required for the node page query.
       
   555  */
       
   556 function node_update_7002() {
       
   557   db_drop_index('node', 'node_promote_status');
       
   558   db_add_index('node', 'node_frontpage', array('promote', 'status', 'sticky', 'created'));
       
   559 }
       
   560 
       
   561 /**
       
   562  * Remove the node_counter if the statistics module is uninstalled.
       
   563  */
       
   564 function node_update_7003() {
       
   565   if (drupal_get_installed_schema_version('statistics') == SCHEMA_UNINSTALLED) {
       
   566     db_drop_table('node_counter');
       
   567   }
       
   568 }
       
   569 
       
   570 /**
       
   571  * Extend the existing default preview and teaser settings to all node types.
       
   572  */
       
   573 function node_update_7004() {
       
   574   // Get original settings and all types.
       
   575   $original_length = variable_get('teaser_length', 600);
       
   576   $original_preview = variable_get('node_preview', 0);
       
   577 
       
   578   // Map old preview setting to new values order.
       
   579   $original_preview ? $original_preview = 2 : $original_preview = 1;
       
   580   node_type_cache_reset();
       
   581 
       
   582   // Apply original settings to all types.
       
   583   foreach (_update_7000_node_get_types() as $type => $type_object) {
       
   584     variable_set('teaser_length_' . $type, $original_length);
       
   585     variable_set('node_preview_' . $type, $original_preview);
       
   586   }
       
   587   // Delete old variable but leave 'teaser_length' for aggregator module upgrade.
       
   588   variable_del('node_preview');
       
   589 }
       
   590 
       
   591 /**
       
   592  * Add status/comment/promote and sticky columns to the {node_revision} table.
       
   593  */
       
   594 function node_update_7005() {
       
   595   foreach (array('status', 'comment', 'promote', 'sticky') as $column) {
       
   596     db_add_field('node_revision', $column, array(
       
   597       'type' => 'int',
       
   598       'not null' => TRUE,
       
   599       'default' => 0,
       
   600     ));
       
   601   }
       
   602 }
       
   603 
       
   604 /**
       
   605  * Convert body and teaser from node properties to fields, and migrate status/comment/promote and sticky columns to the {node_revision} table.
       
   606  */
       
   607 function node_update_7006(&$sandbox) {
       
   608   $sandbox['#finished'] = 0;
       
   609 
       
   610   // Get node type info for every invocation.
       
   611   node_type_cache_reset();
       
   612 
       
   613   if (!isset($sandbox['total'])) {
       
   614     // Initial invocation.
       
   615 
       
   616     // First, create the body field.
       
   617     $body_field = array(
       
   618       'field_name' => 'body',
       
   619       'type' => 'text_with_summary',
       
   620       'module' => 'text',
       
   621       'cardinality' => 1,
       
   622       'entity_types' => array('node'),
       
   623       'translatable' => TRUE,
       
   624     );
       
   625     _update_7000_field_create_field($body_field);
       
   626 
       
   627     $default_trim_length = variable_get('teaser_length', 600);
       
   628 
       
   629     // Get node type info, specifically the body field settings.
       
   630     $node_types = _update_7000_node_get_types();
       
   631 
       
   632     // Add body field instances for existing node types.
       
   633     foreach ($node_types as $node_type) {
       
   634       if ($node_type->has_body) {
       
   635         $trim_length = variable_get('teaser_length_' . $node_type->type, $default_trim_length);
       
   636 
       
   637         $instance = array(
       
   638           'entity_type' => 'node',
       
   639           'bundle' => $node_type->type,
       
   640           'label' => $node_type->body_label,
       
   641           'description' => isset($node_type->description) ? $node_type->description : '',
       
   642           'required' => (isset($node_type->min_word_count) && $node_type->min_word_count > 0) ? 1 : 0,
       
   643           'widget' => array(
       
   644             'type' => 'text_textarea_with_summary',
       
   645             'settings' => array(
       
   646               'rows' => 20,
       
   647               'summary_rows' => 5,
       
   648             ),
       
   649             'weight' => -4,
       
   650             'module' => 'text',
       
   651           ),
       
   652           'settings' => array('display_summary' => TRUE),
       
   653           'display' => array(
       
   654             'default' => array(
       
   655               'label' => 'hidden',
       
   656               'type' => 'text_default',
       
   657             ),
       
   658             'teaser' => array(
       
   659               'label' => 'hidden',
       
   660               'type' => 'text_summary_or_trimmed',
       
   661               'trim_length' => $trim_length,
       
   662             ),
       
   663           ),
       
   664         );
       
   665         _update_7000_field_create_instance($body_field, $instance);
       
   666         variable_del('teaser_length_' . $node_type->type);
       
   667       }
       
   668       // Leave 'teaser_length' variable for aggregator module upgrade.
       
   669 
       
   670       $sandbox['node_types_info'][$node_type->type] = array(
       
   671         'has_body' => $node_type->has_body,
       
   672       );
       
   673     }
       
   674 
       
   675     // Used below when updating the stored text format of each node body.
       
   676     $sandbox['existing_text_formats'] = db_query("SELECT format FROM {filter_format}")->fetchCol();
       
   677 
       
   678     // Initialize state for future calls.
       
   679     $sandbox['last'] = 0;
       
   680     $sandbox['count'] = 0;
       
   681 
       
   682     $query = db_select('node', 'n');
       
   683     $query->join('node_revision', 'nr', 'n.nid = nr.nid');
       
   684     $sandbox['total'] = $query->countQuery()->execute()->fetchField();
       
   685 
       
   686     $sandbox['body_field_id'] = $body_field['id'];
       
   687   }
       
   688   else {
       
   689     // Subsequent invocations.
       
   690 
       
   691     $found = FALSE;
       
   692     if ($sandbox['total']) {
       
   693       // Operate on every revision of every node (whee!), in batches.
       
   694       $batch_size = 200;
       
   695       $query = db_select('node_revision', 'nr');
       
   696       $query->innerJoin('node', 'n', 'n.nid = nr.nid');
       
   697       $query
       
   698         ->fields('nr', array('nid', 'vid', 'body', 'teaser', 'format'))
       
   699         ->fields('n', array('type', 'status', 'comment', 'promote', 'sticky', 'language'))
       
   700         ->condition('nr.vid', $sandbox['last'], '>')
       
   701         ->orderBy('nr.vid', 'ASC')
       
   702         ->range(0, $batch_size);
       
   703       $revisions = $query->execute();
       
   704 
       
   705       // Load each revision of each node, set up 'body'
       
   706       // appropriately, and save the node's field data.  Note that
       
   707       // node_load() will not return the body or teaser values from
       
   708       // {node_revision} because those columns have been removed from the
       
   709       // schema structure in memory (but not yet from the database),
       
   710       // so we get the values from the explicit query of the table
       
   711       // instead.
       
   712       foreach ($revisions as $revision) {
       
   713         $found = TRUE;
       
   714 
       
   715         if ($sandbox['node_types_info'][$revision->type]['has_body']) {
       
   716           $node = (object) array(
       
   717             'nid' => $revision->nid,
       
   718             'vid' => $revision->vid,
       
   719             'type' => $revision->type,
       
   720           );
       
   721           // After node_update_7009() we will always have LANGUAGE_NONE as
       
   722           // language neutral language code, but here we still have empty
       
   723           // strings.
       
   724           $langcode = empty($revision->language) ? LANGUAGE_NONE : $revision->language;
       
   725           if (!empty($revision->teaser) && $revision->teaser != text_summary($revision->body)) {
       
   726             $node->body[$langcode][0]['summary'] = $revision->teaser;
       
   727           }
       
   728           // Do this after text_summary() above.
       
   729           $break = '<!--break-->';
       
   730           if (substr($revision->body, 0, strlen($break)) == $break) {
       
   731             $revision->body = substr($revision->body, strlen($break));
       
   732           }
       
   733           $node->body[$langcode][0]['value'] = $revision->body;
       
   734           // Update the revision's text format for the changes to the Drupal 7
       
   735           // filter system. This uses the same kind of logic that occurs, for
       
   736           // example, in user_update_7010(), but we do this here rather than
       
   737           // via a separate set of database queries, since we are already
       
   738           // migrating the data.
       
   739           if (empty($revision->body) && empty($revision->format)) {
       
   740             $node->body[$langcode][0]['format'] = NULL;
       
   741           }
       
   742           elseif (!in_array($revision->format, $sandbox['existing_text_formats'])) {
       
   743             $node->body[$langcode][0]['format'] = variable_get('filter_default_format', 1);
       
   744           }
       
   745           else {
       
   746             $node->body[$langcode][0]['format'] = $revision->format;
       
   747           }
       
   748           // This is a core update and no contrib modules are enabled yet, so
       
   749           // we can assume default field storage for a faster update.
       
   750           _update_7000_field_sql_storage_write('node', $node->type, $node->nid, $node->vid, 'body', $node->body);
       
   751         }
       
   752 
       
   753         // Migrate the status columns to the {node_revision} table.
       
   754         db_update('node_revision')
       
   755           ->fields(array(
       
   756             'status' => $revision->status,
       
   757             'comment' => $revision->comment,
       
   758             'promote' => $revision->promote,
       
   759             'sticky' => $revision->sticky,
       
   760           ))
       
   761           ->condition('vid', $revision->vid)
       
   762           ->execute();
       
   763 
       
   764         $sandbox['last'] = $revision->vid;
       
   765         $sandbox['count'] += 1;
       
   766       }
       
   767 
       
   768       $sandbox['#finished'] = min(0.99, $sandbox['count'] / $sandbox['total']);
       
   769     }
       
   770 
       
   771     if (!$found) {
       
   772       // All nodes are processed.
       
   773 
       
   774       // Remove the now-obsolete body info from node_revision.
       
   775       db_drop_field('node_revision', 'body');
       
   776       db_drop_field('node_revision', 'teaser');
       
   777       db_drop_field('node_revision', 'format');
       
   778 
       
   779       // Remove node_type properties related to the former 'body'.
       
   780       db_drop_field('node_type', 'has_body');
       
   781       db_drop_field('node_type', 'body_label');
       
   782 
       
   783       // We're done.
       
   784       $sandbox['#finished'] = 1;
       
   785     }
       
   786   }
       
   787 }
       
   788 
       
   789 /**
       
   790  * Remove column min_word_count.
       
   791  */
       
   792 function node_update_7007() {
       
   793   db_drop_field('node_type', 'min_word_count');
       
   794 }
       
   795 
       
   796 /**
       
   797  * Split the 'administer nodes' permission from 'access content overview'.
       
   798  */
       
   799 function node_update_7008() {
       
   800   $roles = user_roles(FALSE, 'administer nodes');
       
   801   foreach ($roles as $rid => $role) {
       
   802     _update_7000_user_role_grant_permissions($rid, array('access content overview'), 'node');
       
   803   }
       
   804 }
       
   805 
       
   806 /**
       
   807  * Convert node languages from the empty string to LANGUAGE_NONE.
       
   808  */
       
   809 function node_update_7009() {
       
   810   db_update('node')
       
   811     ->fields(array('language' => LANGUAGE_NONE))
       
   812     ->condition('language', '')
       
   813     ->execute();
       
   814 }
       
   815 
       
   816 /**
       
   817  * Add the {block_node_type} table.
       
   818  */
       
   819 function node_update_7010() {
       
   820   $schema['block_node_type'] = array(
       
   821     'description' => 'Sets up display criteria for blocks based on content types',
       
   822     'fields' => array(
       
   823       'module' => array(
       
   824         'type' => 'varchar',
       
   825         'length' => 64,
       
   826         'not null' => TRUE,
       
   827         'description' => "The block's origin module, from {block}.module.",
       
   828       ),
       
   829       'delta' => array(
       
   830         'type' => 'varchar',
       
   831         'length' => 32,
       
   832         'not null' => TRUE,
       
   833         'description' => "The block's unique delta within module, from {block}.delta.",
       
   834       ),
       
   835       'type' => array(
       
   836         'type' => 'varchar',
       
   837         'length' => 32,
       
   838         'not null' => TRUE,
       
   839         'description' => "The machine-readable name of this type from {node_type}.type.",
       
   840       ),
       
   841     ),
       
   842     'primary key' => array('module', 'delta', 'type'),
       
   843     'indexes' => array(
       
   844       'type' => array('type'),
       
   845     ),
       
   846   );
       
   847 
       
   848   db_create_table('block_node_type', $schema['block_node_type']);
       
   849 }
       
   850 
       
   851 /**
       
   852  * @} End of "addtogroup updates-6.x-to-7.x".
       
   853  */
       
   854 
       
   855 /**
       
   856  * @addtogroup updates-7.x-extra
       
   857  * @{
       
   858  */
       
   859 
       
   860 /**
       
   861  * Update the database from Drupal 6 to match the schema.
       
   862  */
       
   863 function node_update_7011() {
       
   864   // Drop node moderation field.
       
   865   db_drop_field('node', 'moderate');
       
   866   db_drop_index('node', 'node_moderate');
       
   867 
       
   868   // Change {node_revision}.status field to default to 1.
       
   869   db_change_field('node_revision', 'status', 'status', array(
       
   870     'type' => 'int',
       
   871     'not null' => TRUE,
       
   872     'default' => 1,
       
   873   ));
       
   874 
       
   875   // Change {node_type}.module field default.
       
   876   db_change_field('node_type', 'module', 'module', array(
       
   877     'type' => 'varchar',
       
   878     'length' => 255,
       
   879     'not null' => TRUE,
       
   880   ));
       
   881 }
       
   882 
       
   883 /**
       
   884  * Switches body fields to untranslatable while upgrading from D6 and makes them language neutral.
       
   885  */
       
   886 function node_update_7012() {
       
   887   // If we are upgrading from D6, then body fields should be set back to
       
   888   // untranslatable, as D6 did not know about the idea of translating fields,
       
   889   // but only nodes. If a D7 > D7 update is running we need to skip this update,
       
   890   // as it is a valid use case to have translatable body fields in this context.
       
   891   if (variable_get('update_d6', FALSE)) {
       
   892     // Make node bodies untranslatable: field_update_field() cannot be used
       
   893     // throughout the upgrade process and we do not have an update counterpart
       
   894     // for _update_7000_field_create_field(). Hence we are forced to update the
       
   895     // 'field_config' table directly. This is a safe operation since it is
       
   896     // being performed while upgrading from D6. Perfoming the same operation
       
   897     // during a D7 update is highly discouraged.
       
   898     db_update('field_config')
       
   899       ->fields(array('translatable' => 0))
       
   900       ->condition('field_name', 'body')
       
   901       ->execute();
       
   902 
       
   903     // Switch field languages to LANGUAGE_NONE, since initially they were
       
   904     // assigned the node language.
       
   905     foreach (array('field_data_body', 'field_revision_body') as $table) {
       
   906       db_update($table)
       
   907         ->fields(array('language' => LANGUAGE_NONE))
       
   908         ->execute();
       
   909     }
       
   910 
       
   911     node_type_cache_reset();
       
   912   }
       
   913 }
       
   914 
       
   915 /**
       
   916  * Change {node}.vid default value from 0 to NULL to avoid deadlock issues on MySQL.
       
   917  */
       
   918 function node_update_7013() {
       
   919   db_drop_unique_key('node', 'vid');
       
   920   db_change_field('node', 'vid', 'vid', array(
       
   921     'description' => 'The current {node_revision}.vid version identifier.',
       
   922     'type' => 'int',
       
   923     'unsigned' => TRUE,
       
   924     'not null' => FALSE,
       
   925     'default' => NULL,
       
   926   ));
       
   927   db_add_unique_key('node', 'vid', array('vid'));
       
   928 }
       
   929 
       
   930 /**
       
   931  * Add an index on {node}.language.
       
   932  */
       
   933 function node_update_7014() {
       
   934   db_add_index('node', 'language', array('language'));
       
   935 }
       
   936 
       
   937 /**
       
   938  * Enable node types that may have been erroneously disabled in Drupal 7.36.
       
   939  */
       
   940 function node_update_7015() {
       
   941   db_update('node_type')
       
   942     ->fields(array('disabled' => 0))
       
   943     ->condition('base', 'node_content')
       
   944     ->execute();
       
   945 }
       
   946 
       
   947 /**
       
   948  * Change {history}.nid to an unsigned int in order to match {node}.nid.
       
   949  */
       
   950 function node_update_7016() {
       
   951   db_drop_primary_key('history');
       
   952   db_drop_index('history', 'nid');
       
   953   db_change_field('history', 'nid', 'nid', array(
       
   954     'description' => 'The {node}.nid that was read.',
       
   955     'type' => 'int',
       
   956     'unsigned' => TRUE,
       
   957     'not null' => TRUE,
       
   958     'default' => 0,
       
   959   ));
       
   960   db_add_primary_key('history', array('uid', 'nid'));
       
   961   db_add_index('history', 'nid', array('nid'));
       
   962 }
       
   963 
       
   964 /**
       
   965  * @} End of "addtogroup updates-7.x-extra".
       
   966  */