<?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 {
	/**
	 *
	 * The host you will connect
	 * @var String
	 */
	private $host;
	/**
	 *
	 * The driver you will use to connect
	 * @var String
	 */
	private $driver;
	/**
	 *
	 * The user you will use to connect to a database
	 * @var String
	 */
	private $user;
	/**
	 *
	 * The password you will use to connect to a database
	 * @var String
	 */
	private $password;
	/**
	 *
	 * The database you will use to connect
	 * @var String
	 */
	private $dbName;
	/**
	 *
	 * String to connect to the database using PDO
	 * @var String
	 */
	private $dsn;

	/**
	 *
	 * Array with the tables of the database
	 * @var Array
	 */
	private $tables = array();

	/**
	 *
	 * Hold the connection
	 * @var ObjectConnection
	 */
	private $handler;
	/**
	 *
	 * Array to hold the errors
	 * @var Array
	 */
	private $error = array();

	/**
	 *
	 * The result string. String with all queries
	 * @var String
	 */
	private $final;

	/**
	 *
	 * The main function
	 * @method DBBackup
	 * @uses Constructor
	 * @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 __construct($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
	 * @example DBBackup::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
	 * @uses Private use
	 */
	private function generate(){
		foreach ($this->tables as $tbl) {
			
			$this->final .= $tbl['create'] . ";\n\n";
			
			$this->final .= $tbl['data']."\n\n\n";
		}
		$this->final .= "\n\n";
	}

	/**
	 *
	 * Connect to a database
	 * @uses Private use
	 */
	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
	 * @uses Private use
	 */
	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
	 * @uses Private use
	 */
	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
	 * @uses Private use
	 */
	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));
				}
				$data .= 'INSERT INTO '. $tableName .' VALUES (\'' . implode('\',\'', $pieces) . '\');'."\n";
			}
			return $data;
		} catch (PDOException $e){
			$this->handler = null;
			$this->error[] = $e->getMessage();
			return false;
		}
	}
}
?>