<?php
/*
  PHP version 5
  Copyright (c) 2002-2018 ECISP.CN、EarcLink.COM
  警告：这不是一个免费的软件，请在许可范围内使用，请尊重知识产权，侵权必究，举报有奖
  作者：黄祥云 E-mail:6326420@qq.com  QQ:6326420 TEL:18665655030
 */

use application\ESPCMS_AdminAuthority;
use application\ESPCMS_Chinese;

class ESPCMS_Templates {
    private $_parser;
    private $list_hash = '6623ef97c6f6ccf2fb032e800d2edda9';
    private $link_hash = '885BA145EFC8431D34F5CC06D142F143';
    private $get_hash = '214adb21252b0af7b03s214s9';
    private $get_table_hash = '60af7b03s21fs';
    private $find_hash = '4adb4912cd04e6fd3';
    private $pack_hash = 'E843B7A28BF9F9FC6D55A5A8EAE72F36';
    public $libdir = 'lib';
    private $libname = 'lib_';
    private $template_out;
    private $cache_dir;
    private $templatesDIR;
    private $cache_pic;
    private $wap_cache_dir;
    private $tpl_c_dir;
    public $templates_themss_dirname;
    public $html_compile_dir;
    public $templatescache_dir;
    public $dbcache_dir;
    public $photo_dir;
    public $templates_path_dir;
    public $templatesfileex;
    public $left_delimiter;
    public $right_delimiter;
    public $libfile;
    public $iscaching;
    public $cache_time;
    private $_tpl_vars;

    public function __construct($html_compile_dir = null, $templatescache_dir = null, $dbcache_dir = null, $photo_dir = null, $templates_path_dir = null, $templates_themss_dirname = null, $templatesfileex = '.html', $left_delimiter = '[%', $right_delimiter = '%]') {
        $this->html_compile_dir = $html_compile_dir;
        $this->templatescache_dir = $templatescache_dir;
        $this->dbcache_dir = $dbcache_dir;
        $this->photo_dir = $photo_dir;
        $this->templates_path_dir = $templates_path_dir;
        $this->templates_themss_dirname = $templates_themss_dirname;
        $this->templatesfileex = $templatesfileex;
        $this->left_delimiter = $left_delimiter;
        $this->right_delimiter = $right_delimiter;
        $this->libfile = false;
        $this->iscaching = false;
        $this->cache_time = 86400;
    }

    public function into($var, $value) {
        if (isset($var) && trim($var) != '') {
            $this->_tpl_vars[$var] = $value;
            return true;
        }
    }

    public function geto($var) {
        return $this->_tpl_vars[$var];
    }

