#!/usr/bin/env php bootstrap(); } require_once dirname(__FILE__) . '/newscoop_bootstrap.php'; require_once $CAMPSITE_DIR . '/classes/CampPlugin.php'; if( isset($GLOBAL['argv']) && !is_array($GLOBALS['argv']) && empty($options)) { echo "Can't read command line arguments\n"; exit(1); } require_once("cli_script_lib.php"); $ETC_DIR = $CAMPSITE_DIR . '/conf'; // fill in HTTP_HOST to avoid notices in campsite_constants.php $_SERVER['HTTP_HOST'] = ''; if (empty($options)) { $options = getopt("d:b:t:efc:slh"); $flush = false; } else { $flush = true; } // prevent flush to fix conflict with zend session $flush = false; // define the cleanup function function __exit_cleanup() { global $tempDirName; if (!empty($tempDirName)) { camp_remove_dir($tempDirName); } } echo "\nNewscoop Restore Utility\n"; echo "------------------------\n"; flush_output($flush); $usage = " Usage: newscoop-restore -b [-t ] \ [-e] [-f] [-c ]|[-s] newscoop-restore -l newscoop-restore -h This script will replace existing data installation with that in the backup file. You must run this script from a directory that you have write access to because this script needs to create a temporary directory. Note that your backup database and files will automatically be upgraded if they are older than the currently installed version of Newscoop. Note: For multiple installations of Newscoop on a single server, you must run this script from the installation directory where you want to restore the data. For example, if you have installed Newscoop in two locations: /var/www/ns1 and /var/www/ns2, and you want to restore the data for the 'foo' installation, you must run /var/www/ns1/bin/newscoop-restore, and NOT /var/www/ns2/bin/newscoop-restore. Parameters: -b The tarball created by the 'newscoop-backup' script. Give the full or relative path to the file. [-t ] If this is specified, the script will use the database name specified instead of the one specified in the backup file. This is useful for site-to-site transfer of a website, that is, moving your website from one server to another. [-e] Use the existing configuration files instead of the ones in the backup file. In other words, the existing config files in the current installation will not be replaced. This parameter takes precedence over -t parameter. E.g.: the database name will be read from the existing database configuration file, not from the -t option. [-c ] Convert the database data from to UTF-8. [-s] Convert the database data from the database server character set to UTF-8. [-l] List all available charsets and exit. [-f] Dont prompt, assume 'yes' to questions. [-h] Show this help and exit. See also: newscoop-backup "; // display help if -h parameter was supplied if (isset($options['h'])) { echo $usage; exit(0); } // initialize options variables from command line parameters $archive_file = isset($options['b']) ? $options['b'] : null; $useExistingConfig = isset($options['e']); $doPrompt = !isset($options['f']); $destDbSpecified = isset($options['t']); $destDbName = isset($options['t']) ? $options['t'] : ""; $convertToUTF = isset($options['c']) || isset($options['s']); // verify if the command line parameters were valid if ((empty($archive_file) && !in_array('l', array_keys($options))) || ($destDbSpecified && empty($destDbName)) || (isset($options['c']) && empty($options['c']))) { echo $usage; camp_exit_with_error("Invalid parameters; please read the usage description above."); } // include the utils library require_once("cli_script_lib.php"); // include the install configuration script if (!camp_is_readable("$ETC_DIR/install_conf.php")) { camp_exit_with_error("Unable to read the install configuration file!"); } // include install configuration file require_once("$ETC_DIR/install_conf.php"); if ($useExistingConfig || isset($options['l'])) { if (!file_exists($ETC_DIR.'/database_conf.php')) { echo "ERROR! File 'database_conf.php' does not exist. Is Newscoop installed?\n\n"; exit(1); } if (!is_writable($ETC_DIR.'/database_conf.php')) { echo "ERROR! File 'database_conf.php' is not writable by this script.\n\n"; exit(1); } } // display the list of available character sets if the option -l was supplied if (isset($options['l'])) { require_once("$ETC_DIR/database_conf.php"); camp_connect_to_database(); echo "The list of available charsets:\n"; $charsetsList = camp_get_all_charsets(); foreach ($charsetsList as $charsetName=>$charsetDescription) { echo "- $charsetName: $charsetDescription\n"; } exit(0); } if (!file_exists($archive_file)) { camp_exit_with_error("The backup file you specified does not exist."); } if (!is_writable(getcwd())) { camp_exit_with_error("You do not have permissions to the currect directory."); } // If convert to UTF-8 verify if the source character set was valid. if ($convertToUTF) { require_once("$ETC_DIR/database_conf.php"); camp_connect_to_database(); $fromCharset = isset($options['c']) ? $options['c'] : camp_get_server_charset(); if (!camp_valid_charset($fromCharset)) { camp_exit_with_error("Invalid charset '$fromCharset'!"); } if ($doPrompt) { echo "\nWARNING! The conversion to UTF-8 may break your database content!\n"; echo "If you broke your database content it can not be recovered unless\n"; echo "you restore the database from a backup!\n\n"; echo "Do you want to continue the conversion now? (y/N): "; if (strtolower(trim(camp_readline())) != 'y') { echo "Restore operation aborted by the user!\n"; exit(1); } } mysql_close(); } /* * Start the restore operation. */ $adviceOnError = "Please run this script as '" . $Campsite['APACHE_USER'] . "' or as 'root'."; // // Get the name of the directory that will be untarred. // echo " * Initializing...\n"; flush_output($flush); $archiveExtension = pathinfo($archive_file, PATHINFO_EXTENSION); if ($archiveExtension == "gz") { $tarGzOption = "z"; } else { $tarGzOption = ""; } $backupDir = $Campsite['CAMPSITE_DIR'] . DIR_SEP . 'backup' . DIR_SEP; $tarDirOption = ' -C ' . escapeshellarg($backupDir); $isNewBackupFormat = true; $cmd = "tar tf$tarGzOption " . escapeshellarg($archive_file)." | grep sql"; exec($cmd, $output); if (count($output) == 0) { $isNewBackupFormat = false; $cmd = "tar tf$tarGzOption " . escapeshellarg($archive_file); exec($cmd, $output); if (count($output) == 0) { camp_exit_with_error("Invalid backup file."); } echo " * Old backup file detected (pre-2.6.0)\n"; } $output = array_pop($output); if ($isNewBackupFormat) { $parts = preg_split('/\//', $output); $tempDirName = array_shift($parts); } else { $tempDirName = "backup-temp-".date("Y-m-d-H-i-s"); } // having the tmp directory inside the backup directory $tempDirName = $backupDir . $tempDirName; echo " * Temp directory: $tempDirName\n"; echo " * Initialization done.\n"; flush_output($flush); if (file_exists($tempDirName)) { echo "\nThis script needs to create a temporary directory named '$tempDirName',\n"; echo "but the directory already exists. Please delete the existing directory or move it out of the way.\n\n"; exit(1); } // // Untar the backup // echo " * Extracting files into temp directory..."; flush_output($flush); if ($isNewBackupFormat) { $cmd = "tar xf$tarGzOption " . escapeshellarg($archive_file) . $tarDirOption; camp_exec_command($cmd, $adviceOnError); } else { camp_create_dir($tempDirName); $currentDir = getcwd(); chdir($tempDirName); $cmd = "tar xf$tarGzOption " . escapeshellarg("../".$archive_file) . " &> /dev/null"; camp_exec_command($cmd, $adviceOnError); chdir($currentDir); } if (!file_exists($tempDirName)) { echo "ERROR! Could not extract archive.\n\n"; exit(1); } // // Get the original database name from the extracted files. // $database_dump_file = glob("$tempDirName/*-database*"); if (sizeof($database_dump_file) != 1) { camp_exit_with_error("Archive $archive_file is invalid."); } $db_file_name = basename($database_dump_file[0]); $origDbName = substr($db_file_name, 0, strrpos($db_file_name, '-')); // If old backup format, extract the tar files inside the tar file. if (!$isNewBackupFormat) { $packages = glob("$tempDirName/$origInstanceName-*.tar.gz"); foreach ($packages as $index => $package) { $package_name = basename($package); if ($package == "") { continue; } $currentDir = getcwd(); chdir($tempDirName); camp_exec_command("tar xzf " . escapeshellarg($package_name), $adviceOnError); chdir($currentDir); } } echo "done.\n"; flush_output($flush); // // Get the version from the backup archive. // $backup_version_file = glob("$tempDirName/BACKUP-VERSION*"); if (sizeof($backup_version_file) != 1) { camp_exit_with_error("Archive $archive_file is invalid."); } $bversion_file_name = basename($backup_version_file[0]); $backupVersion = (int)substr($bversion_file_name, strlen('BACKUP-VERSION-'), 1); if ($useExistingConfig) { $includeFile = "$ETC_DIR/database_conf.php"; } else { if ($backupVersion < 3) { $includeFile = "$tempDirName/$origDbName/database_conf.php"; } else { $includeFile = "$tempDirName/conf/database_conf.php"; } } // Check if the database configuration file exists. if (!file_exists($includeFile)) { echo "\nThe database configuration file '$includeFile' does not exist.\n"; echo "It is likely because Newscoop is not properly installed.\n"; echo "Please run the Web installer and try restoring from the backup after that.\n\n"; echo " * Cleaning up..."; camp_remove_dir($tempDirName); echo "done.\n\n"; exit(1); } // Check if configuration file is readable. if (!camp_is_readable($includeFile)) { echo " * Cleaning up..."; camp_remove_dir($tempDirName); echo "done.\n\n"; exit(1); } require($includeFile); if ($destDbSpecified) { $Campsite['DATABASE_NAME'] = $destDbName; } elseif ($useExistingConfig) { $destDbName = $Campsite['DATABASE_NAME']; } else { $destDbName = $origDbName; } camp_connect_to_database(); echo " * Backup database name is '$origDbName'.\n"; echo " * Destination database name (to be replaced) is '$destDbName'.\n"; flush_output($flush); // // Restore the backup files // if ($backupVersion < 3) { if (!camp_is_empty_dir("$tempDirName/look")) { $templatesSrcDir = "$tempDirName/look"; $packageTemplatesDirName = 'look'; } else { $templatesSrcDir = null; } $configSrcDir = "$tempDirName/$origDbName/database_conf.php"; } else { $templatesSrcDir = "$tempDirName/templates"; $themesSrcDir = "$tempDirName/themes"; $packageTemplatesDirName = 'templates'; $packageThemesDirName = 'themes'; $configSrcDir = "$tempDirName/conf/database_conf.php"; } $fileSrcDir = "$tempDirName/public/files"; $imagesSrcDir = "$tempDirName/images"; $configDestDir = $ETC_DIR; $filesDestDir = $CAMPSITE_DIR.'/public/files'; $imagesDestDir = $CAMPSITE_DIR.'/images'; $templatesDirName = 'templates'; // keep for gimme template upgrade $themesDirName = 'themes'; // keep for gimme theme upgrade $templatesDestDir = $CAMPSITE_DIR.'/'.$templatesDirName; $themesDestDir = $CAMPSITE_DIR.'/'.$themesDirName; $compiledTemplatesDir = $CAMPSITE_DIR.'/cache'; $pdfDir = $CAMPSITE_DIR.'/public/pdf'; $destDirs = array("$CAMPSITE_DIR/themes", $imagesDestDir, $filesDestDir, $compiledTemplatesDir, $pdfDir); foreach ($destDirs as $dir) { if (!file_exists($dir)) { echo "ERROR! Directory $dir does not exist. Is Newscoop installed?\n\n"; exit(1); } if (!is_writable($dir)) { echo "ERROR! Directory $dir is not writable by this script.\n\n"; exit(1); } } if ($doPrompt) { // Clear out all files currently residing in these directories echo "\n All files in the following directories will be deleted.\n"; echo " (The backup files will be copied to these locations)\n"; foreach ($destDirs as $dir) { echo " ".$dir."\n"; } $answer = "dummy_value"; while (!in_array($answer, array('y','n', ''))) { echo " Are you sure you want to continue? (y/N) "; $answer = camp_readline(); $answer = strtolower(trim($answer)); } if ($answer == 'n' || $answer == '') { echo "\n Restore cancelled.\n"; echo " * Cleaning up..."; flush_output($flush); camp_remove_dir($tempDirName); echo "done.\n\n"; exit(0); } } // // Remove all existing files... // foreach ($destDirs as $dir) { echo " * Removing files in $dir..."; flush_output($flush); if ($dir == $templatesDestDir) { camp_remove_dir($dir."/*", '', array('system_templates')); } else if ($dir == $themesDestDir) { camp_remove_dir($dir."/*", '', array('system_templates')); } else { camp_remove_dir($dir."/*"); } echo "done.\n"; } // // Restore files from backup... // if (is_dir($templatesSrcDir)) { echo " * Restoring templates..."; flush_output($flush); if (!is_null($templatesSrcDir)) { camp_copy_files($templatesSrcDir, $CAMPSITE_DIR); if ($packageTemplatesDirName != $templatesDirName) { camp_remove_dir($templatesDestDir); rename($CAMPSITE_DIR.'/'.$packageTemplatesDirName, $templatesDestDir); } } echo "done.\n"; } echo " * Restoring themes..."; flush_output($flush); if (!is_null($themesSrcDir) && file_exists($themesSrcDir)) { camp_copy_files($themesSrcDir, $CAMPSITE_DIR); if ($packageThemesDirName != $themesDirName) { camp_remove_dir($themesDestDir); rename($CAMPSITE_DIR.'/'.$packageThemesDirName, $themesDestDir); } } echo "done.\n"; echo " * Restoring images..."; flush_output($flush); if (is_dir($imagesSrcDir)) { camp_copy_files($imagesSrcDir, $CAMPSITE_DIR); } echo "done.\n"; echo " * Restoring file attachments..."; flush_output($flush); if (is_dir($fileSrcDir)) { camp_copy_files($fileSrcDir, $CAMPSITE_DIR); } echo "done.\n"; flush_output($flush); if (!$useExistingConfig) { if ($backupVersion < 3) { echo " * Restoring configuration..."; $configFile = @file_get_contents("$ETC_DIR/database_conf.php"); $newConfigFile = camp_migrate_config_file($configFile); @file_put_contents("$ETC_DIR/database_conf.php", $newConfigFile); } else { camp_copy_files($configSrcDir, $CAMPSITE_DIR); } echo "done.\n"; } // // Converting template files if necessary // if ($backupVersion < 3) { echo " * Converting templates from 2.x versions..."; flush_output($flush); require_once($CAMPSITE_DIR.'/classes/TemplateConverter.php'); $template_files = camp_read_files($CAMPSITE_DIR.'/templates'); $converter = new TemplateConverter(); foreach($template_files as $template_file) { $converter->read($template_file); $converter->parse(); $converter->write(); } echo "done.\n"; } // // Restore the database... // echo " * Restoring the database $destDbName..."; flush_output($flush); if (camp_database_exists($destDbName)) { camp_clean_database($destDbName); } else { if (!mysql_query("CREATE DATABASE `$destDbName` CHARACTER SET utf8")) { camp_exit_with_error("Can't create database $destDbName"); } } $sqlFile = "$tempDirName/$origDbName-database.sql"; camp_restore_database($sqlFile); $cmd = "mysql -u " . $Campsite['DATABASE_USER'] . " --host=" . $Campsite['DATABASE_SERVER_ADDRESS'] . " --port=" . $Campsite['DATABASE_SERVER_PORT'] . ' --default-character-set=utf8'; echo "done.\n"; flush_output($flush); // If database version is minor than 2.6.0 we do nothing but exit the // script as we only care about upgrading newer Newscoops. camp_detect_database_version($destDbName, $dbVersion); if ($dbVersion < '2.6.0') { echo "\n You must upgrade to Newscoop 2.6 or 2.7 first, after that"; echo "\n run this script again to upgrade to 3.0.\n\n"; echo " * Cleaning up..."; camp_clean_database($destDbName); @mysql_query("DROP DATABASE `$destDbName`"); camp_remove_dir($tempDirName); echo "done.\n\n"; exit(1); } // Upgrade the database echo " * Upgrading (if necessary)..."; flush_output($flush); $res = camp_upgrade_database($destDbName); if ($res !== 0) { camp_exit_with_error($res); } // replace $campsite by $gimme echo " * Upgrading templates..."; flush_output($flush); require_once($CAMPSITE_DIR.'/classes/TemplateConverterNewscoop.php'); $template_files = camp_read_files($CAMPSITE_DIR.'/themes'); $converter = new TemplateConverterNewscoop(); foreach($template_files as $template_file) { $converter->read($template_file); $converter->parse(); $converter->write(); } echo "done.\n"; //if( $res === 0 ) //{ if ($convertToUTF) { echo " * Converting the database from '$fromCharset' to 'UTF-8'...\n"; $dumpFile = "$tempDirName/$destDbName-database-$fromCharset.sql"; if (camp_backup_database($destDbName, $dumpFile, $output, array("--default-character-set=$fromCharset")) != 0) { camp_exit_with_error("Unable to backup the database $destDbName\n" . implode("\n", $output)); } $outDumpFile = "$tempDirName/$destDbName-database-utf8.sql"; camp_change_dump_encoding($dumpFile, $outDumpFile, $fromCharset); camp_restore_database($outDumpFile); unlink($dumpFile); unlink($outDumpFile); echo " done.\n"; } //} // upgrade plugins echo " * Updating plugins (if necessary)..."; @CampPlugin::OnUpgrade(); @CampPlugin::OnAfterUpgrade(); echo " done.\n"; // // Remove the temp dir. // echo " * Cleaning up..."; flush_output($flush); camp_remove_dir($tempDirName); $file = $CAMPSITE_DIR . '/system_preferences.php'; if (file_exists($file)) { unlink($file); } echo "done.\n\n"; if ($useExistingConfig || $destDbSpecified) { echo "Note: If you are doing a site-to-site transfer you may have to fix the aliases in your publications before the frontend will work. An alias is the base URL for your publication. To change an alias, login to the administration interface and go to the publication configure screen.\n\n"; } echo "IMPORTANT!\n"; echo "You must restart the apache server for the changes to take effect!\n";