'Content-type: text/xml; charset="$Charset"', '_start' => ' '."\n", '_end' => "\n", 'title' => '$WikiTitle', 'link' => '', 'id' => '{$PageUrl}?action=atom', 'updated' => '$FeedISOTime', 'author' => "$WikiTitle\n", 'generator' => '$Version', 'logo' => '$PageLogoUrl')); SDVA($FeedFmt['atom']['item'], array( '_start' => "\n", 'id' => '{$PageUrl}', 'title' => '{$Title}', 'updated' => '$ItemISOTime', 'link' => "\n", 'author' => "{\$LastModifiedBy}\n", 'summary' => '{$Description}', 'category' => "\n", '_end' => "\n")); ## Settings for ?action=dc SDVA($FeedFmt['dc']['feed'], array( '_header' => 'Content-type: text/xml; charset="$Charset"', '_start' => ' '."\n", '_end' => "\n")); SDVA($FeedFmt['dc']['item'], array( '_start' => "\n", 'dc:title' => '{$Title}', 'dc:identifier' => '{$PageUrl}', 'dc:date' => '$ItemISOTime', 'dc:type' => 'Text', 'dc:format' => 'text/html', 'dc:description' => '{$Description}', 'dc:subject' => "\$Category\n", 'dc:publisher' => '$WikiTitle', 'dc:author' => '{$LastModifiedBy}', '_end' => "\n")); ## RSS 2.0 settings for ?action=rss SDVA($FeedFmt['rss']['feed'], array( '_header' => 'Content-type: text/xml; charset="$Charset"', '_start' => ' '."\n", '_end' => "\n\n", 'title' => '$WikiTitle | {$Group} / {$Title}', 'link' => '{$PageUrl}?action=rss', 'description' => '{$Group}.{$Title}', 'lastBuildDate' => '$FeedRSSTime')); SDVA($FeedFmt['rss']['item'], array( '_start' => "\n", '_end' => "\n", 'title' => '{$Group} / {$Title}', 'link' => '{$PageUrl}', 'description' => '{$Description}', 'dc:contributor' => '{$LastModifiedBy}', 'dc:date' => '$ItemISOTime', 'pubDate' => '$ItemRSSTime', 'enclosure' => 'RSSEnclosure')); ## RDF 1.0, for ?action=rdf SDVA($FeedFmt['rdf']['feed'], array( '_header' => 'Content-type: text/xml; charset="$Charset"', '_start' => ' '."\n", 'title' => '$WikiTitle | {$Group} / {$Title}', 'link' => '{$PageUrl}?action=rdf', 'description' => '{$Group}.{$Title}', 'dc:date' => '$FeedISOTime', 'items' => "\n\n\$FeedRDFSeq\n\n", '_items' => "\n", '_end' => "\n")); SDVA($FeedFmt['rdf']['item'], array( '_start' => "\n", '_end' => "\n", 'title' => '$WikiTitle | {$Group} / {$Title}', 'link' => '{$PageUrl}', 'description' => '{$Description}', 'dc:date' => '$ItemISOTime')); foreach(array_keys($FeedFmt) as $k) { SDV($HandleActions[$k], 'HandleFeed'); SDV($HandleAuth[$k], 'read'); } function HandleFeed($pagename, $auth = 'read') { global $FeedFmt, $action, $PCache, $FmtV, $TimeISOZFmt, $RSSTimeFmt, $FeedPageListOpt, $FeedCategoryOpt, $FeedTrailOpt, $FeedDescPatterns, $CategoryGroup, $EntitiesTable; SDV($RSSTimeFmt, 'D, d M Y H:i:s \G\M\T'); SDV($FeedDescPatterns, array('/<[^>]*$/' => ' ', '/\\w+$/' => '', '/<[^>]+>/' => '')); $FeedPageListOpt = (array)@$FeedPageListOpt; SDVA($FeedCategoryOpt, array('link' => $pagename)); SDVA($FeedTrailOpt, array('trail' => $pagename, 'count' => 10)); $f = $FeedFmt[$action]; $page = RetrieveAuthPage($pagename, $auth, true, READPAGE_CURRENT); if (!$page) Abort("?cannot generate feed"); $feedtime = $page['time']; # determine list of pages to display if (@($_REQUEST['trail'] || $_REQUEST['group'] || $_REQUEST['link'] || $_REQUEST['name'])) $opt = $FeedPageListOpt; else if (preg_match("/^$CategoryGroup\\./", $pagename)) $opt = $FeedCategoryOpt; else if ($action != 'dc') $opt = $FeedTrailOpt; else { PCache($pagename, $page); $pagelist = array($pagename); } if (!@$pagelist) { $opt = array_merge($opt, @$_REQUEST); $pagelist = MakePageList($pagename, $opt, 0); } # process list of pages in feed $rdfseq = ''; $pl = array(); foreach($pagelist as $pn) { if (!PageExists($pn)) continue; if (!isset($PCache[$pn]['time'])) { $page = ReadPage($pn, READPAGE_CURRENT); PCache($pn, $page); } $pc = & $PCache[$pn]; $pl[] = $pn; if (@$opt['count'] && count($pl) >= $opt['count']) break; $rdfseq .= FmtPageName("\n", $pn); if ($pc['time'] > $feedtime) $feedtime = $pc['time']; } $pagelist = $pl; $FmtV['$FeedRDFSeq'] = $rdfseq; $FmtV['$FeedISOTime'] = gmstrftime($TimeISOZFmt, $feedtime); $FmtV['$FeedRSSTime'] = gmdate($RSSTimeFmt, $feedtime); # format start of feed $out = FmtPageName($f['feed']['_start'], $pagename); # format feed elements foreach($f['feed'] as $k => $v) { if ($k{0} == '_' || !$v) continue; $x = FmtPageName($v, $pagename); if (!$x) continue; $out .= ($v{0} == '<') ? $x : "<$k>$x\n"; } # format items in feed if (@$f['feed']['_items']) $out .= FmtPageName($f['feed']['_items'], $pagename); foreach($pagelist as $pn) { $page = &$PCache[$pn]; $FmtV['$ItemDesc'] = @$page['description']; $FmtV['$ItemISOTime'] = gmstrftime($TimeISOZFmt, $page['time']); $FmtV['$ItemRSSTime'] = gmdate($RSSTimeFmt, $page['time']); ## SMC: only deal with pages that have lat/lng info if (empty($page['latitude'])) continue; ## /SMC $out .= FmtPageName($f['item']['_start'], $pn); foreach((array)@$f['item'] as $k => $v) { if ($k{0} == '_' || !$v) continue; if (is_callable($v)) { $out .= $v($pn, $page, $k); continue; } if (strpos($v, '$LastModifiedBy') !== false && !@$page['author']) continue; if (strpos($v, '$Category') !== false) { if (preg_match_all("/(?<=^|,)$CategoryGroup\\.([^,]+)/", @$page['targets'], $match)) { foreach($match[1] as $c) { $FmtV['$Category'] = $c; $out .= FmtPageName($v, $pn); } } continue; } $x = FmtPageName($v, $pn); if (!$x) continue; $out .= ($v{0} == '<') ? $x : "<$k>$x\n"; } $out .= FmtPageName($f['item']['_end'], $pn); } $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); } ## RSSEnclosure is called in ?action=rss to generate ## tags for any pages that have an attached "PageName.mp3" file. ## The set of attachments to enclose is given by $RSSEnclosureFmt. function RSSEnclosure($pagename, &$page, $k) { global $RSSEnclosureFmt, $UploadFileFmt, $UploadExts; if (!function_exists('MakeUploadName')) return ''; SDV($RSSEnclosureFmt, array('{$Name}.mp3')); $encl = ''; foreach((array)$RSSEnclosureFmt as $fmt) { $path = FmtPageName($fmt, $pagename); $upname = MakeUploadName($pagename, $path); $filepath = FmtPageName("$UploadFileFmt/$upname", $pagename); if (file_exists($filepath)) { $length = filesize($filepath); $type = @$UploadExts[preg_replace('/.*\\./', '', $filepath)]; $url = LinkUpload($pagename, 'Attach:', $path, '', '', '$LinkUrl'); $encl .= "<$k url='$url' length='$length' type='$type' />"; } } return $encl; } ## Since most feeds don't understand html character entities, we ## convert the common ones to their numeric form here. SDVA($EntitiesTable, array( # entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent" ' ' => ' ', '¡' => '¡', '¢' => '¢', '£' => '£', '¤' => '¤', '¥' => '¥', '¦' => '¦', '§' => '§', '¨' => '¨', '©' => '©', 'ª' => 'ª', '«' => '«', '¬' => '¬', '­' => '­', '®' => '®', '¯' => '¯', '°' => '°', '±' => '±', '²' => '²', '³' => '³', '´' => '´', 'µ' => 'µ', '¶' => '¶', '·' => '·', '¸' => '¸', '¹' => '¹', 'º' => 'º', '»' => '»', '¼' => '¼', '½' => '½', '¾' => '¾', '¿' => '¿', 'À' => 'À', 'Á' => 'Á', 'Â' => 'Â', 'Ã' => 'Ã', 'Ä' => 'Ä', 'Å' => 'Å', 'Æ' => 'Æ', 'Ç' => 'Ç', 'È' => 'È', 'É' => 'É', 'Ê' => 'Ê', 'Ë' => 'Ë', 'Ì' => 'Ì', 'Í' => 'Í', 'Î' => 'Î', 'Ï' => 'Ï', 'Ð' => 'Ð', 'Ñ' => 'Ñ', 'Ò' => 'Ò', 'Ó' => 'Ó', 'Ô' => 'Ô', 'Õ' => 'Õ', 'Ö' => 'Ö', '×' => '×', 'Ø' => 'Ø', 'Ù' => 'Ù', 'Ú' => 'Ú', 'Û' => 'Û', 'Ü' => 'Ü', 'Ý' => 'Ý', 'Þ' => 'Þ', 'ß' => 'ß', 'à' => 'à', 'á' => 'á', 'â' => 'â', 'ã' => 'ã', 'ä' => 'ä', 'å' => 'å', 'æ' => 'æ', 'ç' => 'ç', 'è' => 'è', 'é' => 'é', 'ê' => 'ê', 'ë' => 'ë', 'ì' => 'ì', 'í' => 'í', 'î' => 'î', 'ï' => 'ï', 'ð' => 'ð', 'ñ' => 'ñ', 'ò' => 'ò', 'ó' => 'ó', 'ô' => 'ô', 'õ' => 'õ', 'ö' => 'ö', '÷' => '÷', 'ø' => 'ø', 'ù' => 'ù', 'ú' => 'ú', 'û' => 'û', 'ü' => 'ü', 'ý' => 'ý', 'þ' => 'þ', 'ÿ' => 'ÿ', # entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent" '"' => '"', #'&' => '&#38;', #'<' => '&#60;', #'>' => '>', ''' => ''', 'Œ' => 'Œ', 'œ' => 'œ', 'Š' => 'Š', 'š' => 'š', 'Ÿ' => 'Ÿ', 'ˆ' => 'ˆ', '˜' => '˜', ' ' => ' ', ' ' => ' ', ' ' => ' ', '‌' => '‌', '‍' => '‍', '‎' => '‎', '‏' => '‏', '–' => '–', '—' => '—', '‘' => '‘', '’' => '’', '‚' => '‚', '“' => '“', '”' => '”', '„' => '„', '†' => '†', '‡' => '‡', '‰' => '‰', '‹' => '‹', '›' => '›', '€' => '€', # entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent" 'ƒ' => 'ƒ', 'Α' => 'Α', 'Β' => 'Β', 'Γ' => 'Γ', 'Δ' => 'Δ', 'Ε' => 'Ε', 'Ζ' => 'Ζ', 'Η' => 'Η', 'Θ' => 'Θ', 'Ι' => 'Ι', 'Κ' => 'Κ', 'Λ' => 'Λ', 'Μ' => 'Μ', 'Ν' => 'Ν', 'Ξ' => 'Ξ', 'Ο' => 'Ο', 'Π' => 'Π', 'Ρ' => 'Ρ', 'Σ' => 'Σ', 'Τ' => 'Τ', 'Υ' => 'Υ', 'Φ' => 'Φ', 'Χ' => 'Χ', 'Ψ' => 'Ψ', 'Ω' => 'Ω', 'α' => 'α', 'β' => 'β', 'γ' => 'γ', 'δ' => 'δ', 'ε' => 'ε', 'ζ' => 'ζ', 'η' => 'η', 'θ' => 'θ', 'ι' => 'ι', 'κ' => 'κ', 'λ' => 'λ', 'μ' => 'μ', 'ν' => 'ν', 'ξ' => 'ξ', 'ο' => 'ο', 'π' => 'π', 'ρ' => 'ρ', 'ς' => 'ς', 'σ' => 'σ', 'τ' => 'τ', 'υ' => 'υ', 'φ' => 'φ', 'χ' => 'χ', 'ψ' => 'ψ', 'ω' => 'ω', 'ϑ' => 'ϑ', 'ϒ' => 'ϒ', 'ϖ' => 'ϖ', '•' => '•', '…' => '…', '′' => '′', '″' => '″', '‾' => '‾', '⁄' => '⁄', '℘' => '℘', 'ℑ' => 'ℑ', 'ℜ' => 'ℜ', '™' => '™', 'ℵ' => 'ℵ', '←' => '←', '↑' => '↑', '→' => '→', '↓' => '↓', '↔' => '↔', '↵' => '↵', '⇐' => '⇐', '⇑' => '⇑', '⇒' => '⇒', '⇓' => '⇓', '⇔' => '⇔', '∀' => '∀', '∂' => '∂', '∃' => '∃', '∅' => '∅', '∇' => '∇', '∈' => '∈', '∉' => '∉', '∋' => '∋', '∏' => '∏', '∑' => '∑', '−' => '−', '∗' => '∗', '√' => '√', '∝' => '∝', '∞' => '∞', '∠' => '∠', '∧' => '∧', '∨' => '∨', '∩' => '∩', '∪' => '∪', '∫' => '∫', '∴' => '∴', '∼' => '∼', '≅' => '≅', '≈' => '≈', '≠' => '≠', '≡' => '≡', '≤' => '≤', '≥' => '≥', '⊂' => '⊂', '⊃' => '⊃', '⊄' => '⊄', '⊆' => '⊆', '⊇' => '⊇', '⊕' => '⊕', '⊗' => '⊗', '⊥' => '⊥', '⋅' => '⋅', '⌈' => '⌈', '⌉' => '⌉', '⌊' => '⌊', '⌋' => '⌋', '⟨' => '〈', '⟩' => '〉', '◊' => '◊', '♠' => '♠', '♣' => '♣', '♥' => '♥', '♦' => '♦'));