<?php
class install {
	public function __construct() {}
	
	/***
	 * 检查GD库
	 */
	public function checkGD() {
		if(!function_exists('phpinfo')) {
			if(function_exists('imagecreate')) {
				return '2.0';
			} else {
				return 0;
			}
		} else {
			ob_start();
			phpinfo(8);
			$module_info = ob_get_contents();
			ob_end_clean();
			if(preg_match("/\bgd\s+version\b[^\d\n\r]+?([\d\.]+)/i", $module_info, $matches)) {
				$gdversion_h = $matches[1];
			} else {
				$gdversion_h = 0;
			}
			return $gdversion_h;
		}
	}
	
	/***
	 * 检查系统目录权限
	 */
	public function checkAuthority($root, $path) {
		$rootlen = strlen(dirname(dirname(__FILE__)));
		if(is_array($path)) {
			foreach($path as $key => $value) {
				if(is_int($key)) {
					$result[substr($root.$value, $rootlen)] = $this->checkPath($root.$value);
				} else {
					$return = $this->checkAuthority($root.$key.DIRECTORY_SEPARATOR, $value);
					foreach($return as $key2 => $value2) {
						$result[$key2] = $value2;
					}
					$result[substr($root.$key, $rootlen)] = $this->checkPath($root.$key);
				}
			}
		} else {
			$result[substr($root.$path, $rootlen)] = $this->checkPath($root.$path);
		}
		return $result;
	}
	
	/***
	 * 初始化数据库
	 */
	public function initDb() {
		if(isset($_POST['cb_newDatabase'])) {
			if($_POST['sql_password'] != $_POST['sql_confirmPassword']) {
				return 'alert("两次密码输入不一致！请重新填写！");';
			} elseif(!isset($_POST['sql_managerpassword']{0})) {
				return 'alert("数据库管理员的密码不能为空！请重新填写！");';
			} elseif(!$this->checkDbManagerInfo()) {
				return 'alert("数据库管理员密码错误，或者没有建库权限！");';
			} elseif($_POST['sql_username'] == 'root') {
				return 'alert("不能创建数据库用户，root为MySQL初始用户！");';
			} elseif($this->checkDbUserConnection()) {
				return 'alert("不能创建数据库用户，已存在该用户！");';
			} elseif($this->checkDbExistsByManager() && $_POST['dbcover'] == 'false') {
				return 'if(confirm("指定数据库已存在，是否继续并覆盖？")) { $("#dbcover").val("true"); $("#form_sql").submit(); }';
			} else {
				if(!$this->checkDbUserInfo()) {
					if(!$this->createDbUser()) {
						return 'alert("创建数据库登录用户失败，管理员密码填写错误！");';
					}
				}
				if($this->checkDbExistsByManager()) {
					if(!$this->deleteDb()) {
						return 'alert("删除数据库失败，请检查数据库管理员权限！");';
					}
				}
				if(!$this->createDb()) {
					return 'alert("创建数据库失败，管理员帐号密码填写错误！");';
				}
			}
		} else {
			if(!$this->checkDbUserInfo()) {
				return 'alert("数据库服务器或用户名或者密码错误！请重新填写！");';
			}
			if(!$this->checkDbExists()) {
				return 'alert("数据库不存在！请重新填写；或者选择自动创建数据库！");';
			}
		}
		$this->editDbConfig($_POST['sql_ip'], $_POST['sql_username'], $_POST['sql_password'], $_POST['sql_name']);
		$return = $this->import(MY_ROOT.'sql'.DIRECTORY_SEPARATOR.'table_struct.sql');
		if($return !== TRUE) {
			return 'alert("'.var_dump($return).'");';
		}
		$this->import(MY_ROOT.'sql'.DIRECTORY_SEPARATOR.'type_data.sql');
		$this->import(MY_ROOT.'sql'.DIRECTORY_SEPARATOR.'about_data.sql');
		return TRUE;
	}
	