    public function output($templates_filenames, $cache_fileid = null, $isceart_html = false, $htm_filename = false, $xml_filename = null) {
        if (!empty($xml_filename)) {
            $templates_filename = $this->templates_path_dir . $this->templates_themss_dirname . $templates_filenames . $xml_filename;
        } else {
            $templates_filename = $this->templates_path_dir . $this->templates_themss_dirname . $templates_filenames . $this->templatesfileex;
        }
        if (!is_dir($this->templates_path_dir) && !$isceart_html) {
            espcms_message_err('public_pack-espcms_templates_dir_err', array($this->templates_path_dir));
        } elseif (!is_dir($this->templates_path_dir) && $isceart_html) {
            return false;
        }
        if (!is_dir($this->html_compile_dir) && !$isceart_html) {
            espcms_message_err('public_pack-espcms_htmlcompile_dir_err', array($this->html_compile_dir));
        } elseif (!is_dir($this->html_compile_dir) && $isceart_html) {
            return false;
        }
        $fetch_filename = $this->templates_themss_dirname . $templates_filenames . $this->templatesfileex;
        if (!file_exists($templates_filename) && !$isceart_html) {
            espcms_message_err('public_pack-espcms_templates_filename_err', array($fetch_filename));
        } elseif (!file_exists($templates_filename) && $isceart_html) {
            return false;
        }
        $out = $this->fetch($fetch_filename, $cache_fileid);
        if (strpos($out, $this->link_hash)) {
            $includefile = explode($this->link_hash, $out);
            foreach ($includefile as $key => $val) {
                if (($key % 2) == 1) {
                    $val = str_replace('|', '', $val);
                    $includefile[$key] = $this->fetch($val);
                }
            }
            $out = implode('', $includefile);
        }
        if (strpos($out, $this->get_hash)) {
            $getout = explode($this->get_hash, $out);
            foreach ($getout as $key => $val) {
                if (($key % 2) == 1) {
                    $getvalue = explode($this->get_table_hash, $val);
                    list($getval, $tempbreak) = $getvalue;
                    $getout[$key] = $this->insert_get_mod($getval, $tempbreak);
                }
            }
            $out = implode('', $getout);
        }
        if (strpos($out, $this->list_hash)) {
            $k = explode($this->list_hash, $out);
            foreach ($k as $key => $val) {
                if (($key % 2) == 1) {
                    $k[$key] = $this->list_mod($val);
                }
            }
            $out = implode('', $k);
            $out = $this->format_js($out);
        }
        if (strpos($out, $this->pack_hash)) {
            $packout = explode($this->pack_hash, $out);
            foreach ($packout as $key => $val) {
                if (($key % 2) == 1) {
                    $packvalue = explode('|', $val);
                    list($message_code, $packclass) = $packvalue;
                    $packout[$key] = $this->insert_pack_mod($message_code, $packclass);
                }
            }
            $out = implode('', $packout);
        }
        if (strpos($out, $this->find_hash)) {
            $findout = explode($this->find_hash, $out);
            foreach ($findout as $key => $val) {
                if (($key % 2) == 1) {
                    $filevalue = explode('|', $val);
                    list($findmodel, $findclass, $findfiled) = $filevalue;
                    $findout[$key] = $this->insert_find_mod($findmodel, $findclass, $findfiled);
                }
            }
            $out = implode('', $findout);
        }
        if ($this->lng == 'big5') {
            ob_start();
            @eval('?' . '>' . trim($out));
            $content = ob_get_contents();
            ob_end_clean();
            ob_end_flush();
            $big_out = ESPCMS_Chinese::g2b($content);
            if ($isceart_html) {
                return $this->cachefilewrite($htm_filename, $big_out);
            } else {
                exit($big_out);
            }
        } else {
            if ($isceart_html) {
                ob_start();
                @eval('?' . '>' . trim($out));
                $content = ob_get_contents();
                ob_end_clean();
                ob_end_flush();
                return $this->cachefilewrite($htm_filename, $content);
            } else {
                @eval('?' . '>' . trim($out));
            }
        }
    }

    private function format_js($str) {
        if (preg_match('/<!--js-->/', $str)) {
            preg_match("@<head>(.*?)</head>@is", $str, $head);
            $str_head = $head[1];
            preg_match_all("@<!--js-->(.*?)<!--end_js-->@is", $str, $js);
            $str_js = $js[1];
            if (!empty($str_js) && is_array($str_js)) {
                $str_jscontent = implode('', $str_js);
            }
            $str = preg_replace("/<!--js-->(.*?)<!--end_js-->/is", '', $str);
            $headstr = $str_head . $str_jscontent;
            $patten = '/<head>(.*?)<\/head>/is';
            $str = preg_replace($patten, '<head>' . $headstr . '</head>', $str);
        }
        return $str;
    }

    private function insert_pack_mod($message_code, $packclass) {
        if ($packclass && strlen($packclass) > 5) {
            ob_start();
            @eval('?' . '>' . trim($packclass));
            $packclass = ob_get_contents();
            ob_end_clean();
            $format_code = explode(',', $packclass);
        }
        $message_lan = espcms_lan_pack($message_code);
        if (isset($message_lan) && !empty($message_lan) && is_array($format_code) && count($format_code) > 0) {
            $message = vsprintf($message_lan, $format_code);
        } else {
            $message = $message_lan;
        }
        return $message;
    }

