Skip to content

Instantly share code, notes, and snippets.

@wkitty42
Created October 19, 2018 17:07
Show Gist options
  • Save wkitty42/7a9b599e3b8391c45a39853082638f9e to your computer and use it in GitHub Desktop.
Save wkitty42/7a9b599e3b8391c45a39853082638f9e to your computer and use it in GitHub Desktop.
<?php
/*
Main methods to use:
quoteFromDir($dir):
Quotes from any of the fortune-files in the dir.
getRandomQuote($file):
Quotes from the specific file.
Written by Henrik Aasted Sorensen, [email protected]
Read more at http://www.aasted.org/quote
*/
class Fortune {
function quoteFromDir($dir) {
//echo "quoteFromDir: using " . $dir . "<br>\n";
if (substr($dir, strlen($dir) - 1) != "/") {
//echo "quoteFromDir: appending / to directory name<br>\n";
$dir = $dir . "/";
//echo "quoteFromDir: using " . $dir . "<br>\n";
}
$amount = 0;
$index = 0;
if ( $handle = opendir($dir) ) {
while (false !== ($file = readdir($handle))) {
//echo "quoteFromDir: looking at " . $file . "<br>\n";
if ( strpos($file, ".dat") != false) {
$len = strlen($file);
if (substr($file, $len - 4) == ".dat"){
$number = $this->getNumberOfQuotes($dir . $file);
$amount += $number;
$quotes[$index] = $amount;
$files[$index] = $file;
$index++;
}
}
}
//srand((double)microtime()*1000000);
//$index = rand(0, $amount);
mt_srand((double)microtime()*1000000);
$index = mt_rand(0, $amount);
$i = 0;
while ($quotes[$i] < $index) {
$i++;
}
//echo "quoteFromDir: in directory " . $dir . " chose " . $files[$i] . "<br>\n";
return $this->getRandomQuote($dir .$files[$i]);
}
return -1;
}
/*
Reads the number of quotes in the file.
*/
function getNumberOfQuotes($file) {
//echo "getNumberOfQuotes: opening " . $file . "<br>\n";
$fd = fopen($file, "rb");
//echo "getNumberOfQuotes: reading " . $file . "<br>\n";
$this->readLong($fd); // Just move over the first long. Might as well be fseek.
$len = $this->readLong($fd);
//echo "getNumberOfQuotes: " . $len . " quotes in " . $file . "<br>\n";
fclose($fd);
//echo "getNumberOfQuotes: closing " . $file . "<br>\n";
return $len;
}
/*
Picks quote number $index from the dat-file in $file.
*/
function getExactQuote($file, $index) {
//echo "getExactQuote: " . $file . " - " . $index . "<br>\n";
if (is_file($file) == FALSE) {
echo "Input must be a file!<br/>";
return;
}
if ( ($fd = fopen($file, "rb")) == FALSE ) {
echo "Cannot open $file<br/>\n";
return;
}
fseek($fd, 24 + 4 * $index);
$phys_index = $this->readLong($fd);
fclose($fd);
$quotefile = substr($file, 0, strlen($file) - 4);
if ( ($fd = fopen($quotefile, "rb")) == FALSE ) {
echo "Cannot find file $quotefile!<br/>";
}
$res = $this->getQuote($fd, $phys_index);
fclose($fd);
$len = strlen($file);
// echo "<!-- " . substr($file, 12, -4) . ":" . $index . " -->\n";
echo "<center>Quote #" . $index . " from \"" . substr($file, 12, -4) . "\":</center><hr style=\"color: yellow;\"><br>\n";
return $res . "\n";
}
/*
Returns a random quote from $file.
*/
function getRandomQuote($file) {
//echo "getRandomQuote: using " . $file . "<br/>\n";
$len = strlen($file);
if (substr($file, $len - 4) == ".dat"){
//echo "getRandomQuote: file has proper extension<br>\n";
} else {
//echo "getRandomQuote: adding .dat extension<br>\n";
$file = $file . ".dat";
//echo "getRandomQuote: using " . $file . "<br/>\n";
}
$number = $this->getNumberOfQuotes($file);
//srand((double)microtime()*1000000);
//$index = rand(0, $number - 1);
mt_srand((double)microtime()*1000000);
$index = mt_rand(0, $number - 1);
return $this->getExactQuote($file, $index);
}
/*
Reads a quote from the specified index.
*/
function getQuote($fd, $index) {
fseek($fd, $index);
$line=""; $res = "";
do {
$res = $res . $line;
$line = fgets($fd, 2048) . "<br>";
} while ( ($line[0] != "%") && (!feof($fd)) );
return $res;
}
/*
Gets indexes from the file pointed to by the filedescriptor $fd.
*/
function getIndices($fd) {
fseek($fd, 24, SEEK_SET);
$i = 0;
while ( feof($fd) == FALSE ) {
$res[$i] = readLong($fd);
$i++;
}
return $res;
}
/*
reads a long integer from the index file
*/
function readLong($fd) {
$res = fread($fd, 4);
$l = ord($res[3]);
$l += ord($res[2]) << 8;
$l += ord($res[1]) << 16;
$l += ord($res[0]) << 24;
return $l;
}
/*
creates the binary index for the specified file
*/
function createIndexFile($file) {
$fd = @fopen($file, "r");
if ($fd == false) {
echo "createIndexFile: Could not open file " . $file . " for reading<br>\n";
exit;
}
$i = 1;
$length = 0;
$longest = 0;
$shortest = 100000;
$indices[0] = 0;
while (!feof($fd)) {
$line = fgets($fd);
if ($line == "%\r\n") {
$indices[$i] = ftell($fd);
$i++;
if ($length > $longest)
$longest = $length;
if ($length < $shortest)
$shortest = $length;
$length = 0;
} elseif ($line == "%\n") {
$indices[$i] = ftell($fd);
$i++;
if ($length > $longest)
$longest = $length;
if ($length < $shortest)
$shortest = $length;
$length = 0;
} else {
$length = $length + strlen($line);
}
}
fclose($fd);
$fd = @fopen($file . ".dat", "w");
if ($fd == false) {
echo "createIndexFile: Could not open file " . $file . ".dat for writing<br>\n";
exit;
}
// Write header.
$this->writeLong($fd, 2);
$this->writeLong($fd, count($indices));
$this->writeLong($fd, $longest);
$this->writeLong($fd, $shortest);
$this->writeLong($fd, 0);
$this->writeLong($fd, 37 << 24);
for ($i = 0 ; $i < count($indices) ; $i++) {
$this->writeLong($fd, $indices[$i]);
}
fclose($fd);
}
/*
writes a long integer
*/
function writeLong($fd, $l) {
fwrite($fd, chr ( ($l >> 24) & 255));
fwrite($fd, chr ( ($l >> 16) & 255));
fwrite($fd, chr ( ($l >> 8) & 255));
fwrite($fd, chr ( $l & 255));
}
} // End of class
// echo "<!-- PHP Fortune - Made by [email protected]. HP: http://www.aasted.org -->\n";
// echo "<!-- mods by wkitty42 - Aug 2004 -->\n";
// echo "<!-- 1. corrected for %CRLF instead of just %LF when creating indexes -->\n";
// echo "<!-- 2. fixed getRandomQuote to append .dat if needed for when called directly -->\n";
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment