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)),$info); //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 * @todo rewrite to use mode instead of hardcoded XHTML 66 */ 67function p_cached_xhtml($file){ 68 global $conf; 69 $cache = $conf['datadir'].'/_cache/xhtml/'; 70 $cache .= md5($file.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT']); 71 $purge = $conf['datadir'].'/_cache/purgefile'; 72 73 // check if cache can be used 74 $cachetime = @filemtime($cache); // 0 if not exists 75 76 if( @file_exists($file) // does the source exist 77 && $cachetime > @filemtime($file) // cache is fresh 78 && ((time() - $cachetime) < $conf['cachetime']) // and is cachefile young enough 79 && !isset($_REQUEST['purge']) // no purge param was set 80 && ($cachetime > @filemtime($purge)) // and newer than the purgefile 81 && ($cachetime > @filemtime(DOKU_INC.'conf/dokuwiki.php')) // newer than the config file 82 && ($cachetime > @filemtime(DOKU_INC.'conf/local.php')) // newer than the local config file 83 && ($cachetime > @filemtime(DOKU_INC.'inc/parser/xhtml.php')) // newer than the renderer 84 && ($cachetime > @filemtime(DOKU_INC.'inc/parser/parser.php')) // newer than the parser 85 && ($cachetime > @filemtime(DOKU_INC.'inc/parser/handler.php')))// newer than the handler 86 { 87 //well then use the cache 88 $parsed = io_readfile($cache); 89 $parsed .= "\n<!-- cachefile $cache used -->\n"; 90 }else{ 91 $parsed = p_render('xhtml', p_cached_instructions($file),$info); //try to use cached instructions 92 93 if($info['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 return $parsed; 103} 104 105/** 106 * Returns the render instructions for a file 107 * 108 * Uses and creates a serialized cache file 109 * 110 * @author Andreas Gohr <andi@splitbrain.org> 111 */ 112function p_cached_instructions($file,$cacheonly=false){ 113 global $conf; 114 $cache = $conf['datadir'].'/_cache/instructions/'; 115 $cache .= md5($file.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT']); 116 117 // check if cache can be used 118 $cachetime = @filemtime($cache); // 0 if not exists 119 120 // cache forced? 121 if($cacheonly){ 122 if($cachetime){ 123 return unserialize(io_readfile($cache)); 124 }else{ 125 return NULL; 126 } 127 } 128 129 if( @file_exists($file) // does the source exist 130 && $cachetime > @filemtime($file) // cache is fresh 131 && !isset($_REQUEST['purge']) // no purge param was set 132 && ($cachetime > @filemtime(DOKU_INC.'conf/dokuwiki.php')) // newer than the config file 133 && ($cachetime > @filemtime(DOKU_INC.'conf/local.php')) // newer than the local config file 134 && ($cachetime > @filemtime(DOKU_INC.'inc/parser/parser.php')) // newer than the parser 135 && ($cachetime > @filemtime(DOKU_INC.'inc/parser/handler.php')))// newer than the handler 136 { 137 //well then use the cache 138 return unserialize(io_readfile($cache)); 139 }elseif(@file_exists($file)){ 140 // no cache - do some work 141 $ins = p_get_instructions(io_readfile($file)); 142 io_savefile($cache,serialize($ins)); 143 return $ins; 144 } 145 146 return NULL; 147} 148 149/** 150 * turns a page into a list of instructions 151 * 152 * @author Harry Fuecks <hfuecks@gmail.com> 153 * @author Andreas Gohr <andi@splitbrain.org> 154 */ 155function p_get_instructions($text){ 156 global $conf; 157 158 require_once DOKU_INC . 'inc/parser/parser.php'; 159 160 // Create the parser 161 $Parser = & new Doku_Parser(); 162 163 // Add the Handler 164 $Parser->Handler = & new Doku_Handler(); 165 166 // Load all the modes 167 $Parser->addMode('listblock',new Doku_Parser_Mode_ListBlock()); 168 $Parser->addMode('preformatted',new Doku_Parser_Mode_Preformatted()); 169 $Parser->addMode('notoc',new Doku_Parser_Mode_NoToc()); 170 $Parser->addMode('nocache',new Doku_Parser_Mode_NoCache()); 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 * In the $info array are informations from the renderer returned 224 * 225 * @author Harry Fuecks <hfuecks@gmail.com> 226 * @author Andreas Gohr <andi@splitbrain.org> 227 */ 228function p_render($mode,$instructions,& $info){ 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 253 //set info array 254 $info = $Renderer->info; 255 256 // Return the output 257 return $Renderer->doc; 258} 259 260/** 261 * Gets the first heading from a file 262 * 263 * @author Jan Decaluwe <jan@jandecaluwe.com> 264 */ 265function p_get_first_heading($id){ 266 $file = wikiFN($id); 267 if (@file_exists($file)) { 268 $instructions = p_cached_instructions($file,true); 269 foreach ( $instructions as $instruction ) { 270 if ($instruction[0] == 'header') { 271 return $instruction[1][0]; 272 } 273 } 274 } 275 return NULL; 276} 277 278//Setup VIM: ex: et ts=2 enc=utf-8 : 279