Newer
Older
<?php
// $Id$

Angie Byron
committed
/**
* @file
* Install, update and uninstall functions for the node module.
*/

Dries Buytaert
committed
* Implement hook_schema().
*/
function node_schema() {
$schema['node'] = array(

Dries Buytaert
committed
'description' => 'The base table for nodes.',
'fields' => array(
'nid' => array(

Dries Buytaert
committed
'description' => 'The primary identifier for a node.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
'vid' => array(

Dries Buytaert
committed
'description' => 'The current {node_revision}.vid version identifier.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'type' => array(

Dries Buytaert
committed
'description' => 'The {node_type}.type of this node.',
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
'default' => '',
),
'language' => array(

Dries Buytaert
committed
'description' => 'The {languages}.language of this node.',
'type' => 'varchar',
'length' => 12,
'not null' => TRUE,
'default' => '',
),
'title' => array(

Dries Buytaert
committed
'description' => 'The title of this node, always treated as non-markup plain text.',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
),
'uid' => array(

Angie Byron
committed
'description' => 'The {users}.uid that owns this node; initially, this is the user that created it.',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
),
'status' => array(

Dries Buytaert
committed
'description' => 'Boolean indicating whether the node is published (visible to non-administrators).',
'type' => 'int',
'not null' => TRUE,
'default' => 1,
),
'created' => array(

Dries Buytaert
committed
'description' => 'The Unix timestamp when the node was created.',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
),
'changed' => array(

Dries Buytaert
committed
'description' => 'The Unix timestamp when the node was most recently saved.',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
),
'comment' => array(

Dries Buytaert
committed
'description' => 'Whether comments are allowed on this node: 0 = no, 1 = closed (read only), 2 = open (read/write).',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
),
'promote' => array(

Dries Buytaert
committed
'description' => 'Boolean indicating whether the node should be displayed on the front page.',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
),
'sticky' => array(

Dries Buytaert
committed
'description' => 'Boolean indicating whether the node should be displayed at the top of lists in which it appears.',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
),
'tnid' => array(

Dries Buytaert
committed
'description' => 'The translation set id for this node, which equals the node id of the source post in each set.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'translate' => array(

Dries Buytaert
committed
'description' => 'A boolean indicating whether this translation page needs to be updated.',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'indexes' => array(
'node_changed' => array('changed'),
'node_created' => array('created'),

Dries Buytaert
committed
'node_frontpage' => array('promote', 'status', 'sticky', 'created'),
'node_status_type' => array('status', 'type', 'nid'),
'node_title_type' => array('title', array('type', 4)),
'node_type' => array(array('type', 4)),
'uid' => array('uid'),
'tnid' => array('tnid'),
'translate' => array('translate'),
'unique keys' => array(
'vid' => array('vid'),
),
'foreign keys' => array(
'vid' => array('node_revision' => 'vid'),
'uid' => array('users' => 'uid'),
),
'primary key' => array('nid'),
$schema['node_access'] = array(

Dries Buytaert
committed
'description' => 'Identifies which realm/grant pairs a user must possess in order to view, update, or delete specific nodes.',
'fields' => array(
'nid' => array(

Dries Buytaert
committed
'description' => 'The {node}.nid this record affects.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'gid' => array(

Dries Buytaert
committed
'description' => "The grant ID a user must possess in the specified realm to gain this row's privileges on the node.",
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'realm' => array(

Dries Buytaert
committed
'description' => 'The realm in which the user must possess the grant ID. Each node access node can define one or more realms.',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
),
'grant_view' => array(

Dries Buytaert
committed
'description' => 'Boolean indicating whether a user with the realm/grant pair can view this node.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
'size' => 'tiny',
),
'grant_update' => array(

Dries Buytaert
committed
'description' => 'Boolean indicating whether a user with the realm/grant pair can edit this node.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
'size' => 'tiny',
),
'grant_delete' => array(

Dries Buytaert
committed
'description' => 'Boolean indicating whether a user with the realm/grant pair can delete this node.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
'size' => 'tiny',
'primary key' => array('nid', 'gid', 'realm'),
'foreign keys' => array('node' => 'nid'),

Dries Buytaert
committed
$schema['node_revision'] = array(

Dries Buytaert
committed
'description' => 'Stores information about each saved version of a {node}.',
'fields' => array(
'nid' => array(

Dries Buytaert
committed
'description' => 'The {node} this version belongs to.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'vid' => array(

Dries Buytaert
committed
'description' => 'The primary identifier for this version.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
'uid' => array(

Angie Byron
committed
'description' => 'The {users}.uid that created this version.',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
),
'title' => array(

Dries Buytaert
committed
'description' => 'The title of this version.',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
),
'log' => array(

Dries Buytaert
committed
'description' => 'The log entry explaining the changes in this version.',
'type' => 'text',
'not null' => TRUE,
'size' => 'big',
),
'timestamp' => array(

Dries Buytaert
committed
'description' => 'A Unix timestamp indicating when this version was created.',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
),

Dries Buytaert
committed
'status' => array(
'description' => 'Boolean indicating whether the node (at the time of this revision) is published (visible to non-administrators).',
'type' => 'int',
'not null' => TRUE,
'default' => 1,
),
'comment' => array(
'description' => 'Whether comments are allowed on this node (at the time of this revision): 0 = no, 1 = closed (read only), 2 = open (read/write).',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
),
'promote' => array(
'description' => 'Boolean indicating whether the node (at the time of this revision) should be displayed on the front page.',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
),
'sticky' => array(
'description' => 'Boolean indicating whether the node (at the time of this revision) should be displayed at the top of lists in which it appears.',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
),
'indexes' => array(
'nid' => array('nid'),
'uid' => array('uid'),
),
'primary key' => array('vid'),
'foreign keys' => array(
'node' => 'nid',
'users' => 'uid'
),
$schema['node_type'] = array(

Dries Buytaert
committed
'description' => 'Stores information about all defined {node} types.',
'fields' => array(
'type' => array(

Dries Buytaert
committed
'description' => 'The machine-readable name of this type.',
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
),
'name' => array(

Dries Buytaert
committed
'description' => 'The human-readable name of this type.',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
),
'base' => array(

Dries Buytaert
committed
'description' => 'The base string used to construct callbacks corresponding to this node type.',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
),
'description' => array(

Dries Buytaert
committed
'description' => 'A brief description of this type.',
'type' => 'text',
'not null' => TRUE,
'size' => 'medium',
),
'help' => array(

Dries Buytaert
committed
'description' => 'Help information shown to the user when creating a {node} of this type.',
'type' => 'text',
'not null' => TRUE,
'size' => 'medium',
),
'has_title' => array(

Dries Buytaert
committed
'description' => 'Boolean indicating whether this type uses the {node}.title field.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'size' => 'tiny',
),
'title_label' => array(

Dries Buytaert
committed
'description' => 'The label displayed for the title field on the edit form.',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
),
'has_body' => array(

Dries Buytaert
committed
'description' => 'Boolean indicating whether this type has the body field attached.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'size' => 'tiny',
),
'body_label' => array(

Dries Buytaert
committed
'description' => 'The label displayed for the body field on the edit form.',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
),
'custom' => array(
'description' => 'A boolean indicating whether this type is defined by a module (FALSE) or by a user via Add content type (TRUE).',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'size' => 'tiny',
),
'modified' => array(

Dries Buytaert
committed
'description' => 'A boolean indicating whether this type has been modified by an administrator; currently not used in any way.',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'size' => 'tiny',
),
'locked' => array(

Dries Buytaert
committed
'description' => 'A boolean indicating whether the administrator can change the machine name of this type.',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'size' => 'tiny',
),
'orig_type' => array(

Dries Buytaert
committed
'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.',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
'primary key' => array('type'),
return $schema;
}
/**

Dries Buytaert
committed
* @defgroup updates-6.x-to-7.x System updates from 6.x to 7.x
* @{
*/
/**
* Fix node type 'module' attribute to avoid name-space conflicts.
*/
function node_update_7000() {
$ret = array();
$ret[] = update_sql("UPDATE {node_type} SET module = 'node_content' WHERE module = 'node'");
db_change_field($ret, 'node_type', 'module', 'base', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE));
return $ret;
}

Dries Buytaert
committed
/**
* Rename {node_revisions} table to {node_revision}.
*/
function node_update_7001() {
$ret = array();
db_rename_table($ret, 'node_revisions', 'node_revision');
return $ret;
}

Dries Buytaert
committed
/**
* Extend the node_promote_status index to include all fields required for the node page query.
*/
function node_update_7002() {
$ret = array();
db_drop_index($ret, 'node', 'node_promote_status');
db_add_index($ret, 'node', 'node_frontpage', array('promote', 'status', 'sticky', 'created'));
return $ret;
}
/**

Dries Buytaert
committed
* Remove the node_counter if the statistics module is uninstalled.
*/
function node_update_7003() {
$ret = array();

Dries Buytaert
committed
if (drupal_get_installed_schema_version('statistics') == SCHEMA_UNINSTALLED) {

Dries Buytaert
committed
db_drop_table($ret, 'node_counter');
}
return $ret;
}

Dries Buytaert
committed
/**
* Extend the existing default preview and teaser settings to all node types.
*/
function node_update_7004() {
// Get original settings and all types.
$original_length = variable_get('teaser_length', 600);
$original_preview = variable_get('node_preview', 0);
// Map old preview setting to new values order.
$original_preview ? $original_preview = 2 : $original_preview = 1;

Dries Buytaert
committed
node_type_clear();
$type_list = node_type_get_types();

Dries Buytaert
committed
// Apply original settings to all types.
foreach ($type_list as $type => $object) {

Dries Buytaert
committed
variable_set('teaser_length_' . $type, $original_length);
variable_set('node_preview_' . $type, $original_preview);
}
// Delete old variable but leave 'teaser_length' for aggregator module upgrade.
variable_del('node_preview');
return array();

Dries Buytaert
committed
}

Dries Buytaert
committed
/**
* Add status/comment/promote and sticky columns to the {node_revision} table.

Dries Buytaert
committed
*/

Dries Buytaert
committed
function node_update_7005() {
$ret = array();
foreach(array('status', 'comment', 'promote', 'sticky') as $column) {

Dries Buytaert
committed
db_add_field($ret, 'node_revision', $column, array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
));
}
return $ret;
}
/**
* Convert body and teaser from node properties to fields, and migrate status/comment/promote and sticky columns to the {node_revision} table.

Dries Buytaert
committed
*/
function node_update_7006(&$context) {

Dries Buytaert
committed
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
$ret = array('#finished' => 0);
// Get node type info for every invocation.
node_type_clear();
$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.
$found = FALSE;
if ($context['total']) {
// Operate on every revision of every node (whee!), in batches.
$batch_size = 50;
$query = db_select('node', 'n');
$nr = $query->innerJoin('node_revision', 'nr', 'n.vid = nr.vid');
$revisions = $query
->fields('n', array('type', 'status', 'comment', 'promote', 'sticky'))

Dries Buytaert
committed
->fields($nr)
->condition('nr.vid', $context['last'], '>')
->orderBy('nr.vid', 'ASC')
->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)) {

Angie Byron
committed
$node->body[FIELD_LANGUAGE_NONE][0]['summary'] = $revision->teaser;

Dries Buytaert
committed
}
// Do this after text_summary() above.
$break = '<!--break-->';
if (substr($revision->body, 0, strlen($break)) == $break) {
$revision->body = substr($revision->body, strlen($break));
}

Angie Byron
committed
$node->body[FIELD_LANGUAGE_NONE][0]['value'] = $revision->body;
$node->body[FIELD_LANGUAGE_NONE][0]['format'] = $revision->format;

Dries Buytaert
committed
// 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());
}

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

Dries Buytaert
committed
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
$context['last'] = $revision->vid;
$context['count'] += 1;
if (--$batch_size == 0) {
break;
}
}
$ret['#finished'] = min(0.99, $context['count'] / $context['total']);
}
if (!$found) {
// All nodes are processed.
$ret[] = array('success' => TRUE, 'query' => "{$context['total']} node body and teaser properties migrated to the 'body' field.");
// Remove the now-obsolete body info from node_revision.
db_drop_field($ret, 'node_revision', 'body');
db_drop_field($ret, 'node_revision', 'teaser');
db_drop_field($ret, 'node_revision', 'format');
// We're done.
$ret['#finished'] = 1;
}
}
return $ret;
}

Dries Buytaert
committed
/**
* Remove column min_word_count.
*/

Dries Buytaert
committed
function node_update_7007() {

Dries Buytaert
committed
$ret = array();
db_drop_field($ret, 'node_type', 'min_word_count');
return $ret;
}

Dries Buytaert
committed
/**
* @} End of "defgroup updates-6.x-to-7.x"
* The next series of updates should start at 8000.