<?php
/* * *********************************************************
 * [cml] (C)2012 - 3000 cml http://linhecheng.com
 * @Author  linhecheng<linhechengbush@live.com>
 * @Date: 13-6-26 上午11:23
 * @version  1.0
 * cml框架入口文件
 * *********************************************************** */

header('X-Powered-By:CmlPHP');
date_default_timezone_set('PRC'); //设置时区为中国

//设置框架所有需要的路径
define('DIR_SEP', DIRECTORY_SEPARATOR); 
defined('CML_PATH') || define('CML_PATH', dirname(__FILE__));
define('PROJECT_PATH', str_replace(array('/', '\\', '//', '\\\\'), DIR_SEP, dirname(isset($_SERVER['SCRIPT_FILENAME']) ? $_SERVER['SCRIPT_FILENAME'] : CML_PATH)));
defined('APP_PATH') || define('APP_PATH', DIR_SEP);
defined('RUNTIME_PATH') || define('RUNTIME_PATH', PROJECT_PATH.DIR_SEP.'Runtime');

// 路径设置 可在入口文件中重新定义 所有路径常量都必须以/ 结尾
defined('CML_LIB_PATH') || define('CML_LIB_PATH', CML_PATH.DIR_SEP.'Lib'); // 系统核心类库目录
defined('CML_LIB_BASE_PATH') || define('CML_LIB_BASE_PATH', CML_LIB_PATH.DIR_SEP.'Base'); // 系统核心类基类类库目录
defined('CML_LIB_DRIVER_PATH') || define('CML_LIB_DRIVER_PATH', CML_LIB_PATH.DIR_SEP.'Driver'); // 系统核心类库驱动类库目录
defined('CML_EXTEND_PATH') || define('CML_EXTEND_PATH', CML_PATH.DIR_SEP.'Extend'); // 系统扩展类库目录

//设置运行时文件路径
defined('RUNTIME_CACHE_PATH') || define('RUNTIME_CACHE_PATH', RUNTIME_PATH.DIR_SEP.'Cache'); //系统缓存目录
defined('RUNTIME_LOGS_PATH') || define('RUNTIME_LOGS_PATH', RUNTIME_PATH.DIR_SEP.'Logs');  //系统日志目录
defined('RUNTIME_DATA_PATH') || define('RUNTIME_DATA_PATH', RUNTIME_PATH.DIR_SEP.'Data');//数据表的结构文件	

//包含框架中的框架函数库文件
require CML_PATH.DIR_SEP.'Common'.DIR_SEP.'functions.inc.php';

//包含应用函数库文件
require PROJECT_PATH.DIR_SEP.APP_PATH.DIR_SEP.'Functions'.DIR_SEP.'function.inc.php';

//引入框架惯例配置文件
$cmlConfig = require CML_PATH.DIR_SEP.'Common'.DIR_SEP.'config.inc.php';

//应用正式配置文件
$appConfigFile = PROJECT_PATH.DIR_SEP.APP_PATH.DIR_SEP.'Configs'.DIR_SEP.'online.inc.php';

//应用开发阶段配置文件
$appDebugConfigFile = PROJECT_PATH.DIR_SEP.APP_PATH.DIR_SEP.'Configs'.DIR_SEP.'development.inc.php';

$appConfig = is_file($appDebugConfigFile) ? require $appDebugConfigFile : require $appConfigFile;

C(array_merge($cmlConfig, $appConfig));//合并配置

//引入语言包
$cmlLang = require CML_PATH.DIR_SEP.'Lang'.DIR_SEP.C('LANG').'.php';
L($cmlLang);

$cmlConfig = $appConfig = $cmlLang = $appConfigFile = $appDebugConfigFile = null;
require CML_LIB_BASE_PATH.DIR_SEP.'CmlBase.class.php';

// 注册AUTOLOAD方法
spl_autoload_register(array('CmlBase', 'autoloadLib'));
spl_autoload_register(array('CmlBase', 'autoloadLibAppFile'));
spl_autoload_register(array('CmlBase', 'autoloadExtend'));

//错误、异常捕获
register_shutdown_function(array('CmlBase', 'fatalError'));

set_exception_handler(array('CmlBase', 'appException'));

ini_set('display_errors', 'off');//屏蔽系统自带的错误输出

// 页面压缩输出支持
if(C('OUTPUT_ENCODE')) {
	$zlib = ini_get('zlib.output_compression');
	if(empty($zlib)) {
		@ob_end_clean () ;
		ob_start('ob_gzhandler') || ob_start();
		define('CML_OB_START', true);
	} else {
		define('CML_OB_START', false);
	}
}

