<?php if (!defined('PmWiki')) exit();
/*
  PageFeed was first written by Daniel Roesler (diafygi)
  in January 2009. It is released under the Gnu Public
  License version 2. Enjoy!
  <http://www.gnu.org/licenses/gpl-2.0.txt>
  
  Contact:
  <http://pmwiki.org/wiki/Cookbook/PageFeed>
  diafygi (curvy thing) gmail (period) com
  <http://daylightpirates.org/>

  Description:
  PageFeed is a recipe for PmWiki that creates an RSS feed
  from a single wiki page's history, where each edit is
  an entry in the feed. The resulting RSS feed can be
  called by using ?action=pagefeed
  (http://example.com/pmwiki.php?n=Main.HomePage&action=pagefeed)
  or
  (http://example.com/pmwiki.php/Main/HomePage?action=pagefeed if you have $EnablePathInfo=1)

  Installation:
  To enable PageFeed, save this file in your cookbook folder,
  and include the following line in your config.php:
    include_once("$FarmD/cookbook/pagefeed.php");

  Count Option:
  You can define how many items are in the feed (default
  is 25) by adding &count=n to the url, where n is the
  number of items you want to appear.
  (i.e. http://example.com/pmwiki.php?n=Main.HomePage&action=pagefeed&count=10
  will only show the 10 most recent history items)

  Minor Edit Option:
  You can choose to not include minor edits in the page
  feed by turing the minor option to 0 in the feed
  url. By default, PageFeed displays all edits.
  (i.e. http://example.com/pmwiki.php?n=Main.HomePage&action=pagefeed&minor=0
  will only show non-minor feeds)

  Format:
  The format for the feed xml is saved in the template
  $FeedFmt['pagefeed'] and follows the same formatting
  guidelines as PmWiki's feeds.php system (see
  http://pmwiki.org/wiki/PmWiki/WebFeeds)

  There are several special variables you can include
  to make the PageFeed more dynamic. These can be
  included in any part of the $FeedFmt['pagefeed']
  array:
    $FeedRSSTime	Most recent edit in standard UTC format
    $FeedISOTime	Most recent edit in standard ISO time
    $ItemRSSTime	Time of edit in standard UTC format
    $ItemAuthor		Author of edit
    $ItemSummary	Summary of edit
    $ItemDiff		Raw revision data (not recommended for inclusion)
    $ItemUnique		Time of edit in Unix format
    $ItemMinor		"Yes" if edit was minor, "No" if not
    $ItemHost		IP address of author

  You may also use any other PmWiki variables ($FarmD,
  $pagename, etc.), including Page Variables (i.e. 
  {$PageUrl}, {$Title}, etc.)

  For example, each item has a default description of "Author: $ItemAuthor"
  (i.e. $FeedFmt['item']['description']['content'] = 'Author: $ItemAuthor')
*/

## Recipe version information
$RecipeInfo['PageFeed']['Version'] = '2010-03-14';

## PageFeed format
SDVA($FeedFmt['pagefeed']['feed'], array(
  '_count' => 25, '_minor' => 1,
  '_header' => 'Content-type: text/xml; charset="$Charset"',
  '_start' => '<?xml version="1.0" encoding="$Charset"?'.'>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>'."\n",
  '_end' => "</channel>\n</rss>\n",
  'title' => '$WikiTitle | {$Group} / {$Title}',
  'link' => '{$PageUrl}?action=pagefeed',
  'description' => '{$Group}.{$Title}',
  'lastBuildDate' => '$FeedRSSTime'));
SDVA($FeedFmt['pagefeed']['item'], array(
  '_start' => "<item>\n",
  '_end' => "</item>\n",
  'title' => '{$Group} / {$Title} - $ItemSummary',
  'link' => '{$PageUrl}',
  'description' => "Edit by: \$ItemAuthor\nMinor: \$ItemMinor",
  'pubDate' => '$ItemRSSTime',
  'guid' => '{$PageUrl}?action=diff#$ItemUnique'));

## Add action for pagefeed
SDV($HandleActions['pagefeed'], 'PageFeed');

