<?php

/**
 *--------------------------------------
 * 应用基类
 *--------------------------------------
 * @project		: pfa
 * @author		: cblee
 * @created		: 2012-9-23
 * @copyright	: (c)2012 AsThis
 *--------------------------------------
 */

class App extends Pfa
{
	/* 开始运行 */
	public function run()
	{
		error_reporting(E_ALL ^ E_NOTICE ^ E_WARNING);
		set_error_handler(array('App', 'app_error'));
		//[RUNTIME]
		App::build(); /* 预编译应用 */

		//[/RUNTIME]
		Url::dispatch(); /* URL调度并定义CTRLR_NAME和ACTN_NAME等 */

		self::load_lang(); /* 加载应用语言 */
		self::load_theme(); /* 检测并定义模板变量 */

		date_default_timezone_set(C('APP.TIMEZONE')); /* 设置时区 */
		header('X-Powered-By: PFA '.PFA_VERSION);

		G('initTime'); /* 记录初始化时间 */

		$group = defined('GROUP_NAME') ? GROUP_NAME.C('APP.GROUP_DEPR') : '';
		$ctrlr = A($group.CTRLR_NAME);
		if(!preg_match('/^[A-Za-z_0-9]+$/', CTRLR_NAME) or !$ctrlr)
		{
			if(C('APP_DEBUG'))
			{
				halt(L('_CTRLR_NOT_EXIST_').CTRLR_NAME);
			}
			else
			{
				header('HTTP/1.1 404 Not Found');
				header('Status:404 Not Found');
				exit;
			}
		}

		/* 执行当前操作 */
		call_user_func(array(&$ctrlr, ACTN_NAME));

		G('execTime'); /* 记录初始化时间 */

		/* 保存日志记录 */
		if(C('LOG.SWITCH'))
		{
			Log::save();
		}
	}

	//[RUNTIME]
	/* 读取配置 编译应用 */
	private static function build()
	{
		/* 加载应用常量 */
		require_cache(CFG_PATH.D_S.'define.php');
		/* 加载应用公共设置 */
		C(require_cache(CFG_PATH.D_S.'comm.php'));
		/* 加载应用公共文件 */
		$common = '';
		if(is_file(LIB_COMM_PATH.D_S.'comm.func.php'))
		{
			include LIB_COMM_PATH.D_S.'comm.func.php'; /* 加载应用公共函数 */
			if(!C('DEBUG.SWITCH'))
			{
				$common .= compile(LIB_COMM_PATH.D_S.'comm.func.php'); /* 编译文件 */
			}
		}
		/* 加载动态配置文件 */
		$configs = C('APP.CFG_LIST');
		if(is_string($configs))
		{
			$configs = explode(',', $configs);
			foreach($configs as $config)
			{
				$file = CFG_PATH.D_S.$config.'.php';
				if(is_file($file))
				{
					C(strtoupper($config), (include $file));
				}
			}
		}
		C('APP.CFG_LIST',''); /* 清除配置参数 */

		/* 编译应用 */
		if(!C('DEBUG.SWITCH'))
		{
			build_runtimeCache($common);
		}
	}
	//[/RUNTIME]

