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                } elseif ($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) {
 
  739            $opts = array(
'no_session' => 
true,
 
  740                          'use_database' => 
true);
 
  742                $opts = array_merge(
$options, $opts);
 
  744            $si = 
new self($opts);
 
  767        $opts = array(
'captchaId' => 
$id,
 
  768                      'no_session' => 
true,
 
  769                      'use_database' => 
true);
 
  772            $opts = array_merge(
$options, $opts);
 
  775        $si = 
new self($opts);
 
  777        if (
$si->openDatabase()) {
 
  780            if (is_array(
$code)) {
 
  782                $si->code_display = 
$code[
'code_disp'];
 
  785            if (
$si->check($value)) {
 
  786                $si->clearCodeFromDatabase();
 
  811    public function show($background_image = 
'')
 
  813        set_error_handler(array(&$this, 
'errorHandler'));
 
  815        if ($background_image != 
'' && is_readable($background_image)) {
 
  816            $this->bgimg = $background_image;
 
  837        $this->code_entered = 
$code;
 
  839        return $this->correct_code;
 
  853        set_error_handler(array(&$this, 
'errorHandler'));
 
  855        require_once dirname(__FILE__) . 
'/WavFile.php';
 
  859        } 
catch (Exception $ex) {
 
  860            if (($fp = @fopen(dirname(__FILE__) . 
'/si.error_log', 
'a+')) !== 
false) {
 
  861                fwrite($fp, date(
'Y-m-d H:i:s') . 
': Securimage audio error "' . $ex->getMessage() . 
'"' . 
"\n");
 
  869            if ($this->send_headers) {
 
  870                $uniq = md5(uniqid(microtime()));
 
  871                header(
"Content-Disposition: attachment; filename=\"securimage_audio-{$uniq}.wav\"");
 
  872                header(
'Cache-Control: no-store, no-cache, must-revalidate');
 
  873                header(
'Expires: Sun, 1 Jan 2000 12:00:00 GMT');
 
  874                header(
'Last-Modified: ' . gmdate(
'D, d M Y H:i:s') . 
'GMT');
 
  875                header(
'Content-type: audio/x-wav');
 
  877                if (extension_loaded(
'zlib')) {
 
  878                    ini_set(
'zlib.output_compression', 
true);  
 
  880                    header(
'Content-Length: ' . strlen($audio));
 
  886            echo 
'<hr /><strong>' 
  887                . 
'Failed to generate audio file, content has already been ' 
  888                . 
'output.<br />This is most likely due to misconfiguration or ' 
  889                . 
'a PHP error was sent to the browser.</strong>';
 
  892        restore_error_handler();
 
  894        if (!$this->no_exit) {
 
  905    public function getCode($array = 
false, $returnExisting = 
false)
 
  911        if ($returnExisting && strlen($this->code) > 0) {
 
  913                return array(
'code' => $this->code,
 
  914                             'display' => $this->code_display,
 
  915                             'code_display' => $this->code_display,
 
  922        if ($this->no_session != 
true) {
 
  923            if (isset(
$_SESSION[
'securimage_code_value'][$this->
namespace]) &&
 
  924                    trim(
$_SESSION[
'securimage_code_value'][$this->
namespace]) != 
'') {
 
  926                    $_SESSION[
'securimage_code_ctime'][$this->
namespace]
 
  935        if (empty(
$code) && $this->use_database) {
 
  942        if ($array == 
true) {
 
  943            return array(
'code' => 
$code, 
'ctime' => 
$time, 
'display' => $disp);
 
  954        if (($this->use_transparent_text == 
true || $this->bgimg != 
'') && function_exists(
'imagecreatetruecolor')) {
 
  955            $imagecreate = 
'imagecreatetruecolor';
 
  957            $imagecreate = 
'imagecreate';
 
  960        $this->im = $imagecreate($this->image_width, $this->image_height);
 
  961        $this->tmpimg = $imagecreate($this->image_width * $this->iscale, $this->image_height * $this->iscale);
 
  964        imagepalettecopy($this->tmpimg, $this->im);
 
  974            if (is_string($this->display_value) && strlen($this->display_value) > 0) {
 
  977                                       $this->display_value   :
 
  978                                       strtolower($this->display_value);
 
  985                if (is_array(
$code)) {
 
  986                    $this->code = 
$code[
'code'];
 
  987                    $this->code_display = 
$code[
'code_disp'];
 
  999        if ($this->noise_level > 0) {
 
 1005        if ($this->perturbation > 0 && is_readable($this->ttf_file)) {
 
 1009        if ($this->num_lines > 0) {
 
 1013        if (trim($this->image_signature) != 
'') {
 
 1026        $this->gdbgcolor = imagecolorallocate(
 
 1028            $this->image_bg_color->r,
 
 1029            $this->image_bg_color->g,
 
 1030            $this->image_bg_color->b
 
 1033        $alpha = intval($this->text_transparency_percentage / 100 * 127);
 
 1035        if ($this->use_transparent_text == 
true) {
 
 1036            $this->gdtextcolor = imagecolorallocatealpha(
 
 1038                $this->text_color->r,
 
 1039                $this->text_color->g,
 
 1040                $this->text_color->b,
 
 1043            $this->gdlinecolor = imagecolorallocatealpha(
 
 1045                $this->line_color->r,
 
 1046                $this->line_color->g,
 
 1047                $this->line_color->b,
 
 1050            $this->gdnoisecolor = imagecolorallocatealpha(
 
 1052                $this->noise_color->r,
 
 1053                $this->noise_color->g,
 
 1054                $this->noise_color->b,
 
 1058            $this->gdtextcolor = imagecolorallocate(
 
 1060                $this->text_color->r,
 
 1061                $this->text_color->g,
 
 1062                $this->text_color->b
 
 1064            $this->gdlinecolor = imagecolorallocate(
 
 1066                $this->line_color->r,
 
 1067                $this->line_color->g,
 
 1068                $this->line_color->b
 
 1070            $this->gdnoisecolor = imagecolorallocate(
 
 1072                $this->noise_color->r,
 
 1073                $this->noise_color->g,
 
 1074                $this->noise_color->b
 
 1078        $this->gdsignaturecolor = imagecolorallocate(
 
 1080            $this->signature_color->r,
 
 1081            $this->signature_color->g,
 
 1082            $this->signature_color->b
 
 1092        imagefilledrectangle(
 
 1097            $this->image_height,
 
 1100        imagefilledrectangle(
 
 1104            $this->image_width * $this->iscale,
 
 1105            $this->image_height * $this->iscale,
 
 1109        if ($this->bgimg == 
'') {
 
 1110            if ($this->background_directory != 
null &&
 
 1111                is_dir($this->background_directory) &&
 
 1112                is_readable($this->background_directory)) {
 
 1114                if (
$img != 
false) {
 
 1115                    $this->bgimg = 
$img;
 
 1120        if ($this->bgimg == 
'') {
 
 1124        $dat = @getimagesize($this->bgimg);
 
 1125        if ($dat == 
false) {
 
 1130            case 1:  $newim = @imagecreatefromgif($this->bgimg); 
break;
 
 1131            case 2:  $newim = @imagecreatefromjpeg($this->bgimg); 
break;
 
 1132            case 3:  $newim = @imagecreatefrompng($this->bgimg); 
break;
 
 1148            $this->image_height,
 
 1161        if (($dh = opendir($this->background_directory)) !== 
false) {
 
 1162            while (($file = readdir($dh)) !== 
false) {
 
 1163                if (preg_match(
'/(jpg|gif|png)$/i', $file)) {
 
 1170            if (
sizeof($images) > 0) {
 
 1171                return rtrim($this->background_directory, 
'/') . 
'/' . $images[mt_rand(0, 
sizeof($images) - 1)];
 
 1183        $this->code = 
false;
 
 1185        switch ($this->captcha_type) {
 
 1189                    $signs = array(
'+', 
'-', 
'x');
 
 1190                    $left = mt_rand(1, 10);
 
 1191                    $right = mt_rand(1, 5);
 
 1192                    $sign = $signs[mt_rand(0, 2)];
 
 1195                        case 'x': 
$c = $left * $right; 
break;
 
 1196                        case '-': 
$c = $left - $right; 
break;
 
 1197                        default:  
$c = $left + $right; 
break;
 
 1202                $this->code_display = 
"$left $sign $right";
 
 1208                $this->code = implode(
' ', $words);
 
 1214                if ($this->use_wordlist && is_readable($this->wordlist_file)) {
 
 1218                if ($this->code == 
false) {
 
 1238        if (!is_readable($this->ttf_file)) {
 
 1239            imagestring($this->im, 4, 10, ($this->image_height / 2) - 5, 
'Failed to load TTF font file!', $this->gdtextcolor);
 
 1241            if ($this->perturbation > 0) {
 
 1242                $font_size = $height2 * .4;
 
 1243                $bb = imageftbbox($font_size, 0, $this->ttf_file, $this->code_display);
 
 1244                $tx = $bb[4] - $bb[0];
 
 1245                $ty = $bb[5] - $bb[1];
 
 1246                $x = floor($width2 / 2 - $tx / 2 - $bb[0]);
 
 1247                $y = round($height2 / 2 - $ty / 2 - $bb[1]);
 
 1249                imagettftext($this->tmpimg, $font_size, 0, 
$x, 
$y, $this->gdtextcolor, $this->ttf_file, $this->code_display);
 
 1251                $font_size = $this->image_height * .4;
 
 1252                $bb = imageftbbox($font_size, 0, $this->ttf_file, $this->code_display);
 
 1253                $tx = $bb[4] - $bb[0];
 
 1254                $ty = $bb[5] - $bb[1];
 
 1255                $x = floor($this->image_width / 2 - $tx / 2 - $bb[0]);
 
 1256                $y = round($this->image_height / 2 - $ty / 2 - $bb[1]);
 
 1258                imagettftext($this->im, $font_size, 0, 
$x, 
$y, $this->gdtextcolor, $this->ttf_file, $this->code_display);
 
 1274        for (
$i = 0; 
$i < $numpoles; ++
$i) {
 
 1275            $px[
$i] = mt_rand($this->image_width * 0.2, $this->image_width * 0.8);
 
 1276            $py[
$i] = mt_rand($this->image_height * 0.2, $this->image_height * 0.8);
 
 1277            $rad[
$i] = mt_rand($this->image_height * 0.2, $this->image_height * 0.8);
 
 1278            $tmp = ((-$this->
frand()) * 0.15) - .15;
 
 1279            $amp[
$i] = $this->perturbation * $tmp;
 
 1282        $bgCol = imagecolorat($this->tmpimg, 0, 0);
 
 1285        imagepalettecopy($this->im, $this->tmpimg); 
 
 1291                for (
$i = 0; 
$i < $numpoles; ++
$i) {
 
 1292                    $dx = $ix - 
$px[
$i];
 
 1293                    $dy = $iy - 
$py[
$i];
 
 1294                    if ($dx == 0 && $dy == 0) {
 
 1297                    $r = sqrt($dx * $dx + $dy * $dy);
 
 1298                    if (
$r > $rad[
$i]) {
 
 1301                    $rscale = $amp[
$i] * sin(3.14 * 
$r / $rad[
$i]);
 
 1302                    $x += $dx * $rscale;
 
 1303                    $y += $dy * $rscale;
 
 1308                if (
$x >= 0 && $x < $width2 && $y >= 0 && 
$y < $height2) {
 
 1309                    $c = imagecolorat($this->tmpimg, 
$x, 
$y);
 
 1312                    imagesetpixel($this->im, $ix, $iy, 
$c);
 
 1324            $x = $this->image_width * (1 + $line) / ($this->num_lines + 1);
 
 1325            $x += (0.5 - $this->
frand()) * $this->image_width / $this->num_lines;
 
 1326            $y = mt_rand($this->image_height * 0.1, $this->image_height * 0.9);
 
 1328            $theta = ($this->
frand() - 0.5) * M_PI * 0.7;
 
 1330            $len = mt_rand(
$w * 0.4, 
$w * 0.7);
 
 1331            $lwid = mt_rand(0, 2);
 
 1333            $k = $this->
frand() * 0.6 + 0.2;
 
 1335            $phi = $this->
frand() * 6.28;
 
 1337            $dx = 
$step * cos($theta);
 
 1338            $dy = 
$step * sin($theta);
 
 1340            $amp = 1.5 * $this->
frand() / ($k + 5.0 / $len);
 
 1341            $x0 = 
$x - 0.5 * $len * cos($theta);
 
 1342            $y0 = 
$y - 0.5 * $len * sin($theta);
 
 1344            $ldx = round(-$dy * $lwid);
 
 1345            $ldy = round($dx * $lwid);
 
 1348                $x = $x0 + 
$i * $dx + $amp * $dy * sin($k * 
$i * 
$step + $phi);
 
 1349                $y = $y0 + 
$i * $dy - $amp * $dx * sin($k * 
$i * 
$step + $phi);
 
 1350                imagefilledrectangle($this->im, 
$x, 
$y, 
$x + $lwid, 
$y + $lwid, $this->gdlinecolor);
 
 1360        if ($this->noise_level > 10) {
 
 1366        $t0 = microtime(
true);
 
 1370        $points = $this->image_width * $this->image_height * 
$this->iscale;
 
 1374            $x = mt_rand(10, $width);
 
 1375            $y = mt_rand(10, $height);
 
 1376            $size = mt_rand(7, 10);
 
 1380            imagefilledarc($this->tmpimg, 
$x, 
$y, 
$size, 
$size, 0, 360, $this->gdnoisecolor, IMG_ARC_PIE);
 
 1383        $t1 = microtime(
true);
 
 1401        $bbox = imagettfbbox(10, 0, $this->signature_font, $this->image_signature);
 
 1402        $textlen = $bbox[2] - $bbox[0];
 
 1403        $x = $this->image_width - $textlen - 5;
 
 1404        $y = $this->image_height - 3;
 
 1406        imagettftext($this->im, 10, 0, 
$x, 
$y, $this->gdsignaturecolor, $this->signature_font, $this->image_signature);
 
 1415            if ($this->send_headers) {
 
 1420                header(
"Expires: Mon, 26 Jul 1997 05:00:00 GMT");
 
 1421                header(
"Last-Modified: " . gmdate(
"D, d M Y H:i:s") . 
"GMT");
 
 1422                header(
"Cache-Control: no-store, no-cache, must-revalidate");
 
 1423                header(
"Cache-Control: post-check=0, pre-check=0", 
false);
 
 1424                header(
"Pragma: no-cache");
 
 1427            switch ($this->image_type) {
 
 1429                    if ($this->send_headers) {
 
 1430                        header(
"Content-Type: image/jpeg");
 
 1432                    imagejpeg($this->im, 
null, 90);
 
 1435                    if ($this->send_headers) {
 
 1436                        header(
"Content-Type: image/gif");
 
 1438                    imagegif($this->im);
 
 1441                    if ($this->send_headers) {
 
 1442                        header(
"Content-Type: image/png");
 
 1444                    imagepng($this->im);
 
 1448            echo 
'<hr /><strong>' 
 1449                . 
'Failed to generate captcha image, content has already been ' 
 1450                . 
'output.<br />This is most likely due to misconfiguration or ' 
 1451                . 
'a PHP error was sent to the browser.</strong>';
 
 1454        imagedestroy($this->im);
 
 1455        restore_error_handler();
 
 1457        if (!$this->no_exit) {
 
 1472        if (
$code[
'code'] == 
'') {
 
 1473            if (strlen($this->display_value) > 0) {
 
 1474                $code = array(
'code' => $this->display_value, 
'display' => $this->display_value);
 
 1481        if (preg_match(
'/(\d+) (\+|-|x) (\d+)/i', 
$code[
'display'], $eq)) {
 
 1485            $sign = str_replace(array(
'+', 
'-', 
'x'), array(
'plus', 
'minus', 
'times'), $eq[2]);
 
 1488            $letters = array($left, $sign, $right);
 
 1492            $length = strlen(
$code[
'display']);
 
 1494            for (
$i = 0; 
$i < $length; ++
$i) {
 
 1495                $letter = 
$code[
'display']{
$i};
 
 1496                $letters[] = $letter;
 
 1502        } 
catch (Exception $ex) {
 
 1512        $fp = fopen($this->wordlist_file, 
'rb');
 
 1517        $fsize = filesize($this->wordlist_file);
 
 1522        if ((
int) $numWords < 1 || (
int) $numWords > 5) {
 
 1529            fseek($fp, mt_rand(0, $fsize - 64), SEEK_SET); 
 
 1530            $data = fread($fp, 64); 
 
 1531            $data = preg_replace(
"/\r?\n/", 
"\n", 
$data);
 
 1533            $start = @strpos(
$data, 
"\n", mt_rand(0, 56)) + 1; 
 
 1539            } elseif (
$end === 
false) {
 
 1545        } 
while (++
$i < $numWords);
 
 1549        if ($numWords < 2) {
 
 1563        if (function_exists(
'mb_strlen')) {
 
 1565                $code .= mb_substr($this->charset, mt_rand(0, $cslen - 1), 1, 
'UTF-8');
 
 1569                $code .= substr($this->charset, mt_rand(0, $cslen - 1), 1);
 
 1582        if (!is_string($this->code) || strlen($this->code) == 0) {
 
 1590        if ($this->case_sensitive == 
false && preg_match(
'/[A-Z]/', 
$code)) {
 
 1593            $this->case_sensitive = 
true;
 
 1596        $code_entered = trim(
 
 1597            (($this->case_sensitive) ? $this->code_entered
 
 1598                                                       : strtolower($this->code_entered))
 
 1600        $this->correct_code = 
false;
 
 1603            if (strpos(
$code, 
' ') !== 
false) {
 
 1605                $code_entered = preg_replace(
'/\s+/', 
' ', $code_entered);
 
 1606                $code_entered = strtolower($code_entered);
 
 1609            if (
$code == $code_entered) {
 
 1610                $this->correct_code = 
true;
 
 1611                if ($this->no_session != 
true) {
 
 1625        if ($this->no_session != 
true) {
 
 1626            if (isset(
$_SESSION[
'securimage_code_value']) && is_scalar(
$_SESSION[
'securimage_code_value'])) {
 
 1628                unset(
$_SESSION[
'securimage_code_value']);
 
 1629                unset(
$_SESSION[
'securimage_code_ctime']);
 
 1637        if ($this->use_database) {
 
 1650        if ($this->use_database && $this->pdo_conn) {
 
 1665            $query = 
"INSERT INTO {$this->database_table} (" 
 1666                    . 
"id, code, code_display, namespace, created) " 
 1667                    . 
"VALUES(?, ?, ?, ?, ?)";
 
 1673                $err = 
$stmt->errorInfo();
 
 1674                trigger_error(
"Failed to insert code into database. {$err[1]}: {$err[2]}", E_USER_WARNING);
 
 1686        $this->pdo_conn = 
false;
 
 1688        if ($this->use_database) {
 
 1689            $pdo_extension = 
'PDO_' . strtoupper($this->database_driver);
 
 1691            if (!extension_loaded($pdo_extension)) {
 
 1692                trigger_error(
"Database support is turned on in Securimage, but the chosen extension $pdo_extension is not loaded in PHP.", E_USER_WARNING);
 
 1697        if ($this->database_driver == self::SI_DRIVER_SQLITE3) {
 
 1698            if (!file_exists($this->database_file)) {
 
 1699                $fp = fopen($this->database_file, 
'w+');
 
 1701                    $err = error_get_last();
 
 1702                    trigger_error(
"Securimage failed to create SQLite3 database file '{$this->database_file}'. Reason: {$err['message']}", E_USER_WARNING);
 
 1706                chmod($this->database_file, 0666);
 
 1707            } elseif (!is_writeable($this->database_file)) {
 
 1708                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);
 
 1717            $this->pdo_conn = 
new PDO(
$dsn, $this->database_user, $this->database_pass, 
$options);
 
 1718        } 
catch (PDOException $pdoex) {
 
 1719            trigger_error(
"Database connection failed: " . $pdoex->getMessage(), E_USER_WARNING);
 
 1728        } 
catch (Exception $ex) {
 
 1729            trigger_error($ex->getMessage(), E_USER_WARNING);
 
 1730            $this->pdo_conn = 
null;
 
 1734        if (mt_rand(0, 100) / 100.0 == 1.0) {
 
 1743        $dsn = sprintf(
'%s:', $this->database_driver);
 
 1745        switch ($this->database_driver) {
 
 1753                    'host=%s;dbname=%s',
 
 1754                    $this->database_host,
 
 1755                    $this->database_name
 
 1766        $table = $this->pdo_conn->quote($this->database_table);
 
 1768        switch ($this->database_driver) {
 
 1772                $query = 
"SELECT COUNT(id) FROM $table";
 
 1776                $query = 
"SHOW TABLES LIKE $table";
 
 1780                $query = 
"SELECT * FROM information_schema.columns WHERE table_name = $table;";
 
 1787            $err = $this->pdo_conn->errorInfo();
 
 1789            if ($this->database_driver == self::SI_DRIVER_SQLITE3 &&
 
 1790                $err[1] === 1 && strpos($err[2], 
'no such table') !== 
false) {
 
 1794            throw new Exception(
"Failed to check tables: {$err[0]} - {$err[1]}: {$err[2]}");
 
 1795        } elseif ($this->database_driver == self::SI_DRIVER_SQLITE3) {
 
 1798        } elseif (
$result->rowCount() == 0) {
 
 1809        switch ($this->database_driver) {
 
 1811                $queries[] = 
"CREATE TABLE \"{$this->database_table}\" ( 
 1813                                namespace VARCHAR(32) NOT NULL, 
 1814                                code VARCHAR(32) NOT NULL, 
 1815                                code_display VARCHAR(32) NOT NULL, 
 1816                                created INTEGER NOT NULL, 
 1817                                PRIMARY KEY(id, namespace) 
 1820                $queries[] = 
"CREATE INDEX ndx_created ON {$this->database_table} (created)";
 
 1824                $queries[] = 
"CREATE TABLE `{$this->database_table}` ( 
 1825                                `id` VARCHAR(40) NOT NULL, 
 1826                                `namespace` VARCHAR(32) NOT NULL, 
 1827                                `code` VARCHAR(32) NOT NULL, 
 1828                                `code_display` VARCHAR(32) NOT NULL, 
 1829                                `created` INT NOT NULL, 
 1830                                PRIMARY KEY(id, namespace), 
 1836                $queries[] = 
"CREATE TABLE {$this->database_table} ( 
 1837                                id character varying(40) NOT NULL, 
 1838                                namespace character varying(32) NOT NULL, 
 1839                                code character varying(32) NOT NULL, 
 1840                                code_display character varying(32) NOT NULL, 
 1841                                created integer NOT NULL, 
 1842                                CONSTRAINT pkey_id_namespace PRIMARY KEY (id, namespace) 
 1845                $queries[] = 
"CREATE INDEX ndx_created ON {$this->database_table} (created);";
 
 1849        $this->pdo_conn->beginTransaction();
 
 1851        foreach ($queries as 
$query) {
 
 1855                $err = $this->pdo_conn->errorInfo();
 
 1856                trigger_error(
"Failed to create table.  {$err[1]}: {$err[2]}", E_USER_WARNING);
 
 1857                $this->pdo_conn->rollBack();
 
 1858                $this->pdo_conn = 
false;
 
 1863        $this->pdo_conn->commit();
 
 1879        if ($this->use_database == 
true && $this->pdo_conn) {
 
 1881                $query = 
"SELECT * FROM {$this->database_table} WHERE id = ?";
 
 1889                $query = 
"SELECT * FROM {$this->database_table} WHERE id = ? AND namespace = ?";
 
 1895                $err = $this->pdo_conn->errorInfo();
 
 1896                trigger_error(
"Failed to select code from database.  {$err[0]}: {$err[1]}", E_USER_WARNING);
 
 1898                if ((
$row = 
$stmt->fetch()) !== 
false) {
 
 1903                                          'code_disp' => 
$row[
'code_display']);
 
 1920        if ($this->pdo_conn) {
 
 1922            $ns = $this->pdo_conn->quote($this->
namespace);
 
 1929            $id = $this->pdo_conn->quote(
$id);
 
 1932                "DELETE FROM %s WHERE id = %s AND namespace = %s",
 
 1933                $this->database_table,
 
 1940                trigger_error(
"Failed to delete code from database.", E_USER_WARNING);
 
 1950        if ($this->use_database && $this->pdo_conn) {
 
 1952            $limit = (!is_numeric($this->expiry_time) || $this->expiry_time < 1) ? 86400 : $this->expiry_time;
 
 1955                "DELETE FROM %s WHERE %s - created > %s",
 
 1956                $this->database_table,
 
 1957                $this->pdo_conn->quote($now, PDO::PARAM_INT),
 
 1958                $this->pdo_conn->quote($limit, PDO::PARAM_INT)
 
 1973        if (!is_numeric($this->expiry_time) || $this->expiry_time < 1) {
 
 1975        } elseif (time() - $creation_time < $this->expiry_time) {
 
 1993        foreach ($letters as $letter) {
 
 1994            $letter = strtoupper($letter);
 
 1997                $l = 
new WavFile($this->audio_path . 
'/' . $letter . 
'.wav');
 
 2001                    $wavCaptcha->setSampleRate(
$l->getSampleRate())
 
 2002                               ->setBitsPerSample(
$l->getBitsPerSample())
 
 2003                               ->setNumChannels(
$l->getNumChannels());
 
 2008                $wavCaptcha->appendWav(
$l);
 
 2011                if ($this->audio_gap_max > 0 && $this->audio_gap_max > $this->audio_gap_min) {
 
 2012                    $wavCaptcha->insertSilence(mt_rand($this->audio_gap_min, $this->audio_gap_max) / 1000.0);
 
 2014            } 
catch (Exception $ex) {
 
 2024        if ($this->audio_use_noise == 
true) {
 
 2028            if ($noiseFile !== 
false && is_readable($noiseFile)) {
 
 2030                    $wavNoise = 
new WavFile($noiseFile, 
false);
 
 2031                } 
catch (Exception $ex) {
 
 2038                if ($wavNoise->getNumBlocks() > 2 * $wavCaptcha->getNumBlocks()) {
 
 2039                    $randBlock = mt_rand(0, $wavNoise->getNumBlocks() - $wavCaptcha->getNumBlocks());
 
 2040                    $wavNoise->readWavData($randBlock * $wavNoise->getBlockAlign(), $wavCaptcha->getNumBlocks() * $wavNoise->getBlockAlign());
 
 2042                    $wavNoise->readWavData();
 
 2043                    $randOffset = mt_rand(0, $wavNoise->getNumBlocks() - 1);
 
 2047                $mixOpts = array(
'wav' => $wavNoise,
 
 2049                                 'blockOffset' => $randOffset);
 
 2056        if ($this->degrade_audio == 
true) {
 
 2062        if (!empty($filters)) {
 
 2063            $wavCaptcha->filter($filters);  
 
 2066        return $wavCaptcha->__toString();
 
 2073        if (($dh = opendir($this->audio_noise_path)) !== 
false) {
 
 2076            while (($file = readdir($dh)) !== 
false) {
 
 2077                if ($file == 
'.' || $file == 
'..') {
 
 2080                if (strtolower(substr($file, -4)) != 
'.wav') {
 
 2089            if (
sizeof(
$list) > 0) {
 
 2091                $return = $this->audio_noise_path . DIRECTORY_SEPARATOR . $file;
 
 2105        return @file_get_contents(dirname(__FILE__) . 
'/audio/en/error.wav');
 
 2115        if (headers_sent()) {
 
 2118        } elseif (strlen((
string) ob_get_contents()) > 0) {
 
 2133        return 0.0001 * mt_rand(0, 9999);
 
 2143        if ($color == 
null) {
 
 2145        } elseif (is_string($color)) {
 
 2148            } 
catch (Exception $e) {
 
 2151        } elseif (is_array($color) && 
sizeof($color) == 3) {
 
 2173    public function errorHandler($errno, $errstr, $errfile = 
'', $errline = 0, $errcontext = array())
 
 2176        $level = error_reporting();
 
 2179        if ($level == 0 || ($level & $errno) == 0) {
 
 2216        $args = func_get_args();
 
 2218        if (
sizeof($args) == 0) {
 
 2222        } elseif (
sizeof($args) == 1) {
 
 2224            if (substr($color, 0, 1) == 
'#') {
 
 2225                $color = substr($color, 1);
 
 2228            if (strlen($color) != 3 && strlen($color) != 6) {
 
 2229                throw new InvalidArgumentException(
 
 2230                    'Invalid HTML color code passed to Securimage_Color' 
 2235        } elseif (
sizeof($args) == 3) {
 
 2238            throw new InvalidArgumentException(
 
 2239                'Securimage_Color constructor expects 0, 1 or 3 arguments; ' . 
sizeof($args) . 
' given' 
 2282        if (strlen($color) == 3) {
 
 2283            $red = str_repeat(substr($color, 0, 1), 2);
 
 2284            $green = str_repeat(substr($color, 1, 1), 2);
 
 2285            $blue = str_repeat(substr($color, 2, 1), 2);
 
 2287            $red = substr($color, 0, 2);
 
 2288            $green = substr($color, 2, 2);
 
 2289            $blue = substr($color, 4, 2);
 
 2292        $this->r = hexdec(
$red);
 
 2293        $this->g = hexdec(
$green);
 
 2294        $this->b = hexdec(
$blue);
 
An exception for terminatinating execution or to throw for unit testing.
__construct($color='#ffffff')
Create a new Securimage_Color object.
constructRGB($red, $green, $blue)
Construct from an rgb triplet.
constructHTML($color)
Construct from an html hex color code.
errorHandler($errno, $errstr, $errfile='', $errline=0, $errcontext=array())
Error handler used when outputting captcha image or audio.
validate()
Checks the entered code against the value stored in the session or sqlite database,...
getCode($array=false, $returnExisting=false)
Return the code from the session or sqlite database if used.
check($code)
Check a submitted code against the stored value.
saveData()
Save data to session namespace and database if used.
drawLines()
Draws distorted lines on the image.
static getCaptchaId($new=true, array $options=array())
Generate a new captcha ID or retrieve the current ID.
isCodeExpired($creation_time)
Checks to see if the captcha code has expired and cannot be used.
saveCodeToDatabase()
Saves the code to the sqlite database.
output()
Sends the appropriate image and cache headers and outputs image to the browser.
allocateColors()
Allocate the colors to be used for the image.
show($background_image='')
Used to serve a captcha image to the browser.
__construct($options=array())
Create a new securimage object, pass options to set in the constructor.
purgeOldCodesFromDatabase()
Deletes old codes from sqlite database.
static getPath()
Return the absolute path to the Securimage directory.
audioError()
Return a wav file saying there was an error generating file.
outputAudioFile()
Output a wav file of the captcha code to the browser.
$text_transparency_percentage
initColor($color, $default)
Convert an html color code to a Securimage_Color.
drawWord()
Draws the captcha code on the image.
getCodeFromDatabase()
Get a code from the sqlite database for ip address/captchaId.
createCode()
Generates the code or math problem and saves the value to the session.
clearCodeFromDatabase()
Remove an entered code from the database.
openDatabase()
Open sqlite database.
getAudibleCode()
Gets the code and returns the binary audio file for the stored captcha code.
doImage()
The main image drawing routing, responsible for constructing the entire image and serving it.
distortedCopy()
Copies the captcha image to the final image with distortion applied.
setBackground()
The the background color, or background image to be used.
static checkByCaptchaId($id, $value, array $options=array())
Validate a captcha code input against a captcha ID.
getBackgroundFromDirectory()
Scan the directory for a background image to use.
generateWAV($letters)
Generate a wav file given the $letters in the code.
canSendHeaders()
Checks to see if headers can be sent and if any error has been output to the browser.
const SI_CAPTCHA_MATHEMATIC
generateCode()
Generates a random captcha code from the set character set.
addSignature()
Print signature text on image.
frand()
Return a random float between 0 and 0.9999.
drawNoise()
Draws random noise on the image.
readCodeFromFile($numWords=1)
Gets a captcha code from a wordlist.
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
if(!array_key_exists('StateId', $_REQUEST)) $id
foreach($paths as $path) $dsn
Project: Securimage: A PHP class for creating and managing form CAPTCHA images  File: securimage....
if(empty($password)) $table
if(isset($_REQUEST['delete'])) $list
if((!isset($_SERVER['DOCUMENT_ROOT'])) OR(empty($_SERVER['DOCUMENT_ROOT']))) $_SERVER['DOCUMENT_ROOT']