<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// $Id: App.class.php 2792 2012-03-02 03:36:36Z liu21st $

/**
 +------------------------------------------------------------------------------
 * ThinkPHP 应用程序类 执行应用过程管理
 * 可以在模式扩展中重新定义 但是必须具有Run方法接口
 +------------------------------------------------------------------------------
 * @category   Think
 * @package  Think
 * @subpackage  Core
 * @author    liu21st <liu21st@gmail.com>
 * @version   $Id: App.class.php 2792 2012-03-02 03:36:36Z liu21st $
 +------------------------------------------------------------------------------
 */
class App {

    /**
     +----------------------------------------------------------
     * 应用程序初始化
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @return void
     +----------------------------------------------------------
     */
    static public function init() {

        // 设置系统时区
        date_default_timezone_set(C('DEFAULT_TIMEZONE'));
        // 加载动态项目公共文件和配置
        load_ext_file();
        // URL调度
        Dispatcher::dispatch();

        if(defined('GROUP_NAME')) {
            // 加载分组配置文件
            if(is_file(CONF_PATH.GROUP_NAME.'/config.php'))
                C(include CONF_PATH.GROUP_NAME.'/config.php');
            // 加载分组函数文件
            if(is_file(COMMON_PATH.GROUP_NAME.'/function.php'))
                include COMMON_PATH.GROUP_NAME.'/function.php';
        }

        /* 获取模板主题名称 */
        /*
        $templateSet =  C('DEFAULT_THEME');
        if(C('TMPL_DETECT_THEME')) {// 自动侦测模板主题
            $t = C('VAR_TEMPLATE');
            if (isset($_GET[$t])){
                $templateSet = $_GET[$t];
            }elseif(cookie('think_template')){
                $templateSet = cookie('think_template');
            }
            // 主题不存在时仍改回使用默认主题
            if(!is_dir(TMPL_PATH.$templateSet))
                $templateSet = C('DEFAULT_THEME');
            cookie('think_template',$templateSet);
        }
        */
        
        //修改By wang 2013-04-02============================================
        $templateSet =  C('DEFAULT_THEME');
        //仅让home分组支持自动切换模板
        $t = C('VAR_TEMPLATE');
        if (isset($_GET[$t])){  //todo 存在bug，必须每次都附加t参数
	        $gn = strtolower(GROUP_NAME);
	        if( in_array($gn, array('home', 'wap')) && C('TMPL_DETECT_THEME')  ) {// 自动侦测模板主题
	        	$ct = $gn.'_think_template';
	        	if (isset($_GET[$t])){
	        		$templateSet = $_GET[$t];
	        		//更换主题，必须清空静态缓存
	        		if(C('HTML_CACHE_ON') == true && is_dir(TMPL_PATH.GROUP_NAME.'/'.$templateSet)) {
	        			YdCache::deleteHtml('all'); //清楚全部Html缓存
	        		}
	        	}elseif(cookie($ct)){
	        		$templateSet = cookie($ct);
	        	}
	        	// 主题不存在时仍改回使用默认主题
	        	if(!is_dir(TMPL_PATH.GROUP_NAME.'/'.$templateSet)) {
	        		$templateSet = C('DEFAULT_THEME');
	        		//切换到默认模板，也需要清空静态缓存
	        		if(C('HTML_CACHE_ON') == true && is_dir(TMPL_PATH.GROUP_NAME.'/'.$templateSet)) {
	        			YdCache::deleteHtml('all'); //清楚全部Html缓存
	        		}
	        	}
	        	cookie($ct, $templateSet);
	        }
        }
        //==============================================================
        
        /* 模板相关目录常量 */
        define('THEME_NAME',   $templateSet);                  // 当前模板主题名称
        $group   =  defined('GROUP_NAME')?GROUP_NAME.'/':'';
        define('THEME_PATH',   TMPL_PATH.$group.(THEME_NAME?THEME_NAME.'/':''));
        define('APP_TMPL_PATH',__ROOT__.'/'.APP_NAME.(APP_NAME?'/':'').basename(TMPL_PATH).'/'.$group.(THEME_NAME?THEME_NAME.'/':''));
        C('TEMPLATE_NAME',THEME_PATH.MODULE_NAME.(defined('GROUP_NAME')?C('TMPL_FILE_DEPR'):'/').ACTION_NAME.C('TMPL_TEMPLATE_SUFFIX'));
        C('CACHE_PATH',CACHE_PATH.$group);
        return ;
    }

    /**
     +----------------------------------------------------------
     * 执行应用程序
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @return void
     +----------------------------------------------------------
     * @throws ThinkExecption
     +----------------------------------------------------------
     */
    static public function exec() {
        // 安全检测
        if(!preg_match('/^[A-Za-z_0-9]+$/',MODULE_NAME)){
            $module =  false;
        }else{
            //创建Action控制器实例
            $group =  defined('GROUP_NAME') ? GROUP_NAME.'/' : '';
            $module  =  A($group.MODULE_NAME);
        }

        if(!$module) {
            if(function_exists('__hack_module')) {
                // hack 方式定义扩展模块 返回Action对象
                $module = __hack_module();
                if(!is_object($module)) {
                    // 不再继续执行 直接返回
                    return ;
                }
            }else{
                // 是否定义Empty模块
                $module = A('Empty');
                if(!$module){
                    $msg =  L('_MODULE_NOT_EXIST_').MODULE_NAME;
                    if(APP_DEBUG) {
                        // 模块不存在 抛出异常
                        throw_exception($msg);
                    }else{
                        if(C('LOG_EXCEPTION_RECORD')) Log::write($msg);
                        send_http_status(404);
                        exit;
                    }
                }
            }
        }
        //获取当前操作名
        $action = ACTION_NAME;
        // 获取操作方法名标签
        tag('action_name',$action);
        if (method_exists($module,'_before_'.$action)) {
            // 执行前置操作
            call_user_func(array(&$module,'_before_'.$action));
        }
        //执行当前操作
        call_user_func(array(&$module,$action));
        if (method_exists($module,'_after_'.$action)) {
            //  执行后缀操作
            call_user_func(array(&$module,'_after_'.$action));
        }
        return ;
    }

    /**
     +----------------------------------------------------------
     * 运行应用实例 入口文件使用的快捷方法
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @return void
     +----------------------------------------------------------
     */
    static public function run() {
        // 项目初始化标签
        tag('app_init');
        App::init();
        // 项目开始标签
        tag('app_begin');
        // Session初始化
        session(C('SESSION_OPTIONS'));
        // 记录应用初始化时间
        G('initTime');
        App::exec();
        // 项目结束标签
        tag('app_end');
        // 保存日志记录
        if(C('LOG_RECORD')) Log::save();
        return ;
    }

}