1<?php 2/** 3 * Utilities for collecting data from config files 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Harry Fuecks <hfuecks@gmail.com> 7 * @author Andreas Gohr <andi@splitbrain.org> 8 */ 9 10 if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/'); 11 12 require_once(DOKU_INC.'inc/confutils.php'); 13 require_once(DOKU_INC.'inc/pageutils.php'); 14 15/** 16 * Returns the parsed Wikitext in XHTML for the given id and revision. 17 * 18 * If $excuse is true an explanation is returned if the file 19 * wasn't found 20 * 21 * @author Andreas Gohr <andi@splitbrain.org> 22 */ 23function p_wiki_xhtml($id, $rev='', $excuse=true){ 24 $file = wikiFN($id,$rev); 25 $ret = ''; 26 27 //ensure $id is in global $ID (needed for parsing) 28 global $ID; 29 $ID = $id; 30 31 if($rev){ 32 if(@file_exists($file)){ 33 $ret = p_render('xhtml',p_get_instructions(io_readfile($file))); //no caching on old revisions 34 }elseif($excuse){ 35 $ret = p_locale_xhtml('norev'); 36 } 37 }else{ 38 if(@file_exists($file)){ 39 $ret = p_cached_xhtml($file); 40 }elseif($excuse){ 41 $ret = p_locale_xhtml('newpage'); 42 } 43 } 44 45 return $ret; 46} 47 48/** 49 * Returns the specified local text in parsed format 50 * 51 * @author Andreas Gohr <andi@splitbrain.org> 52 */ 53function p_locale_xhtml($id){ 54 //fetch parsed locale 55 $html = p_cached_xhtml(localeFN($id)); 56 return $html; 57} 58 59/** 60 * Returns the given file parsed to XHTML 61 * 62 * Uses and creates a cachefile 63 * 64 * @author Andreas Gohr <andi@splitbrain.org> 65 */ 66function p_cached_xhtml($file){ 67 global $conf; 68 $cache = $conf['datadir'].'/_cache/xhtml/'; 69 $cache .= md5($file.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT']); 70 71 // check if cache can be used 72 $cachetime = @filemtime($cache); // 0 if not exists 73 74 if( @file_exists($file) // does the source exist 75 && $cachetime > @filemtime($file) // cache is fresh 76 && ((time() - $cachetime) < $conf['cachetime']) // and is cachefile young enough 77 && !isset($_REQUEST['purge']) // no purge param was set 78 && ($cachetime > @filemtime(DOKU_INC.'conf/dokuwiki.php')) // newer than the config file 79 && ($cachetime > @filemtime(DOKU_INC.'conf/local.php')) // newer than the local config file 80 && ($cachetime > @filemtime(DOKU_INC.'inc/parser/xhtml.php')) // newer than the renderer 81 && ($cachetime > @filemtime(DOKU_INC.'inc/parser/parser.php')) // newer than the parser 82 && ($cachetime > @filemtime(DOKU_INC.'inc/parser/handler.php')))// newer than the handler 83 { 84 //well then use the cache 85 $parsed = io_readfile($cache); 86 $parsed .= "\n<!-- cachefile $cache used -->\n"; 87 }else{ 88 $parsed = p_render('xhtml', p_cached_instructions($file)); //try to use cached instructions 89 io_saveFile($cache,$parsed); //save cachefile 90 $parsed .= "\n<!-- no cachefile used, but created -->\n"; 91 92 /* FIXME add nocache directive handling like this: 93 if($parser['cache']){ 94 io_saveFile($cache,$parsed); //save cachefile 95 $parsed .= "\n<!-- no cachefile used, but created -->\n"; 96 }else{ 97 @unlink($cache); //try to delete cachefile 98 $parsed .= "\n<!-- no cachefile used, caching forbidden -->\n"; 99 } 100 */ 101 } 102 103 return $parsed; 104} 105 106/** 107 * Returns the render instructions for a file 108 * 109 * Uses and creates a serialized cache file 110 * 111 * @author Andreas Gohr <andi@splitbrain.org> 112 */ 113function p_cached_instructions($file,$cacheonly=false){ 114 global $conf; 115 $cache = $conf['datadir'].'/_cache/instructions/'; 116 $cache .= md5($file.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT']); 117 118 // check if cache can be used 119 $cachetime = @filemtime($cache); // 0 if not exists 120 121 // cache forced? 122 if($cacheonly){ 123 if($cachetime){ 124 return unserialize(io_readfile($cache)); 125 }else{ 126 return NULL; 127 } 128 } 129 130 if( @file_exists($file) // does the source exist 131 && $cachetime > @filemtime($file) // cache is fresh 132 && !isset($_REQUEST['purge']) // no purge param was set 133 && ($cachetime > @filemtime(DOKU_INC.'conf/dokuwiki.php')) // newer than the config file 134 && ($cachetime > @filemtime(DOKU_INC.'conf/local.php')) // newer than the local config file 135 && ($cachetime > @filemtime(DOKU_INC.'inc/parser/parser.php')) // newer than the parser 136 && ($cachetime > @filemtime(DOKU_INC.'inc/parser/handler.php')))// newer than the handler 137 { 138 //well then use the cache 139 return unserialize(io_readfile($cache)); 140 }elseif(@file_exists($file)){ 141 // no cache - do some work 142 $ins = p_get_instructions(io_readfile($file)); 143 io_savefile($cache,serialize($ins)); 144 return $ins; 145 } 146 147 return NULL; 148} 149 150/** 151 * turns a page into a list of instructions 152 * 153 * @author Harry Fuecks <hfuecks@gmail.com> 154 * @author Andreas Gohr <andi@splitbrain.org> 155 */ 156function p_get_instructions($text){ 157 global $conf; 158 159 require_once DOKU_INC . 'inc/parser/parser.php'; 160 161 // Create the parser 162 $Parser = & new Doku_Parser(); 163 164 // Add the Handler 165 $Parser->Handler = & new Doku_Handler(); 166 167 // Load all the modes 168 $Parser->addMode('listblock',new Doku_Parser_Mode_ListBlock()); 169 $Parser->addMode('preformatted',new Doku_Parser_Mode_Preformatted()); 170 $Parser->addMode('notoc',new Doku_Parser_Mode_NoToc()); 171 $Parser->addMode('header',new Doku_Parser_Mode_Header()); 172 $Parser->addMode('table',new Doku_Parser_Mode_Table()); 173 174 $formats = array ( 175 'strong', 'emphasis', 'underline', 'monospace', 176 'subscript', 'superscript', 'deleted', 177 ); 178 foreach ( $formats as $format ) { 179 $Parser->addMode($format,new Doku_Parser_Mode_Formatting($format)); 180 } 181 182 $Parser->addMode('linebreak',new Doku_Parser_Mode_Linebreak()); 183 $Parser->addMode('footnote',new Doku_Parser_Mode_Footnote()); 184 $Parser->addMode('hr',new Doku_Parser_Mode_HR()); 185 186 $Parser->addMode('unformatted',new Doku_Parser_Mode_Unformatted()); 187 $Parser->addMode('php',new Doku_Parser_Mode_PHP()); 188 $Parser->addMode('html',new Doku_Parser_Mode_HTML()); 189 $Parser->addMode('code',new Doku_Parser_Mode_Code()); 190 $Parser->addMode('file',new Doku_Parser_Mode_File()); 191 $Parser->addMode('quote',new Doku_Parser_Mode_Quote()); 192 193 $Parser->addMode('smiley',new Doku_Parser_Mode_Smiley(array_keys(getSmileys()))); 194 $Parser->addMode('acronym',new Doku_Parser_Mode_Acronym(array_keys(getAcronyms()))); 195 #$Parser->addMode('wordblock',new Doku_Parser_Mode_Wordblock(getBadWords())); 196 $Parser->addMode('entity',new Doku_Parser_Mode_Entity(array_keys(getEntities()))); 197 198 $Parser->addMode('multiplyentity',new Doku_Parser_Mode_MultiplyEntity()); 199 $Parser->addMode('quotes',new Doku_Parser_Mode_Quotes()); 200 201 if($conf['camelcase']){ 202 $Parser->addMode('camelcaselink',new Doku_Parser_Mode_CamelCaseLink()); 203 } 204 205 $Parser->addMode('internallink',new Doku_Parser_Mode_InternalLink()); 206 $Parser->addMode('rss',new Doku_Parser_Mode_RSS()); 207 $Parser->addMode('media',new Doku_Parser_Mode_Media()); 208 $Parser->addMode('externallink',new Doku_Parser_Mode_ExternalLink()); 209 $Parser->addMode('emaillink',new Doku_Parser_Mode_EmailLink()); 210 $Parser->addMode('windowssharelink',new Doku_Parser_Mode_WindowsShareLink()); 211 //$Parser->addMode('filelink',new Doku_Parser_Mode_FileLink()); //FIXME ??? 212 $Parser->addMode('eol',new Doku_Parser_Mode_Eol()); 213 214 // Do the parsing 215 $p = $Parser->parse($text); 216# dbg($p); 217 return $p; 218} 219 220/** 221 * Renders a list of instruction to the specified output mode 222 * 223 * @author Harry Fuecks <hfuecks@gmail.com> 224 * @author Andreas Gohr <andi@splitbrain.org> 225 */ 226function p_render($mode,$instructions){ 227 if(is_null($instructions)) return ''; 228 229 // Create the renderer 230 if(!@file_exists(DOKU_INC."inc/parser/$mode.php")){ 231 msg("No renderer for $mode found",-1); 232 return null; 233 } 234 235 require_once DOKU_INC."inc/parser/$mode.php"; 236 $rclass = "Doku_Renderer_$mode"; 237 $Renderer = & new $rclass(); #FIXME any way to check for class existance? 238 239 $Renderer->smileys = getSmileys(); 240 $Renderer->entities = getEntities(); 241 $Renderer->acronyms = getAcronyms(); 242 $Renderer->interwiki = getInterwiki(); 243 #$Renderer->badwords = getBadWords(); 244 245 // Loop through the instructions 246 foreach ( $instructions as $instruction ) { 247 // Execute the callback against the Renderer 248 call_user_func_array(array(&$Renderer, $instruction[0]),$instruction[1]); 249 } 250 // Return the output 251 return $Renderer->doc; 252} 253 254/** 255 * Gets the first heading from a file 256 * 257 * @author Jan Decaluwe <jan@jandecaluwe.com> 258 */ 259 260function p_get_first_heading($id){ 261 $file = wikiFN($id); 262 if (@file_exists($file)) { 263 $instructions = p_cached_instructions($file); 264 foreach ( $instructions as $instruction ) { 265 if ($instruction[0] == 'header') { 266 return $instruction[1][0]; 267 } 268 } 269 } 270 return NULL; 271} 272 273//Setup VIM: ex: et ts=2 enc=utf-8 : 274