<?php

/**------------------------------------------------
*
* Rooty, 2018 <rooty@rooty.me>
*
*
* This software is protected by copyright, please
* read the file COPYRIGHT.
* This program is distributed in the hope that it
* will be useful, but without any warranty; without
* even the implied warranty of merchantability or
* fitness for a particular purpose. Please
* read the file LICENCE.
*
* @link www.rooty.me
* @copyright Copyright &copy; 2009-2018, Rooty
* @author Rooty <www.rooty.me|rooty@rooty.me>
* @since 2004/09/03
* @version 0.3
* @package package
* @subpackage backup
*/

if ( !defined('SYSTEM_IN') )
{
	//die("Hacking attempt");
}

/**
* Inclusion des dépendance
*/
includePackage("backup/backupdb.php");
includePackage("backup/backupfile.php");

/**
* classe de gestion des backups
* @package package
* @subpackage backup
*/ 

class backup
{
/**
* Création d'un nouveau backup
* @access public
* @param chaine nom du backup
* @return entier clé du paquet
*/
	function createBackup($name){
		$sql="INSERT INTO ".DATA_ACCES_TABLE_PREFIX.DATA_ACCES_PACKAGE_PREFIX."backup(backup_libelle, backup_date) VALUES ('".addslashes($name)."', ".time().")";
		$rs=$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_query($sql);
		return $GLOBALS["SYSTEM_DATABASE_CONN"]->sql_nextid($rs);
	}

/**
*Cette fonction permet de stocher dans la base de données les noms et emplacement des fichiers modifiés 
* @access public
* @param entier id du patch 
* @param chaine nom de l'ancien fichier
* @param chaine nom du nouveau fichier
* @return booleen 
*/ 
	function stockFile($idpatch,$oldname,$newname)
	{
		$sql="INSERT INTO ".DATA_ACCES_TABLE_PREFIX.DATA_ACCES_PACKAGE_PREFIX."backupfile(backupfile_new_name,backupfile_old_name,backup_id) VALUES ('".addslashes($newname)."','".addslashes($oldname)."',".$idpatch.")";
		$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_query($sql);
		return true;    
	}
	
/**
*Cette fonction permet de stocher dans la base de données le nom des BD sauvegardées 
* @access public
* @param entier id du patch 
* @param chaine nom de la base de données
* @return booleen 
*/ 
	function stockDb($idpatch,$nomBD)
	{
		//$prefixe=(!defined("DATA_ACCES_TABLE_PREFIX"))?"": DATA_ACCES_TABLE_PREFIX ;
		$sql="INSERT INTO ".DATA_ACCES_TABLE_PREFIX.DATA_ACCES_PACKAGE_PREFIX."backupbd(backupbd_nom,backup_id) VALUES ('".addslashes($nomBD)."',".$idpatch.")";
		$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_query($sql);
		return true;    
	}
	
/**
*Cette fonction permet de récupérer l'ensembles des patchs appliqués en les ordonnént par date 
* @access public
* @return tableau tableau contenant le nom du patch, la date du pacth, s'il posséde des script(booleen) et s'il posséde un bd(booleen) indexé par le nom du patch 
*/ 
	function getAllPatch()
	{
		$tabresult=array();
		$tabpatch=array();
		
		//Requete permettant de recupérer tous les patchs
		$sql_patch="SELECT * FROM ".DATA_ACCES_TABLE_PREFIX.DATA_ACCES_PACKAGE_PREFIX."backup ORDER BY backup_date DESC";
		$query_patch=$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_query($sql_patch);
		
		if ($GLOBALS["SYSTEM_DATABASE_CONN"]->sql_numrows($query_patch)>0)
		{
			//Création du tableau
			$i=0;
			while ($tabpatch=$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_fetchrow($query_patch))
			{
				$tabresult[$i]["backup_id"]=$tabpatch["backup_id"];
				$tabresult[$i]["backup_nom"]=stripslashes($tabpatch["backup_libelle"]);
				$tabresult[$i]["backup_date"]=$tabpatch["backup_date"];
				
				//On vérifie s'il existe des scripts associés au patch
				$sql_script="SELECT COUNT(new_name) as cpt FROM ".DATA_ACCES_TABLE_PREFIX.DATA_ACCES_PACKAGE_PREFIX."backupfile WHERE backup_id=".$tabpatch["backup_id"];
				$result_script=$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_query($sql_script);
				$tab=$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_fetchrow();

				if ($tab["cpt"]>0)
				{
					$tabresult[$i]["script"]=true;
				}
				else
				{
					$tabresult[$i]["script"]=false;
				}

				//On vérifie s'il existe des sauvegardes de bd associées au patch 
				$sql_db="SELECT COUNT(nom_bd) as cpt FROM ".$prefixe."backupbd WHERE backup_id=".$tabpatch["backup_id"];
				$result_db=$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_query($sql_db);
				$tab=$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_fetchrow();

				if ($tab["cpt"]>0)
				{
					$tabresult[$i]["db"]=true;
				}
				else
				{
					$tabresult[$i]["db"]=false;
				}

				$i++;
			}
			$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_freeresult($query_patch);	
		}
		return $tabresult;
	}
	
/**
*Cette fonction recupére la liste de tous les fichiers de scripts altérés 
* @access public
* @param chaine nom du patch 
* @return tableau tableau contenant la liste des scripts associés au patch passé en paramètre indexé par leur id
*/
	function getAllScriptArchiveForPatch($id)
	{
		$tabresult=array();
		$tabpatch=array();
		$i=0;
		
		//Requete permettant de recupérer tous les patchs
		$sql_patch="SELECT backupfile_id,backupfile_new_name,backupfile_old_name,backup_id FROM ".DATA_ACCES_TABLE_PREFIX.DATA_ACCES_PACKAGE_PREFIX."backupfile WHERE "; 
		$sql_patch.="backup_id=".$id;
		$query_patch=$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_query($sql_patch);
		
		if ($GLOBALS["SYSTEM_DATABASE_CONN"]->sql_numrows()>0)
		{
			//Création du tableau
			while ($tabpatch=$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_fetchrow($query_patch))
			{
				$tabresult[$i]["newname"]=stripslashes($tabpatch["backupfile_new_name"]);
				$tabresult[$i]["oldname"]=stripslashes($tabpatch["backupfile_old_name"]);
				$tabresult[$i]["id"]=$tabpatch["backup_id"];
				$i++;
			}
			$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_freeresult();   
		}
		else
		{
			echo "Il n'existe pas d'enregistrement correspondant au libelle passé en paramètre!";
		}
		return $tabresult;
	}

/**
*Cette fonction recupére un script altéré  depuis son id
* @access public
* @param chaine nom du patch 
* @return tableau tableau contenant les données du script altéré
*/
	function getScriptArchiveFromId($id)
	{
		$tabresult=array();
		$tabpatch=array();
		$i=0;
		
		//Requete permettant de recupérer tous les patchs
		$sql_patch="SELECT backupfile_id,backupfile_new_name,backupfile_old_name,backup_id FROM ".DATA_ACCES_TABLE_PREFIX.DATA_ACCES_PACKAGE_PREFIX."backupfile WHERE "; 
		$sql_patch.="id=".$id;
		$query_patch=$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_query($sql_patch);
		
		if ($GLOBALS["SYSTEM_DATABASE_CONN"]->sql_numrows()>0)
		{
			//Création du tableau
			while ($tabpatch=$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_fetchrow($query_patch))
			{
				$tabresult["newname"]=stripslashes($tabpatch["backupfile_new_name"]);
				$tabresult["oldname"]=stripslashes($tabpatch["backupfile_old_name"]);
				$tabresult["id"]=$tabpatch["backup_id"];
				$i++;
			}
			$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_freeresult();   
		}
		else
		{
			return false;
		}
		return $tabresult;
	}

/**
*Cette fonction recupére la liste de tous les fichiers de scripts altérés 
* @access public
* @param entier id
* @return tableau tableau contenant la liste de tous les fichiers BD associés au patch passé en paramètre indexé par leur id
*/
	function getAllDbArchiveForPatch($id)
	{
		$tabresult=array();
		$tabpatch=array();
		$i=0;
		
		//Requete permettant de recupérer tous les patchs
		$sql_patch="SELECT backupbd_id,backupbd_nom,backup_id FROM ".DATA_ACCES_TABLE_PREFIX.DATA_ACCES_PACKAGE_PREFIX."backupbd WHERE "; 
		$sql_patch.="backup_id=".$id;
		$query_patch=$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_query($sql_patch);
		
		if ($GLOBALS["SYSTEM_DATABASE_CONN"]->sql_numrows()>0)
		{
			//Création du tableau
			while ($tabpatch=$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_fetchrow($query_patch))
			{
				$tabresult[$i]["nom"]=stripslashes($tabpatch["backupbd_nom"]);
				$tabresult[$i]["id"]=$tabpatch["backup_id"];
				$i++;
			}
			$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_freeresult();   
		}
		return $tabresult;
	}

/**
*Cette fonction recupére une sauvegarde de bd depuis son Id
* @access public
* @param entier id
* @return tableau tableau contenant les données de la sauvegarde BD
*/
	function getDbArchiveFromId($id)
	{
		$tabresult=array();
		$tabpatch=array();
		$i=0;

		//Requete permettant de recupérer tous les patchs
		$sql_patch="SELECT backupbd_id,backupbd_nom,backup_id FROM ".DATA_ACCES_TABLE_PREFIX.DATA_ACCES_PACKAGE_PREFIX."backupbd WHERE "; 
		$sql_patch.="backup_id=".$id;
		$query_patch=$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_query($sql_patch);
		
		if ($GLOBALS["SYSTEM_DATABASE_CONN"]->sql_numrows()>0)
		{
			//Création du tableau
			while ($tabpatch=$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_fetchrow($query_patch))
			{
				$tabresult["nom"]=stripslashes($tabpatch["backupbd_nom"]);
				$tabresult["id"]=$tabpatch["backup_id"];
				$i++;
			}
			$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_freeresult();   
		}
		return $tabresult;
	}
	
/**
*Cette fonction permet de supprimer les enregistrements associés au patch dont l'id est passé en paramétre 
* @access public
* @param entier id du patch
* @return booleen 
*/
	function deleteBackup($id)
	{
		//Requete permettant de supprimer le backup associés a l'id ainsi que les enregistrements associés dans les autres tables
		$sql_patch="DELETE FROM ".DATA_ACCES_TABLE_PREFIX.DATA_ACCES_PACKAGE_PREFIX."backup WHERE backup_id=".$id;
		$sql_file="DELETE FROM ".DATA_ACCES_TABLE_PREFIX.DATA_ACCES_PACKAGE_PREFIX."backupfile WHERE backup_id=".$id;
		$sql_bd="DELETE FROM ".DATA_ACCES_TABLE_PREFIX.DATA_ACCES_PACKAGE_PREFIX."backupbd WHERE backup_id=".$id;
		
		$query_patch=$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_query($sql_patch);
		$query_file=$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_query($sql_file);
		$query_bd=$GLOBALS["SYSTEM_DATABASE_CONN"]->sql_query($sql_bd);
	 
		return true;
	}

########################################################################################################
####### APPEL DES METHODES DES CLASSES BackupFile et BackupDB pour être conforme au modéle objet #######
########################################################################################################	

/**
*Liste le contenu d'un répertoire
* @access public
* @param chaine path vers le répertoire à lister
* @return tableau tableau deux dimensions avec chemin+nom de fichier, type de fichier(rep="Directory", fichier="File", other="Inconnu"), nom fichier
*/ 
	function getContentDir($path)
	{
		$backupFile	= new backupFile();
		$tabFile	= array();
		if ($tabFile=$backupFile->getContentDir($path))
		{
			return $tabFile;
		}
		else
		{
			return false;
		}
	}



/**
* Vérifie la configuration des droits systéme (droit php && utilisateur)
* retourne faux si les fichiers uploadés ne sont pas accessibles via php sinon int pour les droits à passer en chmod!!!
* @return entier droits a affecter aux fichiers && faux si inaccessibles
*/
	function checkConfigForPerms()
	{
		$backupFile	= new backupFile();
		
		if ($retour=$backupFile->checkConfigForPerms())
		{
			return $retour;
		}
		else
		{
			return false;
		}
	}



/**
* crée une copie de chaque fichier depuis tabIni dans son repertoire.
* retourne un tableau au format:
* - oldname : nom d'origine
* - newname : nom du fichier bkp
* - success : si l'opération à réussi.
* @param entier clé du backup
* @param tableau au format de backupFile array(fichier_src=>array(0=>fichier_destination,1=>booleen (src existe ou pas)))
* @return tableau tableau des fichiers copiès ou faux si une erreur survient
*/
	function bkpFileFromTab($backupId, $tabini)
	{
		$backupFile	= new backupFile();
		$tabCopy=array();
		$tabbkpfic=array();
		# Backup des fichiers...
		if (count($tabini)>0){
			foreach ($tabini as $key=>$val)
			{
				//Backup nécessaire
				$tabCopy=$backupFile->copy($tabini[$key][0], ".bkp".$backupId);
				if ( ($tabCopy===false) || ($tabCopy["success"]===true))
				{
					$this->stockFile($backupId, $tabCopy["oldname"], $tabCopy["newname"]);
					$tabbkpfic=array_merge($tabbkpfic,array($tabCopy));
				}
				// si le fichier source n'existe pas, pas besoin de le renome -> pas d'erreur...
				else{
					return false;
				}
			}
		}
		return $tabbkpfic;
	}

/**
*Cette fonction charge un fichier ini, qui indique ou copier les fichier dans l'arbo granilim
*Le fichier .ini doit etre strucuturé comme suit:
*[source]
*testsource="./test/testdestination/"
* @access public
* @param chaine path vers le fichier ini
* @param entier valeur du umask
* @return tableau tableau d'état des fichier copier avec les paths sources et destinations et le status de la copie (true or false)
*/
	function copyFileFromTab($tabini, $installName, $chmod)
	{
		$backupFile	= new backupFile();
		$tabfilecopie	= array();
		
		if ($tabfilecopie=$backupFile->copyFileFromTab($tabini, $installName, $chmod))
		{
			return $tabfilecopie;
		}
		else
		{
			return false;
		}
	}

/**
*Fonction qui verifie que les fichiers distants existent, et si ils existent qu'on a les droits pour les écraser.
* @access public
* @param tableau type tableau renvoyé par ParcoursIniTab
* @return tableau tableau contenant le path vers le fichier dont on veut vérifier les perms, et l'état de la permission testée (true or false)
*/
	function verifFilePermFromTab($tab, $chmod)
	{
		$tabresult	= array();
		$backupFile	= new backupFile();
		if ($tabresult=$backupFile->verifFilePermFromTab($tab, $chmod))
		{
			return $tabresult;
		}
		else
		{
			return false;
		}
		
	}

/**
* Fonction qui parcours le fichier .ini et verifie l'existence des fichiers sources
* @access public
* @param chaine path vers le fichier ini
* @return tableau tableau assosiatif du contenu du fichier .ini
*/
	function parcoursInitoTab($PathIni, $path="./", $chmod)
	{
		$tabresult	= array();
		$backupFile	= new backupFile();
		
		if ($tabresult=$backupFile->parcoursInitoTab($PathIni,$path,$chmod))
		{
			return $tabresult;
		}
		else
		{
			return false;
		}
		
	}

/**
*Supprime un répertoire
*Utilisation de la récursivité pour supprimé les sous-répertoire du répertoire racine passé en paramétre
*Retourne TRUE si suppression reussie, retourne FALSE si un répertoire n'est pas vide
* @access public
* @param chaine path vers le répertoire a supprimer
* @return booleen
*/
	function eraseDir($sourcepath)
	{
		$backupfile= new backupfile();
		if ($backupfile->EraseDir($sourcepath))
		{
			return True;
		}
		else
		{
			return False;
		}
	}

/**
* crée une sauvegarde intégrale de la Base
* retourne un tableau au format:
* - oldname : nom d'origine
* - newname : nom du fichier bkp
* - success : si l'opération à réussi.
* @param entier clé du backup
* @param tableau au format de backupFile array(fichier_src=>array(0=>fichier_destination,1=>booleen (src existe ou pas)))
* @return tableau tableau des fichiers copiès ou faux si une erreur survient
*/
	function bkpDbFromTab($backupId, $installName, $chmod="")
	{
		$backupDB = new backupDb();

		# Backup de la DB
		if (!$backupDB->createBackupDb($GLOBALS["CONF_DATA_PATH"]."data/backup/", $installName."-".$backupId.".sql"))
		{
			return "InvalidBackupDb";
		}else{
			if ($chmod!="")
				@chmod(($GLOBALS["CONF_DATA_PATH"]."data/backup/".$installName."-".$backupId.".sql"), $chmod);
			$this->stockDb($backupId, $installName."-".$backupId.".sql");
		}
	}

/**
* Restoration d'une sauvegarde DB dans la base courante!!
* Le type de la base est défini dans conf/conf.data_source.php<br/>
* Utilisation:<br/>
* $var=BackupDbFactory::createBackup("data/", "test.sql");
* @param chaine host
* @param chaine login
* @param chaine password
* @param chaine chemin de sauvgarde
* @param chaine nom du fichier de sauvegarde
* @param chaine nom de la base de données
* @return booleen
*/
	function restoreBackUpDb($chemin,$nom_fichier)
	{
		$backupDB = new backupDb();

		# Restore un backup de la DB			
		if ($backupDB->RestoreBackupDb($chemin,$nom_fichier))
		{
			return true;
		}else{
			return "InvalidRestoreDb";
		}
		
	}

##################################################################################################################
####### (FIN)APPEL DES METHODES DES CLASSES BackupFile et BackupDB pour être conforme au modéle objet(FIN) #######
##################################################################################################################
/**
* Renvoie true si la version de la source et supérieure à la version de la destination
* s'il s'agit d'une template renvoie true
* @access public
* @param chaine path vers la source
* @param chaine path vers la destination
* @return booleen 
*/	
	function checkFileVersion($src, $dest)
	{
		if (strstr($dest, $GLOBALS["CONF_DATA_PATH"]."data/") || strstr($dest, $GLOBALS["CONF_LOG_PATH"]."log/") ) 
		{
			//Copie autorisée
			return true;    
		}
		elseif (file_exists($src) && file_exists($dest))
		{
			if (($this->getFileVersion($src)) > ($this->getFileVersion($dest)))
			{
				//Copie autorisée
				return true;    
			}
		}
		elseif (!file_exists($dest))
		{
			//Si la destination n'existe pas copie autorisée
			return true;
		}
		else
		{
			//Pas de copie fichier version destination supérieure à version source ou path fichier source invalide
			return false;
		}
	}

/**
* vérification de la version d'un fichier...
* Lecture du fichier jusqu'a trouver le tag "version"
* @param chaine path vers le fichier dont on veut connaitre la version
* @return float version du fichier sinon False
*/
	function getFileVersion($pathFile)
	{
		//On utilise la lib file pour les accés aux fichiers
		if (file_exists($pathFile)) 
		{
			//On vérifie également que le fichier passé en paramétre n'est pas un fichier image.
			$pos=strrpos($pathFile,".");
			$ext=substr($pathFile,$pos);
			
			if ($ext <> ".jpg" || $ext <> ".png" || $ext <> ".gif" || $ext <> ".bmp" || $ext <> ".mxt")
			{
				//Lecture du fichier et retour de la version
				$fic=new File($pathFile);
				$nbligne=$fic->lines();
				for($i=0;$i<$nbligne;$i++)
				{
					$line=$fic->lineRead($i);
					//On quitte aprés avoir trouvé le tag "phpdocumentor" correspondant a la version
					if (strstr($line,"@version"))
					{
						break;
					}
				}
				$pos=strpos($line,"n")+1;
				$vers=substr($line,$pos);
				
				//On retourne la version
				return floatval($vers);
			}
		}
		else
		{
			//Le fichier n'existe pas
			return false;
		}
		
	}

/**
*Cette fonction restore un patch (fichier et base en fonction des options sélectionnés). 
* @access public
* @param chaine nom du patch a restorer
* @param booleen précise si la restauration des scripts doit s'effectuer ou pas
* @param booleen précise si la restauration des bd doit s'effectuer ou pas
* @return tableau tableau contenant la liste de tous les fichiers BD associés au patch passé en paramètre 
*/
/*	function restorePatch($nom, $script, $db)
	{
	
	}
	*/
}
?>