    private function list_mod($name) {
        ob_start();
        @eval('?' . '>' . trim($name));
        $name = ob_get_contents();
        ob_end_clean();
        list($fun, $para, $filename, $iscache, $cachefile, $libdir) = explode('|', $name);
        $libdir_name = $libdir ? $this->libdir . $libdir : $this->libdir;
        $libfile = ESPCMS_FILE_ROOT . $libdir_name . $this->libname . $fun . '.php';
        if (!file_exists($libfile)) {
            return false;
        } else {
            require_once $libfile;
            $className = $this->libname . $fun;
            if (class_exists($className)) {
                $boot = new $className();
            } else {
                return false;
            }
        }
        $fun = 'call_' . $fun;
        $para_array = explode(',', $para);
        if ($iscache) {
            $cache_fileID = 'list_' . $fun;
            $cache_file = empty($cachefile) ? $this->templatescache_dir . $cache_fileID . '_cache_' . md5($name) . '.php' : $this->templatescache_dir . $cache_fileID . '_cache_' . trim($cachefile) . '.php';
            if (is_file($cache_file)) {
                $html_out = file_get_contents($cache_file);
            } else {
                ob_start();
                if (empty($filename)) {
                    echo $boot->$fun($para_array);
                } else {
                    echo $boot->$fun($para_array, $filename);
                }
                $html_out = ob_get_contents();
                ob_end_clean();
                $this->cachefilewrite($cache_file, $html_out);
            }
        } else {
            if (empty($filename)) {
                $html_out = $boot->$fun($para_array);
            } else {
                $html_out = $boot->$fun($para_array, $filename);
            }
        }
        return $html_out;
    }

    private function insert_get_mod($name, $template) {
        ob_start();
        @eval('?' . '>' . trim($name));
        $name = ob_get_contents();
        ob_end_clean();
        list($fun, $para, $iscache, $cachefile, $libdir) = explode('|', $name);
        $libdir_name = $libdir ? $this->libdir . $libdir : $this->libdir;
        $libfile = ESPCMS_FILE_ROOT . $libdir_name . $this->libname . $fun . '.php';
        if (!file_exists($libfile)) {
            return false;
        } else {
            require_once $libfile;
            $className = $this->libname . $fun;
            if (class_exists($className)) {
                $boot = new $className();
            } else {
                return false;
            }
        }
        $fun = 'call_' . $fun;
        $para_array = explode(',', $para);
        if ($iscache) {
            $cache_fileID = 'get_' . $fun;
            $cache_file = empty($cachefile) ? $this->templatescache_dir . $cache_fileID . '_cache_' . md5($name) . '.php' : $this->templatescache_dir . $cache_fileID . '_cache_' . trim($cachefile) . '.php';
            if (is_file($cache_file)) {
                $html_out = file_get_contents($cache_file);
            } else {
                ob_start();
                echo $boot->$fun($para_array, null, $template);
                $html_out = ob_get_contents();
                ob_end_clean();
                $this->cachefilewrite($cache_file, $html_out);
            }
        } else {
            $html_out = $boot->$fun($para_array, null, $template);
        }
        return $html_out;
    }

    private function insert_find_mod($findmodel, $findclass, $findfiled) {
        ob_start();
        @eval('?' . '>' . trim($findclass));
        $findclass = ob_get_contents();
        ob_end_clean();
        $libfile = ESPCMS_FILE_ROOT . $this->libdir . $this->libname . $findmodel . '.php';
        if (!file_exists($libfile)) {
            return false;
        } else {
            require_once $libfile;
            $className = $this->libname . $findmodel;
            if (class_exists($className)) {
                $this->findboot = new $className();
            }
        }
        $fun = 'find_' . $findmodel;
        return $this->findboot->$fun($findclass, $findfiled, $this->lng);
    }

    public function fetch($fetch_filename = null, $cache_fileid = null, $out_html = null, $ispack = false) {
        if (!empty($out_html)) {
            $out = $this->gettemprequire($out_html);
            return $out;
        }
        require_once 'ESPCMS_Templates_Parser.php';
        if ($this->libfile) {
            $fetch_filename = $this->templates_themss_dirname . $fetch_filename . $this->templatesfileex;
            $templates_filename = $this->templates_path_dir . $fetch_filename;
        } else {
            $templates_filename = $this->templates_path_dir . $fetch_filename;
        }
        $parsed_file = $this->html_compile_dir . md5($templates_filename) . '.php';
        if ($this->iscaching) {
            if ($this->tempcheckcache($fetch_filename, $cache_fileid)) {
                if (!file_exists($parsed_file) || filemtime($parsed_file) < filemtime($templates_filename)) {
                    $this->_parser = new ESPCMS_Templates_Parser();
                    $this->_parser->compile($fetch_filename, $this->templates_path_dir, $this->templates_themss_dirname, $this->html_compile_dir, $this->left_delimiter, $this->right_delimiter);
                }
                $this->tempcachesave($fetch_filename, $cache_fileid);
                $out = $this->template_out;
            } else {
                $out = $this->template_out;
            }
        } else {
            if (!file_exists($parsed_file) || filemtime($parsed_file) < filemtime($templates_filename)) {
                $this->_parser = new ESPCMS_Templates_Parser();
                $this->_parser->compile($fetch_filename, $this->templates_path_dir, $this->templates_themss_dirname, $this->html_compile_dir, $this->left_delimiter, $this->right_delimiter);
            }
            if ($this->libfile) {
                $out = $this->temprequire($parsed_file);
            } else {
                $out = file_get_contents($parsed_file);
            }
        }
        if ($ispack) {
            if (strpos($out, $this->pack_hash)) {
                $packout = explode($this->pack_hash, $out);
                foreach ($packout as $key => $val) {
                    if (($key % 2) == 1) {
                        $packvalue = explode('|', $val);
                        list($message_code, $packclass) = $packvalue;
                        $packout[$key] = $this->insert_pack_mod($message_code, $packclass);
                    }
                }
                $out = implode('', $packout);
            }
        }
        return $out;
    }

    private function gettemprequire($outHTML) {
        ob_start();
        eval('?' . '>' . trim($outHTML));
        $content = ob_get_contents();
        ob_end_clean();
        return $content;
    }

    private function cachefilewrite($fileName, $content, $type = "wb+") {
        $fd = fopen($fileName, $type);
        if ($fd) {
            fwrite($fd, $content);
            fclose($fd);
            return true;
        } else {
            return false;
        }
    }

    private function temprequire($filename) {
        ob_start();
        include $filename;
        $content = ob_get_contents();
        ob_end_clean();
        return $content;
    }

    private function tempcachesave($fetch_filename, $cache_fileid = null, $renewid = true) {
        if (!$this->iscaching || empty($fetch_filename)) {
            return false;
        }
        $cache_ID = !empty($cache_fileid) ? $cache_fileid . '_' : '';
        $templates_filename = $this->templates_path_dir . $fetch_filename;
        $parsed_file = $this->html_compile_dir . md5($templates_filename) . '.php';
        $cache_file = $this->templatescache_dir . $cache_ID . 'cache_' . md5($fetch_filename) . '.php';
        if ($renewid || !is_file($cache_file)) {
            ob_start();
            require_once $parsed_file;
            $data = ob_get_contents();
            ob_end_clean();
            $this->cachefilewrite($cache_file, $data);
            $this->template_out = $data;
            return false;
        } else {
            $data = file_get_contents($cache_file);
            $this->template_out = $data;
            return false;
        }
        return true;
    }

    private function tempcheckcache($fetch_filename, $cache_fileid = null, $cache_fase = false) {
        if (!$this->iscaching && !$cache_fase) {
            return true;
        }
        $nowtime = strtotime(date('Y-m-d H:i:s', time()));
        $cache_ID = !empty($cache_fileid) ? $cache_fileid . '_' : '';
        $cache_file = $this->templatescache_dir . $cache_ID . 'cache_' . md5($fetch_filename) . '.php';
        if (is_file($cache_file)) {
            $filetime = filemtime($cache_file);
            $endtime = $filetime + $this->cache_time;
            $exchchefiletime = $nowtime - $endtime;
            if ($exchchefiletime >= 0) {
                return true;
            } else {
                $data = file_get_contents($cache_file);
                $this->template_out = $data;
                return false;
            }
        } else {
            return true;
        }
    }

    public function clearcache($cache_file = null, $cache_ID = null, $iswap = false) {
        if ($cache_file) {
            if (!strpos($cache_file, $this->templatesfileex)) {
                $cache_file = $this->templatesDIR . $cache_file . $this->templatesfileex;
            }
            $cache_ID = !empty($cache_ID) ? $cache_ID . '_' : '';
            $cachefilename = $this->cache_dir . $cache_ID . 'cache_' . md5($cache_file) . '.php';
            if (is_file($cachefilename)) {
                unlink($cachefilename);
                return true;
            } else {
                return false;
            }
        } else {
            $cachefilename = $this->cache_dir;
            if (file_exists($cachefilename)) {
                $dirname = opendir($cachefilename);
                while ($val = readdir($dirname)) {
                    if ($val == '.' || $val == '..') {
                        continue;
                    }
                    $value = $cachefilename . $val;
                    unlink($value);
                }
                closedir($dirname);
                if ($iswap) {
                    $wap_cachefilename = $this->wap_cache_dir;
                    $wapdirname = opendir($wap_cachefilename);
                    while ($val = readdir($wapdirname)) {
                        if ($val == '.' || $val == '..') {
                            continue;
                        }
                        $value = $wap_cachefilename . $val;
                        unlink($value);
                    }
                    closedir($wapdirname);
                }
                return true;
            } else {
                return false;
            }
        }
    }

    public function clearpic($iswap = false) {
        $cachefilename = $this->cache_pic;
        if (file_exists($cachefilename)) {
            $dirname = opendir($cachefilename);
            while ($val = readdir($dirname)) {
                if ($val == '.' || $val == '..' || $val == '3gwap') {
                    continue;
                }
                $value = $cachefilename . $val;
                unlink($value);
            }
            closedir($dirname);
            if ($iswap) {
                $wap_cachefilename = $cachefilename . '3gwap/';
                $wapdirname = opendir($wap_cachefilename);
                while ($val = readdir($wapdirname)) {
                    if ($val == '.' || $val == '..') {
                        continue;
                    }
                    $value = $wap_cachefilename . $val;
                    unlink($value);
                }
                closedir($wapdirname);
            }
            return true;
        } else {
            return false;
        }
    }

    public function cleartemplates($iswap = false) {
        $cachefilename = $this->tpl_c_dir;
        if (file_exists($cachefilename)) {
            $dirname = opendir($cachefilename);
            while ($val = readdir($dirname)) {
                if ($val == '.' || $val == '..') {
                    continue;
                }
                $value = $cachefilename . $val;
                unlink($value);
            }
            closedir($dirname);
            if ($iswap) {
                $wap_cachefilename = $this->wap_tpl_c_dir;
                $wapdirname = opendir($wap_cachefilename);
                while ($val = readdir($wapdirname)) {
                    if ($val == '.' || $val == '..') {
                        continue;
                    }
                    $value = $wap_cachefilename . $val;
                    unlink($value);
                }
                closedir($wapdirname);
            }
            return true;
        } else {
            return false;
        }
    }

    public function power($funtionname = null) {
        return ESPCMS_AdminAuthority::authorityVerify($funtionname);
    }

    public function isadmin() {
        return ESPCMS_AdminAuthority::authorityIsAdminVerify();
    }

    public function format_size($size, $type = 0) {
        if ($size < 1000) {
            $size_BKM = (string)$size . ' B';
        } elseif ($size < (1000 * 1000)) {
            $size_BKM = number_format((double)($size / 1000), 1) . ' KB';
        } else {
            $size_BKM = number_format((double)($size / (1000 * 1000)), 1) . ' MB';
        }
        return $size_BKM;
    }

    public function checkvol($volarray = null, $vol = null) {
        if (empty($vol) || empty($volarray)) {
            return false;
        }
        $volarray = explode(',', $volarray);
        if (!in_array($vol, $volarray)) {
            return false;
        } else {
            return true;
        }
    }

    private function imp($str, $type = '/') {
        if (empty($str) || !is_array($str)) {
            return false;
        } else {
            $restr = implode($type, $str);
        }
        return $restr;
    }

    private function getMimeType($file) {
        return is_dir($file) ? $file : $this->mime($file);
    }

    private function mime($file) {
        $file = realpath($file);
        $options = pathinfo($file, PATHINFO_EXTENSION);
        return $options;
    }
}
