<?php
/**
 * UpgradeWizardCommon
 *
 * The contents of this file are subject to the SugarCRM Public License Version
 * 1.1.3 ("License"); You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at http://www.sugarcrm.com/SPL
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * All copies of the Covered Code must include on each user interface screen:
 *    (i) the "Powered by SugarCRM" logo and
 *    (ii) the SugarCRM copyright notice
 * in the same form as they appear in the distribution.  See full license for
 * requirements.
 *
 * The Original Code is: SugarCRM Open Source
 * The Initial Developer of the Original Code is SugarCRM, Inc.
 * Portions created by SugarCRM are Copyright (C) 2004-2006 SugarCRM, Inc.;
 * All Rights Reserved.
 * Contributor(s): ______________________________________.
 */

///////////////////////////////////////////////////////////////////////////////
////	UTILITIES THAT MUST BE LOCAL :(
function prepSystemForUpgradeSilent() {
	global $subdirs;
	global $cwd;
	global $sugar_config;

	// make sure dirs exist
	foreach($subdirs as $subdir) {
	    mkdir_recursive(clean_path("{$cwd}/{$sugar_config['upload_dir']}upgrades/{$subdir}"));
	}
}
////	END UTILITIES THAT MUST BE LOCAL :(
///////////////////////////////////////////////////////////////////////////////


// only run from command line
if(isset($_SERVER['HTTP_USER_AGENT'])) {
	die('This utility may only be run from the command line or command prompt.');
}

///////////////////////////////////////////////////////////////////////////////
////	USAGE
$usage =<<<eoq
Usage: php -f su.php [installZipFile] [logFile] [pathToSugarInstance]
Example:
    php -f su.php \
    /home/joey/upgradefiles/SugarPro-Patch-4.5.0g.zip \
    /home/joey/logs/someLogFile.log \
    /var/www/html/joeytest

Arguments:
    installZipFile      Full path to the zip file, generally 
                        ./cache/upload/upgrades/patch/[fileName].zip
    logFile             Full path to an alternate log file.
    
    pathToSugarInstance (optional) Full path to the instance being upgraded.  
                        Will fill with current directory if not found.

eoq;
////	END USAGE
///////////////////////////////////////////////////////////////////////////////

if(count($argv) < 2) {
	echo $usage;
	die();
}

///////////////////////////////////////////////////////////////////////////////
////	HANDLE RUNNING FROM PATH OUTSIDE OF INSTANCE
$cwd = getcwd(); // default to current, assumed to be in a valid SugarCRM root dir.
if(isset($argv[3])) {
	if(is_dir($argv[3])) {
		$cwd = $argv[3];
		chdir($cwd);
	} else {
		echo "*******************************************************************************\n";
		echo "*** ERROR: 3rd parameter must be a valid directory.  Tried to cd to [ {$argv[3]} ].\n";
		echo $usage;
		echo "FAILURE\n";
		die();
	}
}

// make sure we're in a Sugar root dir
if(!is_file("{$cwd}/include/entryPoint.php")) {
	echo "*******************************************************************************\n";
	echo "*** ERROR: Tried to execute in a non-SugarCRM root directory.  Pass a 3rd parameter.\n";
	echo $usage;
	echo "FAILURE\n";
	die();
}


///////////////////////////////////////////////////////////////////////////////
////	STANDARD REQUIRED SUGAR INCLUDES AND PRESETS
if(!defined('sugarEntry')) define('sugarEntry', true);

$_SESSION = array();
$_SESSION['schema_change'] = 'sugar'; // we force-run all SQL
$_SESSION['silent_upgrade'] = true;
$_SESSION['step'] = 'silent'; // flag to NOT try redirect to 4.5.x upgrade wizard

$_REQUEST = array();
$_REQUEST['addTaskReminder'] = 'remind';

require_once('include/entryPoint.php');
require_once('include/dir_inc.php');
require_once('include/utils/zip_utils.php');
require_once('modules/Administration/UpgradeHistory.php');
//require_once('modules/UpgradeWizard/uw_utils.php'); // must upgrade UW first
require_once("{$cwd}/sugar_version.php"); // provides $sugar_version & $sugar_flavor

