#!/usr/bin/php 
<?php
/*+*******************************************************************************
 * Scripts to update elastix 5.1.0 to latest version
 ********************************************************************************/
/* 
 * During migration config.inc.php might not be populated.
 * We will create this instance later based on the configuration file as later binding.
 * Para migrar se necesita el directorio anterior de vtiger ademas de la base anterior
 * en este scrip se usan funciones ya implementadas por vtigercrm para poder completar el
 * proceso de migracion
 * el principal scrip de migracion de vtigercrm 5.2.1 es /vtigercrm/include/install/resources/utils.php
*/


/* 
 * recibe como parametros
 * argv[1] = old_version formato 5.x.x-x , version desde la cual se quiere actualizar
 * argv[2] = new_version formato 5.x.x, version a la que se va a actualizar
 * argv[3] = $root_directory , directorio actual de vtigercrm 
 * argv[4] = $path_base, direccion donde se encuentra el schema del vtiger
 * argv[5] = $db_schema_vtiger, nombre del script sql que contine el esquema de vtiger
 * argv[6] = $sources_directory, ruta donde se encuentra el directorio anterior de vtigercrm, se lo usa para poder migrar
 */


$root_directory=$argv[3]; // /var/www/html/vtigercrm

include("$root_directory/adodb/adodb.inc.php");
require_once("$root_directory/include/utils/utils.php");
require_once("$root_directory/include/logging.php");
$migrationlog = & LoggerManager::getLogger('MIGRATION');
require_once("$root_directory/include/DatabaseUtil.php");
include_once('/var/www/html/libs/misc.lib.php');
require_once("$root_directory/include/install/resources/utils.php");
include("$root_directory/connection.php");

$old_version=get_old_version($argv[1]);
$current_version=get_current_version($argv[2]);
$new_dbname="vtigercrm".$current_version;
$db_schema_vtiger=$argv[5]; //el nombre del schema  ej: schema_vtiger.sql
$path_base=$argv[4]; // donde se encuantra el esquema de la base ej: /usr/share/elastix/module_installer/vtigercrm
$source_directory=$argv[6];

$query_count = 1;
$success_query_count = 1;
$failure_query_count = 1;
$success_query_array = Array();
$failure_query_array = Array();

$log =& LoggerManager::getLogger('PLATFORM');
$completed = false;

//antes de proceder amigragar verificamos que exista el directorio anterior del vtigercrm ($source_directory)
//y dentro de el otros archivos y directorios necesarios 
if(is_dir($source_directory)){
	if(!is_file($source_directory."config.inc.php")){
		echo "no existe config.inc.php, no se puede proceder";	
		restaurarSourceDirectory();	
		exec(exit);
	}
	if(!is_dir($source_directory."user_privileges")){
		echo "no existe direcorio user_privileges, no se puede proceder";		
		restaurarSourceDirectory();	
		exec(exit);

	}
	if(!is_dir($source_directory."storage")){
		echo "no existe direcorio storage, no se puede proceder";		
		restaurarSourceDirectory();	
		exec(exit);

	}
}else{
	echo "no existe direcorio anterior de configuracion, no se puede proceder";
	exit;
}

//obtenemos los parametros de configuracion anteriores de la base del archivo config.inc.php
$configInfo=crearArregloConfig_file_Info();

$dbtype=$configInfo['db_type'];
$db_user=$configInfo['db_username'];
$db_pswd=$configInfo['db_password'];
$db_host='localhost';
$mysql_port='3306';
$old_dbname=$configInfo['old_dbname'];


//se hace esto para obtener la clave de root de mysql
$db_pswd_root = obtenerClaveConocidaMySQL('root', '/var/www/html/');

session_start();

global $conn,$migrationlog;

//se verifica que la clave de root no este vacia
if($db_pswd_root != '')
{
	$password_str = "\"-p$db_pswd_root\""; 
}
else
{
	$password_str = '';
}

if(!ismysqlRunning())
{
	echo "Service mysql is not runnig, please start service mysql and then try to migrate again\n";
	restaurarSourceDirectory();	
	exec(exit);
}