//程序运行必须的类  
$runTimeClassList = array(       
	CML_LIB_BASE_PATH.DIR_SEP.'CmlController.class.php',      
	CML_LIB_BASE_PATH.DIR_SEP.'CmlRoute.class.php',
	CML_LIB_BASE_PATH.DIR_SEP.'CmlSecure.class.php',       
);
C('SESSION_USER') && $runTimeClassList[] = CML_LIB_BASE_PATH.DIR_SEP.'CmlSession.class.php';

//设置调试模式
if(C('APP_DEBUG')) {
	$GLOBALS['APP_DEBUG'] = true;//开启debug
	CmlDebug::start();
	set_error_handler(array('CmlDebug', 'Catcher'));

	//包含程序运行必须的类  
	foreach($runTimeClassList as $file) {
		require $file;
		CmlDebug::addTipInfo(L('_CMLDEBUG_ADDTIP_CLASS_', null, basename($file)), 1);//在debug中显示包含的类
	}
	$runTimeClassList = $file = null;
	CmlDebug::addTipInfo(L('_CMLDEBUG_ADDTIP_CLASS_', null, 'CmlBase'), 1);
} else {  
	$GLOBALS['APP_DEBUG'] = false;//关闭debug
	ini_set('error_reporting', 'E_ALL & ~E_NOTICE');//记录除了notice之外的错误
	ini_set('log_errors', 'on'); //开启错误日志
	$log_dir = RUNTIME_LOGS_PATH.DIR_SEP.APP_PATH;
	is_dir($log_dir) || mkdir($log_dir, 0700, true);
	ini_set('error_log', $log_dir.DIR_SEP.'warning_notice_error_'.date('Y-m-d').'.log');//将错误文件指定到Runtime/Logs下
	$log_dir = null;

	//线上模式包含runtime.php    
	$runTimeFile = RUNTIME_PATH.DIR_SEP.'_runtime_.php'; 
	if (!is_file($runTimeFile)) {		
		$runTimeContent = '<?php';
		foreach($runTimeClassList as $file) {
			$runTimeContent .= str_replace(array('<?php', '?>'), '', php_strip_whitespace($file));
		}		
		file_put_contents($runTimeFile, $runTimeContent);
		$runTimeContent = null;
	}
	require $runTimeFile;    
}

CmlRoute::parseUrl();    //解析处理URL


//设置应用路径
$addModule =  isset($_GET[C('VAR_MODULE')]) ?  DIR_SEP.$_GET[C('VAR_MODULE')] : '';
define('APP_CONTROLLER_ROOT_PATH', PROJECT_PATH.DIR_SEP.APP_PATH.DIR_SEP.'Controllers');
define('APP_CONTROLLER_PATH', APP_CONTROLLER_ROOT_PATH.$addModule);
define('APP_MODEL_ROOT_PATH', PROJECT_PATH.DIR_SEP.APP_PATH.DIR_SEP.'Models');
define('APP_MODEL_PATH', APP_MODEL_ROOT_PATH.$addModule);
define('APP_PLUGIN_PATH', PROJECT_PATH.DIR_SEP.APP_PATH.DIR_SEP.'Plugins');
$addModule = null;

//载入插件配置文件
$pluginConfig = require PROJECT_PATH.DIR_SEP.APP_PATH.DIR_SEP.'Configs'.DIR_SEP.'plugin.inc.php';
C('PLUGINS' , $pluginConfig);
$pluginConfig = null;

//控制器所在路径
$actionController = APP_CONTROLLER_PATH.DIR_SEP.ucfirst($_GET[C('VAR_CONTROLLER')]).'Controller.class.php';

$GLOBALS['APP_DEBUG'] && CmlDebug::addTipInfo(L('_CML_ACTION_CONTROLLER_', null, $actionController));

//执行
if(is_file($actionController)) {
	$className = ucfirst($_GET[C('VAR_CONTROLLER')]).'Controller';
	$controller = new $className();
	$controller->run();//运行
} else {
	if($GLOBALS['APP_DEBUG']) {
		throw_exception(L('_CONTROLLER_NOT_FOUND_', null, APP_CONTROLLER_PATH, ucfirst($_GET[C('VAR_CONTROLLER')]), ucfirst($_GET[C('VAR_CONTROLLER')])));
	} else {
		show404Page();
	}
}


//输出Debug模式的信息       
if($GLOBALS['APP_DEBUG']) {
	CmlDebug::stop();
} else {
	$deBugLogData = dump('', 1);
	if(!empty($deBugLogData)) require CML_LIB_BASE_PATH.DIR_SEP.'CmlConsoleLog.php';
	CML_OB_START && ob_end_flush();
	exit();
}