289 public $charset =
'ABCDEFGHKLMNPRSTUVWYZabcdefghklmnprstuvwyz23456789';
631 $this->securimage_path = dirname(__FILE__);
634 foreach(
$options as $prop => $val) {
635 if ($prop ==
'captchaId') {
637 $this->use_database =
true;
638 }
else if ($prop ==
'use_sqlite_db') {
639 trigger_error(
"The use_sqlite_db option is deprecated, use 'use_database' instead", E_USER_NOTICE);
646 $this->image_bg_color = $this->
initColor($this->image_bg_color,
'#ffffff');
647 $this->text_color = $this->
initColor($this->text_color,
'#616161');
648 $this->line_color = $this->
initColor($this->line_color,
'#616161');
649 $this->noise_color = $this->
initColor($this->noise_color,
'#616161');
650 $this->signature_color = $this->
initColor($this->signature_color,
'#616161');
652 if (is_null($this->ttf_file)) {
653 $this->ttf_file = $this->securimage_path .
'/AHGBold.ttf';
658 if (is_null($this->wordlist_file)) {
659 $this->wordlist_file = $this->securimage_path .
'/words/words.txt';
662 if (is_null($this->database_file)) {
663 $this->database_file = $this->securimage_path .
'/database/securimage.sq3';
666 if (is_null($this->audio_path)) {
667 $this->audio_path = $this->securimage_path .
'/audio/en/';
670 if (is_null($this->audio_noise_path)) {
671 $this->audio_noise_path = $this->securimage_path .
'/audio/noise/';
674 if (is_null($this->audio_use_noise)) {
675 $this->audio_use_noise =
true;
678 if (is_null($this->degrade_audio)) {
679 $this->degrade_audio =
true;
682 if (is_null($this->code_length) || (
int)$this->code_length < 1) {
683 $this->code_length = 6;
686 if (is_null($this->perturbation) || !is_numeric($this->perturbation)) {
687 $this->perturbation = 0.75;
690 if (is_null($this->
namespace) || !is_string($this->
namespace)) {
691 $this->
namespace = 'default';
694 if (is_null($this->no_exit)) {
695 $this->no_exit =
false;
698 if (is_null($this->no_session)) {
699 $this->no_session =
false;
702 if (is_null($this->send_headers)) {
703 $this->send_headers =
true;
706 if ($this->no_session !=
true) {
708 if ( session_id() ==
'' ) {
709 if (!is_null($this->session_name) && trim($this->session_name) !=
'') {
710 session_name(trim($this->session_name));
723 return dirname(__FILE__);
737 if (is_null(
$new) || (
bool)
$new ==
true) {
738 $id = sha1(uniqid(
$_SERVER[
'REMOTE_ADDR'],
true));
739 $opts =
array(
'no_session' =>
true,
740 'use_database' =>
true);
742 $si =
new self($opts);
765 $opts =
array(
'captchaId' => $id,
766 'no_session' =>
true,
767 'use_database' =>
true);
771 $si =
new self($opts);
773 if (
$si->openDatabase()) {
776 if (is_array(
$code)) {
778 $si->code_display =
$code[
'code_disp'];
781 if (
$si->check($value)) {
782 $si->clearCodeFromDatabase();
807 public function show($background_image =
'')
809 set_error_handler(
array(&$this,
'errorHandler'));
811 if($background_image !=
'' && is_readable($background_image)) {
812 $this->bgimg = $background_image;
833 $this->code_entered =
$code;
835 return $this->correct_code;
849 set_error_handler(
array(&$this,
'errorHandler'));
851 require_once dirname(__FILE__) .
'/WavFile.php';
856 if (($fp = @fopen(dirname(__FILE__) .
'/si.error_log',
'a+')) !==
false) {
857 fwrite($fp,
date(
'Y-m-d H:i:s') .
': Securimage audio error "' . $ex->getMessage() .
'"' .
"\n");
865 if ($this->send_headers) {
866 $uniq = md5(uniqid(microtime()));
867 header(
"Content-Disposition: attachment; filename=\"securimage_audio-{$uniq}.wav\"");
868 header(
'Cache-Control: no-store, no-cache, must-revalidate');
869 header(
'Expires: Sun, 1 Jan 2000 12:00:00 GMT');
870 header(
'Last-Modified: ' . gmdate(
'D, d M Y H:i:s') .
'GMT');
871 header(
'Content-type: audio/x-wav');
873 if (extension_loaded(
'zlib')) {
874 ini_set(
'zlib.output_compression',
true);
876 header(
'Content-Length: ' . strlen($audio));
882 echo '<hr /><strong>' 883 .
'Failed to generate audio file, content has already been ' 884 .
'output.<br />This is most likely due to misconfiguration or ' 885 .
'a PHP error was sent to the browser.</strong>';
888 restore_error_handler();
890 if (!$this->no_exit)
exit;
899 public function getCode($array =
false, $returnExisting =
false)
905 if ($returnExisting && strlen($this->code) > 0) {
907 return array(
'code' => $this->code,
908 'display' => $this->code_display,
909 'code_display' => $this->code_display,
916 if ($this->no_session !=
true) {
917 if (isset(
$_SESSION[
'securimage_code_value'][$this->
namespace]) &&
918 trim(
$_SESSION[
'securimage_code_value'][$this->
namespace]) !=
'') {
920 $_SESSION[
'securimage_code_ctime'][$this->
namespace]) ==
false) {
928 if (empty(
$code) && $this->use_database) {
934 if ($array ==
true) {
935 return array(
'code' =>
$code,
'ctime' => $time,
'display' => $disp);
946 if( ($this->use_transparent_text ==
true || $this->bgimg !=
'') && function_exists(
'imagecreatetruecolor')) {
947 $imagecreate =
'imagecreatetruecolor';
949 $imagecreate =
'imagecreate';
952 $this->im = $imagecreate($this->image_width, $this->image_height);
953 $this->tmpimg = $imagecreate($this->image_width * $this->iscale, $this->image_height * $this->iscale);
956 imagepalettecopy($this->tmpimg, $this->im);
966 if (is_string($this->display_value) && strlen($this->display_value) > 0) {
969 $this->display_value :
970 strtolower($this->display_value);
977 if (is_array(
$code)) {
978 $this->code =
$code[
'code'];
979 $this->code_display =
$code[
'code_disp'];
991 if ($this->noise_level > 0) {
997 if ($this->perturbation > 0 && is_readable($this->ttf_file)) {
1001 if ($this->num_lines > 0) {
1005 if (trim($this->image_signature) !=
'') {
1018 $this->gdbgcolor = imagecolorallocate($this->im,
1019 $this->image_bg_color->r,
1020 $this->image_bg_color->g,
1021 $this->image_bg_color->b);
1023 $alpha = intval($this->text_transparency_percentage / 100 * 127);
1025 if ($this->use_transparent_text ==
true) {
1026 $this->gdtextcolor = imagecolorallocatealpha($this->im,
1027 $this->text_color->r,
1028 $this->text_color->g,
1029 $this->text_color->b,
1031 $this->gdlinecolor = imagecolorallocatealpha($this->im,
1032 $this->line_color->r,
1033 $this->line_color->g,
1034 $this->line_color->b,
1036 $this->gdnoisecolor = imagecolorallocatealpha($this->im,
1037 $this->noise_color->r,
1038 $this->noise_color->g,
1039 $this->noise_color->b,
1042 $this->gdtextcolor = imagecolorallocate($this->im,
1043 $this->text_color->r,
1044 $this->text_color->g,
1045 $this->text_color->b);
1046 $this->gdlinecolor = imagecolorallocate($this->im,
1047 $this->line_color->r,
1048 $this->line_color->g,
1049 $this->line_color->b);
1050 $this->gdnoisecolor = imagecolorallocate($this->im,
1051 $this->noise_color->r,
1052 $this->noise_color->g,
1053 $this->noise_color->b);
1056 $this->gdsignaturecolor = imagecolorallocate($this->im,
1057 $this->signature_color->r,
1058 $this->signature_color->g,
1059 $this->signature_color->b);
1069 imagefilledrectangle($this->im, 0, 0,
1070 $this->image_width, $this->image_height,
1072 imagefilledrectangle($this->tmpimg, 0, 0,
1073 $this->image_width * $this->iscale, $this->image_height * $this->iscale,
1076 if ($this->bgimg ==
'') {
1077 if ($this->background_directory != null &&
1078 is_dir($this->background_directory) &&
1079 is_readable($this->background_directory))
1082 if (
$img !=
false) {
1083 $this->bgimg =
$img;
1088 if ($this->bgimg ==
'') {
1092 $dat = @getimagesize($this->bgimg);
1098 case 1: $newim = @imagecreatefromgif($this->bgimg);
break;
1099 case 2: $newim = @imagecreatefromjpeg($this->bgimg);
break;
1100 case 3: $newim = @imagecreatefrompng($this->bgimg);
break;
1106 imagecopyresized($this->im, $newim, 0, 0, 0, 0,
1107 $this->image_width, $this->image_height,
1108 imagesx($newim), imagesy($newim));
1118 if ( ($dh = opendir($this->background_directory)) !==
false) {
1119 while ((
$file = readdir($dh)) !==
false) {
1120 if (preg_match(
'/(jpg|gif|png)$/i',
$file)) $images[] =
$file;
1125 if (
sizeof($images) > 0) {
1126 return rtrim($this->background_directory,
'/') .
'/' . $images[mt_rand(0,
sizeof($images)-1)];
1138 $this->code =
false;
1140 switch($this->captcha_type) {
1141 case self::SI_CAPTCHA_MATHEMATIC:
1144 $signs =
array(
'+',
'-',
'x');
1145 $left = mt_rand(1, 10);
1146 $right = mt_rand(1, 5);
1147 $sign = $signs[mt_rand(0, 2)];
1150 case 'x': $c = $left * $right;
break;
1151 case '-': $c = $left - $right;
break;
1152 default: $c = $left + $right;
break;
1157 $this->code_display =
"$left $sign $right";
1161 case self::SI_CAPTCHA_WORDS:
1163 $this->code = implode(
' ', $words);
1169 if ($this->use_wordlist && is_readable($this->wordlist_file)) {
1173 if ($this->code ==
false) {
1193 if (!is_readable($this->ttf_file)) {
1194 imagestring($this->im, 4, 10, ($this->image_height / 2) - 5,
'Failed to load TTF font file!', $this->gdtextcolor);
1196 if ($this->perturbation > 0) {
1197 $font_size = $height2 * .4;
1198 $bb = imageftbbox($font_size, 0, $this->ttf_file, $this->code_display);
1199 $tx = $bb[4] - $bb[0];
1200 $ty = $bb[5] - $bb[1];
1201 $x = floor($width2 / 2 - $tx / 2 - $bb[0]);
1202 $y = round($height2 / 2 - $ty / 2 - $bb[1]);
1204 imagettftext($this->tmpimg, $font_size, 0,
$x,
$y, $this->gdtextcolor, $this->ttf_file, $this->code_display);
1206 $font_size = $this->image_height * .4;
1207 $bb = imageftbbox($font_size, 0, $this->ttf_file, $this->code_display);
1208 $tx = $bb[4] - $bb[0];
1209 $ty = $bb[5] - $bb[1];
1210 $x = floor($this->image_width / 2 - $tx / 2 - $bb[0]);
1211 $y = round($this->image_height / 2 - $ty / 2 - $bb[1]);
1213 imagettftext($this->im, $font_size, 0,
$x,
$y, $this->gdtextcolor, $this->ttf_file, $this->code_display);
1230 for ($i = 0; $i < $numpoles; ++ $i) {
1231 $px[$i] = mt_rand($this->image_width * 0.2, $this->image_width * 0.8);
1232 $py[$i] = mt_rand($this->image_height * 0.2, $this->image_height * 0.8);
1233 $rad[$i] = mt_rand($this->image_height * 0.2, $this->image_height * 0.8);
1234 $tmp = ((- $this->
frand()) * 0.15) - .15;
1235 $amp[$i] = $this->perturbation * $tmp;
1238 $bgCol = imagecolorat($this->tmpimg, 0, 0);
1241 imagepalettecopy($this->im, $this->tmpimg);
1247 for ($i = 0; $i < $numpoles; ++ $i) {
1248 $dx = $ix -
$px[$i];
1249 $dy = $iy -
$py[$i];
1250 if ($dx == 0 && $dy == 0) {
1253 $r = sqrt($dx * $dx + $dy * $dy);
1254 if (
$r > $rad[$i]) {
1257 $rscale = $amp[$i] * sin(3.14 *
$r / $rad[$i]);
1258 $x += $dx * $rscale;
1259 $y += $dy * $rscale;
1264 if (
$x >= 0 && $x < $width2 && $y >= 0 &&
$y < $height2) {
1265 $c = imagecolorat($this->tmpimg,
$x,
$y);
1268 imagesetpixel($this->im, $ix, $iy, $c);
1280 $x = $this->image_width * (1 + $line) / ($this->num_lines + 1);
1281 $x += (0.5 - $this->
frand()) * $this->image_width / $this->num_lines;
1282 $y = mt_rand($this->image_height * 0.1, $this->image_height * 0.9);
1284 $theta = ($this->
frand() - 0.5) * M_PI * 0.7;
1286 $len = mt_rand(
$w * 0.4,
$w * 0.7);
1287 $lwid = mt_rand(0, 2);
1289 $k = $this->
frand() * 0.6 + 0.2;
1291 $phi = $this->
frand() * 6.28;
1293 $dx =
$step * cos($theta);
1294 $dy =
$step * sin($theta);
1296 $amp = 1.5 * $this->
frand() / ($k + 5.0 / $len);
1297 $x0 =
$x - 0.5 * $len * cos($theta);
1298 $y0 =
$y - 0.5 * $len * sin($theta);
1300 $ldx = round(- $dy * $lwid);
1301 $ldy = round($dx * $lwid);
1303 for ($i = 0; $i <
$n; ++ $i) {
1304 $x = $x0 + $i * $dx + $amp * $dy * sin($k * $i *
$step + $phi);
1305 $y = $y0 + $i * $dy - $amp * $dx * sin($k * $i *
$step + $phi);
1306 imagefilledrectangle($this->im,
$x,
$y,
$x + $lwid,
$y + $lwid, $this->gdlinecolor);
1316 if ($this->noise_level > 10) {
1322 $t0 = microtime(
true);
1326 $points = $this->image_width * $this->image_height *
$this->iscale;
1330 $x = mt_rand(10, $width);
1331 $y = mt_rand(10, $height);
1332 $size = mt_rand(7, 10);
1334 imagefilledarc($this->tmpimg,
$x,
$y,
$size,
$size, 0, 360, $this->gdnoisecolor, IMG_ARC_PIE);
1337 $t1 = microtime(
true);
1355 $bbox = imagettfbbox(10, 0, $this->signature_font, $this->image_signature);
1356 $textlen = $bbox[2] - $bbox[0];
1357 $x = $this->image_width - $textlen - 5;
1358 $y = $this->image_height - 3;
1360 imagettftext($this->im, 10, 0,
$x,
$y, $this->gdsignaturecolor, $this->signature_font, $this->image_signature);
1369 if ($this->send_headers) {
1374 header(
"Expires: Mon, 26 Jul 1997 05:00:00 GMT");
1375 header(
"Last-Modified: " . gmdate(
"D, d M Y H:i:s") .
"GMT");
1376 header(
"Cache-Control: no-store, no-cache, must-revalidate");
1377 header(
"Cache-Control: post-check=0, pre-check=0",
false);
1378 header(
"Pragma: no-cache");
1381 switch ($this->image_type) {
1382 case self::SI_IMAGE_JPEG:
1383 if ($this->send_headers)
header(
"Content-Type: image/jpeg");
1384 imagejpeg($this->im, null, 90);
1386 case self::SI_IMAGE_GIF:
1387 if ($this->send_headers)
header(
"Content-Type: image/gif");
1388 imagegif($this->im);
1391 if ($this->send_headers)
header(
"Content-Type: image/png");
1392 imagepng($this->im);
1396 echo '<hr /><strong>' 1397 .
'Failed to generate captcha image, content has already been ' 1398 .
'output.<br />This is most likely due to misconfiguration or ' 1399 .
'a PHP error was sent to the browser.</strong>';
1402 imagedestroy($this->im);
1403 restore_error_handler();
1405 if (!$this->no_exit)
exit;
1418 if (
$code[
'code'] ==
'') {
1419 if (strlen($this->display_value) > 0) {
1420 $code =
array(
'code' => $this->display_value,
'display' => $this->display_value);
1427 if (preg_match(
'/(\d+) (\+|-|x) (\d+)/i',
$code[
'display'], $eq)) {
1431 $sign = str_replace(
array(
'+',
'-',
'x'),
array(
'plus',
'minus',
'times'), $eq[2]);
1434 $letters =
array($left, $sign, $right);
1438 $length = strlen(
$code[
'display']);
1440 for($i = 0; $i < $length; ++$i) {
1441 $letter =
$code[
'display']{$i};
1442 $letters[] = $letter;
1458 $fp = fopen($this->wordlist_file,
'rb');
1459 if (!$fp)
return false;
1461 $fsize = filesize($this->wordlist_file);
1462 if ($fsize < 128)
return false;
1464 if ((
int)$numWords < 1 || (
int)$numWords > 5) $numWords = 1;
1469 fseek($fp, mt_rand(0, $fsize - 64), SEEK_SET);
1470 $data = fread($fp, 64);
1471 $data = preg_replace(
"/\r?\n/",
"\n",
$data);
1473 $start = @strpos(
$data,
"\n", mt_rand(0, 56)) + 1;
1479 }
else if ($end ===
false) {
1480 $end = strlen(
$data);
1485 }
while (++$i < $numWords);
1489 if ($numWords < 2) {
1503 if (function_exists(
'mb_strlen')) {
1505 $code .= mb_substr($this->charset, mt_rand(0, $cslen - 1), 1,
'UTF-8');
1509 $code .= substr($this->charset, mt_rand(0, $cslen - 1), 1);
1522 if (!is_string($this->code) || strlen($this->code) == 0) {
1530 if ($this->case_sensitive ==
false && preg_match(
'/[A-Z]/',
$code)) {
1533 $this->case_sensitive =
true;
1536 $code_entered = trim( (($this->case_sensitive) ? $this->code_entered
1537 : strtolower($this->code_entered))
1539 $this->correct_code =
false;
1542 if (strpos(
$code,
' ') !==
false) {
1544 $code_entered = preg_replace(
'/\s+/',
' ', $code_entered);
1545 $code_entered = strtolower($code_entered);
1548 if (
$code == $code_entered) {
1549 $this->correct_code =
true;
1550 if ($this->no_session !=
true) {
1564 if ($this->no_session !=
true) {
1565 if (isset(
$_SESSION[
'securimage_code_value']) && is_scalar(
$_SESSION[
'securimage_code_value'])) {
1567 unset(
$_SESSION[
'securimage_code_value']);
1568 unset(
$_SESSION[
'securimage_code_ctime']);
1576 if ($this->use_database) {
1589 if ($this->use_database && $this->pdo_conn) {
1604 $query =
"INSERT INTO {$this->database_table} (" 1605 .
"id, code, code_display, namespace, created) " 1606 .
"VALUES(?, ?, ?, ?, ?)";
1608 $stmt = $this->pdo_conn->prepare(
$query);
1612 $err = $stmt->errorInfo();
1613 trigger_error(
"Failed to insert code into database. {$err[1]}: {$err[2]}", E_USER_WARNING);
1625 $this->pdo_conn =
false;
1627 if ($this->use_database) {
1628 $pdo_extension =
'PDO_' . strtoupper($this->database_driver);
1630 if (!extension_loaded($pdo_extension)) {
1631 trigger_error(
"Database support is turned on in Securimage, but the chosen extension $pdo_extension is not loaded in PHP.", E_USER_WARNING);
1636 if ($this->database_driver == self::SI_DRIVER_SQLITE3) {
1637 if (!file_exists($this->database_file)) {
1638 $fp = fopen($this->database_file,
'w+');
1640 $err = error_get_last();
1641 trigger_error(
"Securimage failed to create SQLite3 database file '{$this->database_file}'. Reason: {$err['message']}", E_USER_WARNING);
1645 chmod($this->database_file, 0666);
1646 }
else if (!is_writeable($this->database_file)) {
1647 trigger_error(
"Securimage does not have read/write access to database file '{$this->database_file}. Make sure permissions are 0666 and writeable by user '" . get_current_user() .
"'", E_USER_WARNING);
1656 $this->pdo_conn =
new PDO($dsn, $this->database_user, $this->database_pass,
$options);
1657 }
catch (PDOException $pdoex) {
1658 trigger_error(
"Database connection failed: " . $pdoex->getMessage(), E_USER_WARNING);
1668 trigger_error($ex->getMessage(), E_USER_WARNING);
1669 $this->pdo_conn = null;
1673 if (mt_rand(0, 100) / 100.0 == 1.0) {
1682 $dsn = sprintf(
'%s:', $this->database_driver);
1684 switch($this->database_driver) {
1685 case self::SI_DRIVER_SQLITE3:
1689 case self::SI_DRIVER_MYSQL:
1690 case self::SI_DRIVER_PGSQL:
1691 $dsn .= sprintf(
'host=%s;dbname=%s',
1692 $this->database_host,
1693 $this->database_name);
1703 $table = $this->pdo_conn->quote($this->database_table);
1705 switch($this->database_driver) {
1706 case self::SI_DRIVER_SQLITE3:
1709 $query =
"SELECT COUNT(id) FROM $table";
1712 case self::SI_DRIVER_MYSQL:
1713 $query =
"SHOW TABLES LIKE $table";
1716 case self::SI_DRIVER_PGSQL:
1717 $query =
"SELECT * FROM information_schema.columns WHERE table_name = $table;";
1724 $err = $this->pdo_conn->errorInfo();
1726 if ($this->database_driver == self::SI_DRIVER_SQLITE3 &&
1727 $err[1] === 1 && strpos($err[2],
'no such table') !==
false)
1732 throw new Exception(
"Failed to check tables: {$err[0]} - {$err[1]}: {$err[2]}");
1733 }
else if ($this->database_driver == self::SI_DRIVER_SQLITE3) {
1736 }
else if (
$result->rowCount() == 0) {
1747 switch($this->database_driver) {
1748 case self::SI_DRIVER_SQLITE3:
1749 $queries[] =
"CREATE TABLE \"{$this->database_table}\" ( 1751 namespace VARCHAR(32) NOT NULL, 1752 code VARCHAR(32) NOT NULL, 1753 code_display VARCHAR(32) NOT NULL, 1754 created INTEGER NOT NULL, 1755 PRIMARY KEY(id, namespace) 1758 $queries[] =
"CREATE INDEX ndx_created ON {$this->database_table} (created)";
1761 case self::SI_DRIVER_MYSQL:
1762 $queries[] =
"CREATE TABLE `{$this->database_table}` ( 1763 `id` VARCHAR(40) NOT NULL, 1764 `namespace` VARCHAR(32) NOT NULL, 1765 `code` VARCHAR(32) NOT NULL, 1766 `code_display` VARCHAR(32) NOT NULL, 1767 `created` INT NOT NULL, 1768 PRIMARY KEY(id, namespace), 1773 case self::SI_DRIVER_PGSQL:
1774 $queries[] =
"CREATE TABLE {$this->database_table} ( 1775 id character varying(40) NOT NULL, 1776 namespace character varying(32) NOT NULL, 1777 code character varying(32) NOT NULL, 1778 code_display character varying(32) NOT NULL, 1779 created integer NOT NULL, 1780 CONSTRAINT pkey_id_namespace PRIMARY KEY (id, namespace) 1783 $queries[] =
"CREATE INDEX ndx_created ON {$this->database_table} (created);";
1787 $this->pdo_conn->beginTransaction();
1789 foreach($queries as
$query) {
1790 $result = $this->pdo_conn->query($query);
1793 $err = $this->pdo_conn->errorInfo();
1794 trigger_error(
"Failed to create table. {$err[1]}: {$err[2]}", E_USER_WARNING);
1795 $this->pdo_conn->rollBack();
1796 $this->pdo_conn =
false;
1801 $this->pdo_conn->commit();
1817 if ($this->use_database ==
true && $this->pdo_conn) {
1819 $query =
"SELECT * FROM {$this->database_table} WHERE id = ?";
1820 $stmt = $this->pdo_conn->prepare(
$query);
1827 $query =
"SELECT * FROM {$this->database_table} WHERE id = ? AND namespace = ?";
1828 $stmt = $this->pdo_conn->prepare(
$query);
1833 $err = $this->pdo_conn->errorInfo();
1834 trigger_error(
"Failed to select code from database. {$err[0]}: {$err[1]}", E_USER_WARNING);
1836 if ( (
$row = $stmt->fetch()) !==
false ) {
1841 'code_disp' =>
$row[
'code_display']);
1858 if ($this->pdo_conn) {
1860 $ns = $this->pdo_conn->quote($this->
namespace);
1867 $id = $this->pdo_conn->quote($id);
1869 $query = sprintf(
"DELETE FROM %s WHERE id = %s AND namespace = %s",
1870 $this->database_table, $id, $ns);
1874 trigger_error(
"Failed to delete code from database.", E_USER_WARNING);
1884 if ($this->use_database && $this->pdo_conn) {
1886 $limit = (!is_numeric($this->expiry_time) || $this->expiry_time < 1) ? 86400 : $this->expiry_time;
1888 $query = sprintf(
"DELETE FROM %s WHERE %s - created > %s",
1889 $this->database_table,
1890 $this->pdo_conn->quote($now, PDO::PARAM_INT),
1891 $this->pdo_conn->quote($limit, PDO::PARAM_INT));
1905 if (!is_numeric($this->expiry_time) || $this->expiry_time < 1) {
1907 }
else if (
time() - $creation_time < $this->expiry_time) {
1925 foreach ($letters as $letter) {
1926 $letter = strtoupper($letter);
1929 $l =
new WavFile($this->audio_path .
'/' . $letter .
'.wav');
1933 $wavCaptcha->setSampleRate(
$l->getSampleRate())
1934 ->setBitsPerSample(
$l->getBitsPerSample())
1935 ->setNumChannels(
$l->getNumChannels());
1940 $wavCaptcha->appendWav(
$l);
1943 if ($this->audio_gap_max > 0 && $this->audio_gap_max > $this->audio_gap_min) {
1944 $wavCaptcha->insertSilence( mt_rand($this->audio_gap_min, $this->audio_gap_max) / 1000.0 );
1956 if ($this->audio_use_noise ==
true) {
1960 if ($noiseFile !==
false && is_readable($noiseFile)) {
1962 $wavNoise =
new WavFile($noiseFile,
false);
1970 if ($wavNoise->getNumBlocks() > 2 * $wavCaptcha->getNumBlocks()) {
1971 $randBlock = mt_rand(0, $wavNoise->getNumBlocks() - $wavCaptcha->getNumBlocks());
1972 $wavNoise->readWavData($randBlock * $wavNoise->getBlockAlign(), $wavCaptcha->getNumBlocks() * $wavNoise->getBlockAlign());
1974 $wavNoise->readWavData();
1975 $randOffset = mt_rand(0, $wavNoise->getNumBlocks() - 1);
1979 $mixOpts =
array(
'wav' => $wavNoise,
1981 'blockOffset' => $randOffset);
1988 if ($this->degrade_audio ==
true) {
1994 if (!empty($filters)) {
1995 $wavCaptcha->filter($filters);
1998 return $wavCaptcha->__toString();
2005 if ( ($dh = opendir($this->audio_noise_path)) !==
false ) {
2008 while ( (
$file = readdir($dh)) !==
false ) {
2010 if (strtolower(substr(
$file, -4)) !=
'.wav')
continue;
2017 if (
sizeof($list) > 0) {
2018 $file = $list[array_rand($list, 1)];
2019 $return = $this->audio_noise_path . DIRECTORY_SEPARATOR .
$file;
2033 return @file_get_contents(dirname(__FILE__) .
'/audio/en/error.wav');
2043 if (headers_sent()) {
2046 }
else if (strlen((
string)ob_get_contents()) > 0) {
2061 return 0.0001 * mt_rand(0,9999);
2071 if ($color == null) {
2073 }
else if (is_string($color)) {
2079 }
else if (is_array($color) &&
sizeof($color) == 3) {
2104 $level = error_reporting();
2107 if ($level == 0 || ($level & $errno) == 0) {
2144 $args = func_get_args();
2146 if (
sizeof($args) == 0) {
2150 }
else if (
sizeof($args) == 1) {
2152 if (substr($color, 0, 1) ==
'#') {
2153 $color = substr($color, 1);
2156 if (strlen($color) != 3 && strlen($color) != 6) {
2158 'Invalid HTML color code passed to Securimage_Color' 2162 $this->constructHTML($color);
2163 }
else if (
sizeof($args) == 3) {
2164 $this->constructRGB($args[0], $args[1], $args[2]);
2167 'Securimage_Color constructor expects 0, 1 or 3 arguments; ' .
sizeof($args) .
' given' 2198 if (strlen($color) == 3) {
2199 $red = str_repeat(substr($color, 0, 1), 2);
2200 $green = str_repeat(substr($color, 1, 1), 2);
2201 $blue = str_repeat(substr($color, 2, 1), 2);
2203 $red = substr($color, 0, 2);
2204 $green = substr($color, 2, 2);
2205 $blue = substr($color, 4, 2);
2208 $this->r = hexdec(
$red);
2209 $this->g = hexdec(
$green);
2210 $this->b = hexdec(
$blue);
drawWord()
Draws the captcha code on the image.
openDatabase()
Open sqlite database.
if((!isset($_SERVER['DOCUMENT_ROOT'])) OR(empty($_SERVER['DOCUMENT_ROOT']))) $_SERVER['DOCUMENT_ROOT']
static getPath()
Return the absolute path to the Securimage directory.
audioError()
Return a wav file saying there was an error generating file.
drawNoise()
Draws random noise on the image.
static getCaptchaId($new=true, array $options=array())
Generate a new captcha ID or retrieve the current ID.
getAudibleCode()
Gets the code and returns the binary audio file for the stored captcha code.
saveData()
Save data to session namespace and database if used.
setBackground()
The the background color, or background image to be used.
Project: Securimage: A PHP class for creating and managing form CAPTCHA images File: securimage...
constructHTML($color)
Construct from an html hex color code.
frand()
Return a random float between 0 and 0.9999.
createCode()
Generates the code or math problem and saves the value to the session.
saveCodeToDatabase()
Saves the code to the sqlite database.
initColor($color, $default)
Convert an html color code to a Securimage_Color.
readCodeFromFile($numWords=1)
Gets a captcha code from a wordlist.
generateCode()
Generates a random captcha code from the set character set.
$text_transparency_percentage
show($background_image='')
Used to serve a captcha image to the browser.
getBackgroundFromDirectory()
Scan the directory for a background image to use.
validate()
Checks the entered code against the value stored in the session or sqlite database, handles case sensitivity Also clears the stored codes if the code was entered correctly to prevent re-use.
getCode($array=false, $returnExisting=false)
Return the code from the session or sqlite database if used.
isCodeExpired($creation_time)
Checks to see if the captcha code has expired and cannot be used.
addSignature()
Print signature text on image.
const SI_CAPTCHA_MATHEMATIC
errorHandler($errno, $errstr, $errfile='', $errline=0, $errcontext=array())
Error handler used when outputting captcha image or audio.
clearCodeFromDatabase()
Remove an entered code from the database.
if(!is_array($argv)) $options
doImage()
The main image drawing routing, responsible for constructing the entire image and serving it...
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
foreach( $_REQUEST as $var) foreach(array('_POST'=> 'HTTP_POST_VARS', '_GET'=> 'HTTP_GET_VARS', '_COOKIE'=> 'HTTP_COOKIE_VARS', '_SERVER'=> 'HTTP_SERVER_VARS', '_ENV'=> 'HTTP_ENV_VARS', '_FILES'=> 'HTTP_POST_FILES') as $array=> $other) $step
getCodeFromDatabase()
Get a code from the sqlite database for ip address/captchaId.
purgeOldCodesFromDatabase()
Deletes old codes from sqlite database.
Add a drawing to the header
static checkByCaptchaId($id, $value, array $options=array())
Validate a captcha code input against a captcha ID.
Create styles array
The data for the language used.
outputAudioFile()
Output a wav file of the captcha code to the browser.
output()
Sends the appropriate image and cache headers and outputs image to the browser.
allocateColors()
Allocate the colors to be used for the image.
canSendHeaders()
Checks to see if headers can be sent and if any error has been output to the browser.
__construct($options=array())
Create a new securimage object, pass options to set in the constructor.
__construct($color='#ffffff')
Create a new Securimage_Color object.
constructRGB($red, $green, $blue)
Construct from an rgb triplet.
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
if(!file_exists("$old.txt")) if($old===$new) if(file_exists("$new.txt")) $file
check($code)
Check a submitted code against the stored value.
drawLines()
Draws distorted lines on the image.
generateWAV($letters)
Generate a wav file given the $letters in the code.
distortedCopy()
Copies the captcha image to the final image with distortion applied.