## Create feed from page history
function PageFeed($pagename, $auth = 'read') {
  global $FeedFmt, $FmtV, $EntitiesTable, $TimeISOZFmt, $RSSTimeFmt;
  SDV($RSSTimeFmt, 'D, d M Y H:i:s \G\M\T');
  $f = &$FeedFmt['pagefeed'];

  ## get options
  $count = ($_REQUEST['count'] !== null)
    ? $_REQUEST['count'] : $f['feed']['_count'];
  $minor = ($_REQUEST['minor'] !== null)
    ? $_REQUEST['minor'] : $f['feed']['_minor'];

  ## get page
  $page = RetrieveAuthPage($pagename, $auth, true, 0);
  if (!$page) Abort("?cannot generate feed");

  ## Create feed start
  $time = $page['time'];
  $FmtV['$FeedISOTime'] = gmstrftime($TimeISOZFmt, $time);
  $FmtV['$FeedRSSTime'] = gmdate($RSSTimeFmt, $time);
  $out = FmtPageName($f['feed']['_start'], $pagename);
  foreach($f['feed'] as $k => $v) {
    if ($k[0] == '_' || !$v) continue;
    $x = FmtPageName($v, $pagename);
    if (!$x) continue;
    $out .= ($v[0] == '<') ? $x : "<$k>$x</$k>\n";
  }

  ## Create feed items
  for($n = 0; $n < $count; $n++) {
    $key = '';
    foreach($page as $k => $v) {
      if(preg_match("/diff:$time:/", $k)) {$key = $k; break;} }
    if(!$key) break;

    if(preg_match("/minor/", $key) && !$minor) {
      $time = substr($key,16,10); $n--; continue;
    }
    $FmtV['$ItemMinor'] = (preg_match("/minor/", $key)) ? 'Yes' : 'No';
    $FmtV['$ItemTime'] = $time;
    $FmtV['$ItemUnique'] = "diff".$time;
    $FmtV['$ItemRSSTime'] = gmdate($RSSTimeFmt, $time);
    $FmtV['$ItemAuthor'] = ($page["author:$time"])
      ? $page["author:$time"] : '';
    $FmtV['$ItemSummary'] = ($page["csum:$time"])
      ? $page["csum:$time"] : '';
    $FmtV['$ItemDiff'] = $page[$key];
    $FmtV['$ItemHost'] = ($page["host:$time"])
      ? $page["host:$time"] : '';
    $out .= FmtPageName($f['item']['_start'], $pagename);
    foreach($f['item'] as $k => $v) {
      if ($k[0] == '_' || !$v) continue;
      $x = FmtPageName($v, $pagename);
      if (!$x) continue;
      $out .= ($v[0] == '<') ? $x : "<$k>$x</$k>\n";
    }
    $out .= FmtPageName($f['item']['_end'], $pagename);
    if($time == substr($key,16,10)) break;
    $time = substr($key,16,10);
  }

  ## Create feed end and print
  $out .= FmtPageName($f['feed']['_end'], $pagename);
  foreach((array)@$f['feed']['_header'] as $fmt)
    header(FmtPageName($fmt, $pagename));
  print str_replace(array_keys($EntitiesTable), array_values($EntitiesTable), $out);
}

