1,'area'=>$area,'section'=>$section,'category'=>$category,'limit'=>$limit)).'" />';
$out[] = '';
$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');
$out[] = callback_event('atom_head');
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;
$expired = ($publish_expired_articles) ? '' : ' and (now() <= Expires or Expires = '.NULLDATETIME.') ';
$rs = safe_rows_start(
"*,
ID as thisid,
unix_timestamp(Posted) as uPosted,
unix_timestamp(Expires) as uExpires,
unix_timestamp(LastMod) as uLastMod",
"textpattern",
"Status=4 and Posted <= now() $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;
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'] = '';
$e['id'] = tag('tag:'.$mail_or_domain.','.$feed_time.':'.$blog_uid.'/'.$uid,'id');
$e['category1'] = (trim($Category1) ? '' : '');
$e['category2'] = (trim($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'] = '';
$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 = '$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])) {
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+xml; charset=utf-8');
return chr(60).'?xml version="1.0" encoding="UTF-8"?'.chr(62).n.
''.join(n,$out).'';
}
// DEPRECATED FUNCTIONS
// these are included only for backwards compatibility with older plugins
// see the above code for more appropriate ways of handling feed content
function safe_hed($toUnicode) {
if (version_compare(phpversion(), "5.0.0", ">=")) {
$str = html_entity_decode($toUnicode, ENT_QUOTES, "UTF-8");
} else {
$trans_tbl = get_html_translation_table(HTML_ENTITIES);
foreach($trans_tbl as $k => $v) {
$ttr[$v] = utf8_encode($k);
}
$str = strtr($toUnicode, $ttr);
}
return $str;
}
function fixup_for_feed($toFeed, $permalink) {
// fix relative urls
$txt = str_replace('href="/','href="'.hu.'/',$toFeed);
$txt = preg_replace("/href=\\\"#(.*)\"/","href=\"".$permalink."#\\1\"",$txt);
// This was removed as entities shouldn't be stripped in Atom feeds
// when the content type is html. Leaving it commented out as a reminder.
//$txt = safe_hed($txt);
// encode and entify
$txt = preg_replace(array('/','/>/',"/'/",'/"/'), array('<','>',''','"'), $txt);
$txt = preg_replace("/&(?![#0-9]+;)/i",'&', $txt);
return $txt;
}
?>