captcha_pi.php

Go to the documentation of this file.
00001 <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
00002 /**
00003  * CodeIgniter
00004  *
00005  * An open source application development framework for PHP 4.3.2 or newer
00006  *
00007  * @package             CodeIgniter
00008  * @author              ExpressionEngine Dev Team
00009  * @copyright   Copyright (c) 2006, EllisLab, Inc.
00010  * @license             http://codeigniter.com/user_guide/license.html
00011  * @link                http://codeigniter.com
00012  * @since               Version 1.0
00013  * @filesource
00014  */
00015 
00016 // ------------------------------------------------------------------------
00017 
00018 /*
00019 Instructions:
00020 
00021 Load the plugin using:
00022 
00023         $this->load->plugin('captcha');
00024 
00025 Once loaded you can generate a captcha like this:
00026         
00027         $vals = array(
00028                                         'word'           => 'Random word',
00029                                         'img_path'       => './captcha/',
00030                                         'img_url'        => 'http://example.com/captcha/',
00031                                         'font_path'      => './system/fonts/texb.ttf',
00032                                         'img_width'      => '150',
00033                                         'img_height' => 30,
00034                                         'expiration' => 7200
00035                                 );
00036         
00037         $cap = create_captcha($vals);
00038         echo $cap['image'];
00039         
00040 
00041 NOTES:
00042         
00043         The captcha function requires the GD image library.
00044         
00045         Only the img_path and img_url are required.
00046         
00047         If a "word" is not supplied, the function will generate a random
00048         ASCII string.  You might put together your own word library that
00049         you can draw randomly from.
00050         
00051         If you do not specify a path to a TRUE TYPE font, the native ugly GD
00052         font will be used.
00053         
00054         The "captcha" folder must be writable (666, or 777)
00055         
00056         The "expiration" (in seconds) signifies how long an image will
00057         remain in the captcha folder before it will be deleted.  The default
00058         is two hours.
00059 
00060 RETURNED DATA
00061 
00062 The create_captcha() function returns an associative array with this data:
00063 
00064   [array]
00065   (
00066         'image' => IMAGE TAG
00067         'time'  => TIMESTAMP (in microtime)
00068         'word'  => CAPTCHA WORD
00069   )
00070 
00071 The "image" is the actual image tag:
00072 <img src="http://example.com/captcha/12345.jpg" width="140" height="50" />
00073 
00074 The "time" is the micro timestamp used as the image name without the file
00075 extension.  It will be a number like this:  1139612155.3422
00076 
00077 The "word" is the word that appears in the captcha image, which if not
00078 supplied to the function, will be a random string.
00079 
00080 
00081 ADDING A DATABASE
00082 
00083 In order for the captcha function to prevent someone from posting, you will need
00084 to add the information returned from create_captcha() function to your database.
00085 Then, when the data from the form is submitted by the user you will need to verify
00086 that the data exists in the database and has not expired.
00087 
00088 Here is a table prototype:
00089 
00090         CREATE TABLE captcha (
00091          captcha_id bigint(13) unsigned NOT NULL auto_increment,
00092          captcha_time int(10) unsigned NOT NULL,
00093          ip_address varchar(16) default '0' NOT NULL,
00094          word varchar(20) NOT NULL,
00095          PRIMARY KEY `captcha_id` (`captcha_id`),
00096          KEY `word` (`word`)
00097         )
00098 
00099 
00100 Here is an example of usage with a DB.
00101 
00102 On the page where the captcha will be shown you'll have something like this:
00103 
00104         $this->load->plugin('captcha');
00105         $vals = array(
00106                                         'img_path'       => './captcha/',
00107                                         'img_url'        => 'http://example.com/captcha/'
00108                                 );
00109         
00110         $cap = create_captcha($vals);
00111 
00112         $data = array(
00113                                         'captcha_id'    => '',
00114                                         'captcha_time'  => $cap['time'],
00115                                         'ip_address'    => $this->input->ip_address(),
00116                                         'word'                  => $cap['word']
00117                                 );
00118 
00119         $query = $this->db->insert_string('captcha', $data);
00120         $this->db->query($query);
00121                 
00122         echo 'Submit the word you see below:';
00123         echo $cap['image'];
00124         echo '<input type="text" name="captcha" value="" />';
00125 
00126 
00127 Then, on the page that accepts the submission you'll have something like this:
00128 
00129         // First, delete old captchas
00130         $expiration = time()-7200; // Two hour limit
00131         $DB->query("DELETE FROM captcha WHERE captcha_time < ".$expiration);            
00132 
00133         // Then see if a captcha exists:
00134         $sql = "SELECT COUNT(*) AS count FROM captcha WHERE word = ? AND ip_address = ? AND date > ?";
00135         $binds = array($_POST['captcha'], $this->input->ip_address(), $expiration);
00136         $query = $this->db->query($sql, $binds);
00137         $row = $query->row();
00138 
00139         if ($row->count == 0)
00140         {
00141                 echo "You must submit the word that appears in the image";
00142         }
00143 
00144 */
00145 
00146 
00147         
00148 /**
00149 |==========================================================
00150 | Create Captcha
00151 |==========================================================
00152 |
00153 */
00154 function create_captcha($data = '', $img_path = '', $img_url = '', $font_path = '')
00155 {               
00156         $defaults = array('word' => '', 'img_path' => '', 'img_url' => '', 'img_width' => '150', 'img_height' => '30', 'font_path' => '', 'expiration' => 7200);                
00157         
00158         foreach ($defaults as $key => $val)
00159         {
00160                 if ( ! is_array($data))
00161                 {
00162                         if ( ! isset($$key) OR $$key == '')
00163                         {
00164                                 $$key = $val;
00165                         }
00166                 }
00167                 else
00168                 {                       
00169                         $$key = ( ! isset($data[$key])) ? $val : $data[$key];
00170                 }
00171         }
00172         
00173         if ($img_path == '' OR $img_url == '')
00174         {
00175                 return FALSE;
00176         }
00177 
00178         if ( ! @is_dir($img_path))
00179         {
00180                 return FALSE;
00181         }
00182         
00183         if ( ! is_really_writable($img_path))
00184         {
00185                 return FALSE;
00186         }
00187                         
00188         if ( ! extension_loaded('gd'))
00189         {
00190                 return FALSE;
00191         }               
00192         
00193         // -----------------------------------
00194         // Remove old images    
00195         // -----------------------------------
00196                         
00197         list($usec, $sec) = explode(" ", microtime());
00198         $now = ((float)$usec + (float)$sec);
00199                         
00200         $current_dir = @opendir($img_path);
00201         
00202         while($filename = @readdir($current_dir))
00203         {
00204                 if ($filename != "." and $filename != ".." and $filename != "index.html")
00205                 {
00206                         $name = str_replace(".jpg", "", $filename);
00207                 
00208                         if (($name + $expiration) < $now)
00209                         {
00210                                 @unlink($img_path.$filename);
00211                         }
00212                 }
00213         }
00214         
00215         @closedir($current_dir);
00216 
00217         // -----------------------------------
00218         // Do we have a "word" yet?
00219         // -----------------------------------
00220         
00221    if ($word == '')
00222    {
00223                 $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
00224 
00225                 $str = '';
00226                 for ($i = 0; $i < 8; $i++)
00227                 {
00228                         $str .= substr($pool, mt_rand(0, strlen($pool) -1), 1);
00229                 }
00230                 
00231                 $word = $str;
00232    }
00233         
00234         // -----------------------------------
00235         // Determine angle and position 
00236         // -----------------------------------
00237         
00238         $length = strlen($word);
00239         $angle  = ($length >= 6) ? rand(-($length-6), ($length-6)) : 0;
00240         $x_axis = rand(6, (360/$length)-16);                    
00241         $y_axis = ($angle >= 0 ) ? rand($img_height, $img_width) : rand(6, $img_height);
00242         
00243         // -----------------------------------
00244         // Create image
00245         // -----------------------------------
00246                         
00247         // PHP.net recommends imagecreatetruecolor(), but it isn't always available
00248         if (function_exists('imagecreatetruecolor'))
00249         {
00250                 $im = imagecreatetruecolor($img_width, $img_height);
00251         }
00252         else
00253         {
00254                 $im = imagecreate($img_width, $img_height);
00255         }
00256                         
00257         // -----------------------------------
00258         //  Assign colors
00259         // -----------------------------------
00260         
00261         $bg_color               = imagecolorallocate ($im, 255, 255, 255);
00262         $border_color   = imagecolorallocate ($im, 153, 102, 102);
00263         $text_color             = imagecolorallocate ($im, 204, 153, 153);
00264         $grid_color             = imagecolorallocate($im, 255, 182, 182);
00265         $shadow_color   = imagecolorallocate($im, 255, 240, 240);
00266 
00267         // -----------------------------------
00268         //  Create the rectangle
00269         // -----------------------------------
00270         
00271         ImageFilledRectangle($im, 0, 0, $img_width, $img_height, $bg_color);
00272         
00273         // -----------------------------------
00274         //  Create the spiral pattern
00275         // -----------------------------------
00276         
00277         $theta          = 1;
00278         $thetac         = 7;
00279         $radius         = 16;
00280         $circles        = 20;
00281         $points         = 32;
00282 
00283         for ($i = 0; $i < ($circles * $points) - 1; $i++)
00284         {
00285                 $theta = $theta + $thetac;
00286                 $rad = $radius * ($i / $points );
00287                 $x = ($rad * cos($theta)) + $x_axis;
00288                 $y = ($rad * sin($theta)) + $y_axis;
00289                 $theta = $theta + $thetac;
00290                 $rad1 = $radius * (($i + 1) / $points);
00291                 $x1 = ($rad1 * cos($theta)) + $x_axis;
00292                 $y1 = ($rad1 * sin($theta )) + $y_axis;
00293                 imageline($im, $x, $y, $x1, $y1, $grid_color);
00294                 $theta = $theta - $thetac;
00295         }
00296 
00297         // -----------------------------------
00298         //  Write the text
00299         // -----------------------------------
00300         
00301         $use_font = ($font_path != '' AND file_exists($font_path) AND function_exists('imagettftext')) ? TRUE : FALSE;
00302                 
00303         if ($use_font == FALSE)
00304         {
00305                 $font_size = 5;
00306                 $x = rand(0, $img_width/($length/3));
00307                 $y = 0;
00308         }
00309         else
00310         {
00311                 $font_size      = 16;
00312                 $x = rand(0, $img_width/($length/1.5));
00313                 $y = $font_size+2;
00314         }
00315 
00316         for ($i = 0; $i < strlen($word); $i++)
00317         {
00318                 if ($use_font == FALSE)
00319                 {
00320                         $y = rand(0 , $img_height/2);
00321                         imagestring($im, $font_size, $x, $y, substr($word, $i, 1), $text_color);
00322                         $x += ($font_size*2);
00323                 }
00324                 else
00325                 {               
00326                         $y = rand($img_height/2, $img_height-3);
00327                         imagettftext($im, $font_size, $angle, $x, $y, $text_color, $font_path, substr($word, $i, 1));
00328                         $x += $font_size;
00329                 }
00330         }
00331         
00332 
00333         // -----------------------------------
00334         //  Create the border
00335         // -----------------------------------
00336 
00337         imagerectangle($im, 0, 0, $img_width-1, $img_height-1, $border_color);          
00338 
00339         // -----------------------------------
00340         //  Generate the image
00341         // -----------------------------------
00342         
00343         $img_name = $now.'.jpg';
00344 
00345         ImageJPEG($im, $img_path.$img_name);
00346         
00347         $img = "<img src=\"$img_url$img_name\" width=\"$img_width\" height=\"$img_height\" style=\"border:0;\" alt=\" \" />";
00348         
00349         ImageDestroy($im);
00350                 
00351         return array('word' => $word, 'time' => $now, 'image' => $img);
00352 }
00353 
00354 
00355 /* End of file captcha_pi.php */
00356 /* Location: ./system/plugins/captcha_pi.php */