ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
Securimage Class Reference
+ Collaboration diagram for Securimage:

Public Member Functions

 __construct ($options=array())
 Create a new securimage object, pass options to set in the constructor. More...
 
 show ($background_image='')
 Used to serve a captcha image to the browser. More...
 
 check ($code)
 Check a submitted code against the stored value. More...
 
 outputAudioFile ()
 Output a wav file of the captcha code to the browser. More...
 
 getCode ($array=false, $returnExisting=false)
 Return the code from the session or sqlite database if used. More...
 
 createCode ()
 Generates the code or math problem and saves the value to the session. More...
 
 getRandomNoiseFile ()
 
 frand ()
 Return a random float between 0 and 0.9999. More...
 
 errorHandler ($errno, $errstr, $errfile='', $errline=0, $errcontext=array())
 Error handler used when outputting captcha image or audio. More...
 

Static Public Member Functions

static getPath ()
 Return the absolute path to the Securimage directory. More...
 
static getCaptchaId ($new=true, array $options=array())
 Generate a new captcha ID or retrieve the current ID. More...
 
static checkByCaptchaId ($id, $value, array $options=array())
 Validate a captcha code input against a captcha ID. More...
 

Data Fields

const SI_IMAGE_JPEG = 1
 
const SI_IMAGE_PNG = 2
 
const SI_IMAGE_GIF = 3
 
const SI_CAPTCHA_STRING = 0
 
const SI_CAPTCHA_MATHEMATIC = 1
 
const SI_CAPTCHA_WORDS = 2
 
const SI_DRIVER_MYSQL = 'mysql'
 
const SI_DRIVER_PGSQL = 'pgsql'
 
const SI_DRIVER_SQLITE3 = 'sqlite'
 
 $image_width = 215
 
 $image_height = 80
 
 $image_type = self::SI_IMAGE_PNG
 
 $image_bg_color = '#ffffff'
 
 $text_color = '#707070'
 
 $line_color = '#707070'
 
 $noise_color = '#707070'
 
 $text_transparency_percentage = 20
 
 $use_transparent_text = true
 
 $code_length = 6
 
 $case_sensitive = false
 
 $charset = 'ABCDEFGHKLMNPRSTUVWYZabcdefghklmnprstuvwyz23456789'
 
 $expiry_time = 900
 
 $session_name = null
 
 $use_wordlist = false
 
 $perturbation = 0.85
 
 $num_lines = 5
 
 $noise_level = 2
 
 $image_signature = ''
 
 $signature_color = '#707070'
 
 $signature_font
 
 $use_sqlite_db = false
 
 $use_database = false
 
 $database_driver = self::SI_DRIVER_SQLITE3
 
 $database_host = 'localhost'
 
 $database_user = ''
 
 $database_pass = ''
 
 $database_name = ''
 
 $database_table = 'captcha_codes'
 
 $database_file
 
 $captcha_type = self::SI_CAPTCHA_STRING
 
 $namespace
 
 $ttf_file
 
 $wordlist_file
 
 $background_directory
 
 $sqlite_database
 
 $audio_path
 
 $audio_noise_path
 
 $audio_use_noise
 
 $audio_mix_normalization = 0.6
 
 $degrade_audio
 
 $audio_gap_min = 0
 
 $audio_gap_max = 600
 
 $securimage_path = null
 
 $display_value
 

Protected Member Functions

 doImage ()
 The main image drawing routing, responsible for constructing the entire image and serving it. More...
 
 allocateColors ()
 Allocate the colors to be used for the image. More...
 
 setBackground ()
 The the background color, or background image to be used. More...
 
 getBackgroundFromDirectory ()
 Scan the directory for a background image to use. More...
 
 drawWord ()
 Draws the captcha code on the image. More...
 
 distortedCopy ()
 Copies the captcha image to the final image with distortion applied. More...
 
 drawLines ()
 Draws distorted lines on the image. More...
 
 drawNoise ()
 Draws random noise on the image. More...
 
 addSignature ()
 Print signature text on image. More...
 
 output ()
 Sends the appropriate image and cache headers and outputs image to the browser. More...
 
 getAudibleCode ()
 Gets the code and returns the binary audio file for the stored captcha code. More...
 
 readCodeFromFile ($numWords=1)
 Gets a captcha code from a wordlist. More...
 
 generateCode ()
 Generates a random captcha code from the set character set. More...
 
 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. More...
 
 saveData ()
 Save data to session namespace and database if used. More...
 
 saveCodeToDatabase ()
 Saves the code to the sqlite database. More...
 
 openDatabase ()
 Open sqlite database. More...
 
 getDsn ()
 
 checkTablesExist ()
 
 createDatabaseTables ()
 
 getCodeFromDatabase ()
 Get a code from the sqlite database for ip address/captchaId. More...
 
 clearCodeFromDatabase ()
 Remove an entered code from the database. More...
 
 purgeOldCodesFromDatabase ()
 Deletes old codes from sqlite database. More...
 
 isCodeExpired ($creation_time)
 Checks to see if the captcha code has expired and cannot be used. More...
 
 generateWAV ($letters)
 Generate a wav file given the $letters in the code. More...
 
 audioError ()
 Return a wav file saying there was an error generating file. More...
 
 canSendHeaders ()
 Checks to see if headers can be sent and if any error has been output to the browser. More...
 
 initColor ($color, $default)
 Convert an html color code to a Securimage_Color. More...
 

Protected Attributes

 $im
 
 $tmpimg
 
 $bgimg
 
 $iscale = 5
 
 $code
 
 $code_display
 
 $captcha_code
 
 $no_exit
 
 $no_session
 
 $send_headers
 
 $pdo_conn
 
 $gdbgcolor
 
 $gdtextcolor
 
 $gdlinecolor
 
 $gdsignaturecolor
 

Static Protected Attributes

static $_captchaId = null
 

Detailed Description

Definition at line 165 of file securimage.php.

Constructor & Destructor Documentation

◆ __construct()

Securimage::__construct (   $options = array())

Create a new securimage object, pass options to set in the constructor.


This can be used to display a captcha, play an audible captcha, or validate an entry

Parameters
array$options $options = array( 'text_color' => new Securimage_Color('#013020'), 'code_length' => 5, 'num_lines' => 5, 'noise_level' => 3, 'font_file' => Securimage::getPath() . '/custom.ttf' );

$img = new Securimage($options);

Definition at line 629 of file securimage.php.

630 {
631 $this->securimage_path = dirname(__FILE__);
632
633 if (is_array($options) && sizeof($options) > 0) {
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);
640 } else {
641 $this->$prop = $val;
642 }
643 }
644 }
645
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');
651
652 if (is_null($this->ttf_file)) {
653 $this->ttf_file = $this->securimage_path . '/AHGBold.ttf';
654 }
655
656 $this->signature_font = $this->ttf_file;
657
658 if (is_null($this->wordlist_file)) {
659 $this->wordlist_file = $this->securimage_path . '/words/words.txt';
660 }
661
662 if (is_null($this->database_file)) {
663 $this->database_file = $this->securimage_path . '/database/securimage.sq3';
664 }
665
666 if (is_null($this->audio_path)) {
667 $this->audio_path = $this->securimage_path . '/audio/en/';
668 }
669
670 if (is_null($this->audio_noise_path)) {
671 $this->audio_noise_path = $this->securimage_path . '/audio/noise/';
672 }
673
674 if (is_null($this->audio_use_noise)) {
675 $this->audio_use_noise = true;
676 }
677
678 if (is_null($this->degrade_audio)) {
679 $this->degrade_audio = true;
680 }
681
682 if (is_null($this->code_length) || (int)$this->code_length < 1) {
683 $this->code_length = 6;
684 }
685
686 if (is_null($this->perturbation) || !is_numeric($this->perturbation)) {
687 $this->perturbation = 0.75;
688 }
689
690 if (is_null($this->namespace) || !is_string($this->namespace)) {
691 $this->namespace = 'default';
692 }
693
694 if (is_null($this->no_exit)) {
695 $this->no_exit = false;
696 }
697
698 if (is_null($this->no_session)) {
699 $this->no_session = false;
700 }
701
702 if (is_null($this->send_headers)) {
703 $this->send_headers = true;
704 }
705
706 if ($this->no_session != true) {
707 // Initialize session or attach to existing
708 if ( session_id() == '' ) { // no session has been started yet, which is needed for validation
709 if (!is_null($this->session_name) && trim($this->session_name) != '') {
710 session_name(trim($this->session_name)); // set session name if provided
711 }
712 session_start();
713 }
714 }
715 }
initColor($color, $default)
Convert an html color code to a Securimage_Color.
static $_captchaId
Definition: securimage.php:539
if(!is_array($argv)) $options

