#!/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 $results, $maintenance;
$results = array();
if ($maintenance) {
variable_set('site_offline', 1);
if (!empty($message)) {
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_del('site_offline');
if (!empty($message)) {
variable_del('site_offine_message');
}
}
return $update_ok;
}
function update_sh_do_one($module, $number, &$context) {
global $dryrun, $results;
// 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 (!$dryrun && 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::dve';
$longopts = array('help', 'root:', 'site:', 'list', 'update',
'maintenance::', 'dry-run', '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.
-d, --dry-run No updates will be run but the system will pretend to do the
updates
-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']);
// toggle verbose mode
$_verbose_mode = isset($args['h']) || isset($args['help']) ? TRUE : FALSE;
$dryrun = FALSE;
$maintenance = FALSE;
$message = NULL;
// 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);
}
}
$dryrun = (isset($args['d']) || isset($args['dry-run'])) ? TRUE : FALSE;
if (isset($args['m']) || isset($args['maintenance'])) {
$maintenance = TRUE;
$opt = isset($args['m']) ? $args['m'] : $args['maintenance'];
if (is_string($opt)) {
$message = $opt;
}
}
include_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
include_once './includes/install.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();