function logit($r = '') { global $siteurl, $id, $record_mentions; $mydomain = str_replace('www.', '', $siteurl); $out['uri'] = $_SERVER['REQUEST_URI']; $out['ref'] = str_replace("http://", "", serverset('HTTP_REFERER')); $out['ip'] = @gethostbyaddr($_SERVER['REMOTE_ADDR']); if (preg_match("/^[^\\.]*\\.?{$mydomain}/i", $out['ref'])) { $out['ref'] = ""; } if ($r == 'refer') { if (trim($out['ref']) != "") { insert_logit($out); } } else { insert_logit($out); } if ($id && $record_mentions && $out['ref']) { $thepage = getReferringPage('http://' . $out['ref']); $refpage = preg_replace("/^(www\\.)?(.*)\\/?\$/Ui", "\$2", $out['ref']); $reftitle = tweezePageTitle($thepage); $excerpt = tweezeExcerpt($thepage, $out['uri']); if ($refpage) { mentionInsert(array('id' => $id, 'refpage' => $refpage, 'reftitle' => $reftitle, 'excerpt' => $excerpt)); } } }
function logit($r = '') { global $siteurl, $prefs; $mydomain = str_replace('www.', '', preg_quote($siteurl, "/")); $out['uri'] = $_SERVER['REQUEST_URI']; $out['ref'] = clean_url(str_replace("http://", "", serverset('HTTP_REFERER'))); $host = $ip = $_SERVER['REMOTE_ADDR']; if (!empty($prefs['use_dns'])) { // A crude rDNS cache if ($h = safe_field('host', 'txp_log', "ip='" . doSlash($ip) . "' limit 1")) { $host = $h; } else { // Double-check the rDNS $host = @gethostbyaddr($_SERVER['REMOTE_ADDR']); if ($host != $ip and @gethostbyname($host) != $ip) { $host = $ip; } } } $out['ip'] = $ip; $out['host'] = $host; $out['status'] = 200; // FIXME $out['method'] = $_SERVER['REQUEST_METHOD']; if (preg_match("/^[^\\.]*\\.?{$mydomain}/i", $out['ref'])) { $out['ref'] = ""; } if ($r == 'refer') { if (trim($out['ref']) != "") { insert_logit($out); } } else { insert_logit($out); } }
/** * Generates and outputs an Atom feed. * * This function can only be called once on a page. It outputs an Atom feed * based on the requested URL parameters. Accepts HTTP GET parameters 'limit', * 'area', 'section' and 'category'. */ function atom() { global $thisarticle, $prefs; set_error_handler('feedErrorHandler'); ob_clean(); extract($prefs); $last = fetch("UNIX_TIMESTAMP(val)", 'txp_prefs', 'name', 'lastmod'); extract(doSlash(gpsa(array('limit', 'area')))); // Build filter criteria from a comma-separated list of sections // and categories. $feed_filter_limit = get_pref('feed_filter_limit', 10); $section = gps('section'); $category = gps('category'); if (!is_scalar($section) || !is_scalar($category)) { txp_die('Not Found', 404); } $section = $section ? array_slice(do_list_unique($section), 0, $feed_filter_limit) : array(); $category = $category ? array_slice(do_list_unique($category), 0, $feed_filter_limit) : array(); $st = array(); foreach ($section as $s) { $st[] = fetch_section_title($s); } $ct = array(); foreach ($category as $c) { $ct[] = fetch_category_title($c); } $sitename .= $section ? ' - ' . join(' - ', $st) : ''; $sitename .= $category ? ' - ' . join(' - ', $ct) : ''; $pub = safe_row("RealName, email", 'txp_users', "privs = 1"); // Feed header. $out[] = tag(htmlspecialchars($sitename), 'title', t_text); $out[] = tag(htmlspecialchars($site_slogan), 'subtitle', t_text); $out[] = '<link' . r_relself . ' href="' . pagelinkurl(array('atom' => 1, 'area' => $area, 'section' => $section, 'category' => $category, 'limit' => $limit)) . '" />'; $out[] = '<link' . r_relalt . t_texthtml . ' href="' . hu . '" />'; // Atom feeds with mail or domain name. $dn = explode('/', $siteurl); $mail_or_domain = $use_mail_on_feeds_id ? eE($blog_mail_uid) : $dn[0]; $out[] = tag('tag:' . $mail_or_domain . ',' . $blog_time_uid . ':' . $blog_uid . ($section ? '/' . join(',', $section) : '') . ($category ? '/' . join(',', $category) : ''), 'id'); $out[] = tag('Textpattern', 'generator', ' uri="http://textpattern.com/" version="' . $version . '"'); $out[] = tag(safe_strftime("w3cdtf", $last), 'updated'); $auth[] = tag($pub['RealName'], 'name'); $auth[] = $include_email_atom ? tag(eE($pub['email']), 'email') : ''; $auth[] = tag(hu, 'uri'); $out[] = tag(n . t . t . join(n . t . t, $auth) . n, 'author'); $out[] = callback_event('atom_head'); // Feed items. $articles = array(); $section = doSlash($section); $category = doSlash($category); if (!$area or $area == 'article') { $sfilter = !empty($section) ? "AND Section IN ('" . join("','", $section) . "')" : ''; $cfilter = !empty($category) ? "AND (Category1 IN ('" . join("','", $category) . "') OR Category2 IN ('" . join("','", $category) . "'))" : ''; $limit = $limit ? $limit : $rss_how_many; $limit = intval(min($limit, max(100, $rss_how_many))); $frs = safe_column("name", 'txp_section', "in_rss != '1'"); $query = array(); foreach ($frs as $f) { $query[] = "AND Section != '" . doSlash($f) . "'"; } $query[] = $sfilter; $query[] = $cfilter; $expired = $publish_expired_articles ? " " : " AND (" . now('expires') . " <= Expires OR Expires = " . NULLDATETIME . ") "; $rs = safe_rows_start("*,\n ID AS thisid,\n UNIX_TIMESTAMP(Posted) AS uPosted,\n UNIX_TIMESTAMP(Expires) AS uExpires,\n UNIX_TIMESTAMP(LastMod) AS uLastMod", 'textpattern', "Status = 4 AND Posted <= " . now('posted') . $expired . join(' ', $query) . "ORDER BY Posted DESC LIMIT {$limit}"); if ($rs) { while ($a = nextRow($rs)) { extract($a); populateArticleData($a); $cb = callback_event('atom_entry'); $e = array(); $a['posted'] = $uPosted; $a['expires'] = $uExpires; if ($show_comment_count_in_feed) { $count = $comments_count > 0 ? ' [' . $comments_count . ']' : ''; } else { $count = ''; } $thisauthor = get_author_name($AuthorID); $e['thisauthor'] = tag(n . t . t . t . tag(htmlspecialchars($thisauthor), 'name') . n . t . t, 'author'); $e['issued'] = tag(safe_strftime('w3cdtf', $uPosted), 'published'); $e['modified'] = tag(safe_strftime('w3cdtf', $uLastMod), 'updated'); $escaped_title = htmlspecialchars($Title); $e['title'] = tag($escaped_title . $count, 'title', t_html); $permlink = permlinkurl($a); $e['link'] = '<link' . r_relalt . t_texthtml . ' href="' . $permlink . '" />'; $e['id'] = tag('tag:' . $mail_or_domain . ',' . $feed_time . ':' . $blog_uid . '/' . $uid, 'id'); $e['category1'] = trim($Category1) ? '<category term="' . htmlspecialchars($Category1) . '" />' : ''; $e['category2'] = trim($Category2) ? '<category term="' . htmlspecialchars($Category2) . '" />' : ''; $summary = trim(replace_relative_urls(parse($thisarticle['excerpt']), $permlink)); $content = trim(replace_relative_urls(parse($thisarticle['body']), $permlink)); if ($syndicate_body_or_excerpt) { // Short feed: use body as summary if there's no excerpt. if (!trim($summary)) { $summary = $content; } $content = ''; } if (trim($content)) { $e['content'] = tag(n . escape_cdata($content) . n, 'content', t_html); } if (trim($summary)) { $e['summary'] = tag(n . escape_cdata($summary) . n, 'summary', t_html); } $articles[$ID] = tag(n . t . t . join(n . t . t, $e) . n . $cb, 'entry'); $etags[$ID] = strtoupper(dechex(crc32($articles[$ID]))); $dates[$ID] = $uLastMod; } } } elseif ($area == 'link') { $cfilter = $category ? "category in ('" . join("','", $category) . "')" : '1'; $limit = $limit ? $limit : $rss_how_many; $limit = intval(min($limit, max(100, $rss_how_many))); $rs = safe_rows_start("*", 'txp_link', "{$cfilter} ORDER BY date DESC, id DESC LIMIT {$limit}"); if ($rs) { while ($a = nextRow($rs)) { extract($a); $e['title'] = tag(htmlspecialchars($linkname), 'title', t_html); $e['content'] = tag(n . htmlspecialchars($description) . n, 'content', t_html); $url = preg_replace("/^\\/(.*)/", "https?://{$siteurl}/\$1", $url); $url = preg_replace("/&((?U).*)=/", "&\\1=", $url); $e['link'] = '<link' . r_relalt . t_texthtml . ' href="' . $url . '" />'; $e['issued'] = tag(safe_strftime('w3cdtf', strtotime($date)), 'published'); $e['modified'] = tag(gmdate('Y-m-d\\TH:i:s\\Z', strtotime($date)), 'updated'); $e['id'] = tag('tag:' . $mail_or_domain . ',' . safe_strftime('%Y-%m-%d', strtotime($date)) . ':' . $blog_uid . '/' . $id, 'id'); $articles[$id] = tag(n . t . t . join(n . t . t, $e) . n, 'entry'); $etags[$id] = strtoupper(dechex(crc32($articles[$id]))); $dates[$id] = $date; } } } if (!$articles) { if ($section) { if (safe_field("name", 'txp_section', "name IN ('" . join("','", $section) . "')") == false) { txp_die(gTxt('404_not_found'), '404'); } } elseif ($category) { switch ($area) { case 'link': if (safe_field("id", 'txp_category', "name = '{$category}' AND type = 'link'") == false) { txp_die(gTxt('404_not_found'), '404'); } break; case 'article': default: if (safe_field("id", 'txp_category', "name IN ('" . join("','", $category) . "') AND type = 'article'") == false) { txp_die(gTxt('404_not_found'), '404'); } break; } } } else { // Turn on compression if we aren't using it already. if (extension_loaded('zlib') && ini_get("zlib.output_compression") == 0 && ini_get('output_handler') != 'ob_gzhandler' && !headers_sent()) { // Make sure notices/warnings/errors don't fudge up the feed when // compression is used. $buf = ''; while ($b = @ob_get_clean()) { $buf .= $b; } @ob_start('ob_gzhandler'); echo $buf; } handle_lastmod(); $hims = serverset('HTTP_IF_MODIFIED_SINCE'); $imsd = $hims ? strtotime($hims) : 0; if (is_callable('apache_request_headers')) { $headers = apache_request_headers(); if (isset($headers["A-IM"])) { $canaim = strpos($headers["A-IM"], "feed"); } else { $canaim = false; } } else { $canaim = false; } $hinm = stripslashes(serverset('HTTP_IF_NONE_MATCH')); $cutarticles = false; if ($canaim !== false) { foreach ($articles as $id => $thing) { if (strpos($hinm, $etags[$id])) { unset($articles[$id]); $cutarticles = true; $cut_etag = true; } if ($dates[$id] < $imsd) { unset($articles[$id]); $cutarticles = true; $cut_time = true; } } } if (isset($cut_etag) && isset($cut_time)) { header("Vary: If-None-Match, If-Modified-Since"); } elseif (isset($cut_etag)) { header("Vary: If-None-Match"); } elseif (isset($cut_time)) { header("Vary: If-Modified-Since"); } $etag = @join("-", $etags); if (strstr($hinm, $etag)) { txp_status_header('304 Not Modified'); exit(0); } if ($etag) { header('ETag: "' . $etag . '"'); } if ($cutarticles) { // header("HTTP/1.1 226 IM Used"); // This should be used as opposed to 200, but Apache doesn't like it. // http://intertwingly.net/blog/2004/09/11/Vary-ETag/ says that the // status code should be 200. header("Cache-Control: no-store, im"); header("IM: feed"); } } $out = array_merge($out, $articles); header('Content-type: application/atom+xml; charset=utf-8'); return chr(60) . '?xml version="1.0" encoding="UTF-8"?' . chr(62) . n . '<feed xml:lang="' . txpspecialchars($language) . '" xmlns="http://www.w3.org/2005/Atom">' . join(n, $out) . '</feed>'; }
function saveComment() { global $siteurl, $comments_moderate, $comments_sendmail, $txpcfg, $comments_disallow_images, $prefs; $ref = serverset('HTTP_REFERRER'); $in = psa(array('parentid', 'name', 'email', 'web', 'message', 'backpage', 'nonce', 'remember')); extract($in); if (!checkCommentsAllowed($parentid)) { exit(graf(gTxt('comments_closed'))); } if ($prefs['comments_require_name']) { if (!trim($name)) { exit(graf(gTxt('comment_name_required')) . graf('<a href="" onClick="history.go(-1)">' . gTxt('back') . '</a>')); } } if ($prefs['comments_require_email']) { if (!trim($email)) { exit(graf(gTxt('comment_email_required')) . graf('<a href="" onClick="history.go(-1)">' . gTxt('back') . '</a>')); } } if (!trim($message)) { exit(graf(gTxt('comment_required')) . graf('<a href="" onClick="history.go(-1)">' . gTxt('back') . '</a>')); } $ip = serverset('REMOTE_ADDR'); $message = trim($message); $blacklisted = is_blacklisted($ip); $name = doSlash(strip_tags(deEntBrackets($name))); $web = doSlash(clean_url(strip_tags(deEntBrackets($web)))); $email = doSlash(clean_url(strip_tags(deEntBrackets($email)))); $message2db = doSlash(markup_comment($message)); $isdup = safe_row("message,name", "txp_discuss", "name='{$name}' and message='{$message2db}' and ip='{$ip}'"); if (checkBan($ip)) { if ($blacklisted == false) { if (!$isdup) { if (checkNonce($nonce)) { $visible = $comments_moderate ? 0 : 1; $rs = safe_insert("txp_discuss", "parentid = '{$parentid}',\n\t\t\t\t\t\t\t name\t\t = '{$name}',\n\t\t\t\t\t\t\t email\t = '{$email}',\n\t\t\t\t\t\t\t web\t\t = '{$web}',\n\t\t\t\t\t\t\t ip\t\t = '{$ip}',\n\t\t\t\t\t\t\t message = '{$message2db}',\n\t\t\t\t\t\t\t visible = {$visible},\n\t\t\t\t\t\t\t posted\t = now()"); if ($rs) { safe_update("txp_discuss_nonce", "used='1'", "nonce='{$nonce}'"); if ($prefs['comment_means_site_updated']) { safe_update("txp_prefs", "val=now()", "name='lastmod'"); } if ($comments_sendmail) { mail_comment($message, $name, $email, $web, $parentid); } $updated = update_comments_count($parentid); ob_start(); $backpage = substr($backpage, 0, $prefs['max_url_len']); $backpage = preg_replace("/[\n\r#].*\$/s", '', $backpage); $backpage .= (strstr($backpage, '?') ? '&' : '?') . 'commented=1'; if ($comments_moderate) { header('Location: ' . $backpage . '#txpCommentInputForm'); } else { header('Location: ' . $backpage . '#c' . sprintf("%06s", $rs)); } } } // end check nonce } // end check dup } else { exit(gTxt('your_ip_is_blacklisted_by' . ' ' . $blacklisted)); } // end check blacklist } else { exit(gTxt('you_have_been_banned')); } // end check site ban }
function bombShelter() { global $prefs; $in = serverset('REQUEST_URI'); if (!empty($prefs['max_url_len']) and strlen($in) > $prefs['max_url_len']) { exit('Nice try.'); } }
function rss() { global $prefs, $txpac; extract($prefs); ob_start(); extract(doSlash(gpsa(array('category', 'section', 'limit', 'area')))); // send a 304 if nothing has changed since the last visit $last = fetch('unix_timestamp(val)', 'txp_prefs', 'name', 'lastmod'); $last = gmdate("D, d M Y H:i:s \\G\\M\\T", $last); header("Last-Modified: {$last}"); $hims = serverset('HTTP_IF_MODIFIED_SINCE'); if ($hims == $last) { header("HTTP/1.1 304 Not Modified"); exit; } $area = gps('area'); $sitename .= $section ? ' - ' . $section : ''; $sitename .= $category ? ' - ' . $category : ''; $out[] = tag(doSpecial($sitename), 'title'); $out[] = tag('http://' . $siteurl . $path_from_root, 'link'); $out[] = tag(doSpecial($site_slogan), 'description'); if (!$area or $area == 'article') { $sfilter = $section ? "and Section = '" . $section . "'" : ''; $cfilter = $category ? "and (Category1='" . $category . "' or Category2='" . $category . "')" : ''; $limit = $limit ? $limit : '5'; $frs = safe_column("name", "txp_section", "in_rss != '1'"); if ($frs) { foreach ($frs as $f) { $query[] = "and Section != '" . $f . "'"; } } $query[] = $sfilter; $query[] = $cfilter; $rs = safe_rows("*", "textpattern", "Status = 4 " . join(' ', $query) . "and Posted < now() order by Posted desc limit {$limit}"); if ($rs) { foreach ($rs as $a) { extract($a); $Body = !$txpac['syndicate_body_or_excerpt'] ? $Body_html : $Excerpt; $Body = !trim($Body) ? $Body_html : $Body; $Body = str_replace('href="/', 'href="http://' . $siteurl . '/', $Body); $Body = htmlspecialchars($Body, ENT_NOQUOTES); $link = $url_mode == 0 ? 'http://' . $siteurl . $path_from_root . 'index.php?id=' . $ID : 'http://' . $siteurl . $path_from_root . $Section . '/' . $ID . '/'; if ($txpac['show_comment_count_in_feed']) { $dc = getCount('txp_discuss', "parentid={$ID} and visible=1"); $count = $dc > 0 ? ' [' . $dc . ']' : ''; } else { $count = ''; } $Title = doSpecial($Title) . $count; $item = tag(strip_tags($Title), 'title') . n . tag($Body, 'description') . n . tag($link, 'link'); $out[] = tag($item, 'item'); } header("Content-Type: text/xml"); return '<rss version="0.92">' . tag(join(n, $out), 'channel') . '</rss>'; } } elseif ($area == 'link') { $cfilter = $category ? "category='{$category}'" : '1'; $limit = $limit ? $limit : 15; $rs = safe_rows("*", "txp_link", "{$cfilter} order by date desc limit {$limit}"); if ($rs) { foreach ($rs as $a) { extract($a); $item = tag(doSpecial($linkname), 'title') . n . tag(doSpecial($description), 'description') . n . tag($url, 'link'); $out[] = tag($item, 'item'); } header("Content-Type: text/xml"); return '<rss version="0.92">' . tag(join(n, $out), 'channel') . '</rss>'; } } return 'no articles recorded yet'; }
function atom() { global $thisarticle; extract($GLOBALS['prefs']); define("t_texthtml", ' type="text/html"'); define("t_text", ' type="text"'); define("t_html", ' type="html"'); define("t_xhtml", ' type="xhtml"'); define('t_appxhtml', ' type="xhtml"'); define("r_relalt", ' rel="alternate"'); define("r_relself", ' rel="self"'); $area = doSlash(gps('area')); extract(doSlash(gpsa(array('category', 'section', 'limit')))); $last = fetch('unix_timestamp(val)', 'txp_prefs', 'name', 'lastmod'); $sitename .= $section ? ' - ' . $section : ''; $sitename .= $category ? ' - ' . $category : ''; $pub = safe_row("RealName, email", "txp_users", "privs=1"); $out[] = tag(escape_output($sitename), 'title', t_text); $out[] = tag(escape_output($site_slogan), 'subtitle', t_text); $out[] = '<link' . r_relself . ' href="' . pagelinkurl(array('atom' => 1, 'area' => $area, 'section' => $section, 'category' => $category, 'limit' => $limit)) . '" />'; $out[] = '<link' . r_relalt . t_texthtml . ' href="' . hu . '" />'; $articles = array(); //Atom feeds with mail or domain name $dn = explode('/', $siteurl); $mail_or_domain = $use_mail_on_feeds_id ? eE($blog_mail_uid) : $dn[0]; $out[] = tag('tag:' . $mail_or_domain . ',' . $blog_time_uid . ':' . $blog_uid . ($section ? '/' . $section : '') . ($category ? '/' . $category : ''), 'id'); $out[] = tag('Textpattern', 'generator', ' uri="http://textpattern.com/" version="' . $version . '"'); $out[] = tag(safe_strftime("w3cdtf", $last), 'updated'); $auth[] = tag($pub['RealName'], 'name'); $auth[] = $include_email_atom ? tag(eE($pub['email']), 'email') : ''; $auth[] = tag(hu, 'uri'); $out[] = tag(n . t . t . join(n . t . t, $auth) . n, 'author'); if (!$area or $area == 'article') { $sfilter = $section ? "and Section = '" . $section . "'" : ''; $cfilter = $category ? "and (Category1='" . $category . "' or Category2='" . $category . "')" : ''; $limit = $limit ? $limit : $rss_how_many; $limit = intval(min($limit, max(100, $rss_how_many))); $frs = safe_column("name", "txp_section", "in_rss != '1'"); $query = array(); foreach ($frs as $f) { $query[] = "and Section != '" . doSlash($f) . "'"; } $query[] = $sfilter; $query[] = $cfilter; $rs = safe_rows_start("*, \n\t\t\t\tID as thisid, \n\t\t\t\tunix_timestamp(Posted) as uPosted,\n\t\t\t\tunix_timestamp(LastMod) as uLastMod", "textpattern", "Status=4 and Posted <= now() " . join(' ', $query) . "order by Posted desc limit {$limit}"); if ($rs) { while ($a = nextRow($rs)) { extract($a); populateArticleData($a); $cb = callback_event('atom_entry'); $e = array(); $a['posted'] = $uPosted; if ($show_comment_count_in_feed) { $count = $comments_count > 0 ? ' [' . $comments_count . ']' : ''; } else { $count = ''; } $thisauthor = get_author_name($AuthorID); $e['thisauthor'] = tag(n . t . t . t . tag(htmlspecialchars($thisauthor), 'name') . n . t . t, 'author'); $e['issued'] = tag(safe_strftime('w3cdtf', $uPosted), 'published'); $e['modified'] = tag(safe_strftime('w3cdtf', $uLastMod), 'updated'); $escaped_title = escape_output($Title); $e['title'] = tag($escaped_title . $count, 'title', t_html); $permlink = permlinkurl($a); $e['link'] = '<link' . r_relalt . t_texthtml . ' href="' . $permlink . '" />'; $e['id'] = tag('tag:' . $mail_or_domain . ',' . $feed_time . ':' . $blog_uid . '/' . $uid, 'id'); $e['category1'] = trim($Category1) ? '<category term="' . htmlspecialchars($Category1) . '" />' : ''; $e['category2'] = trim($Category2) ? '<category term="' . htmlspecialchars($Category2) . '" />' : ''; $summary = trim(replace_relative_urls(parse($thisarticle['excerpt']), $permlink)); $content = trim(replace_relative_urls(parse($thisarticle['body']), $permlink)); if ($syndicate_body_or_excerpt) { # short feed: use body as summary if there's no excerpt if (!trim($summary)) { $summary = $content; } $content = ''; } if (trim($content)) { $e['content'] = tag(n . escape_cdata($content) . n, 'content', t_html); } if (trim($summary)) { $e['summary'] = tag(n . escape_cdata($summary) . n, 'summary', t_html); } $articles[$ID] = tag(n . t . t . join(n . t . t, $e) . n . $cb, 'entry'); $etags[$ID] = strtoupper(dechex(crc32($articles[$ID]))); $dates[$ID] = $uLastMod; } } } elseif ($area == 'link') { $cfilter = $category ? "category='" . $category . "'" : '1'; $limit = $limit ? $limit : $rss_how_many; $limit = intval(min($limit, max(100, $rss_how_many))); $rs = safe_rows_start("*", "txp_link", "{$cfilter} order by date desc, id desc limit {$limit}"); if ($rs) { while ($a = nextRow($rs)) { extract($a); $e['title'] = tag(htmlspecialchars($linkname), 'title', t_html); $e['content'] = tag(n . htmlspecialchars($description) . n, 'content', t_html); $url = preg_replace("/^\\/(.*)/", "https?://{$siteurl}/\$1", $url); $url = preg_replace("/&((?U).*)=/", "&\\1=", $url); $e['link'] = '<link' . r_relalt . t_texthtml . ' href="' . $url . '" />'; $e['issued'] = tag(safe_strftime('w3cdtf', strtotime($date)), 'published'); $e['modified'] = tag(gmdate('Y-m-d\\TH:i:s\\Z', strtotime($date)), 'updated'); $e['id'] = tag('tag:' . $mail_or_domain . ',' . $feed_time . ':' . $id, 'id'); $articles[$id] = tag(n . t . t . join(n . t . t, $e) . n, 'entry'); $etags[$id] = strtoupper(dechex(crc32($articles[$id]))); $dates[$id] = $date; } } } if (!empty($articles)) { //turn on compression if we aren't using it already if (extension_loaded('zlib') && ini_get("zlib.output_compression") == 0 && ini_get('output_handler') != 'ob_gzhandler' && !headers_sent()) { @ob_start("ob_gzhandler"); } handle_lastmod(); $hims = serverset('HTTP_IF_MODIFIED_SINCE'); $imsd = $hims ? strtotime($hims) : 0; if ($imsd >= $last) { txp_status_header("304 Not Modified"); exit; } header("Last-Modified: " . gmdate('D, d M Y H:i:s \\G\\M\\T', $last)); if (is_callable('apache_request_headers')) { $headers = apache_request_headers(); if (isset($headers["A-IM"])) { $canaim = strpos($headers["A-IM"], "feed"); } else { $canaim = false; } } else { $canaim = false; } $hinm = stripslashes(serverset('HTTP_IF_NONE_MATCH')); $cutarticles = false; if ($canaim !== false) { foreach ($articles as $id => $thing) { if (strpos($hinm, $etags[$id])) { unset($articles[$id]); $cutarticles = true; $cut_etag = true; } if ($dates[$id] < $imsd) { unset($articles[$id]); $cutarticles = true; $cut_time = true; } } } if (isset($cut_etag) && isset($cut_time)) { header("Vary: If-None-Match, If-Modified-Since"); } else { if (isset($cut_etag)) { header("Vary: If-None-Match"); } else { if (isset($cut_time)) { header("Vary: If-Modified-Since"); } } } $etag = @join("-", $etags); if (strstr($hinm, $etag)) { header("HTTP/1.1 304 Not Modified"); exit; } if ($etag) { header('ETag: "' . $etag . '"'); } if ($cutarticles) { //header("HTTP/1.1 226 IM Used"); //This should be used as opposed to 200, but Apache doesn't like it. //http://intertwingly.net/blog/2004/09/11/Vary-ETag/ says that the status code should be 200. header("Cache-Control: no-store, im"); header("IM: feed"); } $out = array_merge($out, $articles); header('Content-type: application/atom+xml; charset=utf-8'); return chr(60) . '?xml version="1.0" encoding="UTF-8"?' . chr(62) . n . '<feed xml:lang="' . $language . '" xmlns="http://www.w3.org/2005/Atom">' . join(n, $out) . '</feed>'; } }
function rss() { global $prefs, $thisarticle; set_error_handler('feedErrorHandler'); ob_clean(); extract($prefs); extract(doSlash(gpsa(array('limit', 'area')))); // build filter criteria from a comma-separated list of sections and categories $feed_filter_limit = get_pref('feed_filter_limit', 10); $section = gps('section'); $category = gps('category'); if (!is_scalar($section) || !is_scalar($category)) { txp_die('Not Found', 404); } $section = $section ? array_slice(array_unique(do_list($section)), 0, $feed_filter_limit) : array(); $category = $category ? array_slice(array_unique(do_list($category)), 0, $feed_filter_limit) : array(); $st = array(); foreach ($section as $s) { $st[] = fetch_section_title($s); } $ct = array(); foreach ($category as $c) { $ct[] = fetch_category_title($c); } $sitename .= $section ? ' - ' . join(' - ', $st) : ''; $sitename .= $category ? ' - ' . join(' - ', $ct) : ''; $dn = explode('/', $siteurl); $mail_or_domain = $use_mail_on_feeds_id ? eE($blog_mail_uid) : $dn[0]; // feed header $out[] = tag('http://textpattern.com/?v=' . $version, 'generator'); $out[] = tag(doSpecial($sitename), 'title'); $out[] = tag(hu, 'link'); $out[] = '<atom:link href="' . pagelinkurl(array('rss' => 1, 'area' => $area, 'section' => $section, 'category' => $category, 'limit' => $limit)) . '" rel="self" type="application/rss+xml" />'; $out[] = tag(doSpecial($site_slogan), 'description'); $last = fetch('unix_timestamp(val)', 'txp_prefs', 'name', 'lastmod'); $out[] = tag(safe_strftime('rfc822', $last), 'pubDate'); $out[] = callback_event('rss_head'); // feed items $articles = array(); $section = doSlash($section); $category = doSlash($category); if (!$area or $area == 'article') { $sfilter = !empty($section) ? "and Section in ('" . join("','", $section) . "')" : ''; $cfilter = !empty($category) ? "and (Category1 in ('" . join("','", $category) . "') or Category2 in ('" . join("','", $category) . "'))" : ''; $limit = $limit ? $limit : $rss_how_many; $limit = intval(min($limit, max(100, $rss_how_many))); $frs = safe_column("name", "txp_section", "in_rss != '1'"); if ($frs) { foreach ($frs as $f) { $query[] = "and Section != '" . doSlash($f) . "'"; } } $query[] = $sfilter; $query[] = $cfilter; $expired = $publish_expired_articles ? '' : ' and (now() <= Expires or Expires = ' . NULLDATETIME . ') '; $rs = safe_rows_start("*, unix_timestamp(Posted) as uPosted, unix_timestamp(LastMod) as uLastMod, unix_timestamp(Expires) as uExpires, ID as thisid", "textpattern", "Status = 4 " . join(' ', $query) . "and Posted < now()" . $expired . "order by Posted desc limit {$limit}"); if ($rs) { while ($a = nextRow($rs)) { extract($a); populateArticleData($a); $cb = callback_event('rss_entry'); $a['posted'] = $uPosted; $permlink = permlinkurl($a); $summary = trim(replace_relative_urls(parse($thisarticle['excerpt']), $permlink)); $content = trim(replace_relative_urls(parse($thisarticle['body']), $permlink)); if ($syndicate_body_or_excerpt) { # short feed: use body as summary if there's no excerpt if (!trim($summary)) { $summary = $content; } $content = ''; } if ($show_comment_count_in_feed) { $count = $comments_count > 0 ? ' [' . $comments_count . ']' : ''; } else { $count = ''; } $Title = escape_title(strip_tags($Title)) . $count; $thisauthor = get_author_name($AuthorID); $item = tag($Title, 'title') . n . (trim($summary) ? tag(n . escape_cdata($summary) . n, 'description') . n : '') . (trim($content) ? tag(n . escape_cdata($content) . n, 'content:encoded') . n : '') . tag($permlink, 'link') . n . tag(safe_strftime('rfc822', $a['posted']), 'pubDate') . n . tag(htmlspecialchars($thisauthor), 'dc:creator') . n . tag('tag:' . $mail_or_domain . ',' . $feed_time . ':' . $blog_uid . '/' . $uid, 'guid', ' isPermaLink="false"') . n . $cb; $articles[$ID] = tag($item, 'item'); $etags[$ID] = strtoupper(dechex(crc32($articles[$ID]))); $dates[$ID] = $uPosted; } } } elseif ($area == 'link') { $cfilter = $category ? "category in ('" . join("','", $category) . "')" : '1'; $limit = $limit ? $limit : $rss_how_many; $limit = intval(min($limit, max(100, $rss_how_many))); $rs = safe_rows_start("*, unix_timestamp(date) as uDate", "txp_link", "{$cfilter} order by date desc limit {$limit}"); if ($rs) { while ($a = nextRow($rs)) { extract($a); $item = tag(doSpecial($linkname), 'title') . n . tag(doSpecial($description), 'description') . n . tag(doSpecial($url), 'link') . n . tag(safe_strftime('rfc822', $uDate), 'pubDate'); $articles[$id] = tag($item, 'item'); $etags[$id] = strtoupper(dechex(crc32($articles[$id]))); $dates[$id] = $date; } } } if (!$articles) { if ($section) { if (safe_field('name', 'txp_section', "name in ('" . join("','", $section) . "')") == false) { txp_die(gTxt('404_not_found'), '404'); } } elseif ($category) { switch ($area) { case 'link': if (safe_field('id', 'txp_category', "name = '{$category}' and type = 'link'") == false) { txp_die(gTxt('404_not_found'), '404'); } break; case 'article': default: if (safe_field('id', 'txp_category', "name in ('" . join("','", $category) . "') and type = 'article'") == false) { txp_die(gTxt('404_not_found'), '404'); } break; } } } else { //turn on compression if we aren't using it already if (extension_loaded('zlib') && ini_get("zlib.output_compression") == 0 && ini_get('output_handler') != 'ob_gzhandler' && !headers_sent()) { // make sure notices/warnings/errors don't fudge up the feed // when compression is used $buf = ''; while ($b = @ob_get_clean()) { $buf .= $b; } @ob_start('ob_gzhandler'); echo $buf; } handle_lastmod(); $hims = serverset('HTTP_IF_MODIFIED_SINCE'); $imsd = $hims ? strtotime($hims) : 0; if (is_callable('apache_request_headers')) { $headers = apache_request_headers(); if (isset($headers["A-IM"])) { $canaim = strpos($headers["A-IM"], "feed"); } else { $canaim = false; } } else { $canaim = false; } $hinm = stripslashes(serverset('HTTP_IF_NONE_MATCH')); $cutarticles = false; if ($canaim !== false) { foreach ($articles as $id => $thing) { if (strpos($hinm, $etags[$id]) !== false) { unset($articles[$id]); $cutarticles = true; $cut_etag = true; } if ($dates[$id] < $imsd) { unset($articles[$id]); $cutarticles = true; $cut_time = true; } } } if (isset($cut_etag) && isset($cut_time)) { header("Vary: If-None-Match, If-Modified-Since"); } else { if (isset($cut_etag)) { header("Vary: If-None-Match"); } else { if (isset($cut_time)) { header("Vary: If-Modified-Since"); } } } $etag = @join("-", $etags); if (strstr($hinm, $etag)) { txp_status_header('304 Not Modified'); exit(0); } if ($cutarticles) { //header("HTTP/1.1 226 IM Used"); //This should be used as opposed to 200, but Apache doesn't like it. //http://intertwingly.net/blog/2004/09/11/Vary-ETag/ says that the status code should be 200. header("Cache-Control: no-store, im"); header("IM: feed"); } } $out = array_merge($out, $articles); header("Content-Type: application/rss+xml; charset=utf-8"); if (isset($etag)) { header('ETag: "' . $etag . '"'); } return '<?xml version="1.0" encoding="utf-8"?>' . n . '<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">' . n . tag(join(n, $out), 'channel') . n . '</rss>'; }
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'); } $name = doSlash(strip_tags(deEntBrackets($name))); $web = doSlash(clean_url(strip_tags(deEntBrackets($web)))); $email = doSlash(clean_url(strip_tags(deEntBrackets($email)))); $message = trim($message); $message2db = doSlash(markup_comment($message)); $isdup = safe_row("message,name", "txp_discuss", "name='{$name}' and message='{$message2db}' and ip='{$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) { $rs = safe_insert("txp_discuss", "parentid = '" . doSlash($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 = '{$ip}',\n\t\t\t\t\t message = '{$message2db}',\n\t\t\t\t\t visible = {$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']) { safe_update("txp_prefs", "val=now()", "name='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 .= (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)); } if ($prefs['logging'] == 'refer') { logit('refer'); } elseif ($prefs['logging'] == 'all') { logit(); } $evaluator->write_trace(); exit; } } } // Force another Preview $_POST['preview'] = RELOAD; //$evaluator->write_trace(); }
function bombShelter() { $in = serverset('REQUEST_URI'); if (strlen($in) > 200) { exit('Nice try.'); } }
function render_feed($rs, $area, $type, $feedtitle, $atom_self_ref, $atom_id_ext) { global $prefs, $thisarticle; extract($prefs); set_error_handler('tagErrorHandler'); $atom = $type == 'atom'; if ($atom) { define("t_texthtml", ' type="text/html"'); define("t_text", ' type="text"'); define("t_html", ' type="html"'); define("t_xhtml", ' type="xhtml"'); define('t_appxhtml', ' type="xhtml"'); define("r_relalt", ' rel="alternate"'); define("r_relself", ' rel="self"'); } else { define("t_texthtml", ''); define("t_text", ''); define("t_html", ''); define("t_xhtml", ''); define('t_appxhtml', ''); define("r_relalt", ''); define("r_relself", ''); } $dn = explode('/', $siteurl); $mail_or_domain = $use_mail_on_feeds_id ? eE($blog_mail_uid) : $dn[0]; $last = fetch('unix_timestamp(val)', 'txp_prefs', 'name', 'lastmod'); if ($atom) { $out[] = tag('Textpattern', 'generator', ' uri="http://textpattern.com/" version="' . $version . '"'); $out[] = tag(htmlspecialchars($feedtitle), 'title', t_text); $out[] = tag(htmlspecialchars($site_slogan), 'subtitle', t_text); $out[] = tag(safe_strftime("w3cdtf", $last), 'updated'); $out[] = '<link' . r_relself . ' href="' . $atom_self_ref . '" />'; $out[] = '<link' . r_relalt . t_texthtml . ' href="' . hu . '" />'; //Atom feeds with mail or domain name $out[] = tag('tag:' . $mail_or_domain . ',' . $blog_time_uid . ':' . $blog_uid . $atom_id_ext, 'id'); $pub = safe_row("RealName, email", "txp_users", "privs=1"); $auth[] = tag($pub['RealName'], 'name'); $auth[] = $include_email_atom ? tag(eE($pub['email']), 'email') : ''; $auth[] = tag(hu, 'uri'); $out[] = tag(n . t . t . join(n . t . t, $auth) . n, 'author'); } else { $out[] = tag('http://textpattern.com/?v=' . $version, 'generator'); $out[] = tag(doSpecial($feedtitle), 'title'); $out[] = tag(doSpecial($site_slogan), 'description'); $out[] = tag(safe_strftime('rfc822', $last), 'pubDate'); $out[] = tag(hu, 'link'); $out[] = '<atom:link href="' . $atom_self_ref . '" rel="self" type="application/rss+xml" />'; } $out[] = callback_event($atom ? 'atom_head' : 'rss_head'); $articles = array(); if (!$area or $area == 'article') { if ($rs) { while ($a = nextRow($rs)) { extract($a); populateArticleData($a); $cb = callback_event($atom ? 'atom_entry' : 'rss_entry'); $e = array(); $thisauthor = doSpecial(get_author_name($AuthorID)); $thisauthor = tag($thisauthor, $atom ? 'name' : 'dc:creator'); if ($atom) { $thisauthor = tag(n . t . t . t . $thisauthor . n . t . t, 'author'); } $e['thisauthor'] = $thisauthor; if ($atom) { $e['issued'] = tag(safe_strftime('w3cdtf', $uPosted), 'published'); } else { $e['issued'] = tag(safe_strftime('rfc822', $uPosted), 'pubDate'); } if ($atom) { $e['modified'] = tag(safe_strftime('w3cdtf', $uLastMod), 'updated'); $e['category1'] = trim($Category1) ? '<category term="' . doSpecial($Category1) . '" />' : ''; $e['category2'] = trim($Category2) ? '<category term="' . doSpecial($Category2) . '" />' : ''; } $count = ''; if ($show_comment_count_in_feed && $comments_count > 0) { $count = ' [' . $comments_count . ']'; } $escaped_title = $atom ? htmlspecialchars($Title) : htmlspecialchars(strip_tags($Title)); $e['title'] = tag($escaped_title . $count, 'title', t_html); $a['posted'] = $uPosted; $permlink = permlinkurl($a); if ($atom) { $e['link'] = '<link' . r_relalt . t_texthtml . ' href="' . $permlink . '" />'; } else { $e['link'] = tag($permlink, 'link'); } $e['id'] = tag('tag:' . $mail_or_domain . ',' . $feed_time . ':' . $blog_uid . '/' . $uid, $atom ? 'id' : 'guid', $atom ? '' : ' isPermaLink="false"'); $summary = trim(replace_relative_urls(parse($thisarticle['excerpt']), $permlink)); $content = trim(replace_relative_urls(parse($thisarticle['body']), $permlink)); if ($syndicate_body_or_excerpt) { # short feed: use body as summary if there's no excerpt if (!trim($summary)) { $summary = $content; } $content = ''; } if (trim($summary)) { $e['summary'] = tag(n . escape_cdata($summary) . n, $atom ? 'summary' : 'description', t_html); } if (trim($content)) { $e['content'] = tag(n . escape_cdata($content) . n, $atom ? 'content' : 'content:encoded', t_html); } $articles[$ID] = tag(n . t . t . join(n . t . t, $e) . n . $cb, $atom ? 'entry' : 'item'); $etags[$ID] = strtoupper(dechex(crc32($articles[$ID]))); $dates[$ID] = $atom ? $uLastMod : $uPosted; } } } elseif ($area == 'link') { if ($rs) { while ($a = nextRow($rs)) { extract($a); $e['title'] = tag(doSpecial($linkname), 'title', t_html); if ($atom) { $e['content'] = tag(n . doSpecial($description) . n, 'content', t_html); $url = preg_replace("/^\\/(.*)/", "https?://{$siteurl}/\$1", $url); $url = preg_replace("/&((?U).*)=/", "&\\1=", $url); $e['link'] = '<link' . r_relalt . t_texthtml . ' href="' . $url . '" />'; $e['issued'] = tag(safe_strftime('w3cdtf', strtotime($date)), 'published'); $e['modified'] = tag(gmdate('Y-m-d\\TH:i:s\\Z', strtotime($date)), 'updated'); $e['id'] = tag('tag:' . $mail_or_domain . ',' . safe_strftime('%Y-%m-%d', strtotime($date)) . ':' . $blog_uid . '/' . $id, 'id'); } else { $e['content'] = tag(doSpecial($description), 'description'); $e['link'] = tag(doSpecial($url), 'link'); $e['issued'] = tag(safe_strftime('rfc822', $uDate), 'pubDate'); } $articles[$id] = tag(n . t . t . join(n . t . t, $e) . n, $atom ? 'entry' : 'item'); $etags[$id] = strtoupper(dechex(crc32($articles[$id]))); $dates[$id] = $date; } } } if (!$articles) { if ($section) { if (safe_field('name', 'txp_section', "name = '{$section}'") == false) { txp_die(gTxt('404_not_found'), '404'); } } elseif ($category) { switch ($area) { case 'link': if (safe_field('id', 'txp_category', "name = '{$category}' and type = 'link'") == false) { txp_die(gTxt('404_not_found'), '404'); } break; case 'article': default: if (safe_field('id', 'txp_category', "name = '{$category}' and type = 'article'") == false) { txp_die(gTxt('404_not_found'), '404'); } break; } } } else { //turn on compression if we aren't using it already if (extension_loaded('zlib') && ini_get("zlib.output_compression") == 0 && ini_get('output_handler') != 'ob_gzhandler' && !headers_sent()) { // make sure notices/warnings/errors don't // fudge up the feed when compression is used $buf = ''; while ($b = @ob_get_clean()) { $buf .= $b; } @ob_start('ob_gzhandler'); echo $buf; } handle_lastmod(); $hims = serverset('HTTP_IF_MODIFIED_SINCE'); $imsd = $hims ? strtotime($hims) : 0; if (is_callable('apache_request_headers')) { $headers = apache_request_headers(); if (isset($headers["A-IM"])) { $canaim = strpos($headers["A-IM"], "feed"); } else { $canaim = false; } } else { $canaim = false; } $hinm = stripslashes(serverset('HTTP_IF_NONE_MATCH')); $cutarticles = false; if ($canaim !== false) { foreach ($articles as $id => $thing) { if (strpos($hinm, $etags[$id]) !== false) { unset($articles[$id]); $cutarticles = true; $cut_etag = true; } if ($dates[$id] < $imsd) { unset($articles[$id]); $cutarticles = true; $cut_time = true; } } } if (isset($cut_etag) && isset($cut_time)) { header("Vary: If-None-Match, If-Modified-Since"); } else { if (isset($cut_etag)) { header("Vary: If-None-Match"); } else { if (isset($cut_time)) { header("Vary: If-Modified-Since"); } } } $etag = @join("-", $etags); if (strstr($hinm, $etag)) { txp_status_header('304 Not Modified'); exit(0); } if ($etag) { header('ETag: "' . $etag . '"'); } if ($cutarticles) { //header("HTTP/1.1 226 IM Used"); //This should be used as opposed to 200, but Apache doesn't like it. //http://intertwingly.net/blog/2004/09/11/Vary-ETag/ says that the status code should be 200. header("Cache-Control: no-store, im"); header("IM: feed"); } } $out = array_merge($out, $articles); header('Content-type: application/' . ($atom ? 'atom' : 'rss') . '+xml; charset=utf-8'); if ($atom) { return chr(60) . '?xml version="1.0" encoding="UTF-8"?' . chr(62) . n . '<feed xml:lang="' . $language . '" xmlns="http://www.w3.org/2005/Atom">' . n . join(n, $out) . '</feed>'; } else { return '<?xml version="1.0" encoding="utf-8"?>' . n . '<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">' . n . tag(join(n, $out), 'channel') . n . '</rss>'; } }
function rss() { global $prefs, $thisarticle; extract($prefs); extract(doSlash(gpsa(array('category', 'section', 'limit', 'area')))); $area = gps('area'); $sitename .= $section ? ' - ' . $section : ''; $sitename .= $category ? ' - ' . $category : ''; $dn = explode('/', $siteurl); $mail_or_domain = $use_mail_on_feeds_id ? eE($blog_mail_uid) : $dn[0]; $out[] = tag('http://textpattern.com/?v=' . $version, 'generator'); $out[] = tag(doSpecial($sitename), 'title'); $out[] = tag(hu, 'link'); $out[] = tag(doSpecial($site_slogan), 'description'); $last = fetch('unix_timestamp(val)', 'txp_prefs', 'name', 'lastmod'); $out[] = tag(safe_strftime('rfc822', $last), 'pubDate'); $articles = array(); if (!$area or $area == 'article') { $sfilter = $section ? "and Section = '" . $section . "'" : ''; $cfilter = $category ? "and (Category1='" . $category . "' or Category2='" . $category . "')" : ''; $limit = $limit ? $limit : $rss_how_many; $limit = intval(min($limit, max(100, $rss_how_many))); $frs = safe_column("name", "txp_section", "in_rss != '1'"); if ($frs) { foreach ($frs as $f) { $query[] = "and Section != '" . doSlash($f) . "'"; } } $query[] = $sfilter; $query[] = $cfilter; $rs = safe_rows_start("*, unix_timestamp(Posted) as uPosted, ID as thisid", "textpattern", "Status = 4 " . join(' ', $query) . "and Posted < now() order by Posted desc limit {$limit}"); if ($rs) { while ($a = nextRow($rs)) { extract($a); populateArticleData($a); $cb = callback_event('rss_entry'); $a['posted'] = $uPosted; $permlink = permlinkurl($a); $summary = trim(replace_relative_urls(parse($thisarticle['excerpt']), $permlink)); $content = trim(replace_relative_urls(parse($thisarticle['body']), $permlink)); if ($syndicate_body_or_excerpt) { # short feed: use body as summary if there's no excerpt if (!trim($summary)) { $summary = $content; } $content = ''; } if ($show_comment_count_in_feed) { $count = $comments_count > 0 ? ' [' . $comments_count . ']' : ''; } else { $count = ''; } $Title = escape_output(strip_tags($Title)) . $count; $thisauthor = get_author_name($AuthorID); $item = tag($Title, 'title') . n . (trim($summary) ? tag(n . escape_cdata($summary) . n, 'description') . n : '') . (trim($content) ? tag(n . escape_cdata($content) . n, 'content:encoded') . n : '') . tag($permlink, 'link') . n . tag(safe_strftime('rfc822', $a['posted']), 'pubDate') . n . tag(htmlspecialchars($thisauthor), 'dc:creator') . n . tag('tag:' . $mail_or_domain . ',' . $feed_time . ':' . $blog_uid . '/' . $uid, 'guid', ' isPermaLink="false"') . n . $cb; $articles[$ID] = tag($item, 'item'); $etags[$ID] = strtoupper(dechex(crc32($articles[$ID]))); $dates[$ID] = $uPosted; } } } elseif ($area == 'link') { $cfilter = $category ? "category='{$category}'" : '1'; $limit = $limit ? $limit : $rss_how_many; $limit = intval(min($limit, max(100, $rss_how_many))); $rs = safe_rows_start("*, unix_timestamp(date) as uDate", "txp_link", "{$cfilter} order by date desc limit {$limit}"); if ($rs) { while ($a = nextRow($rs)) { extract($a); $item = tag(doSpecial($linkname), 'title') . n . tag(doSpecial($description), 'description') . n . tag(doSpecial($url), 'link') . n . tag(safe_strftime('rfc822', $uDate), 'pubDate'); $articles[$id] = tag($item, 'item'); $etags[$id] = strtoupper(dechex(crc32($articles[$id]))); $dates[$id] = $date; } } } //turn on compression if we aren't using it already if (extension_loaded('zlib') && ini_get("zlib.output_compression") == 0 && ini_get('output_handler') != 'ob_gzhandler' && !headers_sent()) { @ob_start("ob_gzhandler"); } handle_lastmod(); $hims = serverset('HTTP_IF_MODIFIED_SINCE'); $imsd = $hims ? strtotime($hims) : 0; if (is_callable('apache_request_headers')) { $headers = apache_request_headers(); if (isset($headers["A-IM"])) { $canaim = strpos($headers["A-IM"], "feed"); } else { $canaim = false; } } else { $canaim = false; } $hinm = stripslashes(serverset('HTTP_IF_NONE_MATCH')); $cutarticles = false; if ($canaim !== false) { foreach ($articles as $id => $thing) { if (strpos($hinm, $etags[$id]) !== false) { unset($articles[$id]); $cutarticles = true; $cut_etag = true; } if ($dates[$id] < $imsd) { unset($articles[$id]); $cutarticles = true; $cut_time = true; } } } if (isset($cut_etag) && isset($cut_time)) { header("Vary: If-None-Match, If-Modified-Since"); } else { if (isset($cut_etag)) { header("Vary: If-None-Match"); } else { if (isset($cut_time)) { header("Vary: If-Modified-Since"); } } } $etag = @join("-", $etags); if (strstr($hinm, $etag)) { header("HTTP/1.1 304 Not Modified"); exit; } if ($cutarticles) { //header("HTTP/1.1 226 IM Used"); //This should be used as opposed to 200, but Apache doesn't like it. //http://intertwingly.net/blog/2004/09/11/Vary-ETag/ says that the status code should be 200. header("Cache-Control: no-store, im"); header("IM: feed"); } $out = array_merge($out, $articles); header("Content-Type: application/rss+xml; charset=utf-8"); if ($etag) { header('ETag: "' . $etag . '"'); } return '<?xml version="1.0" encoding="utf-8"?>' . n . '<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">' . n . tag(join(n, $out), 'channel') . n . '</rss>'; }
function bombShelter() { $in = serverset('REQUEST_URI'); $ip = $_SERVER['REMOTE_ADDR']; if (strlen($in) > 260) { pixieExit(); } }
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); } } }
function saveComment() { global $siteurl, $comments_moderate, $comments_sendmail, $txpcfg, $comments_disallow_images, $txpac; include_once $txpcfg['txpath'] . '/lib/classTextile.php'; $im = !empty($comments_disallow_images) ? 1 : ''; $textile = new Textile(); $ref = serverset('HTTP_REFERRER'); extract(psa(array('parentid', 'name', 'email', 'web', 'message', 'backpage', 'nonce', 'remember'))); if ($txpac['comments_require_name']) { if (!trim($name)) { exit(graf(gTxt('comment_name_required')) . graf('<a href="" onClick="history.go(-1)">' . gTxt('back') . '</a>')); } } if ($txpac['comments_require_email']) { if (!trim($email)) { exit(graf(gTxt('comment_email_required')) . graf('<a href="" onClick="history.go(-1)">' . gTxt('back') . '</a>')); } } if (!trim($message)) { exit(graf(gTxt('comment_required')) . graf('<a href="" onClick="history.go(-1)">' . gTxt('back') . '</a>')); } $ip = @getHostByAddr(serverset('REMOTE_ADDR')); $message = strip_tags(trim($message)); $message2db = addslashes(nl2br($textile->textileThis($message, 1, '', $im))); $isdup = safe_row("message,name", "txp_discuss", "name='{$name}' and message='{$message2db}' and ip='{$ip}'"); if (checkBan($ip)) { if (!$isdup) { if (checkNonce($nonce)) { $visible = $comments_moderate ? 0 : 1; $rs = safe_insert("txp_discuss", "parentid = '{$parentid}',\n\t\t\t\t\t\t name = '{$name}',\n\t\t\t\t\t\t email = '{$email}',\n\t\t\t\t\t\t web = '{$web}',\n\t\t\t\t\t\t ip = '{$ip}',\n\t\t\t\t\t\t message = '{$message2db}',\n\t\t\t\t\t\t visible = {$visible},\n\t\t\t\t\t\t posted = now()"); if ($rs) { safe_update("txp_discuss_nonce", "used='1'", "nonce='{$nonce}'"); if ($txpac['comment_means_site_updated']) { safe_update("txp_prefs", "val=now()", "name='lastmod'"); } if ($comments_sendmail) { mail_comment($message, $name, $email, $web, $parentid); } ob_start(); header('location: ' . $backpage); } } // end check nonce } // end check dup } else { exit(gTxt('you_have_been_banned')); } }
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 rss() { global $prefs, $thisarticle; extract($prefs); ob_start(); extract(doSlash(gpsa(array('category', 'section', 'limit', 'area')))); $area = gps('area'); $sitename .= $section ? ' - ' . $section : ''; $sitename .= $category ? ' - ' . $category : ''; $out[] = tag(doSpecial($sitename), 'title'); $out[] = tag(hu, 'link'); $out[] = tag(doSpecial($site_slogan), 'description'); $articles = array(); if (!$area or $area == 'article') { $sfilter = $section ? "and Section = '" . $section . "'" : ''; $cfilter = $category ? "and (Category1='" . $category . "' or Category2='" . $category . "')" : ''; $limit = $limit ? $limit : '5'; $frs = safe_column("name", "txp_section", "in_rss != '1'"); if ($frs) { foreach ($frs as $f) { $query[] = "and Section != '" . $f . "'"; } } $query[] = $sfilter; $query[] = $cfilter; $rs = safe_rows_start("*, unix_timestamp(Posted) as uPosted, ID as thisid", "textpattern", "Status = 4 " . join(' ', $query) . "and Posted < now() order by Posted desc limit {$limit}"); if ($rs) { while ($a = nextRow($rs)) { extract($a); populateArticleData($a); $a['posted'] = $uPosted; $Body = !$syndicate_body_or_excerpt ? $thisarticle['body'] : $thisarticle['excerpt']; $Body = !trim($Body) ? $thisarticle['body'] : $Body; $Body = str_replace('href="/', 'href="' . hu, $Body); $Body = preg_replace("/href=\\\"#(.*)\"/", "href=\"" . permlinkurl($a) . "#\\1\"", $Body); $Body = safe_hed($Body); $Body = preg_replace(array('/</', '/>/', "/'/", '/"/'), array('<', '>', ''', '"'), $Body); // encode bare ampersands $Body = preg_replace("/&(?![#0-9]+;|\\w+;)/i", '&', $Body); $uTitle = $url_title ? $url_title : stripSpace($Title); $uTitle = htmlspecialchars($uTitle, ENT_NOQUOTES); if ($show_comment_count_in_feed) { $dc = getCount('txp_discuss', "parentid={$ID} and visible=1"); $count = $dc > 0 ? ' [' . $dc . ']' : ''; } else { $count = ''; } $Title = doSpecial($Title) . $count; $permlink = permlinkurl($a); $item = tag(strip_tags($Title), 'title') . n . tag($Body, 'description') . n . tag($permlink, 'link'); $articles[$ID] = tag($item, 'item'); $etags[$ID] = strtoupper(dechex(crc32($articles[$ID]))); $dates[$ID] = $uPosted; } } } elseif ($area == 'link') { $cfilter = $category ? "category='{$category}'" : '1'; $limit = $limit ? $limit : 15; $rs = safe_rows_start("*", "txp_link", "{$cfilter} order by date desc limit {$limit}"); if ($rs) { while ($a = nextRow($rs)) { extract($a); $item = tag(doSpecial($linkname), 'title') . n . tag(doSpecial($description), 'description') . n . tag(doSpecial($url), 'link'); $articles[$id] = tag($item, 'item'); $etags[$id] = strtoupper(dechex(crc32($articles[$id]))); $dates[$id] = $date; } } } //turn on compression if we aren't using it already if (extension_loaded('zlib') && ini_get("zlib.output_compression") == 0 && ini_get('output_handler') != 'ob_gzhandler' && !headers_sent()) { ob_start("ob_gzhandler"); } $last = fetch('unix_timestamp(val)', 'txp_prefs', 'name', 'lastmod'); $last = gmdate("D, d M Y H:i:s \\G\\M\\T", $last); header("Last-Modified: {$last}"); $expires = gmdate('D, d M Y H:i:s \\G\\M\\T', time() + 3600 * 1); header("Expires: {$expires}"); $hims = serverset('HTTP_IF_MODIFIED_SINCE'); if ($hims == $last) { header("HTTP/1.1 304 Not Modified"); exit; } $imsd = @strtotime($hims); if (is_callable('apache_request_headers')) { $headers = apache_request_headers(); if (isset($headers["A-IM"])) { $canaim = strpos($headers["A-IM"], "feed"); } else { $canaim = false; } } else { $canaim = false; } $hinm = stripslashes(serverset('HTTP_IF_NONE_MATCH')); $cutarticles = false; if ($canaim !== false) { foreach ($articles as $id => $thing) { if (strpos($hinm, $etags[$id]) !== false) { unset($articles[$id]); $cutarticles = true; $cut_etag = true; } if ($dates[$id] < $imsd) { unset($articles[$id]); $cutarticles = true; $cut_time = true; } } } if (isset($cut_etag) && isset($cut_time)) { header("Vary: If-None-Match, If-Modified-Since"); } else { if (isset($cut_etag)) { header("Vary: If-None-Match"); } else { if (isset($cut_time)) { header("Vary: If-Modified-Since"); } } } $etag = @join("-", $etags); if (strstr($hinm, $etag)) { header("HTTP/1.1 304 Not Modified"); exit; } if ($cutarticles) { //header("HTTP/1.1 226 IM Used"); //This should be used as opposed to 200, but Apache doesn't like it. //http://intertwingly.net/blog/2004/09/11/Vary-ETag/ says that the status code should be 200. header("Cache-Control: no-store, im"); header("IM: feed"); } $out = array_merge($out, $articles); header("Content-Type: application/rss+xml; charset=utf-8"); if ($etag) { header('ETag: "' . $etag . '"'); } return '<rss version="0.92">' . tag(join(n, $out), 'channel') . '</rss>'; }
function atom() { global $thisarticle; extract($GLOBALS['prefs']); define("textplain", ' type="text/plain"'); define("texthtml", ' type="text/html"'); define("relalt", ' rel="alternate"'); define('appxhtml', ' type="application/xhtml+xml"'); define("divxhtml", '<div xmlns="http://www.w3.org/1999/xhtml">'); $area = doSlash(gps('area')); extract(doSlash(gpsa(array('category', 'section', 'limit')))); $last = fetch('unix_timestamp(val)', 'txp_prefs', 'name', 'lastmod'); $sitename .= $section ? ' - ' . $section : ''; $sitename .= $category ? ' - ' . $category : ''; $pub = safe_row("RealName, email", "txp_users", "privs=1"); $out[] = tag($sitename, 'title', textplain); $out[] = tag($site_slogan, 'tagline', textplain); $out[] = '<link' . relalt . texthtml . ' href="' . hu . '" />'; $articles = array(); //Atom feeds with mail or domain name $dn = explode('/', $siteurl); $mail_or_domain = $use_mail_on_feeds_id ? eE($blog_mail_uid) : $dn[0]; $out[] = tag('tag:' . $mail_or_domain . ',' . $blog_time_uid . ':' . $blog_uid . ($section ? '/' . $section : '') . ($category ? '/' . $category : ''), 'id'); $out[] = tag('Textpattern', 'generator', ' url="http://textpattern.com" version="' . $version . '"'); $out[] = tag(date("Y-m-d\\TH:i:s\\Z", $last), 'modified'); $auth[] = tag($pub['RealName'], 'name'); $auth[] = $include_email_atom ? tag(eE($pub['email']), 'email') : ''; $auth[] = tag(hu, 'url'); $out[] = tag(n . t . t . join(n . t . t, $auth) . n, 'author'); if (!$area or $area == 'article') { $sfilter = $section ? "and Section = '" . $section . "'" : ''; $cfilter = $category ? "and (Category1='" . $category . "' or Category2='" . $category . "')" : ''; $limit = $limit ? $limit : '5'; $frs = safe_column("name", "txp_section", "in_rss != '1'"); foreach ($frs as $f) { $query[] = "and Section != '" . $f . "'"; } $query[] = $sfilter; $query[] = $cfilter; $rs = safe_rows_start("*, \n\t\t\t\tID as thisid, \n\t\t\t\tunix_timestamp(Posted) as uPosted,\n\t\t\t\tunix_timestamp(LastMod) as uLastMod", "textpattern", "Status=4 and Posted <= now() " . join(' ', $query) . "order by Posted desc limit {$limit}"); if ($rs) { while ($a = nextRow($rs)) { extract($a); populateArticleData($a); $a['posted'] = $uPosted; if ($show_comment_count_in_feed) { $dc = getCount('txp_discuss', "parentid={$ID} and visible=1"); $count = $dc > 0 ? ' [' . $dc . ']' : ''; } else { $count = ''; } $thisauthor = safe_field("RealName", "txp_users", "name='{$AuthorID}'"); $e['thisauthor'] = tag(n . t . t . t . tag(htmlspecialchars($thisauthor), 'name') . n . t . t, 'author'); $e['issued'] = tag(gmdate("Y-m-d\\TH:i:s\\Z", $uPosted), 'issued'); $e['modified'] = tag(gmdate("Y-m-d\\TH:i:s\\Z", $uLastMod), 'modified'); $escaped_title = safe_hed($Title); $escaped_title = preg_replace("/&(?![#a-z0-9]+;)/i", '&', $escaped_title); $escaped_title = str_replace('<', '<', $escaped_title); $escaped_title = str_replace('>', '>', $escaped_title); $e['title'] = tag($escaped_title . $count, 'title'); $uTitle = $url_title ? $url_title : stripSpace($Title); $uTitle = htmlspecialchars($uTitle, ENT_NOQUOTES); $permlink = permlinkurl($a); $e['link'] = '<link' . relalt . texthtml . ' href="' . $permlink . '" />'; $e['id'] = tag('tag:' . $mail_or_domain . ',' . $feed_time . ':' . $blog_uid . '/' . $uid, 'id'); $e['subject'] = tag(htmlspecialchars($Category1), 'dc:subject'); // pull Body or Excerpt? $Body = !$syndicate_body_or_excerpt ? $thisarticle['body'] : $thisarticle['excerpt']; // if Excerpt is empty, switch back to Body_html $Body = !trim($Body) ? $thisarticle['body'] : $Body; // fix relative urls $Body = str_replace('href="/', 'href="' . hu, $Body); $Body = preg_replace("/href=\\\"#(.*)\"/", "href=\"" . permlinkurl($a) . "#\\1\"", $Body); $Body = safe_hed($Body); // encode and entify $Body = preg_replace(array('/</', '/>/', "/'/", '/"/'), array('<', '>', ''', '"'), $Body); // encode bare ampersands $Body = preg_replace("/&(?![#0-9]+;|\\w+;)/i", '&', $Body); $e['content'] = tag(n . $Body . n, 'content', ' type="text/html" mode="escaped"'); $articles[$ID] = tag(n . t . t . join(n . t . t, $e) . n, 'entry'); $etags[$ID] = strtoupper(dechex(crc32($articles[$ID]))); $dates[$ID] = $uLastMod; } } } elseif ($area == 'link') { $cfilter = $category ? "category='{$category}'" : '1'; $limit = $limit ? $limit : 15; $rs = safe_rows_start("*", "txp_link", "{$cfilter} order by date desc limit {$limit}"); if ($rs) { while ($a = nextRow($rs)) { extract($a); $e['title'] = tag(doSpecial($linkname), 'title'); $content = utf8_encode(htmlspecialchars($description)); $e['content'] = tag(n . $description . n, 'content', ' type="text/html" mode="escaped"'); $url = preg_replace("/^\\/(.*)/", "http://{$siteurl}/\$1", $url); $url = preg_replace("/&((?U).*)=/", "&\\1=", $url); $e['link'] = '<link' . relalt . texthtml . ' href="' . $url . '" />'; $e['issued'] = tag(gmdate("Y-m-d\\TH:i:s\\Z", $date), 'issued'); $e['modified'] = tag(gmdate("Y-m-d\\TH:i:s\\Z", $date), 'modified'); $e['id'] = tag('tag:' . $mail_or_domain . ',' . $feed_time . ':' . $id, 'id'); $articles[$id] = tag(n . t . t . join(n . t . t, $e) . n, 'entry'); $etags[$id] = strtoupper(dechex(crc32($articles[$id]))); $dates[$id] = $date; } } } if (!empty($articles)) { //turn on compression if we aren't using it already if (extension_loaded('zlib') && ini_get("zlib.output_compression") == 0 && ini_get('output_handler') != 'ob_gzhandler' && !headers_sent()) { ob_start("ob_gzhandler"); } $last = fetch('unix_timestamp(val)', 'txp_prefs', 'name', 'lastmod'); $last = gmdate("D, d M Y H:i:s \\G\\M\\T", $last); header("Last-Modified: {$last}"); $expires = gmdate('D, d M Y H:i:s \\G\\M\\T', time() + 3600 * 1); header("Expires: {$expires}"); $hims = serverset('HTTP_IF_MODIFIED_SINCE'); if ($hims == $last) { header("HTTP/1.1 304 Not Modified"); exit; } $imsd = @strtotime($hims); if (is_callable('apache_request_headers')) { $headers = apache_request_headers(); if (isset($headers["A-IM"])) { $canaim = strpos($headers["A-IM"], "feed"); } else { $canaim = false; } } else { $canaim = false; } $hinm = stripslashes(serverset('HTTP_IF_NONE_MATCH')); $cutarticles = false; if ($canaim !== false) { foreach ($articles as $id => $thing) { if (strpos($hinm, $etags[$id])) { unset($articles[$id]); $cutarticles = true; $cut_etag = true; } if ($dates[$id] < $imsd) { unset($articles[$id]); $cutarticles = true; $cut_time = true; } } } if (isset($cut_etag) && isset($cut_time)) { header("Vary: If-None-Match, If-Modified-Since"); } else { if (isset($cut_etag)) { header("Vary: If-None-Match"); } else { if (isset($cut_time)) { header("Vary: If-Modified-Since"); } } } $etag = @join("-", $etags); if (strstr($hinm, $etag)) { header("HTTP/1.1 304 Not Modified"); exit; } if ($etag) { header('ETag: "' . $etag . '"'); } if ($cutarticles) { //header("HTTP/1.1 226 IM Used"); //This should be used as opposed to 200, but Apache doesn't like it. //http://intertwingly.net/blog/2004/09/11/Vary-ETag/ says that the status code should be 200. header("Cache-Control: no-store, im"); header("IM: feed"); } $out = array_merge($out, $articles); ob_start(); header('Content-type: application/atom+xml; charset=utf-8'); return chr(60) . '?xml version="1.0" encoding="UTF-8"?' . chr(62) . n . '<feed version="0.3" xml:lang="' . $language . '" xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">' . join(n, $out) . '</feed>'; } }
/** * Protection from those who'd bomb the site by GET. * * Origin of the infamous 'Nice try' message and an even more useful '503' http status. */ function bombShelter() { global $prefs; $in = serverset('REQUEST_URI'); if (!empty($prefs['max_url_len']) and strlen($in) > $prefs['max_url_len']) { txp_status_header('503 Service Unavailable'); exit('Nice try.'); } }
function comments_form($atts) { global $thisarticle, $has_comments_preview; extract(lAtts(array('class' => __FUNCTION__, 'form' => 'comment_form', 'isize' => '25', 'msgcols' => '25', 'msgrows' => '5', 'msgstyle' => '', 'show_preview' => empty($has_comments_preview), 'wraptag' => '', 'previewlabel' => gTxt('preview'), 'submitlabel' => gTxt('submit'), 'rememberlabel' => gTxt('remember'), 'forgetlabel' => gTxt('forget')), $atts)); assert_article(); extract($thisarticle); $out = ''; $ip = serverset('REMOTE_ADDR'); $blacklisted = is_blacklisted($ip); if (!checkCommentsAllowed($thisid)) { $out = graf(gTxt("comments_closed"), ' id="comments_closed"'); } elseif (!checkBan($ip)) { $out = graf(gTxt('you_have_been_banned'), ' id="comments_banned"'); } elseif ($blacklisted) { $out = graf(gTxt('your_ip_is_blacklisted_by' . ' ' . $blacklisted), ' id="comments_blacklisted"'); } elseif (gps('commented') !== '') { $out = gTxt("comment_posted"); if (gps('commented') === '0') { $out .= " " . gTxt("comment_moderated"); } $out = graf($out, ' id="txpCommentInputForm"'); } else { # display a comment preview if required if (ps('preview') and $show_preview) { $out = comments_preview(array()); } $out .= commentForm($thisid, $atts); } return !$wraptag ? $out : doTag($out, $wraptag, $class); }
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 comments_form($atts, $thing = null) { global $thisarticle, $has_comments_preview; global $thiscommentsform; // TODO: Remove any uses of $thiscommentsform when removing deprecated attributes from below. // deprecated attributes since TXP 4.6. Most of these (except msgstyle) // were moved to the tags that occur within a comments_form, although // some of the names changed. $deprecated = array('isize', 'msgrows', 'msgcols', 'msgstyle', 'previewlabel', 'submitlabel', 'rememberlabel', 'forgetlabel'); foreach ($deprecated as $att) { if (isset($atts[$att])) { trigger_error(gTxt('deprecated_attribute', array('{name}' => $att)), E_USER_NOTICE); } } $atts = lAtts(array('class' => __FUNCTION__, 'form' => 'comment_form', 'isize' => '25', 'msgcols' => '25', 'msgrows' => '5', 'msgstyle' => '', 'show_preview' => empty($has_comments_preview), 'wraptag' => '', 'previewlabel' => gTxt('preview'), 'submitlabel' => gTxt('submit'), 'rememberlabel' => gTxt('remember'), 'forgetlabel' => gTxt('forget')), $atts); extract($atts); $thiscommentsform = array_intersect_key($atts, array_flip($deprecated)); assert_article(); extract($thisarticle); $out = ''; $ip = serverset('REMOTE_ADDR'); $blacklisted = is_blacklisted($ip); if (!checkCommentsAllowed($thisid)) { $out = graf(gTxt("comments_closed"), ' id="comments_closed"'); } elseif ($blacklisted) { $out = graf(gTxt('your_ip_is_blacklisted_by' . ' ' . $blacklisted), ' id="comments_blacklisted"'); } elseif (gps('commented') !== '') { $out = gTxt("comment_posted"); if (gps('commented') === '0') { $out .= " " . gTxt("comment_moderated"); } $out = graf($out, ' id="txpCommentInputForm"'); } else { // Display a comment preview if required. if (ps('preview') and $show_preview) { $out = comments_preview(array()); } extract(doDeEnt(psa(array('parentid', 'backpage')))); // If the form fields are filled (anything other than blank), pages really // should not be saved by a public cache (rfc2616/14.9.1). if (pcs('name') || pcs('email') || pcs('web')) { header('Cache-Control: private'); } $url = $GLOBALS['pretext']['request_uri']; // Experimental clean URLs with only 404-error-document on Apache possibly // requires messy URLs for POST requests. if (defined('PARTLY_MESSY') and PARTLY_MESSY) { $url = hu . '?id=' . intval($parentid); } $out .= '<form id="txpCommentInputForm" method="post" action="' . txpspecialchars($url) . '#cpreview">' . n . '<div class="comments-wrapper">' . n . ($thing === null ? parse_form($form) : parse($thing)) . n . hInput('parentid', $parentid ? $parentid : $thisid) . n . hInput('backpage', ps('preview') ? $backpage : $url) . n . '</div>' . n . '</form>'; } return !$wraptag ? $out : doTag($out, $wraptag, $class); }