function safe_query($q = '', $debug = '', $unbuf = '') { global $DB, $txpcfg, $qcount, $qtime, $production_status; $method = !$unbuf ? 'mysql_query' : 'mysql_unbuffered_query'; if (!$q) { return false; } if ($debug or TXP_DEBUG === 1) { dmp($q); } $start = getmicrotime(); $result = $method($q, $DB->link); $time = sprintf('%02.6f', getmicrotime() - $start); @($qtime += $time); @$qcount++; if ($result === false and (txpinterface === 'admin' or @$production_status == 'debug' or @$production_status == 'testing')) { $caller = $production_status == 'debug' ? n . join("\n", get_caller()) : ''; trigger_error(mysql_error() . n . $q . $caller, E_USER_WARNING); } trace_add("[SQL ({$time}): {$q}]"); if (!$result) { return false; } return $result; }
function safe_query($q = '', $debug = '', $unbuf = '') { global $DB, $txpcfg, $qcount, $qtime, $production_status; $method = !$unbuf ? 'mysql_query' : 'mysql_unbuffered_query'; if (!$q) { return false; } if ($debug or TXP_DEBUG === 1) { dmp($q); dmp(mysql_error()); // dmp(debug_backtrace()); } $start = getmicrotime(); $result = $method($q, $DB->link); $time = sprintf('%02.6f', getmicrotime() - $start); @($qtime += $time); @$qcount++; if ($result === false and (@$production_status == 'debug' or @$production_status == 'test')) { trigger_error(mysql_error() . n . $q, E_USER_ERROR); } trace_add("[SQL ({$time}): {$q}]"); if (!$result) { return false; } return $result; }
function processTags($matches) { global $pretext, $production_status, $txptrace, $txptracelevel, $txp_current_tag; $tag = $matches[1]; $trouble_makers = array('link'); if (in_array($tag, $trouble_makers)) { $tag = 'tpt_' . $tag; } $atts = isset($matches[2]) ? splat($matches[2]) : ''; $thing = isset($matches[4]) ? $matches[4] : null; $old_tag = @$txp_current_tag; $txp_current_tag = '<txp:' . $tag . ($atts ? $matches[2] : '') . ($thing ? '>' : '/>'); trace_add($txp_current_tag); @++$txptracelevel; if ($production_status == 'debug') { maxMemUsage(trim($matches[0])); } $out = ''; if (function_exists($tag)) { $out = $tag($atts, $thing, $matches[0]); } elseif (isset($pretext[$tag])) { $out = $pretext[$tag]; } else { trigger_error(gTxt('unknown_tag', array('{tag}' => $tag)), E_USER_WARNING); } @--$txptracelevel; if (isset($matches[4])) { trace_add('</txp:' . $tag . '>'); } $txp_current_tag = $old_tag; return $out; }
/** * Parses a page template. * * @param string $name The template * @return string|bool The parsed page template, or FALSE on error * @since 4.6.0 * @package TagParser * @example * echo parse_page('default'); */ function parse_page($name) { global $pretext; $page = fetch_page($name); if ($page !== false) { $pretext['secondpass'] = false; $page = parse($page); $pretext['secondpass'] = true; trace_add('[ ~~~ ' . gTxt('secondpass') . ' ~~~ ]'); $page = parse($page); } return $page; }
function variable($atts, $thing = NULL) { global $variable; extract(lAtts(array('name' => '', 'value' => parse($thing)), $atts)); if (empty($name)) { trigger_error(gTxt('variable_name_empty')); return; } if (!isset($atts['value']) && is_null($thing)) { if (isset($variable[$name])) { return $variable[$name]; } else { trace_add("[<txp:variable>: Unknown variable '{$name}']"); return ''; } } else { $variable[$name] = $value; } }
function fetch_form($name) { static $forms = array(); if (isset($forms[$name])) { $f = $forms[$name]; } else { $f = fetch('Form', 'txp_form', 'name', doSlash($name)); if (!$f) { return graf('form ' . strong($name) . ' does not exist'); } $forms[$name] = $f; } trace_add('[' . gTxt('form') . ': ' . $name . ']'); return $f; }
/** * Save and retrieve the individual article's attributes plus article list attributes for next/prev tags * * @param array $atts * @return array * @since 4.5.0 */ function filterAtts($atts = null) { global $prefs; static $out = array(); $valid = array('sort' => 'Posted desc', 'sortby' => '', 'sortdir' => '', 'keywords' => '', 'expired' => $prefs['publish_expired_articles'], 'id' => '', 'time' => 'past'); if (is_array($atts)) { if (empty($out)) { $out = $atts; trace_add('[filterAtts accepted]'); } else { // TODO: deal w/ nested txp:article[_custom] tags. trace_add('[filterAtts ignored]'); } } if (empty($out)) { trace_add('[filterAtts not set]'); } return lAtts($valid, $out, 0); }
die('If you just updated and expect to see your site here, please also update the files in your main installation directory.' . ' (Otherwise note that publish.php cannot be called directly.)'); } include_once txpath . '/vendors/Textpattern/Loader.php'; $loader = new \Textpattern\Loader(txpath . '/vendors'); $loader->register(); $loader = new \Textpattern\Loader(txpath . '/lib'); $loader->register(); include_once txpath . '/lib/txplib_publish.php'; include_once txpath . '/lib/txplib_db.php'; include_once txpath . '/lib/txplib_html.php'; include_once txpath . '/lib/txplib_forms.php'; include_once txpath . '/lib/admin_config.php'; include_once txpath . '/publish/taghandlers.php'; include_once txpath . '/publish/log.php'; include_once txpath . '/publish/comment.php'; trace_add('[PHP Include end]'); set_error_handler('publicErrorHandler', error_reporting()); ob_start(); $txp_current_tag = ''; // Get all prefs as an array. $prefs = get_prefs(); // Add prefs to globals. extract($prefs); // Check the size of the URL request. bombShelter(); // Set a higher error level during initialisation. set_error_level(@$production_status == 'live' ? 'testing' : @$production_status); // Use the current URL path if $siteurl is unknown. if (empty($siteurl)) { $httphost = preg_replace('/[^-_a-zA-Z0-9.:]/', '', $_SERVER['HTTP_HOST']); $prefs['siteurl'] = $siteurl = $httphost . rtrim(dirname($_SERVER['SCRIPT_NAME']), DS);
/** * Loads a class. * * @param string $class The class * @return bool */ public function load($class) { $request = $class; if ($this->namespace !== null && strpos($class, $this->namespace . $this->separator) !== 0 || !preg_match('/^[\\a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\\\x7f-\\xff]*$/', $class)) { return false; } $file = $this->directory . '/'; $divide = strripos($class, $this->separator); if ($divide !== false) { $namespace = substr($class, 0, $divide); $class = substr($class, $divide + 1); $file .= str_replace($this->separator, '/', $namespace) . '/'; } $file .= $class . $this->extension; if (is_readable($file)) { trace_add("\t[Load: '" . str_replace(txpath . '/', '', $file) . "']"); require_once $file; if (class_exists($request, false)) { trace_add("\t\t[Class loaded: '{$class}']"); return true; } } return false; }
function safe_query($q = '', $debug = '', $unbuf = '') { global $DB, $txpcfg, $qcount, $qtime, $production_status; $method = !$unbuf ? 'mysql_query' : 'mysql_unbuffered_query'; if (!$q) { return false; } if ($debug or TXP_DEBUG === 1) { dmp($q); } $start = getmicrotime(); $result = $method($q, $DB->link); $time = getmicrotime() - $start; @($qtime += $time); @$qcount++; if ($result === false) { trigger_error(mysql_error(), E_USER_ERROR); } trace_add("[SQL ({$time}): {$q}]"); if (!$result) { return false; } return $result; }
function _l10n_pretext() { function load_localised_pref($name) { global $prefs, $pretext; $k = "snip-{$name}"; $r = gTxt($k); if ($r !== $k) { $GLOBALS[$name] = $r; $GLOBALS['prefs'][$name] = $r; $prefs[$name] = $r; $pretext[$name] = $r; } } global $l10n_language, $textarray, $prefs; $first_chunk = _l10n_process_url(); # # Now we know what language this user is browsing in. # If it is NOT the site's currently selected language then we need to re-load # the textarray with the right language (otherwise some strings used in comment forms # and older/newer tags will be wrong! # if (LANG !== $l10n_language['long'] and LANG !== $l10n_language['short']) { trace_add("L10N MLP: Switching to {$l10n_language['long']} from " . LANG); $textarray = load_lang($l10n_language['long']); $prefs['language'] = $l10n_language['long']; } load_localised_pref('site_slogan'); @($GLOBALS['prefs']['comments_default_invite'] = gTxt('comment')); # # Don't know why, but there seems to be some whitespace getting into the # output buffer. XHTML can cope but it causes a parse error in the feed xml # # Simple solution is to make sure the output buffer is empty before # continuing the processing of rss or atom requests... # $ob_cleaning = array('rss', 'atom'); if (in_array($first_chunk, $ob_cleaning)) { while (@ob_end_clean()) { } } }
/** * Trace log: Start / Display / Result values / Quiet mode. * * @param int $flags One of TEXTPATTERN_TRACE_START | TEXTPATTERN_TRACE_DISPLAY * TEXTPATTERN_TRACE_RESULT | TEXTPATTERN_TRACE_QUIET * @return mixed * @since 4.6.0 * @package Debug */ function trace_log($flags = TEXTPATTERN_TRACE_RESULT) { global $production_status, $plugin_callback, $txptrace, $txptrace_quiet, $txptrace_qtime, $txptrace_qcount, $txptrace_microstart, $txptrace_maxMemMsg; if ($flags & TEXTPATTERN_TRACE_START) { $txptrace_microstart = getmicrotime(); $production_status = 'debug'; $txptrace = array(); trace_add('[Trace Start]'); return; } if ($flags & TEXTPATTERN_TRACE_QUIET) { $txptrace_quiet = 1; return; } $microdiff = getmicrotime() - $txptrace_microstart; $memory_peak = is_callable('memory_get_peak_usage') ? ceil(memory_get_peak_usage(true) / 1024) : '-'; if ($production_status !== 'live' && $flags & TEXTPATTERN_TRACE_DISPLAY) { trace_add('[Trace End]'); echo n, comment('Runtime: ' . substr($microdiff, 0, 8)); echo n, comment('Query time: ' . sprintf('%02.6f', $txptrace_qtime) . "; Queries: {$txptrace_qcount} "); if (!empty($txptrace_maxMemMsg)) { echo n . comment("Memory: {$txptrace_maxMemMsg}"); } echo n . comment(sprintf('Memory Peak: %s kB ', $memory_peak)); if ($production_status === 'debug') { $trace_log = join(n, preg_replace('/[\\r\\n]+/s', ' ', $txptrace)); trace_out('Trace log: ' . n . 'Mem(kB)_|__+(kB)_|___+(ms)_|_Trace___' . n . $trace_log); if (!empty($plugin_callback)) { $out = sprintf('%40s |%40s |%20s | %s ', 'function', 'event', 'step', 'pre') . n; $out = str_replace(' ', '_', $out); foreach ($plugin_callback as $p) { if (is_string($p['function'])) { $name = $p['function']; } elseif (@is_object($p['function'][0])) { $name = @get_class($p['function'][0]); } else { $name = ''; } $out .= sprintf('%40s | %-40s| %-20s| %s', $name, $p['event'], $p['step'], $p['pre']) . n; } trace_out('Plugin callback:' . n . $out); } if (preg_match_all('/(\\[SQL.*\\])/', $trace_log, $mm)) { trace_out('Query log:' . n . join(n, $mm[1]) . n . 'Time: ' . sprintf('%02.6f', $txptrace_qtime) . ": Queries: {$txptrace_qcount} "); } callback_event('trace_end', 'display'); } } if ($flags & TEXTPATTERN_TRACE_RESULT) { if ($production_status === 'debug') { callback_event('trace_end', 'result'); } return array('microdiff' => $microdiff, 'memory_peak' => $memory_peak, 'queries' => $txptrace_qcount); } }
define("txpinterface", "public"); if (!defined('txpath')) { define("txpath", dirname(__FILE__) . '/textpattern'); } // Save server path to site root. if (!isset($here)) { $here = dirname(__FILE__); } // Pull in config unless configuration data has already been provided // (multi-headed use). if (!isset($txpcfg['table_prefix'])) { // Use buffering to ensure bogus whitespace in config.php is ignored. ob_start(null, 2048); include txpath . '/config.php'; ob_end_clean(); } include txpath . '/lib/constants.php'; include txpath . '/lib/txplib_misc.php'; trace_log(TEXTPATTERN_TRACE_START); if (!isset($txpcfg['table_prefix'])) { txp_status_header('503 Service Unavailable'); exit('config.php is missing or corrupt. To install Textpattern, visit <a href="./textpattern/setup/">textpattern/setup/</a>'); } // Custom caches, etc? if (!empty($txpcfg['pre_publish_script'])) { trace_add("[Pre Publish Script: '{$txpcfg['pre_publish_script']}']"); require $txpcfg['pre_publish_script']; } include txpath . '/publish.php'; textpattern(); trace_log(TEXTPATTERN_TRACE_DISPLAY);
/** * Executes an SQL statement. * * @param string $q The SQL statement to execute * @param bool $debug Dump query * @param bool $unbuf If TRUE, executes the statement without fetching and buffering the results * @return mixed * @example * echo safe_query('SELECT * FROM table'); */ function safe_query($q = '', $debug = false, $unbuf = false) { global $DB, $txpcfg, $txptrace_qcount, $txptrace_qtime, $production_status; $method = $unbuf ? MYSQLI_USE_RESULT : MYSQLI_STORE_RESULT; if (!$q) { return false; } if ($debug or TXP_DEBUG === 1) { dmp($q); } $start = getmicrotime(); $result = mysqli_query($DB->link, $q, $method); $time = getmicrotime() - $start; @($txptrace_qtime += $time); @$txptrace_qcount++; if ($result === false) { trigger_error(mysqli_error($DB->link), E_USER_ERROR); } trace_add('[SQL (' . number_format($time, 6, '.', '') . "): {$q}]"); if (!$result) { return false; } return $result; }
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'); } $html = safe_field('user_html', 'txp_page', "name='" . doSlash($pretext['page']) . "'"); if (!$html) { txp_die(gTxt('unknown_section'), '404'); } // useful for clean urls with error-handlers txp_status_header('200 OK'); trace_add('[' . gTxt('page') . ': ' . $pretext['page'] . ']'); set_error_handler("tagErrorHandler"); $pretext['secondpass'] = false; $html = parse($html); $pretext['secondpass'] = true; trace_add('[ ~~~ ' . gTxt('secondpass') . ' ~~~ ]'); $html = parse($html); // the function so nice, he ran it twice // 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 . str_replace('--', '­­', join(n, $txptrace)) . n); } // '­­' is *no* tribute to Kajagoogoo, but an attempt to avoid prematurely terminating HTML comments } callback_event('textpattern_end'); }
function query($q = '', $debug = '') { global $qcount, $qtime; if (!$q) { return false; } $start = getmicrotime(); $result = $this->DB->do_query($q, $this->DB->link); if ($debug or $this->_debug) { dmp($q, $result); } $time = sprintf('%02.6f', getmicrotime() - $start); @($qtime += $time); @$qcount++; if ($result === false and (txpinterface === 'admin' or !is_production_status('live'))) { $caller = is_production_status('debug') ? n . join("\n", get_caller()) : ''; trigger_error($this->DB->lasterror() . n . $q . $caller, E_USER_WARNING); } trace_add("[SQL ({$time}): {$q}]"); if (!$result) { return false; } return $result; }
function processTags($tag, $atts, $thing = NULL) { global $production_status, $txptrace, $txptracelevel, $txp_current_tag; if ($production_status !== 'live') { $old_tag = $txp_current_tag; $txp_current_tag = '<txp:' . $tag . $atts . (isset($thing) ? '>' : '/>'); trace_add($txp_current_tag); ++$txptracelevel; if ($production_status === 'debug') { maxMemUsage($txp_current_tag); } } if ($tag === 'link') { $tag = 'tpt_' . $tag; } if (function_exists($tag)) { $out = $tag(splat($atts), $thing); } elseif (isset($GLOBALS['pretext'][$tag])) { $out = htmlspecialchars($pretext[$tag]); trigger_error(gTxt('deprecated_tag'), E_USER_NOTICE); } else { $out = ''; trigger_error(gTxt('unknown_tag'), E_USER_WARNING); } if ($production_status !== 'live') { --$txptracelevel; if (isset($thing)) { trace_add('</txp:' . $tag . '>'); } $txp_current_tag = $old_tag; } return $out; }
function fetch_page_template($name, $pfx = NULL) { static $pages = array(); global $txp_theme; if ($pfx === NULL) { $pfx = @$txp_theme; } $name = $pfx . $name; if (isset($pages[$name])) { $p = $pages[$name]; } else { $row = safe_row('user_html', 'txp_page', "name='" . doSlash($name) . "'"); if (!$row) { trigger_error(gTxt('page_template_not_found', array('{name}' => $name))); return; } $p = $row['user_html']; $pages[$name] = $p; } trace_add('[' . gTxt('page') . ': ' . $name . ']'); return $p; }
function fetch_section_description($name) { static $sections = array(); if (isset($sections[$name])) { $f = $sectionss[$name]; } else { $row = safe_row('descr', 'txp_section', "name='" . doSlash($name) . "'"); if (!$row) { return; } $f = $row['descr']; $sectionss[$name] = $f; } trace_add('[' . gTxt('section') . ': ' . $name . ']'); return $f; }
function populateArticleData($rs) { extract($rs); trace_add("[" . gTxt('Article') . " {$ID}]"); $out['thisid'] = $ID; $out['posted'] = $uPosted; $out['expires'] = $uExpires; $out['modified'] = $LastMod; $out['annotate'] = $Annotate; $out['comments_invite'] = $AnnotateInvite; $out['authorid'] = $AuthorID; $out['title'] = $Title; $out['url_title'] = $url_title; $out['category1'] = $Category1; $out['category2'] = $Category2; $out['section'] = $Section; $out['keywords'] = $Keywords; $out['article_image'] = $Image; $out['comments_count'] = $comments_count; $out['body'] = $Body_html; $out['excerpt'] = $Excerpt_html; $out['override_form'] = $override_form; $out['status'] = $Status; $custom = getCustomFields(); if ($custom) { foreach ($custom as $i => $name) { $out[$name] = $rs['custom_' . $i]; } } global $thisarticle; $thisarticle = $out; }
function fetch_form($name) { static $forms = array(); if (isset($forms[$name])) { $f = $forms[$name]; } else { $row = safe_row('Form', 'txp_form', "name='" . doSlash($name) . "'"); if (!$row) { trigger_error(gTxt('form_not_found') . ': ' . $name); return; } $f = $row['Form']; $forms[$name] = $f; } trace_add('[' . gTxt('form') . ': ' . $name . ']'); return $f; }
function _l10n_pretext() { global $l10n_language, $textarray, $prefs; $first_chunk = _l10n_process_url(); # # Now we know what language this user is browsing in. # If it is NOT the site's currently selected language then we need to re-load # the textarray with the right language (otherwise some strings used in comment forms # and older/newer tags will be wrong! # if (LANG !== $l10n_language['long'] and LANG !== $l10n_language['short']) { trace_add("L10N MLP: Switching to {$l10n_language['long']} from " . LANG); $textarray = load_lang($l10n_language['long']); $prefs['language'] = $l10n_language['long']; } _l10n_load_localised_pref('site_slogan'); @($GLOBALS['prefs']['comments_default_invite'] = gTxt('comment')); $feeds = array('rss', 'atom'); if (in_array($first_chunk, $feeds)) { # Prevent the feed routine(s) from removing our handler! if (extension_loaded('zlib') && ini_get('zlib.output_compression') == 0 && ini_get('output_handler') != 'ob_gzhandler' && !headers_sent()) { @ob_start('ob_gzhandler'); if ($prefs['l10n_l10n-clean_feeds'] == '0') { ini_set('zlib.output_compression', 1); } } # Inject our language markers into the feed stream... @ob_start('_l10n_inject_' . $first_chunk . '_lang_markers'); } elseif ($first_chunk !== 'file_download') { @ob_start('_l10n_inject_lang_markers'); } }