<?php
/**
 *
 * Use this class to do a backup of your database
 * @author Raul Souza Silva (raul.3k@gmail.com)
 * @category Database
 * @copyright No one. You can copy, edit, do anything you want. If you change anything to better, please let me know.
 *
 */
Class DBBackup {
	private $host;					// The host you will connect
	private $driver;				// The driver you will use to connect
	private $user;					// The user you will use to connect to a database
	private $password;				// The password you will use to connect to a database
	private $dbName;				// The database you will use to connect
	private $dsn;					// String to connect to the database using PDO
	private $tables = array();		// Array with the tables of the database
	private $handler;				// Hold the connection
	private $error = array();		// Array to hold the errors
	private $final;					// The result string. String with all queries
	/**
	 * @param Array $args{host, driver, user, password, database}
	 * @example $db = new DBBackup(array('host'=>'my_host', 'driver'=>'bd_type(mysql)', 'user'=>'db_user', 'password'=>'db_password', 'database'=>'db_name'));
	 */
	public function DBBackup($args){
		if(!$args['host']) $this->error[] = 'Parameter host missing';
		if(!$args['user']) $this->error[] = 'Parameter user missing';
		if(!isset($args['password'])) $this->error[] = 'Parameter password missing';
		if(!$args['database']) $this->error[] = 'Parameter database missing';
		if(!$args['driver']) $this->error[] = 'Parameter driver missing';

		if(count($this->error)>0) return;

		$this->host = $args['host'];
		$this->driver = $args['driver'];
		$this->user = $args['user'];
		$this->password = $args['password'];
		$this->dbName = $args['database'];

		//$this->final = 'CREATE DATABASE ' . $this->dbName.";\n\n";

		if($this->host=='localhost'){
			// We have a little issue in unix systems when you set the host as localhost
			$this->host = '127.0.0.1';
		}
		$this->dsn = $this->driver.':host='.$this->host.';dbname='.$this->dbName;
		$this->connect();
		$this->getTables();
		$this->generate();
	}

	// Call this function to get the database backup
	public function backup(){
		//return $this->final;
		if(count($this->error)>0){
			return array('error'=>true, 'msg'=>$this->error);
		}
		return array('error'=>false, 'msg'=>$this->final);
	}

	// Generate backup string
	private function generate(){
		foreach ($this->tables as $tbl) {
			if($tbl['name']!=SYS_LOG_TABLE){
				$this->final .= '-- (RE)CREATING TABLE '.$tbl['name'].";\n";
				$this->final .= 'DROP TABLE IF EXISTS '.$tbl['name'] . ";\n";
				$this->final .= $tbl['create'] . ";\n\n";
				$this->final .= '-- INSERTING DATA INTO '.$tbl['name'].";\n";
				$this->final .= $tbl['data']."\n\n\n";
			}
		}
		$this->final .= '-- THE END'."\n\n";
	}

	// Connect to a database
	private function connect(){
		try {
			$this->handler = new PDO($this->dsn, $this->user, $this->password);
		} catch (PDOException $e) {
			$this->handler = null;
			$this->error[] = $e->getMessage();
			return false;
		}
	}

	// Get the list of tables
	private function getTables(){
		try {
			$stmt = $this->handler->query('SHOW TABLES');
			$tbs = $stmt->fetchAll();
			$i=0;
			foreach($tbs as $table){
				$this->tables[$i]['name'] = $table[0];
				$this->tables[$i]['create'] = $this->getColumns($table[0]);
				$this->tables[$i]['data'] = $this->getData($table[0]);
				$i++;
			}
			unset($stmt);
			unset($tbs);
			unset($i);

			return true;
		} catch (PDOException $e) {
			$this->handler = null;
			$this->error[] = $e->getMessage();
			return false;
		}
	}

	// Get the list of Columns
	private function getColumns($tableName){
		try {
			$stmt = $this->handler->query('SHOW CREATE TABLE '.$tableName);
			$q = $stmt->fetchAll();
			$q[0][1] = preg_replace("/AUTO_INCREMENT=[\w]*./", '', $q[0][1]);
			return $q[0][1];
		} catch (PDOException $e){
			$this->handler = null;
			$this->error[] = $e->getMessage();
			return false;
		}
	}

	// Get the insert data of tables
	private function getData($tableName){
		try {
			$stmt = $this->handler->query('SELECT * FROM '.$tableName);
			$q = $stmt->fetchAll(PDO::FETCH_NUM);
			$data = '';
			foreach ($q as $pieces){
				foreach($pieces as &$value){
					//$value = htmlentities(addslashes($value));		// Original
					// Tenemos que arreglar el fallo que se produce cuando una línea acaba en ";"
					$value = preg_replace("/;[\s]*\r\n/",";", $value);
					$value = (addslashes($value));
					//$value="\xEF\xBB\xBF".$value;
				}
				$data .= 'INSERT INTO '. $tableName .' VALUES (\'' . implode('\',\'', $pieces) . '\');'."\n";
			}
			return $data;
		} catch (PDOException $e){
			$this->handler = null;
			$this->error[] = $e->getMessage();
			return false;
		}
	}
}
?>