<?php
/**
 * dbupgrade.php - database upgrade
 *
 * @author $Author: dtong $
 * @version $Id: dbupgrade.php,v 1.3 2011/04/27 05:46:26 dtong Exp $
 * @copyright Copyright (c) 2011, Tiller Software Co., Ltd.
*/

class Dbupgrade extends CI_Controller {
	const TIME_LIMIT = 600;

	public $dir_script = '';
	public $current_version = '';//store db current version.
	public $script = array();//store MySQL script name.
	public $data; //store data use in view page.

	function __construct() {
		parent::__construct();
		$this->access_model->checkaccess_any('admin_system_management');
		osa_load_lang('admin');
		$this->load->model('admin/dbupgrade_model');
		$this->dir_script = FCPATH . 'install/upgrade/db/';
		$this->_init_script();
		$this->data = new stdClass();
		$this->data->admin_dbupgrade_title = lang('admin_dbupgrade_title');
		$this->data->admin_dbupgrade_warn = lang('admin_dbupgrade_warn');
		$this->data->admin_dbupgrade_currentversion = lang('admin_dbupgrade_currentversion');
		$this->data->admin_dbupgrade_listofupgrade = lang('admin_dbupgrade_listofupgrade');
		$this->data->admin_dbupgrade_db_latest = lang('admin_dbupgrade_db_latest');
		//iframe display.
		$this->data->admin_dbupgrade_iframe_headtitle = lang('admin_dbupgrade_iframe_headtitle');
		$this->data->admin_dbupgrade_iframe_text = lang('admin_dbupgrade_iframe_text');
		$this->data->admin_dbupgrade_iframe_title = lang('admin_dbupgrade_iframe_title');
		$this->data->current_ver = $this->current_version;
		osa_php_session_start();
	}

	function index() {
		//if $this->script have data will do upgrade.
		if ( $this->script ) {
			$this->data->script_ver = $this->script;
			$this->load->view('admin/dbupgrade_warning_view', $this->data);
		}
		else {
			$this->load->view('admin/dbupgrade_view', $this->data);
		}
	}

	function upgrade() {
		set_time_limit(self::TIME_LIMIT);
		echo $this->load->view('admin/dbupgrade_upgrading_head_view', $this->data, true);
		$this->flush_buffer();
		//assign for display.
		$current_version = $this->current_version;

		//query newer script.
		foreach ( $this->script as $script_name ){
			$upgrade_version = basename($script_name, '.sql');
			echo lang('admin_dbupgrade_upgraded_from') . " $current_version " . lang('admin_dbupgrade_upgraded_to') .
				  " <span style=\"color:red;\">{$upgrade_version}</span><br/>";
			$this->flush_buffer();
			$sql = osa_next_sql(realpath($this->dir_script.$script_name));
			$count = 0;
			$line = 1;
			while ($sql) {
				//echo $line.' : '.$sql.'<br />';//use for check sql that will query.
				$ret = $this->_todcm_query($sql);

				if ( !$ret ) {
					echo '<br /><br /><div style="color:red;font-size:12px;font-weight:bold">' . lang('admin_dbupgrade_failed_msg1');
					echo "<br /><br />" . lang('admin_dbupgrade_sql') . "$sql<br /><br />" .
							lang('admin_dbupgrade_error_num') . "{$this->dbupgrade_model->error_number}<br /><br />" .
							lang('admin_dbupgrade_error_msg') . "{$this->dbupgrade_model->error_message}<br /><br /><br/>" .
							lang('admin_dbupgrade_failed_msg2');
					echo '</div>';
					echo $this->load->view('admin/dbupgrade_upgrading_foot_view', array('failed_upgrade'=>TRUE), true);
					exit;
				}
				if ( $count > 17 ) {
					echo '<br />';
					$count = 0;
				}
				echo '. . ';
				$this->flush_buffer();
				$sql = osa_next_sql();
				$count++;
				$line++;
			}
			echo '<hr />';
			$this->flush_buffer();
			//change current version to upgraded version for display.
			$current_version = $upgrade_version;
		}
		echo '<br />** ' . lang('admin_dbupgrade_success_msg') . ' **<br />';
		echo $this->load->view('admin/dbupgrade_upgrading_foot_view', '', true);
	}

	/*
	 * get database current version.
	 * get script version by $this->_get_script_version()
	 * return empty if no newer script.
	 */
	private function _init_script() {
		//get database current version.
		$this->current_version = $this->dbupgrade_model->get_current_version();
		$script_version = $this->_get_script_version();
		if( empty($this->current_version) || empty($script_version) || $this->current_version == 'APPLICATION_VERSION_NUMBER' ){
			return FALSE;
		}
		$db_current_version = $this->current_version.'.sql';//need this to correct comparing.
		foreach( $script_version as $script_name ) {
			$use_script = $this->_compare_version($db_current_version, $script_name);
			//collect newer script for upgrade.
			if ( $use_script ) {
				$this->script[] = $script_name;
			}
		}
//		return $this->script;
	}

	// get script name and store in array.
	private function _get_script_version() {
		$script_name = array();
		$dir = $this->dir_script;
		$hand = @opendir($dir);
		if ( empty($hand) ) {
			return FALSE;
		}
		while( $file = @readdir($hand) ) {
			//collect only .sql file name.
			if( strripos($file, '.sql') ) {
				$script_name[] = $file;
			}
		}
		closedir($hand);
		usort($script_name, 'strnatcasecmp');
		return $script_name;
	}

	// compare current database with script version.
	private function _compare_version($current_ver, $script_ver) {
		return (strnatcasecmp($current_ver, $script_ver) < 0);
	}

//from install/db_function.php and change a little code.
	private function _todcm_query($sql) {
		return $this->dbupgrade_model->update_sql(trim($sql));
	}

	private function flush_buffer() {
		ob_end_flush();
   	ob_flush();
    	flush();
   	ob_start();
	}

}