xref: /dokuwiki/feed.php (revision 8c6b3080c2e978c0b4422555baedeca97f678bbf)
1f3f0262cSandi<?php
215fae107Sandi/**
315fae107Sandi * XML feed export
415fae107Sandi *
515fae107Sandi * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
615fae107Sandi * @author     Andreas Gohr <andi@splitbrain.org>
715fae107Sandi */
815fae107Sandi
9ed7b5f09Sandi  if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__)).'/');
10ed7b5f09Sandi  require_once(DOKU_INC.'inc/init.php');
114d58bd99Sandi  require_once(DOKU_INC.'inc/common.php');
1230e171a0Salexander.krause  require_once(DOKU_INC.'inc/events.php');
134d58bd99Sandi  require_once(DOKU_INC.'inc/parserutils.php');
144d58bd99Sandi  require_once(DOKU_INC.'inc/feedcreator.class.php');
154d58bd99Sandi  require_once(DOKU_INC.'inc/auth.php');
16fbf82939SBen Coburn  require_once(DOKU_INC.'inc/pageutils.php');
17f3f0262cSandi
187131b668SAndreas Gohr  //close session
198746e727Sandi  session_write_close();
208746e727Sandi
21f3f0262cSandi
22f3f0262cSandi  $num   = $_REQUEST['num'];
23f3f0262cSandi  $type  = $_REQUEST['type'];
24f3f0262cSandi  $mode  = $_REQUEST['mode'];
25b6912aeaSAndreas Gohr  $minor = $_REQUEST['minor'];
26f3f0262cSandi  $ns    = $_REQUEST['ns'];
274d58bd99Sandi  $ltype = $_REQUEST['linkto'];
28f3f0262cSandi
2931f1284dSjoe.lapp  if($type == '')
3031f1284dSjoe.lapp    $type = $conf['rss_type'];
3131f1284dSjoe.lapp
32f3f0262cSandi  switch ($type){
33f3f0262cSandi    case 'rss':
3426d75eefSAndreas Gohr       $type = 'RSS0.91';
3526d75eefSAndreas Gohr       $mime = 'text/xml';
36f3f0262cSandi       break;
37f3f0262cSandi    case 'rss2':
38f3f0262cSandi       $type = 'RSS2.0';
3926d75eefSAndreas Gohr       $mime = 'text/xml';
40f3f0262cSandi       break;
41f3f0262cSandi    case 'atom':
42f3f0262cSandi       $type = 'ATOM0.3';
4326d75eefSAndreas Gohr       $mime = 'application/xml';
4426d75eefSAndreas Gohr       break;
4526d75eefSAndreas Gohr    case 'atom1':
4626d75eefSAndreas Gohr       $type = 'ATOM1.0';
4726d75eefSAndreas Gohr       $mime = 'application/atom+xml';
48f3f0262cSandi       break;
49f3f0262cSandi    default:
50f3f0262cSandi       $type = 'RSS1.0';
5126d75eefSAndreas Gohr       $mime = 'application/xml';
52f3f0262cSandi  }
53f3f0262cSandi
547131b668SAndreas Gohr  // the feed is dynamic - we need a cache for each combo
557131b668SAndreas Gohr  // (but most people just use the default feed so it's still effective)
567131b668SAndreas Gohr  $cache = getCacheName($num.$type.$mode.$ns.$ltype.$_SERVER['REMOTE_USER'],'.feed');
57f3f0262cSandi
587131b668SAndreas Gohr  // check cacheage and deliver if nothing has changed since last
59fbf82939SBen Coburn  // time or the update interval has not passed, also handles conditional requests
60fbf82939SBen Coburn  header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
61fbf82939SBen Coburn  header('Pragma: public');
627131b668SAndreas Gohr  header('Content-Type: application/xml; charset=utf-8');
63fbf82939SBen Coburn  $cmod = @filemtime($cache); // 0 if not exists
64fbf82939SBen Coburn  if($cmod && (($cmod+$conf['rss_update']>time()) || ($cmod>@filemtime($conf['changelog'])))){
65fbf82939SBen Coburn    http_conditionalRequest($cmod);
668716966dSAndreas Gohr    if($conf['allowdebug']) header("X-CacheUsed: $cache");
677131b668SAndreas Gohr    print io_readFile($cache);
687131b668SAndreas Gohr    exit;
69fbf82939SBen Coburn  } else {
70fbf82939SBen Coburn    http_conditionalRequest(time());
717131b668SAndreas Gohr  }
727131b668SAndreas Gohr
737131b668SAndreas Gohr  // create new feed
74f3f0262cSandi  $rss = new DokuWikiFeedCreator();
75dbb00abcSEsther Brunner  $rss->title = $conf['title'].(($ns) ? ' '.$ns : '');
76ed7b5f09Sandi  $rss->link  = DOKU_URL;
77f62ea8a1Sandi  $rss->syndicationURL = DOKU_URL.'feed.php';
78f62ea8a1Sandi  $rss->cssStyleSheet  = DOKU_URL.'lib/styles/feed.css';
79f3f0262cSandi
8079b608ceSandi  $image = new FeedImage();
8179b608ceSandi  $image->title = $conf['title'];
82f62ea8a1Sandi  $image->url = DOKU_URL."lib/images/favicon.ico";
8379b608ceSandi  $image->link = DOKU_URL;
8479b608ceSandi  $rss->image = $image;
8579b608ceSandi
86f3f0262cSandi  if($mode == 'list'){
87f3f0262cSandi    rssListNamespace($rss,$ns);
88f3f0262cSandi  }else{
89b6912aeaSAndreas Gohr    rssRecentChanges($rss,$num,$ltype,$ns,$minor);
90f3f0262cSandi  }
91f3f0262cSandi
927131b668SAndreas Gohr  $feed = $rss->createFeed($type,'utf-8');
937131b668SAndreas Gohr
947131b668SAndreas Gohr  // save cachefile
957131b668SAndreas Gohr  io_saveFile($cache,$feed);
967131b668SAndreas Gohr
977131b668SAndreas Gohr  // finally deliver
987131b668SAndreas Gohr  print $feed;
99f3f0262cSandi
10015fae107Sandi// ---------------------------------------------------------------- //
101f3f0262cSandi
10215fae107Sandi/**
1038716966dSAndreas Gohr * Add recent changed pages to a feed object
10415fae107Sandi *
10515fae107Sandi * @author Andreas Gohr <andi@splitbrain.org>
10615fae107Sandi */
107b6912aeaSAndreas Gohrfunction rssRecentChanges(&$rss,$num,$ltype,$ns,$minor){
108f62ea8a1Sandi    global $conf;
109c0f9af6dSNathan Neulinger    global $auth;
110c0f9af6dSNathan Neulinger
111f62ea8a1Sandi    if(!$num) $num = $conf['recent'];
1127a98db20Sjoe.lapp    $guardmail = ($conf['mailguard'] != '' && $conf['mailguard'] != 'none');
113f62ea8a1Sandi
114b6912aeaSAndreas Gohr
115b6912aeaSAndreas Gohr    $flags = RECENTS_SKIP_DELETED;
116b6912aeaSAndreas Gohr    if(!$minor) $flags += RECENTS_SKIP_MINORS;
117b6912aeaSAndreas Gohr
118b6912aeaSAndreas Gohr    $recents = getRecents(0,$num,$ns,$flags);
119f62ea8a1Sandi
120d437bcc4SAndreas Gohr    foreach($recents as $recent){
121f3f0262cSandi        $item = new FeedItem();
1228716966dSAndreas Gohr        $meta = p_get_metadata($recent['id']);
12303ee62cbSjoe.lapp
1248716966dSAndreas Gohr        if($conf['useheading'] && $meta['title']){
1258716966dSAndreas Gohr            $item->title = $meta['title'];
1268716966dSAndreas Gohr        }else{
1278716966dSAndreas Gohr            $item->title = $recent['id'];
12803ee62cbSjoe.lapp        }
129d437bcc4SAndreas Gohr        if(!empty($recent['sum'])){
130d437bcc4SAndreas Gohr            $item->title .= ' - '.strip_tags($recent['sum']);
131b1a1915cSandi        }
1324d58bd99Sandi
1338716966dSAndreas Gohr        if(empty($ltype)) $ltype = $conf['rss_linkto'];
13492e52d8dSjoe.lapp
1354d58bd99Sandi        switch ($ltype){
1364d58bd99Sandi            case 'page':
137d437bcc4SAndreas Gohr                $item->link = wl($recent['id'],'rev='.$recent['date'],true);
1384d58bd99Sandi                break;
1394d58bd99Sandi            case 'rev':
140aa11db09SAndreas Gohr                $item->link = wl($recent['id'],'do=revisions&rev='.$recent['date'],true);
1414d58bd99Sandi                break;
14292e52d8dSjoe.lapp            case 'current':
143d437bcc4SAndreas Gohr                $item->link = wl($recent['id'], '', true);
14492e52d8dSjoe.lapp                break;
14592e52d8dSjoe.lapp            case 'diff':
1464d58bd99Sandi            default:
14737beb806SAndreas Gohr                $item->link = wl($recent['id'],'rev='.$recent['date'].'&do=diff'.$recent['date'],true);
1484d58bd99Sandi        }
1494d58bd99Sandi
1508716966dSAndreas Gohr        $item->description = $meta['description']['abstract'];
151d437bcc4SAndreas Gohr        $item->date        = date('r',$recent['date']);
152d437bcc4SAndreas Gohr        $cat = getNS($recent['id']);
153d437bcc4SAndreas Gohr        if($cat) $item->category = $cat;
1547a98db20Sjoe.lapp
1558716966dSAndreas Gohr        // FIXME should the user be pulled from metadata as well?
1567a98db20Sjoe.lapp        $user = null;
157d437bcc4SAndreas Gohr        $user = @$recent['user']; // the @ spares time repeating lookup
1587a98db20Sjoe.lapp        $item->author = '';
1597a98db20Sjoe.lapp
1607a98db20Sjoe.lapp        if($user){
161c0f9af6dSNathan Neulinger            $userInfo = $auth->getUserData($user);
1627a98db20Sjoe.lapp            $item->author = $userInfo['name'];
1637a98db20Sjoe.lapp            if($guardmail) {
1647a98db20Sjoe.lapp            //cannot obfuscate because some RSS readers may check validity
165d437bcc4SAndreas Gohr                $item->authorEmail = $user.'@'.$recent['ip'];
166f3f0262cSandi            }else{
1677a98db20Sjoe.lapp                $item->authorEmail = $userInfo['mail'];
168f3f0262cSandi            }
1697a98db20Sjoe.lapp        }else{
170d437bcc4SAndreas Gohr            $item->authorEmail = 'anonymous@'.$recent['ip'];
1717a98db20Sjoe.lapp        }
172f3f0262cSandi        $rss->addItem($item);
173f3f0262cSandi    }
174f3f0262cSandi}
175f3f0262cSandi
17615fae107Sandi/**
17715fae107Sandi * Add all pages of a namespace to a feedobject
17815fae107Sandi *
17915fae107Sandi * @author Andreas Gohr <andi@splitbrain.org>
18015fae107Sandi */
181f3f0262cSandifunction rssListNamespace(&$rss,$ns){
182f62ea8a1Sandi    require_once(DOKU_INC.'inc/search.php');
183f3f0262cSandi    global $conf;
184f3f0262cSandi
185f3f0262cSandi    $ns=':'.cleanID($ns);
186f3f0262cSandi    $ns=str_replace(':','/',$ns);
187f3f0262cSandi
188f3f0262cSandi    $data = array();
189f3f0262cSandi    sort($data);
190f3f0262cSandi    search($data,$conf['datadir'],'search_list','',$ns);
191f3f0262cSandi    foreach($data as $row){
19285cf8195SAndreas Gohr        $item = new FeedItem();
19385cf8195SAndreas Gohr
194f3f0262cSandi        $id   = $row['id'];
195f3f0262cSandi        $date = filemtime(wikiFN($id));
1968716966dSAndreas Gohr        $meta = p_get_metadata($id);
19785cf8195SAndreas Gohr
1988716966dSAndreas Gohr        if($conf['useheading'] && $meta['title']){
1998716966dSAndreas Gohr            $item->title = $meta['title'];
2008716966dSAndreas Gohr        }else{
2018716966dSAndreas Gohr            $item->title = $id;
20285cf8195SAndreas Gohr        }
20385cf8195SAndreas Gohr
204ed7b5f09Sandi        $item->link        = wl($id,'rev='.$date,true);
205*8c6b3080SMichael Klier chi@chimeric.de        $item->description = $meta['description']['abstract'];
206f3f0262cSandi        $item->date        = date('r',$date);
207f3f0262cSandi        $rss->addItem($item);
208f3f0262cSandi  }
209f3f0262cSandi}
210f3f0262cSandi
2118716966dSAndreas Gohr//Setup VIM: ex: et ts=4 enc=utf-8 :
212f3f0262cSandi?>
213