References $_captchaId, $options, $ttf_file, and initColor().

+ Here is the call graph for this function:

Member Function Documentation

◆ addSignature()

Securimage::addSignature ( )
protected

Print signature text on image.

Definition at line 1353 of file securimage.php.

1354 {
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;
1359
1360 imagettftext($this->im, 10, 0, $x, $y, $this->gdsignaturecolor, $this->signature_font, $this->image_signature);
1361 }
$y
Definition: example_007.php:83
$x
Definition: example_009.php:98

References $x, and $y.

Referenced by doImage().

+ Here is the caller graph for this function:

◆ allocateColors()

Securimage::allocateColors ( )
protected

Allocate the colors to be used for the image.

Definition at line 1015 of file securimage.php.

1016 {
1017 // allocate bg color first for imagecreate
1018 $this->gdbgcolor = imagecolorallocate($this->im,
1019 $this->image_bg_color->r,
1020 $this->image_bg_color->g,
1021 $this->image_bg_color->b);
1022
1023 $alpha = intval($this->text_transparency_percentage / 100 * 127);
1024
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,
1030 $alpha);
1031 $this->gdlinecolor = imagecolorallocatealpha($this->im,
1032 $this->line_color->r,
1033 $this->line_color->g,
1034 $this->line_color->b,
1035 $alpha);
1036 $this->gdnoisecolor = imagecolorallocatealpha($this->im,
1037 $this->noise_color->r,
1038 $this->noise_color->g,
1039 $this->noise_color->b,
1040 $alpha);
1041 } else {
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);
1054 }
1055
1056 $this->gdsignaturecolor = imagecolorallocate($this->im,
1057 $this->signature_color->r,
1058 $this->signature_color->g,
1059 $this->signature_color->b);
1060
1061 }

Referenced by doImage().

+ Here is the caller graph for this function:

◆ audioError()

Securimage::audioError ( )
protected

Return a wav file saying there was an error generating file.

Returns
string The binary audio contents

Definition at line 2031 of file securimage.php.

2032 {
2033 return @file_get_contents(dirname(__FILE__) . '/audio/en/error.wav');
2034 }

Referenced by outputAudioFile().

+ Here is the caller graph for this function:

◆ canSendHeaders()

Securimage::canSendHeaders ( )
protected

Checks to see if headers can be sent and if any error has been output to the browser.

Returns
bool true if headers haven't been sent and no output/errors will break audio/images, false if unsafe

Definition at line 2041 of file securimage.php.

2042 {
2043 if (headers_sent()) {
2044 // output has been flushed and headers have already been sent
2045 return false;
2046 } else if (strlen((string)ob_get_contents()) > 0) {
2047 // headers haven't been sent, but there is data in the buffer that will break image and audio data
2048 return false;
2049 }
2050
2051 return true;
2052 }

Referenced by output(), and outputAudioFile().

+ Here is the caller graph for this function:

◆ check()

Securimage::check (   $code)

Check a submitted code against the stored value.

Parameters
string$codeThe captcha code to check $code = $_POST['code']; $img = new Securimage(); if ($img->check($code) == true) { $captcha_valid = true; } else { $captcha_valid = false; }

Definition at line 831 of file securimage.php.

832 {
833 $this->code_entered = $code;
834 $this->validate();
835 return $this->correct_code;
836 }
validate()
Checks the entered code against the value stored in the session or sqlite database,...

References $code, and validate().

+ Here is the call graph for this function:

◆ checkByCaptchaId()

static Securimage::checkByCaptchaId (   $id,
  $value,
array  $options = array() 
)
static

Validate a captcha code input against a captcha ID.

Parameters
string$idThe captcha ID to check
string$valueThe captcha value supplied by the user
array$optionsArray of options to construct Securimage with. Options must include database options if they are not set in securimage.php
See also
Securimage::$database_driver
Returns
bool true if the code was valid for the given captcha ID, false if not or if database failed to open

Definition at line 763 of file securimage.php.

764 {
765 $opts = array('captchaId' => $id,
766 'no_session' => true,
767 'use_database' => true);
768
769 if (sizeof($options) > 0) $opts = array_merge($options, $opts);
770
771 $si = new self($opts);
772
773 if ($si->openDatabase()) {
774 $code = $si->getCodeFromDatabase();
775
776 if (is_array($code)) {
777 $si->code = $code['code'];
778 $si->code_display = $code['code_disp'];
779 }
780
781 if ($si->check($value)) {
782 $si->clearCodeFromDatabase();
783
784 return true;
785 } else {
786 return false;
787 }
788 } else {
789 return false;
790 }
791 }

References $code, $options, and $si.

◆ checkTablesExist()

Securimage::checkTablesExist ( )
protected

Definition at line 1701 of file securimage.php.

1702 {
1703 $table = $this->pdo_conn->quote($this->database_table);
1704
1705 switch($this->database_driver) {
1707 // query row count for sqlite, PRAGMA queries seem to return no
1708 // rowCount using PDO even if there are rows returned
1709 $query = "SELECT COUNT(id) FROM $table";
1710 break;
1711
1713 $query = "SHOW TABLES LIKE $table";
1714 break;
1715
1717 $query = "SELECT * FROM information_schema.columns WHERE table_name = $table;";
1718 break;
1719 }
1720
1721 $result = $this->pdo_conn->query($query);
1722
1723 if (!$result) {
1724 $err = $this->pdo_conn->errorInfo();
1725
1726 if ($this->database_driver == self::SI_DRIVER_SQLITE3 &&
1727 $err[1] === 1 && strpos($err[2], 'no such table') !== false)
1728 {
1729 return false;
1730 }
1731
1732 throw new Exception("Failed to check tables: {$err[0]} - {$err[1]}: {$err[2]}");
1733 } else if ($this->database_driver == self::SI_DRIVER_SQLITE3) {
1734 // successful here regardless of row count for sqlite
1735 return true;
1736 } else if ($result->rowCount() == 0) {
1737 return false;
1738 } else {
1739 return true;
1740 }
1741 }
$result
const SI_DRIVER_MYSQL
Definition: securimage.php:208
const SI_DRIVER_SQLITE3
Definition: securimage.php:222
const SI_DRIVER_PGSQL
Definition: securimage.php:215

References $query, $result, SI_DRIVER_MYSQL, SI_DRIVER_PGSQL, and SI_DRIVER_SQLITE3.

Referenced by openDatabase().

+ Here is the caller graph for this function:

◆ clearCodeFromDatabase()

Securimage::clearCodeFromDatabase ( )
protected

Remove an entered code from the database.

Definition at line 1856 of file securimage.php.

1857 {
1858 if ($this->pdo_conn) {
1859 $ip = $_SERVER['REMOTE_ADDR'];
1860 $ns = $this->pdo_conn->quote($this->namespace);
1862
1863 if (empty($id)) {
1864 $id = $ip; // if no captchaId set, IP address is captchaId.
1865 }
1866
1867 $id = $this->pdo_conn->quote($id);
1868
1869 $query = sprintf("DELETE FROM %s WHERE id = %s AND namespace = %s",
1870 $this->database_table, $id, $ns);
1871
1872 $result = $this->pdo_conn->query($query);
1873 if (!$result) {
1874 trigger_error("Failed to delete code from database.", E_USER_WARNING);
1875 }
1876 }
1877 }
if((!isset($_SERVER['DOCUMENT_ROOT'])) OR(empty($_SERVER['DOCUMENT_ROOT']))) $_SERVER['DOCUMENT_ROOT']

References $_captchaId, $_SERVER, $query, and $result.

Referenced by saveCodeToDatabase(), and validate().

+ Here is the caller graph for this function:

◆ createCode()

Securimage::createCode ( )

Generates the code or math problem and saves the value to the session.

