function saveComment() { global $siteurl, $comments_moderate, $comments_sendmail, $txpcfg, $comments_disallow_images, $prefs; $ref = serverset('HTTP_REFERRER'); $in = getComment(); $evaluator =& get_comment_evaluator(); extract($in); if (!checkCommentsAllowed($parentid)) { txp_die(gTxt('comments_closed'), '403'); } $ip = serverset('REMOTE_ADDR'); if (!checkBan($ip)) { txp_die(gTxt('you_have_been_banned'), '403'); } $blacklisted = is_blacklisted($ip); if ($blacklisted) { txp_die(gTxt('your_ip_is_blacklisted_by' . ' ' . $blacklisted), '403'); } $web = clean_url($web); $email = clean_url($email); if ($remember == 1 || ps('checkbox_type') == 'forget' && ps('forget') != 1) { setCookies($name, $email, $web); } else { destroyCookies(); } $name = doSlash(strip_tags(deEntBrackets($name))); $web = doSlash(strip_tags(deEntBrackets($web))); $email = doSlash(strip_tags(deEntBrackets($email))); $message = substr(trim($message), 0, 65535); $message2db = doSlash(markup_comment($message)); $isdup = safe_row("message,name", "txp_discuss", "name='{$name}' and message='{$message2db}' and ip='" . doSlash($ip) . "'"); if ($prefs['comments_require_name'] && !trim($name) || $prefs['comments_require_email'] && !trim($email) || !trim($message)) { $evaluator->add_estimate(RELOAD, 1); // The error-messages are added in the preview-code } if ($isdup) { $evaluator->add_estimate(RELOAD, 1); } // FIXME? Tell the user about dupe? if ($evaluator->get_result() != RELOAD && checkNonce($nonce)) { callback_event('comment.save'); $visible = $evaluator->get_result(); if ($visible != RELOAD) { $parentid = assert_int($parentid); $rs = safe_insert("txp_discuss", "parentid = {$parentid},\n\t\t\t\t\t name\t\t = '{$name}',\n\t\t\t\t\t email\t = '{$email}',\n\t\t\t\t\t web\t\t = '{$web}',\n\t\t\t\t\t ip\t\t = '" . doSlash($ip) . "',\n\t\t\t\t\t message = '{$message2db}',\n\t\t\t\t\t visible = " . intval($visible) . ",\n\t\t\t\t\t posted\t = now()"); if ($rs) { safe_update("txp_discuss_nonce", "used = 1", "nonce='" . doSlash($nonce) . "'"); if ($prefs['comment_means_site_updated']) { update_lastmod(); } if ($comments_sendmail) { mail_comment($message, $name, $email, $web, $parentid, $rs); } $updated = update_comments_count($parentid); $backpage = substr($backpage, 0, $prefs['max_url_len']); $backpage = preg_replace("/[\n\r#].*\$/s", '', $backpage); $backpage = preg_replace("#(https?://[^/]+)/.*\$#", "\$1", hu) . $backpage; if (defined('PARTLY_MESSY') and PARTLY_MESSY) { $backpage = permlinkurl_id($parentid); } $backpage .= (strstr($backpage, '?') ? '&' : '?') . 'commented=' . ($visible == VISIBLE ? '1' : '0'); txp_status_header('302 Found'); if ($comments_moderate) { header('Location: ' . $backpage . '#txpCommentInputForm'); } else { header('Location: ' . $backpage . '#c' . sprintf("%06s", $rs)); } log_hit('302'); $evaluator->write_trace(); exit; } } } // Force another Preview $_POST['preview'] = RELOAD; //$evaluator->write_trace(); }
function handle_lastmod($unix_ts = NULL, $exit = 1) { global $prefs; extract($prefs); if ($send_lastmod and $production_status == 'live') { $unix_ts = get_lastmod($unix_ts); # make sure lastmod isn't in the future $unix_ts = min($unix_ts, time()); # or too far in the past (7 days) $unix_ts = max($unix_ts, time() - 3600 * 24 * 7); $last = safe_strftime('rfc822', $unix_ts, 1); header("Last-Modified: {$last}"); header('Cache-Control: no-cache'); $hims = serverset('HTTP_IF_MODIFIED_SINCE'); if ($hims and @strtotime($hims) >= $unix_ts) { log_hit('304'); if (!$exit) { return array('304', $last); } txp_status_header('304 Not Modified'); # some mod_deflate versions have a bug that breaks subsequent # requests when keepalive is used. dropping the connection # is the only reliable way to fix this. if (empty($lastmod_keepalive)) { header('Connection: close'); } header('Content-Length: 0'); # discard all output while (@ob_end_clean()) { } exit; } if (!$exit) { return array('200', $last); } } }
function output_file_download($filename) { global $file_error, $file_base_path, $pretext; callback_event('file_download'); if (!isset($file_error)) { $filename = sanitizeForFile($filename); $fullpath = build_file_path($file_base_path, $filename); if (is_file($fullpath)) { // Discard any error PHP messages. ob_clean(); $filesize = filesize($fullpath); $sent = 0; header('Content-Description: File Download'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="' . $filename . '"; size = "' . $filesize . '"'); // Fix for IE6 PDF bug on servers configured to send cache headers. header('Cache-Control: private'); @ini_set("zlib.output_compression", "Off"); @set_time_limit(0); @ignore_user_abort(true); if ($file = fopen($fullpath, 'rb')) { while (!feof($file) and connection_status() == 0) { echo fread($file, 1024 * 64); $sent += 1024 * 64; ob_flush(); flush(); } fclose($file); // Record download. if (connection_status() == 0 and !connection_aborted()) { safe_update('txp_file', "downloads = downloads + 1", "id = " . intval($pretext['id'])); } else { $pretext['request_uri'] .= $sent >= $filesize ? '#aborted' : "#aborted-at-" . floor($sent * 100 / $filesize) . "%"; } log_hit('200'); } } else { $file_error = 404; } } // Deal with error. if (isset($file_error)) { switch ($file_error) { case 403: txp_die(gTxt('403_forbidden'), '403'); break; case 404: txp_die(gTxt('404_not_found'), '404'); break; default: txp_die(gTxt('500_internal_server_error'), '500'); break; } } }
break; case 404: txp_die(gTxt('404_not_found'), '404'); break; default: txp_die(gTxt('500_internal_server_error'), '500'); break; } } // download done exit(0); } // send 304 Not Modified if appropriate handle_lastmod(); // log the page view log_hit($status); // ------------------------------------------------------------- function preText($s, $prefs) { extract($prefs); callback_event('pretext'); if (gps('rss')) { include txpath . '/publish/rss.php'; exit(rss()); } if (gps('atom')) { include txpath . '/publish/atom.php'; exit(atom()); } // set messy variables $out = makeOut('id', 's', 'c', 'q', 'pg', 'p', 'month', 'author');
/** * Sends and handles a lastmod header. * * @param int|null $unix_ts The last modification date as a UNIX timestamp * @param bool $exit If TRUE, terminates the script * @return array|null Array of sent HTTP status and the lastmod header, or NULL * @package Pref */ function handle_lastmod($unix_ts = null, $exit = true) { if (get_pref('send_lastmod') && get_pref('production_status') == 'live') { $unix_ts = get_lastmod($unix_ts); // Make sure lastmod isn't in the future. $unix_ts = min($unix_ts, time()); // Or too far in the past (7 days). $unix_ts = max($unix_ts, time() - 3600 * 24 * 7); $last = safe_strftime('rfc822', $unix_ts, 1); header("Last-Modified: {$last}"); header('Cache-Control: no-cache'); $hims = serverSet('HTTP_IF_MODIFIED_SINCE'); if ($hims and @strtotime($hims) >= $unix_ts) { log_hit('304'); if (!$exit) { return array('304', $last); } txp_status_header('304 Not Modified'); // Some mod_deflate versions have a bug that breaks subsequent // requests when keepalive is used. dropping the connection // is the only reliable way to fix this. if (!get_pref('lastmod_keepalive')) { header('Connection: close'); } header('Content-Length: 0'); // Discard all output. while (@ob_end_clean()) { } exit; } if (!$exit) { return array('200', $last); } } }
function _textpattern() { global $plugins_ver, $pretext, $prefs, $plugin_callback; $this->debug('Plugin: ' . $this->plugin_name . ' - ' . $plugins_ver[$this->plugin_name]); $this->debug('Function: ' . __FUNCTION__ . '()'); // URI $req = $pretext['req']; $req = preg_replace('%\\?[^\\/]+$%', '', $req); $this->debug('Request URI: ' . $req); $uri = explode('/', trim($req, '/')); // The number of components comes in useful when determining the best partial match. $uri_component_count = count($uri); // Permanent links $permlinks = $this->get_all_permlinks(1); // Force Textpattern and tags to use messy URLs - these are easier to // find in regex $this->set_permlink_mode(); if (count($permlinks)) { // We also want to match the front page of the site (for page numbers / feeds etc..). // Add a permlinks rule which will do that. $permlinks['default'] = array('components' => array(), 'settings' => array('pl_name' => 'gbp_permanent_links_default', 'pl_precedence' => '', 'pl_preview' => '/', 'con_section' => '', 'con_category' => '', 'des_section' => '', 'des_category' => '', 'des_permlink' => '', 'des_feed' => '', 'des_location' => '', 'des_page' => '')); // Extend the pretext_replacement scope outside the foreach permlink loop $pretext_replacement = NULL; foreach ($permlinks as $id => $pl) { // Extract the permlink settings $pl_settings = $pl['settings']; extract($pl_settings); $this->debug('Permlink name: ' . $pl_name); $this->debug('Permlink id: ' . $id); $this->debug('Preview: ' . $pl_preview); $pl_components = $pl['components']; // URI components $uri_components = $uri; $this->debug('PL component count: ' . count($pl_components)); $this->debug('URL component count: ' . count($uri_components)); $date = false; $title_page_feed = false; foreach ($pl_components as $pl_c) { // Are we expecting a date component? If so the number of pl and uri components won't match if ($pl_c['type'] == 'date') { $date = true; } else { if (in_array($pl_c['type'], array('title', 'page', 'feed'))) { $title_page_feed = true; } } } if (!$title_page_feed) { // If there isn't a title, page or feed component then append a special type for cleaver partial matching $pl_components[] = array('type' => 'title_page_feed', 'prefix' => '', 'suffix' => '', 'regex' => '', 'text' => ''); } // Exit early if there are more URL components than PL components, // taking into account whether there is a data component if (!$uri_components[0] || count($uri_components) > count($pl_components) + ($date ? 2 : 0)) { $this->debug('More URL components than PL components'); continue; } // Reset pretext_replacement as we are about to start another comparison $pretext_replacement = array('permlink_id' => $id); // Reset the article context string $context = array(); unset($context_str); if (!empty($des_section)) { $context[] = "`Section` = '{$des_section}'"; } if (!empty($des_category)) { $context[] = "(`Category1` = '{$des_category}' OR `Category2` = '{$des_category}')"; } $context_str = count($context) > 0 ? 'and ' . join(' and ', $context) : ''; // Assume there is no match $partial_match = false; $cleaver_partial_match = false; // Loop through the permlink components foreach ($pl_components as $pl_c_index => $pl_c) { // Assume there is no match $match = false; // Check to see if there are still URI components to be checked. if (count($uri_components)) { // Get the next component. $uri_c = array_shift($uri_components); } else { if (!$title_page_feed && count($pl_components) - 1 == $uri_component_count) { // If we appended a title_page_feed component earlier and permlink and URI components // counts are equal, we must of finished checking this permlink, and it matches so break. $match = true; break; } else { // If there are no more URI components then we have a partial match. // Store the partial match data unless there has been a preceding permlink with the // same number of components, as permlink have already been sorted by precedence. if (!array_key_exists($uri_component_count, $this->partial_matches)) { $this->partial_matches[$uri_component_count] = $pretext_replacement; } // Unset pretext_replacement as changes could of been made in a preceding component unset($pretext_replacement); // Break early form the foreach permlink components loop. $partial_match = true; break; } } // Extract the permlink components. extract($pl_c); // If it's a date, grab and combine the next two URI components. if ($type == 'date') { $uri_c .= '/' . array_shift($uri_components) . '/' . array_shift($uri_components); } // Decode the URL $uri_c = urldecode($uri_c); // Always check the type unless the prefix or suffix aren't there $check_type = true; // Check prefix if ($prefix && $this->pref('show_prefix')) { $sanitized_prefix = urldecode($this->encode_url($prefix)); if (($pos = strpos($uri_c, $sanitized_prefix)) === false || $pos != 0) { $check_type = false; $this->debug('Can\'t find prefix: ' . $prefix); } else { // Check passed, remove prefix ready for the next check $uri_c = substr_replace($uri_c, '', 0, strlen($sanitized_prefix)); } } // Check suffix if ($check_type && $suffix && $this->pref('show_suffix')) { $sanitized_suffix = urldecode($this->encode_url($suffix)); if (($pos = strrpos($uri_c, $sanitized_suffix)) === false) { $check_type = false; $this->debug('Can\'t find suffix: ' . $suffix); } else { // Check passed, remove suffix ready for the next check $uri_c = substr_replace($uri_c, '', $pos, strlen($sanitized_suffix)); } } // Both the prefix and suffix settings have passed if ($check_type) { $this->debug('Checking if "' . $uri_c . '" is of type "' . $type . '"'); $uri_c = doSlash($uri_c); // if ($prefs['permalink_title_format']) { $mt_search = array('/_/', '/\\.html$/'); $mt_replace = array('-', ''); } else { $mt_search = array('/(?:^|_)(.)/e', '/\\.html$/'); $mt_replace = array("strtoupper('\\1')", ''); } $mt_uri_c = $this->pref('redirect_mt_style_links') ? preg_replace($mt_search, $mt_replace, $uri_c) : ''; // Compare based on type switch ($type) { case 'section': if ($rs = safe_row('name', 'txp_section', "(`name` like '{$uri_c}' or `name` like '{$mt_uri_c}') limit 1")) { $this->debug('Section name: ' . $rs['name']); $pretext_replacement['s'] = $rs['name']; $context[] = "`Section` = '{$rs['name']}'"; $match = true; } break; case 'category': if ($rs = safe_row('name', 'txp_category', "(`name` like '{$uri_c}' or `name` like '{$mt_uri_c}') and `type` = 'article' limit 1")) { $this->debug('Category name: ' . $rs['name']); $pretext_replacement['c'] = $rs['name']; $context[] = "(`Category1` = '{$rs['name']}' OR `Category2` = '{$uri_c}')"; $match = true; } break; case 'title': if ($rs = safe_row('url_title', 'textpattern', "(`url_title` like '{$uri_c}' or `url_title` like '{$mt_uri_c}') {$context_str} and `Status` >= 4 limit 1")) { $this->debug('URL Title: ' . $rs['url_title']); $mt_redirect = $uri_c != $mt_uri_c; $pretext_replacement['url_title'] = $rs['url_title']; $match = true; } break; case 'id': if ($rs = safe_row('ID, Posted', 'textpattern', "`ID` = '{$uri_c}' {$context_str} and `Status` >= 4 limit 1")) { $pretext_replacement['id'] = $rs['ID']; $pretext_replacement['Posted'] = $rs['Posted']; $pretext['numPages'] = 1; $pretext['is_article_list'] = false; $match = true; } break; case 'author': if ($author = safe_field('name', 'txp_users', "RealName like '{$uri_c}' limit 1")) { $pretext_replacement['author'] = $author; $context[] = "`AuthorID` = '{$author}'"; $match = true; } break; case 'login': if ($author = safe_field('name', 'txp_users', "name like '{$uri_c}' limit 1")) { $pretext_replacement['author'] = $author; $context[] = "`AuthorID` = '{$author}'"; $match = true; } break; case 'custom': $custom_options = array_values(array_map(array($this, "encode_url"), safe_column("custom_{$custom}", 'textpattern', "custom_{$custom} != ''"))); if ($this->pref('force_lowercase_urls')) { $custom_options = array_map("strtolower", $custom_options); } if (in_array($uri_c, $custom_options)) { $match = true; } break; case 'date': if (preg_match('/^\\d{4}\\/\\d{2}\\/\\d{2}$/', $uri_c)) { $pretext_replacement['date'] = str_replace('/', '-', $uri_c); $match = true; } break; case 'year': if (preg_match('/^\\d{4}$/', $uri_c)) { $pretext_replacement['year'] = $uri_c; $match = true; } break; case 'month': case 'day': if (preg_match('/^\\d{2}$/', $uri_c)) { $pretext_replacement[$type] = $uri_c; $match = true; } break; case 'page': if (is_numeric($uri_c)) { $pretext_replacement['pg'] = $uri_c; $match = true; } break; case 'feed': if (in_array($uri_c, array('rss', 'atom'))) { $pretext_replacement[$uri_c] = 1; $match = true; } break; case 'search': $pretext_replacement['q'] = $uri_c; $match = true; break; case 'text': if ($this->encode_url($text) == $uri_c) { $match = true; $pretext_replacement["permlink_text_{$name}"] = $uri_c; } break; case 'regex': // Check to see if regex is valid without outputting error messages. ob_start(); preg_match($regex, $uri_c, $regex_matches); $is_valid_regex = !ob_get_clean(); if ($is_valid_regex && @$regex_matches[0]) { $match = true; $pretext_replacement["permlink_regex_{$name}"] = $regex_matches[0]; } break; } // switch type end // Update the article context string $context_str = count($context) > 0 ? 'and ' . join(' and ', $context) : ''; $this->debug($match == true ? 'YES' : 'NO'); if (!$match && !$cleaver_partial_match && $this->pref('use_cleaver_partial_matches')) { // There hasn't been a match or a complete cleaver partial match. Lets try to be cleaver and // check to see if this component is either a title, page or a feed. This makes it more probable // a successful match for a given permlink rule occurs. $this->debug('Checking if "' . $uri_c . '" is of type "title_page_feed"'); if ($type != 'title' && ($url_title = safe_field('url_title', 'textpattern', "`url_title` like '{$uri_c}' {$context_str} and `Status` >= 4 limit 1"))) { $pretext_replacement['url_title'] = $url_title; $pretext['numPages'] = 1; $pretext['is_article_list'] = false; $cleaver_partial_match = true; } else { if ($this->pref('clean_page_archive_links') && $type != 'page' && is_numeric($uri_c)) { $pretext_replacement['pg'] = $uri_c; $cleaver_partial_match = true; } else { if ($type != 'feed' && in_array($uri_c, array('rss', 'atom'))) { $pretext_replacement[$uri_c] = 1; $cleaver_partial_match = true; } } } $this->debug($cleaver_partial_match == true ? 'YES' : 'NO'); if ($cleaver_partial_match) { $this->cleaver_partial_match = $pretext_replacement; // Unset pretext_replacement as changes could of been made in a preceding component unset($pretext_replacement); $cleaver_partial_match = true; continue 2; } } } // check type end // Break early if the component doesn't match, as there is no point continuing if ($match == false) { // Unset pretext_replacement as changes could of been made in a preceding component unset($pretext_replacement); break; } } // foreach permlink component end if (!isset($pretext_replacement['id'])) { if (isset($pretext_replacement['url_title'])) { if (isset($pretext_replacement['date'])) { $date_val = $pretext_replacement['date']; } else { if (isset($pretext_replacement['year'])) { $date_val = $pretext_replacement['year']; if (isset($pretext_replacement['month'])) { $date_val .= '-' . $pretext_replacement['month']; if (isset($pretext_replacement['day'])) { $date_val .= '-' . $pretext_replacement['day']; } } } } if (isset($date_val)) { $context_str .= " and `Posted` like '{$date_val}%'"; } if ($rs = safe_row('ID, Posted', 'textpattern', "`url_title` like '{$pretext_replacement['url_title']}' {$context_str} and `Status` >= 4 order by `Posted` desc limit 1")) { if (isset($date_val)) { $this->debug('Found date and title-based match.'); } else { $this->debug('Found title-based match.'); } $pretext_replacement['id'] = $rs['ID']; $pretext_replacement['Posted'] = $rs['Posted']; $pretext['numPages'] = 1; $pretext['is_article_list'] = false; } else { $match = false; unset($pretext_replacement); } } } if ($match || $partial_match || $cleaver_partial_match) { // Extract the settings for this permlink @extract($permlinks[$pretext_replacement['permlink_id']]['settings']); // Check the permlink section and category conditions if (!empty($con_section) && $con_section != @$pretext_replacement['s'] || !empty($con_category) && $con_category != @$pretext_replacement['c']) { $this->debug('Permlink conditions failed'); if (@$con_section) { $this->debug('con_section = ' . $con_section); } if (@$con_category) { $this->debug('con_category = ' . $con_category); } unset($pretext_replacement); } else { if ($match && isset($pretext_replacement)) { $this->debug('We have a match!'); } else { if ($partial_match && count($this->partial_matches)) { $this->debug('We have a \'partial match\''); } else { if ($cleaver_partial_match && isset($cleaver_partial_match)) { $this->debug('We have a \'cleaver partial match\''); } else { $this->debug('Error: Can\'t determine the correct type match'); // This permlink has failed, continue execution of the foreach permlinks loop unset($pretext_replacement); } } } } } // We have a match if (@$pretext_replacement) { break; } } // foreach permlinks end // If there is no match restore the most likely partial match. Sorted by number of components and then precedence if (!@$pretext_replacement && count($this->partial_matches)) { $pt_slice = array_slice($this->partial_matches, -1); $pretext_replacement = array_shift($pt_slice); } unset($this->partial_matches); // Restore the cleaver_partial_match if there is no other matches if (!@$pretext_replacement && $this->cleaver_partial_match) { $pretext_replacement = $this->cleaver_partial_match; } unset($this->cleaver_partial_match); // Extract the settings for this permlink @extract($permlinks[$pretext_replacement['permlink_id']]['settings']); // If pretext_replacement is still set here then we have a match if (@$pretext_replacement) { $this->debug('Pretext Replacement ' . print_r($pretext_replacement, 1)); if (!empty($des_section)) { $pretext_replacement['s'] = $des_section; } if (!empty($des_category)) { $pretext_replacement['c'] = $des_category; } if (!empty($des_feed)) { $pretext_replacement[$des_feed] = 1; } if (@$pretext_replacement['id'] && @$pretext_replacement['Posted']) { if ($np = getNextPrev($pretext_replacement['id'], $pretext_replacement['Posted'], @$pretext_replacement['s'])) { $pretext_replacement = array_merge($pretext_replacement, $np); } } unset($pretext_replacement['Posted']); // If there is a match then we most set the http status correctly as txp's pretext might set it to 404 $pretext_replacement['status'] = '200'; // Store the orginial HTTP status code // We might need to log the page hit if it equals 404 $orginial_status = $pretext['status']; // Txp only looks at the month, but due to how we phase the month we can manipulate the sql to our needs if (array_key_exists('date', $pretext_replacement)) { $pretext_replacement['month'] = $pretext_replacement['date']; unset($pretext_replacement['date']); } else { if (array_key_exists('year', $pretext_replacement) || array_key_exists('month', $pretext_replacement) || array_key_exists('day', $pretext_replacement)) { $month = ''; $month .= array_key_exists('year', $pretext_replacement) ? $pretext_replacement['year'] . '-' : '____-'; $month .= array_key_exists('month', $pretext_replacement) ? $pretext_replacement['month'] . '-' : '__-'; $month .= array_key_exists('day', $pretext_replacement) ? $pretext_replacement['day'] . ' ' : '__ '; $pretext_replacement['month'] = $month; unset($pretext_replacement['year']); unset($pretext_replacement['day']); } } // Section needs to be defined so we can always get a page template. if (!array_key_exists('s', $pretext_replacement)) { if (!@$pretext_replacement['id']) { $pretext_replacement['s'] = 'default'; } else { $pretext_replacement['s'] = safe_field('Section', 'textpattern', 'ID = ' . $pretext_replacement['id']); } } // Set the css and page template, otherwise we get an unknown section $section_settings = safe_row('css, page', 'txp_section', "name = '{$pretext_replacement['s']}' limit 1"); $pretext_replacement['page'] = @$des_page ? $des_page : $section_settings['page']; $pretext_replacement['css'] = $section_settings['css']; $this->matched_permlink = $pretext_replacement; global $permlink_mode; if (in_array($prefs['permlink_mode'], array('id_title', 'section_id_title')) && @$pretext_replacement['pg'] && !@$pretext_replacement['id']) { $pretext_replacement['id'] = ''; $pretext_replacement['is_article_list'] = true; } // Merge pretext_replacement with pretext $pretext = array_merge($pretext, $pretext_replacement); if (is_numeric(@$pretext['id'])) { $a = safe_row('*, unix_timestamp(Posted) as uPosted, unix_timestamp(Expires) as uExpires, unix_timestamp(LastMod) as uLastMod', 'textpattern', 'ID=' . intval($pretext['id']) . ' and Status >= 4'); populateArticleData($a); } // Export required values to the global namespace foreach (array('id', 's', 'c', 'pg', 'is_article_list', 'prev_id', 'prev_title', 'next_id', 'next_title', 'css') as $key) { if (array_key_exists($key, $pretext)) { $GLOBALS[$key] = $pretext[$key]; } } if (count($this->matched_permlink) || @$mt_redirect) { $pl_index = $pretext['permlink_id']; if (!@$mt_redirect || !$this->pref('redirect_mt_style_links')) { $pl = $this->get_permlink($pretext['permlink_id']); $pl_index = @$pl['settings']['des_permlink']; } if (@$pretext['id'] && $pl_index) { if (count($this->get_permlink($pl_index)) > 0) { ob_clean(); global $siteurl; $rs = safe_row('*, ID as thisid, unix_timestamp(Posted) as posted', 'textpattern', "ID = '{$pretext['id']}'"); $host = rtrim(str_replace(rtrim(doStrip($pretext['subpath']), '/'), '', hu), '/'); $this->redirect($host . $this->_permlinkurl($rs, PERMLINKURL, $pl_index), $this->pref('permlink_redirect_http_status')); } } else { if ($url = @$pl['settings']['des_location']) { ob_clean(); $this->redirect($url, $this->pref('url_redirect_http_status')); } } } if (@$pretext['rss']) { if (@$pretext['s']) { $_POST['section'] = $pretext['s']; } if (@$pretext['c']) { $_POST['category'] = $pretext['c']; } ob_clean(); include txpath . '/publish/rss.php'; exit(rss()); } if (@$pretext['atom']) { if (@$pretext['s']) { $_POST['section'] = $pretext['s']; } if (@$pretext['c']) { $_POST['category'] = $pretext['c']; } ob_clean(); include txpath . '/publish/atom.php'; exit(atom()); } $this->debug('Pretext ' . print_r($pretext, 1)); } else { $this->debug('NO CHANGES MADE'); } // Log this page hit if (@$orginial_status == 404) { log_hit($pretext['status']); } // Start output buffering and pseudo callback to textpattern_end ob_start(array(&$this, '_textpattern_end_callback')); // TxP 4.0.5 (r2436) introduced the textpattern_end callback making the following redundant $version = array_sum(array_map(create_function('$line', 'if (preg_match(\'/^\\$' . 'LastChangedRevision: (\\w+) \\$/\', $line, $match)) return $match[1];'), @file(txpath . '/publish.php'))); if ($version >= '2436') { return; } // Remove the plugin callbacks which have already been called function filter_callbacks($c) { if ($c['event'] != 'textpattern') { return true; } if (@$c['function'][0]->plugin_name == 'gbp_permanent_links' && @$c['function'][1] == '_textpattern') { $GLOBALS['gbp_found_self'] = true; return false; } return @$GLOBALS['gbp_found_self']; } $plugin_callback = array_filter($plugin_callback, 'filter_callbacks'); unset($GLOBALS['gbp_found_self']); // Re-call textpattern textpattern(); // Call custom textpattern_end callback $this->_textpattern_end(); // textpattern() has run, kill the connection die; } }
function handle_lastmod($unix_ts = NULL, $exit = 1) { global $prefs; extract($prefs); if ($send_lastmod and $production_status == 'live') { $unix_ts = get_lastmod($unix_ts); # make sure lastmod isn't in the future $unix_ts = min($unix_ts, time()); # or too far in the past (7 days) $unix_ts = max($unix_ts, time() - 3600 * 24 * 7); $last = safe_strftime('rfc822', $unix_ts, 1); header("Last-Modified: {$last}"); header('Cache-Control: no-cache'); $hims = serverset('HTTP_IF_MODIFIED_SINCE'); if ($hims and @strtotime($hims) >= $unix_ts) { log_hit('304'); if (!$exit) { return array('304', $last); } txp_status_header('304 Not Modified'); # header('Connection: close'); header('Content-Length: 0'); # discard all output while (@ob_end_clean()) { } exit; } if (!$exit) { return array('200', $last); } } }