[ Index ] |
PHP Cross Reference of Textpattern 4.0.8 |
[Summary view] [Print] [Text view]
1 <?php 2 3 /* 4 This is Textpattern 5 Copyright 2005 by Dean Allen - all rights reserved. 6 7 Use of this software denotes acceptance of the Textpattern license agreement 8 9 $HeadURL: https://textpattern.googlecode.com/svn/releases/4.0.8/source/textpattern/publish/atom.php $ 10 $LastChangedRevision: 3029 $ 11 12 */ 13 14 15 // ------------------------------------------------------------- 16 function atom() 17 { 18 global $thisarticle; 19 set_error_handler('feedErrorHandler'); 20 ob_clean(); 21 extract($GLOBALS['prefs']); 22 define("t_texthtml",' type="text/html"'); 23 define("t_text",' type="text"'); 24 define("t_html",' type="html"'); 25 define("t_xhtml",' type="xhtml"'); 26 define('t_appxhtml',' type="xhtml"'); 27 define("r_relalt",' rel="alternate"'); 28 define("r_relself",' rel="self"'); 29 30 extract(doSlash(gpsa(array('category','section','limit','area')))); 31 32 $last = fetch('unix_timestamp(val)','txp_prefs','name','lastmod'); 33 34 $sitename .= ($section) ? ' - '.fetch_section_title($section) : ''; 35 $sitename .= ($category) ? ' - '.fetch_category_title($category) : ''; 36 37 $pub = safe_row("RealName, email", "txp_users", "privs=1"); 38 39 $out[] = tag(htmlspecialchars($sitename),'title',t_text); 40 $out[] = tag(htmlspecialchars($site_slogan),'subtitle',t_text); 41 $out[] = '<link'.r_relself.' href="'.pagelinkurl(array('atom'=>1,'area'=>$area,'section'=>$section,'category'=>$category,'limit'=>$limit)).'" />'; 42 $out[] = '<link'.r_relalt.t_texthtml.' href="'.hu.'" />'; 43 $articles = array(); 44 45 //Atom feeds with mail or domain name 46 $dn = explode('/',$siteurl); 47 $mail_or_domain = ($use_mail_on_feeds_id)? eE($blog_mail_uid):$dn[0]; 48 $out[] = tag('tag:'.$mail_or_domain.','.$blog_time_uid.':'.$blog_uid.(($section)? '/'.$section:'').(($category)? '/'.$category:''),'id'); 49 50 $out[] = tag('Textpattern','generator', 51 ' uri="http://textpattern.com/" version="'.$version.'"'); 52 $out[] = tag(safe_strftime("w3cdtf",$last),'updated'); 53 54 55 $auth[] = tag($pub['RealName'],'name'); 56 $auth[] = ($include_email_atom) ? tag(eE($pub['email']),'email') : ''; 57 $auth[] = tag(hu,'uri'); 58 59 $out[] = tag(n.t.t.join(n.t.t,$auth).n,'author'); 60 $out[] = callback_event('atom_head'); 61 62 if (!$area or $area=='article') { 63 64 $sfilter = ($section) ? "and Section = '".$section."'" : ''; 65 $cfilter = ($category) 66 ? "and (Category1='".$category."' or Category2='".$category."')":''; 67 $limit = ($limit) ? $limit : $rss_how_many; 68 $limit = intval(min($limit,max(100,$rss_how_many))); 69 70 $frs = safe_column("name", "txp_section", "in_rss != '1'"); 71 72 $query = array(); 73 foreach($frs as $f) $query[] = "and Section != '".doSlash($f)."'"; 74 $query[] = $sfilter; 75 $query[] = $cfilter; 76 77 $expired = ($publish_expired_articles) ? '' : ' and (now() <= Expires or Expires = '.NULLDATETIME.') '; 78 $rs = safe_rows_start( 79 "*, 80 ID as thisid, 81 unix_timestamp(Posted) as uPosted, 82 unix_timestamp(Expires) as uExpires, 83 unix_timestamp(LastMod) as uLastMod", 84 "textpattern", 85 "Status=4 and Posted <= now() $expired".join(' ',$query). 86 "order by Posted desc limit $limit" 87 ); 88 if ($rs) { 89 while ($a = nextRow($rs)) { 90 91 extract($a); 92 populateArticleData($a); 93 $cb = callback_event('atom_entry'); 94 $e = array(); 95 96 $a['posted'] = $uPosted; 97 98 if ($show_comment_count_in_feed) 99 $count = ($comments_count > 0) ? ' ['.$comments_count.']' : ''; 100 else $count = ''; 101 102 $thisauthor = get_author_name($AuthorID); 103 104 $e['thisauthor'] = tag(n.t.t.t.tag(htmlspecialchars($thisauthor),'name').n.t.t,'author'); 105 106 $e['issued'] = tag(safe_strftime('w3cdtf',$uPosted),'published'); 107 $e['modified'] = tag(safe_strftime('w3cdtf',$uLastMod),'updated'); 108 109 $escaped_title = htmlspecialchars($Title); 110 $e['title'] = tag($escaped_title.$count,'title',t_html); 111 112 $permlink = permlinkurl($a); 113 $e['link'] = '<link'.r_relalt.t_texthtml.' href="'.$permlink.'" />'; 114 115 $e['id'] = tag('tag:'.$mail_or_domain.','.$feed_time.':'.$blog_uid.'/'.$uid,'id'); 116 117 $e['category1'] = (trim($Category1) ? '<category term="'.htmlspecialchars($Category1).'" />' : ''); 118 $e['category2'] = (trim($Category2) ? '<category term="'.htmlspecialchars($Category2).'" />' : ''); 119 120 $summary = trim(replace_relative_urls(parse($thisarticle['excerpt']), $permlink)); 121 $content = trim(replace_relative_urls(parse($thisarticle['body']), $permlink)); 122 123 if ($syndicate_body_or_excerpt) { 124 # short feed: use body as summary if there's no excerpt 125 if (!trim($summary)) 126 $summary = $content; 127 $content = ''; 128 } 129 130 if (trim($content)) 131 $e['content'] = tag(n.escape_cdata($content).n,'content',t_html); 132 133 if (trim($summary)) 134 $e['summary'] = tag(n.escape_cdata($summary).n,'summary',t_html); 135 136 $articles[$ID] = tag(n.t.t.join(n.t.t,$e).n.$cb,'entry'); 137 138 $etags[$ID] = strtoupper(dechex(crc32($articles[$ID]))); 139 $dates[$ID] = $uLastMod; 140 } 141 } 142 } elseif ($area=='link') { 143 144 $cfilter = ($category) ? "category='".$category."'" : '1'; 145 $limit = ($limit) ? $limit : $rss_how_many; 146 $limit = intval(min($limit,max(100,$rss_how_many))); 147 148 $rs = safe_rows_start("*", "txp_link", "$cfilter order by date desc, id desc limit $limit"); 149 150 if ($rs) { 151 while ($a = nextRow($rs)) { 152 extract($a); 153 154 $e['title'] = tag(htmlspecialchars($linkname),'title',t_html); 155 $e['content'] = tag(n.htmlspecialchars($description).n,'content',t_html); 156 157 $url = (preg_replace("/^\/(.*)/","https?://$siteurl/$1",$url)); 158 $url = preg_replace("/&((?U).*)=/","&\\1=",$url); 159 $e['link'] = '<link'.r_relalt.t_texthtml.' href="'.$url.'" />'; 160 161 $e['issued'] = tag(safe_strftime('w3cdtf', strtotime($date)),'published'); 162 $e['modified'] = tag(gmdate('Y-m-d\TH:i:s\Z',strtotime($date)),'updated'); 163 $e['id'] = tag('tag:'.$mail_or_domain.','.safe_strftime( '%Y-%m-%d', strtotime( $date)).':'.$blog_uid.'/'.$id,'id'); 164 165 $articles[$id] = tag(n.t.t.join(n.t.t,$e).n,'entry'); 166 167 $etags[$id] = strtoupper(dechex(crc32($articles[$id]))); 168 $dates[$id] = $date; 169 170 } 171 } 172 } 173 174 if (!$articles) { 175 if ($section) { 176 if (safe_field('name', 'txp_section', "name = '$section'") == false) { 177 txp_die(gTxt('404_not_found'), '404'); 178 } 179 } elseif ($category) { 180 switch ($area) { 181 case 'link': 182 if (safe_field('id', 'txp_category', "name = '$category' and type = 'link'") == false) { 183 txp_die(gTxt('404_not_found'), '404'); 184 } 185 break; 186 187 case 'article': 188 default: 189 if (safe_field('id', 'txp_category', "name = '$category' and type = 'article'") == false) { 190 txp_die(gTxt('404_not_found'), '404'); 191 } 192 break; 193 } 194 } 195 } else { 196 //turn on compression if we aren't using it already 197 if (extension_loaded('zlib') && ini_get("zlib.output_compression") == 0 && ini_get('output_handler') != 'ob_gzhandler' && !headers_sent()) { 198 // make sure notices/warnings/errors don't fudge up the feed 199 // when compression is used 200 $buf = ''; 201 while ($b = @ob_get_clean()) 202 $buf .= $b; 203 @ob_start('ob_gzhandler'); 204 echo $buf; 205 } 206 207 handle_lastmod(); 208 $hims = serverset('HTTP_IF_MODIFIED_SINCE'); 209 $imsd = ($hims) ? strtotime($hims) : 0; 210 211 if (is_callable('apache_request_headers')) { 212 $headers = apache_request_headers(); 213 if (isset($headers["A-IM"])) { 214 $canaim = strpos($headers["A-IM"], "feed"); 215 } else { 216 $canaim = false; 217 } 218 } else { 219 $canaim = false; 220 } 221 222 $hinm = stripslashes(serverset('HTTP_IF_NONE_MATCH')); 223 224 $cutarticles = false; 225 226 if ($canaim !== false) { 227 foreach($articles as $id=>$thing) { 228 if (strpos($hinm, $etags[$id])) { 229 unset($articles[$id]); 230 $cutarticles = true; 231 $cut_etag = true; 232 } 233 234 if ($dates[$id] < $imsd) { 235 unset($articles[$id]); 236 $cutarticles = true; 237 $cut_time = true; 238 } 239 } 240 } 241 242 if (isset($cut_etag) && isset($cut_time)) { 243 header("Vary: If-None-Match, If-Modified-Since"); 244 } else if (isset($cut_etag)) { 245 header("Vary: If-None-Match"); 246 } else if (isset($cut_time)) { 247 header("Vary: If-Modified-Since"); 248 } 249 250 $etag = @join("-",$etags); 251 252 if (strstr($hinm, $etag)) { 253 txp_status_header('304 Not Modified'); 254 exit(0); 255 } 256 257 if ($etag) header('ETag: "'.$etag.'"'); 258 259 if ($cutarticles) { 260 //header("HTTP/1.1 226 IM Used"); 261 //This should be used as opposed to 200, but Apache doesn't like it. 262 //http://intertwingly.net/blog/2004/09/11/Vary-ETag/ says that the status code should be 200. 263 header("Cache-Control: no-store, im"); 264 header("IM: feed"); 265 } 266 267 } 268 269 $out = array_merge($out, $articles); 270 271 header('Content-type: application/atom+xml; charset=utf-8'); 272 return chr(60).'?xml version="1.0" encoding="UTF-8"?'.chr(62).n. 273 '<feed xml:lang="'.$language.'" xmlns="http://www.w3.org/2005/Atom">'.join(n,$out).'</feed>'; 274 } 275 276 277 // DEPRECATED FUNCTIONS 278 // these are included only for backwards compatibility with older plugins 279 // see the above code for more appropriate ways of handling feed content 280 281 function safe_hed($toUnicode) { 282 283 if (version_compare(phpversion(), "5.0.0", ">=")) { 284 $str = html_entity_decode($toUnicode, ENT_QUOTES, "UTF-8"); 285 } else { 286 $trans_tbl = get_html_translation_table(HTML_ENTITIES); 287 foreach($trans_tbl as $k => $v) { 288 $ttr[$v] = utf8_encode($k); 289 } 290 $str = strtr($toUnicode, $ttr); 291 } 292 return $str; 293 } 294 295 function fixup_for_feed($toFeed, $permalink) { 296 297 // fix relative urls 298 $txt = str_replace('href="/','href="'.hu.'/',$toFeed); 299 $txt = preg_replace("/href=\\\"#(.*)\"/","href=\"".$permalink."#\\1\"",$txt); 300 // This was removed as entities shouldn't be stripped in Atom feeds 301 // when the content type is html. Leaving it commented out as a reminder. 302 //$txt = safe_hed($txt); 303 304 // encode and entify 305 $txt = preg_replace(array('/</','/>/',"/'/",'/"/'), array('<','>',''','"'), $txt); 306 $txt = preg_replace("/&(?![#0-9]+;)/i",'&', $txt); 307 return $txt; 308 309 } 310 311 312 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu May 21 23:03:01 2009 | Cross-referenced by PHPXref 0.7 |