source: trunk/www.guidonia.net/wp/wp-content/plugins/odlinks/includes/captcha_class.php@ 44

Last change on this file since 44 was 44, checked in by luciano, 14 years ago
File size: 11.6 KB
Line 
1<?php
2
3/*
4* This class is taken in part from the Code of
5* PhpCaptcha CAPTCHA generation library from Edward Eliot.
6* class defaults - change to effect globally
7*/
8 session_start();
9 define('CAPCC_WIDTH', 120); // max 500
10 define('CAPCC_HEIGHT', 50); // max 200
11 define('CAPCC_NUM_CHARS', 4);
12 define('CAPCC_NUM_LINES', 20);
13 define('CAPCC_CHAR_SHADOW', false);
14 define('CAPCC_CHAR_SET', ''); // defaults to A-Z
15 define('CAPCC_CASE_INSENSITIVE', true);
16 define('CAPCC_BACKGROUND_IMAGES', '');
17 define('CAPCC_MIN_FONT_SIZE', 12);
18 define('CAPCC_MAX_FONT_SIZE', 20);
19 define('CAPCC_USE_COLOUR', true);
20 define('CAPCC_FILE_TYPE', 'png');
21
22 /************************ End Default Options **********************/
23
24 // don't edit below this line (unless you want to change the class!)
25
26 class _odl_captcha {
27 var $oImage;
28 var $iWidth = CAPCC_WIDTH;
29 var $iHeight = CAPCC_HEIGHT;
30 var $aFonts;
31 var $iNumChars;
32 var $iNumLines;
33 var $iSpacing;
34 var $bCharShadow;
35 var $aCharSet;
36 var $bCaseInsensitive;
37 var $vBackgroundImages;
38 var $iMinFontSize;
39 var $iMaxFontSize;
40 var $bUseColour;
41 var $sFileType;
42 var $sCode = '';
43
44
45 function _odl_captcha($aFonts) {
46 // get parameters
47 $this->aFonts = $aFonts;
48 $this->SetNumChars(CAPCC_NUM_CHARS);
49 $this->SetNumLines(CAPCC_NUM_LINES);
50 $this->DisplayShadow(CAPCC_CHAR_SHADOW);
51 $this->SetCharSet(CAPCC_CHAR_SET);
52 $this->CaseInsensitive(CAPCC_CASE_INSENSITIVE);
53 $this->SetBackgroundImages(CAPCC_BACKGROUND_IMAGES);
54 $this->SetMinFontSize(CAPCC_MIN_FONT_SIZE);
55 $this->SetMaxFontSize(CAPCC_MAX_FONT_SIZE);
56 $this->UseColour(CAPCC_USE_COLOUR);
57 $this->SetFileType(CAPCC_FILE_TYPE);
58 $this->SetWidth(CAPCC_WIDTH);
59 $this->SetHeight(CAPCC_HEIGHT);
60 }
61
62 function CalculateSpacing() {
63 $this->iSpacing = (int)($this->iWidth / $this->iNumChars);
64 }
65
66 function SetWidth($iWidth) {
67 $this->iWidth = $iWidth;
68 if ($this->iWidth > 500) $this->iWidth = 500; // to prevent perfomance impact
69 $this->CalculateSpacing();
70 }
71
72 function SetHeight($iHeight) {
73 $this->iHeight = $iHeight;
74 if ($this->iHeight > 200) $this->iHeight = 200; // to prevent performance impact
75 }
76
77 function SetNumChars($iNumChars) {
78 $this->iNumChars = $iNumChars;
79 $this->CalculateSpacing();
80 }
81
82 function SetNumLines($iNumLines) {
83 $this->iNumLines = $iNumLines;
84 }
85
86 function DisplayShadow($bCharShadow) {
87 $this->bCharShadow = $bCharShadow;
88 }
89
90
91 function SetCharSet($vCharSet) {
92 // check for input type
93 if (is_array($vCharSet)) {
94 $this->aCharSet = $vCharSet;
95 } else {
96 if ($vCharSet != '') {
97 // split items on commas
98 $aCharSet = explode(',', $vCharSet);
99 // initialise array
100 $this->aCharSet = array();
101 // loop through items
102 foreach ($aCharSet as $sCurrentItem) {
103 // a range should have 3 characters, otherwise is normal character
104 if (strlen($sCurrentItem) == 3) {
105 // split on range character
106 $aRange = explode('-', $sCurrentItem);
107 // check for valid range
108 if (count($aRange) == 2 && $aRange[0] < $aRange[1]) {
109 // create array of characters from range
110 $aRange = range($aRange[0], $aRange[1]);
111 // add to charset array
112 $this->aCharSet = array_merge($this->aCharSet, $aRange);
113 }
114 } else {
115 $this->aCharSet[] = $sCurrentItem;
116 }
117 }
118 }
119 }
120 }
121
122 function CaseInsensitive($bCaseInsensitive) {
123 $this->bCaseInsensitive = $bCaseInsensitive;
124 }
125
126 function SetBackgroundImages($vBackgroundImages) {
127 $this->vBackgroundImages = $vBackgroundImages;
128 }
129
130 function SetMinFontSize($iMinFontSize) {
131 $this->iMinFontSize = $iMinFontSize;
132 }
133
134 function SetMaxFontSize($iMaxFontSize) {
135 $this->iMaxFontSize = $iMaxFontSize;
136 }
137
138 function UseColour($bUseColour) {
139 $this->bUseColour = $bUseColour;
140 }
141
142 function SetFileType($sFileType) {
143 // check for valid file type
144 if (in_array($sFileType, array('gif', 'png', 'jpeg'))) {
145 $this->sFileType = $sFileType;
146 } else {
147 $this->sFileType = 'jpeg';
148 }
149 }
150
151 function DrawLines() {
152 for ($i = 0; $i < $this->iNumLines; $i++) {
153 // allocate colour
154 if ($this->bUseColour) {
155 $iLineColour = imagecolorallocate($this->oImage, rand(100, 250), rand(100, 250), rand(100, 250));
156 } else {
157 $iRandColour = rand(100, 250);
158 $iLineColour = imagecolorallocate($this->oImage, $iRandColour, $iRandColour, $iRandColour);
159 }
160 // draw line
161 imageline($this->oImage, rand(0, $this->iWidth), rand(0, $this->iHeight), rand(0, $this->iWidth), rand(0, $this->iHeight), $iLineColour);
162 }
163 }
164
165 function GenerateCode() {
166 // reset code
167 $this->sCode = '';
168 // loop through and generate the code letter by letter
169 for ($i = 0; $i < $this->iNumChars; $i++) {
170 if (count($this->aCharSet) > 0) {
171 // select random character and add to code string
172 $this->sCode .= $this->aCharSet[array_rand($this->aCharSet)];
173 } else {
174 // select random character and add to code string
175 $this->sCode .= chr(rand(65, 90));
176 }
177 }
178 // save code in session variable
179 if ($this->bCaseInsensitive) {
180 $_SESSION[CAPCC_SESSION_ID] = strtoupper($this->sCode);
181 } else {
182 $_SESSION[CAPCC_SESSION_ID] = $this->sCode;
183 }
184 }
185
186 function DrawCharacters() {
187 // loop through and write out selected number of characters
188 for ($i = 0; $i < strlen($this->sCode); $i++) {
189 // select random font
190 $sCurrentFont = $this->aFonts[array_rand($this->aFonts)];
191 // select random colour
192 if ($this->bUseColour) {
193 $iTextColour = imagecolorallocate($this->oImage, rand(0, 100), rand(0, 100), rand(0, 100));
194 if ($this->bCharShadow) {
195 // shadow colour
196 $iShadowColour = imagecolorallocate($this->oImage, rand(0, 100), rand(0, 100), rand(0, 100));
197 }
198 } else {
199 $iRandColour = rand(0, 100);
200 $iTextColour = imagecolorallocate($this->oImage, $iRandColour, $iRandColour, $iRandColour);
201 if ($this->bCharShadow) {
202 // shadow colour
203 $iRandColour = rand(0, 100);
204 $iShadowColour = imagecolorallocate($this->oImage, $iRandColour, $iRandColour, $iRandColour);
205 }
206 }
207 // select random font size
208 $iFontSize = rand($this->iMinFontSize, $this->iMaxFontSize);
209 // select random angle
210 $iAngle = rand(-30, 30);
211 // get dimensions of character in selected font and text size
212 $aCharDetails = imageftbbox($iFontSize, $iAngle, $sCurrentFont, $this->sCode[$i], array());
213 // calculate character starting coordinates
214 $iX = $this->iSpacing / 4 + $i * $this->iSpacing;
215 $iCharHeight = $aCharDetails[2] - $aCharDetails[5];
216 $iY = $this->iHeight / 2 + $iCharHeight / 4;
217 // write text to image
218 imagefttext($this->oImage, $iFontSize, $iAngle, $iX, $iY, $iTextColour, $sCurrentFont, $this->sCode[$i], array());
219 if ($this->bCharShadow) {
220 $iOffsetAngle = rand(-30, 30);
221 $iRandOffsetX = rand(-5, 5);
222 $iRandOffsetY = rand(-5, 5);
223 imagefttext($this->oImage, $iFontSize, $iOffsetAngle, $iX + $iRandOffsetX, $iY + $iRandOffsetY, $iShadowColour, $sCurrentFont, $this->sCode[$i], array());
224 }
225 }
226 }
227
228 function create($sFilename = '') {
229 // check for required gd functions
230 if (!function_exists('imagecreate') ||
231 !function_exists("image$this->sFileType") || ($this->vBackgroundImages != '' && !function_exists('imagecreatetruecolor'))) {
232 return false;
233 }
234 // get background image if specified and copy to CAPTCHA
235 if (is_array($this->vBackgroundImages) || $this->vBackgroundImages != '') {
236 // create new image
237 $this->oImage = imagecreatetruecolor($this->iWidth, $this->iHeight);
238 // create background image
239 if (is_array($this->vBackgroundImages)) {
240 $iRandImage = array_rand($this->vBackgroundImages);
241 $oBackgroundImage = imagecreatefromjpeg($this->vBackgroundImages[$iRandImage]);
242 } else {
243 $oBackgroundImage = imagecreatefromjpeg($this->vBackgroundImages);
244 }
245 // copy background image
246 imagecopy($this->oImage, $oBackgroundImage, 0, 0, 0, 0, $this->iWidth, $this->iHeight);
247 // free memory used to create background image
248 imagedestroy($oBackgroundImage);
249 } else {
250 // create new image
251 $this->oImage = imagecreate($this->iWidth, $this->iHeight);
252 //$this->oImage = imagecreatetruecolor($this->iWidth, $this->iHeight);
253 }
254 // allocate white background colour
255 imagecolorallocate($this->oImage, 255, 255, 255);
256 // check for background image before drawing lines
257 if (!is_array($this->vBackgroundImages) && $this->vBackgroundImages == '') {
258 $this->DrawLines();
259 }
260 $this->GenerateCode();
261 $this->DrawCharacters();
262 // write out image to file or browser
263 $this->WriteFile($sFilename);
264 // free memory used in creating image
265 imagedestroy($this->oImage);
266 return true;
267 }
268
269 function WriteFile($sFilename) {
270 if ($sFilename == '') {
271 // tell browser that data is jpeg
272 header("Content-type: image/" . $this->sFileType );
273 }
274 switch ($this->sFileType) {
275 case 'gif':
276 $sFilename != '' ? imagegif($this->oImage, $sFilename) : imagegif($this->oImage);
277 break;
278 case 'png':
279 $sFilename != '' ? imagepng($this->oImage, $sFilename) : imagepng($this->oImage);
280 break;
281 default:
282 $sFilename != '' ? imagejpeg($this->oImage, $sFilename) : imagejpeg($this->oImage);
283 }
284 }
285
286 // call this method statically
287 function Validate($sUserCode, $bCaseInsensitive = true) {
288 if ($bCaseInsensitive) {
289 $sUserCode = strtoupper($sUserCode);
290 }
291 if (!empty($_SESSION[CAPCC_SESSION_ID]) && $sUserCode == $_SESSION[CAPCC_SESSION_ID]) {
292 // clear to prevent re-use
293 unset($_SESSION[CAPCC_SESSION_ID]);
294 return true;
295 }
296 return false;
297 }
298 }
299
300 // example sub class
301 class _odl_captchaColour extends _odl_captcha {
302 function _odl_captchaColour($aFonts) {
303 // call parent constructor
304 parent::_odl_captcha($aFonts);
305
306 // set options
307 $this->UseColour(true);
308 }
309 }
310?>
Note: See TracBrowser for help on using the repository browser.