///////////////////////////////////////////////////////////////////////////////
////	CONFIRM NECESSARY ARGS
if(count($argv) < 3) {
	echo "*******************************************************************************\n";
	echo "*** ERROR: Missing required parameters.  Received ".($argc - 1)." argument(s), require 2.\n";
	echo $usage;
	echo "FAILURE\n";
	die();
}

if(!is_file($argv[1])) { // valid zip?
	echo "*******************************************************************************\n";
	echo "*** ERROR: First argument must be a full path to the patch file. Got [ {$argv[1]} ].\n";
	echo $usage;
	echo "FAILURE\n";
	die();
}
////	CONFIRM NECESSARY ARGS
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
////	PREP LOCALLY USED PASSED-IN VARS & CONSTANTS
$GLOBALS['log']	= LoggerManager::getLogger('SugarCRM');
$patchName		= basename($argv[1]);
$zip_from_dir	= substr($patchName, 0, strlen($patchName) - 4); // patch folder name (minus ".zip")
$path			= $argv[2]; // custom log file, if blank will use ./upgradeWizard.log
$db				= &DBManager :: getInstance();
$UWstrings		= return_module_language('en_us', 'UpgradeWizard');
$adminStrings	= return_module_language('en_us', 'Administration');
$mod_strings	= array_merge($adminStrings, $UWstrings);
$subdirs		= array('full', 'langpack', 'module', 'patch', 'theme', 'temp');

$_REQUEST['zip_from_dir'] = $zip_from_dir;

define('SUGARCRM_PRE_INSTALL_FILE', 'scripts/pre_install.php');
define('SUGARCRM_POST_INSTALL_FILE', 'scripts/post_install.php');
define('SUGARCRM_PRE_UNINSTALL_FILE', 'scripts/pre_uninstall.php');
define('SUGARCRM_POST_UNINSTALL_FILE', 'scripts/post_uninstall.php');
////	END PREP LOCALLY USED PASSED-IN VARS
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
////	UPGRADE PREP
if(!is_dir(clean_path("{$cwd}/{$sugar_config['upload_dir']}/upgrades"))) {
	prepSystemForUpgradeSilent();
}

$unzip_dir = clean_path("{$cwd}/{$sugar_config['upload_dir']}upgrades/temp/su_temp");
$install_file = clean_path("{$cwd}/{$sugar_config['upload_dir']}upgrades/patch/".basename($argv[1]));
mkdir_recursive($unzip_dir);
if(!is_dir($unzip_dir)) {
	die("\nFAILURE\n");
}
unzip($argv[1], $unzip_dir);
// mimic standard UW by copy patch zip to appropriate dir
copy($argv[1], $install_file);
////	END UPGRADE PREP
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
////	UPGRADE UPGRADEWIZARD
$zipBasePath = clean_path("{$cwd}/{$sugar_config['upload_dir']}upgrades/temp/su_temp/{$zip_from_dir}");
$uwFiles = findAllFiles(clean_path("{$zipBasePath}/modules/UpgradeWizard"), array());
$destFiles = array();

foreach($uwFiles as $uwFile) {
	$destFile = clean_path(str_replace($zipBasePath, $cwd, $uwFile));
	copy($uwFile, $destFile);
}
require_once('modules/UpgradeWizard/uw_utils.php'); // must upgrade UW first
logThis("*** SILENT UPGRADE INITIATED.", $path);
logThis("*** UpgradeWizard Upgraded", $path);
////	END UPGRADE UPGRADEWIZARD
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
////	MAKE SURE PATCH IS COMPATIBLE
if(is_file("{$cwd}/{$sugar_config['upload_dir']}upgrades/temp/su_temp/manifest.php")) {
	// provides $manifest array
	include("{$cwd}/{$sugar_config['upload_dir']}upgrades/temp/su_temp/manifest.php");
	if(!isset($manifest)) {
		die("\nThe patch did not contain a proper manifest.php file.  Cannot continue.\n\n");
	} else {
		copy("{$cwd}/{$sugar_config['upload_dir']}upgrades/temp/su_temp/manifest.php", "{$cwd}/{$sugar_config['upload_dir']}upgrades/patch/{$zip_from_dir}-manifest.php");
		
		$error = validate_manifest($manifest);
		if(!empty($error)) {
			$error = strip_tags(br2nl($error));
			die("\n{$error}\n\nFAILURE\n");
		}
	}
} else {
	die("\nThe patch did not contain a proper manifest.php file.  Cannot continue.\n\n");
}
////	END MAKE SURE PATCH IS COMPATIBLE
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
////	RUN SILENT UPGRADE
ob_start();
set_time_limit(0);

