/system/plugins/captcha_pi.php
PHP | 356 lines | 130 code | 46 blank | 180 comment | 26 complexity | 2f5491003b50b5a330c4b2a8c0e94916 MD5 | raw file
Possible License(s): Unlicense
1<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); 2/** 3 * CodeIgniter 4 * 5 * An open source application development framework for PHP 4.3.2 or newer 6 * 7 * @package CodeIgniter 8 * @author ExpressionEngine Dev Team 9 * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. 10 * @license http://codeigniter.com/user_guide/license.html 11 * @link http://codeigniter.com 12 * @since Version 1.0 13 * @filesource 14 */ 15 16// ------------------------------------------------------------------------ 17 18/* 19Instructions: 20 21Load the plugin using: 22 23 $this->load->plugin('captcha'); 24 25Once loaded you can generate a captcha like this: 26 27 $vals = array( 28 'word' => 'Random word', 29 'img_path' => './captcha/', 30 'img_url' => 'http://example.com/captcha/', 31 'font_path' => './system/fonts/texb.ttf', 32 'img_width' => '150', 33 'img_height' => 30, 34 'expiration' => 7200 35 ); 36 37 $cap = create_captcha($vals); 38 echo $cap['image']; 39 40 41NOTES: 42 43 The captcha function requires the GD image library. 44 45 Only the img_path and img_url are required. 46 47 If a "word" is not supplied, the function will generate a random 48 ASCII string. You might put together your own word library that 49 you can draw randomly from. 50 51 If you do not specify a path to a TRUE TYPE font, the native ugly GD 52 font will be used. 53 54 The "captcha" folder must be writable (666, or 777) 55 56 The "expiration" (in seconds) signifies how long an image will 57 remain in the captcha folder before it will be deleted. The default 58 is two hours. 59 60RETURNED DATA 61 62The create_captcha() function returns an associative array with this data: 63 64 [array] 65 ( 66 'image' => IMAGE TAG 67 'time' => TIMESTAMP (in microtime) 68 'word' => CAPTCHA WORD 69 ) 70 71The "image" is the actual image tag: 72<img src="http://example.com/captcha/12345.jpg" width="140" height="50" /> 73 74The "time" is the micro timestamp used as the image name without the file 75extension. It will be a number like this: 1139612155.3422 76 77The "word" is the word that appears in the captcha image, which if not 78supplied to the function, will be a random string. 79 80 81ADDING A DATABASE 82 83In order for the captcha function to prevent someone from posting, you will need 84to add the information returned from create_captcha() function to your database. 85Then, when the data from the form is submitted by the user you will need to verify 86that the data exists in the database and has not expired. 87 88Here is a table prototype: 89 90 CREATE TABLE captcha ( 91 captcha_id bigint(13) unsigned NOT NULL auto_increment, 92 captcha_time int(10) unsigned NOT NULL, 93 ip_address varchar(16) default '0' NOT NULL, 94 word varchar(20) NOT NULL, 95 PRIMARY KEY `captcha_id` (`captcha_id`), 96 KEY `word` (`word`) 97 ) 98 99 100Here is an example of usage with a DB. 101 102On the page where the captcha will be shown you'll have something like this: 103 104 $this->load->plugin('captcha'); 105 $vals = array( 106 'img_path' => './captcha/', 107 'img_url' => 'http://example.com/captcha/' 108 ); 109 110 $cap = create_captcha($vals); 111 112 $data = array( 113 'captcha_id' => '', 114 'captcha_time' => $cap['time'], 115 'ip_address' => $this->input->ip_address(), 116 'word' => $cap['word'] 117 ); 118 119 $query = $this->db->insert_string('captcha', $data); 120 $this->db->query($query); 121 122 echo 'Submit the word you see below:'; 123 echo $cap['image']; 124 echo '<input type="text" name="captcha" value="" />'; 125 126 127Then, on the page that accepts the submission you'll have something like this: 128 129 // First, delete old captchas 130 $expiration = time()-7200; // Two hour limit 131 $DB->query("DELETE FROM captcha WHERE captcha_time < ".$expiration); 132 133 // Then see if a captcha exists: 134 $sql = "SELECT COUNT(*) AS count FROM captcha WHERE word = ? AND ip_address = ? AND date > ?"; 135 $binds = array($_POST['captcha'], $this->input->ip_address(), $expiration); 136 $query = $this->db->query($sql, $binds); 137 $row = $query->row(); 138 139 if ($row->count == 0) 140 { 141 echo "You must submit the word that appears in the image"; 142 } 143 144*/ 145 146 147 148/** 149|========================================================== 150| Create Captcha 151|========================================================== 152| 153*/ 154function create_captcha($data = '', $img_path = '', $img_url = '', $font_path = '') 155{ 156 $defaults = array('word' => '', 'img_path' => '', 'img_url' => '', 'img_width' => '150', 'img_height' => '30', 'font_path' => '', 'expiration' => 7200); 157 158 foreach ($defaults as $key => $val) 159 { 160 if ( ! is_array($data)) 161 { 162 if ( ! isset($$key) OR $$key == '') 163 { 164 $$key = $val; 165 } 166 } 167 else 168 { 169 $$key = ( ! isset($data[$key])) ? $val : $data[$key]; 170 } 171 } 172 173 if ($img_path == '' OR $img_url == '') 174 { 175 return FALSE; 176 } 177 178 if ( ! @is_dir($img_path)) 179 { 180 return FALSE; 181 } 182 183 if ( ! is_really_writable($img_path)) 184 { 185 return FALSE; 186 } 187 188 if ( ! extension_loaded('gd')) 189 { 190 return FALSE; 191 } 192 193 // ----------------------------------- 194 // Remove old images 195 // ----------------------------------- 196 197 list($usec, $sec) = explode(" ", microtime()); 198 $now = ((float)$usec + (float)$sec); 199 200 $current_dir = @opendir($img_path); 201 202 while($filename = @readdir($current_dir)) 203 { 204 if ($filename != "." and $filename != ".." and $filename != "index.html") 205 { 206 $name = str_replace(".jpg", "", $filename); 207 208 if (($name + $expiration) < $now) 209 { 210 @unlink($img_path.$filename); 211 } 212 } 213 } 214 215 @closedir($current_dir); 216 217 // ----------------------------------- 218 // Do we have a "word" yet? 219 // ----------------------------------- 220 221 if ($word == '') 222 { 223 $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; 224 225 $str = ''; 226 for ($i = 0; $i < 8; $i++) 227 { 228 $str .= substr($pool, mt_rand(0, strlen($pool) -1), 1); 229 } 230 231 $word = $str; 232 } 233 234 // ----------------------------------- 235 // Determine angle and position 236 // ----------------------------------- 237 238 $length = strlen($word); 239 $angle = ($length >= 6) ? rand(-($length-6), ($length-6)) : 0; 240 $x_axis = rand(6, (360/$length)-16); 241 $y_axis = ($angle >= 0 ) ? rand($img_height, $img_width) : rand(6, $img_height); 242 243 // ----------------------------------- 244 // Create image 245 // ----------------------------------- 246 247 // PHP.net recommends imagecreatetruecolor(), but it isn't always available 248 if (function_exists('imagecreatetruecolor')) 249 { 250 $im = imagecreatetruecolor($img_width, $img_height); 251 } 252 else 253 { 254 $im = imagecreate($img_width, $img_height); 255 } 256 257 // ----------------------------------- 258 // Assign colors 259 // ----------------------------------- 260 261 $bg_color = imagecolorallocate ($im, 255, 255, 255); 262 $border_color = imagecolorallocate ($im, 153, 102, 102); 263 $text_color = imagecolorallocate ($im, 204, 153, 153); 264 $grid_color = imagecolorallocate($im, 255, 182, 182); 265 $shadow_color = imagecolorallocate($im, 255, 240, 240); 266 267 // ----------------------------------- 268 // Create the rectangle 269 // ----------------------------------- 270 271 ImageFilledRectangle($im, 0, 0, $img_width, $img_height, $bg_color); 272 273 // ----------------------------------- 274 // Create the spiral pattern 275 // ----------------------------------- 276 277 $theta = 1; 278 $thetac = 7; 279 $radius = 16; 280 $circles = 20; 281 $points = 32; 282 283 for ($i = 0; $i < ($circles * $points) - 1; $i++) 284 { 285 $theta = $theta + $thetac; 286 $rad = $radius * ($i / $points ); 287 $x = ($rad * cos($theta)) + $x_axis; 288 $y = ($rad * sin($theta)) + $y_axis; 289 $theta = $theta + $thetac; 290 $rad1 = $radius * (($i + 1) / $points); 291 $x1 = ($rad1 * cos($theta)) + $x_axis; 292 $y1 = ($rad1 * sin($theta )) + $y_axis; 293 imageline($im, $x, $y, $x1, $y1, $grid_color); 294 $theta = $theta - $thetac; 295 } 296 297 // ----------------------------------- 298 // Write the text 299 // ----------------------------------- 300 301 $use_font = ($font_path != '' AND file_exists($font_path) AND function_exists('imagettftext')) ? TRUE : FALSE; 302 303 if ($use_font == FALSE) 304 { 305 $font_size = 5; 306 $x = rand(0, $img_width/($length/3)); 307 $y = 0; 308 } 309 else 310 { 311 $font_size = 16; 312 $x = rand(0, $img_width/($length/1.5)); 313 $y = $font_size+2; 314 } 315 316 for ($i = 0; $i < strlen($word); $i++) 317 { 318 if ($use_font == FALSE) 319 { 320 $y = rand(0 , $img_height/2); 321 imagestring($im, $font_size, $x, $y, substr($word, $i, 1), $text_color); 322 $x += ($font_size*2); 323 } 324 else 325 { 326 $y = rand($img_height/2, $img_height-3); 327 imagettftext($im, $font_size, $angle, $x, $y, $text_color, $font_path, substr($word, $i, 1)); 328 $x += $font_size; 329 } 330 } 331 332 333 // ----------------------------------- 334 // Create the border 335 // ----------------------------------- 336 337 imagerectangle($im, 0, 0, $img_width-1, $img_height-1, $border_color); 338 339 // ----------------------------------- 340 // Generate the image 341 // ----------------------------------- 342 343 $img_name = $now.'.jpg'; 344 345 ImageJPEG($im, $img_path.$img_name); 346 347 $img = "<img src=\"$img_url$img_name\" width=\"$img_width\" height=\"$img_height\" style=\"border:0;\" alt=\" \" />"; 348 349 ImageDestroy($im); 350 351 return array('word' => $word, 'time' => $now, 'image' => $img); 352} 353 354 355/* End of file captcha_pi.php */ 356/* Location: ./system/plugins/captcha_pi.php */