<?php
/*
 * This file is part of a larger software package. Please read the License file 
 * in the root of this installation for terms of usage and distribution.
 * 
 * @author The Web Pro Miami, Inc. <info@thewebpro.com>
 * @copyright The Web Pro Miami, Inc. <info@thewebpro.com>, http://www.thewebpro.com/
 * 
 * CORE: manage/updater.php - version 1.0 (IMPORTANT: Non-core items in CORE config below only)
*/

/* CORE config */
$nURL = "http://cp.thewebpro.com/wpm_update.php";
// $nURL = "http://cp.thewebpro.com/wpm_update_dev.php"; // dev channel, use with caution


$nSuccessURL = "home.php?nShowNotify=1";
$nDEBUG = false;
$nAdminOnlyPg = 0;

require("inc/stop_cache.php");
// connect to mysql
require("../inc/dbconnect.php");
require("inc/secure_page.php");
include_once("../inc/config.php");

// Get passed-in vars
$nRedirect = (isset($_POST['nRedirect']) ? $_POST['nRedirect'] : NULL);
$nRedirect = trim($nRedirect);
$nRedirect = str_replace("~~","=",$nRedirect);
// sanitize for security
if($nRedirect){ $nRedirect = nSanitizeURL(substr($nRedirect,0,250)); }
if($nRedirect){ $nSuccessURL = $nRedirect; }

// Get real path of this installation
$nServerHost = $_SERVER["HTTP_HOST"];
$nPathSelf = $_SERVER["PHP_SELF"];
$nPathSelf = str_replace("updater.php","",$nPathSelf);
$nPathSelf = str_replace("manage/","",$nPathSelf);
$nSitePath = "$nServerHost$nPathSelf";


// TO DO: try using "fopen" if cURL is not installed on server

if(!function_exists("curl_init")){
	if(!$nDEBUG){
		exit("<html><head><script>nHomePage = \"$nSuccessURL\";window.location=nHomePage;</script></head><body></body></html>");
	} else {
		exit("Update failed! CURL not installed on this server.");
	}
}

$ch = curl_init(); /// initialize a cURL session 
curl_setopt ($ch, CURLOPT_URL,$nURL); ///set the post-to url (do not include the ?query+string here!)
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt ($ch, CURLOPT_HEADER, 0);  /// Header control 
curl_setopt($ch, CURLOPT_POST, 1);  /// tell it to make a POST, not a GET 
curl_setopt($ch, CURLOPT_POSTFIELDS, "v=$nCPVersion&i=$nSitePath");  /// put the query string here
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);  /// This allows the output to be set into a variable $xyz
$nUpdateInfo = curl_exec ($ch); /// execute the curl session and return the output to a variable $xyz
curl_close ($ch);

if($nDEBUG){ print "Sent to server: v=$nCPVersion&i=$nSitePath<BR>"; print "Returned from server ($nURL): $nUpdateInfo<BR>"; }

// if the server responded and an update is available...
$nUpgradingNow = false;
if($nUpdateInfo){
	$nUpdateInfoARRAY = explode(",",$nUpdateInfo);
	$nUpdateVer = $nUpdateInfoARRAY[0];
	$nUpdatePath = $nUpdateInfoARRAY[1];
	$nUpdateFile = nGetFileName($nUpdatePath);
	// Download update
	$nFileCopySuccess = copyFile($nUpdatePath,"");
	if($nFileCopySuccess && file_exists("$nUpdateFile")){
		include_once("inc/pclzip/pclzip.lib.php");
		$nUpdateZIP = new PclZip(dirname(__FILE__)."/$nUpdateFile");
		if ($nUpdateZIP->extract(PCLZIP_OPT_PATH, dirname(__FILE__)."/tmp_$nUpdateVer") != 0) {
		    // Archive extracted
			unlink("$nUpdateFile");
			// Run before_install.php, then delete it
			$nScriptToRun = "tmp_$nUpdateVer/before_install.php";
			if(file_exists($nScriptToRun)){ include_once($nScriptToRun); unlink($nScriptToRun); }
			// Copy files from extracted folder to installation
			$nFileFrom = "tmp_$nUpdateVer/";
			$nFileTo = "../"; // root of installation
			smartCopy($nFileFrom,$nFileTo,array('folderPermission'=>0755,'filePermission'=>0644));
			// Run after_install.php, then delete it
			$nScriptToRun = "tmp_$nUpdateVer/after_install.php";
			if(file_exists($nScriptToRun)){ include_once($nScriptToRun); unlink($nScriptToRun); }
			if(file_exists("../after_install.php")){ unlink("../after_install.php"); }
			// Delete temp upgrade folder
			recursive_remove_directory("tmp_$nUpdateVer");
		}
	}
	$nUpgradingNow = true;
} else {
	if(!$nDEBUG){
		exit("<html><head><script>nHomePage = \"$nSuccessURL\";window.location=nHomePage;</script></head><body></body></html>");
	} else {
		exit("No update available.");
	}
}
?>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head>
	<title>Logging in...</title>
	<meta name="Robots" content="None">
