Index: branches/RC/core/kernel/nparser/nparser.php =================================================================== diff -u -N -r10598 -r10610 --- branches/RC/core/kernel/nparser/nparser.php (.../nparser.php) (revision 10598) +++ branches/RC/core/kernel/nparser/nparser.php (.../nparser.php) (revision 10610) @@ -13,9 +13,19 @@ var $Params = array(); var $ParamsStack = array(); var $ParamsLevel = 0; + + var $Definitions = ''; var $Elements = array(); // holds dynamic elements to function names mapping during execution var $DataExists = false; + + var $TemplateName = null; + var $TempalteFullPath = null; + + var $CachePointers = array(); + var $Cachable = array(); + + function NParser() @@ -51,7 +61,13 @@ function CompileRaw($data, $t_name) { $code = "extract (\$_parser->Params);\n"; + +// $code .= "__@@__DefinitionsMarker__@@__\n"; + +// $code .= "if (!\$this->CacheStart('".abs(crc32($t_name))."_0')) {\n"; $this->Buffers[0] = '\n"; + $this->Cacheable[0] = true; + $this->Definitions = ''; // finding all the tags $reg = '(.*?)(<[\\/]?)inp2:([^>]*?)([\\/]?>)(\r\n){0,1}'; @@ -98,6 +114,8 @@ // if no tag was found at all ($tag_data is not set) - append the whole $data $this->Buffers[$this->Level] .= isset($tag_data) ? substr($data, $tag_data[4][1]+strlen($tag_data[4][0])) : $data; $this->Buffers[$this->Level] = preg_replace('//s', '', $this->Buffers[$this->Level]); // remove hidden comments IB#23065 +// $this->Buffers[$this->Level] .= 'CacheEnd();\n}\n"." ?".">\n"; +// $this->Buffers[$this->Level] = str_replace('__@@__DefinitionsMarker__@@__', $this->Definitions, $this->Buffers[$this->Level]); } function SplitParamsStr($params_str) @@ -145,6 +163,7 @@ /* @var $instance _BlockTag */ $this->Stack[++$this->Level] =& $instance; $this->Buffers[$this->Level] = ''; + $this->Cachable[$this->Level] = true; $open_code = $instance->Open($tag); if ($open_code === false) return false; $o .= $open_code; @@ -182,12 +201,28 @@ if (!$tag['processed']) { $compiled = $this->CompileTag($tag); if ($compiled === false) return false; - $o .= '\n"; + if (isset($tag['NP']['cachable']) && (!$tag['NP']['cachable'] || $tag['NP']['cachable'] == 'false')) { + $this->Cachable[$this->Level] = false; + } + $o .= '\n"; +// $o .= 'BreakCache($compiled, $this->GetPointer($tag)) : $compiled; +// $o .= " ?".">\n"; } } $this->Buffers[$this->Level] .= $o; return true; } + + function GetPointer($tag) + { + return abs(crc32($tag['file'])).'_'.$tag['line']; + } + + function BreakCache($code, $pointer, $condition='') + { + return "\$_parser->CacheEnd();\n}\n" . $code."\nif ( !\$_parser->CacheStart('{$pointer}'" . ($condition ? ", {$condition}" : '') . ") ) {\n"; + } function TagInfo($tag, $with_params=false) { @@ -254,22 +289,25 @@ { $pre_parsed = $this->CheckTemplate($t, $silent); if (!$pre_parsed) return false; + $backup_template = $this->TemplateName; + $backup_fullpath = $this->TempalteFullPath; + $this->TemplateName = $t; + $this->TempalteFullPath = $pre_parsed['tname']; ob_start(); $_parser =& $this; if ($pre_parsed['mode'] == 'file') { - if (false && $result = $this->Application->getCache('nparser', $pre_parsed['fname'])) { - return $result; - } include($pre_parsed['fname']); } else { eval('?'.'>'.$pre_parsed['content']); } $output = ob_get_contents(); - // $this->Application->setCache('nparser', $pre_parsed['fname'], $output); ob_end_clean(); + $this->TemplateName = $backup_template; + $this->TempalteFullPath = $backup_fullpath; + return $output; } @@ -325,6 +363,12 @@ function ParseBlock($params, $pass_params=false) { + if (isset($params['cache_timeout']) && ($ret = $this->CacheGet($this->FormCacheKey('element_'.$params['name'])))) { + return $ret; + } + + $original_params = $params; + if ($pass_params || isset($params['pass_params'])) $params = array_merge($this->Params, $params); $this->PushParams($params); $data_exists_bak = $this->DataExists; @@ -360,12 +404,32 @@ $this->CheckNoData($ret, $params); $this->DataExists = $data_exists_bak || $this->DataExists; - return $ret; + + if (isset($original_params['cache_timeout'])) { + $this->CacheSet($this->FormCacheKey('element_'.$original_params['name']), $ret, $original_params['cache_timeout']); + } + + return defined('DBG_DECORATE_BLOCKS') && DBG_DECORATE_BLOCKS ? $this->DecorateBlock($ret, $params) : $ret; } + + function DecorateBlock($block_content, $block_params) + { + if (preg_match('/^(\s*)(.*)<\/td>(.*)$/is', $block_content, $regs)) { + // block with td -> put div inside td + return $regs[1].'
'.$regs[3].'
'.$regs[4]; + } + return '
'.$block_content.'
'; + } + function IncludeTemplate($params, $silent=null) { $t = is_array($params) ? $this->SelectParam($params, 't,template,block,name') : $params; + + if (isset($params['cache_timeout']) && ($ret = $this->CacheGet('template:'.$t))) { + return $ret; + } + $t = eregi_replace("\.tpl$", '', $t); $data_exists_bak = $this->DataExists; $this->DataExists = false; @@ -380,6 +444,11 @@ $this->CheckNoData($ret, $params); $this->DataExists = $data_exists_bak || $this->DataExists; + + if (isset($params['cache_timeout'])) { + $this->CacheSet('template:'.$t, $ret, $params['cache_timeout']); + } + return $ret; } @@ -395,4 +464,77 @@ } } } + + function CacheGet($name) + { + if (!$this->Application->ConfigValue('SystemTagCache')) return false; + return $this->Application->CacheGet($name); + } + + function CacheSet($name, $value, $expiration=0) + { + if (!$this->Application->ConfigValue('SystemTagCache')) return false; + return $this->Application->CacheSet($name, $value, $expiration); + } + + function FormCacheKey($element, $file=null, $add_prefixes=null) + { + if (!isset($file)) { + $file = str_replace(FULL_PATH, '', $this->TempalteFullPath).':'.$this->Application->GetVar('t'); + } + $parts = array( + 'file_'.$file.'('.filemtime($this->TempalteFullPath).')' => 'serials:file_ts', // theme + template timestamp + 'm_lang_'.$this->Application->GetVar('m_lang') => 'serials:lang_ts', + 'm_cat_id_'.$this->Application->GetVar('m_cat_id') => 'serials:cat_'.$this->Application->GetVar('m_cat_id').'_ts', + 'm_cat_page'.$this->Application->GetVar('m_cat_page') => false, + ); + if (isset($add_prefixes)) { + foreach ($add_prefixes as $prefix) { + $parts[$prefix.'_id_'.$this->Application->GetVar("{$prefix}_id")] = "serials:$prefix_".$this->Application->GetVar("{$prefix}_id").'_ts'; + $parts[$prefix.'_page_'.$this->Application->GetVar("{$prefix}_Page")] = false; + } + } + $key = ''; + foreach ($parts as $part => $ts_name) { + if ($ts_name) { + $ts = $this->Application->CacheGet($ts_name); + $key .= "$part($ts):"; + } + else { + $key .= "$part:"; + } + } + $key .= $element; + + return crc32($key); + } + + function PushPointer($pointer) + { + $this->CachePointers[++$this->CacheLevel] = $this->FormCacheKey('pointer:'.$pointer); + return $this->CachePointers[$this->CacheLevel]; + } + + function PopPointer() + { + return $this->CachePointers[$this->CacheLevel--]; + } + + function CacheStart($pointer=null) + { + if ($ret = $this->CacheGet($this->PushPointer($pointer)) ) { + echo $ret; + $this->PopPointer(); + return true; + } + ob_start(); + return false; + } + + function CacheEnd($elem=null) + { + $ret = ob_get_clean(); + $this->CacheSet($this->PopPointer(), $ret); // . ($this->CurrentKeyPart ? ':'.$this->CurrentKeyPart : '') + echo $ret; + } } \ No newline at end of file