#verificar si existe la base de datos anterior
if(databaseExists($dbtype,$old_dbname) ){
	if(!databaseExists($dbtype,$new_dbname)){
	    Migrate_Database();
	}
	else{
		if($old_dbname != $new_dbname){	
		    	renameDatabase($new_dbname, $password_str, $path_base);
		}
	    Migrate_Database();
	}
}
#si no existe la base de datos anterior, comprobar que no exista la base de datos nueva que se quiere crear
else{
	if(databaseExists($dbtype,$new_dbname)){
		if(renameDatabase($new_dbname, $db_pswd_root, $path_base)){
			echo "Creating Databases ".$new_dbname."\n";
			$command = "mysql -uroot  ".$password_str."< $path_base/$db_schema_vtiger";
            		exec($command,$arrConsole,$status);
            		if($status != 0){
                		echo "Could no create the database $new_dbname\n";
				restaurarSourceDirectory();
                		exec(exit);
			}		
		}
		else{
			echo "Couldn't be updated\n";
			echo "Update Failed!!!\n";
			exec(exit);
		}
	}else{
		echo("Creating Databases ".$new_dbname."\n");
		$command = "mysql -uroot  ".$password_str."< $path_base/$db_schema_vtiger";
            	exec($command,$arrConsole,$status);
            	if($status != 0){
                	echo "Could no create the database $new_dbname\n";
			restaurarSourceDirectory();
                	exec(exit);
            	}
	}
}


//funcion principal usada para migrar, invocas funciones que se encuentran en /vtigercrm/include/install/resources/utils.php
function Migrate_Database(){
	global $migrationlog,$old_version,$current_version,$old_dbname,$new_dbname,$root_directory,$db_schema_vtiger; 
	global $path_base,$dbtype,$db_user,$db_pswd,$db_host,$db_pswd_root,$mysql_port,$password_str;
	
	set_time_limit(0);
	//tomamos un respaldo de la base anterior
	$dump_file=takeDatabaseDump($db_host,'root',$password_str,$old_dbname,$db_user,$db_pswd);
	if(is_file($dump_file) && filesize($dump_file) > 10000)
	{
		echo "Source database dump taken successfully\n";
	}
	else
	{
		echo "Couldn't be made dump, Update FAILED!!\n";
		restaurarSourceDirectory();
		exec(exit);
	}

	//creamos la nueva base que vamos a usar para migrar
	if(!createDatabase($new_dbname,$password_str)){
		echo "\n";
		restaurarSourceDirectory();
		exec(exit);
	}
	else{
		//createUser($new_dbname,$db_user,$db_pswd);
		//usamos el dump de la base anterior para llenar la base que creamos y luego con esa base hacer el proceso de migracion
		if(applyDumpData($db_host,'root',$password_str,$new_dbname,$dump_file)){
			
			repararBase();

			$configFileUtils = new ConfigFile_Utils(crearArregloConfig_file_Info());

			if (!$configFileUtils->createConfigFile()) {
				echo "Couldn't be created Configuration File\n";
				echo "Update Failed!!!\n";				
				restaurarSourceDirectory();
				exec(exit);
			}
			$migrateInfo=crearArregloMIgrateInfo();
			Migration_Utils::copyRequiredFiles($migrateInfo['source_directory'], $migrateInfo['root_directory']);			
				$completed = Migration_Utils::migrate(crearArregloMIgrateInfo());
				
				if ($completed == true) {
					echo "MIGRATION COMPLETED\n";
				}else{
					echo "Couldn't completed NIGRATION\n";
					echo "Update Failed!!!\n";
					restaurarSourceDirectory();
					exec(exit);
				}
		}else{
			echo "DATABASE UPDATE FAILED\n";
			echo "Update Failed!!!\n";
			restaurarSourceDirectory();
			exec(exit);
		}
	}	
}

function get_old_version($version){
	$split = explode("-",$version);
	$ver = $split[0]; 				
	$cadena=str_replace(".","",$ver);
	return $cadena;
}
		
function get_current_version($version){ 				
	$cadena=str_replace(".","",$version);
	return $cadena;
}

function get_array_versions($old_version,$current_version){ 
	global $root_directory;	
	$reach = 0;
	
	include($root_directory."/modules/Migration/versions.php");
	foreach($versions as $version => $label) {
		if($version == $old_version || $reach == 1) {
			$reach = 1;
			$temp[] = $version;
		}
	}
	$temp[] = $current_version;
	return $temp;
}