	/***
	 * 初始化管理员
	 */
	public function initAdmin() {
		global $MyDB;
		$link = mysql_connect($MyDB['hostname'], $MyDB['username'], $MyDB['password']);
		mysql_select_db($MyDB['dbname'], $link);
		mysql_query('SET NAMES '.$MyDB['charset'], $link);
		
		if(isset($_POST['adminName']{0}) && isset($_POST['adminPassword']{0})) {
			
			if(mysql_query("INSERT INTO `{$MyDB['dbprefix']}admin`(`id`,`account`,`password`,`name`,`phone`,`qq`,`date`,`sex`,`email`,`address`,`remark`,`status`) VALUES('1','{$_POST['adminName']}','{$_POST['adminPassword']}','系统管理员','','',NOW(),'男','','','','已激活')", $link)) {
				return TRUE;
			} elseif(mysql_query("UPDATE `{$MyDB['dbprefix']}admin` SET `account`='{$_POST['adminName']}',`password`='{$_POST['adminPassword']}',`name`='系统管理员',`date`=NOW(),`sex`='男',`status`='已激活' WHERE `id`=1", $link)) {
				return TRUE;
			} else {
				return 'alert("添加管理员失败！请检查数据库权限！");';
			}
		} else {
			return 'alert("管理员帐号和密码不能为空！");';
		}
	}
	
	/***
	 * 获取管理员
	 */
	public function getAdmin() {
		global $MyDB;
		$link = mysql_connect($MyDB['hostname'], $MyDB['username'], $MyDB['password']);
		mysql_select_db($MyDB['dbname'], $link);
		mysql_query('SET NAMES '.$MyDB['charset'], $link);
		$result = mysql_query("SELECT `account`,`password` FROM `{$MyDB['dbprefix']}admin` WHERE `id`=1", $link);
		return mysql_fetch_array($result);
	}
	
	private function import($sqlfile) {
		if(file_exists($sqlfile)) {
			include MY_DATADIR.'Config'.DIRECTORY_SEPARATOR.'database.config.php';
			$sql = file($sqlfile);
			
			$link = mysql_connect($MyDB['hostname'], $MyDB['username'], $MyDB['password']);
			mysql_select_db($MyDB['dbname'], $link);
			mysql_query('SET NAMES '.$MyDB['charset'], $link);
			
			foreach($sql as $key => $value) { // 遍历，删除注释
				$flag = mb_substr($value, 0, 2, 'utf-8'); // 去前两位字符
				if($flag == '--') { // 判断是否为注释
					$sql[$key] = ''; // 删除
				}
			}
			$sql = implode('', $sql); // 转换为字符串
			$sql = trim($sql);
			$sql = str_replace('{$dbprefix}', $MyDB['dbprefix'], $sql);
			if(strpos($sql, '$$') !== FALSE) {
				$sql = explode('$$', $sql); // 转换为数组
			} else {
				$sql = explode(';', $sql); // 转换为数组
			}
			$sql = array_filter($sql, array(self, 'myFilter'));
			
			foreach($sql as $value) { // 遍历执行
				mysql_query($value, $link);
				$errno = mysql_errno($link);
				if($errno > 0) {
					return $errno;
				}
			}
			return TRUE;
		} else {
			return '找不到'.substr($sqlfile, strrpos($sqlfile, DIRECTORY_SEPARATOR) + 1).'文件，请检查安装文件是否完整！';
		}
	}
	
	private function myFilter($value) {
		if(isset($value{0}) && strpos(trim($value), 'DELIMITER') !== 0) {
			return TRUE;
		}
		return FALSE;
	}
	
	/***
	 * 将用户填写的数据库信息写入配置文件
	 * dbpath: 数据库地址
	 * dbuser: 数据库账号
	 * dbpassword: 数据库账号密码
	 * dbname: 数据库名
	 */
	private function editDbConfig($dbpath, $dbuser, $dbpassword, $dbname) {
		$configPath = MY_DATADIR.'Config'.DIRECTORY_SEPARATOR.'database.config.php';
		$config = "<?php
!defined('IN_MY') && exit('Access Denied!');
// 数据库设置
\$MyDB['hostname'] = '$dbpath';   // 数据库主机地址 冒号后面是端口
\$MyDB['username'] = '$dbuser';             // 数据库连接账户名
\$MyDB['password'] = '$dbpassword';         // 数据库连接密码
\$MyDB['dbname'] = '$dbname';                // 数据库名
\$MyDB['dbprefix'] = 'my_';               // 数据表前缀
\$MyDB['charset'] = 'utf8';              // SET NAMES 编码
\$MyDB['pconnect'] = FALSE;              // 是否打开长连接
\$MyDB['dbdriver'] = 'MySQL';            // 数据库类型 可以为 MySQl  MySQLi
\$MyDB['resulttype'] = MYSQL_ASSOC;      // 获取结果值的方式
?>";
		$file = fopen($configPath, 'wb');
		fwrite($file, $config);
		fclose($file);
	}
	