Definition at line 1136 of file securimage.php.

1137 {
1138 $this->code = false;
1139
1140 switch($this->captcha_type) {
1142 {
1143 do {
1144 $signs = array('+', '-', 'x');
1145 $left = mt_rand(1, 10);
1146 $right = mt_rand(1, 5);
1147 $sign = $signs[mt_rand(0, 2)];
1148
1149 switch($sign) {
1150 case 'x': $c = $left * $right; break;
1151 case '-': $c = $left - $right; break;
1152 default: $c = $left + $right; break;
1153 }
1154 } while ($c <= 0); // no negative #'s or 0
1155
1156 $this->code = $c;
1157 $this->code_display = "$left $sign $right";
1158 break;
1159 }
1160
1162 $words = $this->readCodeFromFile(2);
1163 $this->code = implode(' ', $words);
1164 $this->code_display = $this->code;
1165 break;
1166
1167 default:
1168 {
1169 if ($this->use_wordlist && is_readable($this->wordlist_file)) {
1170 $this->code = $this->readCodeFromFile();
1171 }
1172
1173 if ($this->code == false) {
1174 $this->code = $this->generateCode($this->code_length);
1175 }
1176
1177 $this->code_display = $this->code;
1178 $this->code = ($this->case_sensitive) ? $this->code : strtolower($this->code);
1179 } // default
1180 }
1181
1182 $this->saveData();
1183 }
saveData()
Save data to session namespace and database if used.
const SI_CAPTCHA_WORDS
Definition: securimage.php:201
const SI_CAPTCHA_MATHEMATIC
Definition: securimage.php:196
generateCode()
Generates a random captcha code from the set character set.
readCodeFromFile($numWords=1)
Gets a captcha code from a wordlist.

References $case_sensitive, $code, generateCode(), readCodeFromFile(), saveData(), SI_CAPTCHA_MATHEMATIC, and SI_CAPTCHA_WORDS.

Referenced by doImage(), and getAudibleCode().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ createDatabaseTables()

Securimage::createDatabaseTables ( )
protected

Definition at line 1743 of file securimage.php.

1744 {
1745 $queries = array();
1746
1747 switch($this->database_driver) {
1749 $queries[] = "CREATE TABLE \"{$this->database_table}\" (
1750 id VARCHAR(40),
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)
1756 )";
1757
1758 $queries[] = "CREATE INDEX ndx_created ON {$this->database_table} (created)";
1759 break;
1760
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),
1769 INDEX(created)
1770 )";
1771 break;
1772
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)
1781 )";
1782
1783 $queries[] = "CREATE INDEX ndx_created ON {$this->database_table} (created);";
1784 break;
1785 }
1786
1787 $this->pdo_conn->beginTransaction();
1788
1789 foreach($queries as $query) {
1790 $result = $this->pdo_conn->query($query);
1791
1792 if (!$result) {
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;
1797 return false;
1798 }
1799 }
1800
1801 $this->pdo_conn->commit();
1802
1803 return true;
1804 }

References $query, $result, SI_DRIVER_MYSQL, SI_DRIVER_PGSQL, and SI_DRIVER_SQLITE3.

Referenced by openDatabase().

+ Here is the caller graph for this function:

◆ distortedCopy()

Securimage::distortedCopy ( )
protected

Copies the captcha image to the final image with distortion applied.

Definition at line 1226 of file securimage.php.

1227 {
1228 $numpoles = 3; // distortion factor
1229 // make array of poles AKA attractor points
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;
1236 }
1237
1238 $bgCol = imagecolorat($this->tmpimg, 0, 0);
1239 $width2 = $this->iscale * $this->image_width;
1240 $height2 = $this->iscale * $this->image_height;
1241 imagepalettecopy($this->im, $this->tmpimg); // copy palette to final image so text colors come across
1242 // loop over $img pixels, take pixels from $tmpimg with distortion field
1243 for ($ix = 0; $ix < $this->image_width; ++ $ix) {
1244 for ($iy = 0; $iy < $this->image_height; ++ $iy) {
1245 $x = $ix;
1246 $y = $iy;
1247 for ($i = 0; $i < $numpoles; ++ $i) {
1248 $dx = $ix - $px[$i];
1249 $dy = $iy - $py[$i];
1250 if ($dx == 0 && $dy == 0) {
1251 continue;
1252 }
1253 $r = sqrt($dx * $dx + $dy * $dy);
1254 if ($r > $rad[$i]) {
1255 continue;
1256 }
1257 $rscale = $amp[$i] * sin(3.14 * $r / $rad[$i]);
1258 $x += $dx * $rscale;
1259 $y += $dy * $rscale;
1260 }
1261 $c = $bgCol;
1262 $x *= $this->iscale;
1263 $y *= $this->iscale;
1264 if ($x >= 0 && $x < $width2 && $y >= 0 && $y < $height2) {
1265 $c = imagecolorat($this->tmpimg, $x, $y);
1266 }
1267 if ($c != $bgCol) { // only copy pixels of letters to preserve any background image
1268 imagesetpixel($this->im, $ix, $iy, $c);
1269 }
1270 }
1271 }
1272 }
frand()
Return a random float between 0 and 0.9999.
$px
$py
$r
Definition: example_031.php:79

References $image_height, $image_width, $iscale, $px, $py, $r, $x, $y, and frand().

Referenced by doImage().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ doImage()

Securimage::doImage ( )
protected

The main image drawing routing, responsible for constructing the entire image and serving it.

Definition at line 944 of file securimage.php.

945 {
946 if( ($this->use_transparent_text == true || $this->bgimg != '') && function_exists('imagecreatetruecolor')) {
947 $imagecreate = 'imagecreatetruecolor';
948 } else {
949 $imagecreate = 'imagecreate';
950 }
951
952 $this->im = $imagecreate($this->image_width, $this->image_height);
953 $this->tmpimg = $imagecreate($this->image_width * $this->iscale, $this->image_height * $this->iscale);
954
955 $this->allocateColors();
956 imagepalettecopy($this->tmpimg, $this->im);
957
958 $this->setBackground();
959
960 $code = '';
961
962 if ($this->getCaptchaId(false) !== null) {
963 // a captcha Id was supplied
964
965 // check to see if a display_value for the captcha image was set
966 if (is_string($this->display_value) && strlen($this->display_value) > 0) {
967 $this->code_display = $this->display_value;
968 $this->code = ($this->case_sensitive) ?
969 $this->display_value :
970 strtolower($this->display_value);
972 } else if ($this->openDatabase()) {
973 // no display_value, check the database for existing captchaId
974 $code = $this->getCodeFromDatabase();
975
976 // got back a result from the database with a valid code for captchaId
977 if (is_array($code)) {
978 $this->code = $code['code'];
979 $this->code_display = $code['code_disp'];
980 $code = $code['code'];
981 }
982 }
983 }
984
985 if ($code == '') {
986 // if the code was not set using display_value or was not found in
987 // the database, create a new code
988 $this->createCode();
989 }
990
991 if ($this->noise_level > 0) {
992 $this->drawNoise();
993 }
994
995 $this->drawWord();
996
997 if ($this->perturbation > 0 && is_readable($this->ttf_file)) {
998 $this->distortedCopy();
999 }
1000
1001 if ($this->num_lines > 0) {
1002 $this->drawLines();
1003 }
1004
1005 if (trim($this->image_signature) != '') {
1006 $this->addSignature();
1007 }
1008
1009 $this->output();
1010 }
drawLines()
Draws distorted lines on the image.
static getCaptchaId($new=true, array $options=array())
Generate a new captcha ID or retrieve the current ID.
Definition: securimage.php:735
output()
Sends the appropriate image and cache headers and outputs image to the browser.
allocateColors()
Allocate the colors to be used for the image.
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.
openDatabase()
Open sqlite database.
distortedCopy()
Copies the captcha image to the final image with distortion applied.
setBackground()
The the background color, or background image to be used.
addSignature()
Print signature text on image.
drawNoise()
Draws random noise on the image.

References $case_sensitive, $code, $display_value, addSignature(), allocateColors(), createCode(), distortedCopy(), drawLines(), drawNoise(), drawWord(), getCaptchaId(), getCodeFromDatabase(), openDatabase(), output(), and setBackground().

