1<?php 2/** 3 * XML feed export 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Andreas Gohr <andi@splitbrain.org> 7 */ 8 9 if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__)).'/'); 10 require_once(DOKU_INC.'inc/init.php'); 11 require_once(DOKU_INC.'inc/common.php'); 12 require_once(DOKU_INC.'inc/parserutils.php'); 13 require_once(DOKU_INC.'inc/feedcreator.class.php'); 14 require_once(DOKU_INC.'inc/auth.php'); 15 16 //close session 17 session_write_close(); 18 19 20 $num = $_REQUEST['num']; 21 $type = $_REQUEST['type']; 22 $mode = $_REQUEST['mode']; 23 $ns = $_REQUEST['ns']; 24 $ltype = $_REQUEST['linkto']; 25 26 switch ($type){ 27 case 'rss': 28 $type = 'RSS0.9'; 29 break; 30 case 'rss2': 31 $type = 'RSS2.0'; 32 break; 33 case 'atom': 34 $type = 'ATOM0.3'; 35 break; 36 default: 37 $type = 'RSS1.0'; 38 } 39 40 // the feed is dynamic - we need a cache for each combo 41 // (but most people just use the default feed so it's still effective) 42 $cache = getCacheName($num.$type.$mode.$ns.$ltype.$_SERVER['REMOTE_USER'],'.feed'); 43 44 // check cacheage and deliver if nothing has changed since last 45 // time (with 5 minutes settletime) 46 $cmod = @filemtime($cache); // 0 if not exists 47 if($cmod && ($cmod+(5*60) >= @filemtime($conf['changelog']))){ 48 header('Content-Type: application/xml; charset=utf-8'); 49 print io_readFile($cache); 50 exit; 51 } 52 53 // create new feed 54 $rss = new DokuWikiFeedCreator(); 55 $rss->title = $conf['title'].(($ns) ? ' '.$ns : ''); 56 $rss->link = DOKU_URL; 57 $rss->syndicationURL = DOKU_URL.'feed.php'; 58 $rss->cssStyleSheet = DOKU_URL.'lib/styles/feed.css'; 59 60 $image = new FeedImage(); 61 $image->title = $conf['title']; 62 $image->url = DOKU_URL."lib/images/favicon.ico"; 63 $image->link = DOKU_URL; 64 $rss->image = $image; 65 66 if($mode == 'list'){ 67 rssListNamespace($rss,$ns); 68 }else{ 69 rssRecentChanges($rss,$num,$ltype,$ns); 70 } 71 72 $feed = $rss->createFeed($type,'utf-8'); 73 74 // save cachefile 75 io_saveFile($cache,$feed); 76 77 // finally deliver 78 header('Content-Type: application/xml; charset=utf-8'); 79 print $feed; 80 81// ---------------------------------------------------------------- // 82 83/** 84 * Add recent changed to a feed object 85 * 86 * @author Andreas Gohr <andi@splitbrain.org> 87 */ 88function rssRecentChanges(&$rss,$num,$ltype,$ns){ 89 global $conf; 90 if(!$num) $num = $conf['recent']; 91 92 $recents = getRecents(0,$num,false,$ns); 93 94 //this can take some time if a lot of recaching has to be done 95 @set_time_limit(90); // set max execution time 96 97 foreach(array_keys($recents) as $id){ 98 $desc = cleanDesc(p_wiki_xhtml($id,'',false)); 99 $item = new FeedItem(); 100 $item->title = $id; 101 if(!empty($recents[$id]['sum'])){ 102 $item->title .= ' - '.strip_tags($recents[$id]['sum']); 103 } 104 105 switch ($ltype){ 106 case 'page': 107 $item->link = wl($id,'rev='.$recents[$id]['date'],true); 108 break; 109 case 'rev': 110 $item->link = wl($id,'do=revisions&rev='.$recents[$id]['date'],true); 111 break; 112 default: 113 $item->link = wl($id,'do=diff&'.$recents[$id]['date'],true); 114 } 115 116 $item->description = $desc; 117 $item->date = date('r',$recents[$id]['date']); 118 if(strpos($id,':')!==false){ 119 $item->category = substr($id,0,strrpos($id,':')); 120 } 121 if($recents[$id]['user']){ 122 $item->author = $recents[$id]['user'].'@'; 123 }else{ 124 $item->author = 'anonymous@'; 125 } 126 $item->author .= $recents[$id]['ip']; 127 $rss->addItem($item); 128 } 129} 130 131/** 132 * Add all pages of a namespace to a feedobject 133 * 134 * @author Andreas Gohr <andi@splitbrain.org> 135 */ 136function rssListNamespace(&$rss,$ns){ 137 require_once(DOKU_INC.'inc/search.php'); 138 global $conf; 139 140 $ns=':'.cleanID($ns); 141 $ns=str_replace(':','/',$ns); 142 143 $data = array(); 144 sort($data); 145 search($data,$conf['datadir'],'search_list','',$ns); 146 foreach($data as $row){ 147 $id = $row['id']; 148 $date = filemtime(wikiFN($id)); 149 $desc = cleanDesc(p_wiki_xhtml($id,'',false)); 150 $item = new FeedItem(); 151 $item->title = $id; 152 $item->link = wl($id,'rev='.$date,true); 153 $item->description = $desc; 154 $item->date = date('r',$date); 155 $rss->addItem($item); 156 } 157} 158 159/** 160 * Clean description for feed inclusion 161 * 162 * Removes HTML tags and line breaks and trims the text to 163 * 250 chars 164 * 165 * @author Andreas Gohr <andi@splitbrain.org> 166 */ 167function cleanDesc($desc){ 168 //remove TOC 169 $desc = preg_replace('!<div class="toc">.*?(</div>\n</div>)!s','',$desc); 170 $desc = strip_tags($desc); 171 $desc = preg_replace('/[\n\r\t]/',' ',$desc); 172 $desc = preg_replace('/ /',' ',$desc); 173 $desc = utf8_substr($desc,0,250); 174 $desc = $desc.'...'; 175 return $desc; 176} 177 178?> 179