<style>
	BODY{ font-family:Arial, Helvetica, sans-serif; color:#555; font-size:11px; line-height:2.5em; }
</style>
<script language="JavaScript">
<!--
<? if($nUpgradingNow){ ?>
setTimeout("loadHome();",2000);
<? } else { ?>
setTimeout("loadHome();",500);
<? } ?>
function loadHome(){
	nHomePage = "<?php echo $nSuccessURL?>";
	window.location = nHomePage;
}
//-->
</script>
</head>

<body>

<? if($nUpgradingNow){ ?>
<BR><BR><BR><BR><BR>
<div align="center" class="content">
  Updating software to <strong>version <?php echo $nUpdateVer;?></strong>...<BR><BR>
  <img src="assets/images/loading.gif" alt="" width="42" height="42" border="0">
  <BR><BR><BR>
  Please wait...
</div>
<? } ?>

</body>
</html>

<?php
function nGetFileName($nPath){
	$nPathARRAY = explode("/",$nPath);
	// make a duplicate of the last array item
	$nFileName = $nPathARRAY[count($nPathARRAY)-1];
	return $nFileName;
}

function copyFile($url,$dirname){ 
	if(!$url){ return; }
	@$file = fopen ($url, "rb"); 
	if(!$file){ 
		return false;
	} else { 
		$filename = basename($url);
		$fc = fopen($dirname."$filename", "wb"); 
		while (!feof ($file)){
			$line = fread ($file, 1028);
			fwrite($fc,$line);
		} 
		fclose($fc);
		return true;
	}
}
?>
<?php
/**
* Create a new directory, and the whole path.
* If  the  parent  directory  does  not exists, we will create it, etc.
* @todo - PHP5 mkdir functoin supports recursive, it should be used
* @author baldurien at club-internet dot fr 
* @param string the directory to create
* @param int the mode to apply on the directory
* @return bool return true on success, false else
* @previousNames mkdirs
*/
function makeAll($dir, $mode = 0755, $recursive = true) {
    if( is_null($dir) || $dir === "" ){ return FALSE; }
    if( is_dir($dir) || $dir === "/" ){ return TRUE; }
    if( makeAll(dirname($dir), $mode, $recursive) ){ return mkdir($dir, $mode); }
    return FALSE;
}

/**
 * Copies file or folder from source to destination, it can also do
 * recursive copy by recursively creating the dest file or directory path if it wasn't exist
 * Use cases:
 * - Src:/home/test/file.txt ,Dst:/home/test/b ,Result:/home/test/b -> If source was file copy file.txt name with b as name to destination
 * - Src:/home/test/file.txt ,Dst:/home/test/b/ ,Result:/home/test/b/file.txt -> If source was file Creates b directory if does not exsits and copy file.txt into it
 * - Src:/home/test ,Dst:/home/ ,Result:/home/test/** -> If source was directory copy test directory and all of its content into dest      
 * - Src:/home/test/ ,Dst:/home/ ,Result:/home/**-> if source was direcotry copy its content to dest
 * - Src:/home/test ,Dst:/home/test2 ,Result:/home/test2/** -> if source was directoy copy it and its content to dest with test2 as name
 * - Src:/home/test/ ,Dst:/home/test2 ,Result:->/home/test2/** if source was directoy copy it and its content to dest with test2 as name
 * @todo
 *  - Should have rollback so it can undo the copy when it wasn't completely successful
 *  - It should be possible to turn off auto path creation feature f
 *  - Supporting callback function
 *  - May prevent some issues on shared enviroments : http://us3.php.net/umask
 * @param $source //file or folder
 * @param $dest ///file or folder
 * @param $options //folderPermission,filePermission
 * @return boolean
 */
function smartCopy($source, $dest, $options=array('folderPermission'=>0755,'filePermission'=>0644)){
	global $nDEBUG;
	$result=false;
	//For Cross Platform Compatibility
	if (!isset($options['noTheFirstRun'])) {
		$source=str_replace('\\','/',$source);
		$dest=str_replace('\\','/',$dest);
		$options['noTheFirstRun']=true;
	}
	$source=str_replace('//','/',$source); $dest=str_replace('//','/',$dest);
	if (is_file($source)) {
		if ($dest[strlen($dest)-1]=='/') {
			if (!file_exists($dest)) {
				makeAll($dest,$options['folderPermission'],true);
			}
			$__dest=$dest."/".basename($source);
		} else {
			$__dest=$dest;
		}
		//if (!file_exists($__dest)) { // allow copying over existing files
			if($nDEBUG){ print "*** Copying file '$source' to '$__dest'<BR>"; }
			$result=copy($source, $__dest);
			chmod($__dest,$options['filePermission']);
		//}
	} elseif(is_dir($source)) {
		if ($dest[strlen($dest)-1]=='/') {
			if ($source[strlen($source)-1]=='/') {
				//Copy only contents
			} else {
				//Change parent itself and its contents
				$dest=$dest.basename($source);
				if(substr_count($dest,'/')<20){ // limit to less than 20 nested folders (prevents against endless loops)
					if($nDEBUG){ print "*** Creating directory(a) '$dest'<BR>"; }
					@mkdir($dest);
					chmod($dest,$options['filePermission']);
				}
			}
		} else {
			if ($source[strlen($source)-1]=='/') {
				//Copy parent directory with new name and all its content
				if(!file_exists($dest) && substr_count($dest,'/')<20){ // limit to less than 20 nested folders (prevents against endless loops)
					if($nDEBUG){ print "*** Creating directory(b) '$dest'<BR>"; }
					@mkdir($dest,$options['folderPermission']);
					//chmod($dest,$options['filePermission']); // commented out, was chmod'ing all new folders to filePermission value (e.g. 0644) making them unwritable
				}
			} else {
				//Copy parent directory with new name and all its content
				if(!file_exists($dest) && substr_count($dest,'/')<20){ // limit to less than 20 nested folders (prevents against endless loops)
					if($nDEBUG){ print "*** Creating directory(c) '$dest'<BR>"; }
					@mkdir($dest,$options['folderPermission']);
					//chmod($dest,$options['filePermission']); // commented out, was chmod'ing all new folders to filePermission value (e.g. 0644) making them unwritable
				}
			}
		}
		$dirHandle=opendir($source);
		while($file=readdir($dirHandle)){
			if($file!="." && $file!=".."){
				$__dest=$dest."/".$file;
				$__source=$source."/".$file;
				$__source=str_replace('//','/',$__source); $__dest=str_replace('//','/',$__dest);
				//echo "$__source ||| $__dest<br />";
				if ($__source!=$dest) {
					if($nDEBUG){ print "'$__source' does not equal '$dest', let's call smartCopy again!<BR>"; }
					$result=smartCopy($__source, $__dest, $options);
				}
			}
		}
		closedir($dirHandle);
		
	} else {
		$result=false;
	}
	return $result;
}

// ------------ lixlpixel recursive PHP functions -------------
// recursive_remove_directory( directory to delete, empty )
// expects path to directory and optional TRUE / FALSE to empty
// of course PHP has to have the rights to delete the directory
// you specify and all files and folders inside the directory
// ------------------------------------------------------------

// to use this function to totally remove a directory, write:
// recursive_remove_directory('path/to/directory/to/delete');

// to use this function to empty a directory, write:
// recursive_remove_directory('path/to/full_directory',TRUE);

function recursive_remove_directory($directory, $empty=FALSE){
	// if the path has a slash at the end we remove it here
	if(substr($directory,-1) == '/'){ $directory = substr($directory,0,-1); }
	// if the path is not valid or is not a directory ...
	if(!file_exists($directory) || !is_dir($directory)){ return FALSE; }
	if(!is_readable($directory)){ return FALSE; }
	// open the directory and scan it
	$handle = opendir($directory);
	while (FALSE !== ($item = readdir($handle))){
		// if the filepointer is not the current directory
		// or the parent directory
		if($item != '.' && $item != '..'){
			// we build the new path to delete
			$path = $directory.'/'.$item;
			// if the new path is a directory
			if(is_dir($path)){
				// we call this function with the new path
				recursive_remove_directory($path);
			// if the new path is a file
			} else { unlink($path); }
		}
	}
	// close the directory
	closedir($handle);
	// if the option to empty is not set to true
	if($empty == FALSE){
		// try to delete the now empty directory
		if(!rmdir($directory)){ return FALSE; }
	}
	return TRUE;
}

function parse_mysql_dump($url){
	global $DBName,$Link,$nDEBUG;
	$nDBName = $DBName; // backwards compatibility
	if(!$Link){
		global $nDBHost,$nDBUser,$nDBPass;
		$Link = @mysql_connect($nDBHost,$nDBUser,$nDBPass);
	}
	if($Link){
		$handle = @fopen($url, "r");
		$Query = "";
		while(!feof($handle)){
			$sql_line = fgets($handle);
			if(trim($sql_line) != "" && strpos($sql_line, "--") === false) {
				$Query .= $sql_line;
				if(preg_match("/;\s*$/", $sql_line)){
					mysql_select_db($nDBName);
					if($nDEBUG){ print "*** parse_mysql_dump: (processing...) $Query<BR>"; }
					if($nDEBUG){
						$result = mysql_query($Query, $Link) or die("<b>A fatal MySQL error occured</b>.\n<br />Query: ".$Query."<br />\nError: (".mysql_errno().") ".mysql_error());
					} else {
						$result = mysql_query($Query, $Link);
					}
					if(!$result){ mysql_error(); return 0; }
					$Query = "";
				}
			}
		}
		if($nDEBUG){ print "*** parse_mysql_dump: Finished running DB dump file...<BR>"; }
	} else {
		if($nDEBUG){ print "*** parse_mysql_dump: INVALID Link for database in parse_mysql_dump.<BR>"; }
		return 0;
	}
	return 1;
}

function nDoesTableExist($nTableToCheck){
	global $DBName,$Link;
	$tables = mysql_list_tables($DBName); 
	$num_tables = @mysql_numrows($tables); 
	$i = 0; 
	$exist = 0; 
	while($i < $num_tables) 
	{ 
		$tablename = mysql_tablename($tables, $i); 
		if ($tablename=="$nTableToCheck") $exist=1; 
		$i++; 
	} 
	return $exist;
}

// cleans URL of strange characters, like exploits and injection attacks
// also checks for the presence of this website in the URL, if does not exist, adds it
function nSanitizeURL($nURL){
	global $nFullSitePath;
	if($nURL==$nFullSitePath){ return $nFullSitePath; }
	$nURL = str_ireplace($nFullSitePath,"",$nURL);
	// clean up trailing and leading slashes
	$nURLARRAY = explode("/",$nURL);
	$nURLARRAY = array_filter($nURLARRAY); // clean out empties
	$nURL = implode("/",$nURLARRAY);
	// clean out all strange chars and hack attempts
	$notAllowed = array("<",">","\"","'","(",")","having","insert","select","update","delete","group by","where");
	$nURL = trim(str_ireplace($notAllowed,"",$nURL));
	$nURL ="$nFullSitePath$nURL";
	$nURL = str_replace(" ","",$nURL);
	return $nURL;
}
?>
<?php //require("../inc/db_close.php"); ?>
