1<?php 2/** 3 * Include Plugin: displays a wiki page within another 4 * Usage: 5 * {{fortune}} 6 * 7 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 8 * @author Otto Vainio <oiv-plugins@valjakko.net> 9 */ 10 11if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 12if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 13require_once(DOKU_PLUGIN.'syntax.php'); 14 15/** 16 * All DokuWiki plugins to extend the parser/rendering mechanism 17 * need to inherit from this class 18 */ 19class syntax_plugin_fortune extends DokuWiki_Syntax_Plugin { 20 21 /** 22 * return some info 23 */ 24 function getInfo(){ 25 return array( 26 'author' => 'Otto Vainio', 27 'email' => 'oiv-plugins@valjakko.net', 28 'date' => '2005-10-14', 29 'name' => 'Fortune Plugin', 30 'desc' => 'Displays qotd (Quote Of The Day)', 31 'url' => 'http://wiki.splitbrain.org/plugin:fortune', 32 ); 33 } 34 35 /** 36 * What kind of syntax are we? 37 */ 38 function getType(){ 39 return 'substition'; 40 } 41 42 /** 43 * Where to sort in? 44 */ 45 function getSort(){ 46 return 56; 47 } 48 49 /** 50 * Paragraph Type 51 */ 52 function getPType(){ 53 return 'block'; 54 } 55 56 57 /** 58 * Connect pattern to lexer 59 */ 60 function connectTo($mode) { 61 $this->Lexer->addSpecialPattern("{{fortune}}",$mode,'plugin_fortune'); 62 } 63 64 /** 65 * Handle the match 66 */ 67 function handle($match, $state, $pos, &$handler){ 68 return $match; 69 } 70 71 /** 72 * Create output 73 */ 74 function render($mode, &$renderer, $data) { 75 76 if($mode == 'xhtml'){ 77// include_once "fortuneclass.php"; 78 $f = new Fortune; 79 $fortunecookie = $f->quoteFromDir(DOKU_PLUGIN . "fortune/dat/"); 80 $renderer->doc .= "<div class=\"fortune\">"; 81 $renderer->doc .= nl2br(htmlspecialchars($fortunecookie)); 82 $renderer->doc .= "</div>"; 83 84 return true; 85 } 86 return false; 87 } 88} 89/* 90Main methods to use: 91 quoteFromDir($dir): 92 Quotes from any of the fortune-files in the dir. 93 getRandomQuote($file): 94 Quotes from the specific file. 95 96 Written by Henrik Aasted Sorensen, henrik@aasted.org 97 Read more at http://www.aasted.org/quote 98 Edited by Otto Vainio 99*/ 100 101class Fortune { 102 function quoteFromDir($dir) { 103 $amount = 0; 104 $index = 0; 105 clearstatcache(); 106 if ( $handle = opendir($dir) ) { 107 while (false !== ($file = readdir($handle))) { 108 if (strlen($file)>2 && $file!="_dummy") { 109 if (substr($file,-4) == ".dat"){ 110 if (@filemtime(substr($file,0,-4))>@filemtime($dir.$file)) { 111 $this->createIndexFile($dir.substr($file,0,-4)); 112 } 113 $number = $this->getNumberOfQuotes($dir . $file); 114 $amount += $number; 115 $quotes[$index] = $amount; 116 $files[$index] = $file; 117 $index++; 118 } else { 119 if (!is_file($dir.$file.".dat") || (@filemtime($dir.$file)>@filemtime($dir.$file.".dat"))) { 120 $this->createIndexFile($dir.$file); 121 $number = $this->getNumberOfQuotes($dir . $file . ".dat"); 122 $amount += $number; 123 $quotes[$index] = $amount; 124 $files[$index] = $file.".dat"; 125 $index++; 126 } 127 } 128 } 129 } 130 srand((double)microtime()*1000000); 131 $index = rand(0, $amount); 132 $i = 0; 133 while ($quotes[$i] < $index) { 134 $i++; 135 } 136 return $this->getRandomQuote($dir .$files[$i]); 137 } 138 return ""; 139 } 140 /* 141 Reads the number of quotes in the file. 142 */ 143 function getNumberOfQuotes($file) { 144 $len=0; 145 if ($fd = @fopen($file, "rb")) { 146 $this->readLong($fd); // Just move over the first long. Might as well be fseek. 147 $len = $this->readLong($fd); 148 fclose($fd); 149 } 150 return $len; 151 } 152 /* 153 Picks quote number $index from the dat-file in $file. 154 */ 155 function getExactQuote($file, $index) { 156 if (is_file($file) == FALSE) { 157 return; 158 } 159 160 if ( ($fd = fopen($file, "rb")) == FALSE ) { 161 return; 162 } 163 fseek($fd, 24 + 4 * $index); 164 165 $phys_index = $this->readLong($fd); 166 167 fclose($fd); 168 169 $quotefile = substr($file, 0, strlen($file) - 4); 170 171 if ( ($fd = fopen($quotefile, "rb")) == FALSE ) { 172 return; 173 } 174 175 $res = $this->getQuote($fd, $phys_index); 176 fclose($fd); 177 178 return $res; 179 } 180 181 /* 182 Returns a random quote from $file. 183 */ 184 function getRandomQuote($file) { 185 $number = $this->getNumberOfQuotes($file); 186 187 $index = rand(0, $number - 1); 188 189 return $this->getExactQuote($file, $index); 190 } 191 192 /* 193 Reads a quote from the specified index. 194 */ 195 function getQuote($fd, $index) { 196 fseek($fd, $index); 197 $line=""; $res = ""; 198 do { 199 $res = $res . $line; 200 $line = fgets($fd, 1024); 201 } while ( ($line[0] != "%") && (!feof($fd)) ); 202 203 return $res; 204 } 205 206 /* 207 Gets indexes from the file pointed to by the filedescriptor $fd. 208 */ 209 function getIndices($fd) { 210 fseek($fd, 24, SEEK_SET); 211 $i = 0; 212 213 while ( feof($fd) == FALSE ) { 214 $res[$i] = readLong($fd); 215 $i++; 216 } 217 return $res; 218 } 219 220 function readLong($fd) { 221 $res = fread($fd, 4); 222 $l = ord($res[3]); 223 $l += ord($res[2]) << 8; 224 $l += ord($res[1]) << 16; 225 $l += ord($res[0]) << 24; 226 return $l; 227 } 228 function createIndexFile($file) { 229 $fd = fopen($file, "r"); 230 if ($fd == false) { 231// echo "File error!"; 232 exit; 233 } 234 235 $i = 1; 236 $length = 0; 237 $longest = 0; 238 $shortest = 100000; 239 $indices[0] = 0; 240 while (!feof($fd)) { 241 $line = fgets($fd); 242 if ($line == "%\n") { 243 $indices[$i] = ftell($fd); 244 $i++; 245 if ($length > $longest) 246 $longest = $length; 247 if ($length < $shortest) 248 $shortest = $length; 249 $length = 0; 250 } else { 251 $length = $length + strlen($line); 252 } 253 } 254 fclose($fd); 255 $fd = @fopen($file . ".dat", "w"); 256 if ($fd == false) { 257// echo "<!-- createIndexFile: Could not write to file....-->"; 258 exit; 259 } 260 261 // Write header. 262 $this->writeLong($fd, 2); 263 $this->writeLong($fd, count($indices)); 264 $this->writeLong($fd, $longest); 265 $this->writeLong($fd, $shortest); 266 $this->writeLong($fd, 0); 267 $this->writeLong($fd, 37 << 24); 268 269 for ($i = 0 ; $i < count($indices) ; $i++) { 270 $this->writeLong($fd, $indices[$i]); 271 } 272 273 fclose($fd); 274 } 275 276 function writeLong($fd, $l) { 277 fwrite($fd, chr ( ($l >> 24) & 255)); 278 fwrite($fd, chr ( ($l >> 16) & 255)); 279 fwrite($fd, chr ( ($l >> 8) & 255)); 280 fwrite($fd, chr ( $l & 255)); 281 } 282}// End of class 283?>