templates_dir = (substr($templates_dir, -1) != '/' ? $templates_dir.'/' : $templates_dir); if(is_dir($compiled_templates_dir))$this -> compiled_templates_dir = (substr($compiled_templates_dir, -1) != '/' ? $compiled_templates_dir.'/' : $compiled_templates_dir); $this -> templates_ext = $templates_ext; } /** * __set * * Установка переменных, доступных в шаблоне * * @param string $var_name имя переменной * @param string $var_value значение переменной **/ public function __set($var_name, $var_value) { $this -> vars[$var_name] = $var_value; } /** * __get * * Получения значения переменной * * @param string $var_name имя переменной * @return mixed значение переменной **/ public function __get($var_name) { if(isset($this -> vars[$var_name]))return $this -> vars[$var_name]; return false; } /** * __set * * Установка переменных, доступных в шаблоне * * @param string $var_name имя переменной * @param string $var_value значение переменной **/ public function assign($var_name, $var_value = false) { if(is_array($var_name) && $var_value == false) { foreach($var_name as $name => $value) { $this -> assign($name, $value); } } else { $this -> vars[$var_name] = $var_value; } return true; } /** * debug * * Просмотр значений всех переменных * * @param bool $exit требуется ли завершение работы скрипта **/ public function debug($exit = true) { echo 'templates_dir = '.$this -> templates_dir.'
'; echo 'templates_ext = '.$this -> templates_ext.'
'; print_r($this -> vars); if($exit)exit; return true; } /** * display * * Обработка шаблона, и вывод на экран * * @param string $template_name имя файла-шаблона * @return bool возникли ли ошибки **/ public function display($template_name) { if(!file_exists($this -> templates_dir.$template_name.'.'.$this -> templates_ext))return false; if($this -> debug_compiler || (!file_exists($this -> compiled_templates_dir.$template_name.'.'.$this -> templates_ext.'.php') || filemtime($this -> compiled_templates_dir.$template_name.'.'.$this -> templates_ext.'.php') < filemtime($this -> templates_dir.$template_name.'.'.$this -> templates_ext))) { if(!isset($this -> cfgs[$template_name]))$this -> cfgs[$template_name] = array(); // генерируем php файл из шаблона $content = $this -> prepare_tpl($template_name); // вставляем комментарий $content = ' compiled_templates_dir.$template_name.'.'.$this -> templates_ext.' */ ?>'.EOL.$content; if(!file_put_contents($this -> compiled_templates_dir.$template_name.'.'.$this -> templates_ext.'.php', $content))return false; } #if(!isset($content))$content = file_get_contents($this -> compiled_templates_dir.$template_name.'.'.$this -> templates_ext.'.php'); require $this -> compiled_templates_dir.$template_name.'.'.$this -> templates_ext.'.php'; #if($this -> debug_compiler)unlink($this -> compiled_templates_dir.$template_name.'.'.$this -> templates_ext.'.php'); return true; } /** * prepare_tpl * * Обработка шаблона * * @param string $filename имя файла-шаблона * @return string PHP-код шаблона **/ private function prepare_tpl($filename) { $code = file_get_contents($this -> templates_dir.$filename.'.'.$this -> templates_ext); #d($code); // блоки $code = $this -> process_blocks($code, $filename); // циклы $code = $this -> process_cycles($code, $filename); // условия $code = $this -> process_ifs($code); // переменные $code = $this -> process_vars($code); #d($code); return $code; } /** * process_blocks * * обработка блоков в шаблоне типа * {block index} * ... * {/block index} * в switch ... case ... break ... endswtich; * * * @param string $code код шаблона * @return string обработанный код **/ private function process_blocks($code) { $new_code = $code; // циклы preg_match_all('~\{block ((\!)?([^!]*))\}(.*)\{\/block \\1\}~uUs', $code, $blocks, PREG_SET_ORDER ^ PREG_OFFSET_CAPTURE); #d($blocks,0); $use_blocks = false; // код до/после/между блоками $after_code = $before_code = $rest = null; $count_blocks = count($blocks); if($count_blocks > 0) { $use_blocks = true; $lenght_shift = 0; for($i = 0;$i < $count_blocks;$i ++) { if($i == 0 && $blocks[$i][0][1] > 0) { // записываем код "до" $after_code = trim(substr($code, 0, $blocks[$i][0][1])); #d(substr($code, $blocks[$i][0][1])); $code = substr($code, $blocks[$i][0][1]); $lenght_shift = strlen($after_code); #d(trim(substr($code, 0, $blocks[$i][0][1])),0); #$result = null; } if($blocks[$i][2][0] == '!') { #d($blocks[$i],0); $result_code = ' vars[\'block\'] != \''.$blocks[$i][3][0].'\'): ?>'.EOL; $result_code .= $blocks[$i][4][0]; $result_code .= EOL.''.EOL; if($i == 0)$after_code .= $result_code; else $before_code .= $result_code; $result = null; } else { $result = ''.EOL; $result .= $blocks[$i][4][0]; $result .= EOL.''.EOL; #d($blocks[$i],0); #d($result,0); } if(($i + 1) == $count_blocks && ($blocks[$i][0][1] + strlen($blocks[$i][0][0])) < strlen($new_code)) { // записываем код "после" $before_code .= trim(substr($code, ($blocks[$i][0][1] + strlen($blocks[$i][0][0])) + $lenght_shift)); $code = trim(substr($code, 0, ($blocks[$i][0][1] + strlen($blocks[$i][0][0])) - $lenght_shift)); #d(($blocks[$i][0][1] + strlen($blocks[$i][0][0])),0); #d($blocks[$i]); #$result = null; } $code = preg_replace('~'.preg_quote($blocks[$i][0][0], '~').'~uUs', $result, $code, 1); } } if($use_blocks) { $code = (!empty($after_code) ? $after_code.EOL : null).' vars[\'block\']): ?>'."\r\n".$code.''.(!empty($before_code) ? EOL.$before_code : null); /*$code = ' vars[\'block\']): ?>'."\r\n".$code.'';*/ } #d($after_code,0); #d($before_code,0); return $code; } /** * process_ifs * * обработка условий в шаблоне * {if $somevar} * ... * {/if $somevar} * в if(...) ... endif; * * * @param string $code код шаблона * @return string обработанный код **/ private function process_ifs($code) { // условии preg_match_all('~\{if ((\!)?(\~)?\$((.+)(\.(.*))?)( (.*) (\$((.+)(\.(.*))?)|.+))?)\}(?:\r\n|\n)?(.*)(?:\r\n|\n)?\{\/if \\1\}~uUs', $code, $ifs, PREG_SET_ORDER); $count_ifs = count($ifs); if($count_ifs > 0) { for($i = 0;$i < $count_ifs;$i ++) { $var = $this -> get_var($ifs[$i][4], false); $chapter1 = 'isset('.$var.') && '; if(!empty($ifs[$i][10])) { // если это переменная if($ifs[$i][10] == '$'.$ifs[$i][11]) { $var2 = $this -> get_var($ifs[$i][11], false); $chapter1 .= 'isset('.$var2.') && '; $strlen = strlen($ifs[$i][10]); $chapter2 = $var.substr($ifs[$i][8], 0, -$strlen).$var2; } else { $chapter2 = $var.$ifs[$i][8]; } } else { if($ifs[$i][2] == '!') { $chapter1 = '!isset('.$var.') || '; if($ifs[$i][3] == '~')$chapter2 = '!(bool)'.$var; else $chapter2 = $var.' !== true'; } else { if($ifs[$i][3] == '~')$chapter2 = '(bool)'.$var; else $chapter2 = $var.' === true'; } #if($ifs[$i][3] == '~')$chapter2 = ($ifs[$i][2] == '!' ? '!' : null).'(bool)'.$var; #else $chapter2 = $var.($ifs[$i][2] == '!' ? '!' : '=').'== true'; } $result = ''; $result .= $this -> process_ifs($ifs[$i][15]); $result .= ''; $code = preg_replace('~'.preg_quote($ifs[$i][0], '~').'~uUs', $result, $code, 1); } } return $code; } /** * process_cycles * * обработка циклов в шаблоне типа * {foreach $a} * ... * {/foreach $a} * в for(...) ... endfor; * * @param string $code код шаблона * @return string обработанный код **/ private function process_cycles($code, $template) { // циклы preg_match_all('~\{foreach (\$(.*))\}(?:\r\n|\n)?(.*)(?:\r\n|\n)?\{\/foreach \\1\}~uUs', $code, $cycles, PREG_SET_ORDER); #d($cycles); $count_cycles = count($cycles); if($count_cycles > 0) { for($i = 0;$i < $count_cycles;$i ++) { $result = null; $var = $this -> get_var($cycles[$i][2], false); #eval('$is_set = isset('.$var.');'); #eval('$array = (isset('..'))'.$var.';'); $last_value = (isset($this -> cfgs['cycles_values']['last_value'])) ? ($this -> cfgs['cycles_values']['last_value'] + 1) : 1; $this -> cfgs['cycles_values']['last_value'] = $last_value; $index = '_cycles_'.$last_value; /*#$this -> vars[$index] = $array; #d('{$'.preg_quote($cycles[$i][2], '~').'(.*)}'); #d($this -> get_recursive_values($array)); #d($index,0); */ $cycles[$i][3] = preg_replace('~\{\$'.preg_quote($cycles[$i][2], '~').'\.(.+)\}~uUs', '', $cycles[$i][3]); $cycles[$i][3] = preg_replace('~if (\!)?(\~)?\$'.preg_quote($cycles[$i][2], '~').'\.(.*)~uUs', 'if $1$2$'.$cycles[$i][2].'.$'.$index.'_i.$3', $cycles[$i][3]); // if ($'.$index.'[\'$2\'] #$count_values = count($array); $result = ''.EOL; $result .= ' '.EOL; $result .= ' '.EOL; $result .= $this -> process_cycles($cycles[$i][3], $template); $result .= ' '.EOL; $result .= ''; $code = preg_replace('~'.preg_quote($cycles[$i][0], '~').'~uUs', $result, $code, 1); } } return $code; } /** * process_vars * * обработка переменных в шаблоне типа * {$somevar} * в echo $somevar; * * @param string $code код шаблона * @return string обработанный код **/ private function process_vars($code) { preg_match_all('~\{\$(.+)\}~uUs', $code, $vars, PREG_SET_ORDER); $count_vars = count($vars); if($count_vars > 0) { for($i = 0;$i < $count_vars;$i ++) { $var = $this -> get_var($vars[$i][1], false); #$result = null; #if(!empty($var)) # { $result = ''; # } $code = preg_replace('~'.preg_quote($vars[$i][0], '~').'~uUs', $result, $code, 1); } } return $code; } /** * get_var * * форматирование переменной типа * $one.two.three * в $this -> vars['one']['two']['three'] * * @param string $code код шаблона * @return string обработанный код **/ private function get_var($string_var, $isset = true, $type = false) { // разбиваем строку на секции $sections = explode('.', $string_var); $count_sections = count($sections); if($count_sections > 0) { $var = null; for($i = 0;$i < $count_sections;$i ++) { if(substr($sections[$i], 0, 1) == '$' || is_numeric($sections[$i]))$var .= '['.$sections[$i].']'; else $var .= '[\''.$sections[$i].'\']'; } #eval('$var = \'[\\\'\'.implode(\'\\\'][\\\'\', $sections).\'\\\']\';'); if(!$isset)return '$this -> vars'.$var; eval('$is_set = isset($this -> vars'.$var.');'); $is_type = true; if($is_set && is_string($type))eval('$is_type = is_'.$type.'($this -> vars'.$var.');'); if($is_set && $is_type) { return '$this -> vars'.$var; } return 0; } return 0; } } # Morgan ?>