<?php
class core{
	public static function start() {
		devmode::init();
		self::ob_start();
		self::init_set();
		self::init_get();
		self::init_control();
	}
	public static function ob_start() {
		ob_start(array('core', 'ob_gzip'));
	}
	public static function ob_gzip($s) {
		$gzip = $_ENV['_config']['gzip'];
		$isfirst = empty($_ENV['_isgzip']);
		if($gzip) {
			if(function_exists('ini_get') && ini_get('zlib.output_compression')) {
				$isfirst && header("Content-Encoding: gzip");
			}elseif(function_exists('gzencode') && strpos($_SERVER["HTTP_ACCEPT_ENCODING"], 'gzip') !== FALSE) {
				$s = gzencode($s, 5);
				if($isfirst) {
					header("Content-Encoding: gzip");
				}
			}
		}elseif($isfirst) {
			header("Content-Encoding: none");
		}
		$isfirst && $_ENV['_isgzip'] = 1;
		return $s;
	}
	public static function ob_clean() {
		!empty($_ENV['_isgzip']) && ob_clean();
	}
	public static function ob_end_clean() {
		!empty($_ENV['_isgzip']) && ob_end_clean();
	}
	public static function init_set() {
		date_default_timezone_set($_ENV['_config']['zone']);
		spl_autoload_register(array('core', 'autoload_handler'));
		if(get_magic_quotes_gpc()) {
			_stripslashes($_GET);
			_stripslashes($_POST);
			_stripslashes($_COOKIE);
		}
		$_ENV['_include'] = array();
		$_ENV['_time'] = isset($_SERVER['REQUEST_TIME']) ? $_SERVER['REQUEST_TIME'] : time();
		$_ENV['_ip'] = ip();
		$_ENV['_sqlnum'] = 0;
		if(!isset($_SERVER['REQUEST_URI'])) {
			if(isset($_SERVER['HTTP_X_REWRITE_URL'])) {
				$_SERVER['REQUEST_URI'] = &$_SERVER['HTTP_X_REWRITE_URL'];
			}else{
				$_SERVER['REQUEST_URI'] = '';
				$_SERVER['REQUEST_URI'] .= $_SERVER['REQUEST_URI'];
				$_SERVER['REQUEST_URI'] .= isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '';
				$_SERVER['REQUEST_URI'] .= empty($_SERVER['QUERY_STRING']) ? '' : '?'.$_SERVER['QUERY_STRING'];
			}
		}
		header("Expires: 0");
		header("Cache-Control: private, post-check=0, pre-check=0, max-age=0");
		header("Pragma: no-cache");
		header('Content-Type: text/html; charset=UTF-8');
	}
	public static function autoload_handler($classname) {
		if(substr($classname, 0, 3) == 'db_') {
			include FINE_PATH.'db/'.$classname.'.class.php';
		}elseif(substr($classname, 0, 6) == 'cache_') {
			include FINE_PATH.'cache/'.$classname.'.class.php';
		}elseif(is_file(FINE_PATH.'ext/'.$classname.'.class.php')) {
			include FINE_PATH.'ext/'.$classname.'.class.php';
		}else{
			throw new Exception("类 $classname 不存在");
		}
		return class_exists($classname, false);
	}
	public static function init_get() {
		if(!empty($_ENV['_config'][APP_NAME.'_parseurl'])) {
			self::parseurl_control();
		}else{
			if(isset($_GET['u'])) {
				$u = $_GET['u'];
				unset($_GET['u']);
			}elseif(!empty($_SERVER['PATH_INFO'])) {
				$u = $_SERVER['PATH_INFO'];
			}else{
				$_GET = array();
				$u = $_SERVER["QUERY_STRING"];
			}
			$url_suffix = C('url_suffix');
			if($url_suffix) {
				$suf_len = strlen($url_suffix);
				if(substr($u, -($suf_len)) == $url_suffix) $u = substr($u, 0, -($suf_len));
			}
			$uarr = explode('-', $u);
			if(isset($uarr[0])) {
				$_GET['control'] = $uarr[0];
				array_shift($uarr);
			}
			if(isset($uarr[0])) {
				$_GET['action'] = $uarr[0];
				array_shift($uarr);
			}
			$num = count($uarr);
			for($i=0; $i<$num; $i+=2){
				isset($uarr[$i+1]) && $_GET[$uarr[$i]] = $uarr[$i+1];
			}
		}
		$_GET['control'] = isset($_GET['control']) && preg_match('/^\w+$/', $_GET['control']) ? $_GET['control'] : 'index';
		$_GET['action'] = isset($_GET['action']) && preg_match('/^\w+$/', $_GET['action']) ? $_GET['action'] : 'index';
		if(in_array($_GET['control'], array('parseurl', 'error404'))) {
			$_GET['control'] = 'error404';
			$_GET['action'] = 'index';
		}
	}
	public static function parseurl_control() {
		$controlname = 'parseurl_control.class.php';
		$objfile = RUNTIME_CONTROL.$controlname;
		if(!is_file($objfile)) {
			$controlfile = self::get_original_file($controlname, CONTROL_PATH);
			if(!$controlfile) {
				$_GET['control'] = 'parseurl';
				throw new Exception("访问的 URL 不正确，$controlname 文件不存在");
			}
			self::parse_all($controlfile, $objfile, "写入 control 编译文件 $controlname 失败");
		}
		include $objfile;
		$obj = new parseurl_control();
		$obj->index();
	}
	public static function init_control() {
		$control = &$_GET['control'];
		$action = &$_GET['action'];
		$controlname = "{$control}_control.class.php";
		$objfile = RUNTIME_CONTROL.$controlname;
		if(DEVMODE || !is_file($objfile)) {
			$controlfile = self::get_original_file($controlname, CONTROL_PATH);
			if($controlfile) {
				self::parse_all($controlfile, $objfile, "写入 control 编译文件 $controlname 失败");
			}else{
				self::error404();
			}
		}
		include $objfile;
		$class_name = $control.'_control';
		$obj = new $class_name();
		$obj->$action();
	}
	public static function error404() {
		log::write('404', 'php_error404.php');
		$errorname = 'error404_control.class.php';
		$objfile = RUNTIME_CONTROL.$errorname;
		if(DEVMODE || !is_file($objfile)) {
			$errorfile = self::get_original_file($errorname, CONTROL_PATH);
			if(!$errorfile) {
				throw new Exception("控制器加载失败，$errorname 文件不存在");
			}
			self::parse_all($errorfile, $objfile, "写入 control 编译文件 $errorname 失败");
		}
		include $objfile;
		$obj = new error404_control();
		$obj->index();
		exit();
	}
	//将原始程序代码解析并写入缓存文件中
	public static function parse_all($readfile, $writefile, $errorstr){
		$s = file_get_contents($readfile);
		$s = self::parse_extends($s);
		if(!FW($writefile, $s)) {
			throw new Exception($errorstr);
		}
	}
	public static function parse_extends($s) {
		if(preg_match('#class\s+\w+\s+extends\s+(\w+)\s*\{#', $s, $m)) {
			if($m[1] != 'control') {
				$controlname = $m[1].'.class.php';
				$realfile = CONTROL_PATH.$controlname;
				if(is_file($realfile)) {
					$objfile = RUNTIME_CONTROL.$controlname;
					self::parse_all($realfile, $objfile, "写入继承的类的编译文件 $controlname 失败");
					$s = str_replace_once($m[0], 'include RUNTIME_CONTROL.\''.$controlname."'; ".$m[0], $s);
				}else{
					throw new Exception("您继承的类文件 $controlname 不存在");
				}
			}
		}
		return $s;
	}
	public static function model($model) {
		$modelname = $model.'_model.class.php';
		if(isset($_ENV['_models'][$modelname])) {
			return $_ENV['_models'][$modelname];
		}
		$objfile = RUNTIME_MODEL.$modelname;
		if(DEVMODE || !is_file($objfile)) {
			$modelfile = core::get_original_file($modelname, MODEL_PATH);
			if(!$modelfile) {
				throw new Exception("模型 $modelname 文件不存在");
			}
			$s = file_get_contents($modelfile);
			if(!FW($objfile, $s)) {
				throw new Exception("写入 model 编译文件 $modelname 失败");
			}
		}
		include $objfile;
		$mod = new $model();
		$_ENV['_models'][$modelname] = $mod;
		return $mod;
	}
	public static function get_original_file($filename, $path) {
		if(is_file($path.$filename)) {
			return $path.$filename;
		}
		return FALSE;
	}
	public static function clear_code($s) {
		$s = trim($s);
		if(substr($s, 0, 5) == '<?php') $s = substr($s, 5);
		$s = ltrim($s);
		if(substr($s, 0, 29) == 'defined(\'FINE_PATH\') || exit;') $s = substr($s, 29);
		if(substr($s, -2, 2) == '?>') $s = substr($s, 0, -2);
		return $s;
	}
}
