5 require(".htconfig.php");
6 $db = @new mysqli($db_host,$db_user,$db_pass,$db_data);
8 header( "Content-type: text/html; charset=utf-8");
9 header( "Last-Modified: " . gmdate( "D, j M Y H:i:s" ) . " GMT" );
10 header( "Expires: " . gmdate( "D, j M Y H:i:s", time() ) . " GMT" );
11 header( "Cache-Control: no-store, no-cache, must-revalidate" ); // HTTP/1.1
12 header( "Cache-Control: post-check=0, pre-check=0", FALSE );
13 header( "Pragma: no-cache" ); // HTTP/1.0
17 $offensive = $_GET['off'];
20 elseif($offensive == 'a')
25 $length = (($_GET['length']) ? intval($_GET['length']) : 0);
26 $numlines = ((intval($_GET['numlines'])) ? intval($_GET['numlines']) : 0);
27 $cat = (($_GET['cat'] == '1') ? 1 : 0);
28 $equal = (($_GET['equal'] == '1') ? 1 : 0);
29 $stats = (($_GET['stats'] == '1') ? 1 : 0);
31 if(strlen($_GET['lang']))
32 $lang = @$db->real_escape_string($_GET['lang']);
34 if(strlen($_GET['pattern']))
35 $pattern = @$db->real_escape_string(urldecode($_GET['pattern']));
37 if(strlen($_GET['regex']))
38 $regex = @$db->real_escape_string(urldecode($_GET['regex']));
40 if(strlen($_GET['db']))
41 $table = @$db->real_escape_string(urldecode($_GET['db']));
50 function do_query($table,$length,$numlines,$adult,$cat,$limit,$lang,$pattern,$regex,$equal) {
55 $typesql = (($table) ? " WHERE `category` = '$table' " : " WHERE 1 ");
56 $lengthsql = (($length) ? " AND LENGTH(`text`) < $length " : "" );
59 $adultsql = " AND offensive = 1 ";
63 $adultsql = " AND offensive = 0 ";
68 " AND (LENGTH(`text`) - LENGTH(REPLACE(`text`,\"\n\",\"\"))) <= $numlines ";
70 $langsql = " AND lang = '$lang' ";
74 $patsql = " AND MATCH text AGAINST ('$pattern' IN BOOLEAN MODE) ";
78 $regexsql = " AND text REGEXP '$regex' ";
84 $res = @$db->query("SELECT DISTINCT ( `category` ) FROM `fortune`
92 while($x = $res->fetch_array(MYSQL_ASSOC))
93 $catsavail[] = $x['category'];
95 $eqsql = " AND `category` = '"
96 . $catsavail[mt_rand(0,$res->num_rows - 1)] . "' ";
100 $result = @$db->query("SELECT `text`, `category` FROM `fortune`
111 if($result->num_rows) {
112 while($x = $result->fetch_array(MYSQL_ASSOC))
113 $r[] = fortune_to_html($x['text'])
114 .(($cat) ? "<br />[{$x['category']}]<br />" : "");
120 function do_stats($table,$length,$numlines,$adult,$cat,$limit,$lang,$pattern,$regex,$equal) {
125 $typesql = (($table) ? " WHERE `category` = '$table' " : " WHERE 1 ");
126 $lengthsql = (($length) ? " AND LENGTH(`text`) < $length " : "" );
129 $adultsql = " AND offensive = 1 ";
133 $adultsql = " AND offensive = 0 ";
138 " AND (LENGTH(`text`) - LENGTH(REPLACE(`text`,\"\n\",\"\"))) <= $numlines ";
140 $langsql = " AND lang = '$lang' ";
144 $patsql = " AND MATCH text AGAINST ('$pattern' IN BOOLEAN MODE) ";
148 $regexsql = " AND text REGEXP '$regex' ";
152 $result = @$db->query("SELECT `text`, `category` FROM `fortune`
162 echo '<br />' . $result->num_rows . ' matching quotations.<br />';
165 $res = @$db->query("SELECT DISTINCT ( `category` ) FROM `fortune`
173 echo '<br />Matching Databases:<br />';
174 while($x = $res->fetch_array(MYSQL_ASSOC))
175 echo $x['category'].'<br />';
179 echo '<br />No matching databases using those search parameters - please refine your options.<br />';
185 function fortune_to_html($s) {
187 // First pass - escape all the HTML entities, and while we're at it
188 // get rid of any MS-DOS end-of-line characters and expand tabs to
189 // 8 non-breaking spaces, and translate linefeeds to <br />.
190 // We also get rid of ^G which used to sound the terminal beep or bell
191 // on ASCII terminals and were humourous in some fortunes.
192 // We could map these to autoplay a short sound file but browser support
193 // is still sketchy and then there's the issue of where to locate the
194 // URL, and a lot of people find autoplay sounds downright annoying.
195 // So for now, just remove them.
212 " ",
216 // Replace pseudo diacritics
217 // These were used to produce accented characters. For instance an accented
218 // e would have been encoded by '^He - the backspace moving the cursor
219 // backward so both the single quote and the e would appear in the same
220 // character position. Umlauts were quite clever - they used a double quote
221 // as the accent mark over a normal character.
223 $s = preg_replace("/'\010([a-zA-Z])/","&\\1acute;",$s);
224 $s = preg_replace("/\"\010([a-zA-Z])/","&\\1uml;",$s);
225 $s = preg_replace("/\`\010([a-zA-Z])/","&\\1grave;",$s);
226 $s = preg_replace("/\^\010([a-zA-Z])/","&\\1circ;",$s);
227 $s = preg_replace("/\~\010([a-zA-Z])/","&\\1tilde;",$s);
229 // Ignore multiple underlines for the same character. These were
230 // most useful when sent to a line printer back in the day as it
231 // would type over the same character a number of times making it
232 // much darker (e.g. bold). I think there are only one or two
233 // instances of this in the current (2008) fortune cookie database.
235 $s = preg_replace("/(_\010)+/","_\010",$s);
236 // Map the characters which sit underneath a backspace.
237 // If you can come up with a regex to do all of the following
238 // madness - be my guest.
239 // It's not as simple as you think. We need to take something
240 // that has been backspaced over an arbitrary number of times
241 // and wrap a forward looking matching number of characters in
242 // HTML, whilst deciding if it's intended as an underline or
243 // strikeout sequence.
245 // Essentially we produce a string of '1' and '0' characters
246 // the same length as the source text.
247 // Any position which is marked '1' has been backspaced over.
252 for($x = 0; $x < strlen($s); $x ++) {
253 if($s[$x] == "\010" && $cursor) {
275 // Underline sequence, convert to bold to avoid confusion with links.
276 // These were generally used for emphasis so it's a reasonable choice.
277 // Please note that this logic will fail if there is an underline sequence
278 // and also a strikeout sequence in the same fortune.
280 if(strstr($s,"_\010")) {
282 for($x = 0; $x < strlen($s); $x ++) {
283 if($dst[$x] == '1') {
290 while($s[$x] == "\010")
292 $out .= substr($s,$x,$len);
304 // These aren't seen very often these days - simulation of
305 // backspace/replace. You could occasionally see the original text
306 // on slower terminals before it got replaced. Once modems reached
307 // 4800/9600 baud in the late 70's and early 80's the effect was
308 // mostly lost - but if you find a really old fortune file you might
309 // encounter a few of these.
312 for($x = 0; $x < strlen($s); $x ++) {
313 if($dst[$x] == '1') {
317 $out .= '<strike>'.$s[$x];
329 // Many of the underline sequences are also wrapped in asterisks,
330 // which was yet another way of marking ASCII as 'bold'.
331 // So if it's an underline sequence, and there are asterisks
332 // on both ends, strip the asterisks as we've already emboldened the text.
334 $out = preg_replace('/\*(<strong>[^<]*<\/strong>)\*/',"\\1",$out);
336 // Finally, remove the backspace characters which we don't need anymore.
338 return str_replace("\010","",$out);
341 $result1 = do_query($table,$length,$numlines,$adult,$cat,1,$lang,$pattern,$regex,$equal);
347 do_stats($table,$length,$numlines,$adult,$cat,1,$lang,$pattern,$regex,$equal);