/** * Outputs a page directly to the browser, parsing anything which needs to be parsed. * * @param string The contents of the page. */ function output_page($contents) { global $db, $lang, $theme, $plugins, $mybb; global $debug, $templatecache, $templatelist, $maintimer, $globaltime, $parsetime; $contents = parse_page($contents); $totaltime = $maintimer->stop(); $contents = $plugins->run_hooks("pre_output_page", $contents); if ($mybb->usergroup['cancp'] == 1) { if ($mybb->settings['extraadmininfo'] != 0) { $phptime = $maintimer->format($maintimer->totaltime - $db->query_time); $query_time = $maintimer->format($db->query_time); if ($maintimer->totaltime > 0) { $percentphp = number_format($phptime / $maintimer->totaltime * 100, 2); $percentsql = number_format($query_time / $maintimer->totaltime * 100, 2); } else { // if we've got a super fast script... all we can do is assume something $percentphp = 0; $percentsql = 0; } $phpversion = PHP_VERSION; $serverload = get_server_load(); if (my_strpos(getenv("REQUEST_URI"), "?")) { $debuglink = htmlspecialchars_uni(getenv("REQUEST_URI")) . "&debug=1"; } else { $debuglink = htmlspecialchars_uni(getenv("REQUEST_URI")) . "?debug=1"; } if ($mybb->settings['gzipoutput'] != 0) { $gzipen = "Enabled"; } else { $gzipen = "Disabled"; } $memory_usage = get_memory_usage(); if ($memory_usage) { $memory_usage = " / Memory Usage: " . get_friendly_size($memory_usage); } else { $memory_usage = ''; } // MySQLi is still MySQL, so present it that way to the user $database_server = $db->short_title; if ($database_server == 'MySQLi') { $database_server = 'MySQL'; } $other = "PHP version: {$phpversion} / Server Load: {$serverload} / GZip Compression: {$gzipen}"; $debugstuff = "Generated in {$totaltime} seconds ({$percentphp}% PHP / {$percentsql}% " . $database_server . ")<br />SQL Queries: {$db->query_count} / Global Parsing Time: {$globaltime}{$memory_usage}<br />{$other}<br />[<a href=\"{$debuglink}\" target=\"_blank\">advanced details</a>]<br />"; $contents = str_replace("<debugstuff>", $debugstuff, $contents); } if ($mybb->debug_mode == true) { debug_page(); } } $contents = str_replace("<debugstuff>", "", $contents); if ($mybb->settings['gzipoutput'] == 1) { $contents = gzip_encode($contents, $mybb->settings['gziplevel']); } @header("Content-type: text/html; charset={$lang->settings['charset']}"); echo $contents; $plugins->run_hooks("post_output_page"); }
/** * Outputs a page directly to the browser, parsing anything which needs to be parsed. * * @param string The contents of the page. */ function output_page($contents) { global $db, $lang, $theme, $plugins, $mybb; global $debug, $templatecache, $templatelist, $maintimer, $globaltime, $parsetime; $contents = parse_page($contents); $totaltime = $maintimer->stop(); if ($mybb->usergroup['cancp'] == 1) { if ($mybb->settings['extraadmininfo'] != 0) { $phptime = $maintimer->format($maintimer->totaltime - $db->query_time); $query_time = $maintimer->format($db->query_time); if ($maintimer->totaltime > 0) { $percentphp = number_format($phptime / $maintimer->totaltime * 100, 2); $percentsql = number_format($query_time / $maintimer->totaltime * 100, 2); } else { // if we've got a super fast script... all we can do is assume something $percentphp = 0; $percentsql = 0; } $phpversion = phpversion(); $serverload = get_server_load(); if (my_strpos(getenv("REQUEST_URI"), "?")) { $debuglink = htmlspecialchars(getenv("REQUEST_URI")) . "&debug=1"; } else { $debuglink = htmlspecialchars(getenv("REQUEST_URI")) . "?debug=1"; } if ($mybb->settings['gzipoutput'] != 0) { $gzipen = "Enabled"; } else { $gzipen = "Disabled"; } if (function_exists("memory_get_usage")) { $memory_usage = " / Memory Usage: " . get_friendly_size(memory_get_peak_usage(true)); } $other = "PHP version: {$phpversion} / Server Load: {$serverload} / GZip Compression: {$gzipen}"; $debugstuff = "Generated in {$totaltime} seconds ({$percentphp}% PHP / {$percentsql}% MySQL)<br />SQL Queries: {$db->query_count} / Global Parsing Time: {$globaltime}{$memory_usage}<br />{$other}<br />[<a href=\"{$debuglink}\" target=\"_blank\">advanced details</a>]<br />"; $contents = str_replace("<debugstuff>", $debugstuff, $contents); } if ($mybb->debug_mode == true) { debug_page(); } } $contents = str_replace("<debugstuff>", "", $contents); $contents = $plugins->run_hooks("pre_output_page", $contents); if ($mybb->settings['gzipoutput'] == 1) { if (version_compare(PHP_VERSION, '4.2.0', '>=')) { $contents = gzip_encode($contents, $mybb->settings['gziplevel']); } else { $contents = gzip_encode($contents); } } @header("Content-type: text/html; charset={$lang->settings['charset']}"); echo $contents; $plugins->run_hooks("post_output_page"); // If the use shutdown functionality is turned off, run any shutdown related items now. if ($mybb->settings['useshutdownfunc'] == 0 && $mybb->use_shutdown != true) { run_shutdown(); } }
/** * Outputs a page directly to the browser, parsing anything which needs to be parsed. * * @param string $contents The contents of the page. */ function output_page($contents) { global $db, $lang, $theme, $templates, $plugins, $mybb; global $debug, $templatecache, $templatelist, $maintimer, $globaltime, $parsetime; $contents = parse_page($contents); $totaltime = format_time_duration($maintimer->stop()); $contents = $plugins->run_hooks("pre_output_page", $contents); if ($mybb->usergroup['cancp'] == 1 || $mybb->dev_mode == 1) { if ($mybb->settings['extraadmininfo'] != 0) { $phptime = $maintimer->totaltime - $db->query_time; $query_time = $db->query_time; if ($maintimer->totaltime > 0) { $percentphp = number_format($phptime / $maintimer->totaltime * 100, 2); $percentsql = number_format($query_time / $maintimer->totaltime * 100, 2); } else { // if we've got a super fast script... all we can do is assume something $percentphp = 0; $percentsql = 0; } $serverload = get_server_load(); if (my_strpos(getenv("REQUEST_URI"), "?")) { $debuglink = htmlspecialchars_uni(getenv("REQUEST_URI")) . "&debug=1"; } else { $debuglink = htmlspecialchars_uni(getenv("REQUEST_URI")) . "?debug=1"; } $memory_usage = get_memory_usage(); if ($memory_usage) { $memory_usage = $lang->sprintf($lang->debug_memory_usage, get_friendly_size($memory_usage)); } else { $memory_usage = ''; } // MySQLi is still MySQL, so present it that way to the user $database_server = $db->short_title; if ($database_server == 'MySQLi') { $database_server = 'MySQL'; } $generated_in = $lang->sprintf($lang->debug_generated_in, $totaltime); $debug_weight = $lang->sprintf($lang->debug_weight, $percentphp, $percentsql, $database_server); $sql_queries = $lang->sprintf($lang->debug_sql_queries, $db->query_count); $server_load = $lang->sprintf($lang->debug_server_load, $serverload); eval("\$debugstuff = \"" . $templates->get("debug_summary") . "\";"); $contents = str_replace("<debugstuff>", $debugstuff, $contents); } if ($mybb->debug_mode == true) { debug_page(); } } $contents = str_replace("<debugstuff>", "", $contents); if ($mybb->settings['gzipoutput'] == 1) { $contents = gzip_encode($contents, $mybb->settings['gziplevel']); } @header("Content-type: text/html; charset={$lang->settings['charset']}"); echo $contents; $plugins->run_hooks("post_output_page"); }
function textpattern() { global $pretext, $prefs, $production_status, $siteurl, $has_article_tag; $has_article_tag = false; callback_event('textpattern'); if ($pretext['status'] == '404') { txp_die(gTxt('404_not_found'), '404'); } if ($pretext['status'] == '410') { txp_die(gTxt('410_gone'), '410'); } // Useful for clean URLs with error-handlers. txp_status_header('200 OK'); set_error_handler('tagErrorHandler'); $html = parse_page($pretext['page']); if ($html === false) { txp_die(gTxt('unknown_section'), '404'); } // Make sure the page has an article tag if necessary. if (!$has_article_tag and $production_status != 'live' and $pretext['context'] == 'article' and (!empty($pretext['id']) or !empty($pretext['c']) or !empty($pretext['q']) or !empty($pretext['pg']))) { trigger_error(gTxt('missing_article_tag', array('{page}' => $pretext['page']))); } restore_error_handler(); header("Content-type: text/html; charset=utf-8"); echo $html; callback_event('textpattern_end'); }
function parse_page($basedir, $tpl_name, $hf, $out_filename = '', $page = '', $parent_hf = 0) { global $PARSE_PAGE_OPEN_TAG, $PARSE_PAGE_CLOSE_TAG; global $CONFIG; //make path 'absolute' if (!preg_match("/^\\//", $tpl_name)) { $tpl_name = "{$basedir}/{$tpl_name}"; } if (!$page) { //load template $page = precache_file($CONFIG['SITE_TEMPLATES'] . $tpl_name); } if ($page) { //if template empty - don't parse it parse_lang($page); //get all tags with attributes needed to be filled preg_match_all("/{$PARSE_PAGE_OPEN_TAG}([^{$PARSE_PAGE_CLOSE_TAG}]+){$PARSE_PAGE_CLOSE_TAG}/", $page, $out, PREG_PATTERN_ORDER); $tags_full = $out[1]; //rw("$tpl_name: found ".count($tags_full)." tags"); if (count($tags_full) > 0) { //if there are no tags found - dont' parse it $hf['ROOT_URL'] = $CONFIG['ROOT_URL']; $hf['ROOT_DIR'] = $CONFIG['SITE_ROOT']; $hf['LANG'] = $GLOBALS['LANG']; // rw("hf=".count($hf)." "); //re-sort $tags_full, so all 'inline' and 'sub' tags will be parsed first $tags_full = parse_page_sort_tags($tags_full); $TAGSEEN = array(); for ($i = 0; $i < count($tags_full); $i++) { $tag_full = $tags_full[$i]; if (array_key_exists($tag_full, $TAGSEEN)) { continue; } $TAGSEEN[$tag_full] = 1; $tag = ''; $attrs = array(); if (!preg_match("/\\s/", $tag_full)) { //if tag doesn't have attrs - don't parse attrs $tag = $tag_full; } else { //now cut attrs <abcd attr1="aa a" attr2='b bb' attr3=ccc attr4> => abcd, attr1="aa a", attr2='b bb', attr3=ccc, attr4 preg_match_all("/((?:\\S+\\=\".*?\")|(?:\\S+\\='.*?')|(?:[^'\"\\s]+)|(?:\\S+\\=\\S*))/", $tag_full, $out, PREG_PATTERN_ORDER); $attrs_raw = $out[1]; //dumparr($attrs_raw); //rw($tag." => ".$attrs_raw); //echo Dumper(@attrs); $tag = $attrs_raw[0]; for ($j = 0; $j < count($attrs_raw); $j++) { $attr = $attrs_raw[$j]; //rw("search attr [$attr]"); if (preg_match("/(?:(\\S+)\\=\"([^\"]*)\")|(?:(\\S+)\\=(\\S*))|(?:(\\S+)\\='([^']*)')/", $attr, $match)) { //split attr and it's value $name = $match[1]; $value = $match[2]; //rw("attr [$attr] $name => $value"); $attrs[$name] = $value; } else { $attrs[$attr] = ""; } } } #echo "tag=$tag_full<br>\n"; if (tag_if($attrs, $hf)) { //check for inline template and prepare it $inline_tpl = ''; $is_inline_tpl = false; if (array_key_exists('inline', $attrs)) { $is_inline_tpl = true; $inline_tpl = get_inline_tpl($page, $tag, $tag_full); #rw("inline = $inline_tpl"); } //get var from GLOBALS, not from $hf if (array_key_exists('global', $attrs)) { $tagvalue = hfvalue($tag, fw::i()->G); #was: $GLOBALS } elseif (array_key_exists('session', $attrs)) { $tagvalue = hfvalue($tag, $_SESSION); } elseif (array_key_exists('parent', $attrs) && is_array($parent_hf)) { $tagvalue = hfvalue($tag, $parent_hf); //get usual var } else { $tagvalue = hfvalue($tag, $hf); } # $attr_lang=''; # if ( array_key_exists('lang', $attrs) ) $attr_lang=$attrs['lang']; //start working with tag value if (!is_null($tagvalue)) { //rw("$tag EXISTS"); if (array_key_exists('repeat', $attrs)) { //if this is 'repeat' tag parse as datarow if (is_array($tagvalue)) { $repeat_array = $tagvalue; $tagvalue = ''; $hfcount = count($repeat_array); $k1 = 0; foreach ($repeat_array as $k => $v) { $hfrow = $v; $hfrow['repeat.last'] = $k1 == $hfcount - 1 ? 1 : 0; $hfrow['repeat.first'] = $k1 == 0 ? 1 : 0; $hfrow['repeat.even'] = $k1 % 2 ? 1 : 0; $hfrow['repeat.odd'] = $k1 % 2 ? 0 : 1; $hfrow['repeat.index'] = $k1; $hfrow['repeat.iteration'] = $k1 + 1; $hfrow['repeat.total'] = $hfcount; $tagvalue .= parse_page($basedir, tag_tplpath($tag, $tpl_name, $is_inline_tpl), $hfrow, 'v', $inline_tpl, $hf); $k1++; } } else { logger('WARN', 'ParsePage - not an array passed to repeat tag = ' . $tag); $tagvalue = ''; } } elseif (array_key_exists('sub', $attrs)) { //if this is 'sub' tag - parse it as independent subtemplate $tagvalue = parse_page($basedir, tag_tplpath($tag, $tpl_name, $is_inline_tpl), $tagvalue, 'v', $inline_tpl, $hf); } else { //if usual tag - replace it with tagvalue got above #CSRF shield +1 if ($tagvalue > "" && !array_key_exists('noescape', $attrs)) { $tagvalue = htmlescape($tagvalue); } } $page = tag_replace($page, $tag_full, $tagvalue, $attrs); } elseif (array_key_exists('repeat', $attrs)) { //if it's repeat tag, but tag value empty - just replace with empty string $page = tag_replace($page, $tag_full, '', $attrs); } elseif (array_key_exists('var', $attrs)) { //if tag doesn't exists in $hf and it's marked as variable (var) //then don't make subparse and just replace to empty string for more performance $page = tag_replace($page, $tag_full, "", $attrs); } elseif (array_key_exists('select', $attrs)) { //this is special case for '<select>' HTML tag $v = parse_select_tag($basedir, tag_tplpath($tag, $tpl_name, $is_inline_tpl), $hf, $attrs); $page = tag_replace($page, $tag_full, $v, $attrs); } elseif (array_key_exists('radio', $attrs)) { //this is special case for '<index type=radio>' HTML tag $v = parse_radio_tag($basedir, tag_tplpath($tag, $tpl_name, $is_inline_tpl), $hf, $attrs); $page = tag_replace($page, $tag_full, $v, $attrs); } elseif (array_key_exists('selvalue', $attrs)) { //this is special case for displaying just one selected value (for '<select>' or '<index type=radio>' HTML tags $v = parse_selvalue_tag($basedir, tag_tplpath($tag, $tpl_name, $is_inline_tpl), $hf, $attrs); if (!array_key_exists('noescape', $attrs)) { $v = htmlescape($v); } $page = tag_replace($page, $tag_full, $v, $attrs); } else { //if tag is not set and not a var - then it's subtemplate in a file - parse it //echo "$tag SUBPARSE<br>\n"; $v = parse_page($basedir, tag_tplpath($tag, $tpl_name, $is_inline_tpl), $hf, 'v', $inline_tpl, $hf); $page = tag_replace($page, $tag_full, $v, $attrs); } } else { $page = tag_replace_raw($page, $tag_full, '', array_key_exists('inline', $attrs)); // print "$tag not shown\n"; } } } //if tags empty } //if tpl empty if ($out_filename && $out_filename != 'v' && $out_filename != 's') { $outdir = dirname($out_filename); //check dir if (!is_dir($outdir)) { mkdir($outdir, 0777); } $OUTFILE = fopen($out_filename, "w") or die("Can't open out [{$out_filename}] file"); fputs($OUTFILE, $page); fclose($OUTFILE); } else { if ($out_filename == 'v') { #variable mode return $page; } else { #screen mode print_header(); print $page; } } }
function parse_page($page, $apiKey) { global $records; echo "Page {$page}\n"; $query = '(standardreferencenumber:RRC+OR+standardreferencenumber:RIC+OR+standardreferencenumber:Price)'; //$query = '"RIC+IX,+p.+235,+88b(1)"'; $service = 'http://api.harvardartmuseums.org/object?size=100&classification=Coins&q=' . $query . '+AND+department:"Department%20of%20Ancient%20and%20Byzantine%20Art%20%26%20Numismatics"&apikey=' . $apiKey . '&page=' . $page; $json = file_get_contents($service); $data = json_decode($json); foreach ($data->records as $record) { $references = explode(';', $record->standardreferencenumber); foreach ($references as $reference) { if (preg_match('/RRC/', $reference)) { $num = explode(' ', $reference); $row = array(); //generate record metadata array $row = construct_metadata($record); $row['reference'] = $reference; //ignore uncertain coins if (substr($num[1], -1) != '?') { $cointype = 'http://numismatics.org/crro/id/rrc-' . str_replace('/', '.', $num[1]); $file_headers = @get_headers($cointype); if ($file_headers[0] == 'HTTP/1.1 200 OK') { echo "{$row['objectnumber']}: {$cointype}\n"; $row['cointype'] = $cointype; } } $records[] = $row; //end RRC processing } elseif (preg_match('/Price/', $reference)) { $num = explode(' ', $reference); $row = array(); //generate record metadata array $row = construct_metadata($record); $row['reference'] = $reference; //ignore uncertain coins if (substr($num[1], -1) != '?') { $cointype = 'http://numismatics.org/pella/id/price.' . $num[1]; $file_headers = @get_headers($cointype); if ($file_headers[0] == 'HTTP/1.1 200 OK') { echo "{$row['objectnumber']}: {$cointype}\n"; $row['cointype'] = $cointype; } } $records[] = $row; //end PELLA processing } elseif (preg_match('/RIC/', $reference)) { $originalReference = $reference; $pieces = explode(',', $reference); $volNum = $pieces[0]; //1. get volume number and then strip from reference. 2. trim leading or trailing commas. 3. trim spaces switch ($volNum) { case 'RIC I 2': $parsedVolume = $volNum; $volume = 'ric.1(2)'; break; case 'RIC II': $parsedVolume = $volNum; $volume = 'ric.2'; break; case 'RIC II.1 2': case 'RIC II (2)': $parsedVolume = $volNum; $volume = 'ric.2_1(2)'; break; case 'RIC III': $parsedVolume = $volNum; $volume = 'ric.3'; break; case 'RIC IV(B)': case 'RIC IV(C)': case 'RIC IV': case 'RIC iv/1': case 'RIC iv/2': case 'RIC iv/3': $parsedVolume = $volNum; $volume = 'ric.4'; break; case 'RIC V': case 'RIC V(1)': case 'RIC V(2)': case 'RIC v/1': case 'RIC v/2': $parsedVolume = $volNum; $volume = 'ric.5'; break; case 'RIC VI': $parsedVolume = $volNum; $volume = 'ric.6'; break; case 'RIC VII': $parsedVolume = $volNum; $volume = 'ric.7'; break; case 'RIC VIII': $parsedVolume = $volNum; $volume = 'ric.8'; break; case 'RIC IX': $parsedVolume = $volNum; $volume = 'ric.9'; break; case 'RIC X': $parsedVolume = $volNum; $volume = 'ric.10'; break; default: $volume = null; } //echo "{$volume}\n"; echo "{$originalReference}\n"; //strip parsed Volume and trailing/leading commas and whitespace $reference = trim(trim(str_replace($parsedVolume, '', $reference), ',')); //strip whitespace following the p. $reference = str_replace('p. ', 'p.', $reference); //only process currently published volumes if ($volume != null && strlen($reference) > 0) { $row = array(); //generate record metadata array $row = construct_metadata($record); $row['reference'] = $originalReference; //parse remaining numbers of the reference, determine page number based on 'p.' $arr = explode(' ', $reference); $pageNumber = ''; $id = ''; foreach ($arr as $item) { if (strpos($item, 'p.') !== FALSE) { $pageNumber = trim(trim(str_replace('p.', '', $item), ',')); } else { $id = trim(trim($item, ',')); } } if (strlen($id) > 0 && strlen($pageNumber) > 0) { //ignore uncertain coins if (substr($id, -1) != '?') { $authority = get_authority($parsedVolume, $pageNumber); if ($authority != null) { //if $authority is properly resolved, try OCRE lookups $prefix = "{$volume}.{$authority}."; if (preg_match('/[a-zA-Z]/', $id)) { //if it is volume 9, attempt to parse subtype numbers if ($volume == 'ric.9' && strpos($id, '(') !== FALSE) { //strip space $id = str_replace(' ', '', $id); preg_match('/([a-z0-9]+)\\(([0-9a-z])\\)/', $id, $matches); //first try to match on the subtype URI if (isset($matches[1]) and isset($matches[2])) { $cointype = "http://numismatics.org/ocre/id/{$prefix}" . strtoupper($matches[1]) . '.' . $matches[2]; $file_headers = @get_headers($cointype); if ($file_headers[0] == 'HTTP/1.1 200 OK') { echo "{$row['objectnumber']}: {$cointype}\n"; $row['cointype'] = $cointype; } else { //if it can't find the subtype, just try to match on parent type $cointype = "http://numismatics.org/ocre/id/{$prefix}" . strtoupper($matches[1]); $file_headers = @get_headers($cointype); if ($file_headers[0] == 'HTTP/1.1 200 OK') { echo "{$row['objectnumber']}: {$cointype}\n"; $row['cointype'] = $cointype; } } } } else { //try uppercase first $upper = strtoupper($id); $cointype = "http://numismatics.org/ocre/id/{$prefix}" . urlencode($upper); $file_headers = @get_headers($cointype); if ($file_headers[0] == 'HTTP/1.1 200 OK') { echo "{$row['objectnumber']}: {$cointype}\n"; $row['cointype'] = $cointype; } else { //then try default $cointype = "http://numismatics.org/ocre/id/{$prefix}" . urlencode($id); $file_headers = @get_headers($cointype); if ($file_headers[0] == 'HTTP/1.1 200 OK') { echo "{$row['objectnumber']}: {$cointype}\n"; $row['cointype'] = $cointype; } } } } else { $cointype = "http://numismatics.org/ocre/id/{$prefix}" . urlencode($id); $file_headers = @get_headers($cointype); if ($file_headers[0] == 'HTTP/1.1 200 OK') { echo "{$row['objectnumber']}: {$cointype}\n"; $row['cointype'] = $cointype; } } } } } $records[] = $row; } //end RIC processing } } } //if the page isn't the last, then move forward to the next one. if ($page < $data->info->pages) { $page++; parse_page($page, $apiKey); } }
public static function redirect($url, $noexit = '') { $url = fw::url2abs($url); logger("REDIRECT to [{$url}]"); $ps = array('url' => $url); parse_page("/common", "redirect_js.html", $ps); if (!$noexit) { throw new ExitException(); } }
function gallery_header() { global $headerinclude, $context, $header; echo parse_page('<html> <head> <title>' . $context['page_title'] . '</title> ' . $headerinclude . ' </head> <body> ' . $header); }
function textpattern() { global $pretext, $microstart, $prefs, $qcount, $qtime, $production_status, $txptrace, $siteurl, $has_article_tag; $has_article_tag = false; callback_event('textpattern'); if ($pretext['status'] == '404') { txp_die(gTxt('404_not_found'), '404'); } if ($pretext['status'] == '410') { txp_die(gTxt('410_gone'), '410'); } // Useful for clean URLs with error-handlers. txp_status_header('200 OK'); set_error_handler('tagErrorHandler'); $html = parse_page($pretext['page']); if ($html === false) { txp_die(gTxt('unknown_section'), '404'); } // Make sure the page has an article tag if necessary. if (!$has_article_tag and $production_status != 'live' and $pretext['context'] == 'article' and (!empty($pretext['id']) or !empty($pretext['c']) or !empty($pretext['q']) or !empty($pretext['pg']))) { trigger_error(gTxt('missing_article_tag', array('{page}' => $pretext['page']))); } restore_error_handler(); header("Content-type: text/html; charset=utf-8"); echo $html; if (in_array($production_status, array('debug', 'testing'))) { $microdiff = getmicrotime() - $microstart; echo n, comment('Runtime: ' . substr($microdiff, 0, 6)); echo n, comment('Query time: ' . sprintf('%02.6f', $qtime)); echo n, comment('Queries: ' . $qcount); echo maxMemUsage('end of textpattern()', 1); if (!empty($txptrace) and is_array($txptrace)) { echo n, comment('txp tag trace: ' . n . join(n, $txptrace) . n); } } callback_event('textpattern_end'); }