[], 'replace' => []]; var $blocks = []; var $language = []; var $file = ''; var $filetype = 'htm'; var $debug = 0; var $cellFuncs = []; function parse_template($tplfile, $templateid = 1, $tpldir = '', $file = '', $cachefile = '', $postparse = null) { $f = $tplfile; $basefile = basename($f, '.' . $this->filetype); $file == 'common/header' && defined('CURMODULE') && CURMODULE && $file = 'common/header_' . CURMODULE; $this->file = $file; if (tplfile::file_exists($tplfile)) { $template = tplfile::file_get_contents($tplfile); } elseif (tplfile::file_exists($filename = substr($tplfile, 0, -(strlen($this->filetype) + 1)) . '.php')) { $template = tplfile::file_get_contents($filename); $template = tplfile::getphptemplate($template); } else { $tpl = $tpldir . '/' . $file . '.' . $this->filetype; $tplfile = $tplfile != $tpl ? $tpl . ', ' . $tplfile : $tplfile; $this->error('template_notfound', $tplfile); } if ($this->debug) { $template = $this->insertdebugmsg($template, $tplfile); } $var_regexp = "((\\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\-\>)?[a-zA-Z0-9_\x7f-\xff]*)(\[[a-zA-Z0-9_\-\.\"\'\[\]\$\x7f-\xff]+\])*)"; $const_regexp = "([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)"; $headerexists = preg_match('/{(sub)?template\s+[\w:\/]+?header\}/', $template); $this->subtemplates = []; for ($i = 1; $i <= 3; $i++) { if (strexists($template, '{subtemplate')) { $template = preg_replace_callback("/[\n\r\t]*(\<\!\-\-)?\{subtemplate\s+([a-z0-9_:\/]+)\}(\-\-\>)?[\n\r\t]*/is", [$this, 'parse_template_callback_loadsubtemplate_2'], $template); } } $template = preg_replace("/([\n\r]+)\t+/s", "\\1", $template); $template = preg_replace('/\/\*\*\{(.+?)\}\*\//s', "{\\1}", $template); $template = preg_replace('/\<\!\-\-\{(.+?)\}\-\-\>/s', "{\\1}", $template); $template = preg_replace_callback("/[\n\r\t]*\{block\/(\d+?)\}[\n\r\t]*/i", [$this, 'parse_template_callback_blocktags_1'], $template); $template = preg_replace_callback("/[\n\r\t]*\{blockdata\/(\d+?)\}[\n\r\t]*/i", [$this, 'parse_template_callback_blockdatatags_1'], $template); $template = preg_replace_callback("/[\n\r\t]*\{ad\/(.+?)\}[\n\r\t]*/i", [$this, 'parse_template_callback_adtags_1'], $template); $template = preg_replace_callback("/[\n\r\t]*\{ad\s+([a-zA-Z0-9_\[\]]+)\/(.+?)\}[\n\r\t]*/i", [$this, 'parse_template_callback_adtags_21'], $template); $template = preg_replace_callback("/[\n\r\t]*\{date\((.+?)\)\}[\n\r\t]*/i", [$this, 'parse_template_callback_datetags_1'], $template); $template = preg_replace_callback("/[\n\r\t]*\{avatar\((.+?)\)\}[\n\r\t]*/i", [$this, 'parse_template_callback_avatartags_1'], $template); $template = preg_replace_callback("/[\n\r\t]*\{eval\}\s*(\<\!\-\-)*(.+?)(\-\-\>)*\s*\{\/eval\}[\n\r\t]*/is", [$this, 'parse_template_callback_evaltags_2'], $template); $template = preg_replace_callback("/[\n\r\t]*\{eval\s+(.+?)\s*\}[\n\r\t]*/is", [$this, 'parse_template_callback_evaltags_1'], $template); $template = str_replace('{LF}', "", $template); $template = preg_replace("/\{(\\\$[a-zA-Z0-9_\-\>\[\]\'\"\$\.\x7f-\xff]+)\s(or|\?\?)\s([a-zA-Z0-9\']+)\}/s", "{echo \\1 ?? \\3}", $template); $template = preg_replace("/\{(\\\$[a-zA-Z0-9_\-\>\[\]\'\"\$\.\x7f-\xff]+)\}/s", "", $template); $template = preg_replace_callback('/\{hook\/(\w+?)(\s+(.+?))?\}/i', [$this, 'parse_template_callback_hooktags_13'], $template); $template = preg_replace_callback("/$var_regexp/s", [$this, 'parse_template_callback_addquote_1'], $template); $template = preg_replace_callback("/\<\?\=\<\?\=$var_regexp\?\>\?\>/s", [$this, 'parse_template_callback_addquote_1'], $template); $headeradd = $headerexists ? "hookscriptoutput('$basefile');" : ''; if (!empty($this->subtemplates)) { $headeradd .= "\n0\n"; foreach ($this->subtemplates as $fname) { $headeradd .= "|| checktplrefresh('$tplfile', '$fname', " . time() . ", '$templateid', '$cachefile', '$tpldir', '$file')\n"; } $headeradd .= ';'; } if (!empty($this->blocks)) { $headeradd .= "\n"; $headeradd .= "block_get('" . implode(',', $this->blocks) . "');"; } if (!empty($this->cellFuncs)) { $headeradd .= "\n"; $headeradd .= implode('', $this->cellFuncs) . ';'; } if ($headerexists) { $headeradd .= "if(defined('IN_RESTFUL')) {\$GLOBALS['_L'] = get_defined_vars();exit;}"; } if ($cachefile) { $template = "\n$template"; } $template = preg_replace_callback("/[\n\r\t]*\{template\s+([a-z0-9_:\/]+)\}[\n\r\t]*/is", [$this, 'parse_template_callback_stripvtags_template1'], $template); $template = preg_replace_callback("/[\n\r\t]*\{template\s+(.+?)\}[\n\r\t]*/is", [$this, 'parse_template_callback_stripvtags_template1'], $template); $template = preg_replace_callback("/[\n\r\t]*\{echo\s+(.+?)\}[\n\r\t]*/is", [$this, 'parse_template_callback_stripvtags_echo1'], $template); $template = preg_replace_callback("/([\n\r\t]*)\{if\s+(.+?)\}([\n\r\t]*)/is", [$this, 'parse_template_callback_stripvtags_if123'], $template); $template = preg_replace_callback("/([\n\r\t]*)\{elseif\s+(.+?)\}([\n\r\t]*)/is", [$this, 'parse_template_callback_stripvtags_elseif123'], $template); $template = preg_replace('/\{else\}/i', '', $template); $template = preg_replace('/\{\/if\}/i', '', $template); $template = preg_replace_callback("/[\n\r\t]*\{loop\s+(\S+)\s+(\S+)\}[\n\r\t]*/is", [$this, 'parse_template_callback_stripvtags_loop12'], $template); $template = preg_replace_callback("/[\n\r\t]*\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}[\n\r\t]*/is", [$this, 'parse_template_callback_stripvtags_loop123'], $template); $template = preg_replace('/\{\/loop\}/i', '', $template); $template = preg_replace("/\{$const_regexp\}/s", "", $template); if (!empty($this->replacecode)) { $template = str_replace($this->replacecode['search'], $this->replacecode['replace'], $template); } $template = preg_replace("/ \?\>[\n\r]*\<\? /s", ' ', $template); if ($cachefile && !@$fp = fopen(DISCUZ_DATA . $cachefile, 'c')) { $this->error('directory_notfound', dirname(DISCUZ_DATA . $cachefile)); } $template = preg_replace_callback("/\"(http)?[\w\.\/:]+\?[^\"]+?&[^\"]+?\"/", [$this, 'parse_template_callback_transamp_0'], $template); $template = preg_replace_callback("/\]*?src=\"(.+?)\"(.*?)\>\s*\<\/script\>/is", [$this, 'parse_template_callback_stripscriptamp_12'], $template); $template = preg_replace_callback("/[\n\r\t]*\{block\s+([a-zA-Z0-9_\[\]']+)\}(.+?)\{\/block\}/is", [$this, 'parse_template_callback_stripblock_12'], $template); $template = preg_replace('/\<\?(\s{1})/is', "/is', "", $template); if ($this->debug) { $template = preg_replace_callback("/\.+?\<\/script\>/is", [$this, 'parse_template_callback_scriptdebugconvert_0'], $template); } if (is_callable($postparse)) { $template = $postparse($template); } if (!($cachefile && $fp && flock($fp, LOCK_EX) && ftruncate($fp, 0) && fwrite($fp, $template) && fflush($fp) && flock($fp, LOCK_UN) && fclose($fp))) { return $template; } } function parse_template_callback_loadsubtemplate_2($matches) { return $this->loadsubtemplate($matches[2]); } function parse_template_callback_blocktags_1($matches) { return $this->blocktags($matches[1]); } function parse_template_callback_blockdatatags_1($matches) { return $this->blockdatatags($matches[1]); } function parse_template_callback_adtags_1($matches) { return $this->adtags($matches[1]); } function parse_template_callback_adtags_21($matches) { return $this->adtags($matches[2], $matches[1]); } function parse_template_callback_datetags_1($matches) { return $this->datetags($matches[1]); } function parse_template_callback_avatartags_1($matches) { return $this->avatartags($matches[1]); } function parse_template_callback_evaltags_2($matches) { return $this->evaltags($matches[2]); } function parse_template_callback_evaltags_1($matches) { return $this->evaltags($matches[1]); } function parse_template_callback_hooktags_13($matches) { return $this->hooktags($matches[1], $matches[3] ?? ''); } function parse_template_callback_addquote_1($matches) { return $this->addquote(''); } function parse_template_callback_stripvtags_template1($matches) { return $this->stripvtags(''); } function parse_template_callback_stripvtags_echo1($matches) { return $this->stripvtags('echopolyfill($matches[1]) . '; ?>'); } function parse_template_callback_stripvtags_if123($matches) { return $this->stripvtags($matches[1] . '' . $matches[3]); } function parse_template_callback_stripvtags_elseif123($matches) { return $this->stripvtags($matches[1] . '' . $matches[3]); } function parse_template_callback_stripvtags_loop12($matches) { return $this->stripvtags($this->looptags($matches[1], $matches[2])); } function parse_template_callback_stripvtags_loop123($matches) { return $this->stripvtags($this->looptags($matches[1], $matches[2], $matches[3])); } function parse_template_callback_transamp_0($matches) { return $this->transamp($matches[0]); } function parse_template_callback_stripscriptamp_12($matches) { return $this->stripscriptamp($matches[1], $matches[2]); } function parse_template_callback_stripblock_12($matches) { return $this->stripblock($matches[1], $matches[2]); } function parse_template_callback_scriptdebugconvert_0($matches) { return $this->scriptdebugconvert($matches[0]); } function blocktags($parameter) { $bid = intval(trim($parameter)); $this->blocks[] = $bid; $i = count($this->replacecode['search']); $this->replacecode['search'][$i] = $search = ""; $this->replacecode['replace'][$i] = ""; return $search; } function blockdatatags($parameter) { $bid = intval(trim($parameter)); $this->blocks[] = $bid; $i = count($this->replacecode['search']); $this->replacecode['search'][$i] = $search = ""; $this->replacecode['replace'][$i] = ''; return $search; } function adtags($parameter, $varname = '') { $parameter = stripslashes($parameter); $parameter = preg_replace("/(\\\$[a-zA-Z0-9_\-\>\[\]\'\"\$\.\x7f-\xff]+)/s", "{\\1}", $this->addquote($parameter)); $i = count($this->replacecode['search']); $this->replacecode['search'][$i] = $search = ""; $this->replacecode['replace'][$i] = '"; return $search; } function datetags($parameter) { $parameter = stripslashes($parameter); $i = count($this->replacecode['search']); $this->replacecode['search'][$i] = $search = ""; $this->replacecode['replace'][$i] = ""; return $search; } function avatartags($parameter) { $parameter = stripslashes($parameter); $i = count($this->replacecode['search']); $this->replacecode['search'][$i] = $search = ""; $this->replacecode['replace'][$i] = ""; return $search; } function evaltags($php) { $i = count($this->replacecode['search']); $this->replacecode['search'][$i] = $search = ""; $this->replacecode['replace'][$i] = $this->debug ? '/', '/\<\!\-\-L\d+[\w\.\/]*\-\-\>/', '/\<\!\-\-L\d+[\w\.\/]*$/', '/^\s*\<\!\-\-/', '/\-\-\>\s*$/'], '', $php) . '?>' : ""; return $search; } function hooktags($hookid, $key = '') { global $_G; $i = count($this->replacecode['search']); $this->replacecode['search'][$i] = $search = ""; $dev = ''; if (isset($_G['config']['plugindeveloper']) && $_G['config']['plugindeveloper'] == 2) { $dev = "echo '[" . ($key ? 'array' : 'string') . " $hookid" . ($key ? '/\'.' . $key . '.\'' : '') . "]';"; } $key = $key != '' ? "[$key]" : ''; $this->replacecode['replace'][$i] = ""; return $search; } function stripphpcode($type, $code) { $this->phpcode[$type][] = $code; return '{phpcode:' . $type . '/' . (count($this->phpcode[$type]) - 1) . '}'; } function loadsubtemplate($file) { $tplfile = template($file, 0, '', 1); $filename = $tplfile; if ((tplfile::file_exists($filename) && is_readable($filename) && ($content = tplfile::file_get_contents($filename))) || (tplfile::file_exists(substr($filename, 0, -4) . '.php') && is_readable(substr($filename, 0, -4) . '.php') && ($content = tplfile::getphptemplate(tplfile::file_get_contents(substr($filename, 0, -4) . '.php'))))) { $this->subtemplates[] = $tplfile; return $this->debug ? $this->insertdebugmsg($content, $tplfile) : $content; } else { return ''; } } function looptags($param1, $param2, $param3 = '') { if (preg_match("/^\<\?\=\\\$.+?\?\>$/s", $param1)) { $exprtemp = $param1; $return = ' ' . $param3 . ') { ?>'; } else { $return .= 'foreach(' . $exprtemp . ' as ' . $param2 . ') { ?>'; } return $return; } function echopolyfill($str) { $str = str_replace(' or ', ' ?? ', $str); if (str_contains($str, ' ?? ') && version_compare(PHP_VERSION, '7.0', '<')) { $str = preg_replace('/^(.+)\s\?\?\s(.+)$/', "isset(\\1) ? (\\1) : (\\2)", $str); } return $str; } function transamp($str) { $str = str_replace('&', '&', $str); $str = str_replace('&amp;', '&', $str); return $str; } function addquote($var) { return str_replace("\\\"", "\"", preg_replace_callback("/\[([a-zA-Z0-9_\-\.\x7f-\xff]+)\]/s", [$this, 'addquote_exec'], $var)); } function addquote_exec($matches) { return is_numeric($matches[1]) ? '[' . $matches[1] . ']' : "['" . $matches[1] . "']"; } function stripvtags($expr, $statement = '') { $expr = str_replace('\\\"', '\"', preg_replace("/\<\?\=(\\\$.+?)\?\>/s", "\\1", $expr)); if ($this->debug) { $expr = preg_replace('/\<\!\-\-L\d+[\w\.\/]*\-\-\>/', '', $expr); } $statement = str_replace('\\\"', '\"', $statement); return $expr . $statement; } function stripscriptamp($s, $extra) { $s = str_replace('&', '&', $s); return ""; } function stripblock($var, $s) { $var = $this->addquote($var); $s = preg_replace("/<\?=\\\$(.+?)\?>/", "{\$\\1}", $s); preg_match_all('/<\?=(.+?)\?>/', $s, $constary); $constadd = ''; $constary[1] = array_unique($constary[1]); foreach ($constary[1] as $const) { $constadd .= '$__' . $const . ' = ' . $const . ';'; } $s = preg_replace('/<\?=(.+?)\?>/', "{\$__\\1}", $s); $s = str_replace('?>', "\n\$$var .= <<"; } function scriptdebugconvert($str) { return preg_replace('/\<\!\-\-L(\d+[\w\.\/]*)\-\-\>/', '/**L\1*/', $str); } function insertdebugmsg($str, $filename) { $startmsg = ''; $endmsg = ''; $count = 2; $debuglevel = $this->debug; $str = preg_replace_callback('/\n(\t*)/', function ($matches) use (&$count, $filename, $debuglevel) { if ($debuglevel > 1) { return "\n" . $matches[1] . ''; } else { return "\n" . $matches[1] . ''; } }, $str); return $startmsg . $str . $endmsg; } function error($message, $tplname) { discuz_error::template_error($message, $tplname); } }