## Since most feeds don't understand html character entities, we
## convert the common ones to their numeric form here.
## Taken from /scripts/feeds.php
SDVA($EntitiesTable, array(
  # entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent"
  '&nbsp;' => '&#160;', 
  '&iexcl;' => '&#161;', 
  '&cent;' => '&#162;', 
  '&pound;' => '&#163;', 
  '&curren;' => '&#164;', 
  '&yen;' => '&#165;', 
  '&brvbar;' => '&#166;', 
  '&sect;' => '&#167;', 
  '&uml;' => '&#168;', 
  '&copy;' => '&#169;', 
  '&ordf;' => '&#170;', 
  '&laquo;' => '&#171;', 
  '&not;' => '&#172;', 
  '&shy;' => '&#173;', 
  '&reg;' => '&#174;', 
  '&macr;' => '&#175;', 
  '&deg;' => '&#176;', 
  '&plusmn;' => '&#177;', 
  '&sup2;' => '&#178;', 
  '&sup3;' => '&#179;', 
  '&acute;' => '&#180;', 
  '&micro;' => '&#181;', 
  '&para;' => '&#182;', 
  '&middot;' => '&#183;', 
  '&cedil;' => '&#184;', 
  '&sup1;' => '&#185;', 
  '&ordm;' => '&#186;', 
  '&raquo;' => '&#187;', 
  '&frac14;' => '&#188;', 
  '&frac12;' => '&#189;', 
  '&frac34;' => '&#190;', 
  '&iquest;' => '&#191;', 
  '&Agrave;' => '&#192;', 
  '&Aacute;' => '&#193;', 
  '&Acirc;' => '&#194;', 
  '&Atilde;' => '&#195;', 
  '&Auml;' => '&#196;', 
  '&Aring;' => '&#197;', 
  '&AElig;' => '&#198;', 
  '&Ccedil;' => '&#199;', 
  '&Egrave;' => '&#200;', 
  '&Eacute;' => '&#201;', 
  '&Ecirc;' => '&#202;', 
  '&Euml;' => '&#203;', 
  '&Igrave;' => '&#204;', 
  '&Iacute;' => '&#205;', 
  '&Icirc;' => '&#206;', 
  '&Iuml;' => '&#207;', 
  '&ETH;' => '&#208;', 
  '&Ntilde;' => '&#209;', 
  '&Ograve;' => '&#210;', 
  '&Oacute;' => '&#211;', 
  '&Ocirc;' => '&#212;', 
  '&Otilde;' => '&#213;', 
  '&Ouml;' => '&#214;', 
  '&times;' => '&#215;', 
  '&Oslash;' => '&#216;', 
  '&Ugrave;' => '&#217;', 
  '&Uacute;' => '&#218;', 
  '&Ucirc;' => '&#219;', 
  '&Uuml;' => '&#220;', 
  '&Yacute;' => '&#221;', 
  '&THORN;' => '&#222;', 
  '&szlig;' => '&#223;', 
  '&agrave;' => '&#224;', 
  '&aacute;' => '&#225;', 
  '&acirc;' => '&#226;', 
  '&atilde;' => '&#227;', 
  '&auml;' => '&#228;', 
  '&aring;' => '&#229;', 
  '&aelig;' => '&#230;', 
  '&ccedil;' => '&#231;', 
  '&egrave;' => '&#232;', 
  '&eacute;' => '&#233;', 
  '&ecirc;' => '&#234;', 
  '&euml;' => '&#235;', 
  '&igrave;' => '&#236;', 
  '&iacute;' => '&#237;', 
  '&icirc;' => '&#238;', 
  '&iuml;' => '&#239;', 
  '&eth;' => '&#240;', 
  '&ntilde;' => '&#241;', 
  '&ograve;' => '&#242;', 
  '&oacute;' => '&#243;', 
  '&ocirc;' => '&#244;', 
  '&otilde;' => '&#245;', 
  '&ouml;' => '&#246;', 
  '&divide;' => '&#247;', 
  '&oslash;' => '&#248;', 
  '&ugrave;' => '&#249;', 
  '&uacute;' => '&#250;', 
  '&ucirc;' => '&#251;', 
  '&uuml;' => '&#252;', 
  '&yacute;' => '&#253;', 
  '&thorn;' => '&#254;', 
  '&yuml;' => '&#255;', 
  # entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent"
  '&quot;' => '&#34;', 
  #'&amp;' => '&#38;#38;', 
  #'&lt;' => '&#38;#60;', 
  #'&gt;' => '&#62;', 
  '&apos;' => '&#39;', 
  '&OElig;' => '&#338;', 
  '&oelig;' => '&#339;', 
  '&Scaron;' => '&#352;', 
  '&scaron;' => '&#353;', 
  '&Yuml;' => '&#376;', 
  '&circ;' => '&#710;', 
  '&tilde;' => '&#732;', 
  '&ensp;' => '&#8194;', 
  '&emsp;' => '&#8195;', 
  '&thinsp;' => '&#8201;', 
  '&zwnj;' => '&#8204;', 
  '&zwj;' => '&#8205;', 
  '&lrm;' => '&#8206;', 
  '&rlm;' => '&#8207;', 
  '&ndash;' => '&#8211;', 
  '&mdash;' => '&#8212;', 
  '&lsquo;' => '&#8216;', 
  '&rsquo;' => '&#8217;', 
  '&sbquo;' => '&#8218;', 
  '&ldquo;' => '&#8220;', 
  '&rdquo;' => '&#8221;', 
  '&bdquo;' => '&#8222;', 
  '&dagger;' => '&#8224;', 
  '&Dagger;' => '&#8225;', 
  '&permil;' => '&#8240;', 
  '&lsaquo;' => '&#8249;', 
  '&rsaquo;' => '&#8250;', 
  '&euro;' => '&#8364;', 
  # entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent"
  '&fnof;' => '&#402;', 
  '&Alpha;' => '&#913;', 
  '&Beta;' => '&#914;', 
  '&Gamma;' => '&#915;', 
  '&Delta;' => '&#916;', 
  '&Epsilon;' => '&#917;', 
  '&Zeta;' => '&#918;', 
  '&Eta;' => '&#919;', 
  '&Theta;' => '&#920;', 
  '&Iota;' => '&#921;', 
  '&Kappa;' => '&#922;', 
  '&Lambda;' => '&#923;', 
  '&Mu;' => '&#924;', 
  '&Nu;' => '&#925;', 
  '&Xi;' => '&#926;', 
  '&Omicron;' => '&#927;', 
  '&Pi;' => '&#928;', 
  '&Rho;' => '&#929;', 
  '&Sigma;' => '&#931;', 
  '&Tau;' => '&#932;', 
  '&Upsilon;' => '&#933;', 
  '&Phi;' => '&#934;', 
  '&Chi;' => '&#935;', 
  '&Psi;' => '&#936;', 
  '&Omega;' => '&#937;', 
  '&alpha;' => '&#945;', 
  '&beta;' => '&#946;', 
  '&gamma;' => '&#947;', 
  '&delta;' => '&#948;', 
  '&epsilon;' => '&#949;', 
  '&zeta;' => '&#950;', 
  '&eta;' => '&#951;', 
  '&theta;' => '&#952;', 
  '&iota;' => '&#953;', 
  '&kappa;' => '&#954;', 
  '&lambda;' => '&#955;', 
  '&mu;' => '&#956;', 
  '&nu;' => '&#957;', 
  '&xi;' => '&#958;', 
  '&omicron;' => '&#959;', 
  '&pi;' => '&#960;', 
  '&rho;' => '&#961;', 
  '&sigmaf;' => '&#962;', 
  '&sigma;' => '&#963;', 
  '&tau;' => '&#964;', 
  '&upsilon;' => '&#965;', 
  '&phi;' => '&#966;', 
  '&chi;' => '&#967;', 
  '&psi;' => '&#968;', 
  '&omega;' => '&#969;', 
  '&thetasym;' => '&#977;', 
  '&upsih;' => '&#978;', 
  '&piv;' => '&#982;', 
  '&bull;' => '&#8226;', 
  '&hellip;' => '&#8230;', 
  '&prime;' => '&#8242;', 
  '&Prime;' => '&#8243;', 
  '&oline;' => '&#8254;', 
  '&frasl;' => '&#8260;', 
  '&weierp;' => '&#8472;', 
  '&image;' => '&#8465;', 
  '&real;' => '&#8476;', 
  '&trade;' => '&#8482;', 
  '&alefsym;' => '&#8501;', 
  '&larr;' => '&#8592;', 
  '&uarr;' => '&#8593;', 
  '&rarr;' => '&#8594;', 
  '&darr;' => '&#8595;', 
  '&harr;' => '&#8596;', 
  '&crarr;' => '&#8629;', 
  '&lArr;' => '&#8656;', 
  '&uArr;' => '&#8657;', 
  '&rArr;' => '&#8658;', 
  '&dArr;' => '&#8659;', 
  '&hArr;' => '&#8660;', 
  '&forall;' => '&#8704;', 
  '&part;' => '&#8706;', 
  '&exist;' => '&#8707;', 
  '&empty;' => '&#8709;', 
  '&nabla;' => '&#8711;', 
  '&isin;' => '&#8712;', 
  '&notin;' => '&#8713;', 
  '&ni;' => '&#8715;', 
  '&prod;' => '&#8719;', 
  '&sum;' => '&#8721;', 
  '&minus;' => '&#8722;', 
  '&lowast;' => '&#8727;', 
  '&radic;' => '&#8730;', 
  '&prop;' => '&#8733;', 
  '&infin;' => '&#8734;', 
  '&ang;' => '&#8736;', 
  '&and;' => '&#8743;', 
  '&or;' => '&#8744;', 
  '&cap;' => '&#8745;', 
  '&cup;' => '&#8746;', 
  '&int;' => '&#8747;', 
  '&there4;' => '&#8756;', 
  '&sim;' => '&#8764;', 
  '&cong;' => '&#8773;', 
  '&asymp;' => '&#8776;', 
  '&ne;' => '&#8800;', 
  '&equiv;' => '&#8801;', 
  '&le;' => '&#8804;', 
  '&ge;' => '&#8805;', 
  '&sub;' => '&#8834;', 
  '&sup;' => '&#8835;', 
  '&nsub;' => '&#8836;', 
  '&sube;' => '&#8838;', 
  '&supe;' => '&#8839;', 
  '&oplus;' => '&#8853;', 
  '&otimes;' => '&#8855;', 
  '&perp;' => '&#8869;', 
  '&sdot;' => '&#8901;', 
  '&lceil;' => '&#8968;', 
  '&rceil;' => '&#8969;', 
  '&lfloor;' => '&#8970;', 
  '&rfloor;' => '&#8971;', 
  '&lang;' => '&#9001;', 
  '&rang;' => '&#9002;', 
  '&loz;' => '&#9674;', 
  '&spades;' => '&#9824;', 
  '&clubs;' => '&#9827;', 
  '&hearts;' => '&#9829;', 
  '&diams;' => '&#9830;'));