Textpattern PHP Cross Reference Content Management Systems

Source: /textpattern/publish/rss.php - 274 lines - 8630 bytes - Summary - Text - Print

   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.5.4/source/textpattern/publish/rss.php $
  10  $LastChangedRevision: 4011 $
  11  
  12  */
  13  
  14  
  15  // -------------------------------------------------------------
  16  	function rss()
  17      {
  18          global $prefs,$thisarticle;
  19          set_error_handler('feedErrorHandler');
  20          ob_clean();
  21          extract($prefs);
  22  
  23          extract(doSlash(gpsa(array('limit','area'))));
  24  
  25          // build filter criteria from a comma-separated list of sections and categories
  26          $feed_filter_limit = get_pref('feed_filter_limit', 10);
  27          $section = gps('section');
  28          $category = gps('category');
  29          if (!is_scalar($section) || !is_scalar($category)) {
  30              txp_die('Not Found', 404);
  31          }
  32  
  33          $section = ($section ? array_slice(array_unique(do_list($section)), 0, $feed_filter_limit) : array());
  34          $category = ($category ? array_slice(array_unique(do_list($category)), 0, $feed_filter_limit) : array());
  35          $st = array();
  36          foreach ($section as $s)
  37          {
  38              $st[] = fetch_section_title($s);
  39          }
  40          $ct = array();
  41          foreach ($category as $c)
  42          {
  43              $ct[] = fetch_category_title($c);
  44          }
  45  
  46          $sitename .= ($section) ? ' - '.join(' - ', $st) : '';
  47          $sitename .= ($category) ? ' - '.join(' - ', $ct) : '';
  48          $dn = explode('/',$siteurl);
  49          $mail_or_domain = ($use_mail_on_feeds_id)? eE($blog_mail_uid):$dn[0];
  50  
  51          // feed header
  52          $out[] = tag('http://textpattern.com/?v='.$version, 'generator');
  53          $out[] = tag(doSpecial($sitename),'title');
  54          $out[] = tag(hu,'link');
  55          $out[] = '<atom:link href="'.pagelinkurl(array('rss'=>1,'area'=>$area,'section'=>$section,'category'=>$category,'limit'=>$limit)).'" rel="self" type="application/rss+xml" />';
  56          $out[] = tag(doSpecial($site_slogan),'description');
  57          $last = fetch('unix_timestamp(val)','txp_prefs','name','lastmod');
  58          $out[] = tag(safe_strftime('rfc822',$last),'pubDate');
  59          $out[] = callback_event('rss_head');
  60  
  61          // feed items
  62          $articles = array();
  63          $section = doSlash($section);
  64          $category = doSlash($category);
  65  
  66          if (!$area or $area=='article') {
  67  
  68              $sfilter = (!empty($section)) ? "and Section in ('".join("','", $section)."')" : '';
  69              $cfilter = (!empty($category))? "and (Category1 in ('".join("','", $category)."') or Category2 in ('".join("','", $category)."'))" : '';
  70              $limit = ($limit) ? $limit : $rss_how_many;
  71              $limit = intval(min($limit,max(100,$rss_how_many)));
  72  
  73              $frs = safe_column("name", "txp_section", "in_rss != '1'");
  74              if ($frs) foreach($frs as $f) $query[] = "and Section != '".doSlash($f)."'";
  75              $query[] = $sfilter;
  76              $query[] = $cfilter;
  77  
  78              $expired = ($publish_expired_articles) ? '' : ' and (now() <= Expires or Expires = '.NULLDATETIME.') ';
  79              $rs = safe_rows_start(
  80                  "*, unix_timestamp(Posted) as uPosted, unix_timestamp(LastMod) as uLastMod, unix_timestamp(Expires) as uExpires, ID as thisid",
  81                  "textpattern",
  82                  "Status = 4 ".join(' ',$query).
  83                  "and Posted < now()".$expired."order by Posted desc limit $limit"
  84              );
  85  
  86              if($rs) {
  87                  while ($a = nextRow($rs)) {
  88                      extract($a);
  89                      populateArticleData($a);
  90  
  91                      $cb = callback_event('rss_entry');
  92  
  93                      $a['posted'] = $uPosted;
  94  
  95                      $permlink = permlinkurl($a);
  96                      $summary = trim(replace_relative_urls(parse($thisarticle['excerpt']), $permlink));
  97                      $content = trim(replace_relative_urls(parse($thisarticle['body']), $permlink));
  98  
  99                      if ($syndicate_body_or_excerpt) {
 100                          # short feed: use body as summary if there's no excerpt
 101                          if (!trim($summary))
 102                              $summary = $content;
 103                          $content = '';
 104                      }
 105  
 106                      if ($show_comment_count_in_feed) {
 107                          $count = ($comments_count > 0) ? ' ['.$comments_count.']' : '';
 108                      } else $count = '';
 109  
 110                      $Title = escape_title(strip_tags($Title)).$count;
 111  
 112                      $thisauthor = get_author_name($AuthorID);
 113  
 114                      $item = tag($Title,'title').n.
 115                          (trim($summary) ? tag(n.escape_cdata($summary).n,'description').n : '').
 116                          (trim($content) ? tag(n.escape_cdata($content).n,'content:encoded').n : '').
 117                          tag($permlink,'link').n.
 118                          tag(safe_strftime('rfc822',$a['posted']),'pubDate').n.
 119                          tag(htmlspecialchars($thisauthor),'dc:creator').n.
 120                          tag('tag:'.$mail_or_domain.','.$feed_time.':'.$blog_uid.'/'.$uid,'guid', ' isPermaLink="false"').n.
 121                          $cb;
 122  
 123                      $articles[$ID] = tag($item,'item');
 124  
 125                      $etags[$ID] = strtoupper(dechex(crc32($articles[$ID])));
 126                      $dates[$ID] = $uPosted;
 127  
 128                  }
 129              }
 130          } elseif ($area=='link') {
 131  
 132              $cfilter = ($category) ? "category in ('".join("','", $category)."')"  : '1';
 133              $limit = ($limit) ? $limit : $rss_how_many;
 134              $limit = intval(min($limit,max(100,$rss_how_many)));
 135  
 136              $rs = safe_rows_start("*, unix_timestamp(date) as uDate", "txp_link", "$cfilter order by date desc limit $limit");
 137  
 138              if ($rs) {
 139                  while ($a = nextRow($rs)) {
 140                      extract($a);
 141                      $item =
 142                          tag(doSpecial($linkname),'title').n.
 143                          tag(doSpecial($description),'description').n.
 144                          tag(doSpecial($url),'link').n.
 145                          tag(safe_strftime('rfc822',$uDate),'pubDate');
 146                      $articles[$id] = tag($item,'item');
 147  
 148                      $etags[$id] = strtoupper(dechex(crc32($articles[$id])));
 149                      $dates[$id] = $date;
 150                  }
 151              }
 152          }
 153  
 154          if (!$articles) {
 155              if ($section) {
 156                  if (safe_field('name', 'txp_section', "name in ('".join("','", $section)."')") == false) {
 157                      txp_die(gTxt('404_not_found'), '404');
 158                  }
 159              } elseif ($category) {
 160                  switch ($area) {
 161                      case 'link':
 162                              if (safe_field('id', 'txp_category', "name = '$category' and type = 'link'") == false) {
 163                                  txp_die(gTxt('404_not_found'), '404');
 164                              }
 165                      break;
 166  
 167                      case 'article':
 168                      default:
 169                              if (safe_field('id', 'txp_category', "name in ('".join("','", $category)."') and type = 'article'") == false) {
 170                                  txp_die(gTxt('404_not_found'), '404');
 171                              }
 172                      break;
 173                  }
 174              }
 175          } else {
 176              //turn on compression if we aren't using it already
 177              if (extension_loaded('zlib') && ini_get("zlib.output_compression") == 0 && ini_get('output_handler') != 'ob_gzhandler' && !headers_sent()) {
 178                  // make sure notices/warnings/errors don't fudge up the feed
 179                  // when compression is used
 180                  $buf = '';
 181                  while ($b = @ob_get_clean())
 182                      $buf .= $b;
 183                  @ob_start('ob_gzhandler');
 184                  echo $buf;
 185              }
 186  
 187              handle_lastmod();
 188              $hims = serverset('HTTP_IF_MODIFIED_SINCE');
 189              $imsd = ($hims) ? strtotime($hims) : 0;
 190  
 191              if (is_callable('apache_request_headers')) {
 192                  $headers = apache_request_headers();
 193                  if (isset($headers["A-IM"])) {
 194                      $canaim = strpos($headers["A-IM"], "feed");
 195                  } else {
 196                      $canaim = false;
 197                  }
 198              } else {
 199                  $canaim = false;
 200              }
 201  
 202              $hinm = stripslashes(serverset('HTTP_IF_NONE_MATCH'));
 203  
 204              $cutarticles = false;
 205  
 206              if ($canaim !== false) {
 207                  foreach($articles as $id=>$thing) {
 208                      if (strpos($hinm, $etags[$id]) !== false) {
 209                          unset($articles[$id]);
 210                          $cutarticles = true;
 211                          $cut_etag = true;
 212                      }
 213  
 214                      if ($dates[$id] < $imsd) {
 215                          unset($articles[$id]);
 216                          $cutarticles = true;
 217                          $cut_time = true;
 218                      }
 219                  }
 220              }
 221  
 222              if (isset($cut_etag) && isset($cut_time)) {
 223                  header("Vary: If-None-Match, If-Modified-Since");
 224              } else if (isset($cut_etag)) {
 225                  header("Vary: If-None-Match");
 226              } else if (isset($cut_time)) {
 227                  header("Vary: If-Modified-Since");
 228              }
 229  
 230              $etag = @join("-",$etags);
 231  
 232              if (strstr($hinm, $etag)) {
 233                  txp_status_header('304 Not Modified');
 234                  exit(0);
 235              }
 236  
 237              if ($cutarticles) {
 238                  //header("HTTP/1.1 226 IM Used");
 239                  //This should be used as opposed to 200, but Apache doesn't like it.
 240                  //http://intertwingly.net/blog/2004/09/11/Vary-ETag/ says that the status code should be 200.
 241                  header("Cache-Control: no-store, im");
 242                  header("IM: feed");
 243              }
 244          }
 245  
 246          $out = array_merge($out, $articles);
 247  
 248          header("Content-Type: application/rss+xml; charset=utf-8");
 249          if (isset($etag)) header('ETag: "'.$etag.'"');
 250          return
 251              '<?xml version="1.0" encoding="utf-8"?>'.n.
 252              '<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.
 253              tag(join(n,$out),'channel').n.
 254              '</rss>';
 255      }
 256  
 257  
 258  // DEPRECATED FUNCTIONS
 259  // included for backwards compatibility with older plugins only
 260  	function rss_safe_hed($toUnicode) {
 261  
 262          if (version_compare(phpversion(), "5.0.0", ">=")) {
 263              $str =  html_entity_decode($toUnicode, ENT_QUOTES, "UTF-8");
 264          } else {
 265              $trans_tbl = get_html_translation_table(HTML_ENTITIES);
 266              foreach($trans_tbl as $k => $v) {
 267                  $ttr[$v] = utf8_encode($k);
 268              }
 269              $str = strtr($toUnicode, $ttr);
 270          }
 271          return $str;
 272      }
 273  
 274  ?>

title

Description

title

Description

title

Description

title

title

Body