Referenced by show().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ drawLines()

Securimage::drawLines ( )
protected

Draws distorted lines on the image.

Definition at line 1277 of file securimage.php.

1278 {
1279 for ($line = 0; $line < $this->num_lines; ++ $line) {
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);
1283
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);
1288
1289 $k = $this->frand() * 0.6 + 0.2;
1290 $k = $k * $k * 0.5;
1291 $phi = $this->frand() * 6.28;
1292 $step = 0.5;
1293 $dx = $step * cos($theta);
1294 $dy = $step * sin($theta);
1295 $n = $len / $step;
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);
1299
1300 $ldx = round(- $dy * $lwid);
1301 $ldy = round($dx * $lwid);
1302
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);
1307 }
1308 }
1309 }
$n
Definition: RandomTest.php:80
$w

References $image_width, $n, $num_lines, $w, $x, $y, and frand().

Referenced by doImage().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ drawNoise()

Securimage::drawNoise ( )
protected

Draws random noise on the image.

Definition at line 1314 of file securimage.php.

1315 {
1316 if ($this->noise_level > 10) {
1317 $noise_level = 10;
1318 } else {
1320 }
1321
1322 $t0 = microtime(true);
1323
1324 $noise_level *= 125; // an arbitrary number that works well on a 1-10 scale
1325
1326 $points = $this->image_width * $this->image_height * $this->iscale;
1327 $height = $this->image_height * $this->iscale;
1328 $width = $this->image_width * $this->iscale;
1329 for ($i = 0; $i < $noise_level; ++$i) {
1330 $x = mt_rand(10, $width);
1331 $y = mt_rand(10, $height);
1332 $size = mt_rand(7, 10);
1333 if ($x - $size <= 0 && $y - $size <= 0) continue; // dont cover 0,0 since it is used by imagedistortedcopy
1334 imagefilledarc($this->tmpimg, $x, $y, $size, $size, 0, 360, $this->gdnoisecolor, IMG_ARC_PIE);
1335 }
1336
1337 $t1 = microtime(true);
1338
1339 $t = $t1 - $t0;
1340
1341 /*
1342 // DEBUG
1343 imagestring($this->tmpimg, 5, 25, 30, "$t", $this->gdnoisecolor);
1344 header('content-type: image/png');
1345 imagepng($this->tmpimg);
1346 exit;
1347 */
1348 }
$size
Definition: RandomTest.php:79

References $iscale, $noise_level, $size, $t, $x, and $y.

Referenced by doImage().

+ Here is the caller graph for this function:

◆ drawWord()

Securimage::drawWord ( )
protected

Draws the captcha code on the image.

Definition at line 1188 of file securimage.php.

1189 {
1190 $width2 = $this->image_width * $this->iscale;
1191 $height2 = $this->image_height * $this->iscale;
1192
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);
1195 } else {
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]);
1203
1204 imagettftext($this->tmpimg, $font_size, 0, $x, $y, $this->gdtextcolor, $this->ttf_file, $this->code_display);
1205 } else {
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]);
1212
1213 imagettftext($this->im, $font_size, 0, $x, $y, $this->gdtextcolor, $this->ttf_file, $this->code_display);
1214 }
1215 }
1216
1217 // DEBUG
1218 //$this->im = $this->tmpimg;
1219 //$this->output();
1220
1221 }

References $iscale, $x, and $y.

Referenced by doImage().

+ Here is the caller graph for this function:

◆ errorHandler()

Securimage::errorHandler (   $errno,
  $errstr,
  $errfile = '',
  $errline = 0,
  $errcontext = array() 
)

Error handler used when outputting captcha image or audio.

This error handler helps determine if any errors raised would prevent captcha image or audio from displaying. If they have no effect on the output buffer or headers, true is returned so the script can continue processing. See https://github.com/dapphp/securimage/issues/15

Parameters
int$errno
string$errstr
string$errfile
int$errline
array$errcontext
Returns
boolean true if handled, false if PHP should handle

Definition at line 2101 of file securimage.php.

2102 {
2103 // get the current error reporting level
2104 $level = error_reporting();
2105
2106 // if error was supressed or $errno not set in current error level
2107 if ($level == 0 || ($level & $errno) == 0) {
2108 return true;
2109 }
2110
2111 return false;
2112 }

◆ frand()

Securimage::frand ( )

Return a random float between 0 and 0.9999.

Returns
float Random float between 0 and 0.9999

Definition at line 2059 of file securimage.php.

2060 {
2061 return 0.0001 * mt_rand(0,9999);
2062 }

Referenced by distortedCopy(), and drawLines().

+ Here is the caller graph for this function:

◆ generateCode()

Securimage::generateCode ( )
protected

Generates a random captcha code from the set character set.

Definition at line 1499 of file securimage.php.

1500 {
1501 $code = '';
1502
1503 if (function_exists('mb_strlen')) {
1504 for($i = 1, $cslen = mb_strlen($this->charset); $i <= $this->code_length; ++$i) {
1505 $code .= mb_substr($this->charset, mt_rand(0, $cslen - 1), 1, 'UTF-8');
1506 }
1507 } else {
1508 for($i = 1, $cslen = strlen($this->charset); $i <= $this->code_length; ++$i) {
1509 $code .= substr($this->charset, mt_rand(0, $cslen - 1), 1);
1510 }
1511 }
1512
1513 return $code;
1514 }

References $code, and $code_length.

Referenced by createCode().

+ Here is the caller graph for this function:

◆ generateWAV()

Securimage::generateWAV (   $letters)
protected

Generate a wav file given the $letters in the code.

Todo:
Add ability to merge 2 sound files together to have random background sounds
Parameters
array$letters
Returns
string The binary contents of the wav file

Definition at line 1920 of file securimage.php.

1921 {
1922 $wavCaptcha = new WavFile();
1923 $first = true; // reading first wav file
1924
1925 foreach ($letters as $letter) {
1926 $letter = strtoupper($letter);
1927
1928 try {
1929 $l = new WavFile($this->audio_path . '/' . $letter . '.wav');
1930
1931 if ($first) {
1932 // set sample rate, bits/sample, and # of channels for file based on first letter
1933 $wavCaptcha->setSampleRate($l->getSampleRate())
1934 ->setBitsPerSample($l->getBitsPerSample())
1935 ->setNumChannels($l->getNumChannels());
1936 $first = false;
1937 }
1938
1939 // append letter to the captcha audio
1940 $wavCaptcha->appendWav($l);
1941
1942 // random length of silence between $audio_gap_min and $audio_gap_max
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 );
1945 }
1946 } catch (Exception $ex) {
1947 // failed to open file, or the wav file is broken or not supported
1948 // 2 wav files were not compatible, different # channels, bits/sample, or sample rate
1949 throw $ex;
1950 }
1951 }
1952
1953 /********* Set up audio filters *****************************/
1954 $filters = array();
1955
1956 if ($this->audio_use_noise == true) {
1957 // use background audio - find random file
1958 $noiseFile = $this->getRandomNoiseFile();
1959
1960 if ($noiseFile !== false && is_readable($noiseFile)) {
1961 try {
1962 $wavNoise = new WavFile($noiseFile, false);
1963 } catch(Exception $ex) {
1964 throw $ex;
1965 }
1966
1967 // start at a random offset from the beginning of the wavfile
1968 // in order to add more randomness
1969 $randOffset = 0;
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());
1973 } else {
1974 $wavNoise->readWavData();
1975 $randOffset = mt_rand(0, $wavNoise->getNumBlocks() - 1);
1976 }
1977
1978
1979 $mixOpts = array('wav' => $wavNoise,
1980 'loop' => true,
1981 'blockOffset' => $randOffset);
1982
1983 $filters[WavFile::FILTER_MIX] = $mixOpts;
1985 }
1986 }
1987
1988 if ($this->degrade_audio == true) {
1989 // add random noise.
1990 // any noise level below 95% is intensely distorted and not pleasant to the ear
1991 $filters[WavFile::FILTER_DEGRADE] = mt_rand(95, 98) / 100.0;
1992 }
1993
1994 if (!empty($filters)) {
1995 $wavCaptcha->filter($filters); // apply filters to captcha audio
1996 }
1997
1998 return $wavCaptcha->__toString();
1999 }
global $l
Definition: afr.php:30
$audio_mix_normalization
Definition: securimage.php:511
getRandomNoiseFile()
const FILTER_DEGRADE
Definition: WavFile.php:81
const FILTER_MIX
Definition: WavFile.php:75
const FILTER_NORMALIZE
Definition: WavFile.php:78

