Code coverage for /20081101/modules/system/system.install

Line #Times calledCode
1
<?php
2
// $Id: system.install,v 1.273 2008/10/31 02:18:22 dries Exp $
3
4
/**
5
 * Test and report Drupal installation requirements.
6
 *
7
 * @param $phase
8
 *   The current system installation phase.
9
 * @return
10
 *   An array of system requirements.
11
 */
1212
function system_requirements($phase) {
133
  global $base_url;
143
  $requirements = array();
15
  // Ensure translations don't break at install time
163
  $t = get_t();
17
18
  // Report Drupal version
193
  if ($phase == 'runtime') {
203
    $requirements['drupal'] = array(
213
      'title' => $t('Drupal'),
223
      'value' => VERSION,
233
      'severity' => REQUIREMENT_INFO,
243
      'weight' => -10,
25
    );
263
  }
27
28
  // Web server information.
293
  $software = $_SERVER['SERVER_SOFTWARE'];
303
  $requirements['webserver'] = array(
313
    'title' => $t('Web server'),
323
    'value' => $software,
33
  );
34
35
  // Test PHP version
363
  $requirements['php'] = array(
373
    'title' => $t('PHP'),
383
    'value' => ($phase == 'runtime') ? l(phpversion(),
'admin/reports/status/php') : phpversion(),
39
  );
403
  if (version_compare(phpversion(), DRUPAL_MINIMUM_PHP) < 0) {
410
    $requirements['php']['description'] = $t('Your PHP installation is too
old. Drupal requires at least PHP %version.', array('%version' =>
DRUPAL_MINIMUM_PHP));
420
    $requirements['php']['severity'] = REQUIREMENT_ERROR;
430
  }
44
45
  // Test PHP register_globals setting.
463
  $requirements['php_register_globals'] = array(
473
    'title' => $t('PHP register globals'),
48
  );
493
  $register_globals = trim(ini_get('register_globals'));
50
  // Unfortunately, ini_get() may return many different values, and we
can't
51
  // be certain which values mean 'on', so we instead check for 'not off'
52
  // since we never want to tell the user that their site is secure
53
  // (register_globals off), when it is in fact on. We can only guarantee
54
  // register_globals is off if the value returned is 'off', '', or 0.
553
  if (!empty($register_globals) && strtolower($register_globals) != 'off')
{
560
    $requirements['php_register_globals']['description'] =
$t('<em>register_globals</em> is enabled. Drupal requires this
configuration directive to be disabled. Your site may not be secure when
<em>register_globals</em> is enabled. The PHP manual has instructions for
<a href="http://php.net/configuration.changes">how to change configuration
settings</a>.');
570
    $requirements['php_register_globals']['severity'] = REQUIREMENT_ERROR;
580
    $requirements['php_register_globals']['value'] = $t("Enabled
('@value')", array('@value' => $register_globals));
590
  }
60
  else {
613
    $requirements['php_register_globals']['value'] = $t('Disabled');
62
  }
63
64
  // Test PHP memory_limit
653
  $memory_limit = ini_get('memory_limit');
663
  $requirements['php_memory_limit'] = array(
673
    'title' => $t('PHP memory limit'),
683
    'value' => $memory_limit,
69
  );
70
713
  if ($memory_limit && parse_size($memory_limit) <
parse_size(DRUPAL_MINIMUM_PHP_MEMORY_LIMIT)) {
720
    $description = '';
730
    if ($phase == 'install') {
740
      $description = $t('Consider increasing your PHP memory limit to
%memory_minimum_limit to help prevent errors in the installation process.',
array('%memory_minimum_limit' => DRUPAL_MINIMUM_PHP_MEMORY_LIMIT));
750
    }
760
    elseif ($phase == 'update') {
770
      $description = $t('Consider increasing your PHP memory limit to
%memory_minimum_limit to help prevent errors in the update process.',
array('%memory_minimum_limit' => DRUPAL_MINIMUM_PHP_MEMORY_LIMIT));
780
    }
790
    elseif ($phase == 'runtime') {
800
      $description = $t('Depending on your configuration, Drupal can run
with a %memory_limit PHP memory limit. However, a %memory_minimum_limit PHP
memory limit or above is recommended, especially if your site uses
additional custom or contributed modules.', array('%memory_limit' =>
$memory_limit, '%memory_minimum_limit' =>
DRUPAL_MINIMUM_PHP_MEMORY_LIMIT));
810
    }
82
830
    if (!empty($description)) {
840
      if ($php_ini_path = get_cfg_var('cfg_file_path')) {
850
        $description .= ' ' . $t('Increase the memory limit by editing the
memory_limit parameter in the file %configuration-file and then restart
your web server (or contact your system administrator or hosting provider
for assistance).', array('%configuration-file' => $php_ini_path));
860
      }
87
      else {
880
        $description .= ' ' . $t('Contact your system administrator or
hosting provider for assistance with increasing your PHP memory limit.');
89
      }
90
910
      $requirements['php_memory_limit']['description'] = $description . ' '
. $t('See the <a href="@url">Drupal requirements</a> for more
information.', array('@url' => 'http://drupal.org/requirements'));
920
      $requirements['php_memory_limit']['severity'] = REQUIREMENT_WARNING;
930
    }
940
  }
95
96
  // Test DB version
973
  global $db_type;
983
  if (function_exists('db_status_report')) {
990
    $requirements += db_status_report($phase);
1000
  }
101
102
  // Test settings.php file writability
1033
  if ($phase == 'runtime') {
1043
    $conf_dir = drupal_verify_install_file(conf_path(), FILE_NOT_WRITABLE,
'dir');
1053
    $conf_file = drupal_verify_install_file(conf_path() . '/settings.php',
FILE_EXIST|FILE_READABLE|FILE_NOT_WRITABLE);
1063
    if (!$conf_dir || !$conf_file) {
1073
      $requirements['settings.php'] = array(
1083
        'value' => $t('Not protected'),
1093
        'severity' => REQUIREMENT_ERROR,
1103
        'description' => '',
111
      );
1123
      if (!$conf_dir) {
1130
        $requirements['settings.php']['description'] .= $t('The directory
%file is not protected from modifications and poses a security risk. You
must change the directory\'s permissions to be non-writable. ',
array('%file' => conf_path()));
1140
      }
1153
      if (!$conf_file) {
1163
        $requirements['settings.php']['description'] .= $t('The file %file
is not protected from modifications and poses a security risk. You must
change the file\'s permissions to be non-writable.', array('%file' =>
conf_path() . '/settings.php'));
1173
      }
1183
    }
119
    else {
1200
      $requirements['settings.php'] = array(
1210
        'value' => $t('Protected'),
122
      );
123
    }
1243
    $requirements['settings.php']['title'] = $t('Configuration file');
1253
  }
126
127
  // Report cron status.
1283
  if ($phase == 'runtime') {
129
    // Cron warning threshold defaults to two days.
1303
    $threshold_warning = variable_get('cron_threshold_warning', 172800);
131
    // Cron error threshold defaults to two weeks.
1323
    $threshold_error = variable_get('cron_threshold_error', 1209600);
133
    // Cron configuration help text.
1343
    $help = $t('For more information, see the online handbook entry for <a
href="@cron-handbook">configuring cron jobs</a>.', array('@cron-handbook'
=> 'http://drupal.org/cron'));
135
136
    // Determine when cron last ran. If never, use the install time to
137
    // determine the warning or error status.
1383
    $cron_last = variable_get('cron_last', NULL);
1393
    $never_run = FALSE;
1403
    if (!is_numeric($cron_last)) {
1412
      $never_run = TRUE;
1422
      $cron_last = variable_get('install_time', 0);
1432
    }
144
145
    // Determine severity based on time since cron last ran.
1463
    $severity = REQUIREMENT_OK;
1473
    if (REQUEST_TIME - $cron_last > $threshold_error) {
1482
      $severity = REQUIREMENT_ERROR;
1492
    }
1501
    elseif ($never_run || (REQUEST_TIME - $cron_last > $threshold_warning))
{
1510
      $severity = REQUIREMENT_WARNING;
1520
    }
153
154
    // If cron hasn't been run, and the user is viewing the main
155
    // administration page, instead of an error, we display a helpful
reminder
156
    // to configure cron jobs.
1573
    if ($never_run && $severity != REQUIREMENT_ERROR && $_GET['q'] ==
'admin' && user_access('administer site configuration')) {
1580
      drupal_set_message($t('Cron has not run. Please visit the <a
href="@status">status report</a> for more information.', array('@status' =>
url('admin/reports/status'))));
1590
    }
160
161
    // Set summary and description based on values determined above.
1623
    if ($never_run) {
1632
      $summary = $t('Never run');
1642
      $description = $t('Cron has not run.') . ' ' . $help;
1652
    }
166
    else {
1671
      $summary = $t('Last run !time ago', array('!time' =>
format_interval(REQUEST_TIME - $cron_last)));
1681
      $description = '';
1691
      if ($severity != REQUIREMENT_OK) {
1700
        $description = $t('Cron has not run recently.') . ' ' . $help;
1710
      }
172
    }
173
1743
    $description .= ' ' . $t('You can <a href="@cron">run cron
manually</a>.', array('@cron' => url('admin/reports/status/run-cron')));
1753
    $description .= '<br />' . $t('To run cron from outside the site, go to
<a href="!cron">!cron</a>', array('!cron' => url($base_url . '/cron.php',
array('external' => TRUE, 'query' => 'cron_key=' . variable_get('cron_key',
'drupal')))));
176
1773
    $requirements['cron'] = array(
1783
      'title' => $t('Cron maintenance tasks'),
1793
      'severity' => $severity,
1803
      'value' => $summary,
181
      'description' => $description
1823
    );
1833
  }
184
185
  // Test files directory
1863
  $directory = file_directory_path();
1873
  $requirements['file system'] = array(
1883
    'title' => $t('File system'),
189
  );
190
191
  // For installer, create the directory if possible.
1923
  if ($phase == 'install' && !is_dir($directory) && @mkdir($directory)) {
1930
    @chmod($directory, 0775); // Necessary for non-webserver users.
1940
  }
195
1963
  $is_writable = is_writable($directory);
1973
  $is_directory = is_dir($directory);
1983
  if (!$is_writable || !$is_directory) {
1990
    $description = '';
2000
    $requirements['file system']['value'] = $t('Not writable');
2010
    if (!$is_directory) {
2020
      $error = $t('The directory %directory does not exist.',
array('%directory' => $directory));
2030
    }
204
    else {
2050
      $error = $t('The directory %directory is not writable.',
array('%directory' => $directory));
206
    }
207
    // The files directory requirement check is done only during install
and runtime.
2080
    if ($phase == 'runtime') {
2090
      $description = $error . ' ' . $t('You may need to set the correct
directory at the <a href="@admin-file-system">file system settings page</a>
or change the current directory\'s permissions so that it is writable.',
array('@admin-file-system' => url('admin/settings/file-system')));
2100
    }
2110
    elseif ($phase == 'install') {
212
      // For the installer UI, we need different wording. 'value' will
213
      // be treated as version, so provide none there.
2140
      $description = $error . ' ' . $t('An automated attempt to create this
directory failed, possibly due to a permissions problem. To proceed with
the installation, either create the directory and modify its permissions
manually, or ensure that the installer has the permissions to create it
automatically. For more information, please see INSTALL.txt or the <a
href="@handbook_url">online handbook</a>.', array('@handbook_url' =>
'http://drupal.org/server-permissions'));
2150
      $requirements['file system']['value'] = '';
2160
    }
2170
    if (!empty($description)) {
2180
      $requirements['file system']['description'] = $description;
2190
      $requirements['file system']['severity'] = REQUIREMENT_ERROR;
2200
    }
2210
  }
222
  else {
2233
    if (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) ==
FILE_DOWNLOADS_PUBLIC) {
2243
      $requirements['file system']['value'] = $t('Writable (<em>public</em>
download method)');
2253
    }
226
    else {
2270
      $requirements['file system']['value'] = $t('Writable
(<em>private</em> download method)');
228
    }
229
  }
230
231
  // See if updates are available in update.php.
2323
  if ($phase == 'runtime') {
2333
    $requirements['update'] = array(
2343
      'title' => $t('Database updates'),
2353
      'severity' => REQUIREMENT_OK,
2363
      'value' => $t('Up to date'),
237
    );
238
239
    // Check installed modules.
2403
    foreach (module_list() as $module) {
2413
      $updates = drupal_get_schema_versions($module);
2423
      if ($updates !== FALSE) {
2433
        $default = drupal_get_installed_schema_version($module);
2443
        if (max($updates) > $default) {
2450
          $requirements['update']['severity'] = REQUIREMENT_ERROR;
2460
          $requirements['update']['value'] = $t('Out of date');
2470
          $requirements['update']['description'] = $t('Some modules have
database schema updates to install. You should run the <a
href="@update">database update script</a> immediately.', array('@update' =>
base_path() . 'update.php'));
2480
          break;
2490
        }
2503
      }
2513
    }
2523
  }
253
254
  // Verify the update.php access setting
2553
  if ($phase == 'runtime') {
2563
    if (!empty($GLOBALS['update_free_access'])) {
2570
      $requirements['update access'] = array(
2580
        'value' => $t('Not protected'),
2590
        'severity' => REQUIREMENT_ERROR,
2600
        'description' => $t('The update.php script is accessible to
everyone without authentication check, which is a security risk. You must
change the $update_free_access value in your settings.php back to FALSE.'),
261
      );
2620
    }
263
    else {
2643
      $requirements['update access'] = array(
2653
        'value' => $t('Protected'),
266
      );
267
    }
2683
    $requirements['update access']['title'] = $t('Access to update.php');
2693
  }
270
271
  // Test Unicode library
2723
  include_once DRUPAL_ROOT . '/includes/unicode.inc';
2733
  $requirements = array_merge($requirements, unicode_requirements());
274
275
  // Check for update status module.
2763
  if ($phase == 'runtime') {
2773
    if (!module_exists('update')) {
2783
      $requirements['update status'] = array(
2793
        'value' => $t('Not enabled'),
2803
        'severity' => REQUIREMENT_WARNING,
2813
        'description' => $t('Update notifications are not enabled. It is
<strong>highly recommended</strong> that you enable the update status
module from the <a href="@module">module administration page</a> in order
to stay up-to-date on new releases. For more information please read the <a
href="@update">Update status handbook page</a>.', array('@update' =>
'http://drupal.org/handbook/modules/update', '@module' =>
url('admin/build/modules'))),
282
      );
2833
    }
284
    else {
2850
      $requirements['update status'] = array(
2860
        'value' => $t('Enabled'),
287
      );
2880
      if (variable_get('drupal_http_request_fails', FALSE)) {
2890
        $requirements['http requests'] = array(
2900
          'title' => $t('HTTP request status'),
2910
          'value' => $t('Fails'),
2920
          'severity' => REQUIREMENT_ERROR,
2930
          'description' => $t('Your system or network configuration does
not allow Drupal to access web pages, resulting in reduced functionality.
This could be due to your webserver configuration or PHP settings, and
should be resolved in order to download information about available
updates, fetch aggregator feeds, sign in via OpenID, or use other
network-dependent services.'),
294
        );
2950
      }
296
    }
2973
    $requirements['update status']['title'] = $t('Update notifications');
2983
  }
299
3003
  return $requirements;
3010
}
302
303
/**
304
 * Implementation of hook_install().
305
 */
