<?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>

// +----------------------------------------------------------------------



/**

 * ThinkPHP Widget类 抽象类

 * @category   Think

 * @package  Think

 * @subpackage  Core

 * @author liu21st <liu21st@gmail.com>

 */

abstract class Widget {



    // 使用的模板引擎 每个Widget可以单独配置不受系统影响

    protected $template =  '';



    /**

     * 渲染输出 render方法是Widget唯一的接口

     * 使用字符串返回 不能有任何输出

     * @access public

     * @param mixed $data  要渲染的数据

     * @return string

     */

    abstract public function render($data);



    /**

     * 渲染模板输出 供render方法内部调用

     * @access public

     * @param string $templateFile  模板文件

     * @param mixed $var  模板变量

     * @return string

     */

    protected function renderFile($templateFile='',$var='') {

        ob_start();

        ob_implicit_flush(0);

        if(!file_exists_case($templateFile)){

            // 自动定位模板文件

            $name   = substr(get_class($this),0,-6);

            $filename   =  empty($templateFile)?$name:$templateFile;

            $templateFile = BASE_LIB_PATH.'Widget/'.$name.'/'.$filename.C('TMPL_TEMPLATE_SUFFIX');

            if(!file_exists_case($templateFile))

                throw_exception(L('_TEMPLATE_NOT_EXIST_').'['.$templateFile.']');

        }

        $template   =  strtolower($this->template?$this->template:(C('TMPL_ENGINE_TYPE')?C('TMPL_ENGINE_TYPE'):'php'));

        if('php' == $template) {

            // 使用PHP模板

            if(!empty($var)) extract($var, EXTR_OVERWRITE);

            // 直接载入PHP模板

            include $templateFile;

        }elseif('think'==$template){ // 采用Think模板引擎

            if($this->checkCache($templateFile)) { // 缓存有效

                // 分解变量并载入模板缓存

                extract($var, EXTR_OVERWRITE);

                //载入模版缓存文件

                include C('CACHE_PATH').md5($templateFile).C('TMPL_CACHFILE_SUFFIX');

            }else{

                $tpl = Think::instance('ThinkTemplate');

                // 编译并加载模板文件

                $tpl->fetch($templateFile,$var);

            }

        }else{

            $class   = 'Template'.ucwords($template);

            if(is_file(CORE_PATH.'Driver/Template/'.$class.'.class.php')) {

                // 内置驱动

                $path = CORE_PATH;

            }else{ // 扩展驱动

                $path = EXTEND_PATH;

            }

            require_cache($path.'Driver/Template/'.$class.'.class.php');

            $tpl   =  new $class;

            $tpl->fetch($templateFile,$var);

        }

        $content = ob_get_clean();

        return $content;

    }



    /**

     * 检查缓存文件是否有效

     * 如果无效则需要重新编译

     * @access public

     * @param string $tmplTemplateFile  模板文件名

     * @return boolen

     */

    protected function checkCache($tmplTemplateFile) {

        if (!C('TMPL_CACHE_ON')) // 优先对配置设定检测

            return false;

        $tmplCacheFile = C('CACHE_PATH').md5($tmplTemplateFile).C('TMPL_CACHFILE_SUFFIX');

        if(!is_file($tmplCacheFile)){

            return false;

        }elseif (filemtime($tmplTemplateFile) > filemtime($tmplCacheFile)) {

            // 模板文件如果有更新则缓存需要更新

            return false;

        }elseif (C('TMPL_CACHE_TIME') != 0 && time() > filemtime($tmplCacheFile)+C('TMPL_CACHE_TIME')) {

            // 缓存是否在有效期

            return false;

        }

        // 缓存有效

        return true;

    }

}