function processor_folding($formatter, $value = "", $options = array()) { // unique id of the folding area $id = isset($GLOBALS['_folding_id_']) ? $GLOBALS['_folding_id_'] : 0; $id++; $GLOBALS['_folding_id_'] = $id; if ($value[0] == '#' and $value[1] == '!') { list($line, $value) = explode("\n", $value, 2); } $init_state = 'none'; $title = _("More"); $class = ''; $opened = ''; // parse args if (isset($line[0]) and ($p = strpos($line, ' ')) !== false) { $tag = substr($line, 0, $p); $args = substr($line, $p + 1); if (preg_match("/^(?:(open|\\+))?(?(1)[ ]*,[ ]*)?((?:(?:[a-zA-Z][a-z0-9_-]+)[ ]*)*)?(?(2)[ ]*,[ ]*)?/", $args, $matches)) { $class = isset($matches[2][0]) ? ' ' . $matches[2] : ''; $tmp = substr($args, strlen($matches[0])); if (isset($tmp[0])) { $title = $tmp; } if ($matches[1] == 'open' or $matches[1] == '+') { $init_state = 'block'; $opened = ' class="opened"'; } } } // FIXME footnote prefix $fn_prefix = 'fn' . substr(md5(substr($value, 0, 32)), 0, 3); // allow wiki syntax in folding content ob_start(); $params = array('notoc' => 1); $params['nosisters'] = 1; $f = new Formatter($formatter->page, $params); $f->foot_prefix = $fn_prefix; $f->get_javascripts(); // trash default javascripts $f->pi['#linenum'] = 0; // do not use linenum $f->send_page($value, $params); $out = ob_get_contents(); ob_end_clean(); $onclick = " onclick=\"var f=document.getElementById('folding_{$id}');var s=f.style.display=='block';" . "f.style.display=s?'none':'block';this.className=s?'':'opened';\""; return <<<HERE <div class="folding-area{$class}"> <dl class="folding"> <dt{$onclick}{$opened}>{$title}</dt> <dd id="folding_{$id}" style="display:{$init_state};">{$out}</dd> </dl> </div> HERE; }
function do_new($formatter, $options) { global $DBInfo; if (!$options['value']) { $title = _("Create a new page"); $formatter->send_header("", $options); $formatter->send_title($title, "", $options); $url = $formatter->link_url($formatter->page->urlname); if ($DBInfo->hasPage('MyNewPage')) { $p = $DBInfo->getPage('MyNewPage'); $f = new Formatter($p, $options); $f->use_rating = 0; $f->send_page('', $options); } $msg = _("Page Name"); $fixname = _("Normalize this page name"); $btn = _("Create a new page"); print <<<FORM <div class='addPage'> <form method='get' action='{$url}'> <table style='border:0'><tr><th class='addLabel'><labe>{$msg}: </label></th><td><input type='hidden' name='action' value='new' /> <input name='value' size='30' /></td></tr> <tr><th class='addLabel'><input type='checkbox' name='fixname' checked='checked' /></th><td>{$fixname}</td></tr> <td></td><td><input type='submit' value='{$btn}' /></td> </tr></table> </form> </div> FORM; $formatter->send_footer(); } else { $pgname = $options['value']; if ($options['fixname']) { $pgname = normalize($pgname); } $options['page'] = $pgname; $page = new WikiPage($pgname); $f = new Formatter($page, $options); do_edit($f, $options); return true; } }
function generate_item($formatter, $log) { global $DBInfo; list($page, $user, $date, $title, $summary) = $log; if (!$title) { return ""; } $url = qualifiedUrl($formatter->link_url(_urlencode($page))); /* perma link */ $tag = md5($user . ' ' . $date . ' ' . $title); /* RFC 822 date format for RSS 2.0 */ $date[10] = ' '; $pubDate = gmdate('D, j M Y H:i:s T', strtotime(substr($date, 0, 19) . ' GMT')); /* description */ if ($summary) { $p = new WikiPage($page); $f = new Formatter($p); $summary = str_replace('\\}}}', '}}}', $summary); ob_start(); $f->send_page($summary, array('fixpath' => 1, 'nojavascript' => 1)); $description = '<description><![CDATA[' . ob_get_contents() . ']]></description>'; ob_end_clean(); } /* convert special characters into HTML entities */ $title = htmlspecialchars($title); return <<<ITEM <item> <title>{$title}</title> <link>{$url}#{$tag}</link> <guid isPermaLink="true">{$url}#{$tag}</guid> {$description} <pubDate>{$pubDate}</pubDate> <author>{$user}</author> <category domain="{$url}">{$page}</category> <comments><![CDATA[{$url}?action=blog&value={$tag}#BlogComment]]></comments> </item> ITEM; }
function macro_Include($formatter, $value = '') { global $DBInfo; if (!isset($GLOBALS['_included_'])) { $GLOBALS['_included_'] = array(); } $max_recursion = isset($DBInfo->include_max_recursion) ? $DBinfo->include_max_recursion : 2; $included =& $GLOBALS['_included_']; // <<Include("Page Name", arg="1", arg2="2", ...)>> // parse variables preg_match("/^(['\"])?(?(1)(?:[^'\"]|\\\\['\"])*(?1)|[^,]*)/", $value, $m); $vars = array(); $pagename = ''; $class = ''; $style = ''; $styles = array(); $title = ''; $debug = false; if ($m) { $pagename = $m[0]; // first arg is page name // detect recursive include if (in_array($pagename, $included)) { if (isset($formatter->recursion) and $formatter->recursion > $max_recursion) { return ''; } } else { $included[] = $pagename; } $last = substr($value, strlen($m[0])); $i = 1; while (isset($last[0])) { if (preg_match("/^(?:(?:\\s*,\\s*)(?:([a-zA-Z0-9_-]+)\\s*=\\s*)?(['\"])?((?(2)(?:[^'\"]|\\\\['\"])*(?2)|[^,]*)))/", $last, $m)) { $last = substr($last, strlen($m[0])); $key = strtolower($m[1]); $val = !empty($m[2]) ? substr($m[3], 0, -1) : $m[3]; // check some built-in vars // set style or class if (in_array($key, array('style', 'class', 'debug'))) { if (empty($val)) { continue; } if ($key == 'style') { $styles[] = $val; } else { if ($key == 'class') { $class .= ' ' . $val; } else { $debug = true; } } continue; } if (empty($key) and $i < 3) { if ($i == 1) { $title = $val; } else { $level = intval($val); } $i++; continue; } if (!empty($key)) { $vars[$key] = $val; } else { $vars[$i] = $val; } $i++; } else { break; } } } if (!isset($pagename[0])) { return ''; } // empty page // out debug msg; $msg = ''; if ($debug) { ob_start(); var_dump($vars); $msg = ob_get_contents(); ob_end_clean(); } // set title if (isset($title[0]) && $title[0] != '=') { if (empty($level) || $level > 5) { $level = 3; } $tag = str_repeat('=', $level); $title = $tag . ' ' . $title . ' ' . $tag; } if ($DBInfo->hasPage($pagename)) { // default class for template if (!empty($vars)) { $class .= ' template'; } // add some default variables if (!isset($vars['pagename'])) { $vars['pagename'] = $formatter->page->name; } $repl = new _localDict($vars); $page = $DBInfo->getPage($pagename); $f = new Formatter($page); // for recursion detect $f->recursion = isset($formatter->recursion) ? $formatter->recursion + 1 : 1; $body = $page->_get_raw_body(); // get raw body // mediawiki like replace variables // @foo@ or @foo[separator]default value@ are accepted // the separator can be space , and | $body = $repl->replace('/@([a-z0-9_-]+)(?:(?:,|\\|)((?!\\s)(?:[^@]|@@)*(?!\\s)))?@/', $body); if (isset($title[0])) { $body = $title . "\n" . $body; } $params['nosisters'] = 1; $f->get_javascripts(); // trash default javascripts ob_start(); $f->pi['#linenum'] = 0; // FIXME $f->send_page($body, $params); $out = ob_get_contents(); ob_end_clean(); if (!empty($class)) { $class = ' class="' . $class . '"'; } if (!empty($styles)) { $style = ' style="' . implode(';', $styles) . '"'; } return '<div' . $class . $style . '>' . $msg . $out . '</div>'; } else { return $formatter->link_repl($pagename); } }
function do_rss_rc($formatter, $options) { global $DBInfo, $Config; // get members to hide log $members = $DBInfo->members; $days = !empty($DBInfo->rc_days) ? $DBInfo->rc_days : RSS_DEFAULT_DAYS; $options['quick'] = 1; if (!empty($options['c'])) { $options['items'] = $options['c']; } $lines = $DBInfo->editlog_raw_lines($days, $options); if (!empty($DBInfo->rss_rc_options)) { $opts = $DBInfo->rss_rc_options; $opts = explode(',', $opts); foreach ($opts as $opt) { $options[$opt] = 1; // FIXME } } // HTTP conditional get $mtime = $DBInfo->mtime(); $lastmod = gmdate('D, d M Y H:i:s \\G\\M\\T', $mtime); $cache_ttl = !empty($DBInfo->rss_rc_ttl) ? $DBInfo->rss_rc_ttl : 60; /* 60 seconds */ // make etag based on some options and mtime. $check_opts = array('quick', 'items', 'oe', 'diffs', 'raw', 'nomsg', 'summary'); $check = array(); foreach ($check_opts as $c) { if (isset($options[$c])) { $check[$c] = $options[$c]; } } $etag = md5($mtime . $DBInfo->logo_img . serialize($check) . $cache_ttl . $options['id']); $headers = array(); $headers[] = 'Pragma: cache'; $maxage = $cache_ttl; $public = 'public'; if ($options['id'] != 'Anonymous') { $public = 'private'; } $headers[] = 'Cache-Control: ' . $public . ', max-age=' . $maxage; $headers[] = 'Last-Modified: ' . $lastmod; $headers[] = 'ETag: "' . $etag . '"'; $need = http_need_cond_request($mtime, $lastmod, $etag); if (!$need) { $headers[] = 'HTTP/1.0 304 Not Modified'; } foreach ($headers as $h) { header($h); } if (!$need) { @ob_end_clean(); return; } $cache = new Cache_Text('rss_rc'); $cache_delay = min($cache_ttl, 30); $mtime = $cache->mtime($etag); $val = false; if (empty($formatter->refresh)) { if (($val = $cache->fetch($etag)) !== false and $DBInfo->checkUpdated($mtime, $cache_delay)) { header("Content-Type: text/xml"); echo $val; return; } } // need to update cache if ($val !== false and $cache->exists($etag . '.lock')) { header("Content-Type: text/xml"); echo $val . '<!-- cached at ' . date('Y-m-d H:i:s', $mtime) . ' -->'; return; } if ($cache->exists($etag . '.lock')) { header("Content-Type: text/xml"); echo ''; return; } $cache->update($etag . '.lock', array('lock'), 5); // 5s lock $time_current = time(); # $secs_per_day= 60*60*24; # $days_to_show= 30; # $time_cutoff= $time_current - ($days_to_show * $secs_per_day); $URL = qualifiedURL($formatter->prefix); $img_url = qualifiedURL($DBInfo->logo_img); $url = qualifiedUrl($formatter->link_url("RecentChanges")); $channel = <<<CHANNEL <channel rdf:about="{$URL}"> <title>{$DBInfo->sitename}</title> <link>{$url}</link> <description>RecentChanges at {$DBInfo->sitename}</description> <image rdf:resource="{$img_url}"></image> <items> <rdf:Seq> CHANNEL; $items = ""; $ratchet_day = FALSE; if (!$lines) { $lines = array(); } foreach ($lines as $line) { $parts = explode("\t", $line); $page_name = $DBInfo->keyToPagename($parts[0]); // hide log if (!empty($members) && !in_array($options['id'], $members) && !empty($Config['ruleset']['hidelog'])) { if (in_array($page_name, $Config['ruleset']['hidelog'])) { continue; } } $addr = $parts[1]; $ed_time = $parts[2]; $user = $parts[4]; $log = _stripslashes($parts[5]); $act = rtrim($parts[6]); # if ($ed_time < $time_cutoff) # break; $url = qualifiedUrl($formatter->link_url(_rawurlencode($page_name))); $diff_url = qualifiedUrl($formatter->link_url(_rawurlencode($page_name), '?action=diff')); $extra = "<br /><a href='{$diff_url}'>" . _("show changes") . "</a>\n"; if (!$DBInfo->hasPage($page_name)) { $status = 'deleted'; $html = '<![CDATA[' . "<a href='{$url}'>" . $page_name . "</a> is deleted" . ']]>' . "\n"; } else { $status = 'updated'; if (!empty($options['diffs'])) { $p = new WikiPage($page_name); $f = new Formatter($p); $options['raw'] = 1; $options['nomsg'] = 1; $html = $f->macro_repl('Diff', '', $options); if (!$html) { ob_start(); $f->send_page('', array('fixpath' => 1)); #$f->send_page(''); $html = ob_get_contents(); ob_end_clean(); $extra = ''; } $html = str_replace(']', ']', $html); $html = "<![CDATA[" . $html . $extra . "]]>"; #$html=strtr($html.$extra,array('&'=>'&','<'=>'<')); } else { if (!empty($options['summary'])) { $p = new WikiPage($page_name); $f = new Formatter($p); $f->section_edit = 0; $f->sister_on = 0; $f->perma_icon = ''; $options['nomsg'] = 1; $b = $p->_get_raw_body(); $chunks = preg_split('/\\n#{4,}/', $b); # summary breaker is #### ob_start(); if ($chunks) { $f->send_page($chunks[0], array('fixpath' => 1)); } else { $f->send_page('', array('fixpath' => 1)); } #$f->send_page(''); $html = ob_get_contents(); ob_end_clean(); $chunks = preg_split('/<!-- break -->/', $html); # <!-- break --> if ($chunks[0]) { $html = $chunks[0]; } $html = str_replace(']', ']', $html); $html = "<![CDATA[" . $html . "]]>"; } else { $html = str_replace('&', '&', $log); } } } $zone = "+00:00"; $date = gmdate("Y-m-d\\TH:i:s", $ed_time) . $zone; #$datetag = gmdate("YmdHis",$ed_time); $channel .= "<rdf:li rdf:resource=\"{$url}\"></rdf:li>\n"; $valid_page_name = preg_replace('/&(?!#?\\w+;)/', '&', _html_escape($page_name)); $items .= "<item rdf:about=\"{$url}\">\n"; $items .= " <title>{$valid_page_name}</title>\n"; $items .= " <link>{$url}</link>\n"; $items .= " <description>{$html}</description>\n"; $items .= " <dc:date>{$date}</dc:date>\n"; $items .= "<dc:creator>{$user}</dc:creator>\n"; $items .= "<dc:contributor>{$user}</dc:contributor>\n"; # $items.=" <dc:contributor>\n <rdf:Description>\n" # ." <rdf:value>$user</rdf:value>\n" # ." </rdf:Description>\n </dc:contributor>\n"; $items .= " <wiki:status>{$status}</wiki:status>\n"; $items .= " <wiki:diff>{$diff_url}</wiki:diff>\n"; $items .= "</item>\n"; } $url = qualifiedUrl($formatter->link_url($DBInfo->frontpage)); $channel .= <<<FOOT </rdf:Seq> </items> </channel> <image rdf:about="{$img_url}"> <title>{$DBInfo->sitename}</title> <link>{$url}</link> <url>{$img_url}</url> </image> FOOT; $url = qualifiedUrl($formatter->link_url("FindPage")); $form = <<<FORM <textinput> <title>Search</title> <link>{$url}</link> <name>goto</name> </textinput> FORM; $new = ""; if (!empty($options['oe']) and strtolower($options['oe']) != $DBInfo->charset) { $charset = $options['oe']; if (function_exists('iconv')) { $out = $head . $channel . $items . $form; $new = iconv($DBInfo->charset, $charset, $out); if (!$new) { $charset = $DBInfo->charset; } } } else { $charset = $DBInfo->charset; } $head = <<<HEAD <?xml version="1.0" encoding="{$charset}"?> <?xml-stylesheet href="{$DBInfo->url_prefix}/css/_feed.css" type="text/css"?> <rdf:RDF xmlns="http://purl.org/rss/1.0/" \txmlns:wiki="http://purl.org/rss/1.0/modules/wiki/" \txmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" \txmlns:xlink="http://www.w3.org/1999/xlink" \txmlns:dc="http://purl.org/dc/elements/1.1/"> <!-- Add "diffs=1" to add change diffs to the description of each items. Add "summary=1" to add summary to the description of each items. Add "oe=utf-8" to convert the charset of this rss to UTF-8. --> HEAD; header("Content-Type: text/xml"); if ($new) { $out = $head . $new; } else { $out = $head . $channel . $items . $form; } $out .= "</rdf:RDF>\n"; echo $out; $cache->update($etag, $out); $cache->remove($etag . '.lock'); }
function do_rdf_blog($formatter, $options) { global $DBInfo; # if (!$options['date'] or !preg_match('/^\d+$/',$date)) $date=date('Ym'); # else $date=$options['date']; $date = $options['date']; if ($options['all']) { # check error and set default value $blog_rss = new Cache_text('blogrss'); # $blog_mtime=filemtime($DBInfo->cache_dir."/blog"); # if ($blog_rss->exists($date'.xml') and ($blog_rss->mtime($date.'.xml') > $blog_mtime)) { # print $blog_rss->fetch($date.'.xml'); # return; # } $blogs = Blog_cache::get_rc_blogs($date); $logs = Blog_cache::get_summary($blogs, $date); $rss_name = $DBInfo->sitename . ': ' . _("Blog Changes"); } else { $blogs = array($DBInfo->pageToKeyname($formatter->page->name)); $logs = Blog_cache::get_summary($blogs, $date); $rss_name = $formatter->page->name; } usort($logs, 'BlogCompare'); $time_current = time(); $URL = qualifiedURL($formatter->prefix); $img_url = qualifiedURL($DBInfo->logo_img); $url = qualifiedUrl($formatter->link_url("BlogChanges")); $desc = sprintf(_("BlogChanges at %s"), $DBInfo->sitename); $channel = <<<CHANNEL <channel rdf:about="{$URL}"> <title>{$rss_name}</title> <link>{$url}</link> <description>{$desc}</description> <image rdf:resource="{$img_url}"/> <items> <rdf:Seq> CHANNEL; $items = ""; # print('<description>'."[$data] :".$chg["action"]." ".$chg["pageName"].$comment.'</description>'."\n"); # print('</rdf:li>'."\n"); # } $ratchet_day = FALSE; if (!$logs) { $logs = array(); } foreach ($logs as $log) { #print_r($log); list($page, $user, $date, $title, $summary) = $log; $url = qualifiedUrl($formatter->link_url(_urlencode($page))); if (!$title) { continue; } #$tag=md5("#!blog ".$line); $tag = md5($user . " " . $date . " " . $title); #$tag=_rawurlencode(normalize($title)); $channel .= " <rdf:li rdf:resource=\"{$url}#{$tag}\"/>\n"; $items .= " <item rdf:about=\"{$url}#{$tag}\">\n"; $items .= " <title>{$title}</title>\n"; $items .= " <link>{$url}#{$tag}</link>\n"; if ($summary) { $p = new WikiPage($page); $f = new Formatter($p); ob_start(); #$f->send_page($summary); $f->send_page($summary, array('fixpath' => 1)); #$summary=_html_escape(ob_get_contents()); $summary = '<![CDATA[' . ob_get_contents() . ']]>'; ob_end_clean(); $items .= " <description>{$summary}</description>\n"; } $items .= " <dc:date>{$date}+00:00</dc:date>\n"; $items .= " <dc:contributor>\n<rdf:Description>\n" . "<rdf:value>{$user}</rdf:value>\n" . "</rdf:Description>\n</dc:contributor>\n"; $items .= " </item>\n"; } $url = qualifiedUrl($formatter->link_url($DBInfo->frontpage)); $channel .= <<<FOOT </rdf:Seq> </items> </channel> <image rdf:about="{$img_url}"> <title>{$DBInfo->sitename}</title> <link>{$url}</link> <url>{$img_url}</url> </image> FOOT; $url = qualifiedUrl($formatter->link_url("FindPage")); $form = <<<FORM <textinput> <title>Search</title> <link>{$url}</link> <name>goto</name> </textinput> FORM; $new = ""; if ($options['oe'] and strtolower($options['oe']) != $DBInfo->charset) { $charset = $options['oe']; if (function_exists('iconv')) { $out = $head . $channel . $items . $form; $new = iconv($DBInfo->charset, $charset, $out); if (!$new) { $charset = $DBInfo->charset; } } } else { $charset = $DBInfo->charset; } $head = <<<HEAD <?xml version="1.0" encoding="{$charset}"?> <rdf:RDF xmlns:wiki="http://purl.org/rss/1.0/modules/wiki/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns="http://purl.org/rss/1.0/"> <!-- Add "oe=utf-8" to convert the charset of this rss to UTF-8. --> HEAD; header("Content-Type: text/xml"); if ($new) { print $head . $new; } else { print $head . $channel . $items . $form; } #print $head; #print $channel; #print $items; #print $form; print "</rdf:RDF>"; }
function render($pagename, $type, $params = array()) { global $DBInfo; $p = $DBInfo->getPage($pagename); $opts = array(); // parameters for mdict if ($type == 'mdict') { $opts = array('prefix' => 'entry:/'); } $formatter = new Formatter($p, $opts); if (isset($params['filters'])) { $formatter->filters = $params['filters']; } // trash javascripts $formatter->get_javascripts(); // init wordrule if (empty($formatter->wordrule)) { $formatter->set_wordrule(); } // render ob_start(); $formatter->send_page(); flush(); $out = ob_get_contents(); ob_end_clean(); // filter for mdict if ($type == 'mdict') { return $formatter->postfilter_repl('mdict', $out); } else { return $out; } }
function do_atom($formatter, $options) { global $DBInfo; global $_release; define('ATOM_DEFAULT_DAYS', 7); $days = $DBInfo->rc_days ? $DBInfo->rc_days : ATOM_DEFAULT_DAYS; $options['quick'] = 1; if ($options['c']) { $options['items'] = $options['c']; } $lines = $DBInfo->editlog_raw_lines($days, $options); $time_current = time(); # $secs_per_day= 60*60*24; # $days_to_show= 30; # $time_cutoff= $time_current - ($days_to_show * $secs_per_day); $URL = qualifiedURL($formatter->prefix); $img_url = qualifiedURL($DBInfo->logo_img); $url = qualifiedUrl($formatter->link_url($DBInfo->frontpage)); $surl = qualifiedUrl($formatter->link_url($options['page'] . '?action=atom')); $channel = <<<CHANNEL <title>{$DBInfo->sitename}</title> <link href="{$url}"></link> <link rel="self" type="application/atom+xml" href="{$surl}" /> <subtitle>RecentChanges at {$DBInfo->sitename}</subtitle> <generator version="{$_release}">MoniWiki Atom feeder</generator> CHANNEL; $items = ""; $ratchet_day = FALSE; if (!$lines) { $lines = array(); } foreach ($lines as $line) { $parts = explode("\t", $line); $page_name = $DBInfo->keyToPagename($parts[0]); $addr = $parts[1]; $ed_time = $parts[2]; $user = $parts[4]; $user_uri = ''; if ($DBInfo->hasPage($user)) { $user_uri = $formatter->link_url(_rawurlencode($user), "", $user); $user_uri = '<uri>' . $user_uri . '</uri>'; } $log = _stripslashes($parts[5]); $act = rtrim($parts[6]); $url = qualifiedUrl($formatter->link_url(_rawurlencode($page_name))); $diff_url = qualifiedUrl($formatter->link_url(_rawurlencode($page_name), '?action=diff')); $extra = "<br /><a href='{$diff_url}'>" . _("show changes") . "</a>\n"; $content = ''; if (!$DBInfo->hasPage($page_name)) { $status = 'deleted'; $content = "<content type='html'><a href='{$url}'>{$page_name}</a> is deleted</content>\n"; } else { $status = 'updated'; if ($options['diffs']) { $p = new WikiPage($page_name); $f = new Formatter($p); $options['raw'] = 1; $options['nomsg'] = 1; $html = $f->macro_repl('Diff', '', $options); if (!$html) { ob_start(); $f->send_page('', array('fixpath' => 1)); #$f->send_page(''); $html = ob_get_contents(); ob_end_clean(); $extra = ''; } $content = " <content type='xhtml'><div xmlns='http://www.w3.org/1999/xhtml'>{$html}</content>\n"; } else { if ($log) { $html = str_replace('&', '&', $log); $content = "<content type='text'>" . $html . "</content>\n"; } else { $content = "<content type='text'>updated</content>\n"; } } } $zone = '+00:00'; $date = gmdate("Y-m-d\\TH:i:s", $ed_time) . $zone; if (!isset($updated)) { $updated = $date; } #$datetag = gmdate("YmdHis",$ed_time); $valid_page_name = str_replace('&', '&', $page_name); $items .= "<entry>\n"; $items .= " <title>{$valid_page_name}</title>\n"; $items .= " <link href='{$url}'></link>\n"; $items .= ' ' . $content; $items .= " <author><name>{$user}</name>{$user_uri}</author>\n"; $items .= " <updated>{$date}</updated>\n"; $items .= " <contributor><name>{$user}</name>{$user_uri}</contributor>\n"; $items .= "</entry>\n"; } $updated = " <updated>{$updated}</updated>\n"; $new = ""; if ($options['oe'] and strtolower($options['oe']) != $DBInfo->charset) { $charset = $options['oe']; if (function_exists('iconv')) { $out = $head . $channel . $items . $form; $new = iconv($DBInfo->charset, $charset, $out); if (!$new) { $charset = $DBInfo->charset; } } } else { $charset = $DBInfo->charset; } $head = <<<HEAD <?xml version="1.0" encoding="{$charset}"?> <!--<?xml-stylesheet href="{$DBInfo->url_prefix}/css/_feed.css" type="text/css"?>--> <feed xmlns="http://www.w3.org/2005/Atom"> <!-- Add "diffs=1" to add change diffs to the description of each items. Add "oe=utf-8" to convert the charset of this rss to UTF-8. --> HEAD; header("Content-Type: application/xml"); if ($new) { print $head . $new; } else { print $head . $channel . $updated . $items . $form; } print "</feed>\n"; }
function do_atom($formatter, $options) { global $DBInfo, $Config; global $_release; define('ATOM_DEFAULT_DAYS', 7); // get members to hide log $members = $DBInfo->members; $days = $DBInfo->rc_days ? $DBInfo->rc_days : ATOM_DEFAULT_DAYS; $options['quick'] = 1; if ($options['c']) { $options['items'] = $options['c']; } $lines = $DBInfo->editlog_raw_lines($days, $options); // HTTP conditional get $mtime = $DBInfo->mtime(); $lastmod = gmdate('D, d M Y H:i:s \\G\\M\\T', $mtime); $cache_ttl = !empty($DBInfo->atom_ttl) ? $DBInfo->atom_ttl : 60 * 30; /* 30 minutes */ // make etag based on some options and mtime. $check_opts = array('quick', 'items', 'c'); $check = array(); foreach ($check_opts as $c) { if (isset($options[$c])) { $check[$c] = $options[$c]; } } $etag = md5($mtime . $DBInfo->logo_img . serialize($check) . $cache_ttl . $options['id']); $headers = array(); $headers[] = 'Pragma: cache'; $maxage = $cache_ttl; $public = 'public'; if ($options['id'] != 'Anonymous') { $public = 'private'; } $headers[] = 'Cache-Control: ' . $public . ', max-age=' . $maxage; $headers[] = 'Last-Modified: ' . $lastmod; $headers[] = 'ETag: "' . $etag . '"'; $need = http_need_cond_request($mtime, $lastmod, $etag); if (!$need) { $headers[] = 'HTTP/1.0 304 Not Modified'; } foreach ($headers as $h) { header($h); } if (!$need) { @ob_end_clean(); return; } $cache = new Cache_Text('atom'); $cache_delay = min($cache_ttl, 30); $mtime = $cache->mtime($etag); $time_current = time(); $val = false; if (empty($formatter->refresh)) { if (($val = $cache->fetch($etag)) !== false and $DBInfo->checkUpdated($mtime, $cache_delay)) { header("Content-Type: application/xml"); echo $val; return; } } // need to update cache if ($val !== false and $cache->exists($etag . '.lock')) { header("Content-Type: application/xml"); echo $val . '<!-- cached at ' . date('Y-m-d H:i:s', $mtime) . ' -->'; return; } if ($cache->exists($etag . '.lock')) { header("Content-Type: application/xml"); echo ''; return; } $cache->update($etag . '.lock', array('lock'), 30); // 30s lock $URL = qualifiedURL($formatter->prefix); $img_url = qualifiedURL($DBInfo->logo_img); $url = qualifiedUrl($formatter->link_url($DBInfo->frontpage)); $surl = qualifiedUrl($formatter->link_url($options['page'] . '?action=atom')); $channel = <<<CHANNEL <title>{$DBInfo->sitename}</title> <link href="{$url}"></link> <link rel="self" type="application/atom+xml" href="{$surl}" /> <subtitle>RecentChanges at {$DBInfo->sitename}</subtitle> <generator version="{$_release}">MoniWiki Atom feeder</generator> CHANNEL; $items = ""; $ratchet_day = FALSE; if (!$lines) { $lines = array(); } foreach ($lines as $line) { $parts = explode("\t", $line); $page_name = $DBInfo->keyToPagename($parts[0]); // hide log if (!empty($members) && !in_array($options['id'], $members) && !empty($Config['ruleset']['hidelog'])) { if (in_array($page_name, $Config['ruleset']['hidelog'])) { continue; } } $addr = $parts[1]; $ed_time = $parts[2]; $user = $parts[4]; $user_uri = ''; if ($user != 'Anonymous' && $DBInfo->hasPage($user)) { $user_uri = $formatter->link_url(_rawurlencode($user), "", $user); $user_uri = '<uri>' . $user_uri . '</uri>'; } $log = _stripslashes($parts[5]); $act = rtrim($parts[6]); $url = qualifiedUrl($formatter->link_url(_rawurlencode($page_name))); $diff_url = qualifiedUrl($formatter->link_url(_rawurlencode($page_name), '?action=diff')); $extra = "<br /><a href='{$diff_url}'>" . _("show changes") . "</a>\n"; $content = ''; if (!$DBInfo->hasPage($page_name)) { $status = 'deleted'; $content = "<content type='html'><a href='{$url}'>{$page_name}</a> is deleted</content>\n"; } else { $status = 'updated'; if ($options['diffs']) { $p = new WikiPage($page_name); $f = new Formatter($p); $options['raw'] = 1; $options['nomsg'] = 1; $html = $f->macro_repl('Diff', '', $options); if (!$html) { ob_start(); $f->send_page('', array('fixpath' => 1)); #$f->send_page(''); $html = ob_get_contents(); ob_end_clean(); $extra = ''; } $content = " <content type='xhtml'><div xmlns='http://www.w3.org/1999/xhtml'>{$html}</content>\n"; } else { if ($log) { $html = str_replace('&', '&', $log); $content = "<content type='text'>" . $html . "</content>\n"; } else { $content = "<content type='text'>updated</content>\n"; } } } $zone = '+00:00'; $date = gmdate("Y-m-d\\TH:i:s", $ed_time) . $zone; if (!isset($updated)) { $updated = $date; } #$datetag = gmdate("YmdHis",$ed_time); $valid_page_name = str_replace('&', '&', $page_name); $items .= "<entry>\n"; $items .= " <title>{$valid_page_name}</title>\n"; $items .= " <link href='{$url}'></link>\n"; $items .= ' ' . $content; $items .= " <author><name>{$user}</name>{$user_uri}</author>\n"; $items .= " <updated>{$date}</updated>\n"; $items .= " <contributor><name>{$user}</name>{$user_uri}</contributor>\n"; $items .= "</entry>\n"; } $updated = " <updated>{$updated}</updated>\n"; $new = ""; if ($options['oe'] and strtolower($options['oe']) != $DBInfo->charset) { $charset = $options['oe']; if (function_exists('iconv')) { $out = $head . $channel . $items . $form; $new = iconv($DBInfo->charset, $charset, $out); if (!$new) { $charset = $DBInfo->charset; } } } else { $charset = $DBInfo->charset; } $head = <<<HEAD <?xml version="1.0" encoding="{$charset}"?> <!--<?xml-stylesheet href="{$DBInfo->url_prefix}/css/_feed.css" type="text/css"?>--> <feed xmlns="http://www.w3.org/2005/Atom"> <!-- Add "diffs=1" to add change diffs to the description of each items. Add "oe=utf-8" to convert the charset of this rss to UTF-8. --> HEAD; header("Content-Type: application/xml"); $out = ''; if ($new) { $out = $head . $new; } else { $out = $head . $channel . $updated . $items . $form; } $out .= "</feed>\n"; echo $out; $cache->update($etag, $out); $cache->remove($etag . '.lock'); }