350 lines
10 KiB
PHP
350 lines
10 KiB
PHP
|
<?php
|
||
|
|
||
|
set_time_limit(0);
|
||
|
error_reporting(0);
|
||
|
require(".htconfig.php");
|
||
|
$db = @new mysqli($db_host,$db_user,$db_pass,$db_data);
|
||
|
|
||
|
header( "Content-type: text/html; charset=utf-8");
|
||
|
header( "Last-Modified: " . gmdate( "D, j M Y H:i:s" ) . " GMT" );
|
||
|
header( "Expires: " . gmdate( "D, j M Y H:i:s", time() ) . " GMT" );
|
||
|
header( "Cache-Control: no-store, no-cache, must-revalidate" ); // HTTP/1.1
|
||
|
header( "Cache-Control: post-check=0, pre-check=0", FALSE );
|
||
|
header( "Pragma: no-cache" ); // HTTP/1.0
|
||
|
|
||
|
$lang = 'en';
|
||
|
|
||
|
$offensive = $_GET['off'];
|
||
|
if($offensive == 'o')
|
||
|
$adult = 2;
|
||
|
elseif($offensive == 'a')
|
||
|
$adult = 1;
|
||
|
else
|
||
|
$adult = 0;
|
||
|
|
||
|
$length = (($_GET['length']) ? intval($_GET['length']) : 0);
|
||
|
$numlines = ((intval($_GET['numlines'])) ? intval($_GET['numlines']) : 0);
|
||
|
$cat = (($_GET['cat'] == '1') ? 1 : 0);
|
||
|
$equal = (($_GET['equal'] == '1') ? 1 : 0);
|
||
|
$stats = (($_GET['stats'] == '1') ? 1 : 0);
|
||
|
|
||
|
if(strlen($_GET['lang']))
|
||
|
$lang = @$db->real_escape_string($_GET['lang']);
|
||
|
|
||
|
if(strlen($_GET['pattern']))
|
||
|
$pattern = @$db->real_escape_string(urldecode($_GET['pattern']));
|
||
|
|
||
|
if(strlen($_GET['regex']))
|
||
|
$regex = @$db->real_escape_string(urldecode($_GET['regex']));
|
||
|
|
||
|
if(strlen($_GET['db']))
|
||
|
$table = @$db->real_escape_string(urldecode($_GET['db']));
|
||
|
else
|
||
|
$table = '';
|
||
|
|
||
|
if($length < 0)
|
||
|
$length = 0;
|
||
|
if($numlines < 0)
|
||
|
$numlines = 0;
|
||
|
|
||
|
function do_query($table,$length,$numlines,$adult,$cat,$limit,$lang,$pattern,$regex,$equal) {
|
||
|
global $db;
|
||
|
$rnd = mt_rand();
|
||
|
$r = [];
|
||
|
|
||
|
$typesql = (($table) ? " WHERE `category` = '$table' " : " WHERE 1 ");
|
||
|
$lengthsql = (($length) ? " AND LENGTH(`text`) < $length " : "" );
|
||
|
|
||
|
if($adult == 2)
|
||
|
$adultsql = " AND offensive = 1 ";
|
||
|
elseif($adult == 1)
|
||
|
$adultsql = "";
|
||
|
else
|
||
|
$adultsql = " AND offensive = 0 ";
|
||
|
|
||
|
|
||
|
if($numlines)
|
||
|
$lengthsql .=
|
||
|
" AND (LENGTH(`text`) - LENGTH(REPLACE(`text`,\"\n\",\"\"))) <= $numlines ";
|
||
|
|
||
|
$langsql = " AND lang = '$lang' ";
|
||
|
|
||
|
$patsql = '';
|
||
|
if(strlen($pattern))
|
||
|
$patsql = " AND MATCH text AGAINST ('$pattern' IN BOOLEAN MODE) ";
|
||
|
|
||
|
$regexsql = '';
|
||
|
if(strlen($regex))
|
||
|
$regexsql = " AND text REGEXP '$regex' ";
|
||
|
|
||
|
$eqsql = '';
|
||
|
|
||
|
if($equal) {
|
||
|
$catsavail = [];
|
||
|
$res = @$db->query("SELECT DISTINCT ( `category` ) FROM `fortune`
|
||
|
$typesql
|
||
|
$adultsql
|
||
|
$lengthsql
|
||
|
$langsql
|
||
|
$patsql
|
||
|
$regexsql ");
|
||
|
if($res->num_rows) {
|
||
|
while($x = $res->fetch_array(MYSQL_ASSOC))
|
||
|
$catsavail[] = $x['category'];
|
||
|
|
||
|
$eqsql = " AND `category` = '"
|
||
|
. $catsavail[mt_rand(0,$res->num_rows - 1)] . "' ";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$result = @$db->query("SELECT `text`, `category` FROM `fortune`
|
||
|
$typesql
|
||
|
$adultsql
|
||
|
$lengthsql
|
||
|
$langsql
|
||
|
$patsql
|
||
|
$regexsql
|
||
|
$eqsql
|
||
|
ORDER BY RAND($rnd)
|
||
|
LIMIT $limit");
|
||
|
|
||
|
if($result->num_rows) {
|
||
|
while($x = $result->fetch_array(MYSQL_ASSOC))
|
||
|
$r[] = fortune_to_html($x['text'])
|
||
|
.(($cat) ? "<br />[{$x['category']}]<br />" : "");
|
||
|
}
|
||
|
return $r;
|
||
|
}
|
||
|
|
||
|
|
||
|
function do_stats($table,$length,$numlines,$adult,$cat,$limit,$lang,$pattern,$regex,$equal) {
|
||
|
global $db;
|
||
|
$rnd = mt_rand();
|
||
|
$r = [];
|
||
|
|
||
|
$typesql = (($table) ? " WHERE `category` = '$table' " : " WHERE 1 ");
|
||
|
$lengthsql = (($length) ? " AND LENGTH(`text`) < $length " : "" );
|
||
|
|
||
|
if($adult == 2)
|
||
|
$adultsql = " AND offensive = 1 ";
|
||
|
elseif($adult == 1)
|
||
|
$adultsql = "";
|
||
|
else
|
||
|
$adultsql = " AND offensive = 0 ";
|
||
|
|
||
|
|
||
|
if($numlines)
|
||
|
$lengthsql .=
|
||
|
" AND (LENGTH(`text`) - LENGTH(REPLACE(`text`,\"\n\",\"\"))) <= $numlines ";
|
||
|
|
||
|
$langsql = " AND lang = '$lang' ";
|
||
|
|
||
|
$patsql = '';
|
||
|
if(strlen($pattern))
|
||
|
$patsql = " AND MATCH text AGAINST ('$pattern' IN BOOLEAN MODE) ";
|
||
|
|
||
|
$regexsql = '';
|
||
|
if(strlen($regex))
|
||
|
$regexsql = " AND text REGEXP '$regex' ";
|
||
|
|
||
|
$eqsql = '';
|
||
|
|
||
|
$result = @$db->query("SELECT `text`, `category` FROM `fortune`
|
||
|
$typesql
|
||
|
$adultsql
|
||
|
$lengthsql
|
||
|
$langsql
|
||
|
$patsql
|
||
|
$regexsql
|
||
|
$eqsql");
|
||
|
|
||
|
|
||
|
echo '<br />' . $result->num_rows . ' matching quotations.<br />';
|
||
|
|
||
|
|
||
|
$res = @$db->query("SELECT DISTINCT ( `category` ) FROM `fortune`
|
||
|
$typesql
|
||
|
$adultsql
|
||
|
$lengthsql
|
||
|
$langsql
|
||
|
$patsql
|
||
|
$regexsql ");
|
||
|
if($res->num_rows) {
|
||
|
echo '<br />Matching Databases:<br />';
|
||
|
while($x = $res->fetch_array(MYSQL_ASSOC))
|
||
|
echo $x['category'].'<br />';
|
||
|
|
||
|
}
|
||
|
else
|
||
|
echo '<br />No matching databases using those search parameters - please refine your options.<br />';
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
function fortune_to_html($s) {
|
||
|
|
||
|
// First pass - escape all the HTML entities, and while we're at it
|
||
|
// get rid of any MS-DOS end-of-line characters and expand tabs to
|
||
|
// 8 non-breaking spaces, and translate linefeeds to <br />.
|
||
|
// We also get rid of ^G which used to sound the terminal beep or bell
|
||
|
// on ASCII terminals and were humourous in some fortunes.
|
||
|
// We could map these to autoplay a short sound file but browser support
|
||
|
// is still sketchy and then there's the issue of where to locate the
|
||
|
// URL, and a lot of people find autoplay sounds downright annoying.
|
||
|
// So for now, just remove them.
|
||
|
|
||
|
$s = str_replace(
|
||
|
["&",
|
||
|
"<",
|
||
|
">",
|
||
|
'"',
|
||
|
"\007",
|
||
|
"\t",
|
||
|
"\r",
|
||
|
"\n"],
|
||
|
|
||
|
["&",
|
||
|
"<",
|
||
|
">",
|
||
|
""",
|
||
|
"",
|
||
|
" ",
|
||
|
"",
|
||
|
"<br />"],
|
||
|
$s);
|
||
|
// Replace pseudo diacritics
|
||
|
// These were used to produce accented characters. For instance an accented
|
||
|
// e would have been encoded by '^He - the backspace moving the cursor
|
||
|
// backward so both the single quote and the e would appear in the same
|
||
|
// character position. Umlauts were quite clever - they used a double quote
|
||
|
// as the accent mark over a normal character.
|
||
|
|
||
|
$s = preg_replace("/'\010([a-zA-Z])/","&\\1acute;",$s);
|
||
|
$s = preg_replace("/\"\010([a-zA-Z])/","&\\1uml;",$s);
|
||
|
$s = preg_replace("/\`\010([a-zA-Z])/","&\\1grave;",$s);
|
||
|
$s = preg_replace("/\^\010([a-zA-Z])/","&\\1circ;",$s);
|
||
|
$s = preg_replace("/\~\010([a-zA-Z])/","&\\1tilde;",$s);
|
||
|
|
||
|
// Ignore multiple underlines for the same character. These were
|
||
|
// most useful when sent to a line printer back in the day as it
|
||
|
// would type over the same character a number of times making it
|
||
|
// much darker (e.g. bold). I think there are only one or two
|
||
|
// instances of this in the current (2008) fortune cookie database.
|
||
|
|
||
|
$s = preg_replace("/(_\010)+/","_\010",$s);
|
||
|
// Map the characters which sit underneath a backspace.
|
||
|
// If you can come up with a regex to do all of the following
|
||
|
// madness - be my guest.
|
||
|
// It's not as simple as you think. We need to take something
|
||
|
// that has been backspaced over an arbitrary number of times
|
||
|
// and wrap a forward looking matching number of characters in
|
||
|
// HTML, whilst deciding if it's intended as an underline or
|
||
|
// strikeout sequence.
|
||
|
|
||
|
// Essentially we produce a string of '1' and '0' characters
|
||
|
// the same length as the source text.
|
||
|
// Any position which is marked '1' has been backspaced over.
|
||
|
|
||
|
$cursor = 0;
|
||
|
$dst = $s;
|
||
|
$bs_found = false;
|
||
|
for($x = 0; $x < strlen($s); $x ++) {
|
||
|
if($s[$x] == "\010" && $cursor) {
|
||
|
$bs_found = true;
|
||
|
$cursor --;
|
||
|
$dst[$cursor] = '1';
|
||
|
$dst[$x] = '0';
|
||
|
$continue;
|
||
|
}
|
||
|
else {
|
||
|
if($bs_found) {
|
||
|
$bs_found = false;
|
||
|
$cursor = $x;
|
||
|
}
|
||
|
$dst[$cursor] = '0';
|
||
|
$cursor ++;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
$out = '';
|
||
|
$strike = false;
|
||
|
$bold = false;
|
||
|
|
||
|
// Underline sequence, convert to bold to avoid confusion with links.
|
||
|
// These were generally used for emphasis so it's a reasonable choice.
|
||
|
// Please note that this logic will fail if there is an underline sequence
|
||
|
// and also a strikeout sequence in the same fortune.
|
||
|
|
||
|
if(strstr($s,"_\010")) {
|
||
|
$len = 0;
|
||
|
for($x = 0; $x < strlen($s); $x ++) {
|
||
|
if($dst[$x] == '1') {
|
||
|
$len ++;
|
||
|
$bold = true;
|
||
|
}
|
||
|
else {
|
||
|
if($bold) {
|
||
|
$out .= '<strong>';
|
||
|
while($s[$x] == "\010")
|
||
|
$x ++;
|
||
|
$out .= substr($s,$x,$len);
|
||
|
$out .= '</strong>';
|
||
|
$x = $x + $len - 1;
|
||
|
$len = 0;
|
||
|
$bold = false;
|
||
|
}
|
||
|
else
|
||
|
$out .= $s[$x];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// These aren't seen very often these days - simulation of
|
||
|
// backspace/replace. You could occasionally see the original text
|
||
|
// on slower terminals before it got replaced. Once modems reached
|
||
|
// 4800/9600 baud in the late 70's and early 80's the effect was
|
||
|
// mostly lost - but if you find a really old fortune file you might
|
||
|
// encounter a few of these.
|
||
|
|
||
|
else {
|
||
|
for($x = 0; $x < strlen($s); $x ++) {
|
||
|
if($dst[$x] == '1') {
|
||
|
if($strike)
|
||
|
$out .= $s[$x];
|
||
|
else
|
||
|
$out .= '<strike>'.$s[$x];
|
||
|
$strike = true;
|
||
|
}
|
||
|
else {
|
||
|
if($strike)
|
||
|
$out .= '</strike>';
|
||
|
$strike = false;
|
||
|
$out .= $s[$x];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Many of the underline sequences are also wrapped in asterisks,
|
||
|
// which was yet another way of marking ASCII as 'bold'.
|
||
|
// So if it's an underline sequence, and there are asterisks
|
||
|
// on both ends, strip the asterisks as we've already emboldened the text.
|
||
|
|
||
|
$out = preg_replace('/\*(<strong>[^<]*<\/strong>)\*/',"\\1",$out);
|
||
|
|
||
|
// Finally, remove the backspace characters which we don't need anymore.
|
||
|
|
||
|
return str_replace("\010","",$out);
|
||
|
}
|
||
|
|
||
|
$result1 = do_query($table,$length,$numlines,$adult,$cat,1,$lang,$pattern,$regex,$equal);
|
||
|
|
||
|
if(count($result1))
|
||
|
echo $result1[0];
|
||
|
|
||
|
if($stats)
|
||
|
do_stats($table,$length,$numlines,$adult,$cat,1,$lang,$pattern,$regex,$equal);
|
||
|
|
||
|
|