]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/fortune.php
remove final \n to be ob_cache independent
[SourceForge/phpwiki.git] / lib / fortune.php
1 <?php
2 rcs_id('PHP Fortune - Made by henrik@aasted.org. HP: http://www.aasted.org');
3 rcs_id('$Id: fortune.php,v 1.2 2004-11-21 11:59:20 rurban Exp $');
4 /* 
5 Main methods to use:
6  quoteFromDir($dir):
7    Quotes from any of the fortune-files in the dir.
8  getRandomQuote($file):
9    Quotes from the specific file.
10    
11  Written by Henrik Aasted Sorensen, henrik@aasted.org
12  Read more at http://www.aasted.org/quote
13 */
14 class Fortune {
15
16     function quoteFromDir($dir) {
17         $amount = 0;
18         $index = 0;
19
20         if ( $handle = opendir($dir) ) {
21             while (false !== ($file = readdir($handle))) {
22                 
23                 if ( strpos($file, ".dat") != false) {
24                     $len = strlen($file);
25                     if (substr($file, $len - 4) == ".dat"){
26                         $number = $this->getNumberOfQuotes($dir . "/" . $file);
27                         $amount += $number;
28                         $quotes[$index] = $amount;
29                         $files[$index] = $file;
30                         $index++;                                       
31                     }
32                 }                       
33                 
34             }
35         
36             srand((double)microtime()*1000000);
37             $index = rand(0, $amount);
38             $i = 0;
39         
40             while ($quotes[$i] < $index)  {
41                 $i++;   
42             }
43
44             return $this->getRandomQuote($dir . "/" .$files[$i]);
45         }
46         return -1;
47     }
48
49     /*
50      Reads the number of quotes in the file. 
51     */
52     function getNumberOfQuotes($file) {
53         $fd = fopen($file, "rb");
54         $this->readLong($fd); // Just move over the first long. Might as well be fseek.
55         $len =  $this->readLong($fd);
56         fclose($fd);
57         return $len;
58     }
59     /*
60      Picks quote number $index from the dat-file in $file.
61     */
62     function getExactQuote($file, $index) {
63         if (is_file($file) == false) {
64             echo "Input must be a file!<br/>";
65             return;
66         }
67         
68         if ( ($fd = fopen($file, "rb")) == false ) {
69             echo "Cannot open $file<br/>";      
70             return;
71         }
72         fseek($fd, 24 + 4 * $index);
73         
74         $phys_index = $this->readLong($fd);
75         
76         fclose($fd);
77         
78         $quotefile = substr($file, 0, strlen($file) - 4);
79
80         if ( ($fd = fopen($quotefile, "rb")) == false ) {
81             echo "Cannot find file $quotefile!<br/>";
82         }               
83         
84         $res = $this->getQuote($fd, $phys_index);
85         fclose($fd);
86         
87         return $res;    
88     }
89
90     /*
91      Returns a random quote from $file.
92     */
93     function getRandomQuote($file) {
94         $number = $this->getNumberOfQuotes($file);
95
96         $index = rand(0, $number - 1);
97
98         return $this->getExactQuote($file, $index);
99     }   
100
101     /*
102      Reads a quote from the specified index.
103     */
104     function getQuote($fd, $index) {
105         fseek($fd, $index);
106         $line=""; $res = "";
107         do {
108             $res = $res . $line;                
109             $line = fgets($fd, 1024) . "<br>";
110         } while ( ($line[0] != "%") && (!feof($fd)) );
111
112         return $res;
113     }
114
115     /*
116      Gets indexes from the file pointed to by the filedescriptor $fd.
117     */
118     function getIndices($fd) {
119         fseek($fd, 24, SEEK_SET);
120         $i = 0;
121         
122         while ( feof($fd) == FALSE ) {
123             $res[$i] = readLong($fd);
124             $i++;
125         }
126         return $res;
127     }
128
129     function readLong($fd) {
130         $res = fread($fd, 4);
131         $l = ord($res[3]);
132         $l += ord($res[2]) << 8;
133         $l += ord($res[1]) << 16;
134         $l += ord($res[0]) << 24;
135         return $l;
136     }
137
138
139     function createIndexFile($file) {
140         $fd = @fopen($file, "r");
141         if ($fd == false) {
142             echo "File error!";
143             exit;
144         }
145
146         $i = 1;
147         $length = 0;
148         $longest = 0;
149         $shortest = 100000;
150         $indices[0] = 0;
151         while (!feof($fd)) {
152             $line = fgets($fd);
153             if ($line == "%\n") {
154                 $indices[$i] = ftell($fd);
155                 $i++;
156                 if ($length > $longest)
157                     $longest = $length;
158         
159                 if ($length < $shortest)
160                     $shortest = $length;
161
162                 $length = 0;
163             } else {
164                 $length = $length + strlen($line);
165             }
166         }
167
168         fclose($fd);
169
170         $fd = @fopen($file . ".dat", "w");
171
172         if ($fd == false) {
173             echo "<!-- createIndexFile: Could not write to file....-->";
174             exit;
175         }
176
177         // Write header.
178         $this->writeLong($fd, 2);
179         $this->writeLong($fd, count($indices));
180         $this->writeLong($fd, $longest);
181         $this->writeLong($fd, $shortest);
182         $this->writeLong($fd, 0);
183         $this->writeLong($fd, 37 << 24);
184
185         for ($i = 0 ; $i < count($indices) ; $i++) {
186             $this->writeLong($fd, $indices[$i]);
187         }
188
189         fclose($fd);
190     }
191
192     function writeLong($fd, $l) {
193         fwrite($fd, chr ( ($l >> 24) & 255));
194         fwrite($fd, chr ( ($l >> 16) & 255));
195         fwrite($fd, chr ( ($l >> 8) & 255));
196         fwrite($fd, chr ( $l & 255));
197     }
198 } // End of class
199 ?>