References $audio_mix_normalization, $l, WavFile\FILTER_DEGRADE, WavFile\FILTER_MIX, WavFile\FILTER_NORMALIZE, and getRandomNoiseFile().

Referenced by getAudibleCode().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getAudibleCode()

Securimage::getAudibleCode ( )
protected

Gets the code and returns the binary audio file for the stored captcha code.

Returns
The audio representation of the captcha in Wav format

Definition at line 1413 of file securimage.php.

1414 {
1415 $letters = array();
1416 $code = $this->getCode(true, true);
1417
1418 if ($code['code'] == '') {
1419 if (strlen($this->display_value) > 0) {
1420 $code = array('code' => $this->display_value, 'display' => $this->display_value);
1421 } else {
1422 $this->createCode();
1423 $code = $this->getCode(true);
1424 }
1425 }
1426
1427 if (preg_match('/(\d+) (\+|-|x) (\d+)/i', $code['display'], $eq)) {
1428 $math = true;
1429
1430 $left = $eq[1];
1431 $sign = str_replace(array('+', '-', 'x'), array('plus', 'minus', 'times'), $eq[2]);
1432 $right = $eq[3];
1433
1434 $letters = array($left, $sign, $right);
1435 } else {
1436 $math = false;
1437
1438 $length = strlen($code['display']);
1439
1440 for($i = 0; $i < $length; ++$i) {
1441 $letter = $code['display']{$i};
1442 $letters[] = $letter;
1443 }
1444 }
1445
1446 try {
1447 return $this->generateWAV($letters);
1448 } catch(Exception $ex) {
1449 throw $ex;
1450 }
1451 }
getCode($array=false, $returnExisting=false)
Return the code from the session or sqlite database if used.
Definition: securimage.php:899
generateWAV($letters)
Generate a wav file given the $letters in the code.

References $code, createCode(), generateWAV(), and getCode().

Referenced by outputAudioFile().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getBackgroundFromDirectory()

Securimage::getBackgroundFromDirectory ( )
protected

Scan the directory for a background image to use.

Definition at line 1114 of file securimage.php.

1115 {
1116 $images = array();
1117
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;
1121 }
1122
1123 closedir($dh);
1124
1125 if (sizeof($images) > 0) {
1126 return rtrim($this->background_directory, '/') . '/' . $images[mt_rand(0, sizeof($images)-1)];
1127 }
1128 }
1129
1130 return false;
1131 }
print $file

References $file.

Referenced by setBackground().

+ Here is the caller graph for this function:

◆ getCaptchaId()

static Securimage::getCaptchaId (   $new = true,
array  $options = array() 
)
static

Generate a new captcha ID or retrieve the current ID.

Parameters
$newbool If true, generates a new challenge and returns and ID
$optionsarray Additional options to be passed to Securimage. Must include database options if not set directly in securimage.php
Returns
null|string Returns null if no captcha id set and new was false, or string captcha ID

Definition at line 735 of file securimage.php.

736 {
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);
741 if (sizeof($options) > 0) $opts = array_merge($options, $opts);
742 $si = new self($opts);
744 $si->createCode();
745
746 return $id;
747 } else {
749 }
750 }

References $_captchaId, $_SERVER, $options, and $si.

Referenced by doImage(), and saveCodeToDatabase().

+ Here is the caller graph for this function:

◆ getCode()

Securimage::getCode (   $array = false,
  $returnExisting = false 
)

Return the code from the session or sqlite database if used.

If none exists yet, an empty string is returned

Parameters
$arraybool True to receive an array containing the code and properties
Returns
array|string Array if $array = true, otherwise a string containing the code

Definition at line 899 of file securimage.php.

900 {
901 $code = '';
902 $time = 0;
903 $disp = 'error';
904
905 if ($returnExisting && strlen($this->code) > 0) {
906 if ($array) {
907 return array('code' => $this->code,
908 'display' => $this->code_display,
909 'code_display' => $this->code_display,
910 'time' => 0);
911 } else {
912 return $this->code;
913 }
914 }
915
916 if ($this->no_session != true) {
917 if (isset($_SESSION['securimage_code_value'][$this->namespace]) &&
918 trim($_SESSION['securimage_code_value'][$this->namespace]) != '') {
919 if ($this->isCodeExpired(
920 $_SESSION['securimage_code_ctime'][$this->namespace]) == false) {
921 $code = $_SESSION['securimage_code_value'][$this->namespace];
922 $time = $_SESSION['securimage_code_ctime'][$this->namespace];
923 $disp = $_SESSION['securimage_code_disp'] [$this->namespace];
924 }
925 }
926 }
927
928 if (empty($code) && $this->use_database) {
929 // no code in session - may mean user has cookies turned off
930 $this->openDatabase();
931 $code = $this->getCodeFromDatabase();
932 } else { /* no code stored in session or sqlite database, validation will fail */ }
933
934 if ($array == true) {
935 return array('code' => $code, 'ctime' => $time, 'display' => $disp);
936 } else {
937 return $code;
938 }
939 }
$_SESSION["AccountId"]
isCodeExpired($creation_time)
Checks to see if the captcha code has expired and cannot be used.

References $_SESSION, $code, $namespace, getCodeFromDatabase(), isCodeExpired(), and openDatabase().

Referenced by getAudibleCode(), and validate().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getCodeFromDatabase()

Securimage::getCodeFromDatabase ( )
protected

Get a code from the sqlite database for ip address/captchaId.

Returns
string|array Empty string if no code was found or has expired, otherwise returns the stored captcha code. If a captchaId is set, this returns an array with indices "code" and "code_disp"

Definition at line 1813 of file securimage.php.

1814 {
1815 $code = '';
1816
1817 if ($this->use_database == true && $this->pdo_conn) {
1818 if (Securimage::$_captchaId !== null) {
1819 $query = "SELECT * FROM {$this->database_table} WHERE id = ?";
1820 $stmt = $this->pdo_conn->prepare($query);
1821 $result = $stmt->execute(array(Securimage::$_captchaId));
1822 } else {
1823 $ip = $_SERVER['REMOTE_ADDR'];
1824 $ns = $this->namespace;
1825
1826 // ip is stored in id column when no captchaId
1827 $query = "SELECT * FROM {$this->database_table} WHERE id = ? AND namespace = ?";
1828 $stmt = $this->pdo_conn->prepare($query);
1829 $result = $stmt->execute(array($ip, $ns));
1830 }
1831
1832 if (!$result) {
1833 $err = $this->pdo_conn->errorInfo();
1834 trigger_error("Failed to select code from database. {$err[0]}: {$err[1]}", E_USER_WARNING);
1835 } else {
1836 if ( ($row = $stmt->fetch()) !== false ) {
1837 if (false == $this->isCodeExpired($row['created'])) {
1838 if (Securimage::$_captchaId !== null) {
1839 // return an array when using captchaId
1840 $code = array('code' => $row['code'],
1841 'code_disp' => $row['code_display']);
1842 } else {
1843 $code = $row['code'];
1844 }
1845 }
1846 }
1847 }
1848 }
1849
1850 return $code;
1851 }

References $_captchaId, $_SERVER, $code, $namespace, $query, $result, $row, and isCodeExpired().

Referenced by doImage(), and getCode().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getDsn()

Securimage::getDsn ( )
protected

Definition at line 1680 of file securimage.php.

1681 {
1682 $dsn = sprintf('%s:', $this->database_driver);
1683
1684 switch($this->database_driver) {
1686 $dsn .= $this->database_file;
1687 break;
1688
1691 $dsn .= sprintf('host=%s;dbname=%s',
1692 $this->database_host,
1693 $this->database_name);
1694 break;
1695
1696 }
1697
1698 return $dsn;
1699 }

References $database_file, SI_DRIVER_MYSQL, SI_DRIVER_PGSQL, and SI_DRIVER_SQLITE3.

Referenced by openDatabase().

