? update.inc.patch
? update.sh
? includes/update.inc
Index: update.php
===================================================================
RCS file: /cvs/drupal/drupal/update.php,v
retrieving revision 1.279
diff -u -u -p -r1.279 update.php
--- update.php 9 Mar 2009 20:58:19 -0000 1.279
+++ update.php 24 Mar 2009 20:16:56 -0000
@@ -26,173 +26,6 @@ define('DRUPAL_ROOT', getcwd());
*/
define('MAINTENANCE_MODE', 'update');
-/**
- * Add a column to a database using syntax appropriate for PostgreSQL.
- * Save result of SQL commands in $ret array.
- *
- * Note: when you add a column with NOT NULL and you are not sure if there are
- * already rows in the table, you MUST also add DEFAULT. Otherwise PostgreSQL
- * won't work when the table is not empty, and db_add_column() will fail.
- * To have an empty string as the default, you must use: 'default' => "''"
- * in the $attributes array. If NOT NULL and DEFAULT are set the PostgreSQL
- * version will set values of the added column in old rows to the
- * DEFAULT value.
- *
- * @param $ret
- * Array to which results will be added.
- * @param $table
- * Name of the table, without {}
- * @param $column
- * Name of the column
- * @param $type
- * Type of column
- * @param $attributes
- * Additional optional attributes. Recognized attributes:
- * not null => TRUE|FALSE
- * default => NULL|FALSE|value (the value must be enclosed in '' marks)
- * @return
- * nothing, but modifies $ret parameter.
- */
-function db_add_column(&$ret, $table, $column, $type, $attributes = array()) {
- if (array_key_exists('not null', $attributes) and $attributes['not null']) {
- $not_null = 'NOT NULL';
- }
- if (array_key_exists('default', $attributes)) {
- if (is_null($attributes['default'])) {
- $default_val = 'NULL';
- $default = 'default NULL';
- }
- elseif ($attributes['default'] === FALSE) {
- $default = '';
- }
- else {
- $default_val = "$attributes[default]";
- $default = "default $attributes[default]";
- }
- }
-
- $ret[] = update_sql("ALTER TABLE {" . $table . "} ADD $column $type");
- if (!empty($default)) {
- $ret[] = update_sql("ALTER TABLE {" . $table . "} ALTER $column SET $default");
- }
- if (!empty($not_null)) {
- if (!empty($default)) {
- $ret[] = update_sql("UPDATE {" . $table . "} SET $column = $default_val");
- }
- $ret[] = update_sql("ALTER TABLE {" . $table . "} ALTER $column SET NOT NULL");
- }
-}
-
-/**
- * Change a column definition using syntax appropriate for PostgreSQL.
- * Save result of SQL commands in $ret array.
- *
- * Remember that changing a column definition involves adding a new column
- * and dropping an old one. This means that any indices, primary keys and
- * sequences from serial-type columns are dropped and might need to be
- * recreated.
- *
- * @param $ret
- * Array to which results will be added.
- * @param $table
- * Name of the table, without {}
- * @param $column
- * Name of the column to change
- * @param $column_new
- * New name for the column (set to the same as $column if you don't want to change the name)
- * @param $type
- * Type of column
- * @param $attributes
- * Additional optional attributes. Recognized attributes:
- * not null => TRUE|FALSE
- * default => NULL|FALSE|value (with or without '', it won't be added)
- * @return
- * nothing, but modifies $ret parameter.
- */
-function db_change_column(&$ret, $table, $column, $column_new, $type, $attributes = array()) {
- if (array_key_exists('not null', $attributes) and $attributes['not null']) {
- $not_null = 'NOT NULL';
- }
- if (array_key_exists('default', $attributes)) {
- if (is_null($attributes['default'])) {
- $default_val = 'NULL';
- $default = 'default NULL';
- }
- elseif ($attributes['default'] === FALSE) {
- $default = '';
- }
- else {
- $default_val = "$attributes[default]";
- $default = "default $attributes[default]";
- }
- }
-
- $ret[] = update_sql("ALTER TABLE {" . $table . "} RENAME $column TO " . $column . "_old");
- $ret[] = update_sql("ALTER TABLE {" . $table . "} ADD $column_new $type");
- $ret[] = update_sql("UPDATE {" . $table . "} SET $column_new = " . $column . "_old");
- if ($default) {
- $ret[] = update_sql("ALTER TABLE {" . $table . "} ALTER $column_new SET $default");
- }
- if ($not_null) {
- $ret[] = update_sql("ALTER TABLE {" . $table . "} ALTER $column_new SET NOT NULL");
- }
- $ret[] = update_sql("ALTER TABLE {" . $table . "} DROP " . $column . "_old");
-}
-
-/**
- * Perform one update and store the results which will later be displayed on
- * the finished page.
- *
- * An update function can force the current and all later updates for this
- * module to abort by returning a $ret array with an element like:
- * $ret['#abort'] = array('success' => FALSE, 'query' => 'What went wrong');
- * The schema version will not be updated in this case, and all the
- * aborted updates will continue to appear on update.php as updates that
- * have not yet been run.
- *
- * @param $module
- * The module whose update will be run.
- * @param $number
- * The update number to run.
- * @param $context
- * The batch context array
- */
-function update_do_one($module, $number, &$context) {
- // If updates for this module have been aborted
- // in a previous step, go no further.
- if (!empty($context['results'][$module]['#abort'])) {
- return;
- }
-
- $function = $module . '_update_' . $number;
- if (function_exists($function)) {
- $ret = $function($context['sandbox']);
- }
-
- if (isset($ret['#finished'])) {
- $context['finished'] = $ret['#finished'];
- unset($ret['#finished']);
- }
-
- if (!isset($context['results'][$module])) {
- $context['results'][$module] = array();
- }
- if (!isset($context['results'][$module][$number])) {
- $context['results'][$module][$number] = array();
- }
- $context['results'][$module][$number] = array_merge($context['results'][$module][$number], $ret);
-
- if (!empty($ret['#abort'])) {
- $context['results'][$module]['#abort'] = TRUE;
- }
- // Record the schema update if it was completed successfully.
- if ($context['finished'] == 1 && empty($context['results'][$module]['#abort'])) {
- drupal_set_installed_schema_version($module, $number);
- }
-
- $context['message'] = 'Updating ' . check_plain($module) . ' module';
-}
-
function update_selection_page() {
drupal_set_title('Drupal database update');
$output = drupal_get_form('update_script_selection_form');
@@ -445,167 +278,6 @@ function update_access_denied_page() {
}
/**
- * Create the batch table.
- *
- * This is part of the Drupal 5.x to 6.x migration.
- */
-function update_create_batch_table() {
-
- // If batch table exists, update is not necessary
- if (db_table_exists('batch')) {
- return;
- }
-
- $schema['batch'] = array(
- 'fields' => array(
- 'bid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE),
- 'token' => array('type' => 'varchar', 'length' => 64, 'not null' => TRUE),
- 'timestamp' => array('type' => 'int', 'not null' => TRUE),
- 'batch' => array('type' => 'text', 'not null' => FALSE, 'size' => 'big')
- ),
- 'primary key' => array('bid'),
- 'indexes' => array('token' => array('token')),
- );
-
- $ret = array();
- db_create_table($ret, 'batch', $schema['batch']);
- return $ret;
-}
-
-/**
- * Disable anything in the {system} table that is not compatible with the
- * current version of Drupal core.
- */
-function update_fix_compatibility() {
- $ret = array();
- $incompatible = array();
- $query = db_query("SELECT name, type, status FROM {system} WHERE status = 1 AND type IN ('module','theme')");
- while ($result = db_fetch_object($query)) {
- if (update_check_incompatibility($result->name, $result->type)) {
- $incompatible[] = $result->name;
- }
- }
- if (!empty($incompatible)) {
- $ret[] = update_sql("UPDATE {system} SET status = 0 WHERE name IN ('" . implode("','", $incompatible) . "')");
- }
- return $ret;
-}
-
-/**
- * Helper function to test compatibility of a module or theme.
- */
-function update_check_incompatibility($name, $type = 'module') {
- static $themes, $modules;
-
- // Store values of expensive functions for future use.
- if (empty($themes) || empty($modules)) {
- $themes = _system_theme_data();
- $modules = module_rebuild_cache();
- }
-
- if ($type == 'module' && isset($modules[$name])) {
- $file = $modules[$name];
- }
- elseif ($type == 'theme' && isset($themes[$name])) {
- $file = $themes[$name];
- }
- if (!isset($file)
- || !isset($file->info['core'])
- || $file->info['core'] != DRUPAL_CORE_COMPATIBILITY
- || version_compare(phpversion(), $file->info['php']) < 0
- || ($type == 'module' && empty($file->info['files']))) {
- return TRUE;
- }
- return FALSE;
-}
-
-/**
- * Perform Drupal 5.x to 6.x updates that are required for update.php
- * to function properly.
- *
- * This function runs when update.php is run the first time for 6.x,
- * even before updates are selected or performed. It is important
- * that if updates are not ultimately performed that no changes are
- * made which make it impossible to continue using the prior version.
- * Just adding columns is safe. However, renaming the
- * system.description column to owner is not. Therefore, we add the
- * system.owner column and leave it to system_update_6008() to copy
- * the data from description and remove description. The same for
- * renaming locales_target.locale to locales_target.language, which
- * will be finished by locale_update_6002().
- */
-function update_fix_d6_requirements() {
- $ret = array();
-
- if (drupal_get_installed_schema_version('system') < 6000 && !variable_get('update_d6_requirements', FALSE)) {
- $spec = array('type' => 'int', 'size' => 'small', 'default' => 0, 'not null' => TRUE);
- db_add_field($ret, 'cache', 'serialized', $spec);
- db_add_field($ret, 'cache_filter', 'serialized', $spec);
- db_add_field($ret, 'cache_page', 'serialized', $spec);
- db_add_field($ret, 'cache_menu', 'serialized', $spec);
-
- db_add_field($ret, 'system', 'info', array('type' => 'text'));
- db_add_field($ret, 'system', 'owner', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
- if (db_table_exists('locales_target')) {
- db_add_field($ret, 'locales_target', 'language', array('type' => 'varchar', 'length' => 12, 'not null' => TRUE, 'default' => ''));
- }
- if (db_table_exists('locales_source')) {
- db_add_field($ret, 'locales_source', 'textgroup', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => 'default'));
- db_add_field($ret, 'locales_source', 'version', array('type' => 'varchar', 'length' => 20, 'not null' => TRUE, 'default' => 'none'));
- }
- variable_set('update_d6_requirements', TRUE);
-
- // Create the cache_block table. See system_update_6027() for more details.
- $schema['cache_block'] = array(
- 'fields' => array(
- 'cid' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
- 'data' => array('type' => 'blob', 'not null' => FALSE, 'size' => 'big'),
- 'expire' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
- 'created' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
- 'headers' => array('type' => 'text', 'not null' => FALSE),
- 'serialized' => array('type' => 'int', 'size' => 'small', 'not null' => TRUE, 'default' => 0)
- ),
- 'indexes' => array('expire' => array('expire')),
- 'primary key' => array('cid'),
- );
- db_create_table($ret, 'cache_block', $schema['cache_block']);
- }
-
- return $ret;
-}
-
-/**
- * Users who still have a Drupal 6 database (and are in the process of
- * updating to Drupal 7) need extra help before a full bootstrap can be
- * achieved. This function does the necessary preliminary work that allows
- * the bootstrap to be successful.
- *
- * No access check has been performed when this function is called, so no
- * changes to the database should be made here.
- */
-function update_prepare_d7_bootstrap() {
- // Allow the database system to work even though the registry has not
- // been created yet.
- drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE);
- include_once DRUPAL_ROOT . '/includes/install.inc';
- drupal_install_init_database();
- spl_autoload_unregister('drupal_autoload_class');
- spl_autoload_unregister('drupal_autoload_interface');
- // The new {blocked_ips} table is used in Drupal 7 to store a list of
- // banned IP addresses. If this table doesn't exist then we are still
- // running on a Drupal 6 database, so suppress the unavoidable errors
- // that occur.
- try {
- drupal_bootstrap(DRUPAL_BOOTSTRAP_ACCESS);
- }
- catch (Exception $e) {
- if (db_table_exists('blocked_ips')) {
- throw $e;
- }
- }
-}
-
-/**
* Add the update task list to the current page.
*/
function update_task_list($active = NULL) {
@@ -620,62 +292,6 @@ function update_task_list($active = NULL
drupal_set_content('left', theme('task_list', $tasks, $active));
}
-/**
- * Check update requirements and report any errors.
- */
-function update_check_requirements() {
- global $db_url, $databases;
- $requirements = array();
-
- // If we will rewrite the settings.php then we need to make sure it is
- // writeable.
- if (empty($databases) && !empty($db_url) && is_string($db_url)) {
- $requirements = install_check_requirements('', FALSE);
- }
- $warnings = FALSE;
-
- // Check the system module requirements only.
- $requirements += module_invoke('system', 'requirements', 'update');
- $severity = drupal_requirements_severity($requirements);
-
- // If there are issues, report them.
- if ($severity != REQUIREMENT_OK) {
- foreach ($requirements as $requirement) {
- if (isset($requirement['severity']) && $requirement['severity'] != REQUIREMENT_OK) {
- $message = isset($requirement['description']) ? $requirement['description'] : '';
- if (isset($requirement['value']) && $requirement['value']) {
- $message .= ' (Currently using ' . $requirement['title'] . ' ' . $requirement['value'] . ')';
- }
- $warnings = TRUE;
- drupal_set_message($message, 'warning');
- }
- }
- }
- return $warnings;
-}
-
-/**
- * Converts Drupal 6 $db_url to Drupal 7 $databases array.
- */
-function update_check_d7_settings() {
- global $db_url, $databases;
-
- if (empty($databases) && !empty($db_url) && is_string($db_url)) {
- $url = parse_url($db_url);
- $driver = substr($db_url, 0, strpos($db_url, '://'));
- if ($driver == 'mysqli') {
- $driver = 'mysql';
- }
- $databases['default']['default']['driver'] = $driver;
- $databases['default']['default']['database'] = substr($url['path'], 1);
- foreach (array('user' => 'username', 'pass' => 'password', 'host' => 'host', 'port' => 'port') as $old_key => $new_key) {
- $databases['default']['default'][$new_key] = isset($url[$old_key]) ? urldecode($url[$old_key]) : '';
- }
- $conf_path = conf_path();
- file_put_contents($conf_path .'/settings.php', "\n" . '$databases = '. var_export($databases, TRUE) . ';', FILE_APPEND);
- }
-}
-
// Some unavoidable errors happen because the database is not yet up-to-date.
// Our custom error handler is not yet installed, so we just suppress them.
ini_set('display_errors', FALSE);
@@ -690,6 +306,7 @@ if (empty($op)) {
drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION);
require_once DRUPAL_ROOT . '/includes/install.inc';
+ require_once DRUPAL_ROOT . '/includes/update.inc';
require_once DRUPAL_ROOT . '/includes/file.inc';
require_once DRUPAL_ROOT . '/modules/system/system.install';
--- /dev/null 2009-03-23 21:07:08.553263372 -0400
+++ includes/update.inc 2009-03-24 16:07:05.000000000 -0400
@@ -0,0 +1,397 @@
+ "''"
+ * in the $attributes array. If NOT NULL and DEFAULT are set the PostgreSQL
+ * version will set values of the added column in old rows to the
+ * DEFAULT value.
+ *
+ * @param $ret
+ * Array to which results will be added.
+ * @param $table
+ * Name of the table, without {}
+ * @param $column
+ * Name of the column
+ * @param $type
+ * Type of column
+ * @param $attributes
+ * Additional optional attributes. Recognized attributes:
+ * not null => TRUE|FALSE
+ * default => NULL|FALSE|value (the value must be enclosed in '' marks)
+ * @return
+ * nothing, but modifies $ret parameter.
+ */
+function db_add_column(&$ret, $table, $column, $type, $attributes = array()) {
+ if (array_key_exists('not null', $attributes) and $attributes['not null']) {
+ $not_null = 'NOT NULL';
+ }
+ if (array_key_exists('default', $attributes)) {
+ if (is_null($attributes['default'])) {
+ $default_val = 'NULL';
+ $default = 'default NULL';
+ }
+ elseif ($attributes['default'] === FALSE) {
+ $default = '';
+ }
+ else {
+ $default_val = "$attributes[default]";
+ $default = "default $attributes[default]";
+ }
+ }
+
+ $ret[] = update_sql("ALTER TABLE {" . $table . "} ADD $column $type");
+ if (!empty($default)) {
+ $ret[] = update_sql("ALTER TABLE {" . $table . "} ALTER $column SET $default");
+ }
+ if (!empty($not_null)) {
+ if (!empty($default)) {
+ $ret[] = update_sql("UPDATE {" . $table . "} SET $column = $default_val");
+ }
+ $ret[] = update_sql("ALTER TABLE {" . $table . "} ALTER $column SET NOT NULL");
+ }
+}
+
+/**
+ * Change a column definition using syntax appropriate for PostgreSQL.
+ * Save result of SQL commands in $ret array.
+ *
+ * Remember that changing a column definition involves adding a new column
+ * and dropping an old one. This means that any indices, primary keys and
+ * sequences from serial-type columns are dropped and might need to be
+ * recreated.
+ *
+ * @param $ret
+ * Array to which results will be added.
+ * @param $table
+ * Name of the table, without {}
+ * @param $column
+ * Name of the column to change
+ * @param $column_new
+ * New name for the column (set to the same as $column if you don't want to change the name)
+ * @param $type
+ * Type of column
+ * @param $attributes
+ * Additional optional attributes. Recognized attributes:
+ * not null => TRUE|FALSE
+ * default => NULL|FALSE|value (with or without '', it won't be added)
+ * @return
+ * nothing, but modifies $ret parameter.
+ */
+function db_change_column(&$ret, $table, $column, $column_new, $type, $attributes = array()) {
+ if (array_key_exists('not null', $attributes) and $attributes['not null']) {
+ $not_null = 'NOT NULL';
+ }
+ if (array_key_exists('default', $attributes)) {
+ if (is_null($attributes['default'])) {
+ $default_val = 'NULL';
+ $default = 'default NULL';
+ }
+ elseif ($attributes['default'] === FALSE) {
+ $default = '';
+ }
+ else {
+ $default_val = "$attributes[default]";
+ $default = "default $attributes[default]";
+ }
+ }
+
+ $ret[] = update_sql("ALTER TABLE {" . $table . "} RENAME $column TO " . $column . "_old");
+ $ret[] = update_sql("ALTER TABLE {" . $table . "} ADD $column_new $type");
+ $ret[] = update_sql("UPDATE {" . $table . "} SET $column_new = " . $column . "_old");
+ if ($default) {
+ $ret[] = update_sql("ALTER TABLE {" . $table . "} ALTER $column_new SET $default");
+ }
+ if ($not_null) {
+ $ret[] = update_sql("ALTER TABLE {" . $table . "} ALTER $column_new SET NOT NULL");
+ }
+ $ret[] = update_sql("ALTER TABLE {" . $table . "} DROP " . $column . "_old");
+}
+
+/**
+ * Disable anything in the {system} table that is not compatible with the
+ * current version of Drupal core.
+ */
+function update_fix_compatibility() {
+ $ret = array();
+ $incompatible = array();
+ $query = db_query("SELECT name, type, status FROM {system} WHERE status = 1 AND type IN ('module','theme')");
+ while ($result = db_fetch_object($query)) {
+ if (update_check_incompatibility($result->name, $result->type)) {
+ $incompatible[] = $result->name;
+ }
+ }
+ if (!empty($incompatible)) {
+ $ret[] = update_sql("UPDATE {system} SET status = 0 WHERE name IN ('" . implode("','", $incompatible) . "')");
+ }
+ return $ret;
+}
+
+/**
+ * Helper function to test compatibility of a module or theme.
+ */
+function update_check_incompatibility($name, $type = 'module') {
+ static $themes, $modules;
+
+ // Store values of expensive functions for future use.
+ if (empty($themes) || empty($modules)) {
+ $themes = _system_theme_data();
+ $modules = module_rebuild_cache();
+ }
+
+ if ($type == 'module' && isset($modules[$name])) {
+ $file = $modules[$name];
+ }
+ elseif ($type == 'theme' && isset($themes[$name])) {
+ $file = $themes[$name];
+ }
+ if (!isset($file)
+ || !isset($file->info['core'])
+ || $file->info['core'] != DRUPAL_CORE_COMPATIBILITY
+ || version_compare(phpversion(), $file->info['php']) < 0
+ || ($type == 'module' && empty($file->info['files']))) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Perform Drupal 5.x to 6.x updates that are required for update.php
+ * to function properly.
+ *
+ * This function runs when update.php is run the first time for 6.x,
+ * even before updates are selected or performed. It is important
+ * that if updates are not ultimately performed that no changes are
+ * made which make it impossible to continue using the prior version.
+ * Just adding columns is safe. However, renaming the
+ * system.description column to owner is not. Therefore, we add the
+ * system.owner column and leave it to system_update_6008() to copy
+ * the data from description and remove description. The same for
+ * renaming locales_target.locale to locales_target.language, which
+ * will be finished by locale_update_6002().
+ */
+function update_fix_d6_requirements() {
+ $ret = array();
+
+ if (drupal_get_installed_schema_version('system') < 6000 && !variable_get('update_d6_requirements', FALSE)) {
+ $spec = array('type' => 'int', 'size' => 'small', 'default' => 0, 'not null' => TRUE);
+ db_add_field($ret, 'cache', 'serialized', $spec);
+ db_add_field($ret, 'cache_filter', 'serialized', $spec);
+ db_add_field($ret, 'cache_page', 'serialized', $spec);
+ db_add_field($ret, 'cache_menu', 'serialized', $spec);
+
+ db_add_field($ret, 'system', 'info', array('type' => 'text'));
+ db_add_field($ret, 'system', 'owner', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
+ if (db_table_exists('locales_target')) {
+ db_add_field($ret, 'locales_target', 'language', array('type' => 'varchar', 'length' => 12, 'not null' => TRUE, 'default' => ''));
+ }
+ if (db_table_exists('locales_source')) {
+ db_add_field($ret, 'locales_source', 'textgroup', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => 'default'));
+ db_add_field($ret, 'locales_source', 'version', array('type' => 'varchar', 'length' => 20, 'not null' => TRUE, 'default' => 'none'));
+ }
+ variable_set('update_d6_requirements', TRUE);
+
+ // Create the cache_block table. See system_update_6027() for more details.
+ $schema['cache_block'] = array(
+ 'fields' => array(
+ 'cid' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
+ 'data' => array('type' => 'blob', 'not null' => FALSE, 'size' => 'big'),
+ 'expire' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
+ 'created' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
+ 'headers' => array('type' => 'text', 'not null' => FALSE),
+ 'serialized' => array('type' => 'int', 'size' => 'small', 'not null' => TRUE, 'default' => 0)
+ ),
+ 'indexes' => array('expire' => array('expire')),
+ 'primary key' => array('cid'),
+ );
+ db_create_table($ret, 'cache_block', $schema['cache_block']);
+ }
+
+ return $ret;
+}
+
+/**
+ * Users who still have a Drupal 6 database (and are in the process of
+ * updating to Drupal 7) need extra help before a full bootstrap can be
+ * achieved. This function does the necessary preliminary work that allows
+ * the bootstrap to be successful.
+ *
+ * No access check has been performed when this function is called, so no
+ * changes to the database should be made here.
+ */
+function update_prepare_d7_bootstrap() {
+ // Allow the database system to work even though the registry has not
+ // been created yet.
+ drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE);
+ include_once DRUPAL_ROOT . '/includes/install.inc';
+ drupal_install_init_database();
+ spl_autoload_unregister('drupal_autoload_class');
+ spl_autoload_unregister('drupal_autoload_interface');
+ // The new {blocked_ips} table is used in Drupal 7 to store a list of
+ // banned IP addresses. If this table doesn't exist then we are still
+ // running on a Drupal 6 database, so suppress the unavoidable errors
+ // that occur.
+ try {
+ drupal_bootstrap(DRUPAL_BOOTSTRAP_ACCESS);
+ }
+ catch (Exception $e) {
+ if (db_table_exists('blocked_ips')) {
+ throw $e;
+ }
+ }
+}
+
+/**
+ * Check update requirements and report any errors.
+ */
+function update_check_requirements() {
+ global $db_url, $databases;
+ $requirements = array();
+
+ // If we will rewrite the settings.php then we need to make sure it is
+ // writeable.
+ if (empty($databases) && !empty($db_url) && is_string($db_url)) {
+ $requirements = install_check_requirements('', FALSE);
+ }
+ $warnings = FALSE;
+
+ // Check the system module requirements only.
+ $requirements += module_invoke('system', 'requirements', 'update');
+ $severity = drupal_requirements_severity($requirements);
+
+ // If there are issues, report them.
+ if ($severity != REQUIREMENT_OK) {
+ foreach ($requirements as $requirement) {
+ if (isset($requirement['severity']) && $requirement['severity'] != REQUIREMENT_OK) {
+ $message = isset($requirement['description']) ? $requirement['description'] : '';
+ if (isset($requirement['value']) && $requirement['value']) {
+ $message .= ' (Currently using ' . $requirement['title'] . ' ' . $requirement['value'] . ')';
+ }
+ $warnings = TRUE;
+ drupal_set_message($message, 'warning');
+ }
+ }
+ }
+ return $warnings;
+}
+
+/**
+ * Create the batch table.
+ *
+ * This is part of the Drupal 5.x to 6.x migration.
+ */
+function update_create_batch_table() {
+
+ // If batch table exists, update is not necessary
+ if (db_table_exists('batch')) {
+ return;
+ }
+
+ $schema['batch'] = array(
+ 'fields' => array(
+ 'bid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE),
+ 'token' => array('type' => 'varchar', 'length' => 64, 'not null' => TRUE),
+ 'timestamp' => array('type' => 'int', 'not null' => TRUE),
+ 'batch' => array('type' => 'text', 'not null' => FALSE, 'size' => 'big')
+ ),
+ 'primary key' => array('bid'),
+ 'indexes' => array('token' => array('token')),
+ );
+
+ $ret = array();
+ db_create_table($ret, 'batch', $schema['batch']);
+ return $ret;
+}
+
+/**
+ * Converts Drupal 6 $db_url to Drupal 7 $databases array.
+ */
+function update_check_d7_settings() {
+ global $db_url, $databases;
+
+ if (empty($databases) && !empty($db_url) && is_string($db_url)) {
+ $url = parse_url($db_url);
+ $driver = substr($db_url, 0, strpos($db_url, '://'));
+ if ($driver == 'mysqli') {
+ $driver = 'mysql';
+ }
+ $databases['default']['default']['driver'] = $driver;
+ $databases['default']['default']['database'] = substr($url['path'], 1);
+ foreach (array('user' => 'username', 'pass' => 'password', 'host' => 'host', 'port' => 'port') as $old_key => $new_key) {
+ $databases['default']['default'][$new_key] = isset($url[$old_key]) ? urldecode($url[$old_key]) : '';
+ }
+ $conf_path = conf_path();
+ file_put_contents($conf_path .'/settings.php', "\n" . '$databases = '. var_export($databases, TRUE) . ';', FILE_APPEND);
+ }
+}
+
+/**
+ * Perform one update and store the results which will later be displayed on
+ * the finished page.
+ *
+ * An update function can force the current and all later updates for this
+ * module to abort by returning a $ret array with an element like:
+ * $ret['#abort'] = array('success' => FALSE, 'query' => 'What went wrong');
+ * The schema version will not be updated in this case, and all the
+ * aborted updates will continue to appear on update.php as updates that
+ * have not yet been run.
+ *
+ * @param $module
+ * The module whose update will be run.
+ * @param $number
+ * The update number to run.
+ * @param $context
+ * The batch context array
+ */
+function update_do_one($module, $number, &$context) {
+ // If updates for this module have been aborted
+ // in a previous step, go no further.
+ if (!empty($context['results'][$module]['#abort'])) {
+ return;
+ }
+
+ $function = $module . '_update_' . $number;
+ if (function_exists($function)) {
+ $ret = $function($context['sandbox']);
+ }
+
+ if (isset($ret['#finished'])) {
+ $context['finished'] = $ret['#finished'];
+ unset($ret['#finished']);
+ }
+
+ if (!isset($context['results'][$module])) {
+ $context['results'][$module] = array();
+ }
+ if (!isset($context['results'][$module][$number])) {
+ $context['results'][$module][$number] = array();
+ }
+ $context['results'][$module][$number] = array_merge($context['results'][$module][$number], $ret);
+
+ if (!empty($ret['#abort'])) {
+ $context['results'][$module]['#abort'] = TRUE;
+ }
+ // Record the schema update if it was completed successfully.
+ if ($context['finished'] == 1 && empty($context['results'][$module]['#abort'])) {
+ drupal_set_installed_schema_version($module, $number);
+ }
+
+ $context['message'] = 'Updating ' . check_plain($module) . ' module';
+}
+
--- /dev/null 2009-03-23 21:07:08.553263372 -0400
+++ update.sh 2009-03-24 16:14:57.000000000 -0400
@@ -0,0 +1,348 @@
+#!/usr/bin/env php
+ drupal_get_installed_schema_version($module);
+}
+
+function update_show_updates($updates) {
+ echo t('Modules requiring updates:') . "\n\n";
+ $files = module_rebuild_cache();
+ foreach ($updates as $module => $update_list) {
+ echo "{$files[$module]->info['name']} ({$files[$module]->name})\n";
+ echo " " . t('Pending updates:') . ' ' . implode(',', $update_list) . "\n\n";
+ }
+}
+
+function update_show_versions() {
+
+ $files = module_rebuild_cache();
+
+ printf("%-20s %-20s %-19s %5s\n\n", 'Name', 'Module', 'Version', 'Schema');
+ foreach ($files as $module => $file) {
+ printf("%-20s %-20s %-19s %5s\n", $file->info['name'], $module, $file->info['version'], $file->schema_version);
+ }
+}
+
+function update_do_updates($updates) {
+ global $maintenance;
+ if ($maintenance) {
+ $site_status = variable_get('site_offline', 0);
+ variable_set('site_offline', 1);
+ if ($maintenance !== TRUE) {
+ $site_status_message = variable_get('site_offline_message', NULL);
+ variable_set('site_offine_message', $message);
+ }
+ }
+ $operations = array();
+ foreach ($updates as $module => $update_list) {
+ foreach ($update_list as $update) {
+ $operations[] = array('update_sh_do_one', array($module, $update));
+ }
+ }
+
+ // Since this is running from the shell, we want to turn progressive off.
+ $_init_batch =& batch_get();
+ if (empty($_init_batch)) {
+ $_init_batch = array(
+ 'sets' => array(),
+ 'progressive' => FALSE,
+ );
+ }
+
+ $batch = array(
+ 'operations' => $operations,
+ 'title' => 'Updating',
+ 'init_message' => 'Starting updates',
+ 'error_message' => 'An unrecoverable error has occurred. You can find the error message below. It is advised to copy it to the clipboard for reference.',
+ 'finished' => 'update_sh_finished',
+ 'progressive' => FALSE,
+ );
+
+ batch_set($batch);
+ batch_process();
+
+ if ($_SESSION['update_success']) {
+ $output = 'Updates were attempted. If you see no failures below, you may proceed happily to the administration pages. Otherwise, you may need to update your database manually.' . $log_message . "\n";
+ }
+ else {
+ list($module, $version) = array_pop(reset($_SESSION['updates_remaining']));
+ $output = 'The update process was aborted prematurely while running update #' . $version . ' in ' . $module . '.module.' . $log_message;
+ if (module_exists('dblog')) {
+ $output .= ' You may need to check the watchdog database table manually.';
+ }
+ $output .= "\n";
+ }
+
+ // Output a list of queries executed
+ $update_ok = TRUE;
+ if (!empty($_SESSION['update_results'])) {
+ $output .= "The following queries were executed\n\n";
+ foreach ($_SESSION['update_results'] as $module => $updates) {
+ $output .= $module . " module\n";
+ foreach ($updates as $number => $queries) {
+ if ($number != '#abort') {
+ $output .= 'Update #' . $number . "\n";
+ foreach ($queries as $query) {
+ if ($query['success']) {
+ $output .= '* ' . htmlspecialchars_decode(html_entity_decode($query['query'])) . "\n";
+ }
+ else {
+ $update_ok = FALSE;
+ $output .= '* Failed: ' . htmlspecialchars_decode(html_entity_decode($query['query'])) . "\n";
+ }
+ }
+ if (!count($queries)) {
+ $output .= "* No queries\n";
+ }
+ }
+ }
+ }
+ echo $output;
+ }
+ unset($_SESSION['update_results']);
+ unset($_SESSION['update_success']);
+
+ if ($maintenance && $update_ok) {
+ variable_set('site_offline', $site_status);
+ if (empty($site_status_message)) {
+ variable_del('site_offine_message');
+ }
+ else {
+ variable_set('site_offine_message', $site_status_message);
+ }
+ }
+ return $update_ok;
+}
+
+function update_sh_do_one($module, $number, &$context) {
+ // If updates for this module have been aborted
+ // in a previous step, go no further.
+ if (!empty($context['results'][$module]['#abort'])) {
+ return;
+ }
+
+ $function = $module . '_update_' . $number;
+ if (function_exists($function)) {
+ $ret = $function($context['sandbox']);
+ }
+
+ if (isset($ret['#finished'])) {
+ $context['finished'] = $ret['#finished'];
+ unset($ret['#finished']);
+ }
+
+ if (!isset($context['results'][$module])) {
+ $context['results'][$module] = array();
+ }
+ if (!isset($context['results'][$module][$number])) {
+ $context['results'][$module][$number] = array();
+ }
+ $context['results'][$module][$number] = array_merge($context['results'][$module][$number], $ret);
+
+ if (!empty($ret['#abort'])) {
+ $context['results'][$module]['#abort'] = TRUE;
+ }
+ // Record the schema update if it was completed successfully.
+ if ($context['finished'] == 1 && empty($context['results'][$module]['#abort'])) {
+ drupal_set_installed_schema_version($module, $number);
+ }
+
+ $context['message'] = 'Updating ' . check_plain($module) . ' module';
+}
+
+function update_sh_finished($success, $results, $operations) {
+ // clear the caches in case the data has been updated.
+ drupal_flush_all_caches();
+
+ $_SESSION['update_results'] = $results;
+ $_SESSION['update_success'] = $success;
+ $_SESSION['updates_remaining'] = $operations;
+}
+
+$script = basename(array_shift($_SERVER['argv']));
+
+$shortopts = 'hr:s:lum::ve';
+$longopts = array('help', 'root:', 'site:', 'list', 'update',
+ 'maintenance::', 'verbose', 'versions');
+
+$args = @getopt($shortopts, $longopts);
+
+if (isset($args['h']) || isset($args['help'])) {
+ echo <<"
+Example: {$script} "http://mysite.org/node"
+
+All arguments are long options.
+
+ -h, --help This page.
+
+ -r, --root Set the working directory for the script to the specified path.
+ To execute Drupal this has to be the root directory of your
+ Drupal installation, f.e. /home/www/foo/drupal (assuming Drupal
+ running on Unix). Current directory is not required.
+ Use surrounding quotation marks on Windows.
+
+ -s, --site Used to specify with site will be used for the upgrade. If no
+ site is selected then default will be used.
+
+ -l, --list List all pending updates. If there are updates available then
+ the script with exit with a 1 return flag
+
+ -u, --update Process all pending updates. If there are any updates are not
+ processed successfully then the script with exit with a return
+ flag of 1.
+
+ -m, --maintenance Set the site into maintenance while the updates are being
+ run. If there are any failures, the site will remain in
+ maintenance mode. An optional message can be specified which
+ will set the message on the maintenance screen.
+
+ -v, --verbose This option displays the options as they are set, but will
+ produce errors from setting the session.
+
+ -e, --versions List the versions of all the modules in the system.
+
+To run this script without --root argument invoke it from the root directory
+of your Drupal installation with
+
+ ./scripts/{$script}
+
+\n
+EOF;
+ if (version_compare(phpversion(), '5.3.0', 'le')) {
+ echo "Warning: This version of PHP doesn't support long options\n";
+ }
+ exit;
+}
+
+// define default settings
+$_SERVER['HTTP_HOST'] = 'default';
+$_SERVER['PHP_SELF'] = '/update.php';
+$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
+$_SERVER['SERVER_SOFTWARE'] = 'PHP CLI';
+$_SERVER['REQUEST_METHOD'] = 'GET';
+$_SERVER['QUERY_STRING'] = '';
+$_SERVER['PHP_SELF'] = $_SERVER['REQUEST_URI'] = '/';
+$_SERVER['SCRIPT_NAME'] = '/' . basename($_SERVER['SCRIPT_NAME']);
+$_SERVER['HTTP_USER_AGENT'] = 'console';
+
+// toggle verbose mode
+$_verbose_mode = isset($args['h']) || isset($args['help']) ? TRUE : FALSE;
+
+$maintenance = TRUE;
+
+// parse invocation arguments
+if (isset($args['r']) || isset($args['root'])) {
+ // change working directory
+ $path = isset($args['r']) ? $args['r'] : $args['root'];
+ if (is_dir($path)) {
+ chdir($path);
+ if ($_verbose_mode) {
+ echo "cwd changed to: {$path}\n";
+ }
+ }
+ else {
+ echo "\nERROR: {$path} not found.\n\n";
+ }
+}
+
+if (isset($args['s']) || isset($args['site'])) {
+ $site = isset($args['s']) ? $args['s'] : $args['site'];
+ if (file_exists('./sites/' . $site)) {
+ $_SERVER['HTTP_HOST'] = $site;
+ $_SERVER['PHP_SELF'] = $_SERVER['REQUEST_URI'] = '/update.php';
+ }
+ else {
+ echo "ERROR: Unable to locate site {$site}\n";
+ exit(1);
+ }
+}
+
+if (isset($args['m']) || isset($args['maintenance'])) {
+ $opt = isset($args['m']) ? $args['m'] : (isset($args['maintenance']) ? $args['maintenance'] : NULL);
+ if (is_string($opt)) {
+ $maintenance = $opt;
+ }
+}
+
+define('DRUPAL_ROOT', realpath(getcwd()));
+
+include_once './includes/bootstrap.inc';
+drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
+include_once './includes/install.inc';
+include_once './includes/update.inc';
+include_once './includes/form.inc';
+drupal_load_updates();
+
+
+
+$user = user_load(array('uid' => 1));
+foreach ($args as $arg => $option) {
+ switch ($arg) {
+ case 'l':
+ case 'list':
+ if ($updates = drupal_get_updates()) {
+ update_show_updates($updates);
+ exit(1);
+ }
+ else {
+ echo t('No updates available') . "\n";
+ }
+ break 2;
+
+ case 'e':
+ case 'versions':
+ update_show_versions();
+ break 2;
+
+ case 'u':
+ case 'update':
+ if ($updates = drupal_get_updates()) {
+ if (!update_do_updates($updates)) {
+ exit(1);
+ }
+ }
+ break 2;
+ }
+}
+exit();