function takeDatabaseDump($host_name,$mysql_username,$password_str,$dbname,$db_user,$db_pswd){
	global $migrationlog,$new_dbname;
	       $migrationlog->debug("Inside the function takeDatabaseDump($host_name,$mysql_username,$password_str,$dbname,$db_user,$db_pswd). Going to take the specified database dump...");
	
	$dump_filename = $dbname.'dump';

	exec("echo 'USE $new_dbname;' > ".$dump_filename);
	exec("echo \"GRANT ALL PRIVILEGES ON $new_dbname.* TO '$db_user'@'localhost' IDENTIFIED BY '$db_pswd';\" >> ".$dump_filename);
	exec("echo 'set FOREIGN_KEY_CHECKS = 0;' >> ".$dump_filename);
	exec("mysqldump -u".$mysql_username." -h".$host_name." ".$password_str." ".$dbname." >> ".$dump_filename);
	exec("echo 'set FOREIGN_KEY_CHECKS = 1;' >> ".$dump_filename);
	return $dump_filename;
}


function createDatabase($dbname,$password_str){
	global $migrationlog;
	$migrationlog->debug("Going to create the database - $dbname");
	
	$sql = "create database ".$dbname." DEFAULT CHARACTER SET utf8";
	$command = "mysql -uroot ".$password_str." -e '$sql'";
	exec($command,$arrConsole,$status);
	if($status != 0){
                echo "Could no create the database $dbname";
                return false;
	}
	$migrationlog->debug("Database ($dbname) has been create.");
	return true;
}

function applyDumpData($host_name,$mysql_username,$password_str,$dbname,$dumpfile)
{
	global $migrationlog,$root_directory;
	$migrationlog->debug("Inside the function applyDumpData($host_name,$mysql_username,$password_str,$dbname,$dumpfile).");

	exec("mysql -u $mysql_username -h$host_name $password_str < $root_directory/$dumpfile",$arrConsole,$status);

	if($status != 0){
                echo "Could no apply the dumofile $dbname";
                return false;
	}
	$migrationlog->debug("Database Dump has been applied to the $dbname database from $dumpfile");
	return true;
}

function renameDatabase($dbName, $password, $path_folder)
{
    $date = date("YMd_His");
    $dbNewName = $dbName."_$date";
    echo "Database $dbName already exist. Renaming to $dbNewName\n";

    if(ismysqlRunning()){
            $file    = fopen("$path_folder/$dbNewName.dump","w");
            if($file){
                $sql = "CREATE DATABASE IF NOT EXISTS $dbNewName;\nUSE $dbNewName;\n";
                fwrite($file,$sql);
                fclose($file);
            }else{
                echo "Could not create the file $path_folder/$dbNewName.dump The rename action was aborted\n";
                return false;
            }
            $command = "mysqldump -uroot $password $dbName >> $path_folder/$dbNewName.dump";
            exec($command,$arrConsole,$status);
            if($status != 0){
                echo "Could not create a dump file for database $dbName\n";
                return false;
            }
            $command = "mysql -uroot $password < $path_folder/$dbNewName.dump";
            exec($command,$arrConsole,$status);
            if($status != 0){
                echo "Could not rename the database $dbName\n";
                return false;
            }
            $command = "mysql -uroot $password -e 'DROP DATABASE $dbName'";
            exec($command,$arrConsole,$status);
            if($status != 0){
                echo "Could not drop database $dbName\n";
                return false;
            }
            return true;
        }
}

function databaseExists($engine,$dbname)
{
    if($engine == "mysql"){
        return is_dir("/var/lib/mysql/$dbname");
    }
}

function ismysqlRunning()
{
    exec("/sbin/service mysqld status &>/dev/null",$arrConsole,$flagStatus);
    if($flagStatus == 0)
        return true;
    else
        return false;
}

//funcion que se usa para volver a colocar el souces_directory en la ruta /var/www/html/
function restaurarSourceDirectory()
{
	global $source_directory,$root_directory;
	if(is_dir($root_directory) && is_dir($source_directory)){
		$command = "rm -rf $root_directory";
		exec($command,$arrConsole,$status); 
		$command = "mv $source_directory /var/www/html/vtigercrm";
		exec($command,$arrConsole,$status);
		$command = "chown -R asterisk.asterisk /var/www/html/vtigercrm/";
		exec($command,$arrConsole,$status); 	
	}	
}

//si la bases usada para migrar no es UTF8, entonces esta funcion se encarga de solucionar este problema
//el esquema de la implemenacion y las funciones aqui usadas se obtienen de vtigercrm 
function repararBase()
{
	global $old_dbname,$new_dbname,$root_directory,$db_schema_vtiger; 
	global $path_base,$dbtype,$db_user,$db_pswd,$db_host,$db_pswd_root;
	global $mysql_port,$password_str;

	require_once('adodb/adodb.inc.php');

	$db = &NewADOConnection($dbtype);
	$db->NConnect($db_host,'root',$db_pswd_root,$new_dbname);

	require_once('include/utils/DBHealthCheck.php');
	$dbHealthCheck = new DBHealthCheck($db);
	$dbHostName = $dbHealthCheck->dbHostName;
	$dbName = $dbHealthCheck->dbName;

	$updateTableEngine=true;
	$updateEngineForAllTables=true;

	if($updateTableEngine == "true") {
		 if($updateEngineForAllTables == "true") {
		 	$dbHealthCheck->updateAllTablesEngineType();
		 }
	}

	$unHealthyTablesList = $dbHealthCheck->getUnhealthyTablesList();
	$noOfTables = count($unHealthyTablesList);
	if ($noOfTables <= 0) {
		$_SESSION[$dbName.'_'.$dbHostName.'_HealthApproved'] = true;
			echo "TABLE_TYPE_FIXED\n";
	} else {		
		$_SESSION[$dbName.'_'.$dbHostName.'_HealthApproved'] = false;
	}
}

//crea un arregle con los parametros usados para la migracion
function crearArregloMIgrateInfo()
{
	global $old_version,$current_version,$new_dbname,$root_directory,$source_directory; 

	$migration_info['source_directory'] = $source_directory;
	$migration_info['root_directory'] = $root_directory; 
	$migration_info['old_version'] = $old_version;
	$migration_info['new_dbname'] = $new_dbname;
	$migration_info['current_version'] = $current_version;
	$migration_info['selected_optional_modules'] = getOptionalModules();
	return $migration_info;
}

//crea un arreglo con los parametros anteriores de los archivos de ocnfiguracion
//usado para escribir los nuevos archivos de configuracion durante la migracion
function crearArregloConfig_file_Info()
{
	global $old_version,$current_version,$new_dbname,$root_directory,$source_directory; 

	$configInfo = array();
	global $dbconfig,$site_URL,$currency_name;
		require_once($source_directory."config.inc.php");
		$old_db_name = $dbconfig['db_name'];
		$db_hostname = $dbconfig['db_server'].$dbconfig['db_port'];
		$db_username = $dbconfig['db_username'];
		$db_password = $dbconfig['db_password'];
		$db_type = $dbconfig['db_type'];
		
			$configInfo['db_name'] = $new_dbname;
			$configInfo['db_type'] = $db_type;
			$configInfo['db_hostname'] = $db_hostname;
			$configInfo['db_username'] = $db_username;
			$configInfo['db_password'] = $db_password;
			$configInfo['admin_email'] = $HELPDESK_SUPPORT_EMAIL_ID;
			$configInfo['currency_name'] = $currency_name;
			$configInfo['vt_charset'] = "UTF-8";
			$configInfo['site_URL'] = $site_URL;
			$configInfo['root_directory'] = $root_directory;
			$configInfo['old_dbname'] = $old_db_name;
	return $configInfo;
}

/*
durante la migracion el usuario tiene la opcion de escoger que modulos desea implementar
con esta funcion lo que se hace es emular la accion de que el usuario haya seleccionado 
todos los modulos opcionales, para despues procederlos a instalar durante la migracion
*/
function getOptionalModules()
{
	global $old_version;	
	$optionalModules = Migration_Utils::getInstallableOptionalModules($old_version);

	if(count($optionalModules) > 0) {

		foreach($optionalModules as $option=>$modules) {
			if(count($modules) > 0) { 								
				foreach($modules as $moduleName=>$moduleDetails) { 
					$moduleDescription = $moduleDetails['description'];
					$moduleSelected = $moduleDetails['selected'];
					$moduleEnabled = $moduleDetails['enabled'];
					$selectedOptionalModuleNames[] = $moduleName;
				}
			}
		}	
	}
	return implode(":",$selectedOptionalModuleNames);
}


?>