+ Here is the caller graph for this function:

◆ getPath()

static Securimage::getPath ( )
static

Return the absolute path to the Securimage directory.

Returns
string The path to the securimage base directory

Definition at line 721 of file securimage.php.

722 {
723 return dirname(__FILE__);
724 }

◆ getRandomNoiseFile()

Securimage::getRandomNoiseFile ( )

Definition at line 2001 of file securimage.php.

2002 {
2003 $return = false;
2004
2005 if ( ($dh = opendir($this->audio_noise_path)) !== false ) {
2006 $list = array();
2007
2008 while ( ($file = readdir($dh)) !== false ) {
2009 if ($file == '.' || $file == '..') continue;
2010 if (strtolower(substr($file, -4)) != '.wav') continue;
2011
2012 $list[] = $file;
2013 }
2014
2015 closedir($dh);
2016
2017 if (sizeof($list) > 0) {
2018 $file = $list[array_rand($list, 1)];
2019 $return = $this->audio_noise_path . DIRECTORY_SEPARATOR . $file;
2020 }
2021 }
2022
2023 return $return;
2024 }

References $file.

Referenced by generateWAV().

+ Here is the caller graph for this function:

◆ initColor()

Securimage::initColor (   $color,
  $default 
)
protected

Convert an html color code to a Securimage_Color.

Parameters
string$color
Securimage_Color$defaultThe defalt color to use if $color is invalid

Definition at line 2069 of file securimage.php.

2070 {
2071 if ($color == null) {
2072 return new Securimage_Color($default);
2073 } else if (is_string($color)) {
2074 try {
2075 return new Securimage_Color($color);
2076 } catch(Exception $e) {
2077 return new Securimage_Color($default);
2078 }
2079 } else if (is_array($color) && sizeof($color) == 3) {
2080 return new Securimage_Color($color[0], $color[1], $color[2]);
2081 } else {
2082 return new Securimage_Color($default);
2083 }
2084 }

Referenced by __construct().

+ Here is the caller graph for this function:

◆ isCodeExpired()

Securimage::isCodeExpired (   $creation_time)
protected

Checks to see if the captcha code has expired and cannot be used.

Parameters
unknown_type$creation_time

Definition at line 1901 of file securimage.php.

1902 {
1903 $expired = true;
1904
1905 if (!is_numeric($this->expiry_time) || $this->expiry_time < 1) {
1906 $expired = false;
1907 } else if (time() - $creation_time < $this->expiry_time) {
1908 $expired = false;
1909 }
1910
1911 return $expired;
1912 }

Referenced by getCode(), and getCodeFromDatabase().

+ Here is the caller graph for this function:

◆ openDatabase()

Securimage::openDatabase ( )
protected

Open sqlite database.

Definition at line 1623 of file securimage.php.

1624 {
1625 $this->pdo_conn = false;
1626
1627 if ($this->use_database) {
1628 $pdo_extension = 'PDO_' . strtoupper($this->database_driver);
1629
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);
1632 return false;
1633 }
1634 }
1635
1636 if ($this->database_driver == self::SI_DRIVER_SQLITE3) {
1637 if (!file_exists($this->database_file)) {
1638 $fp = fopen($this->database_file, 'w+');
1639 if (!$fp) {
1640 $err = error_get_last();
1641 trigger_error("Securimage failed to create SQLite3 database file '{$this->database_file}'. Reason: {$err['message']}", E_USER_WARNING);
1642 return false;
1643 }
1644 fclose($fp);
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);
1648 return false;
1649 }
1650 }
1651
1652 $dsn = $this->getDsn();
1653
1654 try {
1655 $options = array();
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);
1659 return false;
1660 }
1661
1662 try {
1663 if (!$this->checkTablesExist()) {
1664 // create tables...
1665 $this->createDatabaseTables();
1666 }
1667 } catch (Exception $ex) {
1668 trigger_error($ex->getMessage(), E_USER_WARNING);
1669 $this->pdo_conn = null;
1670 return false;
1671 }
1672
1673 if (mt_rand(0, 100) / 100.0 == 1.0) {
1675 }
1676
1677 return $this->pdo_conn;
1678 }
purgeOldCodesFromDatabase()
Deletes old codes from sqlite database.
createDatabaseTables()

References $options, $pdo_conn, checkTablesExist(), createDatabaseTables(), getDsn(), and purgeOldCodesFromDatabase().

Referenced by doImage(), getCode(), and saveCodeToDatabase().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ output()

Securimage::output ( )
protected

Sends the appropriate image and cache headers and outputs image to the browser.

Definition at line 1366 of file securimage.php.

1367 {
1368 if ($this->canSendHeaders() || $this->send_headers == false) {
1369 if ($this->send_headers) {
1370 // only send the content-type headers if no headers have been output
1371 // this will ease debugging on misconfigured servers where warnings
1372 // may have been output which break the image and prevent easily viewing
1373 // source to see the error.
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");
1379 }
1380
1381 switch ($this->image_type) {
1383 if ($this->send_headers) header("Content-Type: image/jpeg");
1384 imagejpeg($this->im, null, 90);
1385 break;
1386 case self::SI_IMAGE_GIF:
1387 if ($this->send_headers) header("Content-Type: image/gif");
1388 imagegif($this->im);
1389 break;
1390 default:
1391 if ($this->send_headers) header("Content-Type: image/png");
1392 imagepng($this->im);
1393 break;
1394 }
1395 } else {
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>';
1400 }
1401
1402 imagedestroy($this->im);
1403 restore_error_handler();
1404
1405 if (!$this->no_exit) exit;
1406 }
const SI_IMAGE_JPEG
Definition: securimage.php:175
const SI_IMAGE_GIF
Definition: securimage.php:185
canSendHeaders()
Checks to see if headers can be sent and if any error has been output to the browser.
exit
Definition: login.php:54

References canSendHeaders(), exit, SI_IMAGE_GIF, and SI_IMAGE_JPEG.

Referenced by doImage().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ outputAudioFile()

Securimage::outputAudioFile ( )

Output a wav file of the captcha code to the browser.

$img = new Securimage(); $img->outputAudioFile(); // outputs a wav file to the browser exit;

Definition at line 847 of file securimage.php.

848 {
849 set_error_handler(array(&$this, 'errorHandler'));
850
851 require_once dirname(__FILE__) . '/WavFile.php';
852
853 try {
854 $audio = $this->getAudibleCode();
855 } catch (Exception $ex) {
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");
858 fclose($fp);
859 }
860
861 $audio = $this->audioError();
862 }
863
864 if ($this->canSendHeaders() || $this->send_headers == false) {
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');
872
873 if (extension_loaded('zlib')) {
874 ini_set('zlib.output_compression', true); // compress output if supported by browser
875 } else {
876 header('Content-Length: ' . strlen($audio));
877 }
878 }
879
880 echo $audio;
881 } else {
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>';
886 }
887
888 restore_error_handler();
889
890 if (!$this->no_exit) exit;
891 }
audioError()
Return a wav file saying there was an error generating file.
getAudibleCode()
Gets the code and returns the binary audio file for the stored captcha code.

References audioError(), canSendHeaders(), exit, and getAudibleCode().

+ Here is the call graph for this function:

◆ purgeOldCodesFromDatabase()

Securimage::purgeOldCodesFromDatabase ( )
protected

Deletes old codes from sqlite database.

Definition at line 1882 of file securimage.php.

1883 {
1884 if ($this->use_database && $this->pdo_conn) {
1885 $now = time();
1886 $limit = (!is_numeric($this->expiry_time) || $this->expiry_time < 1) ? 86400 : $this->expiry_time;
1887
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));
1892
1893 $result = $this->pdo_conn->query($query);
1894 }
1895 }

References $query, and $result.

Referenced by openDatabase().

+ Here is the caller graph for this function:

◆ readCodeFromFile()

Securimage::readCodeFromFile (   $numWords = 1)
protected

Gets a captcha code from a wordlist.

Definition at line 1456 of file securimage.php.