	/***
	 * 测试用户填写的数据库账号和密码是否正确
	 */
	private function checkDbUserInfo() {
		if(@mysql_connect($_POST['sql_ip'], $_POST['sql_username'], $_POST['sql_password'])) {
			return TRUE;
		} else {
			return FALSE;
		}
	}
	
	/***
	 * 创建数据库登录用户
	 */
	private function createDbUser() {
		$link = mysql_connect($_POST['sql_ip'], $_POST['sql_manager'], $_POST['sql_managerpassword']);
		if(mysql_query('GRANT ALL ON `'.$_POST['sql_name'].'`.* TO '.$_POST['sql_username'].'@localhost IDENTIFIED BY \''.$_POST['sql_password'].'\'', $link)) {
			return TRUE;
		} else {
			return FALSE;
		}
	}
	
	/***
	 * 检测数据库是否存在
	 */
	private function checkDbExists() {
		$link = mysql_connect($_POST['sql_ip'], $_POST['sql_username'], $_POST['sql_password']);
		if(mysql_select_db($_POST['sql_name'], $link)) {
			return TRUE;
		} else {
			return FALSE;
		}
	}
	
	/***
	 * 用数据库管理员的账号检测数据库是否存在
	 */
	private function checkDbExistsByManager() {
		$link = mysql_connect($_POST['sql_ip'], $_POST['sql_manager'], $_POST['sql_managerpassword']);
		if(mysql_select_db($_POST['sql_name'], $link)) {
			return TRUE;
		} else {
			return FALSE;
		}
	}
	
	/***
	 * 创建数据库
	 */
	private function createDb() {
		$link = mysql_connect($_POST['sql_ip'], $_POST['sql_manager'], $_POST['sql_managerpassword']);
		if(mysql_query('CREATE DATABASE `'.$_POST['sql_name'].'`', $link)) {
			return TRUE;
		} else {
			return FALSE;
		}
	}
	
	/***
	 * 删除数据库
	 */
	private function deleteDb() {
		$link = mysql_connect($_POST['sql_ip'], $_POST['sql_manager'], $_POST['sql_managerpassword']);
		if(mysql_query('DROP DATABASE `'.$_POST['sql_name'].'`', $link)) {
			return TRUE;
		} else {
			return FALSE;
		}
	}
	
	/***
	 * 检查数据库管理员的账号信息
	 */
	private function checkDbManagerInfo() {
		$link = mysql_connect($_POST['sql_ip'], $_POST['sql_manager'], $_POST['sql_managerpassword']);
		if(mysql_query('CREATE DATABASE `bookingecms_test`', $link)) {
			if(mysql_query('DROP DATABASE `bookingecms_test`', $link)) {
				return TRUE;
			} else {
				return FALSE;
			}
		} else {
			return FALSE;
		}
	}

	/***
	 * 检查数据库用户是否存在
	 */
	private function checkDbUserConnection() {
		$link = mysql_connect($_POST['sql_ip'], $_POST['sql_manager'], $_POST['sql_managerpassword']);
		mysql_select_db('mysql', $link);
		$result = mysql_query('SELECT * FROM `user` WHERE `user`=\''.$_POST['sql_username'].'\'', $link);
		if(mysql_fetch_array($result)) {
			return TRUE;
		} else {
			return FALSE;
		}
	}
	
