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