	/* 语言文件加载 */
	private static function load_lang()
	{
		$langSet = C('LANG.NAME');
		if(C('LANG.DETECT'))
		{
			$_t_l = ARequest::get(C('VAR.LANG'));
			if(!empty($_t_l))
			{
				$langSet = strtolower(ARequest::get(C('VAR.LANG')));
				ACookie::set('lang', $langSet);
			}
			elseif(ACookie::get('lang'))
			{
				$langSet = ACookie::get('lang');
			}
			elseif(isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
			{
				preg_match('/^([a-z\-]+)/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches);
				$langSet = strtolower($matches[1]);
				ACookie::set('lang', $langSet);
			}
		}
		define('LANG_SET', strtolower($langSet));
		/* 加载框架默认语言 */
		if(is_file(PFA_PATH.'/lang/'.LANG_SET.'.lang.php'))
		{
			L(include PFA_PATH.'/lang/'.LANG_SET.'.lang.php');
		}
		elseif(is_file(PFA_PATH.'/lang/'.C('LANG.NAME').'.lang.php'))
		{
			L(include PFA_PATH.'/lang/'.C('LANG.NAME').'.lang.php');
		}
		/* 读取应用公共语言包 */
		if(is_file(LANG_PATH.D_S.LANG_SET.'/comm.lang.php'))
		{
			L(include LANG_PATH.D_S.LANG_SET.'/comm.lang.php');
		}
		elseif(is_file(LANG_PATH.D_S.C('LANG.NAME').'/comm.lang.php'))
		{
			L(include LANG_PATH.D_S.C('LANG.NAME').'/comm.lang.php');
		}
		/* 读取群组语言包 */
		$group = '';
		if(defined('GROUP_NAME'))
		{
			$group = strtolower(D_S.GROUP_NAME);
		}
		if(is_file(LANG_PATH.D_S.LANG_SET.$group.'/comm.lang.php'))
		{
			L(include LANG_PATH.D_S.LANG_SET.$group.'/comm.lang.php');
		}
		elseif(is_file(LANG_PATH.D_S.C('LANG.NAME').$group.'/comm.lang.php'))
		{
			L(include LANG_PATH.D_S.C('LANG.NAME').$group.'/comm.lang.php');
		}
		/* 读取控制器语言包 */
		if(is_file(LANG_PATH.D_S.LANG_SET.$group.D_S.strtolower(CTRLR_NAME).'.lang.php'))
		{
			L(include LANG_PATH.D_S.LANG_SET.$group.D_S.strtolower(CTRLR_NAME).'.lang.php');
		}
		elseif(is_file(LANG_PATH.D_S.C('LANG.NAME').$group.D_S.strtolower(CTRLR_NAME).'.lang.php'))
		{
			L(include LANG_PATH.D_S.C('LANG.NAME').$group.D_S.strtolower(CTRLR_NAME).'.lang.php');
		}
	}

	/** 加载模板主题 */
	private static function load_theme()
	{
		$tplSet = C('TE.TPL_THEME');
		if(C('TE.TPL_DETECT')) /* 侦测模板主题 */
		{
			$t = C('VAR.TPL');
			if(isset($_GET[$t]))
			{
				$tplSet = $_GET[$t];
			}
			elseif(ACookie::get('theme'))
			{
				$tplSet = ACookie::get('theme');
			}
			if(!is_dir(TPL_PATH.D_S.$tplSet)) /* 主题不存在时使用默认主题 */
			{
				$tplSet = C('TE.TPL_THEME');
			}
			ACookie::set('theme', $tplSet);
			C('TE.TPL_THEME', $tplSet); /* 当前主题名称 */
		}
		/* 模板相关目录常量 */
		define('THEME_NAME', $tplSet); /* 当前主题名称 */
		/* 当前主题路径 */
		define('THEME_PATH', TPL_PATH.(THEME_NAME ? D_S.THEME_NAME : ''));
		/* 当前应用模板主题 URL */
		define('__THEME__', __APP__.'/'.TPL_DIR.'/'.(THEME_NAME ? THEME_NAME : ''));

		if(defined('GROUP_NAME'))
		{
			/* 当前模板文件 */
			C('TE.CURRENT_FILE', THEME_PATH.D_S.parse_name(GROUP_NAME).D_S.parse_name(CTRLR_NAME).D_S.strtolower(ACTN_NAME).C('TE.TPL_SUFFIX'));
			/* 当前缓存路径 */
			C('CACHE.PATH', C('CACHE.PATH').D_S.parse_name(GROUP_NAME));
		}
		else
		{
			C('TE.CURRENT_FILE', THEME_PATH.D_S.parse_name(CTRLR_NAME).D_S.strtolower(ACTN_NAME).C('TE.TPL_SUFFIX'));
		}
		return;
	}

	/** 自定义错误处理 */
	public static function app_error($errno, $errstr, $errfile, $errline)
	{
		$errno = $errno & error_reporting();
		if(!defined('E_STRICT')) define('E_STRICT', 2048);
		if(!defined('E_RECOVERABLE_ERROR')) define('E_RECOVERABLE_ERROR', 4096);
		switch($errno)
		{
			case E_ERROR:
			case E_WARNING:
			case E_PARSE:
			case E_NOTICE:
			case E_CORE_ERROR:
			case E_CORE_WARNING:
			case E_COMPILE_ERROR:
			case E_COMPILE_WARNING:
			case E_USER_ERROR:
				$errorStr = "[{$errno}]{$errstr} ".basename($errfile)."({$errline})";
				Log::record($errorStr);
				halt($errorStr);
				break;
			case E_USER_WARNING:
			case E_USER_NOTICE:
			case E_STRICT:
			case E_RECOVERABLE_ERROR:
			default:
				$errorStr = "[{$errno}]{$errstr} ".basename($errfile)."({$errline})";
				Log::record($errorStr);
				break;
		}
	}

	/** 保存日志 */
	public function __destruct()
	{
		if(C('LOG.SWITCH'))
		{
			Log::save();
		}
	}
}

?>