1457 {
1458 $fp = fopen($this->wordlist_file, 'rb');
1459 if (!$fp) return false;
1460
1461 $fsize = filesize($this->wordlist_file);
1462 if ($fsize < 128) return false; // too small of a list to be effective
1463
1464 if ((int)$numWords < 1 || (int)$numWords > 5) $numWords = 1;
1465
1466 $words = array();
1467 $i = 0;
1468 do {
1469 fseek($fp, mt_rand(0, $fsize - 64), SEEK_SET); // seek to a random position of file from 0 to filesize-64
1470 $data = fread($fp, 64); // read a chunk from our random position
1471 $data = preg_replace("/\r?\n/", "\n", $data);
1472
1473 $start = @strpos($data, "\n", mt_rand(0, 56)) + 1; // random start position
1474 $end = @strpos($data, "\n", $start); // find end of word
1475
1476 if ($start === false) {
1477 // picked start position at end of file
1478 continue;
1479 } else if ($end === false) {
1480 $end = strlen($data);
1481 }
1482
1483 $word = strtolower(substr($data, $start, $end - $start)); // return a line of the file
1484 $words[] = $word;
1485 } while (++$i < $numWords);
1486
1487 fclose($fp);
1488
1489 if ($numWords < 2) {
1490 return $words[0];
1491 } else {
1492 return $words;
1493 }
1494 }
$data

References $data.

Referenced by createCode().

+ Here is the caller graph for this function:

◆ saveCodeToDatabase()

Securimage::saveCodeToDatabase ( )
protected

Saves the code to the sqlite database.

Definition at line 1584 of file securimage.php.

1585 {
1586 $success = false;
1587 $this->openDatabase();
1588
1589 if ($this->use_database && $this->pdo_conn) {
1590 $id = $this->getCaptchaId(false);
1591 $ip = $_SERVER['REMOTE_ADDR'];
1592
1593 if (empty($id)) {
1594 $id = $ip;
1595 }
1596
1597 $time = time();
1599 $code_disp = $this->code_display;
1600
1601 // This is somewhat expensive in PDO Sqlite3 (when there is something to delete)
1602 $this->clearCodeFromDatabase();
1603
1604 $query = "INSERT INTO {$this->database_table} ("
1605 ."id, code, code_display, namespace, created) "
1606 ."VALUES(?, ?, ?, ?, ?)";
1607
1608 $stmt = $this->pdo_conn->prepare($query);
1609 $success = $stmt->execute(array($id, $code, $code_disp, $this->namespace, $time));
1610
1611 if (!$success) {
1612 $err = $stmt->errorInfo();
1613 trigger_error("Failed to insert code into database. {$err[1]}: {$err[2]}", E_USER_WARNING);
1614 }
1615 }
1616
1617 return $success !== false;
1618 }
$success
Definition: Utf8Test.php:87
clearCodeFromDatabase()
Remove an entered code from the database.

References $_SERVER, $code, $code_display, $query, $success, clearCodeFromDatabase(), getCaptchaId(), and openDatabase().

Referenced by saveData().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ saveData()

Securimage::saveData ( )
protected

Save data to session namespace and database if used.

Definition at line 1562 of file securimage.php.

1563 {
1564 if ($this->no_session != true) {
1565 if (isset($_SESSION['securimage_code_value']) && is_scalar($_SESSION['securimage_code_value'])) {
1566 // fix for migration from v2 - v3
1567 unset($_SESSION['securimage_code_value']);
1568 unset($_SESSION['securimage_code_ctime']);
1569 }
1570
1571 $_SESSION['securimage_code_disp'] [$this->namespace] = $this->code_display;
1572 $_SESSION['securimage_code_value'][$this->namespace] = $this->code;
1573 $_SESSION['securimage_code_ctime'][$this->namespace] = time();
1574 }
1575
1576 if ($this->use_database) {
1577 $this->saveCodeToDatabase();
1578 }
1579 }
saveCodeToDatabase()
Saves the code to the sqlite database.

References $_SESSION, $code, $code_display, $namespace, and saveCodeToDatabase().

Referenced by createCode().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setBackground()

Securimage::setBackground ( )
protected

The the background color, or background image to be used.

Definition at line 1066 of file securimage.php.

1067 {
1068 // set background color of image by drawing a rectangle since imagecreatetruecolor doesn't set a bg color
1069 imagefilledrectangle($this->im, 0, 0,
1070 $this->image_width, $this->image_height,
1071 $this->gdbgcolor);
1072 imagefilledrectangle($this->tmpimg, 0, 0,
1073 $this->image_width * $this->iscale, $this->image_height * $this->iscale,
1074 $this->gdbgcolor);
1075
1076 if ($this->bgimg == '') {
1077 if ($this->background_directory != null &&
1078 is_dir($this->background_directory) &&
1079 is_readable($this->background_directory))
1080 {
1082 if ($img != false) {
1083 $this->bgimg = $img;
1084 }
1085 }
1086 }
1087
1088 if ($this->bgimg == '') {
1089 return;
1090 }
1091
1092 $dat = @getimagesize($this->bgimg);
1093 if($dat == false) {
1094 return;
1095 }
1096
1097 switch($dat[2]) {
1098 case 1: $newim = @imagecreatefromgif($this->bgimg); break;
1099 case 2: $newim = @imagecreatefromjpeg($this->bgimg); break;
1100 case 3: $newim = @imagecreatefrompng($this->bgimg); break;
1101 default: return;
1102 }
1103
1104 if(!$newim) return;
1105
1106 imagecopyresized($this->im, $newim, 0, 0, 0, 0,
1107 $this->image_width, $this->image_height,
1108 imagesx($newim), imagesy($newim));
1109 }
getBackgroundFromDirectory()
Scan the directory for a background image to use.

References $img, and getBackgroundFromDirectory().

Referenced by doImage().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ show()

Securimage::show (   $background_image = '')

Used to serve a captcha image to the browser.

Parameters
string$background_imageThe path to the background image to use $img = new Securimage(); $img->code_length = 6; $img->num_lines = 5; $img->noise_level = 5;

$img->show(); // sends the image to browser exit;

Definition at line 807 of file securimage.php.

808 {
809 set_error_handler(array(&$this, 'errorHandler'));
810
811 if($background_image != '' && is_readable($background_image)) {
812 $this->bgimg = $background_image;
813 }
814
815 $this->doImage();
816 }
doImage()
The main image drawing routing, responsible for constructing the entire image and serving it.
Definition: securimage.php:944

References doImage().

+ Here is the call graph for this function:

◆ validate()

Securimage::validate ( )
protected

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.

Definition at line 1520 of file securimage.php.

1521 {
1522 if (!is_string($this->code) || strlen($this->code) == 0) {
1523 $code = $this->getCode();
1524 // returns stored code, or an empty string if no stored code was found
1525 // checks the session and database if enabled
1526 } else {
1528 }
1529
1530 if ($this->case_sensitive == false && preg_match('/[A-Z]/', $code)) {
1531 // case sensitive was set from securimage_show.php but not in class
1532 // the code saved in the session has capitals so set case sensitive to true
1533 $this->case_sensitive = true;
1534 }
1535
1536 $code_entered = trim( (($this->case_sensitive) ? $this->code_entered
1537 : strtolower($this->code_entered))
1538 );
1539 $this->correct_code = false;
1540
1541 if ($code != '') {
1542 if (strpos($code, ' ') !== false) {
1543 // for multi word captchas, remove more than once space from input
1544 $code_entered = preg_replace('/\s+/', ' ', $code_entered);
1545 $code_entered = strtolower($code_entered);
1546 }
1547
1548 if ($code == $code_entered) {
1549 $this->correct_code = true;
1550 if ($this->no_session != true) {
1551 $_SESSION['securimage_code_value'][$this->namespace] = '';
1552 $_SESSION['securimage_code_ctime'][$this->namespace] = '';
1553 }
1554 $this->clearCodeFromDatabase();
1555 }
1556 }
1557 }

References $_SESSION, $code, $namespace, clearCodeFromDatabase(), and getCode().

Referenced by check().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Field Documentation

◆ $_captchaId

Securimage::$_captchaId = null
staticprotected

◆ $audio_gap_max

Securimage::$audio_gap_max = 600

Definition at line 533 of file securimage.php.

◆ $audio_gap_min

Securimage::$audio_gap_min = 0

Definition at line 526 of file securimage.php.

◆ $audio_mix_normalization

Securimage::$audio_mix_normalization = 0.6

