1<?php 2 3/** 4 * @file 5 * Install, update and uninstall functions for the node module. 6 */ 7 8/** 9 * Implements hook_schema(). 10 */ 11function 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 */ 436function 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 */ 453function 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 */ 481function _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 */ 512function 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 */ 549function 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 */ 556function 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 */ 564function 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 */ 573function 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 */ 594function 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 */ 607function 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 */ 792function 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 */ 799function 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 */ 809function 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 */ 819function 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 */ 863function 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 */ 886function 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 */ 918function 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 */ 933function 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 */ 940function 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 */ 950function 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 */ 967