30612
function system_install() {
307134
  if (db_driver() == 'pgsql') {
308
    // We create some custom types and functions using global names instead
of
309
    // prefixing them like we do with table names. If this function is ever
310
    // called again (for example, by the test framework when creating
prefixed
311
    // test databases), the global names will already exist. We therefore
avoid
312
    // trying to create them again in that case.
313
314
    // Create unsigned types.
3150
    if (!db_result(db_query("SELECT COUNT(*) FROM pg_constraint WHERE
conname = 'int_unsigned_check'"))) {
3160
      db_query("CREATE DOMAIN int_unsigned integer CHECK (VALUE >= 0)");
3170
    }
3180
    if (!db_result(db_query("SELECT COUNT(*) FROM pg_constraint WHERE
conname = 'smallint_unsigned_check'"))) {
3190
      db_query("CREATE DOMAIN smallint_unsigned smallint CHECK (VALUE >=
0)");
3200
    }
3210
    if (!db_result(db_query("SELECT COUNT(*) FROM pg_constraint WHERE
conname = 'bigint_unsigned_check'"))) {
3220
      db_query("CREATE DOMAIN bigint_unsigned bigint CHECK (VALUE >= 0)");
3230
    }
324
325
    // Create functions.
3260
    db_query('CREATE OR REPLACE FUNCTION "greatest"(numeric, numeric)
RETURNS numeric AS
327
      \'SELECT CASE WHEN (($1 > $2) OR ($2 IS NULL)) THEN $1 ELSE $2 END;\'
328
      LANGUAGE \'sql\''
3290
    );
3300
    db_query('CREATE OR REPLACE FUNCTION "greatest"(numeric, numeric,
numeric) RETURNS numeric AS
331
      \'SELECT greatest($1, greatest($2, $3));\'
332
      LANGUAGE \'sql\''
3330
    );
3340
    if (!db_result(db_query("SELECT COUNT(*) FROM pg_proc WHERE proname =
'rand'"))) {
3350
      db_query('CREATE OR REPLACE FUNCTION "rand"() RETURNS float AS
336
        \'SELECT random();\'
337
        LANGUAGE \'sql\''
3380
      );
3390
    }
340
3410
    if (!db_result(db_query("SELECT COUNT(*) FROM pg_proc WHERE proname =
'concat'"))) {
3420
      db_query('CREATE OR REPLACE FUNCTION "concat"(text, text) RETURNS
text AS
343
        \'SELECT $1 || $2;\'
344
        LANGUAGE \'sql\''
3450
      );
3460
    }
3470
    db_query('CREATE OR REPLACE FUNCTION "if"(boolean, text, text) RETURNS
text AS
348
      \'SELECT CASE WHEN $1 THEN $2 ELSE $3 END;\'
349
      LANGUAGE \'sql\''
3500
    );
3510
    db_query('CREATE OR REPLACE FUNCTION "if"(boolean, integer, integer)
RETURNS integer AS
352
      \'SELECT CASE WHEN $1 THEN $2 ELSE $3 END;\'
353
      LANGUAGE \'sql\''
3540
    );
3550
  }
356
357
  // Create tables.
358134
  $modules = array('system', 'filter', 'block', 'user', 'node', 'comment',
'taxonomy');
359134
  foreach ($modules as $module) {
360134
    drupal_install_schema($module);
361134
  }
362
363
  // Load system theme data appropriately.
364134
  system_theme_data();
365
366
  // Inserting uid 0 here confuses MySQL -- the next user might be created
as
367
  // uid 2 which is not what we want. So we insert the first user here, the
368
  // anonymous user. uid is 1 here for now, but very soon it will be
changed
369
  // to 0.
370134
  db_query("INSERT INTO {users} (name, mail) VALUES('%s', '%s')", '', '');
371
  // We need some placeholders here as name and mail are uniques and data
is
372
  // presumed to be a serialized array. Install will change uid 1
immediately
373
  // anyways. So we insert the superuser here, the uid is 2 here for now,
but
374
  // very soon it will be changed to 1.
375134
  db_query("INSERT INTO {users} (name, mail, created, status, data)
VALUES('%s', '%s', %d, %d, '%s')", 'placeholder-for-uid-1',
'placeholder-for-uid-1', REQUEST_TIME, 1, serialize(array()));
376
  // This sets the above two users uid 0 (anonymous). We avoid an explicit
0
377
  // otherwise MySQL might insert the next auto_increment value.
378134
  db_query("UPDATE {users} SET uid = uid - uid WHERE name = '%s'", '');
379
  // This sets uid 1 (superuser). We skip uid 2 but that's not a big
problem.
380134
  db_query("UPDATE {users} SET uid = 1 WHERE name = '%s'",
'placeholder-for-uid-1');
381
382
  // Built-in roles.
383134
  db_query("INSERT INTO {role} (name) VALUES ('%s')", 'anonymous user');
384134
  db_query("INSERT INTO {role} (name) VALUES ('%s')", 'authenticated
user');
385
386
  // Anonymous role permissions.
387134
  db_query("INSERT INTO {role_permission} (rid, permission) VALUES (%d,
'%s')", 1, 'access content');
388
389
  // Authenticated role permissions.
390134
  db_query("INSERT INTO {role_permission} (rid, permission) VALUES (%d,
'%s')", 2, 'access comments');
391134
  db_query("INSERT INTO {role_permission} (rid, permission) VALUES (%d,
'%s')", 2, 'access content');
392134
  db_query("INSERT INTO {role_permission} (rid, permission) VALUES (%d,
'%s')", 2, 'post comments');
393134
  db_query("INSERT INTO {role_permission} (rid, permission) VALUES (%d,
'%s')", 2, 'post comments without approval');
394
395134
  db_query("INSERT INTO {variable} (name, value) VALUES ('%s', '%s')",
'theme_default', 's:7:"garland";');
396134
  db_query("UPDATE {system} SET status = %d WHERE type = '%s' AND name =
'%s'", 1, 'theme', 'garland');
397134
  db_query("INSERT INTO {blocks} (module, delta, theme, status, weight,
region, pages, cache) VALUES ('%s', '%s', '%s', %d, %d, '%s', '%s', %d)",
'user', 'login', 'garland', 1, 0, 'left', '', -1);
398134
  db_query("INSERT INTO {blocks} (module, delta, theme, status, weight,
region, pages, cache) VALUES ('%s', '%s', '%s', %d, %d, '%s', '%s', %d)",
'user', 'navigation', 'garland', 1, 0, 'left', '', -1);
399134
  db_query("INSERT INTO {blocks} (module, delta, theme, status, weight,
region, pages, cache) VALUES ('%s', '%s', '%s', %d, %d, '%s', '%s', %d)",
'system', 'powered-by', 'garland', 1, 10, 'footer', '', -1);
400
401134
  db_query("INSERT INTO {node_access} (nid, gid, realm, grant_view,
grant_update, grant_delete) VALUES (%d, %d, '%s', %d, %d, %d)", 0, 0,
'all', 1, 0, 0);
402
403
  // Add input formats.
404134
  db_query("INSERT INTO {filter_formats} (name, roles, cache) VALUES ('%s',
'%s', %d)", 'Filtered HTML', ',1,2,', 1);
405134
  db_query("INSERT INTO {filter_formats} (name, roles, cache) VALUES ('%s',
'%s', %d)", 'Full HTML', '', 1);
406
407
  // Enable filters for each input format.
408
409
  // Filtered HTML:
410
  // URL filter.
411134
  db_query("INSERT INTO {filters} (format, module, delta, weight) VALUES
(%d, '%s', %d, %d)", 1, 'filter', 2, 0);
412
  // HTML filter.
413134
  db_query("INSERT INTO {filters} (format, module, delta, weight) VALUES
(%d, '%s', %d, %d)", 1, 'filter', 0, 1);
414
  // Line break filter.
415134
  db_query("INSERT INTO {filters} (format, module, delta, weight) VALUES
(%d, '%s', %d, %d)", 1, 'filter', 1, 2);
416
  // HTML corrector filter.
417134
  db_query("INSERT INTO {filters} (format, module, delta, weight) VALUES
(%d, '%s', %d, %d)", 1, 'filter', 3, 10);
418
419
  // Full HTML:
420
  // URL filter.
421134
  db_query("INSERT INTO {filters} (format, module, delta, weight) VALUES
(%d, '%s', %d, %d)", 2, 'filter', 2, 0);
422
  // Line break filter.
423134
  db_query("INSERT INTO {filters} (format, module, delta, weight) VALUES
(%d, '%s', %d, %d)", 2, 'filter', 1, 1);
424
  // HTML corrector filter.
425134
  db_query("INSERT INTO {filters} (format, module, delta, weight) VALUES
(%d, '%s', %d, %d)", 2, 'filter', 3, 10);
426
427134
  db_query("INSERT INTO {variable} (name, value) VALUES ('%s','%s')",
'filter_html_1', 'i:1;');
428
429134
  db_query("INSERT INTO {variable} (name, value) VALUES ('%s', '%s')",
'node_options_forum', 'a:1:{i:0;s:6:"status";}');
430
431134
  $cron_key = serialize(md5(mt_rand()));
432
433134
  db_query("INSERT INTO {variable} (name, value) VALUES ('%s', '%s')",
'cron_key', $cron_key);
434134
}
435
436
/**
437
 * Implementation of hook_schema().
438
 */
43912
function system_schema() {
440
  // NOTE: {variable} needs to be created before all other tables, as
441
  // some database drivers, e.g. Oracle and DB2, will require
variable_get()
442
  // and variable_set() for overcoming some database specific limitations.
443134
  $schema['variable'] = array(
444134
    'description' => t('Named variable/value pairs created by Drupal core
or any other module or theme. All variables are cached in memory at the
start of every Drupal request so developers should not be careless about
what is stored here.'),
445
    'fields' => array(
446
      'name' => array(
447134
        'description' => t('The name of the variable.'),
448134
        'type' => 'varchar',
449134
        'length' => 128,
450134
        'not null' => TRUE,
451134
        'default' => '',
452134
      ),
453
      'value' => array(
454134
        'description' => t('The value of the variable.'),
455134
        'type' => 'text',
456134
        'not null' => TRUE,
457134
        'size' => 'big',
458134
      ),
459134
    ),
460134
    'primary key' => array('name'),
461
  );
462
463134
  $schema['actions'] = array(
464134
    'description' => t('Stores action information.'),
465
    'fields' => array(
466
      'aid' => array(
467134
        'description' => t('Primary Key: Unique actions ID.'),
468134
        'type' => 'varchar',
469134
        'length' => 255,
470134
        'not null' => TRUE,
471134
        'default' => '0',
472134
      ),
473
      'type' => array(
474134
        'description' => t('The object that that action acts on (node,
user, comment, system or custom types.)'),
475134
        'type' => 'varchar',
476134
        'length' => 32,
477134
        'not null' => TRUE,
478134
        'default' => '',
479134
      ),
480
      'callback' => array(
481134
        'description' => t('The callback function that executes when the
action runs.'),
482134
        'type' => 'varchar',
483134
        'length' => 255,
484134
        'not null' => TRUE,
485134
        'default' => '',
486134
      ),
487
      'parameters' => array(
488134
        'description' => t('Parameters to be passed to the callback
function.'),
489134
        'type' => 'text',
490134
        'not null' => TRUE,
491134
        'size' => 'big',
492134
      ),
493
      'description' => array(
494134
        'description' => t('Description of the action.'),
495134
        'type' => 'varchar',
496134
        'length' => 255,
497134
        'not null' => TRUE,
498134
        'default' => '0',
499134
      ),
500134
    ),
501134
    'primary key' => array('aid'),
502
  );
503
504134
  $schema['actions_aid'] = array(
505134
    'description' => t('Stores action IDs for non-default actions.'),
506
    'fields' => array(
507
      'aid' => array(
508134
        'description' => t('Primary Key: Unique actions ID.'),
509134
        'type' => 'serial',
510134
        'unsigned' => TRUE,
511134
        'not null' => TRUE,
512134
      ),
513134
    ),
514134
    'primary key' => array('aid'),
515
  );
516
517134
  $schema['batch'] = array(
518134
    'description' => t('Stores details about batches (processes that run in
multiple HTTP requests).'),
519
    'fields' => array(
520
      'bid' => array(
521134
        'description' => t('Primary Key: Unique batch ID.'),
522134
        'type' => 'serial',
523134
        'unsigned' => TRUE,
524134
        'not null' => TRUE,
525134
      ),
526
      'token' => array(
527134
        'description' => t("A string token generated against the current
user's session id and the batch id, used to ensure that only the user who
submitted the batch can effectively access it."),
528134
        'type' => 'varchar',
529134
        'length' => 64,
530134
        'not null' => TRUE,
531134
      ),
532
      'timestamp' => array(
533134
        'description' => t('A Unix timestamp indicating when this batch was
submitted for processing. Stale batches are purged at cron time.'),
534134
        'type' => 'int',
535134
        'not null' => TRUE,
536134
      ),
537
      'batch' => array(
538134
        'description' => t('A serialized array containing the processing
data for the batch.'),
539134
        'type' => 'text',
540134
        'not null' => FALSE,
541134
        'size' => 'big',
542134
      ),
543134
    ),
544134
    'primary key' => array('bid'),
545
    'indexes' => array(
546134
      'token' => array('token'),
547134
    ),
548
  );
549
550134
  $schema['blocked_ips'] = array(
551134
    'description' => t('Stores blocked IP addresses.'),
552
    'fields' => array(
553
       'iid' => array(
554134
        'description' => t('Primary Key: unique ID for IP addresses.'),
555134
        'type' => 'serial',
556134
        'unsigned' => TRUE,
557134
        'not null' => TRUE,
558134
      ),
559
      'ip' => array(
560134
        'description' => t('IP address'),
561134
        'type' => 'varchar',
562134
        'length' => 32,
563134
        'not null' => TRUE,
564134
        'default' => '',
565134
      ),
566134
    ),
567
    'indexes' => array(
568134
      'blocked_ip' => array('ip'),
569134
    ),
570134
    'primary key' => array('iid'),
571
  );
572
573134
  $schema['cache'] = array(
574134
    'description' => t('Generic cache table for caching things not
separated out into their own tables. Contributed modules may also use this
to store cached items.'),
575
    'fields' => array(
576
      'cid' => array(
577134
        'description' => t('Primary Key: Unique cache ID.'),
578134
        'type' => 'varchar',
579134
        'length' => 255,
580134
        'not null' => TRUE,
581134
        'default' => '',
582134
      ),
583
      'data' => array(
584134
        'description' => t('A collection of data to cache.'),
585134
        'type' => 'blob',
586134
        'not null' => FALSE,
587134
        'size' => 'big',
588134
      ),
589
      'expire' => array(
590134
        'description' => t('A Unix timestamp indicating when the cache
entry should expire, or 0 for never.'),
591134
        'type' => 'int',
592134
        'not null' => TRUE,
593134
        'default' => 0,
594134
      ),
595
      'created' => array(
596134
        'description' => t('A Unix timestamp indicating when the cache
entry was created.'),
597134
        'type' => 'int',
598134
        'not null' => TRUE,
599134
        'default' => 0,
600134
      ),
601
      'headers' => array(
602134
        'description' => t('Any custom HTTP headers to be added to cached
data.'),
603134
        'type' => 'text',
604134
        'not null' => FALSE,
605134
      ),
606
      'serialized' => array(
607134
        'description' => t('A flag to indicate whether content is
serialized (1) or not (0).'),
608134
        'type' => 'int',
609134
        'size' => 'small',
610134
        'not null' => TRUE,
611134
        'default' => 0,
612134
      ),
613134
    ),
614
    'indexes' => array(
615134
      'expire' => array('expire'),
616134
    ),
617134
    'primary key' => array('cid'),
618
  );
619
620134
  $schema['cache_form'] = $schema['cache'];
621134
  $schema['cache_form']['description'] = t('Cache table for the form system
to store recently built forms and their storage data, to be used in
subsequent page requests.');
622134
  $schema['cache_page'] = $schema['cache'];
623134
  $schema['cache_page']['description'] = t('Cache table used to store
compressed pages for anonymous users, if page caching is enabled.');
624134
  $schema['cache_menu'] = $schema['cache'];
625134
  $schema['cache_menu']['description'] = t('Cache table for the menu system
to store router information as well as generated link trees for various
menu/page/user combinations.');
626134
  $schema['cache_registry'] = $schema['cache'];
627134
  $schema['cache_registry']['description'] = t('Cache table for the code
registry system to remember what code files need to be loaded on any given
page.');
628
629134
  $schema['files'] = array(
630134
    'description' => t('Stores information for uploaded files.'),
631
    'fields' => array(
632
      'fid' => array(
633134
        'description' => t('File ID.'),
634134
        'type' => 'serial',
635134
        'unsigned' => TRUE,
636134
        'not null' => TRUE,
637134
      ),
638
      'uid' => array(
639134
        'description' => t('The {users}.uid of the user who is associated
with the file.'),
640134
        'type' => 'int',
641134
        'unsigned' => TRUE,
642134
        'not null' => TRUE,
643134
        'default' => 0,
644134
      ),
645
      'filename' => array(
646134
        'description' => t('Name of the file with no path components. This
may differ from the basename of the filepath if the file is renamed to
avoid overwriting an existing file.'),
647134
        'type' => 'varchar',
648134
        'length' => 255,
649134
        'not null' => TRUE,
650134
        'default' => '',
651134
      ),
652
      'filepath' => array(
653134
        'description' => t('Path of the file relative to Drupal root.'),
654134
        'type' => 'varchar',
655134
        'length' => 255,
656134
        'not null' => TRUE,
657134
        'default' => '',
658134
      ),
659
      'filemime' => array(
660134
        'description' => t("The file's MIME type."),
661134
        'type' => 'varchar',
662134
        'length' => 255,
663134
        'not null' => TRUE,
664134
        'default' => '',
665134
      ),
666
      'filesize' => array(
667134
        'description' => t('The size of the file in bytes.'),
668134
        'type' => 'int',
669134
        'unsigned' => TRUE,
670134
        'not null' => TRUE,
671134
        'default' => 0,
672134
      ),
673
      'status' => array(
674134
        'description' => t('A bitmapped field indicating the status of the
file the least sigifigant bit indicates temporary (1) or permanent (0).
Temporary files older than DRUPAL_MAXIMUM_TEMP_FILE_AGE will be removed
during a cron run.'),
675134
        'type' => 'int',
676134
        'not null' => TRUE,
677134
        'default' => 0,
678134
      ),
679
      'timestamp' => array(
680134
        'description' => t('UNIX timestamp for when the file was added.'),
681134
        'type' => 'int',
682134
        'unsigned' => TRUE,
683134
        'not null' => TRUE,
684134
        'default' => 0,
685134
      ),
686134
    ),
687
    'indexes' => array(
688134
      'uid' => array('uid'),
689134
      'status' => array('status'),
690134
      'timestamp' => array('timestamp'),
691134
    ),
692134
    'primary key' => array('fid'),
693
  );
694
695134
  $schema['flood'] = array(
696134
    'description' => t('Flood controls the threshold of events, such as the
number of contact attempts.'),
697
    'fields' => array(
698
      'fid' => array(
699134
        'description' => t('Unique flood event ID.'),
700134
        'type' => 'serial',
701134
        'not null' => TRUE,
702134
      ),
703
      'event' => array(
704134
        'description' => t('Name of event (e.g. contact).'),
705134
        'type' => 'varchar',
706134
        'length' => 64,
707134
        'not null' => TRUE,
708134
        'default' => '',
709134
      ),
710
      'hostname' => array(
711134
        'description' => t('Hostname of the visitor.'),
712134
        'type' => 'varchar',
713134
        'length' => 128,
714134
        'not null' => TRUE,
715134
        'default' => '',
716134
      ),
717
      'timestamp' => array(
718134
        'description' => t('Timestamp of the event.'),
719134
        'type' => 'int',
720134
        'not null' => TRUE,
721134
        'default' => 0,
722134
      ),
723134
    ),
724134
    'primary key' => array('fid'),
725
    'indexes' => array(
726134
      'allow' => array('event', 'hostname', 'timestamp'),
727134
    ),
728
  );
729
730134
  $schema['history'] = array(
731134
    'description' => t('A record of which {users} have read which
{node}s.'),
732
    'fields' => array(
733
      'uid' => array(
734134
        'description' => t('The {users}.uid that read the {node} nid.'),
735134
        'type' => 'int',
736134
        'not null' => TRUE,
737134
        'default' => 0,
738134
      ),
739
      'nid' => array(
740134
        'description' => t('The {node}.nid that was read.'),
741134
        'type' => 'int',
742134
        'not null' => TRUE,
743134
        'default' => 0,
744134
      ),
745
      'timestamp' => array(
746134
        'description' => t('The Unix timestamp at which the read
occurred.'),
747134
        'type' => 'int',
748134
        'not null' => TRUE,
749134
        'default' => 0,
750134
      ),
751134
    ),
752134
    'primary key' => array('uid', 'nid'),
753
    'indexes' => array(
754134
      'nid' => array('nid'),
755134
    ),
756
  );
757134
  $schema['menu_router'] = array(
758134
    'description' => t('Maps paths to various callbacks (access, page and
title)'),
759
    'fields' => array(
760
      'path' => array(
761134
        'description' => t('Primary Key: the Drupal path this entry
describes'),
762134
        'type' => 'varchar',
763134
        'length' => 255,
764134
        'not null' => TRUE,
765134
        'default' => '',
766134
      ),
767
      'load_functions' => array(
768134
        'description' => t('A serialized array of function names (like
node_load) to be called to load an object corresponding to a part of the
current path.'),
769134
        'type' => 'text',
770134
        'not null' => TRUE,
771134
      ),
772
      'to_arg_functions' => array(
773134
        'description' => t('A serialized array of function names (like
user_uid_optional_to_arg) to be called to replace a part of the router path
with another string.'),
774134
        'type' => 'text',
775134
        'not null' => TRUE,
776134
      ),
777
      'access_callback' => array(
778134
        'description' => t('The callback which determines the access to
this router path. Defaults to user_access.'),
779134
        'type' => 'varchar',
780134
        'length' => 255,
781134
        'not null' => TRUE,
782134
        'default' => '',
783134
      ),
784
      'access_arguments' => array(
785134
        'description' => t('A serialized array of arguments for the access
callback.'),
786134
        'type' => 'text',
787134
        'not null' => FALSE,
788134
      ),
789
      'page_callback' => array(
790134
        'description' => t('The name of the function that renders the
page.'),
791134
        'type' => 'varchar',
792134
        'length' => 255,
793134
        'not null' => TRUE,
794134
        'default' => '',
795134
      ),
796
      'page_arguments' => array(
797134
        'description' => t('A serialized array of arguments for the page
callback.'),
798134
        'type' => 'text',
799134
        'not null' => FALSE,
800134
      ),
801
      'fit' => array(
802134
        'description' => t('A numeric representation of how specific the
path is.'),
803134
        'type' => 'int',
804134
        'not null' => TRUE,
805134
        'default' => 0,
806134
      ),
807
      'number_parts' => array(
808134
        'description' => t('Number of parts in this router path.'),
809134
        'type' => 'int',
810134
        'not null' => TRUE,
811134
        'default' => 0,
812134
        'size' => 'small',
813134
      ),
814
      'tab_parent' => array(
815134
        'description' => t('Only for local tasks (tabs) - the router path
of the parent page (which may also be a local task).'),
816134
        'type' => 'varchar',
817134
        'length' => 255,
818134
        'not null' => TRUE,
819134
        'default' => '',
820134
      ),
821
      'tab_root' => array(
822134
        'description' => t('Router path of the closest non-tab parent page.
For pages that are not local tasks, this will be the same as the path.'),
823134
        'type' => 'varchar',
824134
        'length' => 255,
825134
        'not null' => TRUE,
826134
        'default' => '',
827134
      ),
828
      'title' => array(
829134
        'description' => t('The title for the current page, or the title
for the tab if this is a local task.'),
830134
        'type' => 'varchar',
831134
        'length' => 255,
832134
        'not null' => TRUE,
833134
        'default' => '',
834134
      ),
835
      'title_callback' => array(
836134
        'description' => t('A function which will alter the title. Defaults
to t()'),
837134
        'type' => 'varchar',
838134
        'length' => 255,
839134
        'not null' => TRUE,
840134
        'default' => '',
841134
      ),
842
      'title_arguments' => array(
843134
        'description' => t('A serialized array of arguments for the title
callback. If empty, the title will be used as the sole argument for the
title callback.'),
844134
        'type' => 'varchar',
845134
        'length' => 255,
846134
        'not null' => TRUE,
847134
        'default' => '',
848134
      ),
849
      'type' => array(
850134
        'description' => t('Numeric representation of the type of the menu
item, like MENU_LOCAL_TASK.'),
851134
        'type' => 'int',
852134
        'not null' => TRUE,
853134
        'default' => 0,
854134
      ),
855
      'block_callback' => array(
856134
        'description' => t('Name of a function used to render the block on
the system administration page for this item.'),
857134
        'type' => 'varchar',
858134
        'length' => 255,
859134
        'not null' => TRUE,
860134
        'default' => '',
861134
      ),
862
      'description' => array(
863134
        'description' => t('A description of this item.'),
864134
        'type' => 'text',
865134
        'not null' => TRUE,
866134
      ),
867
      'position' => array(
868134
        'description' => t('The position of the block (left or right) on
the system administration page for this item.'),
869134
        'type' => 'varchar',
870134
        'length' => 255,
871134
        'not null' => TRUE,
872134
        'default' => '',
873134
      ),
874
      'weight' => array(
875134
        'description' => t('Weight of the element. Lighter weights are
higher up, heavier weights go down.'),
876134
        'type' => 'int',
877134
        'not null' => TRUE,
878134
        'default' => 0,
879134
      ),
880134
    ),
881
    'indexes' => array(
882134
      'fit' => array('fit'),
883134
      'tab_parent' => array('tab_parent'),
884134
    ),
885134
    'primary key' => array('path'),
886
  );
887
888134
  $schema['menu_links'] = array(
889134
    'description' => t('Contains the individual links within a menu.'),
890
    'fields' => array(
891
     'menu_name' => array(
892134
        'description' => t("The menu name. All links with the same menu
name (such as 'navigation') are part of the same menu."),
893134
        'type' => 'varchar',
894134
        'length' => 32,
895134
        'not null' => TRUE,
896134
        'default' => '',
897134
      ),
898
      'mlid' => array(
899134
        'description' => t('The menu link ID (mlid) is the integer primary
key.'),
900134
        'type' => 'serial',
901134
        'unsigned' => TRUE,
902134
        'not null' => TRUE,
903134
      ),
904
      'plid' => array(
905134
        'description' => t('The parent link ID (plid) is the mlid of the
link above in the hierarchy, or zero if the link is at the top level in its
menu.'),
906134
        'type' => 'int',
907134
        'unsigned' => TRUE,
908134
        'not null' => TRUE,
909134
        'default' => 0,
910134
      ),
911
      'link_path' => array(
912134
        'description' => t('The Drupal path or external path this link
points to.'),
913134
        'type' => 'varchar',
914134
        'length' => 255,
915134
        'not null' => TRUE,
916134
        'default' => '',
917134
      ),
918
      'router_path' => array(
919134
        'description' => t('For links corresponding to a Drupal path
(external = 0), this connects the link to a {menu_router}.path for
joins.'),
920134
        'type' => 'varchar',
921134
        'length' => 255,
922134
        'not null' => TRUE,
923134
        'default' => '',
924134
      ),
925
      'link_title' => array(
926134
      'description' => t('The text displayed for the link, which may be
modified by a title callback stored in {menu_router}.'),
927134
        'type' => 'varchar',
928134
        'length' => 255,
929134
        'not null' => TRUE,
930134
        'default' => '',
931134
      ),
932
      'options' => array(
933134
        'description' => t('A serialized array of options to be passed to
the url() or l() function, such as a query string or HTML attributes.'),
934134
        'type' => 'text',
935134
        'not null' => FALSE,
936134
      ),
937
      'module' => array(
938134
        'description' => t('The name of the module that generated this
link.'),
939134
        'type' => 'varchar',
940134
        'length' => 255,
941134
        'not null' => TRUE,
942134
        'default' => 'system',
943134
      ),
944
      'hidden' => array(
945134
        'description' => t('A flag for whether the link should be rendered
in menus. (1 = a disabled menu item that may be shown on admin screens, -1
= a menu callback, 0 = a normal, visible link)'),
946134
        'type' => 'int',
947134
        'not null' => TRUE,
948134
        'default' => 0,
949134
        'size' => 'small',
950134
      ),
951
      'external' => array(
952134
        'description' => t('A flag to indicate if the link points to a full
URL starting with a protocol, like http:// (1 = external, 0 = internal).'),
953134
        'type' => 'int',
954134
        'not null' => TRUE,
955134
        'default' => 0,
956134
        'size' => 'small',
957134
      ),
958
      'has_children' => array(
959134
        'description' => t('Flag indicating whether any links have this
link as a parent (1 = children exist, 0 = no children).'),
960134
        'type' => 'int',
961134
        'not null' => TRUE,
962134
        'default' => 0,
963134
        'size' => 'small',
964134
      ),
965
      'expanded' => array(
966134
        'description' => t('Flag for whether this link should be rendered
as expanded in menus - expanded links always have their child links
displayed, instead of only when the link is in the active trail (1 =
expanded, 0 = not expanded)'),
967134
        'type' => 'int',
968134
        'not null' => TRUE,
969134
        'default' => 0,
970134
        'size' => 'small',
971134
      ),
972
      'weight' => array(
973134
        'description' => t('Link weight among links in the same menu at the
same depth.'),
974134
        'type' => 'int',
975134
        'not null' => TRUE,
976134
        'default' => 0,
977134
      ),
978
      'depth' => array(
979134
        'description' => t('The depth relative to the top level. A link
with plid == 0 will have depth == 1.'),
980134
        'type' => 'int',
981134
        'not null' => TRUE,
982134
        'default' => 0,
983134
        'size' => 'small',
984134
      ),
985
      'customized' => array(
986134
        'description' => t('A flag to indicate that the user has manually
created or edited the link (1 = customized, 0 = not customized).'),
987134
        'type' => 'int',
988134
        'not null' => TRUE,
989134
        'default' => 0,
990134
        'size' => 'small',
991134
      ),
992
      'p1' => array(
993134
        'description' => t('The first mlid in the materialized path. If N =
depth, then pN must equal the mlid. If depth > 1 then p(N-1) must equal the
plid. All pX where X > depth must equal zero. The columns p1 .. p9 are also
called the parents.'),
994134
        'type' => 'int',
995134
        'unsigned' => TRUE,
996134
        'not null' => TRUE,
997134
        'default' => 0,
998134
      ),
999
      'p2' => array(
1000134
        'description' => t('The second mlid in the materialized path. See
p1.'),
1001134
        'type' => 'int',
1002134
        'unsigned' => TRUE,
1003134
        'not null' => TRUE,
1004134
        'default' => 0,
1005134
      ),
1006
      'p3' => array(
1007134
        'description' => t('The third mlid in the materialized path. See
p1.'),
1008134
        'type' => 'int',
1009134
        'unsigned' => TRUE,
1010134
        'not null' => TRUE,
1011134
        'default' => 0,
1012134
      ),
1013
      'p4' => array(
1014134
        'description' => t('The fourth mlid in the materialized path. See
p1.'),
1015134
        'type' => 'int',
1016134
        'unsigned' => TRUE,
1017134
        'not null' => TRUE,
1018134
        'default' => 0,
1019134
      ),
1020
      'p5' => array(
1021134
        'description' => t('The fifth mlid in the materialized path. See
p1.'),
1022134
        'type' => 'int',
1023134
        'unsigned' => TRUE,
1024134
        'not null' => TRUE,
1025134
        'default' => 0,
1026134
      ),
1027
      'p6' => array(
1028134
        'description' => t('The sixth mlid in the materialized path. See
p1.'),
1029134
        'type' => 'int',
1030134
        'unsigned' => TRUE,
1031134
        'not null' => TRUE,
1032134
        'default' => 0,
1033134
      ),
1034
      'p7' => array(
1035134
        'description' => t('The seventh mlid in the materialized path. See
p1.'),
1036134
        'type' => 'int',
1037134
        'unsigned' => TRUE,
1038134
        'not null' => TRUE,
1039134
        'default' => 0,
1040134
      ),
1041
      'p8' => array(
1042134
        'description' => t('The eighth mlid in the materialized path. See
p1.'),
1043134
        'type' => 'int',
1044134
        'unsigned' => TRUE,
1045134
        'not null' => TRUE,
1046134
        'default' => 0,
1047134
      ),
1048
      'p9' => array(
1049134
        'description' => t('The ninth mlid in the materialized path. See
p1.'),
1050134
        'type' => 'int',
1051134
        'unsigned' => TRUE,
1052134
        'not null' => TRUE,
1053134
        'default' => 0,
1054134
      ),
1055
      'updated' => array(
1056134
        'description' => t('Flag that indicates that this link was
generated during the update from Drupal 5.'),
1057134
        'type' => 'int',
1058134
        'not null' => TRUE,
1059134
        'default' => 0,
1060134
        'size' => 'small',
1061134
      ),
1062134
    ),
1063
    'indexes' => array(
1064134
      'path_menu' => array(array('link_path', 128), 'menu_name'),
1065134
      'menu_plid_expand_child' => array('menu_name', 'plid', 'expanded',
'has_children'),
1066134
      'menu_parents' => array('menu_name', 'p1', 'p2', 'p3', 'p4', 'p5',
'p6', 'p7', 'p8', 'p9'),
1067134
      'router_path' => array(array('router_path', 128)),
1068134
    ),
1069134
    'primary key' => array('mlid'),
1070
  );
1071
1072134
  $schema['registry'] = array(
1073134
    'description' => t("Each record is a function, class, or interface name
and the file it is in."),
1074
    'fields' => array(
1075
      'name'   => array(
1076134
        'description' => t('The name of the function, class, or
interface.'),
1077134
        'type' => 'varchar',
1078134
        'length' => 255,
1079134
        'not null' => TRUE,
1080134
        'default' => '',
1081134
      ),
1082
      'type'   => array(
1083134
        'description' => t('Either function or class or interface.'),
1084134
        'type' => 'varchar',
1085134
        'length' => 9,
1086134
        'not null' => TRUE,
1087134
        'default' => '',
1088134
      ),
1089
      'filename'   => array(
1090134
        'description' => t('Name of the file.'),
1091134
        'type' => 'varchar',
1092134
        'length' => 255,
1093134
        'not null' => TRUE,
1094134
      ),
1095
      'module' => array(
1096134
        'description' => t('Name of the module the file belongs to.'),
1097134
        'type' => 'varchar',
1098134
        'length' => 255,
1099134
        'not null' => TRUE,
1100
        'default' => ''
1101134
      ),
1102
      'suffix' => array(
1103134
        'description' => t("The part of the function name after the module,
which is the hook this function implements, if any."),
1104134
        'type' => 'varchar',
1105134
        'length' => 68,
1106134
        'not null' => TRUE,
1107
        'default' => ''
1108134
      ),
1109
      'weight' => array(
1110134
        'description' => t("The order in which this module's hooks should
be invoked relative to other modules. Equal-weighted modules are ordered by
name."),
1111134
        'type' => 'int',
1112134
        'not null' => TRUE,
1113134
        'default' => 0,
1114134
      ),
1115134
    ),
1116134
    'primary key' => array('name', 'type'),
1117
    'indexes' => array(
1118134
      'hook' => array('type', 'suffix', 'weight', 'module'),
1119134
    ),
1120
  );
1121
1122134
  $schema['registry_file'] = array(
1123134
    'description' => t("Files parsed to build the registry."),
1124
    'fields' => array(
1125
      'filename'   => array(
1126134
        'description' => t('Path to the file.'),
1127134
        'type' => 'varchar',
1128134
        'length' => 255,
1129134
        'not null' => TRUE,
1130134
      ),
1131
      'md5'  => array(
1132134
        'description' => t("Md5 hash of the file's contents when last
parsed."),
1133134
        'type' => 'varchar',
1134134
        'length' => 32,
1135134
        'not null' => TRUE,
1136134
      ),
1137134
    ),
1138134
    'primary key' => array('filename'),
1139
  );
1140
1141134
  $schema['sessions'] = array(
1142134
    'description' => t("Drupal's session handlers read and write into the
sessions table. Each record represents a user session, either anonymous or
authenticated."),
1143
    'fields' => array(
1144
      'uid' => array(
1145134
        'description' => t('The {users}.uid corresponding to a session, or
0 for anonymous user.'),
1146134
        'type' => 'int',
1147134
        'unsigned' => TRUE,
1148134
        'not null' => TRUE,
1149134
      ),
1150
      'sid' => array(
1151134
        'description' => t("Primary key: A session ID. The value is
generated by PHP's Session API."),
1152134
        'type' => 'varchar',
1153134
        'length' => 64,
1154134
        'not null' => TRUE,
1155134
        'default' => '',
1156134
      ),
1157
      'hostname' => array(
1158134
        'description' => t('The IP address that last used this session ID
(sid).'),
1159134
        'type' => 'varchar',
1160134
        'length' => 128,
1161134
        'not null' => TRUE,
1162134
        'default' => '',
1163134
      ),
1164
      'timestamp' => array(
1165134
        'description' => t('The Unix timestamp when this session last
requested a page. Old records are purged by PHP automatically.'),
1166134
        'type' => 'int',
1167134
        'not null' => TRUE,
1168134
        'default' => 0,
1169134
      ),
1170
      'cache' => array(
1171134
        'description' => t("The time of this user's last post. This is used
when the site has specified a minimum_cache_lifetime. See cache_get()."),
1172134
        'type' => 'int',
1173134
        'not null' => TRUE,
1174134
        'default' => 0,
1175134
      ),
1176
      'session' => array(
1177134
        'description' => t('The serialized contents of $_SESSION, an array
of name/value pairs that persists across page requests by this session ID.
Drupal loads $_SESSION from here at the start of each request and saves it
at the end.'),
1178134
        'type' => 'text',
1179134
        'not null' => FALSE,
1180134
        'size' => 'big',
1181134
      ),
1182134
    ),
1183134
    'primary key' => array('sid'),
1184
    'indexes' => array(
1185134
      'timestamp' => array('timestamp'),
1186134
      'uid' => array('uid'),
1187134
    ),
1188
  );
1189
1190134
  $schema['system'] = array(
1191134
    'description' => t("A list of all modules, themes, and theme engines
that are or have been installed in Drupal's file system."),
1192
    'fields' => array(
1193
      'filename' => array(
1194134
        'description' => t('The path of the primary file for this item,
relative to the Drupal root; e.g. modules/node/node.module.'),
1195134
        'type' => 'varchar',
1196134
        'length' => 255,
1197134
        'not null' => TRUE,
1198134
        'default' => '',
1199134
      ),
1200
      'name' => array(
1201134
        'description' => t('The name of the item; e.g. node.'),
1202134
        'type' => 'varchar',
1203134
        'length' => 255,
1204134
        'not null' => TRUE,
1205134
        'default' => '',
1206134
      ),
1207
      'type' => array(
1208134
        'description' => t('The type of the item, either module, theme, or
theme_engine.'),
1209134
        'type' => 'varchar',
1210134
        'length' => 255,
1211134
        'not null' => TRUE,
1212134
        'default' => '',
1213134
      ),
1214
      'owner' => array(
1215134
        'description' => t("A theme's 'parent' . Can be either a theme or
an engine."),
1216134
        'type' => 'varchar',
1217134
        'length' => 255,
1218134
        'not null' => TRUE,
1219134
        'default' => '',
1220134
      ),
1221
      'status' => array(
1222134
        'description' => t('Boolean indicating whether or not this item is
enabled.'),
1223134
        'type' => 'int',
1224134
        'not null' => TRUE,
1225134
        'default' => 0,
1226134
      ),
1227
      'throttle' => array(
1228134
        'description' => t('Boolean indicating whether this item is
disabled when the throttle.module disables throttleable items.'),
1229134
        'type' => 'int',
1230134
        'not null' => TRUE,
1231134
        'default' => 0,
1232134
        'size' => 'tiny',
1233134
      ),
1234
      'bootstrap' => array(
1235134
        'description' => t("Boolean indicating whether this module is
loaded during Drupal's early bootstrapping phase (e.g. even before the page
cache is consulted)."),
1236134
        'type' => 'int',
1237134
        'not null' => TRUE,
1238134
        'default' => 0,
1239134
      ),
1240
      'schema_version' => array(
1241134
        'description' => t("The module's database schema version number. -1
if the module is not installed (its tables do not exist); 0 or the largest
N of the module's hook_update_N() function that has either been run or
existed when the module was first installed."),
1242134
        'type' => 'int',
1243134
        'not null' => TRUE,
1244134
        'default' => -1,
1245134
        'size' => 'small',
1246134
      ),
1247
      'weight' => array(
1248134
        'description' => t("The order in which this module's hooks should
be invoked relative to other modules. Equal-weighted modules are ordered by
name."),
1249134
        'type' => 'int',
1250134
        'not null' => TRUE,
1251134
        'default' => 0,
1252134
      ),
1253
      'info' => array(
1254134
        'description' => t("A serialized array containing information from
the module's .info file; keys can include name, description, package,
version, core, dependencies, dependents, and php."),
1255134
        'type' => 'text',
1256134
        'not null' => FALSE,
1257134
      ),
1258134
    ),
1259134
    'primary key' => array('filename'),
1260
    'indexes' => array(
1261134
      'modules' => array(array('type', 12), 'status', 'weight',
'filename'),
1262134
      'bootstrap' => array(array('type', 12), 'status', 'bootstrap',
'weight', 'filename'),
1263134
    ),
1264
  );
1265
1266134
  $schema['url_alias'] = array(
1267134
    'description' => t('A list of URL aliases for Drupal paths; a user may
visit either the source or destination path.'),
1268
    'fields' => array(
1269
      'pid' => array(
1270134
        'description' => t('A unique path alias identifier.'),
1271134
        'type' => 'serial',
1272134
        'unsigned' => TRUE,
1273134
        'not null' => TRUE,
1274134
      ),
1275
      'src' => array(
1276134
        'description' => t('The Drupal path this alias is for; e.g.
node/12.'),
1277134
        'type' => 'varchar',
1278134
        'length' => 128,
1279134
        'not null' => TRUE,
1280134
        'default' => '',
1281134
      ),
1282
      'dst' => array(
1283134
        'description' => t('The alias for this path; e.g.
title-of-the-story.'),
1284134
        'type' => 'varchar',
1285134
        'length' => 128,
1286134
        'not null' => TRUE,
1287134
        'default' => '',
1288134
      ),
1289
      'language' => array(
1290134
        'description' => t('The language this alias is for; if blank, the
alias will be used for unknown languages. Each Drupal path can have an
alias for each supported language.'),
1291134
        'type' => 'varchar',
1292134
        'length' => 12,
1293134
        'not null' => TRUE,
1294134
        'default' => '',
1295134
      ),
1296134
    ),
1297
    'unique keys' => array(
1298134
      'dst_language' => array('dst', 'language'),
1299134
    ),
1300134
    'primary key' => array('pid'),
1301
    'indexes' => array(
1302134
      'src' => array('src'),
1303134
    ),
1304
  );
1305
1306134
  return $schema;
13070
}
1308
1309
// Updates for core.
1310
131112
function system_update_last_removed() {
13120
  return 1021;
13130
}
1314
1315
/**
1316
 * @defgroup updates-5.x-extra Extra system updates for 5.x
1317
 * @{
1318
 */
1319
1320
/**
1321
 * Add index on users created column.
1322
 */
132312
function system_update_1022() {
13240
  $ret = array();
13250
  db_add_index($ret, 'users', 'created', array('created'));
1326
  // Also appears as system_update_6004(). Ensure we don't update twice.
13270
  variable_set('system_update_1022', TRUE);
13280
  return $ret;
13290
}
1330
1331
/**
1332
 * @} End of "defgroup updates-5.x-extra"
1333
 */
1334
1335
/**
1336
 * @defgroup updates-5.x-to-6.x System updates from 5.x to 6.x
1337
 * @{
1338
 */
1339
1340
/**
1341
 * Remove auto_increment from {boxes} to allow adding custom blocks with
1342
 * visibility settings.
1343
 */
134412
function system_update_6000() {
13450
  $ret = array();
13460
  switch ($GLOBALS['db_type']) {
13470
    case 'mysql':
13480
    case 'mysqli':
13490
      $max = (int)db_result(db_query('SELECT MAX(bid) FROM {boxes}'));
13500
      $ret[] = update_sql('ALTER TABLE {boxes} CHANGE COLUMN bid bid int
NOT NULL');
13510
      $ret[] = update_sql("REPLACE INTO {sequences} VALUES ('{boxes}_bid',
$max)");
13520
      break;
13530
  }
13540
  return $ret;
13550
}
1356
1357
/**
1358
 * Add version id column to {term_node} to allow taxonomy module to use
revisions.
1359
 */
136012
function system_update_6001() {
13610
  $ret = array();
1362
1363
  // Add vid to term-node relation.  The schema says it is unsigned.
13640
  db_add_field($ret, 'term_node', 'vid', array('type' => 'int', 'unsigned'
=> TRUE, 'not null' => TRUE, 'default' => 0));
13650
  db_drop_primary_key($ret, 'term_node');
13660
  db_add_primary_key($ret, 'term_node', array('vid', 'tid', 'nid'));
13670
  db_add_index($ret, 'term_node', 'vid', array('vid'));
1368
13690
  db_query('UPDATE {term_node} t SET vid = (SELECT vid FROM {node} n WHERE
t.nid = n.nid)');
13700
  return $ret;
13710
}
1372
1373
/**
1374
 * Increase the maximum length of variable names from 48 to 128.
1375
 */
137612
function system_update_6002() {
13770
  $ret = array();
13780
  db_drop_primary_key($ret, 'variable');
13790
  db_change_field($ret, 'variable', 'name', 'name', array('type' =>
'varchar', 'length' => 128, 'not null' => TRUE, 'default' => ''));
13800
  db_add_primary_key($ret, 'variable', array('name'));
13810
  return $ret;
13820
}
1383
1384
/**
1385
 * Add index on comments status column.
1386
 */
138712
function system_update_6003() {
13880
  $ret = array();
13890
  db_add_index($ret, 'comments', 'status', array('status'));
13900
  return $ret;
13910
}
1392
1393
/**
1394
 * This update used to add an index on users created column (#127941).
1395
 * However, system_update_1022() does the same thing.  This update
1396
 * tried to detect if 1022 had already run but failed to do so,
1397
 * resulting in an "index already exists" error.
1398
 *
1399
 * Adding the index here is never necessary.  Sites installed before
1400
 * 1022 will run 1022, getting the update.  Sites installed on/after 1022
1401
 * got the index when the table was first created.  Therefore, this
1402
 * function is now a no-op.
1403
 */
140412
function system_update_6004() {
14050
  return array();
14060
}
1407
1408
/**
1409
 * Add language to url_alias table and modify indexes.
1410
 */
141112
function system_update_6005() {
14120
  $ret = array();
14130
  switch ($GLOBALS['db_type']) {
14140
    case 'pgsql':
14150
      db_add_column($ret, 'url_alias', 'language', 'varchar(12)',
array('default' => "''", 'not null' => TRUE));
1416
1417
      // As of system.install:1.85 (before the new language
1418
      // subsystem), new installs got a unique key named
1419
      // url_alias_dst_key on url_alias.dst.  Unfortunately,
1420
      // system_update_162 created a unique key inconsistently named
1421
      // url_alias_dst_idx on url_alias.dst (keys should have the _key
1422
      // suffix, indexes the _idx suffix).  Therefore, sites installed
1423
      // before system_update_162 have a unique key with a different
1424
      // name than sites installed after system_update_162().  Now, we
1425
      // want to drop the unique key on dst which may have either one
1426
      // of two names and create a new unique key on (dst, language).
1427
      // There is no way to know which key name exists so we have to
1428
      // drop both, causing an SQL error.  Thus, we just hide the
1429
      // error and only report the update_sql results that work.
14300
      $err = error_reporting(0);
14310
      $ret1 = update_sql('DROP INDEX {url_alias}_dst_idx');
14320
      if ($ret1['success']) {
14330
  $ret[] = $ret1;
14340
      }
14350
      $ret1 = array();
14360
      db_drop_unique_key($ret, 'url_alias', 'dst');
14370
      foreach ($ret1 as $r) {
14380
  if ($r['success']) {
14390
    $ret[] = $r;
14400
  }
14410
      }
14420
      error_reporting($err);
1443
14440
      $ret[] = update_sql('CREATE UNIQUE INDEX {url_alias}_dst_language_idx
ON {url_alias}(dst, language)');
14450
      break;
14460
    case 'mysql':
14470
    case 'mysqli':
14480
      $ret[] = update_sql("ALTER TABLE {url_alias} ADD language varchar(12)
NOT NULL default ''");
14490
      $ret[] = update_sql("ALTER TABLE {url_alias} DROP INDEX dst");
14500
      $ret[] = update_sql("ALTER TABLE {url_alias} ADD UNIQUE dst_language
(dst, language)");
14510
      break;
14520
  }
14530
  return $ret;
14540
}
1455
1456
/**
1457
 * Drop useless indices on node_counter table.
1458
 */
145912
function system_update_6006() {
14600
  $ret = array();
14610
  switch ($GLOBALS['db_type']) {
14620
    case 'pgsql':
14630
      $ret[] = update_sql('DROP INDEX {node_counter}_daycount_idx');
14640
      $ret[] = update_sql('DROP INDEX {node_counter}_totalcount_idx');
14650
      $ret[] = update_sql('DROP INDEX {node_counter}_timestamp_idx');
14660
      break;
14670
    case 'mysql':
14680
    case 'mysqli':
14690
      $ret[] = update_sql("ALTER TABLE {node_counter} DROP INDEX
daycount");
14700
      $ret[] = update_sql("ALTER TABLE {node_counter} DROP INDEX
totalcount");
14710
      $ret[] = update_sql("ALTER TABLE {node_counter} DROP INDEX
timestamp");
14720
      break;
14730
  }
14740
  return $ret;
14750
}
1476
1477
/**
1478
 * Change the severity column in the watchdog table to the new values.
1479
 */
148012
function system_update_6007() {
14810
  $ret = array();
14820
  $ret[] = update_sql("UPDATE {watchdog} SET severity = " . WATCHDOG_NOTICE
. " WHERE severity = 0");
14830
  $ret[] = update_sql("UPDATE {watchdog} SET severity = " .
WATCHDOG_WARNING . " WHERE severity = 1");
14840
  $ret[] = update_sql("UPDATE {watchdog} SET severity = " . WATCHDOG_ERROR
. " WHERE severity = 2");
14850
  return $ret;
14860
}
1487
1488
/**
1489
 * Add info files to themes.  The info and owner columns are added by
1490
 * update_fix_d6_requirements() in update.php to avoid a large number
1491
 * of error messages from update.php.  All we need to do here is copy
1492
 * description to owner and then drop description.
1493
 */
149412
function system_update_6008() {
14950
  $ret = array();
14960
  $ret[] = update_sql('UPDATE {system} SET owner = description');
14970
  db_drop_field($ret, 'system', 'description');
1498
1499
  // Rebuild system table contents.
15000
  module_rebuild_cache();
15010
  system_theme_data();
1502
15030
  return $ret;
15040
}
1505
1506
/**
1507
 * The PHP filter is now a separate module.
1508
 */
150912
function system_update_6009() {
15100
  $ret = array();
1511
1512
  // If any input format used the Drupal 5 PHP filter.
15130
  if (db_result(db_query("SELECT COUNT(format) FROM {filters} WHERE module
= 'filter' AND delta = 1"))) {
1514
    // Enable the PHP filter module.
15150
    $ret[] = update_sql("UPDATE {system} SET status = 1 WHERE name = 'php'
AND type = 'module'");
1516
    // Update the input filters.
15170
    $ret[] = update_sql("UPDATE {filters} SET delta = 0, module = 'php'
WHERE module = 'filter' AND delta = 1");
15180
  }
1519
1520
  // With the removal of the PHP evaluator filter, the deltas of the line
break
1521
  // and URL filter have changed.
15220
  $ret[] = update_sql("UPDATE {filters} SET delta = 1 WHERE module =
'filter' AND delta = 2");
15230
  $ret[] = update_sql("UPDATE {filters} SET delta = 2 WHERE module =
'filter' AND delta = 3");
1524
15250
  return $ret;
15260
}
1527
1528
/**
1529
 * Add variable replacement for watchdog messages.
1530
 *
1531
 * The variables field is NOT NULL and does not have a default value.
1532
 * Existing log messages should not be translated in the new system,
1533
 * so we insert 'N;' (serialize(NULL)) as the temporary default but
1534
 * then remove the default value to match the schema.
1535
 */
153612
function system_update_6010() {
15370
  $ret = array();
15380
  db_add_field($ret, 'watchdog', 'variables', array('type' => 'text',
'size' => 'big', 'not null' => TRUE, 'initial' => 'N;'));
15390
  return $ret;
15400
}
1541
1542
/**
1543
 * Add language support to nodes
1544
 */
154512
function system_update_6011() {
15460
  $ret = array();
15470
  switch ($GLOBALS['db_type']) {
15480
    case 'pgsql':
15490
      db_add_column($ret, 'node', 'language', 'varchar(12)',
array('default' => "''", 'not null' => TRUE));
15500
      break;
15510
    case 'mysql':
15520
    case 'mysqli':
15530
      $ret[] = update_sql("ALTER TABLE {node} ADD language varchar(12) NOT
NULL default ''");
15540
      break;
15550
  }
15560
  return $ret;
15570
}
1558
1559
/**
1560
 * Add serialized field to cache tables.  This is now handled directly
1561
 * by update.php, so this function is a no-op.
1562
 */
156312
function system_update_6012() {
15640
  return array();
15650
}
1566
1567
/**
1568
 * Rebuild cache data for theme system changes
1569
 */
157012
function system_update_6013() {
1571
  // Rebuild system table contents.
15720
  module_rebuild_cache();
15730
  system_theme_data();
1574
15750
  return array(array('success' => TRUE, 'query' => 'Cache rebuilt.'));
15760
}
1577
1578
/**
1579
 * Record that the installer is done, so it is not
1580
 * possible to run the installer on upgraded sites.
1581
 */
158212
function system_update_6014() {
15830
  variable_set('install_task', 'done');
1584
15850
  return array(array('success' => TRUE, 'query' =>
"variable_set('install_task')"));
15860
}
1587
1588
/**
1589
 * Add the form cache table.
1590
 */
159112
function system_update_6015() {
15920
  $ret = array();
1593
15940
  switch ($GLOBALS['db_type']) {
15950
    case 'pgsql':
15960
      $ret[] = update_sql("CREATE TABLE {cache_form} (
1597
        cid varchar(255) NOT NULL default '',
1598
        data bytea,
1599
        expire int NOT NULL default '0',
1600
        created int NOT NULL default '0',
1601
        headers text,
1602
        serialized smallint NOT NULL default '0',
1603
        PRIMARY KEY (cid)
16040
    )");
16050
      $ret[] = update_sql("CREATE INDEX {cache_form}_expire_idx ON
{cache_form} (expire)");
16060
      break;
16070
    case 'mysql':
16080
    case 'mysqli':
16090
      $ret[] = update_sql("CREATE TABLE {cache_form} (
1610
        cid varchar(255) NOT NULL default '',
1611
        data longblob,
1612
        expire int NOT NULL default '0',
1613
        created int NOT NULL default '0',
1614
        headers text,
1615
        serialized int(1) NOT NULL default '0',
1616
        PRIMARY KEY (cid),
1617
        INDEX expire (expire)
16180
      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
16190
      break;
16200
  }
1621
16220
  return $ret;
16230
}
1624
1625
/**
1626
 * Make {node}'s primary key be nid, change nid,vid to a unique key.
1627
 * Add primary keys to block, filters, flood, permission, and
term_relation.
1628
 */
162912
function system_update_6016() {
16300
  $ret = array();
1631
16320
  switch ($GLOBALS['db_type']) {
16330
    case 'pgsql':
16340
      $ret[] = update_sql("ALTER TABLE {node} ADD CONSTRAINT
{node}_nid_vid_key UNIQUE (nid, vid)");
16350
      db_add_column($ret, 'blocks', 'bid', 'serial');
16360
      $ret[] = update_sql("ALTER TABLE {blocks} ADD PRIMARY KEY (bid)");
16370
      db_add_column($ret, 'filters', 'fid', 'serial');
16380
      $ret[] = update_sql("ALTER TABLE {filters} ADD PRIMARY KEY (fid)");
16390
      db_add_column($ret, 'flood', 'fid', 'serial');
16400
      $ret[] = update_sql("ALTER TABLE {flood} ADD PRIMARY KEY (fid)");
16410
      db_add_column($ret, 'permission', 'pid', 'serial');
16420
      $ret[] = update_sql("ALTER TABLE {permission} ADD PRIMARY KEY
(pid)");
16430
      db_add_column($ret, 'term_relation', 'trid', 'serial');
16440
      $ret[] = update_sql("ALTER TABLE {term_relation} ADD PRIMARY KEY
(trid)");
16450
      db_add_column($ret, 'term_synonym', 'tsid', 'serial');
16460
      $ret[] = update_sql("ALTER TABLE {term_synonym} ADD PRIMARY KEY
(tsid)");
16470
      break;
16480
    case 'mysql':
16490
    case 'mysqli':
16500
      $ret[] = update_sql('ALTER TABLE {node} ADD UNIQUE KEY nid_vid (nid,
vid)');
16510
      $ret[] = update_sql("ALTER TABLE {blocks} ADD bid int NOT NULL
AUTO_INCREMENT PRIMARY KEY");
16520
      $ret[] = update_sql("ALTER TABLE {filters} ADD fid int NOT NULL
AUTO_INCREMENT PRIMARY KEY");
16530
      $ret[] = update_sql("ALTER TABLE {flood} ADD fid int NOT NULL
AUTO_INCREMENT PRIMARY KEY");
16540
      $ret[] = update_sql("ALTER TABLE {permission} ADD pid int NOT NULL
AUTO_INCREMENT PRIMARY KEY");
16550
      $ret[] = update_sql("ALTER TABLE {term_relation} ADD trid int NOT
NULL AUTO_INCREMENT PRIMARY KEY");
16560
      $ret[] = update_sql("ALTER TABLE {term_synonym} ADD tsid int NOT NULL
AUTO_INCREMENT PRIMARY KEY");
16570
      break;
16580
  }
1659
16600
  return $ret;
16610
}
1662
1663
/**
1664
 * Rename settings related to user.module email notifications.
1665
 */
166612
function system_update_6017() {
16670
  $ret = array();
1668
  // Maps old names to new ones.
1669
  $var_names = array(
16700
    'admin'    => 'register_admin_created',
16710
    'approval' => 'register_pending_approval',
16720
    'welcome'  => 'register_no_approval_required',
16730
    'pass'     => 'password_reset',
16740
  );
16750
  foreach ($var_names as $old => $new) {
16760
    foreach (array('_subject', '_body') as $suffix) {
16770
      $old_name = 'user_mail_' . $old . $suffix;
16780
      $new_name = 'user_mail_' . $new . $suffix;
16790
      if ($old_val = variable_get($old_name, FALSE)) {
16800
        variable_set($new_name, $old_val);
16810
        variable_del($old_name);
16820
        $ret[] = array('success' => TRUE, 'query' =>
"variable_set($new_name)");
16830
        $ret[] = array('success' => TRUE, 'query' =>
"variable_del($old_name)");
16840
        if ($old_name == 'user_mail_approval_body') {
16850
          drupal_set_message('Saving an old value of the welcome message
body for users that are pending administrator approval. However, you should
consider modifying this text, since Drupal can now be configured to
automatically notify users and send them their login information when their
accounts are approved. See the <a href="' . url('admin/user/settings') .
'">User settings</a> page for details.');
16860
        }
16870
      }
16880
    }
16890
  }
16900
  return $ret;
16910
}
1692
1693
/**
1694
 * Add HTML corrector to HTML formats or replace the old module if it was
in use.
1695
 */
169612
function system_update_6018() {
16970
  $ret = array();
1698
1699
  // Disable htmlcorrector.module, if it exists and replace its filter.
17000
  if (module_exists('htmlcorrector')) {
17010
    module_disable(array('htmlcorrector'));
17020
    $ret[] = update_sql("UPDATE {filter_formats} SET module = 'filter',
delta = 3 WHERE module = 'htmlcorrector'");
17030
    $ret[] = array('success' => TRUE, 'query' => 'HTML Corrector module was
disabled; this functionality has now been added to core.');
17040
    return $ret;
17050
  }
1706
1707
  // Otherwise, find any format with 'HTML' in its name and add the filter
at the end.
17080
  $result = db_query("SELECT format, name FROM {filter_formats} WHERE name
LIKE '%HTML%'");
17090
  while ($format = db_fetch_object($result)) {
17100
    $weight = db_result(db_query("SELECT MAX(weight) FROM {filters} WHERE
format = %d", $format->format));
17110
    db_query("INSERT INTO {filters} (format, module, delta, weight) VALUES
(%d, '%s', %d, %d)", $format->format, 'filter', 3, max(10, $weight + 1));
17120
    $ret[] = array('success' => TRUE, 'query' => "HTML corrector filter
added to the '" . $format->name . "' input format.");
17130
  }
1714
17150
  return $ret;
17160
}
1717
1718
/**
1719
 * Reconcile small differences in the previous, manually created mysql
1720
 * and pgsql schemas so they are the same and can be represented by a
1721
 * single schema structure.
1722
 *
1723
 * Note that the mysql and pgsql cases make different changes.  This
1724
 * is because each schema needs to be tweaked in different ways to
1725
 * conform to the new schema structure.  Also, since they operate on
1726
 * tables defined by many optional core modules which may not ever
1727
 * have been installed, they must test each table for existence.  If
1728
 * the modules are first installed after this update exists the tables
1729
 * will be created from the schema structure and will start out
1730
 * correct.
1731
 */
173212
function system_update_6019() {
17330
  $ret = array();
1734
17350
  switch ($GLOBALS['db_type']) {
17360
    case 'pgsql':
1737
      // Remove default ''.
17380
      if (db_table_exists('aggregator_feed')) {
17390
        db_field_set_no_default($ret, 'aggregator_feed', 'description');
17400
        db_field_set_no_default($ret, 'aggregator_feed', 'image');
17410
      }
17420
      db_field_set_no_default($ret, 'blocks', 'pages');
17430
      if (db_table_exists('contact')) {
17440
        db_field_set_no_default($ret, 'contact', 'recipients');
17450
        db_field_set_no_default($ret, 'contact', 'reply');
17460
      }
17470
      db_field_set_no_default($ret, 'watchdog', 'location');
17480
      db_field_set_no_default($ret, 'node_revisions', 'body');
17490
      db_field_set_no_default($ret, 'node_revisions', 'teaser');
17500
      db_field_set_no_default($ret, 'node_revisions', 'log');
1751
1752
      // Update from pgsql 'float' (which means 'double precision') to
1753
      // schema 'float' (which in pgsql means 'real').
17540
      if (db_table_exists('search_index')) {
17550
        db_change_field($ret, 'search_index', 'score', 'score',
array('type' => 'float'));
17560
      }
17570
      if (db_table_exists('search_total')) {
17580
        db_change_field($ret, 'search_total', 'count', 'count',
array('type' => 'float'));
17590
      }
1760
1761
      // Replace unique index dst_language with a unique constraint.  The
1762
      // result is the same but the unique key fits our current schema
1763
      // structure.  Also, the postgres documentation implies that
1764
      // unique constraints are preferable to unique indexes.  See
1765
      //
http://www.postgresql.org/docs/8.2/interactive/indexes-unique.html.
17660
      if (db_table_exists('url_alias')) {
17670
        db_drop_index($ret, 'url_alias', 'dst_language');
17680
        db_add_unique_key($ret, 'url_alias', 'dst_language',
17690
          array('dst', 'language'));
17700
      }
1771
1772
      // Fix term_node pkey: mysql and pgsql code had different orders.
17730
      if (db_table_exists('term_node')) {
17740
        db_drop_primary_key($ret, 'term_node');
17750
        db_add_primary_key($ret, 'term_node', array('vid', 'tid', 'nid'));
17760
      }
1777
1778
      // Make boxes.bid unsigned.
17790
      db_drop_primary_key($ret, 'boxes');
17800
      db_change_field($ret, 'boxes', 'bid', 'bid', array('type' =>
'serial', 'unsigned' => TRUE, 'not null' => TRUE), array('primary key' =>
array('bid')));
1781
1782
      // Fix primary key
17830
      db_drop_primary_key($ret, 'node');
17840
      db_add_primary_key($ret, 'node', array('nid'));
1785
17860
      break;
1787
17880
    case 'mysql':
17890
    case 'mysqli':
1790
      // Rename key 'link' to 'url'.
17910
      if (db_table_exists('aggregator_feed')) {
17920
        db_drop_unique_key($ret, 'aggregator_feed', 'link');
17930
        db_add_unique_key($ret, 'aggregator_feed', 'url', array('url'));
17940
      }
1795
1796
      // Change to size => small.
17970
      if (db_table_exists('boxes')) {
17980
        db_change_field($ret, 'boxes', 'format', 'format', array('type' =>
'int', 'size' => 'small', 'not null' => TRUE, 'default' => 0));
17990
      }
1800
1801
      // Change to size => small.
1802
      // Rename index 'lid' to 'nid'.
18030
      if (db_table_exists('comments')) {
18040
        db_change_field($ret, 'comments', 'format', 'format', array('type'
=> 'int', 'size' => 'small', 'not null' => TRUE, 'default' => 0));
18050
        db_drop_index($ret, 'comments', 'lid');
18060
        db_add_index($ret, 'comments', 'nid', array('nid'));
18070
      }
1808
1809
      // Change to size => small.
18100
      db_change_field($ret, 'cache', 'serialized', 'serialized',
array('type' => 'int', 'size' => 'small', 'not null' => TRUE, 'default' =>
0));
18110
      db_change_field($ret, 'cache_filter', 'serialized', 'serialized',
array('type' => 'int', 'size' => 'small', 'not null' => TRUE, 'default' =>
0));
18120
      db_change_field($ret, 'cache_page', 'serialized', 'serialized',
array('type' => 'int', 'size' => 'small', 'not null' => TRUE, 'default' =>
0));
18130
      db_change_field($ret, 'cache_form', 'serialized', 'serialized',
array('type' => 'int', 'size' => 'small', 'not null' => TRUE, 'default' =>
0));
1814
1815
      // Remove default => 0, set auto increment.
18160
      $new_uid = 1 + db_result(db_query('SELECT MAX(uid) FROM {users}'));
18170
      $ret[] = update_sql('UPDATE {users} SET uid = ' . $new_uid . ' WHERE
uid = 0');
18180
      db_drop_primary_key($ret, 'users');
18190
      db_change_field($ret, 'users', 'uid', 'uid', array('type' =>
'serial', 'unsigned' => TRUE, 'not null' => TRUE), array('primary key' =>
array('uid')));
18200
      $ret[] = update_sql('UPDATE {users} SET uid = 0 WHERE uid = ' .
$new_uid);
1821
1822
      // Special field names.
18230
      $map = array('node_revisions' => 'vid');
1824
      // Make sure these tables have proper auto_increment fields.
18250
      foreach (array('boxes', 'files', 'node', 'node_revisions') as $table)
{
18260
        $field = isset($map[$table]) ? $map[$table] : $table[0] . 'id';
18270
        db_drop_primary_key($ret, $table);
18280
        db_change_field($ret, $table, $field, $field, array('type' =>
'serial', 'unsigned' => TRUE, 'not null' => TRUE), array('primary key' =>
array($field)));
18290
      }
1830
18310
      break;
18320
  }
1833
18340
  return $ret;
18350
}
1836
1837
/**
1838
 * Create the tables for the new menu system.
1839
 */
184012
function system_update_6020() {
18410
  $ret = array();
1842
18430
  $schema['menu_router'] = array(
1844
    'fields' => array(
18450
      'path'             => array('type' => 'varchar', 'length' => 255,
'not null' => TRUE, 'default' => ''),
18460
      'load_functions'   => array('type' => 'varchar', 'length' => 255,
'not null' => TRUE, 'default' => ''),
18470
      'to_arg_functions' => array('type' => 'varchar', 'length' => 255,
'not null' => TRUE, 'default' => ''),
18480
      'access_callback'  => array('type' => 'varchar', 'length' => 255,
'not null' => TRUE, 'default' => ''),
18490
      'access_arguments' => array('type' => 'text', 'not null' => FALSE),
18500
      'page_callback'    => array('type' => 'varchar', 'length' => 255,
'not null' => TRUE, 'default' => ''),
18510
      'page_arguments'   => array('type' => 'text', 'not null' => FALSE),
18520
      'fit'              => array('type' => 'int', 'not null' => TRUE,
'default' => 0),
18530
      'number_parts'     => array('type' => 'int', 'not null' => TRUE,
'default' => 0, 'size' => 'small'),
18540
      'tab_parent'       => array('type' => 'varchar', 'length' => 255,
'not null' => TRUE, 'default' => ''),
18550
      'tab_root'         => array('type' => 'varchar', 'length' => 255,
'not null' => TRUE, 'default' => ''),
18560
      'title'            => array('type' => 'varchar', 'length' => 255,
'not null' => TRUE, 'default' => ''),
18570
      'title_callback'   => array('type' => 'varchar', 'length' => 255,
'not null' => TRUE, 'default' => ''),
18580
      'title_arguments'  => array('type' => 'varchar', 'length' => 255,
'not null' => TRUE, 'default' => ''),
18590
      'type'             => array('type' => 'int', 'not null' => TRUE,
'default' => 0),
18600
      'block_callback'   => array('type' => 'varchar', 'length' => 255,
'not null' => TRUE, 'default' => ''),
18610
      'description'      => array('type' => 'text', 'not null' => TRUE),
18620
      'position'         => array('type' => 'varchar', 'length' => 255,
'not null' => TRUE, 'default' => ''),
18630
      'weight'           => array('type' => 'int', 'not null' => TRUE,
'default' => 0),
18640
      'file'             => array('type' => 'text', 'size' => 'medium')
18650
    ),
1866
    'indexes' => array(
18670
      'fit'        => array('fit'),
18680
      'tab_parent' => array('tab_parent')
18690
    ),
18700
    'primary key' => array('path'),
1871
  );
1872
18730
  $schema['menu_links'] = array(
1874
    'fields' => array(
18750
      'menu_name'    => array('type' => 'varchar', 'length' => 32, 'not
null' => TRUE, 'default' => ''),
18760
      'mlid'         => array('type' => 'serial', 'unsigned' => TRUE, 'not
null' => TRUE),
18770
      'plid'         => array('type' => 'int', 'unsigned' => TRUE, 'not
null' => TRUE, 'default' => 0),
18780
      'link_path'    => array('type' => 'varchar', 'length' => 255, 'not
null' => TRUE, 'default' => ''),
18790
      'router_path'  => array('type' => 'varchar', 'length' => 255, 'not
null' => TRUE, 'default' => ''),
18800
      'link_title'   => array('type' => 'varchar', 'length' => 255, 'not
null' => TRUE, 'default' => ''),
18810
      'options'      => array('type' => 'text', 'not null' => FALSE),
18820
      'module'       => array('type' => 'varchar', 'length' => 255, 'not
null' => TRUE, 'default' => 'system'),
18830
      'hidden'       => array('type' => 'int', 'not null' => TRUE,
'default' => 0, 'size' => 'small'),
18840
      'external'     => array('type' => 'int', 'not null' => TRUE,
'default' => 0, 'size' => 'small'),
18850
      'has_children' => array('type' => 'int', 'not null' => TRUE,
'default' => 0, 'size' => 'small'),
18860
      'expanded'     => array('type' => 'int', 'not null' => TRUE,
'default' => 0, 'size' => 'small'),
18870
      'weight'       => array('type' => 'int', 'not null' => TRUE,
'default' => 0),
18880
      'depth'        => array('type' => 'int', 'not null' => TRUE,
'default' => 0, 'size' => 'small'),
18890
      'customized'   => array('type' => 'int', 'not null' => TRUE,
'default' => 0, 'size' => 'small'),
18900
      'p1'           => array('type' => 'int', 'unsigned' => TRUE, 'not
null' => TRUE, 'default' => 0),
18910
      'p2'           => array('type' => 'int', 'unsigned' => TRUE, 'not
null' => TRUE, 'default' => 0),
18920
      'p3'           => array('type' => 'int', 'unsigned' => TRUE, 'not
null' => TRUE, 'default' => 0),
18930
      'p4'           => array('type' => 'int', 'unsigned' => TRUE, 'not
null' => TRUE, 'default' => 0),
18940
      'p5'           => array('type' => 'int', 'unsigned' => TRUE, 'not
null' => TRUE, 'default' => 0),
18950
      'p6'           => array('type' => 'int', 'unsigned' => TRUE, 'not
null' => TRUE, 'default' => 0),
18960
      'p7'           => array('type' => 'int', 'unsigned' => TRUE, 'not
null' => TRUE, 'default' => 0),
18970
      'p8'           => array('type' => 'int', 'unsigned' => TRUE, 'not
null' => TRUE, 'default' => 0),
18980
      'p9'           => array('type' => 'int', 'unsigned' => TRUE, 'not
null' => TRUE, 'default' => 0),
18990
      'updated'      => array('type' => 'int', 'not null' => TRUE,
'default' => 0, 'size' => 'small'),
19000
    ),
1901
    'indexes' => array(
19020
      'path_menu'              => array(array('link_path', 128),
'menu_name'),
19030
      'menu_plid_expand_child' => array('menu_name', 'plid', 'expanded',
'has_children'),
19040
      'menu_parents'           => array('menu_name', 'p1', 'p2', 'p3',
'p4', 'p5', 'p6', 'p7', 'p8', 'p9'),
19050
      'router_path'            => array(array('router_path', 128)),
19060
    ),
19070
    'primary key' => array('mlid'),
1908
  );
1909
19100
  foreach ($schema as $name => $table) {
19110
    db_create_table($ret, $name, $table);
19120
  }
19130
  return $ret;
19140
}
1915
1916
/**
1917
 * Migrate the menu items from the old menu system to the new menu_links
table.
1918
 */
191912
function system_update_6021() {
19200
  $ret = array('#finished' => 0);
1921
  $menus = array(
1922
    'navigation' => array(
19230
      'menu_name' => 'navigation',
19240
      'title' => 'Navigation',
19250
      'description' => 'The navigation menu is provided by Drupal and is
the main interactive menu for any site. It is usually the only menu that
contains personalized links for authenticated users, and is often not even
visible to anonymous users.',
19260
    ),
1927
    'primary-links' => array(
19280
      'menu_name' => 'primary-links',
19290
      'title' => 'Primary links',
19300
      'description' => 'Primary links are often used at the theme layer to
show the major sections of a site. A typical representation for primary
links would be tabs along the top.',
19310
    ),
1932
    'secondary-links' => array(
19330
      'menu_name' => 'secondary-links',
19340
      'title' => 'Secondary links',
19350
      'description' => 'Secondary links are often used for pages like legal
notices, contact details, and other secondary navigation items that play a
lesser role than primary links.',
19360
    ),
19370
  );
1938
  // Multi-part update
19390
  if (!isset($_SESSION['system_update_6021'])) {
19400
    db_add_field($ret, 'menu', 'converted', array('type' => 'int',
'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'size' => 'tiny'));
19410
    $_SESSION['system_update_6021_max'] = db_result(db_query('SELECT
COUNT(*) FROM {menu}'));
19420
    $_SESSION['menu_menu_map'] = array(1 => 'navigation');
1943
    // 0 => FALSE is for new menus, 1 => FALSE is for the navigation.
19440
    $_SESSION['menu_item_map'] = array(0 => FALSE, 1 => FALSE);
1945
    $table = array(
1946
      'fields' => array(
19470
        'menu_name'   => array('type' => 'varchar', 'length' => 32, 'not
null' => TRUE, 'default' => ''),
19480
        'title'       => array('type' => 'varchar', 'length' => 255, 'not
null' => TRUE, 'default' => ''),
19490
        'description' => array('type' => 'text', 'not null' => FALSE),
19500
      ),
19510
      'primary key' => array('menu_name'),
19520
    );
19530
    db_create_table($ret, 'menu_custom', $table);
19540
    db_query("INSERT INTO {menu_custom} (menu_name, title, description)
VALUES ('%s', '%s', '%s')", $menus['navigation']);
19550
    $_SESSION['system_update_6021'] = 0;
19560
  }
1957
19580
  $limit = 50;
19590
  while ($limit-- && ($item = db_fetch_array(db_query_range('SELECT * FROM
{menu} WHERE converted = 0', 0, 1)))) {
1960
    // If it's not a menu...
19610
    if ($item['pid']) {
1962
      // Let's climb up until we find an item with a converted parent.
19630
      $item_original = $item;
19640
      while ($item && !isset($_SESSION['menu_item_map'][$item['pid']])) {
19650
        $item = db_fetch_array(db_query('SELECT * FROM {menu} WHERE mid =
%d', $item['pid']));
19660
      }
1967
      // This can only occur if the menu entry is a leftover in the menu
table.
1968
      // These do not appear in Drupal 5 anyways, so we skip them.
19690
      if (!$item) {
19700
        db_query('UPDATE {menu} SET converted = %d WHERE mid = %d', 1,
$item_original['mid']);
19710
        $_SESSION['system_update_6021']++;
19720
        continue;
19730
      }
19740
    }
1975
    // We need to recheck because item might have changed.
19760
    if ($item['pid']) {
1977
      // Fill the new fields.
19780
      $item['link_title'] = $item['title'];
19790
      $item['link_path'] = drupal_get_normal_path($item['path']);
1980
      // We know the parent is already set. If it's not FALSE then it's an
item.
19810
      if ($_SESSION['menu_item_map'][$item['pid']]) {
1982
        // The new menu system parent link id.
19830
        $item['plid'] = $_SESSION['menu_item_map'][$item['pid']]['mlid'];
1984
        // The new menu system menu name.
19850
        $item['menu_name'] =
$_SESSION['menu_item_map'][$item['pid']]['menu_name'];
19860
      }
1987
      else {
1988
        // This a top level element.
19890
        $item['plid'] = 0;
1990
        // The menu name is stored among the menus.
19910
        $item['menu_name'] = $_SESSION['menu_menu_map'][$item['pid']];
1992
      }
1993
      // Is the element visible in the menu block?
19940
      $item['hidden'] = !($item['type'] & MENU_VISIBLE_IN_TREE);
1995
      // Is it a custom(ized) element?
19960
      if ($item['type'] & (MENU_CREATED_BY_ADMIN | MENU_MODIFIED_BY_ADMIN))
{
19970
        $item['customized'] = TRUE;
19980
      }
1999
      // Items created via the menu module need to be assigned to it.
20000
      if ($item['type'] & MENU_CREATED_BY_ADMIN) {
20010
        $item['module'] = 'menu';
20020
        $item['router_path'] = '';
20030
        $item['updated'] = TRUE;
20040
      }
2005
      else {
20060
        $item['module'] = 'system';
20070
        $item['router_path'] = $item['path'];
20080
        $item['updated'] = FALSE;
2009
      }
2010
      // Save the link.
20110
      menu_link_save($item);
20120
      $_SESSION['menu_item_map'][$item['mid']] = array('mlid' =>
$item['mlid'], 'menu_name' => $item['menu_name']);
20130
    }
20140
    elseif (!isset($_SESSION['menu_menu_map'][$item['mid']])) {
20150
      $item['menu_name'] = 'menu-' . preg_replace('/[^a-zA-Z0-9]/', '-',
strtolower($item['title']));
20160
      $item['menu_name'] = substr($item['menu_name'], 0, 20);
20170
      $original_menu_name = $item['menu_name'];
20180
      $i = 0;
20190
      while (db_result(db_query("SELECT menu_name FROM {menu_custom} WHERE
menu_name = '%s'", $item['menu_name']))) {
20200
        $item['menu_name'] = $original_menu_name . ($i++);
20210
      }
20220
      if ($item['path']) {
2023
        // Another bunch of bogus entries. Apparently, these are leftovers
2024
        // from Drupal 4.7 .
20250
        $_SESSION['menu_bogus_menus'][] = $item['menu_name'];
20260
      }
2027
      else {
2028
        // Add this menu to the list of custom menus.
20290
        db_query("INSERT INTO {menu_custom} (menu_name, title, description)
VALUES ('%s', '%s', '')", $item['menu_name'], $item['title']);
2030
      }
20310
      $_SESSION['menu_menu_map'][$item['mid']] = $item['menu_name'];
20320
      $_SESSION['menu_item_map'][$item['mid']] = FALSE;
20330
    }
20340
    db_query('UPDATE {menu} SET converted = %d WHERE mid = %d', 1,
$item['mid']);
20350
    $_SESSION['system_update_6021']++;
20360
  }
2037
20380
  if ($_SESSION['system_update_6021'] >=
$_SESSION['system_update_6021_max']) {
20390
    if (!empty($_SESSION['menu_bogus_menus'])) {
2040
      // Remove entries in bogus menus. This is secure because we deleted
2041
      // every non-alpanumeric character from the menu name.
20420
      $ret[] = update_sql("DELETE FROM {menu_links} WHERE menu_name IN ('"
. implode("', '", $_SESSION['menu_bogus_menus']) . "')");
20430
    }
2044
20450
    $menu_primary_menu = variable_get('menu_primary_menu', 0);
2046
    // Ensure that we wind up with a system menu named 'primary-links'.
20470
    if (isset($_SESSION['menu_menu_map'][2])) {
2048
      // The primary links menu that ships with Drupal 5 has mid = 2.  If
this
2049
      // menu hasn't been deleted by the site admin, we use that.
20500
      $updated_primary_links_menu = 2;
20510
    }
20520
    elseif (isset($_SESSION['menu_menu_map'][$menu_primary_menu]) &&
$menu_primary_menu > 1) {
2053
      // Otherwise, we use the menu that is currently assigned to the
primary
2054
      // links region of the theme, as long as it exists and isn't the
2055
      // Navigation menu.
20560
      $updated_primary_links_menu = $menu_primary_menu;
20570
    }
2058
    else {
2059
      // As a last resort, create 'primary-links' as a new menu.
20600
      $updated_primary_links_menu = 0;
20610
      db_query("INSERT INTO {menu_custom} (menu_name, title, description)
VALUES ('%s', '%s', '%s')", $menus['primary-links']);
2062
    }
2063
20640
    if ($updated_primary_links_menu) {
2065
      // Change the existing menu name to 'primary-links'.
20660
      $replace = array('%new_name' => 'primary-links', '%desc' =>
$menus['primary-links']['description'], '%old_name' =>
$_SESSION['menu_menu_map'][$updated_primary_links_menu]);
20670
      $ret[] = update_sql(strtr("UPDATE {menu_custom} SET menu_name =
'%new_name', description = '%desc' WHERE menu_name = '%old_name'",
$replace));
20680
      $ret[] = update_sql("UPDATE {menu_links} SET menu_name =
'primary-links' WHERE menu_name = '" .
$_SESSION['menu_menu_map'][$updated_primary_links_menu] . "'");
20690
      $_SESSION['menu_menu_map'][$updated_primary_links_menu] =
'primary-links';
20700
    }
2071
20720
    $menu_secondary_menu = variable_get('menu_secondary_menu', 0);
2073
    // Ensure that we wind up with a system menu named 'secondary-links'.
20740
    if (isset($_SESSION['menu_menu_map'][$menu_secondary_menu]) &&
$menu_secondary_menu > 1 && $menu_secondary_menu !=
$updated_primary_links_menu) {
2075
      // We use the menu that is currently assigned to the secondary links
2076
      // region of the theme, as long as (a) it exists, (b) it isn't the
2077
      // Navigation menu, (c) it isn't the same menu we assigned as the
2078
      // system 'primary-links' menu above, and (d) it isn't the same menu
2079
      // assigned to the primary links region of the theme.
20800
      $updated_secondary_links_menu = $menu_secondary_menu;
20810
    }
2082
    else {
2083
      // Otherwise, create 'secondary-links' as a new menu.
20840
      $updated_secondary_links_menu = 0;
20850
      db_query("INSERT INTO {menu_custom} (menu_name, title, description)
VALUES ('%s', '%s', '%s')", $menus['secondary-links']);
2086
    }
2087
20880
    if ($updated_secondary_links_menu) {
2089
      // Change the existing menu name to 'secondary-links'.
20900
      $replace = array('%new_name' => 'secondary-links', '%desc' =>
$menus['secondary-links']['description'], '%old_name' =>
$_SESSION['menu_menu_map'][$updated_secondary_links_menu]);
20910
      $ret[] = update_sql(strtr("UPDATE {menu_custom} SET menu_name =
'%new_name', description = '%desc' WHERE menu_name = '%old_name'",
$replace));
20920
      $ret[] = update_sql("UPDATE {menu_links} SET menu_name =
'secondary-links' WHERE menu_name = '" .
$_SESSION['menu_menu_map'][$updated_secondary_links_menu] . "'");
20930
      $_SESSION['menu_menu_map'][$updated_secondary_links_menu] =
'secondary-links';
20940
    }
2095
2096
    // Update menu OTF preferences.
20970
    $mid = variable_get('menu_parent_items', 0);
20980
    $menu_name = ($mid && isset($_SESSION['menu_menu_map'][$mid])) ?
$_SESSION['menu_menu_map'][$mid] : 'navigation';
20990
    variable_set('menu_default_node_menu', $menu_name);
21000
    variable_del('menu_parent_items');
2101
2102
    // Update the source of the primary and secondary links.
21030
    $menu_name = ($menu_primary_menu &&
isset($_SESSION['menu_menu_map'][$menu_primary_menu])) ?
$_SESSION['menu_menu_map'][$menu_primary_menu] : '';
21040
    variable_set('menu_primary_links_source', $menu_name);
21050
    variable_del('menu_primary_menu');
2106
21070
    $menu_name = ($menu_secondary_menu &&
isset($_SESSION['menu_menu_map'][$menu_secondary_menu])) ?
$_SESSION['menu_menu_map'][$menu_secondary_menu] : '';
21080
    variable_set('menu_secondary_links_source', $menu_name);
21090
    variable_del('menu_secondary_menu');
2110
2111
    // Skip the navigation menu - it is handled by the user module.
21120
    unset($_SESSION['menu_menu_map'][1]);
2113
    // Update the deltas for all menu module blocks.
21140
    foreach ($_SESSION['menu_menu_map'] as $mid => $menu_name) {
2115
      // This is again secure because we deleted every non-alpanumeric
2116
      // character from the menu name.
21170
      $ret[] = update_sql("UPDATE {blocks} SET delta = '" . $menu_name . "'
WHERE module = 'menu' AND delta = '" . $mid . "'");
21180
      $ret[] = update_sql("UPDATE {blocks_roles} SET delta = '" .
$menu_name . "' WHERE module = 'menu' AND delta = '" . $mid . "'");
21190
    }
21200
    $ret[] = array('success' => TRUE, 'query' => 'Relocated ' .
$_SESSION['system_update_6021'] . ' existing items to the new menu
system.');
21210
    $ret[] = update_sql("DROP TABLE {menu}");
21220
    unset($_SESSION['system_update_6021'],
$_SESSION['system_update_6021_max'], $_SESSION['menu_menu_map'],
$_SESSION['menu_item_map'], $_SESSION['menu_bogus_menus']);
2123
    // Create the menu overview links - also calls menu_rebuild(). If menu
is
2124
    // disabled, then just call menu_rebuild.
21250
    if (function_exists('menu_enable')) {
21260
      menu_enable();
21270
    }
2128
    else {
21290
      menu_rebuild();
2130
    }
21310
    $ret['#finished'] = 1;
21320
  }
2133
  else {
21340
    $ret['#finished'] = $_SESSION['system_update_6021'] /
$_SESSION['system_update_6021_max'];
2135
  }
21360
  return $ret;
21370
}
2138
2139
/**
2140
 * Update files tables to associate files to a uid by default instead of a
nid.
2141
 * Rename file_revisions to upload since it should only be used by the
upload
2142
 * module used by upload to link files to nodes.
2143
 */
214412
function system_update_6022() {
21450
  $ret = array();
2146
2147
  // Rename the nid field to vid, add status and timestamp fields, and
indexes.
21480
  db_drop_index($ret, 'files', 'nid');
21490
  db_change_field($ret, 'files', 'nid', 'uid', array('type' => 'int',
'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
21500
  db_add_field($ret, 'files', 'status', array('type' => 'int', 'not null'
=> TRUE, 'default' => 0));
21510
  db_add_field($ret, 'files', 'timestamp', array('type' => 'int',
'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
21520
  db_add_index($ret, 'files', 'uid', array('uid'));
21530
  db_add_index($ret, 'files', 'status', array('status'));
21540
  db_add_index($ret, 'files', 'timestamp', array('timestamp'));
2155
2156
  // Rename the file_revisions table to upload then add nid column. Since
we're
2157
  // changing the table name we need to drop and re-add the indexes and
2158
  // the primary key so both mysql and pgsql end up with the correct index
2159
  // names.
21600
  db_drop_primary_key($ret, 'file_revisions');
21610
  db_drop_index($ret, 'file_revisions', 'vid');
21620
  db_rename_table($ret, 'file_revisions', 'upload');
21630
  db_add_field($ret, 'upload', 'nid', array('type' => 'int', 'unsigned' =>
TRUE, 'not null' => TRUE, 'default' => 0));
21640
  db_add_index($ret, 'upload', 'nid', array('nid'));
21650
  db_add_primary_key($ret, 'upload', array('vid', 'fid'));
21660
  db_add_index($ret, 'upload', 'fid', array('fid'));
2167
2168
  // The nid column was renamed to uid. Use the old nid to find the node's
uid.
21690
  update_sql('UPDATE {files} SET uid = (SELECT n.uid FROM {node} n WHERE
{files}.uid = n.nid)');
21700
  update_sql('UPDATE {upload} SET nid = (SELECT r.nid FROM {node_revisions}
r WHERE {upload}.vid = r.vid)');
2171
2172
  // Mark all existing files as FILE_STATUS_PERMANENT.
21730
  $ret[] = update_sql('UPDATE {files} SET status = 1');
2174
21750
  return $ret;
21760
}
2177
217812
function system_update_6023() {
21790
  $ret = array();
2180
2181
  // nid is DEFAULT 0
21820
  db_drop_index($ret, 'node_revisions', 'nid');
21830
  db_change_field($ret, 'node_revisions', 'nid', 'nid', array('type' =>
'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
21840
  db_add_index($ret, 'node_revisions', 'nid', array('nid'));
21850
  return $ret;
21860
}
2187
2188
/**
2189
 * Add translation fields to nodes used by translation module.
2190
 */
219112
function system_update_6024() {
21920
  $ret = array();
21930
  db_add_field($ret, 'node', 'tnid', array('type' => 'int', 'unsigned' =>
TRUE, 'not null' => TRUE, 'default' => 0));
21940
  db_add_field($ret, 'node', 'translate', array('type' => 'int', 'not null'
=> TRUE, 'default' => 0));
21950
  db_add_index($ret, 'node', 'tnid', array('tnid'));
21960
  db_add_index($ret, 'node', 'translate', array('translate'));
21970
  return $ret;
21980
}
2199
2200
/**
2201
 * Increase the maximum length of node titles from 128 to 255.
2202
 */
220312
function system_update_6025() {
22040
  $ret = array();
22050
  db_drop_index($ret, 'node', 'node_title_type');
22060
  db_change_field($ret, 'node', 'title', 'title', array('type' =>
'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
22070
  db_add_index($ret, 'node', 'node_title_type', array('title',
array('type', 4)));
22080
  db_change_field($ret, 'node_revisions', 'title', 'title', array('type' =>
'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
22090
  return $ret;
22100
}
2211
2212
/**
2213
 * Display warning about new Update status module.
2214
 */
221512
function system_update_6026() {
22160
  $ret = array();
2217
2218
  // Notify user that new update module exists.
22190
  drupal_set_message('Drupal can check periodically for important bug fixes
and security releases using the new update status module. This module can
be turned on from the <a href="' . url('admin/build/modules') . '">modules
administration page</a>. For more information please read the <a
href="http://drupal.org/handbook/modules/update">Update status handbook
page</a>.');
2220
22210
  return $ret;
22220
}
2223
2224
/**
2225
 * Add block cache.
2226
 */
222712
function system_update_6027() {
22280
  $ret = array();
2229
2230
  // Create the blocks.cache column.
22310
  db_add_field($ret, 'blocks', 'cache', array('type' => 'int', 'not null'
=> TRUE, 'default' => 1, 'size' => 'tiny'));
2232
2233
  // The cache_block table is created in update_fix_d6_requirements() since
2234
  // calls to cache_clear_all() would otherwise cause warnings.
2235
2236
  // Fill in the values for the new 'cache' column in the {blocks} table.
22370
  foreach (module_list() as $module) {
22380
    if ($module_blocks = module_invoke($module, 'block', 'list')) {
22390
      foreach ($module_blocks as $delta => $block) {
22400
        if (isset($block['cache'])) {
22410
          db_query("UPDATE {blocks} SET cache = %d WHERE module = '%s' AND
delta = %d", $block['cache'], $module, $delta);
22420
        }
22430
      }
22440
    }
22450
  }
2246
22470
  return $ret;
22480
}
2249
2250
/**
2251
 * Add the node load cache table.
2252
 */
225312
function system_update_6028() {
2254
  // Removed node_load cache to discuss it more for Drupal 7.
22550
  return array();
22560
}
2257
2258
/**
2259
 * Enable the dblog module on sites that upgrade, since otherwise
2260
 * watchdog logging will stop unexpectedly.
2261
 */
226212
function system_update_6029() {
2263
  // The watchdog table is now owned by dblog, which is not yet
2264
  // "installed" according to the system table, but the table already
2265
  // exists.  We set the module as "installed" here to avoid an error
2266
  // later.
2267
  //
2268
  // Although not the case for the initial D6 release, it is likely
2269
  // that dblog.install will have its own update functions eventually.
2270
  // However, dblog did not exist in D5 and this update is part of the
2271
  // initial D6 release, so we know that dblog is not installed yet.
2272
  // It is therefore correct to install it as version 0.  If
2273
  // dblog updates exist, the next run of update.php will get them.
22740
  drupal_set_installed_schema_version('dblog', 0);
22750
  module_enable(array('dblog'));
22760
  menu_rebuild();
22770
  return array(array('success' => TRUE, 'query' => "'dblog' module
enabled."));
22780
}
2279
2280
/**
2281
 * Add the tables required by actions.inc.
2282
 */
228312
function system_update_6030() {
22840
  $ret = array();
2285
2286
  // Rename the old contrib actions table if it exists so the contrib
version
2287
  // of the module can do something with the old data.
22880
  if (db_table_exists('actions')) {
22890
    db_rename_table($ret, 'actions', 'actions_old_contrib');
22900
  }
2291
22920
  $schema['actions'] = array(
2293
    'fields' => array(
22940
      'aid' => array('type' => 'varchar', 'length' => 255, 'not null' =>
TRUE, 'default' => '0'),
22950
      'type' => array('type' => 'varchar', 'length' => 32, 'not null' =>
TRUE, 'default' => ''),
22960
      'callback' => array('type' => 'varchar', 'length' => 255, 'not null'
=> TRUE, 'default' => ''),
22970
      'parameters' => array('type' => 'text', 'not null' => TRUE, 'size' =>
'big'),
22980
      'description' => array('type' => 'varchar', 'length' => 255, 'not
null' => TRUE, 'default' => '0'),
22990
    ),
23000
    'primary key' => array('aid'),
2301
  );
2302
23030
  $schema['actions_aid'] = array(
2304
    'fields' => array(
23050
      'aid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' =>
TRUE),
23060
    ),
23070
    'primary key' => array('aid'),
2308
  );
2309
23100
  db_create_table($ret, 'actions', $schema['actions']);
23110
  db_create_table($ret, 'actions_aid', $schema['actions_aid']);
2312
23130
  return $ret;
23140
}
2315
2316
/**
2317
 * Ensure that installer cannot be run again after updating from Drupal 5.x
to 6.x
2318
 * Actually, this is already done by system_update_6014(), so this is now a
no-op.
2319
 */
232012
function system_update_6031() {
23210
  return array();
23220
}
2323
2324
/**
2325
 * profile_fields.name used to be nullable but is part of a unique key
2326
 * and so shouldn't be.
2327
 */
232812
function system_update_6032() {
23290
  $ret = array();
23300
  if (db_table_exists('profile_fields')) {
23310
    db_drop_unique_key($ret, 'profile_fields', 'name');
23320
    db_change_field($ret, 'profile_fields', 'name', 'name', array('type' =>
'varchar', 'length' => 128, 'not null' => TRUE, 'default' => ''));
23330
    db_add_unique_key($ret, 'profile_fields', 'name', array('name'));
23340
  }
23350
  return $ret;
23360
}
2337
2338
/**
2339
 * Change node_comment_statistics to be not autoincrement.
2340
 */
234112
function system_update_6033() {
23420
  $ret = array();
23430
  if (db_table_exists('node_comment_statistics')) {
2344
    // On pgsql but not mysql, db_change_field() drops all keys
2345
    // involving the changed field, which in this case is the primary
2346
    // key.  The normal approach is explicitly drop the pkey, change the
2347
    // field, and re-create the pkey.
2348
    //
2349
    // Unfortunately, in this case that won't work on mysql; we CANNOT
2350
    // drop the pkey because on mysql auto-increment fields must be
2351
    // included in at least one key or index.
2352
    //
2353
    // Since we cannot drop the pkey before db_change_field(), after
2354
    // db_change_field() we may or may not still have a pkey.  The
2355
    // simple way out is to re-create the pkey only when using pgsql.
2356
    // Realistic requirements trump idealistic purity.
23570
    db_change_field($ret, 'node_comment_statistics', 'nid', 'nid',
array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' =>
0));
23580
    if ($GLOBALS['db_type'] == 'pgsql') {
23590
      db_add_primary_key($ret, 'node_comment_statistics', array('nid'));
23600
    }
23610
  }
23620
  return $ret;
23630
}
2364
2365
/**
2366
 * Rename permission "administer access control" to "administer
permissions".
2367
 */
236812
function system_update_6034() {
23690
  $ret = array();
23700
  $result = db_query("SELECT rid, perm FROM {permission} ORDER BY rid");
23710
  while ($role = db_fetch_object($result)) {
23720
    $renamed_permission = preg_replace('/administer access control/',
'administer permissions', $role->perm);
23730
    if ($renamed_permission != $role->perm) {
23740
      $ret[] = update_sql("UPDATE {permission} SET perm =
'$renamed_permission' WHERE rid = $role->rid");
23750
    }
23760
  }
23770
  return $ret;
23780
}
2379
2380
/**
2381
 * Change index on system table for better performance.
2382
 */
238312
function system_update_6035() {
23840
  $ret = array();
23850
  db_drop_index($ret, 'system', 'weight');
23860
  db_add_index($ret, 'system', 'modules', array(array('type', 12),
'status', 'weight', 'filename'));
23870
  db_add_index($ret, 'system', 'bootstrap', array(array('type', 12),
'status', 'bootstrap', 'weight', 'filename'));
23880
  return $ret;
23890
}
2390
2391
/**
2392
 * Change the search schema and indexing.
2393
 *
2394
 * The table data is preserved where possible in MYSQL and MYSQLi using
2395
 * ALTER IGNORE. Other databases don't support that, so for them the
2396
 * tables are dropped and re-created, and will need to be re-indexed
2397
 * from scratch.
2398
 */
239912
function system_update_6036() {
24000
  $ret = array();
24010
  if (db_table_exists('search_index')) {
2402
    // Create the search_dataset.reindex column.
24030
    db_add_field($ret, 'search_dataset', 'reindex', array('type' => 'int',
'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
2404
2405
    // Drop the search_index.from fields which are no longer used.
24060
    db_drop_index($ret, 'search_index', 'from_sid_type');
24070
    db_drop_field($ret, 'search_index', 'fromsid');
24080
    db_drop_field($ret, 'search_index', 'fromtype');
2409
2410
    // Drop the search_dataset.sid_type index, so that it can be made
unique.
24110
    db_drop_index($ret, 'search_dataset', 'sid_type');
2412
2413
    // Create the search_node_links Table.
2414
    $search_node_links_schema = array(
2415
      'fields' => array(
24160
        'sid'      => array('type' => 'int', 'unsigned' => TRUE, 'not null'
=> TRUE, 'default' => 0),
24170
        'type'     => array('type' => 'varchar', 'length' => 16, 'not null'
=> TRUE, 'default' => ''),
24180
        'nid'      => array('type' => 'int', 'unsigned' => TRUE, 'not null'
=> TRUE, 'default' => 0),
24190
        'caption'    => array('type' => 'text', 'size' => 'big', 'not null'
=> FALSE),
24200
      ),
24210
      'primary key' => array('sid', 'type', 'nid'),
24220
      'indexes' => array('nid' => array('nid')),
24230
    );
24240
    db_create_table($ret, 'search_node_links', $search_node_links_schema);
2425
2426
    // with the change to search_dataset.reindex, the search queue is
handled differently,
2427
    // and this is no longer needed
24280
    variable_del('node_cron_last');
2429
2430
    // Add a unique index for the search_index.
24310
    if ($GLOBALS['db_type'] == 'mysql' || $GLOBALS['db_type'] == 'mysqli')
{
2432
      // Since it's possible that some existing sites have duplicates,
2433
      // create the index using the IGNORE keyword, which ignores duplicate
errors.
2434
      // However, pgsql doesn't support it
24350
      $ret[] = update_sql("ALTER IGNORE TABLE {search_index} ADD UNIQUE KEY
word_sid_type (word, sid, type)");
24360
      $ret[] = update_sql("ALTER IGNORE TABLE {search_dataset} ADD UNIQUE
KEY sid_type (sid, type)");
2437
2438
      // Everything needs to be reindexed.
24390
      $ret[] = update_sql("UPDATE {search_dataset} SET reindex = 1");
24400
    }
2441
    else {
2442
      // Delete the existing tables if there are duplicate values
24430
      if (db_result(db_query("SELECT sid FROM {search_dataset} GROUP BY
sid, type HAVING COUNT(*) > 1")) || db_result(db_query("SELECT sid FROM
{search_index} GROUP BY word, sid, type HAVING COUNT(*) > 1"))) {
24440
        $ret[] = update_sql('DELETE FROM {search_dataset}');
24450
        $ret[] = update_sql('DELETE FROM {search_index}');
24460
        $ret[] = update_sql('DELETE FROM {search_total}');
24470
      }
2448
      else {
2449
        // Everything needs to be reindexed.
24500
        $ret[] = update_sql("UPDATE {search_dataset} SET reindex = 1");
2451
      }
2452
2453
      // create the new indexes
24540
      db_add_unique_key($ret, 'search_index', 'word_sid_type',
array('word', 'sid', 'type'));
24550
      db_add_unique_key($ret, 'search_dataset', 'sid_type', array('sid',
'type'));
2456
    }
24570
  }
24580
  return $ret;
24590
}
2460
2461
/**
2462
 * Create consistent empty region for disabled blocks.
2463
 */
246412
function system_update_6037() {
24650
  $ret = array();
24660
  db_change_field($ret, 'blocks', 'region', 'region', array('type' =>
'varchar', 'length' => 64, 'not null' => TRUE, 'default' => ''));
24670
  $ret[] = update_sql("UPDATE {blocks} SET region = '' WHERE status = 0");
24680
  return $ret;
24690
}
2470
2471
/**
2472
 * Ensure that "Account" is not used as a Profile category.
2473
 */
247412
function system_update_6038() {
24750
  $ret = array();
24760
  if (db_table_exists('profile_fields')) {
24770
    $ret[] = update_sql("UPDATE {profile_fields} SET category = 'Account
settings' WHERE LOWER(category) = 'account'");
24780
    if ($affectedrows = db_affected_rows()) {
24790
      drupal_set_message('There were ' . $affectedrows . ' profile fields
that used a reserved category name. They have been assigned to the category
"Account settings".');
24800
    }
24810
  }
24820
  return $ret;
24830
}
2484
2485
/**
2486
 * Rename permissions "edit foo content" to "edit any foo content".
2487
 * Also update poll module permission "create polls" to "create
2488
 * poll content".
2489
 */
249012
function system_update_6039() {
24910
  $ret = array();
24920
  $result = db_query("SELECT rid, perm FROM {permission} ORDER BY rid");
24930
  while ($role = db_fetch_object($result)) {
24940
    $renamed_permission = preg_replace('/(?<=^|,\ )edit\ ([a-zA-Z0-9_\-]+)\
content(?=,|$)/', 'edit any $1 content', $role->perm);
24950
    $renamed_permission = preg_replace('/(?<=^|,\ )create\ polls(?=,|$)/',
'create poll content', $renamed_permission);
24960
    if ($renamed_permission != $role->perm) {
24970
      $ret[] = update_sql("UPDATE {permission} SET perm =
'$renamed_permission' WHERE rid = $role->rid");
24980
    }
24990
  }
25000
  return $ret;
25010
}
2502
2503
/**
2504
 * Add a weight column to the upload table.
2505
 */
250612
function system_update_6040() {
25070
  $ret = array();
25080
  if (db_table_exists('upload')) {
25090
    db_add_field($ret, 'upload', 'weight', array('type' => 'int', 'not
null' => TRUE, 'default' => 0, 'size' => 'tiny'));
25100
  }
25110
  return $ret;
25120
}
2513
2514
/**
2515
 * Change forum vocabulary not to be required by default and set the weight
of the forum.module 1 higher than the taxonomy.module.
2516
 */
251712
function system_update_6041() {
25180
  $weight = intval((db_result(db_query("SELECT weight FROM {system} WHERE
name = 'taxonomy'"))) + 1);
25190
  $ret = array();
25200
  $vid = intval(variable_get('forum_nav_vocabulary', ''));
25210
  if (db_table_exists('vocabulary') && $vid) {
25220
    $ret[] = update_sql("UPDATE {vocabulary} SET required = 0 WHERE vid = "
. $vid);
25230
    $ret[] = update_sql("UPDATE {system} SET weight = " . $weight . " WHERE
name = 'forum'");
25240
  }
25250
  return $ret;
25260
}
2527
2528
/**
2529
 * Upgrade recolored theme stylesheets to new array structure.
2530
 */
253112
function system_update_6042() {
25320
  foreach (list_themes() as $theme) {
25330
    $stylesheet = variable_get('color_' . $theme->name . '_stylesheet',
NULL);
25340
    if (!empty($stylesheet)) {
25350
      variable_set('color_' . $theme->name . '_stylesheets',
array($stylesheet));
25360
      variable_del('color_' . $theme->name . '_stylesheet');
25370
    }
25380
  }
25390
  return array();
25400
}
2541
2542
/**
2543
 * Update table indices to make them more rational and useful.
2544
 */
254512
function system_update_6043() {
25460
  $ret = array();
2547
  // Required modules first.
2548
  // Add new system module indexes.
25490
  db_add_index($ret, 'flood', 'allow', array('event', 'hostname',
'timestamp'));
25500
  db_add_index($ret, 'history', 'nid', array('nid'));
2551
  // Change length of theme field in {blocks} to be consistent with module,
and
2552
  // to avoid a MySQL error regarding a too-long index.  Also add new
indices.
25530
  db_change_field($ret, 'blocks', 'theme', 'theme', array('type' =>
'varchar', 'length' => 64, 'not null' => TRUE, 'default' => ''),array(
25540
                  'unique keys' => array('tmd' => array('theme', 'module',
'delta'),),
25550
                  'indexes' => array('list' => array('theme', 'status',
'region', 'weight', 'module'),),));
25560
  db_add_index($ret, 'blocks_roles', 'rid', array('rid'));
2557
  // Improve filter module indices.
25580
  db_drop_index($ret, 'filters', 'weight');
25590
  db_add_unique_key($ret, 'filters', 'fmd', array('format', 'module',
'delta'));
25600
  db_add_index($ret, 'filters', 'list', array('format', 'weight', 'module',
'delta'));
2561
  // Drop unneeded keys form the node table.
25620
  db_drop_index($ret, 'node', 'status');
25630
  db_drop_unique_key($ret, 'node', 'nid_vid');
2564
  // Improve user module indices.
25650
  db_add_index($ret, 'users', 'mail', array('mail'));
25660
  db_add_index($ret, 'users_roles', 'rid', array('rid'));
2567
2568
  // Optional modules - need to check if the tables exist.
2569
  // Alter aggregator module's tables primary keys to make them more
useful.
25700
  if (db_table_exists('aggregator_category_feed')) {
25710
    db_drop_primary_key($ret, 'aggregator_category_feed');
25720
    db_add_primary_key($ret, 'aggregator_category_feed', array('cid',
'fid'));
25730
    db_add_index($ret, 'aggregator_category_feed', 'fid', array('fid'));
25740
  }
25750
  if (db_table_exists('aggregator_category_item')) {
25760
    db_drop_primary_key($ret, 'aggregator_category_item');
25770
    db_add_primary_key($ret, 'aggregator_category_item', array('cid',
'iid'));
25780
    db_add_index($ret, 'aggregator_category_item', 'iid', array('iid'));
25790
  }
2580
  // Alter contact module's table to add an index.
25810
  if (db_table_exists('contact')) {
25820
    db_add_index($ret, 'contact', 'list', array('weight', 'category'));
25830
  }
2584
  // Alter locale table to add a primary key, drop an index.
25850
  if (db_table_exists('locales_target')) {
25860
    db_add_primary_key($ret, 'locales_target', array('language', 'lid',
'plural'));
25870
  }
2588
  // Alter a poll module table to add a primary key.
25890
  if (db_table_exists('poll_votes')) {
25900
    db_drop_index($ret, 'poll_votes', 'nid');
25910
    db_add_primary_key($ret, 'poll_votes', array('nid', 'uid',
'hostname'));
25920
  }
2593
  // Alter a profile module table to add a primary key.
25940
  if (db_table_exists('profile_values')) {
25950
    db_drop_index($ret, 'profile_values', 'uid');
25960
    db_drop_index($ret, 'profile_values', 'fid');
25970
    db_change_field($ret,'profile_values' ,'fid', 'fid', array('type' =>
'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0,),
array('indexes' => array('fid' => array('fid'),)));
25980
    db_change_field($ret,'profile_values' ,'uid', 'uid', array('type' =>
'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0,));
25990
    db_add_primary_key($ret, 'profile_values', array('uid', 'fid'));
26000
  }
2601
  // Alter a statistics module table to add an index.
26020
  if (db_table_exists('accesslog')) {
26030
    db_add_index($ret, 'accesslog', 'uid', array('uid'));
26040
  }
2605
  // Alter taxonomy module's tables.
26060
  if (db_table_exists('term_data')) {
26070
    db_drop_index($ret, 'term_data', 'vid');
26080
    db_add_index($ret, 'term_data', 'vid_name', array('vid', 'name'));
26090
    db_add_index($ret, 'term_data', 'taxonomy_tree', array('vid', 'weight',
'name'));
26100
  }
26110
  if (db_table_exists('term_node')) {
26120
    db_drop_primary_key($ret, 'term_node');
26130
    db_drop_index($ret, 'term_node', 'tid');
26140
    db_add_primary_key($ret, 'term_node', array('tid', 'vid'));
26150
  }
26160
  if (db_table_exists('term_relation')) {
26170
    db_drop_index($ret, 'term_relation', 'tid1');
26180
    db_add_unique_key($ret, 'term_relation', 'tid1_tid2', array('tid1',
'tid2'));
26190
  }
26200
  if (db_table_exists('term_synonym')) {
26210
    db_drop_index($ret, 'term_synonym', 'name');
26220
    db_add_index($ret, 'term_synonym', 'name_tid', array('name', 'tid'));
26230
  }
26240
  if (db_table_exists('vocabulary')) {
26250
    db_add_index($ret, 'vocabulary', 'list', array('weight', 'name'));
26260
  }
26270
  if (db_table_exists('vocabulary_node_types')) {
26280
    db_drop_primary_key($ret, 'vocabulary_node_types');
26290
    db_add_primary_key($ret, 'vocabulary_node_types', array('type',
'vid'));
26300
    db_add_index($ret, 'vocabulary_node_types', 'vid', array('vid'));
26310
  }
2632
  // If we updated in RC1 or before ensure we don't update twice.
26330
  variable_set('system_update_6043_RC2', TRUE);
2634
26350
  return $ret;
26360
}
2637
2638
/**
2639
 * RC1 to RC2 index cleanup.
2640
 */
264112
function system_update_6044() {
26420
  $ret = array();
2643
2644
  // Delete invalid entries in {term_node} after system_update_6001.
26450
  $ret[] = update_sql("DELETE FROM {term_node} WHERE vid = 0");
2646
2647
  // Only execute the rest of this function if 6043 was run in RC1 or
before.
26480
  if (variable_get('system_update_6043_RC2', FALSE)) {
26490
    variable_del('system_update_6043_RC2');
26500
    return $ret;
26510
  }
2652
2653
  // User module indices.
26540
  db_drop_unique_key($ret, 'users', 'mail');
26550
  db_add_index($ret, 'users', 'mail', array('mail'));
2656
2657
  // Optional modules - need to check if the tables exist.
2658
  // Alter taxonomy module's tables.
26590
  if (db_table_exists('term_data')) {
26600
    db_drop_unique_key($ret, 'term_data', 'vid_name');
26610
    db_add_index($ret, 'term_data', 'vid_name', array('vid', 'name'));
26620
  }
26630
  if (db_table_exists('term_synonym')) {
26640
    db_drop_unique_key($ret, 'term_synonym', 'name_tid', array('name',
'tid'));
26650
    db_add_index($ret, 'term_synonym', 'name_tid', array('name', 'tid'));
26660
  }
2667
26680
  return $ret;
26690
}
2670
2671
/**
2672
 * Update blog, book and locale module permissions.
2673
 *
2674
 * Blog module got "edit own blog" replaced with the more granular "create
2675
 * blog entries", "edit own blog entries" and "delete own blog entries"
2676
 * permissions. We grant create and edit to previously privileged users,
but
2677
 * delete is not granted to be in line with other permission changes in
Drupal 6.
2678
 *
2679
 * Book module's "edit book pages" was upgraded to the bogus "edit book
content"
2680
 * in Drupal 6 RC1 instead of "edit any book content", which would be
correct.
2681
 *
2682
 * Locale module introduced "administer languages" and "translate
interface"
2683
 * in place of "administer locales".
2684
 *
2685
 * Modeled after system_update_6039().
2686
 */
268712
function system_update_6045() {
26880
  $ret = array();
26890
  $result = db_query("SELECT rid, perm FROM {permission} ORDER BY rid");
26900
  while ($role = db_fetch_object($result)) {
26910
    $renamed_permission = preg_replace('/(?<=^|,\ )edit\ own\
blog(?=,|$)/', 'create blog entries, edit own blog entries', $role->perm);
26920
    $renamed_permission = preg_replace('/(?<=^|,\ )edit\ book\
content(?=,|$)/', 'edit any book content', $renamed_permission);
26930
    $renamed_permission = preg_replace('/(?<=^|,\ )administer\
locales(?=,|$)/', 'administer languages, translate interface',
$renamed_permission);
26940
    if ($renamed_permission != $role->perm) {
26950
      $ret[] = update_sql("UPDATE {permission} SET perm =
'$renamed_permission' WHERE rid = $role->rid");
26960
    }
26970
  }
2698
2699
  // Notify user that delete permissions may have been changed. This was in
2700
  // effect since system_update_6039(), but there was no user notice.
27010
  drupal_set_message('Drupal now has separate edit and delete permissions.
Previously, users who were able to edit content were automatically allowed
to delete it. For added security, delete permissions for individual core
content types have been <strong>removed</strong> from all roles on your
site (only roles with the "administer nodes" permission can now delete
these types of content). If you would like to reenable any individual
delete permissions, you can do this at the <a href="' .
url('admin/user/permissions', array('fragment' => 'module-node')) .
'">permissions page</a>.');
27020
  return $ret;
27030
}
2704
2705
/**
2706
 * Ensure that the file_directory_path variable is set (using the old 5.x
2707
 * default, if necessary), so that the changed 6.x default won't break
2708
 * existing sites.
2709
 */
271012
function system_update_6046() {
27110
  $ret = array();
27120
  if (!variable_get('file_directory_path', FALSE)) {
27130
    variable_set('file_directory_path', 'files');
27140
    $ret[] = array('success' => TRUE, 'query' =>
"variable_set('file_directory_path')");
27150
  }
27160
  return $ret;
27170
}
2718
2719
/**
2720
 * Fix cache mode for blocks inserted in system_install() in fresh installs
of previous RC.
2721
 */
272212
function system_update_6047() {
27230
  $ret = array();
27240
  $ret[] = update_sql("UPDATE {blocks} SET cache = -1 WHERE module = 'user'
AND delta IN ('0', '1')");
27250
  $ret[] = update_sql("UPDATE {blocks} SET cache = -1 WHERE module =
'system' AND delta = '0'");
27260
  return $ret;
27270
}
2728
2729
/**
2730
 * @} End of "defgroup updates-5.x-to-6.x"
2731
 * The next series of updates should start at 7000.
2732
 */
2733
2734
/**
2735
 * @defgroup updates-6.x-to-7.x System updates from 6.x to 7.x
2736
 * @{
2737
 */
2738
2739
/**
2740
 * Rename blog and forum permissions to be consistent with other content
types.
2741
 */
274212
function system_update_7000() {
27430
  $ret = array();
27440
  $result = db_query("SELECT rid, perm FROM {permission} ORDER BY rid");
27450
  while ($role = db_fetch_object($result)) {
27460
    $renamed_permission = preg_replace('/(?<=^|,\ )create\ blog\
entries(?=,|$)/', 'create blog content', $role->perm);
27470
    $renamed_permission = preg_replace('/(?<=^|,\ )edit\ own\ blog\
entries(?=,|$)/', 'edit own blog content', $role->perm);
27480
    $renamed_permission = preg_replace('/(?<=^|,\ )edit\ any\ blog\
entry(?=,|$)/', 'edit any blog content', $role->perm);
27490
    $renamed_permission = preg_replace('/(?<=^|,\ )delete\ own\ blog\
entries(?=,|$)/', 'delete own blog content', $role->perm);
27500
    $renamed_permission = preg_replace('/(?<=^|,\ )delete\ any\ blog\
entry(?=,|$)/', 'delete any blog content', $role->perm);
2751
27520
    $renamed_permission = preg_replace('/(?<=^|,\ )create\ forum\
topics(?=,|$)/', 'create forum content', $role->perm);
27530
    $renamed_permission = preg_replace('/(?<=^|,\ )delete\ any\ forum\
topic(?=,|$)/', 'delete any forum content', $role->perm);
27540
    $renamed_permission = preg_replace('/(?<=^|,\ )delete\ own\ forum\
topics(?=,|$)/', 'delete own forum content', $role->perm);
27550
    $renamed_permission = preg_replace('/(?<=^|,\ )edit\ any\ forum\
topic(?=,|$)/', 'edit any forum content', $role->perm);
27560
    $renamed_permission = preg_replace('/(?<=^|,\ )edit\ own\ forum\
topics(?=,|$)/', 'edit own forum content', $role->perm);
2757
27580
    if ($renamed_permission != $role->perm) {
27590
      $ret[] = update_sql("UPDATE {permission} SET perm =
'$renamed_permission' WHERE rid = $role->rid");
27600
    }
27610
  }
2762
27630
  return $ret;
27640
}
2765
2766
/**
2767
 * Generate a cron key and save it in the variables table.
2768
 */
276912
function system_update_7001() {
27700
  $ret = array();
27710
  variable_set('cron_key', md5(mt_rand()));
27720
  $ret[] = array('success' => TRUE, 'query' => "variable_set('cron_key')");
27730
  return $ret;
27740
}
2775
2776
/**
2777
 * Add a table to store blocked IP addresses.
2778
 */
277912
function system_update_7002() {
27800
  $ret = array();
27810
  $schema['blocked_ips'] = array(
27820
    'description' => t('Stores blocked IP addresses.'),
2783
    'fields' => array(
2784
      'iid' => array(
27850
        'description' => t('Primary Key: unique ID for IP addresses.'),
27860
        'type' => 'serial',
27870
        'unsigned' => TRUE,
27880
        'not null' => TRUE,
27890
      ),
2790
      'ip' => array(
27910
        'description' => t('IP address'),
27920
        'type' => 'varchar',
27930
        'length' => 32,
27940
        'not null' => TRUE,
27950
        'default' => '',
27960
      ),
27970
    ),
2798
    'indexes' => array(
27990
      'blocked_ip' => array('ip'),
28000
    ),
28010
    'primary key' => array('iid'),
2802
  );
2803
28040
  db_create_table($ret, 'blocked_ips', $schema['blocked_ips']);
2805
28060
  return $ret;
28070
}
2808
2809
/**
2810
 * Update {blocked_ips} with valid IP addresses from {access}.
2811
 */
281212
function system_update_7003() {
28130
  $ret = array();
28140
  $type = 'host';
28150
  $result = db_query("SELECT mask FROM {access} WHERE status = %d AND TYPE
= '%s'", 0, $type);
28160
  while ($blocked = db_fetch_object($result)) {
28170
    if (filter_var($blocked->mask, FILTER_VALIDATE_IP,
FILTER_FLAG_NO_RES_RANGE) !== FALSE) {
28180
      $ret[] = update_sql("INSERT INTO {blocked_ips} (ip) VALUES
('$blocked->mask')");
28190
    }
2820
    else {
28210
      $invalid_host = check_plain($blocked->mask);
28220
      $ret[] = array('success' => TRUE, 'query' => 'The host ' .
$invalid_host . ' is no longer blocked because it is not a valid IP
address.');
2823
    }
28240
  }
28250
  if (isset($invalid_host)) {
28260
    drupal_set_message('Drupal no longer supports wildcard IP address
blocking. Visitors whose IP addresses match ranges you have previously set
using <em>access rules</em> will no longer be blocked from your site when
you take it out of maintenance mode. See the <a
href="http://drupal.org/node/24302">IP address and referrer blocking
Handbook page</a> for alternative methods.', 'warning');
28270
    $ret[] = array('success' => TRUE, 'query' => '');
28280
  }
2829
  // Make sure not to block any IP addresses that were specifically allowed
by access rules.
28300
  if (!empty($result)) {
28310
    $result = db_query("SELECT mask FROM {access} WHERE status = %d AND
type = '%s'", 1, $type);
28320
    while ($allowed = db_fetch_object($result)) {
28330
      $ret[] = update_sql("DELETE FROM {blocked_ips} WHERE LOWER(ip) LIKE
LOWER('$allowed->mask')");
28340
    }
28350
  }
2836
28370
  return $ret;
28380
}
2839
2840
/**
2841
 * Remove hardcoded numeric deltas from all blocks in core.
2842
 */
284312
function system_update_7004(&$sandbox) {
28440
  $ret = array();
2845
  // Get an array of the renamed block deltas, organized by module.
2846
  $renamed_deltas = array(
28470
    'blog' => array('0' => 'recent'),
28480
    'book' => array('0' => 'navigation'),
28490
    'comment' => array('0' => 'recent'),
2850
    'forum' => array(
28510
      '0' => 'active',
28520
      '1' => 'new',
28530
    ),
28540
    'locale' => array('0' => 'language-switcher'),
28550
    'node' => array('0' => 'syndicate'),
28560
    'poll' => array('0' => 'recent'),
28570
    'profile' => array('0' => 'author-information'),
28580
    'search' => array('0' => 'form'),
28590
    'statistics' => array('0' => 'popular'),
28600
    'system' => array('0' => 'powered-by'),
2861
    'user' => array(
28620
      '0' => 'login',
28630
      '1' => 'navigation',
28640
      '2' => 'new',
28650
      '3' => 'online',
28660
    ),
28670
  );
2868
  // Loop through each block and make changes to the core block tables.
2869
  // Only run this the first time through the batch update.
28700
  if (!isset($sandbox['progress'])) {
28710
    $block_tables = array('blocks', 'blocks_roles');
28720
    foreach ($block_tables as $table) {
28730
      foreach ($renamed_deltas as $module => $deltas) {
28740
        foreach ($deltas as $old_delta => $new_delta) {
2875
          // Only do the update if the old block actually exists.
28760
          if (db_result(db_query("SELECT COUNT(*) FROM {" . $table . "}
WHERE module = '%s' AND delta = '%s'", $module, $old_delta))) {
28770
            $ret[] = update_sql("UPDATE {" . $table . "} SET delta = '" .
$new_delta . "' WHERE module = '" . $module . "' AND delta = '" .
$old_delta . "'");
28780
          }
28790
        }
28800
      }
28810
    }
2882
    // Rename forum module's block variables.
28830
    $forum_block_num_0 = variable_get('forum_block_num_0', NULL);
28840
    if (isset($forum_block_num_0)) {
28850
      variable_set('forum_block_num_active', $forum_block_num_0);
28860
      variable_del('forum_block_num_0');
28870
    }
28880
    $forum_block_num_1 = variable_get('forum_block_num_1', NULL);
28890
    if (isset($forum_block_num_1)) {
28900
      variable_set('forum_block_num_new', $forum_block_num_1);
28910
      variable_del('forum_block_num_1');
28920
    }
2893
    // Initialize batch update information.
28940
    $sandbox['progress'] = 0;
28950
    $sandbox['last_user_processed'] = -1;
28960
    $sandbox['max'] = db_result(db_query("SELECT COUNT(*) FROM {users}
WHERE data IS NOT NULL"));
28970
  }
2898
  // Now do the batch update of the user-specific block visibility
settings.
28990
  $limit = 100;
29000
  $result = db_query_range("SELECT uid, data FROM {users} WHERE uid > %d
AND data IS NOT NULL", $sandbox['last_user_processed'], 0, $limit);
29010
  while ($row = db_fetch_object($result)) {
29020
    $data = unserialize($row->data);
29030
    $user_needs_update = FALSE;
29040
    foreach ($renamed_deltas as $module => $deltas) {
29050
      foreach ($deltas as $old_delta => $new_delta) {
29060
        if (isset($data['block'][$module][$old_delta])) {
2907
          // Transfer the old block visibility settings to the
newly-renamed
2908
          // block, and mark this user for a database update.
29090
          $data['block'][$module][$new_delta] =
$data['block'][$module][$old_delta];
29100
          unset($data['block'][$module][$old_delta]);
29110
          $user_needs_update = TRUE;
29120
        }
29130
      }
29140
    }
2915
    // Update the current user.
29160
    if ($user_needs_update) {
29170
      db_query("UPDATE {users} SET data = '%s' WHERE uid = %d",
serialize($data), $row->uid);
29180
    }
2919
    // Update our progress information for the batch update.
29200
    $sandbox['progress']++;
29210
    $sandbox['last_user_processed'] = $row->uid;
29220
  }
2923
  // Indicate our current progress to the batch update system.
29240
  if ($sandbox['progress'] < $sandbox['max']) {
29250
    $ret['#finished'] = $sandbox['progress'] / $sandbox['max'];
29260
  }
29270
  return $ret;
29280
}
2929
2930
/**
2931
 * Remove throttle columns and variables.
2932
 */
293312
function system_update_7005() {
29340
  $ret = array();
29350
  db_drop_field($ret, 'blocks', 'throttle');
29360
  db_drop_field($ret, 'system', 'throttle');
29370
  variable_del('throttle_user');
29380
  variable_del('throttle_anonymous');
29390
  variable_del('throttle_level');
29400
  variable_del('throttle_probability_limiter');
2941
29420
  return $ret;
29430
}
2944
2945
/**
2946
 * Registry tables and drop the file key of the menu router, since it is no
2947
 * longer needed.
2948
 */
294912
function system_update_7006() {
29500
  $ret = array();
29510
  db_drop_field($ret, 'menu_router', 'file');
29520
  $schema['registry'] = array(
2953
    'fields' => array(
29540
      'name'   => array('type' => 'varchar', 'length' => 255, 'not null' =>
TRUE, 'default' => ''),
29550
      'type'   => array('type' => 'varchar', 'length' => 9, 'not null' =>
TRUE, 'default' => ''),
29560
      'filename'   => array('type' => 'varchar', 'length' => 255, 'not
null' => TRUE, 'default' => ''),
29570
      'module'   => array('type' => 'varchar', 'length' => 255, 'not null'
=> TRUE, 'default' => ''),
29580
      'suffix'   => array('type' => 'varchar', 'length' => 69, 'not null'
=> TRUE, 'default' => ''),
29590
      'weight'   => array('type' => 'int', 'not null' => TRUE, 'default' =>
0),
29600
    ),
29610
    'primary key' => array('name', 'type'),
2962
    'indexes' => array(
29630
      'hook' => array('type', 'suffix', 'weight', 'module'),
29640
    ),
2965
  );
29660
  $schema['registry_file'] = array(
2967
    'fields' => array(
29680
      'filename'   => array('type' => 'varchar', 'length' => 255, 'not
null' => TRUE, 'default' => ''),
29690
      'md5'   => array('type' => 'varchar', 'length' => 32, 'not null' =>
TRUE, 'default' => ''),
29700
    ),
29710
    'primary key' => array('filename'),
2972
  );
29730
  $schema['cache_registry'] = array(
2974
    'fields' => array(
29750
      'cid'        => array('type' => 'varchar', 'length' => 255, 'not
null' => TRUE, 'default' => ''),
29760
      'data'       => array('type' => 'blob', 'not null' => FALSE, 'size'
=> 'big'),
29770
      'expire'     => array('type' => 'int', 'not null' => TRUE, 'default'
=> 0),
29780
      'created'    => array('type' => 'int', 'not null' => TRUE, 'default'
=> 0),
29790
      'headers'    => array('type' => 'text', 'not null' => FALSE),
29800
      'serialized' => array('type' => 'int', 'size' => 'small', 'not null'
=> TRUE, 'default' => 0)
29810
    ),
29820
    'indexes' => array('expire' => array('expire')),
29830
    'primary key' => array('cid'),
2984
  );
29850
  db_create_table($ret, 'cache_registry', $schema['cache_registry']);
29860
  db_create_table($ret, 'registry', $schema['registry']);
29870
  db_create_table($ret, 'registry_file', $schema['registry_file']);
29880
  registry_rebuild();
29890
  return $ret;
29900
}
2991
2992
/**
2993
 * Convert to new method of storing permissions.
2994
 *
2995
 * This update is in system.install rather than user.install so that
2996
 * all modules can use the updated permission scheme during their updates.
2997
 */
299812
function system_update_7007() {
29990
  $ret = array();
3000
30010
  $schema['role_permission'] = array(
3002
    'fields' => array(
3003
      'rid' => array(
30040
        'type' => 'int',
30050
        'unsigned' => TRUE,
30060
        'not null' => TRUE,
30070
      ),
3008
      'permission' => array(
30090
        'type' => 'varchar',
30100
        'length' => 64,
30110
        'not null' => TRUE,
30120
        'default' => '',
30130
      ),
30140
    ),
30150
    'primary key' => array('rid', 'permission'),
3016
    'indexes' => array(
30170
      'permission' => array('permission'),
30180
    ),
3019
  );
3020
30210
  db_create_table($ret, 'role_permission', $schema['role_permission']);
3022
3023
  // Copy the permissions from the old {permission} table to the new
{role_permission} table.
30240
  $result = db_query("SELECT rid, perm FROM {permission} ORDER BY rid
ASC");
30250
  while ($role = db_fetch_object($result)) {
30260
    foreach (explode(', ', $role->perm) as $perm) {
30270
      db_query("INSERT INTO {role_permission} (rid, permission) VALUES (%d,
'%s')", $role->rid, $perm);
30280
    }
30290
    $ret[] = array('success' => TRUE, 'query' => "Inserted into
{role_permission} the permissions for role ID " . $role->rid);
30300
  }
30310
  db_drop_table($ret, 'permission');
3032
30330
  return $ret;
30340
}
3035
3036
3037
/**
3038
 * Use the poll_choice primary key to record votes in poll_votes rather
than
3039
 * the choice order. Rename chorder to weight.
3040
 */
304112
function system_update_7008() {
30420
  $ret = array();
30430
  if (db_table_exists('poll_votes')) {
3044
    // Add chid column and convert existing votes.
30450
    db_add_field($ret, 'poll_votes', 'chid', array('type' => 'int',
'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
30460
    db_add_index($ret, 'poll_votes', 'chid', array('chid'));
30470
    $ret[] = update_sql("UPDATE {poll_votes} v SET chid = (SELECT chid FROM
{poll_choices} c WHERE v.chorder = c.chorder AND v.nid = c.nid)");
3048
    // Remove old chorder column.
30490
    db_drop_field($ret, 'poll_votes', 'chorder');
30500
  }
30510
  if (db_table_exists('poll_choices')) {
3052
    // Change the chorder column to weight in poll_choices.
30530
    db_change_field($ret, 'poll_choices', 'chorder', 'weight', array('type'
=> 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'tiny'));
30540
  }
30550
  return $ret;
30560
}
3057
3058
/**
3059
 * Rename the variables for primary and secondary links.
3060
 *
3061
 */
306212
function system_update_7009() {
30630
  $ret = array();
30640
  $ret[] = update_sql("UPDATE {variable} SET name =
'menu_main_links_source' WHERE name = 'menu_primary_links_source'");
3065
30660
  return $ret;
30670
}
3068
3069
/**
3070
 * Increase the size of the 'load_functions' and 'to_arg_functions' fields
in table 'menu_router'.
3071
 */
307212
function system_update_7010() {
30730
  $ret = array();
30740
  db_change_field($ret, 'menu_router', 'load_functions', 'load_functions',
array('type' => 'text', 'not null' => TRUE, 'default' => ''));
30750
  db_change_field($ret, 'menu_router', 'to_arg_functions',
'to_arg_functions', array('type' => 'text', 'not null' => TRUE, 'default'
=> '',));
3076
30770
  return $ret;
30780
}
3079
3080
/**
3081
 * Split the 'bypass node access' permission from 'administer nodes'.
3082
 */
308312
function system_update_7011() {
30840
  $ret = array();
3085
  // Get existing roles that can 'administer nodes'.
30860
  $rids = array();
30870
  $rids = db_query("SELECT rid FROM {role_permission} WHERE permission =
:perm", array(':perm' => 'administer nodes'))->fetchCol();
3088
  // None found.
30890
  if (empty($rids)) {
30900
    return $ret;
30910
  }
30920
  $insert = db_insert('role_permission')->fields(array('rid',
'permission'));
30930
  foreach ($rids as $rid) {
30940
    $insert->values(array(
30950
    'rid' => $rid,
30960
    'permission' => 'bypass node access',
30970
    ));
30980
  }
30990
  $insert->execute();  
31000
  return $ret;
31010
}
3102
3103
/**
3104
 * @} End of "defgroup updates-6.x-to-7.x"
3105
 * The next series of updates should start at 8000.
3106
 */
3107
310812