Definition at line 511 of file securimage.php.

Referenced by generateWAV().

◆ $audio_noise_path

Securimage::$audio_noise_path

Definition at line 479 of file securimage.php.

◆ $audio_path

Securimage::$audio_path

Definition at line 472 of file securimage.php.

◆ $audio_use_noise

Securimage::$audio_use_noise

Definition at line 489 of file securimage.php.

◆ $background_directory

Securimage::$background_directory

Definition at line 458 of file securimage.php.

◆ $bgimg

Securimage::$bgimg
protected

Definition at line 543 of file securimage.php.

◆ $captcha_code

Securimage::$captcha_code
protected

Definition at line 577 of file securimage.php.

◆ $captcha_type

Securimage::$captcha_type = self::SI_CAPTCHA_STRING

Definition at line 425 of file securimage.php.

◆ $case_sensitive

Securimage::$case_sensitive = false

Definition at line 284 of file securimage.php.

Referenced by createCode(), and doImage().

◆ $charset

Securimage::$charset = 'ABCDEFGHKLMNPRSTUVWYZabcdefghklmnprstuvwyz23456789'

Definition at line 289 of file securimage.php.

◆ $code

◆ $code_display

Securimage::$code_display
protected

Definition at line 560 of file securimage.php.

Referenced by saveCodeToDatabase(), and saveData().

◆ $code_length

Securimage::$code_length = 6

Definition at line 279 of file securimage.php.

Referenced by generateCode().

◆ $database_driver

Securimage::$database_driver = self::SI_DRIVER_SQLITE3

Definition at line 367 of file securimage.php.

◆ $database_file

Securimage::$database_file

Definition at line 418 of file securimage.php.

Referenced by getDsn().

◆ $database_host

Securimage::$database_host = 'localhost'

Definition at line 376 of file securimage.php.

◆ $database_name

Securimage::$database_name = ''

Definition at line 400 of file securimage.php.

◆ $database_pass

Securimage::$database_pass = ''

Definition at line 392 of file securimage.php.

◆ $database_table

Securimage::$database_table = 'captcha_codes'

Definition at line 409 of file securimage.php.

◆ $database_user

Securimage::$database_user = ''

Definition at line 384 of file securimage.php.

◆ $degrade_audio

Securimage::$degrade_audio

Definition at line 519 of file securimage.php.

◆ $display_value

Securimage::$display_value

Definition at line 570 of file securimage.php.

Referenced by doImage().

◆ $expiry_time

Securimage::$expiry_time = 900

Definition at line 294 of file securimage.php.

◆ $gdbgcolor

Securimage::$gdbgcolor
protected

Definition at line 608 of file securimage.php.

◆ $gdlinecolor

Securimage::$gdlinecolor
protected

Definition at line 610 of file securimage.php.

◆ $gdsignaturecolor

Securimage::$gdsignaturecolor
protected

Definition at line 611 of file securimage.php.

◆ $gdtextcolor

Securimage::$gdtextcolor
protected

Definition at line 609 of file securimage.php.

◆ $im

Securimage::$im
protected

Definition at line 541 of file securimage.php.

◆ $image_bg_color

Securimage::$image_bg_color = '#ffffff'

Definition at line 247 of file securimage.php.

◆ $image_height

Securimage::$image_height = 80

Definition at line 236 of file securimage.php.

Referenced by distortedCopy().

◆ $image_signature

Securimage::$image_signature = ''

Definition at line 329 of file securimage.php.

◆ $image_type

Securimage::$image_type = self::SI_IMAGE_PNG

Definition at line 241 of file securimage.php.

◆ $image_width

Securimage::$image_width = 215

Definition at line 231 of file securimage.php.

Referenced by distortedCopy(), and drawLines().

◆ $iscale

Securimage::$iscale = 5
protected

Definition at line 544 of file securimage.php.

Referenced by distortedCopy(), drawNoise(), and drawWord().

◆ $line_color

Securimage::$line_color = '#707070'

Definition at line 257 of file securimage.php.

◆ $namespace

Securimage::$namespace

Definition at line 442 of file securimage.php.

Referenced by getCode(), getCodeFromDatabase(), saveData(), and validate().

◆ $no_exit

Securimage::$no_exit
protected

Definition at line 584 of file securimage.php.

◆ $no_session

Securimage::$no_session
protected

Definition at line 591 of file securimage.php.

◆ $noise_color

Securimage::$noise_color = '#707070'

Definition at line 262 of file securimage.php.

◆ $noise_level

Securimage::$noise_level = 2

Definition at line 323 of file securimage.php.

Referenced by drawNoise().

◆ $num_lines

Securimage::$num_lines = 5

Definition at line 318 of file securimage.php.

Referenced by drawLines().

◆ $pdo_conn

Securimage::$pdo_conn
protected

Definition at line 605 of file securimage.php.

Referenced by openDatabase().

◆ $perturbation

Securimage::$perturbation = 0.85

Definition at line 313 of file securimage.php.

◆ $securimage_path

Securimage::$securimage_path = null

Definition at line 546 of file securimage.php.

◆ $send_headers

Securimage::$send_headers
protected

Definition at line 598 of file securimage.php.

◆ $session_name

Securimage::$session_name = null

Definition at line 301 of file securimage.php.

◆ $signature_color

Securimage::$signature_color = '#707070'

Definition at line 334 of file securimage.php.

◆ $signature_font

Securimage::$signature_font

Definition at line 339 of file securimage.php.

◆ $sqlite_database

Securimage::$sqlite_database

Definition at line 464 of file securimage.php.

◆ $text_color

Securimage::$text_color = '#707070'

Definition at line 252 of file securimage.php.

◆ $text_transparency_percentage

Securimage::$text_transparency_percentage = 20

Definition at line 268 of file securimage.php.

◆ $tmpimg

Securimage::$tmpimg
protected

Definition at line 542 of file securimage.php.

◆ $ttf_file

Securimage::$ttf_file

Definition at line 448 of file securimage.php.

Referenced by __construct().

◆ $use_database

Securimage::$use_database = false

Definition at line 358 of file securimage.php.

◆ $use_sqlite_db

Securimage::$use_sqlite_db = false

Definition at line 348 of file securimage.php.

◆ $use_transparent_text

Securimage::$use_transparent_text = true

Definition at line 273 of file securimage.php.

◆ $use_wordlist

Securimage::$use_wordlist = false

Definition at line 307 of file securimage.php.

◆ $wordlist_file

Securimage::$wordlist_file

Definition at line 453 of file securimage.php.

◆ SI_CAPTCHA_MATHEMATIC

const Securimage::SI_CAPTCHA_MATHEMATIC = 1

Definition at line 196 of file securimage.php.

Referenced by createCode().

◆ SI_CAPTCHA_STRING

const Securimage::SI_CAPTCHA_STRING = 0

Definition at line 191 of file securimage.php.

◆ SI_CAPTCHA_WORDS

const Securimage::SI_CAPTCHA_WORDS = 2

Definition at line 201 of file securimage.php.

Referenced by createCode().

◆ SI_DRIVER_MYSQL

const Securimage::SI_DRIVER_MYSQL = 'mysql'

Definition at line 208 of file securimage.php.

Referenced by checkTablesExist(), createDatabaseTables(), and getDsn().

◆ SI_DRIVER_PGSQL

const Securimage::SI_DRIVER_PGSQL = 'pgsql'

Definition at line 215 of file securimage.php.

Referenced by checkTablesExist(), createDatabaseTables(), and getDsn().

◆ SI_DRIVER_SQLITE3

const Securimage::SI_DRIVER_SQLITE3 = 'sqlite'

Definition at line 222 of file securimage.php.

Referenced by checkTablesExist(), createDatabaseTables(), and getDsn().

◆ SI_IMAGE_GIF

const Securimage::SI_IMAGE_GIF = 3

Definition at line 185 of file securimage.php.

Referenced by output().

◆ SI_IMAGE_JPEG

const Securimage::SI_IMAGE_JPEG = 1

Definition at line 175 of file securimage.php.

Referenced by output().

◆ SI_IMAGE_PNG

const Securimage::SI_IMAGE_PNG = 2

Definition at line 180 of file securimage.php.


The documentation for this class was generated from the following file: