'; /** * file * * @var string */ protected $file; /** * path * * @var string */ protected $path; /** * template * * @var string */ protected $template; /** * content * * @var array */ protected $content; /** * update * * @var bull */ protected $update = false; /** * load file * @param string $file * @param string $path * @param string $service * @param string $project * * @return mixed */ public function __construct($file, $template, $service, $project = false, $path = '') { $this->path = $path; $this->project($project); $this->file = $this->path($path . $file) . '.cmp.php'; Debug::log($this->file); $this->read($file, $template, $service); } /** * read file * @param string $file * @param string $path * @param string $service * @param bool $local * * @return mixed */ public function read($file, $path, $service, $local = false) { if(strpos($file, 'http://')) { $content = file_get_contents($file); # 增加抓取功能 本地化 if($local == true) { $content = $this->local($content); } $this->template = $content; } else { $this->template = $path . $file . '.html'; if(is_file($this->template)) { $is_service = is_file($service); $time = is_file($this->file) ? filemtime($this->file) : 0; $this->update = defined('MAZE_COMPILE'); if(filemtime($this->template) > $time || ($is_service && filemtime($service) > $time)) { # 可以更新 $this->update = true; } if($time == 0 || $this->update == true) { $content = $this->readContent($path); } if(!empty($content) && !$is_service) { return $this->create($content); } } else { # 当文件不存在时 $this->update = false; } } } /** * readContent 获取当前模板的内容 * * @return string */ public function readContent($path) { # 这里直接用content传过去效率高 $content = file_get_contents($this->template); if(strpos($content, '@include:') !== false) { $temp = explode('@include:', $content); $file = end($temp); $this->template = $path . $file . '.html'; $content = file_get_contents($this->template); } # 远程读取 elseif(strpos($content, '@url:') !== false) { //$config = $content; $content = str_replace("\n", '', $content); $temp = explode('@url:', $content); $this->template = end($temp); //$this->template = end(explode('@url:', $config)); $content = file_get_contents($this->template); # 增加资源处理功能 @res:replace 将资源中的路径替换为带有域名的路径 @res:local 本地化 if(strpos($temp[0], '@res:') !== false) { $temp = explode('@res:', $temp[0]); $content = $this->res(end($temp), $content, $this->template, $path); } } $this->template = $content; return $content; } /** * res 资源处理 此处待优化 * * @return string */ private function res($type, $content, $url, $path) { //return $content; $encode = mb_detect_encoding($content, array('GB2312','GBK','UTF-8')); if($encode == 'GB2312' || $encode == 'GBK' || $encode == 'EUC-CN' || $encode == 'CP936') { $content = iconv('GBK', 'UTF-8', $content); } # 过滤换行 $content = str_replace(PHP_EOL, '', $content); if($type == 'local') { # 规则 $rule = ' $v) { $content = $this->replace($k, $v, $content); } } else { parse_str($type, $param); foreach($param as $k => $v) { $content = $this->replace($k, $v, $content); } } return $content; } /** * get file * * @return string */ public function file() { return $this->file; } /** * get template or content * * @return string */ public function template() { return $this->template; } /** * project * * @return string */ public function project($project = false) { $this->project = $project ? $project : MAZE_PROJECT_NAME; return $this->project; } /** * path create path * @param string $file * @param string $project * * @return string */ public function path($file, $path = 'compile') { return Path::create(MAZE_PATH . 'data/' . $path . '/' . $this->project . '/', $file); } /** * get * * @return mixed */ public function get() { if($this->update == false && is_file($this->file)) { ob_start(); require $this->file; $content = ob_get_contents(); ob_end_clean(); return $content; } elseif($this->update == false) { return ''; } else { return false; } } /** * load view * * @param string $service * @return \Maze\Template\View */ public function load($file, $path = '') { $desc = ''; $view = View::getInstance($file); if($path) { $view->path($path); } else { $view->path($this->path); } $view->runing(); $file = $view->file(); if($file) { return $desc . $this->script('require MAZE_PATH . \'' . str_replace(MAZE_PATH, '', $file) . '\'') . $desc; } } /** * create * @param string $content * * @return string */ public function create($content) { $this->update = false; if($this->content) { $content = implode("\n", $this->content) . "\n" . $content; } $this->write($this->assets($content)); return $this->get(); } /** * write * * @return mixed */ public function write($content) { $content = preg_replace('//s', '', $content); if(isset(Config::$global['host']['merge']) && Config::$global['host']['merge'] && strpos($content, Config::$global['host']['assets']) !== false) { $this->merge ( array('', ''), $content ); } $copyright = ''; file_put_contents($this->file, $copyright . $content); @chmod($this->file, 0755); system('chmod -R ' . $this->file . ' 777'); } /** * assets * @param string $content * * @return string */ public function assets($content) { if(isset(Config::$global['base']['replace']) && is_array(Config::$global['base']['replace'])) { foreach(Config::$global['base']['replace'] as $k => $v) { if(isset(Config::$global['host'][$k])) { $content = $this->replace($v, Config::$global['host'][$k], $content); } } } return $content; } /** * merge * * @return string */ private function merge($rule, &$content) { foreach($rule as $k => $v) { $v = '/' . $v . '/i'; preg_match_all($v, $content, $result); //print_r($result); if(isset($result[2]) && $result[2]) { if($k == 1) { $ext = 'js'; $fext = ';'; } else { $ext = 'css'; $fext = ''; } $file = md5($this->file) . '.' . $ext; $host = Config::$global['host']['merge'] . $this->project . '/' . $file . '?v' . MAZE_TIME; $file = $this->path($file, 'assets'); $assets = ''; foreach($result[2] as $fk => $fv) { if($fv) { $fv = str_replace(Config::$global['host']['assets'], Config::$global['base']['assets'], $fv); $assets .= file_get_contents($fv) . $fext; if(strpos($content, '{{file}}') === false) { $content = str_replace($result[0][$fk], '{{file}}', $content); } else { $content = str_replace($result[0][$fk], '', $content); } } } if($assets) { $method = 'zip_' . $ext; $assets = $this->assets($assets); file_put_contents($file, $this->$method($assets)); } $file = $k == 1 ? '' : ''; //$content = $this->zip_css($content); $content = str_replace('{{file}}', $file, $content); } } } /** * zip_css * @param string $string * * @return string */ private function zip_css($string) { return str_replace(array("\t", "\r\n", "\r", "\n"), '', $string); } /** * zip_js * @param string $string * * @return string */ private function zip_js($string) { return $string; $h1 = 'http://'; $s1 = '【:??】'; $h2 = 'https://'; $s2 = '【s:??】'; $string = preg_replace('#function include([^}]*)}#isU','',$string);//include函数体 $string = preg_replace('#\/\*.*\*\/#isU','',$string);//块注释 $string = str_replace($h1,$s1,$string); $string = str_replace($h2,$s2,$string); $string = preg_replace('#\/\/[^\n]*#','',$string);//行注释 $string = str_replace($s1,$h1,$string); $string = str_replace($s2,$h2,$string); $string = preg_replace('#\s?(=|>=|\?|:|==|\+|\|\||\+=|>|<|\/|\-|,|\()\s?#','$1',$string);//字符前后多余空格 $string = $this->zip_css($string); $string = trim($string," "); return $string; } /** * script * @param string $string * * @return string */ public function script($string) { return self::left . $string . self::right; } /** * equal * @param string $variable * @param string $value * @param string $key * * @return string */ public function equal($variable, $value, $key = '') { if(strpos($key, '$') !== false) { $variable .= '['.$key.']'; } elseif($key) { $variable .= '[\''.$key.'\']'; } if(is_array($value)) { $value = var_export($value, true); } elseif(is_string($value) && strpos($value, '"') !== false) { $value = '\'' . $value . '\''; } return $this->script('$' . $variable . '=' . $value); } /** * data * @param string $data * * @return mixed */ public function data($data) { if(is_object($data)) { return $data(); /* $this->set('$test', $data); return '<{$test}>'; */ } $type = $this->strip($data); # include page if(strpos($type, '@') !== false) { return explode('@', $type); } # include database|model elseif(strpos($type, 'http://') === false && strpos($type, '/') !== false && (strpos($type, '.') !== false || strpos($type, '-') !== false)) { $key = $type; if(strpos($type, '|') !== false) { if(strpos($type, '!') !== false) { $type = str_replace('!', '$', $type . ''); } $temp = explode('|', $type); $type = $temp[0]; parse_str($temp[1], $param); // print_r($param);die; } $callback = 'Maze\\Routing\\Load::get(\'' . $type . '\')'; if(isset($param)) { $param = var_export($param, true); $callback = str_replace(')', ', '.$param.')', $callback); if(strpos($callback, '$') !== false) { $callback = preg_replace('/\'\$(.*?)\'/', '\$$1', $callback); } } $this->push($key, $this->equal('data', $callback, $key)); return true; } return $data; } /** * out echo variable * @param string $variable * * @return string */ public function out($variable) { return $this->script('echo $' . $variable); } /** * each * @param string $replace * @param string $data * @param string $content * * @return string */ public function each($replace, $data, $content) { if($replace) { $strip = $this->strip($replace); if($strip && strpos($replace, $strip) !== false) { $replace = $strip; } } # 增加数组和非数组的判断,如果这里效率不高,以后可以优化,去掉第一行和最后三行即可 return $this->script('if(is_array($data[\''.$data.'\'])):') .$this->equal('t', 'count($data[\''.$data.'\'])-1') .$this->equal('i', 0) .$this->script('foreach($data[\''.$data.'\'] as $k => $v):') //.$this->replace($replace, $this->out('v'), $content) .$content .$this->equal('i', '$i+1') .$this->script('endforeach;') .$this->script('else:') .$this->replace($replace, $this->out('data[\''.$data.'\']'), $content) .$this->script('endif;'); } /** * content * @param string $content * * @return string */ public function content($content, $data = false) { $echo = ' echo '; $content = $this->rule($content); $content = $this->replace('<{', self::left . $echo, $this->replace('}>', self::right, $content)); $array = array('function', 'foreach', 'endforeach', 'if', 'endif', 'else', 'for', 'endfor', 'highlight_string', 'echo', 'print_r'); foreach($array as $k => $v) { if(strpos($content, self::left . $echo . $v) !== false) { $content = $this->replace(self::left . $echo . $v, self::left . $v, $content); } } if(strpos($content, '{self}') !== false) { $content = $this->replace('{self}', '$data[\'' . $data . '\']', $content); } return $content; } /** * logic * @param string $logic * @param string $string * * @return string */ public function logic($logic, $string) { # 这里暂时这样判断,以后再处理多种逻辑情况的 if(strpos($logic, '|') !== false) { list($handle, $logic) = explode('|', $logic); if($logic == 'foreach') { $string = '<{if(isset('.$handle.') && is_array('.$handle.')):foreach('.$handle.' as $ki => $vi):}>' . $string . '<{endforeach;endif;}>'; } elseif($logic == 'if') { $string = '<{if(isset('.$handle.') && '.$handle.'):}>' . $string . '<{endif;}>'; } else { $string = '<{'.$handle.'}>' . $string . '<{'.$logic.'}>'; } } else { $string = '<{if(isset('.$logic.') && is_array('.$logic.')):foreach('.$logic.' as $ki => $vi):}>' . $string . '<{endforeach;endif;}>'; } return $this->content($string); } /** * replace * @param string $replace * @param string $value * @param string $content * * @return string */ public function replace($replace, $value, $content) { if(!$replace) { return $value; } $content = str_replace($replace, $value, $content); /* if(strpos($content, $replace) !== false && strpos($content, $replace) !== false) { $content = str_replace($replace, $value, $content); } */ return $content; } /** * push * @param string $value * * @return string */ public function push($key, $value) { $this->content[$key] = $value; } /** * set * @param string $value * * @return string */ public function set($key, $value = false) { if(!$value) { return $this->push($key, $this->script($this->rule($key))); } if(is_string($value)) { if(strpos($value, 'Maze') === false) { $value = var_export($value, true); } $value = $this->rule($value); } elseif(is_object($value)) { $value = $value(); } $this->push($key, $this->script($this->rule($key) . '=' . $value . '')); } /** * tag * @param string $key * @param string $data * * @return string */ public function tag($key, $data = false) { if($data) { $result = $data[$key]; } else { $result = $key; } return $result; } /** * handle * @param string $data * @param string $content * @param string $expression * * @return string */ public function handle($data, $content, $expression = '') { $result = ''; if(is_array($data)) { $tags = $this->strip($content); foreach($data as $k => $v) { $result .= $this->replace($tags, $v, $content); } } else { $index = false; if(is_string($data) && strpos($data, '#') > 0 && strpos($data, '"') === false) { list($data, $index) = explode('#', $data); } $method = $this->data($data); if($method === true) { $result = $this->complex($data, $content, $index, $expression); } elseif(is_array($method)) { $result = $this->load($method[1], $method[0]); } elseif($method && (is_string($method) || is_numeric($method))) { $method = $this->content($method); $result = $this->replace($content, $method, $content); if($result == $content) { //$result = $this->replace($this->strip($content), $method, $content); } } elseif(!$result && (is_string($data) || is_numeric($data))) { $data = $this->content($data); $result = $this->replace($this->strip($content), $data, $content); } else { $result = $content; } } return $result; } /** * complex * @param string $data * @param string $content * @param string $index * @param string $expression * * @return string */ public function complex($data, $content, $index = false, $expression = '') { if($index) { $strip = $this->strip($content); $result = $this->out('data[\''.$data.'\'][\''.$index.'\']'); if($strip == $content) { $result = $this->replace($strip, $result, $content); } } else { if($expression) { $content = $this->replace($expression, $this->out('v'), $content); } $result = $this->each($content, $data, $this->content($content)); } return $result; } /** * rule * @param string $content * * @return string */ public function rule($content) { if(strpos($content, 'request.') !== false) { $content = preg_replace('/request\.([a-zA-Z0-9]+)/', 'Maze::input(\'$1\')', $content); } if(strpos($content, '$') !== false && strpos($content, '.') !== false) { $rule = '\$([a-zA-Z0-9]+)\.([a-zA-Z0-9._]+)'; $content = preg_replace_callback('/' . $rule . '/i', array($this, 'rule_val'), $content); } if(strpos($content, '"+') !== false) { $content = str_replace(array('"+','+"'), array('".', '."'), $content); } if(strpos($content, '++') !== false) { $content = str_replace('++', '.', $content); } if(strpos($content, '<{$') !== false) { //$content = str_replace('<{$', '<{echo $', $content); } return $content; } /** * rule_val * @param array $result * * @return string */ public function rule_val($result) { if(isset($result[2]) && $result[2]) { $result[2] = '$' . $result[1] . '' . preg_replace('/\.([a-zA-Z0-9_]+)/', '[\'$1\']', '.' . $result[2]); return $result[2]; } return $result[0]; } /** * strip * @param string $content * * @return string */ public function strip($content) { if(is_string($content)) { return strip_tags($content); } return $content; } }