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