///////////////////////////////////////////////////////////////////////////////
////	MAKE BACKUPS OF TARGET FILES
$rest_dir = clean_path(remove_file_extension($install_file) . "-restore");
$errors = commitMakeBackupFiles($rest_dir, $install_file, $unzip_dir, $zip_from_dir, array(), $path);

///////////////////////////////////////////////////////////////////////////////
////	HANDLE PREINSTALL SCRIPTS
if(empty($errors)) {
	$file = "{$unzip_dir}/".constant('SUGARCRM_PRE_INSTALL_FILE');
	
	if(is_file($file)) {
		include($file);
		logThis('Running pre_install()...', $path);
		pre_install();
		logThis('pre_install() done.', $path);
	}
}

///////////////////////////////////////////////////////////////////////////////
////	COPY NEW FILES INTO TARGET INSTANCE
if(empty($errors)) {
	$split = commitCopyNewFiles($unzip_dir, $zip_from_dir, $path);
	$copiedFiles = $split['copiedFiles'];
	$skippedFiles = $split['skippedFiles'];
}

///////////////////////////////////////////////////////////////////////////////
////	HANDLE POSTINSTALL SCRIPTS
if(empty($errors)) {
	logThis('Starting post_install()...', $path);
	$file = "{$unzip_dir}/".constant('SUGARCRM_POST_INSTALL_FILE');
	
	if(is_file($file)) {
		include($file);
		post_install();
	}

	logThis('Performing UWrebuild()...', $path);
	UWrebuild();
	logThis('UWrebuild() done.', $path);

	if(!rebuildConfigFile($sugar_config, $sugar_version)) {
		logThis('*** ERROR: could not write config.php! - upgrade will fail!', $path);
		$errors[] = 'Could not write config.php!';
	}
	logThis('post_install() done.', $path);
}

///////////////////////////////////////////////////////////////////////////////
////	REGISTER UPGRADE
if(empty($errors)) {
	logThis('Registering upgrade with UpgradeHistory', $path);
	$file_action = "copied";
	// if error was encountered, script should have died before now
	$new_upgrade = new UpgradeHistory();
	$new_upgrade->filename = $install_file;
	$new_upgrade->md5sum = md5_file($install_file);
	$new_upgrade->name = $zip_from_dir;
	$new_upgrade->description = $manifest['description'];
	$new_upgrade->type = 'patch';
	$new_upgrade->version = $sugar_version;
	$new_upgrade->status = "installed";
	$new_upgrade->manifest = (!empty($_SESSION['install_manifest']) ? $_SESSION['install_manifest'] : '');
	$new_upgrade->save();
}

///////////////////////////////////////////////////////////////////////////////
////	TAKE OUT TRASH
if(empty($errors)) {
	logThis('Taking out the trash, unlinking temp files.', $path);
	unlinkTempFiles();
}	

///////////////////////////////////////////////////////////////////////////////
////	HANDLE REMINDERS
if(empty($errors)) {	
	commitHandleReminders($skippedFiles, $path);
}

///////////////////////////////////////////////////////////////////////////////
////	RECORD ERRORS
$phpErrors = ob_get_contents();
ob_end_clean();
logThis("**** Potential PHP generated error messages: {$phpErrors}", $path);

if(count($errors) > 0) {
	foreach($errors as $error) {
		logThis("****** SilentUpgrade ERROR: {$error}", $path);
	}
	echo "FAILED\n";
} else {
	logThis("***** SilentUpgrade completed successfully.", $path);
	echo "SUCCESS\n";
}

?>
