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