From 5d797a51e4decf90ba90d5eddebb85d14770bc73 Mon Sep 17 00:00:00 2001 From: taggon Date: Fri, 21 Oct 2011 07:29:45 +0000 Subject: [PATCH] issue 38: format code style git-svn-id: http://xe-core.googlecode.com/svn/branches/1.5.0@9705 201d5d3c-b55e-5fd7-737f-ddc643e51545 --- classes/template/TemplateHandler.class.php | 967 +++++++++++---------- 1 file changed, 484 insertions(+), 483 deletions(-) diff --git a/classes/template/TemplateHandler.class.php b/classes/template/TemplateHandler.class.php index 59e6fb1ff..3f234f88c 100644 --- a/classes/template/TemplateHandler.class.php +++ b/classes/template/TemplateHandler.class.php @@ -1,561 +1,562 @@ xe_path = rtrim(preg_replace('/([^\.^\/]+)\.php$/i','',$_SERVER['SCRIPT_NAME']),'/'); + } + + /** + * @brief returns TemplateHandler's singleton object + * @return TemplateHandler instance + **/ + function &getInstance() + { + static $oTemplate = null; + + if(__DEBUG__==3 ) { + if(!isset($GLOBALS['__TemplateHandlerCalled__'])) $GLOBALS['__TemplateHandlerCalled__']=1; + else $GLOBALS['__TemplateHandlerCalled__']++; + } + + if(!$oTemplate) $oTemplate = new TemplateHandler(); + + return $oTemplate; + } + + /** + * @brief set variables for template compile + **/ + function init($tpl_path, $tpl_filename, $tpl_file='') + { + // verify arguments + if(substr($tpl_path,-1)!='/') $tpl_path .= '/'; + if(!file_exists($tpl_path.$tpl_filename)&&file_exists($tpl_path.$tpl_filename.'.html')) $tpl_filename .= '.html'; + + // create tpl_file variable + if(!$tpl_file) $tpl_file = $tpl_path.$tpl_filename; + + // set template file infos. + $this->path = $tpl_path; + $this->filename = $tpl_filename; + $this->file = $tpl_file; + + $this->web_path = $this->xe_path.'/'.ltrim(preg_replace('@^'.preg_quote(_XE_PATH_,'@').'|\./@','',$this->path),'/'); + + // get compiled file name + $hash = md5($this->file . __ZBXE_VERSION__); + $this->compiled_file = "{$this->compiled_path}{$hash}.compiled.php"; + + // compare various file's modified time for check changed + $this->handler_mtime = filemtime(__FILE__); + + $skip = array(''); + } + + /** + * @brief compiles specified tpl file and execution result in Context into resultant content + * @param[in] $tpl_path path of the directory containing target template file + * @param[in] $tpl_filename target template file's name + * @param[in] $tpl_file if specified use it as template file's full path + * @return Returns compiled result in case of success, NULL otherwise + */ + function compile($tpl_path, $tpl_filename, $tpl_file='') { + global $__templatehandler_root_tpl; + + $buff = ''; + + // store the starting time for debug information + if(__DEBUG__==3 ) $start = getMicroTime(); + + // initiation + $this->init($tpl_path, $tpl_filename, $tpl_file); + + // if target file does not exist exit + if(!$this->file || !file_exists($this->file)) return "Err : '{$this->file}' template file does not exists."; + + // for backward compatibility + if(is_null($__templatehandler_root_tpl)) { + $__templatehandler_root_tpl = $this->file; + } + + $source_template_mtime = filemtime($this->file); + $latest_mtime = $source_template_mtime>$this->handler_mtime?$source_template_mtime:$this->handler_mtime; + + // cache control + $oCacheHandler = &CacheHandler::getInstance('template'); + + // get cached buff + if($oCacheHandler->isSupport()){ + $cache_key = 'template:'.$this->file; + $buff = $oCacheHandler->get($cache_key, $latest_mtime); + } else { + if(is_readable($this->compiled_file) && filemtime($this->compiled_file)>$latest_mtime && filesize($this->compiled_file)) { + $buff = 'file://'.$this->compiled_file; + } + } + + if(!$buff) { + $buff = $this->parse(); + if($oCacheHandler->isSupport()) $oCacheHandler->put($cache_key, $buff); + else FileHandler::writeFile($this->compiled_file, $buff); + } + + $output = $this->_fetch($buff); + + if($__templatehandler_root_tpl == $this->file) { $__templatehandler_root_tpl = null; - - $this->xe_path = rtrim(preg_replace('/([^\.^\/]+)\.php$/i','',$_SERVER['SCRIPT_NAME']),'/'); } - /** - * @brief returns TemplateHandler's singleton object - * @return TemplateHandler instance - **/ - function &getInstance() - { - static $oTemplate = null; + // store the ending time for debug information + if(__DEBUG__==3 ) $GLOBALS['__template_elapsed__'] += getMicroTime() - $start; - if(__DEBUG__==3 ) { - if(!isset($GLOBALS['__TemplateHandlerCalled__'])) $GLOBALS['__TemplateHandlerCalled__']=1; - else $GLOBALS['__TemplateHandlerCalled__']++; - } + return $output; + } - if(!$oTemplate) $oTemplate = new TemplateHandler(); + /** + * @brief compile specified file and immediately return + * @param[in] $tpl_path path of the directory containing target template file + * @param[in] $tpl_filename target template file's name + * @return Returns compiled content in case of success or NULL in case of failure + **/ + function compileDirect($tpl_path, $tpl_filename) { + $this->init($tpl_path, $tpl_filename, null); - return $oTemplate; - } - - /** - * @brief set variables for template compile - **/ - function init($tpl_path, $tpl_filename, $tpl_file='') - { - // verify arguments - if(substr($tpl_path,-1)!='/') $tpl_path .= '/'; - if(!file_exists($tpl_path.$tpl_filename)&&file_exists($tpl_path.$tpl_filename.'.html')) $tpl_filename .= '.html'; - - // create tpl_file variable - if(!$tpl_file) $tpl_file = $tpl_path.$tpl_filename; - - // set template file infos. - $this->path = $tpl_path; - $this->filename = $tpl_filename; - $this->file = $tpl_file; - - $this->web_path = $this->xe_path.'/'.ltrim(preg_replace('@^'.preg_quote(_XE_PATH_,'@').'|\./@','',$this->path),'/'); - - // get compiled file name - $hash = md5($this->file . __ZBXE_VERSION__); - $this->compiled_file = "{$this->compiled_path}{$hash}.compiled.php"; - - // compare various file's modified time for check changed - $this->handler_mtime = filemtime(__FILE__); - - $skip = array(''); + // if target file does not exist exit + if(!$this->file || !file_exists($this->file)) { + Context::close(); + exit("Cannot find the template file: '{$this->file}'"); } - /** - * @brief compiles specified tpl file and execution result in Context into resultant content - * @param[in] $tpl_path path of the directory containing target template file - * @param[in] $tpl_filename target template file's name - * @param[in] $tpl_file if specified use it as template file's full path - * @return Returns compiled result in case of success, NULL otherwise - */ - function compile($tpl_path, $tpl_filename, $tpl_file='') { - global $__templatehandler_root_tpl; + return $this->parse(); + } - $buff = ''; + /** + * @brief compile a template file specified in $tpl_file and + * @pre files specified by $tpl_file exists. + * @param[in] $tpl_file path of tpl file + * @param[in] $compiled_tpl_file if specified, write compiled result into the file + * @return compiled result in case of success or NULL in case of error + **/ + function parse($buff=null) { + if(is_null($buff)) { + if(!is_readable($this->file)) return; - // store the starting time for debug information - if(__DEBUG__==3 ) $start = getMicroTime(); + // read tpl file + $buff = FileHandler::readFile($this->file); + } - // initiation - $this->init($tpl_path, $tpl_filename, $tpl_file); + // HTML tags to skip + if(is_null($this->skipTags)) { + $this->skipTags = array('marquee'); + } - // if target file does not exist exit - if(!$this->file || !file_exists($this->file)) return "Err : '{$this->file}' template file does not exists."; + // replace comments + $buff = preg_replace('@@s', '', $buff); - // for backward compatibility - if(is_null($__templatehandler_root_tpl)) { - $__templatehandler_root_tpl = $this->file; - } + // replace value of src in img/input/script tag + $buff = preg_replace_callback('/<(?:img|input|script)(?:(?!["\'\/]\s*>).)* src="(?!https?:\/\/|[\/\{])([^"]+)"/is', array($this, '_replacePath'), $buff); - $source_template_mtime = filemtime($this->file); - $latest_mtime = $source_template_mtime>$this->handler_mtime?$source_template_mtime:$this->handler_mtime; + // replace loop and cond template syntax + $buff = $this->_parseInline($buff); - // cache control - $oCacheHandler = &CacheHandler::getInstance('template'); + // include, unload/load, import + $buff = preg_replace_callback('/{(@[\s\S]+?|(?=\$\w+|_{1,2}[A-Z]+|[!\(+-]|\w+(?:\(|::)|\d+|[\'"].*?[\'"]).+?)}|<(!--[#%])?(include|import|(un)?load(?(4)|(?:_js_plugin)?))(?(2)\("([^"]+)")(.*?)(?(2)\)--|\/)>|/', array($this, '_parseResource'), $buff); - // get cached buff - if($oCacheHandler->isSupport()){ - $cache_key = 'template:'.$this->file; - $buff = $oCacheHandler->get($cache_key, $latest_mtime); - } else { - if(is_readable($this->compiled_file) && filemtime($this->compiled_file)>$latest_mtime && filesize($this->compiled_file)) { - $buff = 'file://'.$this->compiled_file; - } - } + // remove block which is a virtual tag and remove comments + $buff = preg_replace('@|\s?@is','',$buff); - if(!$buff) { - $buff = $this->parse(); - if($oCacheHandler->isSupport()) $oCacheHandler->put($cache_key, $buff); - else FileHandler::writeFile($this->compiled_file, $buff); - } + // form auto generation + $buff = preg_replace_callback('/(|[^<>]+)*?>)(.*?)(<\/form>)/is', array($this, '_compileFormAuthGeneration'), $buff); - $output = $this->_fetch($buff); + // prevent from calling directly before writing into file + $buff = ''.$buff; - if($__templatehandler_root_tpl == $this->file) { - $__templatehandler_root_tpl = null; - } + return $buff; + } - // store the ending time for debug information - if(__DEBUG__==3 ) $GLOBALS['__template_elapsed__'] += getMicroTime() - $start; - - return $output; - } - - /** - * @brief compile specified file and immediately return - * @param[in] $tpl_path path of the directory containing target template file - * @param[in] $tpl_filename target template file's name - * @return Returns compiled content in case of success or NULL in case of failure - **/ - function compileDirect($tpl_path, $tpl_filename) { - $this->init($tpl_path, $tpl_filename, null); - - // if target file does not exist exit - if(!$this->file || !file_exists($this->file)) { - Context::close(); - exit("Cannot find the template file: '{$this->file}'"); - } - - return $this->parse(); - } - - /** - * @brief compile a template file specified in $tpl_file and - * @pre files specified by $tpl_file exists. - * @param[in] $tpl_file path of tpl file - * @param[in] $compiled_tpl_file if specified, write compiled result into the file - * @return compiled result in case of success or NULL in case of error - **/ - function parse($buff=null) { - if(is_null($buff)) { - if(!is_readable($this->file)) return; - - // read tpl file - $buff = FileHandler::readFile($this->file); - } - - // HTML tags to skip - if(is_null($this->skipTags)) { - $this->skipTags = array('marquee'); - } - - // replace comments - $buff = preg_replace('@@s', '', $buff); - - // replace value of src in img/input/script tag - $buff = preg_replace_callback('/<(?:img|input|script)(?:(?!["\'\/]\s*>).)* src="(?!https?:\/\/|[\/\{])([^"]+)"/is', array($this, '_replacePath'), $buff); - - // replace loop and cond template syntax - $buff = $this->_parseInline($buff); - - // include, unload/load, import - $buff = preg_replace_callback('/{(@[\s\S]+?|(?=\$\w+|_{1,2}[A-Z]+|[!\(+-]|\w+(?:\(|::)|\d+|[\'"].*?[\'"]).+?)}|<(!--[#%])?(include|import|(un)?load(?(4)|(?:_js_plugin)?))(?(2)\("([^"]+)")(.*?)(?(2)\)--|\/)>|/', array($this, '_parseResource'), $buff); - - // remove block which is a virtual tag and remove comments - $buff = preg_replace('@|\s?@is','',$buff); - - // form auto generation - $buff = preg_replace_callback('/(|[^<>]+)*?>)(.*?)(<\/form>)/is', array($this, '_compileFormAuthGeneration'), $buff); - - // prevent from calling directly before writing into file - $buff = ''.$buff; - - return $buff; - } - - /** - * @brief 1. remove ruleset from form tag - * 2. add hidden tag with ruleset value - * 3. if empty default hidden tag, generate hidden tag (ex:mid, vid, act...) - * 4. generate return url, return url use in server side validator - **/ - function _compileFormAuthGeneration($matches) + /** + * @brief 1. remove ruleset from form tag + * 2. add hidden tag with ruleset value + * 3. if empty default hidden tag, generate hidden tag (ex:mid, vid, act...) + * 4. generate return url, return url use in server side validator + **/ + function _compileFormAuthGeneration($matches) + { + // form ruleset attribute move to hidden tag + if($matches[1]) { - // form ruleset attribute move to hidden tag - if($matches[1]) + preg_match('/ruleset="([^"]*?)"/is', $matches[1], $m); + if($m[0]) { - preg_match('/ruleset="([^"]*?)"/is', $matches[1], $m); - if($m[0]) - { - $matches[1] = preg_replace('/'.$m[0].'/i', '', $matches[1]); - $matches[2] = ''.$matches[2]; + $matches[1] = preg_replace('/'.$m[0].'/i', '', $matches[1]); + $matches[2] = ''.$matches[2]; - if (strpos($m[1],'@') !== false){ - $path = str_replace('@', '', $m[1]); - $path = './files/ruleset/'.$path.'.xml'; - }else if(preg_match('@(?:^|\.?/)(modules/[\w-]+)@', $this->path, $mm)) { - $module_path = $mm[1]; - $path = $module_path.'/ruleset/'.$m[1].'.xml'; - } - //assign to addJsFile method for js dynamic recache - $matches[1] = ''.$matches[1]; + if (strpos($m[1],'@') !== false){ + $path = str_replace('@', '', $m[1]); + $path = './files/ruleset/'.$path.'.xml'; + }else if(preg_match('@(?:^|\.?/)(modules/[\w-]+)@', $this->path, $mm)) { + $module_path = $mm[1]; + $path = $module_path.'/ruleset/'.$m[1].'.xml'; } + //assign to addJsFile method for js dynamic recache + $matches[1] = ''.$matches[1]; } + } - // if not exists default hidden tag, generate hidden tag - preg_match_all('/]* name="(act|mid|vid)"/is', $matches[2], $m2); - $checkVar = array('act', 'mid', 'vid'); - $resultArray = array_diff($checkVar, $m2[1]); - if(is_array($resultArray)) + // if not exists default hidden tag, generate hidden tag + preg_match_all('/]* name="(act|mid|vid)"/is', $matches[2], $m2); + $checkVar = array('act', 'mid', 'vid'); + $resultArray = array_diff($checkVar, $m2[1]); + if(is_array($resultArray)) + { + $generatedHidden = ''; + foreach($resultArray AS $key=>$value) { - $generatedHidden = ''; - foreach($resultArray AS $key=>$value) - { - $generatedHidden .= ''; - } - $matches[2] = $generatedHidden.$matches[2]; + $generatedHidden .= ''; } - - // return url generate - preg_match('/]*name="error_return_url"[^>]*>/is', $matches[2], $m3); - if(!$m3[0]) $matches[2] = ''.$matches[2]; - - $matches[0] = ''; - return implode($matches); + $matches[2] = $generatedHidden.$matches[2]; } - /** - * @brief fetch using ob_* function - * @param[in] $compiled_tpl_file path of compiled template file - * @param[in] $buff if buff is not null, eval it instead of including compiled template file - * @param[in] $tpl_path set context's tpl path - * @return result string - **/ - function _fetch($buff) { - if(!$buff) return; + // return url generate + preg_match('/]*name="error_return_url"[^>]*>/is', $matches[2], $m3); + if(!$m3[0]) $matches[2] = ''.$matches[2]; - $__Context = &$GLOBALS['__Context__']; - $__Context->tpl_path = $this->path; + $matches[0] = ''; + return implode($matches); + } - if($_SESSION['is_logged']) { - $__Context->logged_info = Context::get('logged_info'); - } + /** + * @brief fetch using ob_* function + * @param[in] $compiled_tpl_file path of compiled template file + * @param[in] $buff if buff is not null, eval it instead of including compiled template file + * @param[in] $tpl_path set context's tpl path + * @return result string + **/ + function _fetch($buff) { + if(!$buff) return; - ob_start(); - if(substr($buff, 0, 7) == 'file://') { - include(substr($buff, 7)); - } else { - $eval_str = "?>".$buff; - eval($eval_str); - } + $__Context = &$GLOBALS['__Context__']; + $__Context->tpl_path = $this->path; - return ob_get_clean(); - } - - /** - * @brief change image path - * @pre $matches is an array containg three elements - * @param[in] $matches match - * @return changed result - **/ - function _replacePath($match) - { - $src = preg_replace('@^(\./)+@', '', trim($match[1])); - - $src = $this->web_path.$src; - $src = str_replace('/./', '/', $src); - - // for backward compatibility - $src = preg_replace('@((?:[\w-]+/)+)\1@', '\1', $src); - - while(($tmp=preg_replace('@[^/]+/\.\./@', '', $src))!==$src) $src = $tmp; - - return substr($match[0],0,-strlen($match[1])-6)."src=\"{$src}\""; + if($_SESSION['is_logged']) { + $__Context->logged_info = Context::get('logged_info'); } - function _parseInline($buff) - { - if(preg_match_all('/<([a-zA-Z]+\d?)(?>(?!<[a-z]+\d?[\s>]).)*?(?:[ \|]cond| loop)="/s', $buff, $match) === false) return $buff; + ob_start(); + if(substr($buff, 0, 7) == 'file://') { + include(substr($buff, 7)); + } else { + $eval_str = "?>".$buff; + eval($eval_str); + } - $tags = array_diff(array_unique($match[1]), $this->skipTags); + return ob_get_clean(); + } - if(!count($tags)) return $buff; + /** + * @brief change image path + * @pre $matches is an array containg three elements + * @param[in] $matches match + * @return changed result + **/ + function _replacePath($match) + { + $src = preg_replace('@^(\./)+@', '', trim($match[1])); - $tags = '(?:'.implode('|',$tags).')'; - $split_regex = "@(<(?>/?{$tags})(?>[^<>\{\}\"']+||{[^}]+}|\".*?\"|'.*?'|.)*?>)@s"; + $src = $this->web_path.$src; + $src = str_replace('/./', '/', $src); - $nodes = preg_split($split_regex, $buff, -1, PREG_SPLIT_DELIM_CAPTURE); + // for backward compatibility + $src = preg_replace('@((?:[\w-]+/)+)\1@', '\1', $src); - // list of self closing tags - $self_closing = explode(',', 'area,base,basefont,br,hr,input,img,link,meta,param,frame,col'); + while(($tmp=preg_replace('@[^/]+/\.\./@', '', $src))!==$src) $src = $tmp; - for($idx=1,$node_len=count($nodes); $idx < $node_len; $idx+=2) { - if(!($node=$nodes[$idx])) continue; + return substr($match[0],0,-strlen($match[1])-6)."src=\"{$src}\""; + } - if(preg_match_all('@\s(loop|cond)="([^"]+)"@', $node, $matches)) { - // this tag - $tag = substr($node, 1, strpos($node, ' ')-1); + function _parseInline($buff) + { + if(preg_match_all('/<([a-zA-Z]+\d?)(?>(?!<[a-z]+\d?[\s>]).)*?(?:[ \|]cond| loop)="/s', $buff, $match) === false) return $buff; - // if the vale of $closing is 0, it means 'skipping' - $closing = 0; + $tags = array_diff(array_unique($match[1]), $this->skipTags); - // process opening tag - foreach($matches[1] as $n=>$stmt) { - $expr = $matches[2][$n]; - $expr = $this->_replaceVar($expr); - $closing++; + if(!count($tags)) return $buff; - switch($stmt) { - case 'cond': - $nodes[$idx-1] .= ""; - break; - case 'loop': - if(!preg_match('@^(?:(.+?)=>(.+?)(?:,(.+?))?|(.*?;.*?;.*?)|(.+?)\s*=\s*(.+?))$@', $expr, $expr_m)) break; - if($expr_m[1]) { - $expr_m[1] = trim($expr_m[1]); - $expr_m[2] = trim($expr_m[2]); - if($expr_m[3]) $expr_m[2] .= '=>'.trim($expr_m[3]); - $nodes[$idx-1] .= ""; - }elseif($expr_m[4]) { - $nodes[$idx-1] .= ""; - }elseif($expr_m[5]) { - $nodes[$idx-1] .= ""; - } - break; - } - } - $node = preg_replace('@\s(loop|cond)="([^"]+)"@', '', $node); - - // find closing tag - $close_php = ''; - if($node{1} == '!' || substr($node,-2,1) == '/' || in_array($tag, $self_closing)) { // self closing tag - $nodes[$idx+1] = $close_php.$nodes[$idx+1]; - } else { - $depth = 1; - for($i=$idx+2; $i < $node_len; $i+=2) { - $nd = $nodes[$i]; - if(strpos($nd, $tag) === 1) { - $depth++; - } elseif(strpos($nd, '/'.$tag) === 1) { - $depth--; - if(!$depth) { - $nodes[$i-1] .= $nodes[$i].$close_php; - $nodes[$i] = ''; - break; - } - } + $tags = '(?:'.implode('|',$tags).')'; + $split_regex = "@(<(?>/?{$tags})(?>[^<>\{\}\"']+||{[^}]+}|\".*?\"|'.*?'|.)*?>)@s"; + + $nodes = preg_split($split_regex, $buff, -1, PREG_SPLIT_DELIM_CAPTURE); + + // list of self closing tags + $self_closing = explode(',', 'area,base,basefont,br,hr,input,img,link,meta,param,frame,col'); + + for($idx=1,$node_len=count($nodes); $idx < $node_len; $idx+=2) { + if(!($node=$nodes[$idx])) continue; + + if(preg_match_all('@\s(loop|cond)="([^"]+)"@', $node, $matches)) { + // this tag + $tag = substr($node, 1, strpos($node, ' ')-1); + + // if the vale of $closing is 0, it means 'skipping' + $closing = 0; + + // process opening tag + foreach($matches[1] as $n=>$stmt) { + $expr = $matches[2][$n]; + $expr = $this->_replaceVar($expr); + $closing++; + + switch($stmt) { + case 'cond': + $nodes[$idx-1] .= ""; + break; + case 'loop': + if(!preg_match('@^(?:(.+?)=>(.+?)(?:,(.+?))?|(.*?;.*?;.*?)|(.+?)\s*=\s*(.+?))$@', $expr, $expr_m)) break; + if($expr_m[1]) { + $expr_m[1] = trim($expr_m[1]); + $expr_m[2] = trim($expr_m[2]); + if($expr_m[3]) $expr_m[2] .= '=>'.trim($expr_m[3]); + $nodes[$idx-1] .= ""; + }elseif($expr_m[4]) { + $nodes[$idx-1] .= ""; + }elseif($expr_m[5]) { + $nodes[$idx-1] .= ""; } + break; } } + $node = preg_replace('@\s(loop|cond)="([^"]+)"@', '', $node); - if(strpos($node, '|cond="') !== false) { - $node = preg_replace('@(\s[\w:]+="[^"]+?")\|cond="(.+?)"@s', '$1', $node); - $node = $this->_replaceVar($node); - } - - if($nodes[$idx] != $node) $nodes[$idx] = $node; - } - - $buff = implode('', $nodes); - - return $buff; - } - - function _parseResource($m) - { - // {@ ... } or {$var} or {func(...)} - if($m[1]) - { - if(preg_match('@^(\w+)\(@', $m[1], $mm) && !function_exists($mm[1])) return $m[0]; - - $echo = 'echo '; - if($m[1]{0} == '@') { - $echo = ''; - $m[1] = substr($m[1], 1); - } - return '_replaceVar($m[1]).' ?>'; - } - - if($m[3]) - { - $attr = array(); - if($m[5]) { - if(preg_match_all('@,(\w+)="([^"]+)"@', $m[6], $mm)) { - foreach($mm[1] as $idx=>$name) { - $attr[$name] = $mm[2][$idx]; - } - } - $attr['target'] = $m[5]; + // find closing tag + $close_php = ''; + if($node{1} == '!' || substr($node,-2,1) == '/' || in_array($tag, $self_closing)) { // self closing tag + $nodes[$idx+1] = $close_php.$nodes[$idx+1]; } else { - if(!preg_match_all('@ (\w+)="([^"]+)"@', $m[6], $mm)) return $m[0]; + $depth = 1; + for($i=$idx+2; $i < $node_len; $i+=2) { + $nd = $nodes[$i]; + if(strpos($nd, $tag) === 1) { + $depth++; + } elseif(strpos($nd, '/'.$tag) === 1) { + $depth--; + if(!$depth) { + $nodes[$i-1] .= $nodes[$i].$close_php; + $nodes[$i] = ''; + break; + } + } + } + } + } + + if(strpos($node, '|cond="') !== false) { + $node = preg_replace('@(\s[\w:]+="[^"]+?")\|cond="(.+?)"@s', '$1', $node); + $node = $this->_replaceVar($node); + } + + if($nodes[$idx] != $node) $nodes[$idx] = $node; + } + + $buff = implode('', $nodes); + + return $buff; + } + + function _parseResource($m) + { + // {@ ... } or {$var} or {func(...)} + if($m[1]) + { + if(preg_match('@^(\w+)\(@', $m[1], $mm) && !function_exists($mm[1])) return $m[0]; + + $echo = 'echo '; + if($m[1]{0} == '@') { + $echo = ''; + $m[1] = substr($m[1], 1); + } + return '_replaceVar($m[1]).' ?>'; + } + + if($m[3]) + { + $attr = array(); + if($m[5]) { + if(preg_match_all('@,(\w+)="([^"]+)"@', $m[6], $mm)) { foreach($mm[1] as $idx=>$name) { $attr[$name] = $mm[2][$idx]; } } - - switch($m[3]) - { - // or - case 'include': - if(!$this->file || !$attr['target']) return ''; - - $pathinfo = pathinfo($attr['target']); - $fileDir = $this->_getRelativeDir($pathinfo['dirname']); - - if(!$fileDir) return ''; - - return "compile('{$fileDir}','{$pathinfo['basename']}') ?>"; - - // - case 'load_js_plugin': - $plugin = $this->_replaceVar($m[5]); - if(strpos($plugin, '$__Context') === false) $plugin = "'{$plugin}'"; - - return ""; - - // or or or - case 'import': - case 'load': - case 'unload': - $metafile = ''; - $pathinfo = pathinfo($attr['target']); - $doUnload = ($m[3] === 'unload'); - $isRemote = !!preg_match('@^https?://@i', $attr['target']); - - if(!$isRemote) { - if(!preg_match('@^\.?/@',$attr['target'])) $attr['target'] = './'.$attr['target']; - if(substr($attr['target'], -5) == '/lang') { - $pathinfo['dirname'] .= '/lang'; - $pathinfo['basename'] = ''; - $pathinfo['extension'] = 'xml'; - } - - $relativeDir = $this->_getRelativeDir($pathinfo['dirname']); - - $attr['target'] = $relativeDir.'/'.$pathinfo['basename']; - } - - switch($pathinfo['extension']) - { - case 'xml': - if($isRemote || $doUnload) return ''; - // language file? - if($pathinfo['basename'] == 'lang.xml' || substr($pathinfo['dirname'],-5) == '/lang') { - $result = "Context::loadLang('{$relativeDir}');"; - } else { - $result = "require_once('./classes/xml/XmlJsFilter.class.php');\$__xmlFilter=new XmlJsFilter('{$relativeDir}','{$pathinfo['basename']}');\$__xmlFilter->compile();"; - } - break; - case 'js': - if($doUnload) { - $result = "Context::unloadFile('{$attr['target']}','{$attr['targetie']}');"; - } else { - $metafile = $attr['target']; - $result = "\$__tmp=array('{$attr['target']}','{$attr['type']}','{$attr['targetie']}','{$attr['index']}');Context::loadFile(\$__tmp,'{$attr['usecdn']}','{$attr['cdnprefix']}','{$attr['cdnversion']}');unset(\$__tmp);"; - } - break; - case 'css': - if($doUnload) { - $result = "Context::unloadFile('{$attr['target']}','{$attr['targetie']}','{$attr['media']}');"; - } else { - $metafile = $attr['target']; - $result = "\$__tmp=array('{$attr['target']}','{$attr['media']}','{$attr['targetie']}','{$attr['index']}');Context::loadFile(\$__tmp,'{$attr['usecdn']}','{$attr['cdnprefix']}','{$attr['cdnversion']}');unset(\$__tmp);"; - } - break; - } - - $result = ""; - if($metafile) $result = "".$result; - - return $result; + $attr['target'] = $m[5]; + } else { + if(!preg_match_all('@ (\w+)="([^"]+)"@', $m[6], $mm)) return $m[0]; + foreach($mm[1] as $idx=>$name) { + $attr[$name] = $mm[2][$idx]; } } - // such as , , - if($m[7]) + switch($m[3]) { - $m[7] = substr($m[7],1); - if(!preg_match('/^(?:((?:end)?(?:if|switch|for(?:each)?|while)|end)|(else(?:if)?)|(break@)?(case|default)|(break))$/', $m[7], $mm)) return ''; - if($mm[1]) { - if($mm[1]{0} == 'e') return ''; + // or + case 'include': + if(!$this->file || !$attr['target']) return ''; - $precheck = ''; - if($mm[1] == 'foreach') { - $var = preg_replace('/^\s*\(\s*(.+?) .*$/', '$1', $m[8]); - $precheck = "if({$var}&&count({$var}))"; + $pathinfo = pathinfo($attr['target']); + $fileDir = $this->_getRelativeDir($pathinfo['dirname']); + + if(!$fileDir) return ''; + + return "compile('{$fileDir}','{$pathinfo['basename']}') ?>"; + + // + case 'load_js_plugin': + $plugin = $this->_replaceVar($m[5]); + if(strpos($plugin, '$__Context') === false) $plugin = "'{$plugin}'"; + + return ""; + + // or or or + case 'import': + case 'load': + case 'unload': + $metafile = ''; + $pathinfo = pathinfo($attr['target']); + $doUnload = ($m[3] === 'unload'); + $isRemote = !!preg_match('@^https?://@i', $attr['target']); + + if(!$isRemote) { + if(!preg_match('@^\.?/@',$attr['target'])) $attr['target'] = './'.$attr['target']; + if(substr($attr['target'], -5) == '/lang') { + $pathinfo['dirname'] .= '/lang'; + $pathinfo['basename'] = ''; + $pathinfo['extension'] = 'xml'; + } + + $relativeDir = $this->_getRelativeDir($pathinfo['dirname']); + + $attr['target'] = $relativeDir.'/'.$pathinfo['basename']; } - return '_replaceVar($precheck.$m[7].$m[8]).'{ ?>'; - } - if($mm[2]) return "_replaceVar($m[8])."{ ?>"; - if($mm[4]) return ""; - if($mm[5]) return ""; - return ''; - } - return $m[0]; + switch($pathinfo['extension']) + { + case 'xml': + if($isRemote || $doUnload) return ''; + // language file? + if($pathinfo['basename'] == 'lang.xml' || substr($pathinfo['dirname'],-5) == '/lang') { + $result = "Context::loadLang('{$relativeDir}');"; + } else { + $result = "require_once('./classes/xml/XmlJsFilter.class.php');\$__xmlFilter=new XmlJsFilter('{$relativeDir}','{$pathinfo['basename']}');\$__xmlFilter->compile();"; + } + break; + case 'js': + if($doUnload) { + $result = "Context::unloadFile('{$attr['target']}','{$attr['targetie']}');"; + } else { + $metafile = $attr['target']; + $result = "\$__tmp=array('{$attr['target']}','{$attr['type']}','{$attr['targetie']}','{$attr['index']}');Context::loadFile(\$__tmp,'{$attr['usecdn']}','{$attr['cdnprefix']}','{$attr['cdnversion']}');unset(\$__tmp);"; + } + break; + case 'css': + if($doUnload) { + $result = "Context::unloadFile('{$attr['target']}','{$attr['targetie']}','{$attr['media']}');"; + } else { + $metafile = $attr['target']; + $result = "\$__tmp=array('{$attr['target']}','{$attr['media']}','{$attr['targetie']}','{$attr['index']}');Context::loadFile(\$__tmp,'{$attr['usecdn']}','{$attr['cdnprefix']}','{$attr['cdnversion']}');unset(\$__tmp);"; + } + break; + } + + $result = ""; + if($metafile) $result = "".$result; + + return $result; + } } - function _getRelativeDir($path) + // such as , , + if($m[7]) { - $_path = $path; + $m[7] = substr($m[7],1); + if(!preg_match('/^(?:((?:end)?(?:if|switch|for(?:each)?|while)|end)|(else(?:if)?)|(break@)?(case|default)|(break))$/', $m[7], $mm)) return ''; + if($mm[1]) { + if($mm[1]{0} == 'e') return ''; - $fileDir = strtr(realpath($this->path),'\\','/'); - if($path{0} != '/') $path = strtr(realpath($fileDir.'/'.$path),'\\','/'); - - // for backward compatibility - if(!$path) { - $dirs = explode('/', $fileDir); - $paths = explode('/', $_path); - $idx = array_search($paths[0], $dirs); - - if($idx !== false) { - while($dirs[$idx] && $dirs[$idx] === $paths[0]) { - array_splice($dirs, $idx, 1); - array_shift($paths); - } - $path = strtr(realpath($fileDir.'/'.implode('/', $paths)),'\\','/'); + $precheck = ''; + if($mm[1] == 'foreach') { + $var = preg_replace('/^\s*\(\s*(.+?) .*$/', '$1', $m[8]); + $precheck = "if({$var}&&count({$var}))"; } + return '_replaceVar($precheck.$m[7].$m[8]).'{ ?>'; } - - $path = preg_replace('/^'.preg_quote(_XE_PATH_,'/').'/', '', $path); - - return $path; + if($mm[2]) return "_replaceVar($m[8])."{ ?>"; + if($mm[4]) return ""; + if($mm[5]) return ""; + return ''; } - /** - * @brief replace PHP variables of $ character - **/ - function _replaceVar($php) { - if(!strlen($php)) return ''; - return preg_replace('@(?$1', $php); + return $m[0]; + } + + function _getRelativeDir($path) + { + $_path = $path; + + $fileDir = strtr(realpath($this->path),'\\','/'); + if($path{0} != '/') $path = strtr(realpath($fileDir.'/'.$path),'\\','/'); + + // for backward compatibility + if(!$path) { + $dirs = explode('/', $fileDir); + $paths = explode('/', $_path); + $idx = array_search($paths[0], $dirs); + + if($idx !== false) { + while($dirs[$idx] && $dirs[$idx] === $paths[0]) { + array_splice($dirs, $idx, 1); + array_shift($paths); + } + $path = strtr(realpath($fileDir.'/'.implode('/', $paths)),'\\','/'); + } } - } -?> + + $path = preg_replace('/^'.preg_quote(_XE_PATH_,'/').'/', '', $path); + + return $path; + } + + /** + * @brief replace PHP variables of $ character + **/ + function _replaceVar($php) { + if(!strlen($php)) return ''; + return preg_replace('@(?$1', $php); + } +} + +/* End of File: TemplateHandler.class.php */