	/***
	 * 检查文件或目录权限
	 * path: 文件或目录路径
	 */
	private function checkPath($path) {
		// 如果不存在，则不可读、不可写、不可改
		if(!file_exists($path)) {
			$state = -1;
		} else {
			$state = 0;
			if(strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
				// 测试文件
				$test_file = $path.DIRECTORY_SEPARATOR.'test.txt';
				if(is_dir($path)) { // 如果是目录
					// 检查目录是否可读
					$dir = @opendir($path);
					if($dir === FALSE) {
						$state = -1; // 如果目录打开失败,直接返回目录不可修改、不可写、不可读
					} else {
						if(@readdir($dir) !== FALSE) {
							$state ^= 1; // 目录可读001,目录不可读000
						}
						@closedir($dir);
						// 检查目录是否可写
						$fp = @fopen($test_file, 'wb');
						if($fp === FALSE) {
							return $state; // 如果目录中的文件创建失败,返回不可写
						}
						if(@fwrite($fp, 'directory access testing.') !== FALSE) {
							$state ^= 2; // 目录可写可读011,目录可写不可读010
						}
						@fclose($fp);
						@unlink($test_file);
						// 检查目录是否可修改
						$fp = @fopen($test_file, 'ab+');
						if($fp === FALSE) {
							return $state;
						}
						if(@fwrite($fp, "modify test.\r\n") !== FALSE) {
							$state ^= 4;
						}
						@fclose($fp);
						// 检查目录下是否有执行rename()函数的权限
						if(@rename($test_file, $test_file) !== FALSE) {
							$state ^= 8;
						}
						@unlink($test_file);
					}
				} elseif(is_file($path)) { // 如果是文件
					// 以读方式打开
					$fp = @fopen($path, 'rb');
					if($fp) {
						$state ^= 1; // 可读001
					}
					@fclose($fp);
					// 试着修改文件
					$fp = @fopen($path, 'ab+');
					if($fp && @fwrite($fp, '') !== FALSE) {
						$state ^= 6; // 可修改可写可读111,不可修改可写可读011
					}
					@fclose($fp);
					// 检查文件是否有执行rename()函数的权限
					if(@rename($path, $path) !== FALSE) {
						$state ^= 8;
					}
				} else {
					$state = -1;
				}
			} else {
				if(@is_readable($path)) {
					$state ^= 1;
				}
				if(@is_writable($path)) {
					$state ^= 14;
				}
			}
		}
		$info = '';
		switch($state) {
			case -1: $info = '不存在'; $GLOBALS['isError'] = TRUE; break;
			case 0: $info = '没有写入、读取、修改、重命名权限'; $GLOBALS['isError'] = TRUE; break;
			case 1: $info = '没有写入、修改、重命名权限'; $GLOBALS['isError'] = TRUE; break;
			case 2: $info = '没有读取、修改、重命名权限'; $GLOBALS['isError'] = TRUE; break;
			case 3: $info = '没有修改、重命名权限'; $GLOBALS['isError'] = TRUE; break;
			case 4: $info = '没有写入、读取、重命名权限'; $GLOBALS['isError'] = TRUE; break;
			case 5: $info = '没有写入、重命名权限'; $GLOBALS['isError'] = TRUE; break;
			case 6: $info = '没有读取、重命名权限'; $GLOBALS['isError'] = TRUE; break;
			case 7: $info = '没有重命名权限'; $GLOBALS['isError'] = TRUE; break;
			case 8: $info = '没有写入、读取、修改权限'; $GLOBALS['isError'] = TRUE; break;
			case 9: $info = '没有写入、修改权限'; $GLOBALS['isError'] = TRUE; break;
			case 10: $info = '没有读取、修改权限'; $GLOBALS['isError'] = TRUE; break;
			case 11: $info = '没有修改权限'; $GLOBALS['isError'] = TRUE; break;
			case 12: $info = '没有写入、读取权限'; $GLOBALS['isError'] = TRUE; break;
			case 13: $info = '没有写入权限'; $GLOBALS['isError'] = TRUE; break;
			case 14: $info = '没有读取权限'; $GLOBALS['isError'] = TRUE; break;
			case 15: $info = '权限验证通过'; break;
		}
		$result = array(
			'state' => $state,
			'info' => $info,
			'mark' => substr('0000'.decbin($state), strlen(decbin($state)))
		);
		return $result;
	}
}
?>