PageRenderTime 45ms CodeModel.GetById 1ms app.highlight 37ms RepoModel.GetById 1ms app.codeStats 0ms

/wwwroot/mantis/make_captcha_img.php

https://github.com/spring/spring-website
PHP | 318 lines | 216 code | 33 blank | 69 comment | 49 complexity | 8d09afd92f4a0b49bc7e9d6b4ba168e6 MD5 | raw file
  1<?php
  2# MantisBT - a php based bugtracking system
  3
  4# MantisBT is free software: you can redistribute it and/or modify
  5# it under the terms of the GNU General Public License as published by
  6# the Free Software Foundation, either version 2 of the License, or
  7# (at your option) any later version.
  8#
  9# MantisBT is distributed in the hope that it will be useful,
 10# but WITHOUT ANY WARRANTY; without even the implied warranty of
 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12# GNU General Public License for more details.
 13#
 14# You should have received a copy of the GNU General Public License
 15# along with MantisBT.  If not, see <http://www.gnu.org/licenses/>.
 16
 17	/**
 18	 * @package MantisBT
 19	 * @copyright Copyright (C) 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
 20	 * @copyright Copyright (C) 2002 - 2014  MantisBT Team - mantisbt-dev@lists.sourceforge.net
 21	 * @author Marcello Scata' <marcelloscata at users.sourceforge.net> ITALY
 22	 * @link http://www.mantisbt.org
 23	 */
 24	 /**
 25	  * MantisBT Core API's
 26	  */
 27	require_once( 'core.php' );
 28
 29	$t_form_key = session_get( CAPTCHA_KEY );
 30
 31	$t_key = utf8_strtolower( utf8_substr( md5( config_get( 'password_confirm_hash_magic_string' ) . $t_form_key ), 1, 5) );
 32	$t_system_font_folder = get_font_path();
 33	$t_font_per_captcha = config_get( 'font_per_captcha' );
 34
 35	$t_captcha_init = array(
 36		'TTF_folder'     => $t_system_font_folder,
 37		'TTF_RANGE'      => array( $t_font_per_captcha )
 38	);
 39
 40	$captcha = new masc_captcha( $t_captcha_init );
 41	$captcha->make_captcha( $t_key );
 42
 43#
 44# The class below was derived from
 45# http://www.phpclasses.org/browse/package/1163.html
 46#
 47# *** 3.0 Author
 48# Pascal Rehfeldt
 49# Pascal@Pascal-Rehfeldt.com
 50#
 51# http://www.phpclasses.org/browse.html/author/102754.html
 52#
 53#
 54# *** 3.1 License
 55# GNU General Public License (Version 2, June 1991)
 56#
 57# This program is free software; you can redistribute
 58# it and/or modify it under the terms of the GNU
 59# General Public License as published by the Free
 60# Software Foundation; either version 2 of the License,
 61# or (at your option) any later version.
 62#
 63# This program is distributed in the hope that it will
 64# be useful, but WITHOUT ANY WARRANTY; without even the
 65# implied warranty of MERCHANTABILITY or FITNESS FOR A
 66# PARTICULAR PURPOSE. See the GNU General Public License
 67# for more details.
 68#
 69
 70	class masc_captcha
 71	{
 72		var $TTF_folder;
 73		var $TTF_RANGE  = array('ARIAL.TTF');
 74		var $chars		= 5;
 75		var $minsize	= 15;
 76		var $maxsize	= 15;
 77		var $maxrotation = 30;
 78		var $noise		= FALSE;
 79		var $websafecolors = TRUE;
 80		var $debug = FALSE;
 81
 82		var $lx;				// width of picture
 83		var $ly;				// height of picture
 84		var $jpegquality = 80;	// image quality
 85		var $noisefactor = 9;	// this will multiplyed with number of chars
 86		var $nb_noise;			// number of background-noise-characters
 87		var $TTF_file;			// holds the current selected TrueTypeFont
 88		var $gd_version;		// holds the Version Number of GD-Library
 89		var $r;
 90		var $g;
 91		var $b;
 92
 93
 94			function masc_captcha( $config )
 95			{
 96				// Test for GD-Library(-Version)
 97				$this->gd_version = get_gd_version();
 98				if($this->gd_version == 0) die("There is no GD-Library-Support enabled. The Captcha-Class cannot be used!");
 99				if($this->debug) echo "\n<br />-Captcha-Debug: The available GD-Library has major version ".$this->gd_version;
100
101				// extracts config array
102				if(is_array($config))
103				{
104					if($this->debug) echo "\n<br />-Captcha-Debug: Extracts Config-Array in unsecure-mode!";
105					foreach($config as $k=>$v) $this->$k = $v;
106				}
107
108				// check vars for maxtry, secretposition and min-max-size
109				if($this->minsize > $this->maxsize)
110				{
111					$temp = $this->minsize;
112					$this->minsize = $this->maxsize;
113					$this->maxsize = $temp;
114					if($this->debug) echo "<br />-Captcha-Debug: Arrghh! What do you think I mean with min and max? Switch minsize with maxsize.";
115				}
116
117				// check TrueTypeFonts
118				if(is_array($this->TTF_RANGE))
119				{
120					if($this->debug) echo "\n<br />-Captcha-Debug: Check given TrueType-Array! (".count($this->TTF_RANGE).")";
121					$temp = array();
122					foreach($this->TTF_RANGE as $k=>$v)
123					{
124						if(is_readable($this->TTF_folder.$v)) $temp[] = $v;
125					}
126					$this->TTF_RANGE = $temp;
127					if($this->debug) echo "\n<br />-Captcha-Debug: Valid TrueType-files: (".count($this->TTF_RANGE).")";
128					//if(count($this->TTF_RANGE) < 1) die('No Truetypefont available for the CaptchaClass.');
129				}
130				else
131				{
132					if($this->debug) echo "\n<br />-Captcha-Debug: Check given TrueType-File! (".$this->TTF_RANGE.")";
133					if(!is_readable($this->TTF_folder.$this->TTF_RANGE)) die('No Truetypefont available for the CaptchaClass.');
134				}
135
136				// select first TrueTypeFont
137				$this->change_TTF();
138				if($this->debug) echo "\n<br />-Captcha-Debug: Set current TrueType-File: (".$this->TTF_file.")";
139
140				// get number of noise-chars for background if is enabled
141				$this->nb_noise = $this->noise ? ($this->chars * $this->noisefactor) : 0;
142				if($this->debug) echo "\n<br />-Captcha-Debug: Set number of noise characters to: (".$this->nb_noise.")";
143
144				// set dimension of image
145				$this->lx = ($this->chars + 1) * (int)(($this->maxsize + $this->minsize) / 1.5);
146				$this->ly = (int)(2.4 * $this->maxsize);
147				if($this->debug) echo "\n<br />-Captcha-Debug: Set image dimension to: (".$this->lx." x ".$this->ly.")";
148			}
149
150			function generate_captcha( $private_key )
151			{
152				if($this->debug) echo "\n<br />-Captcha-Debug: Generate private key: ($private_key)";
153
154				// create Image and set the apropriate function depending on GD-Version & websafecolor-value
155				if($this->gd_version >= 2 && !$this->websafecolors)
156				{
157					$func1 = 'imagecreatetruecolor';
158					$func2 = 'imagecolorallocate';
159				}
160				else
161				{
162					$func1 = 'imageCreate';
163					$func2 = 'imagecolorclosest';
164				}
165				$image = $func1($this->lx,$this->ly);
166				if($this->debug) echo "\n<br />-Captcha-Debug: Generate ImageStream with: ($func1())";
167				if($this->debug) echo "\n<br />-Captcha-Debug: For colordefinitions we use: ($func2())";
168
169				// Set Backgroundcolor
170				$this->random_color(224, 255);
171				$back =  @imagecolorallocate($image, $this->r, $this->g, $this->b);
172				@ImageFilledRectangle($image,0,0,$this->lx,$this->ly,$back);
173				if($this->debug) echo "\n<br />-Captcha-Debug: We allocate one color for Background: (".$this->r."-".$this->g."-".$this->b.")";
174
175				// allocates the 216 websafe color palette to the image
176				if($this->gd_version < 2 || $this->websafecolors) $this->makeWebsafeColors($image);
177
178				// fill with noise or grid
179				if($this->nb_noise > 0)
180				{
181					// random characters in background with random position, angle, color
182					if($this->debug) echo "\n<br />-Captcha-Debug: Fill background with noise: (".$this->nb_noise.")";
183					for($i=0; $i < $this->nb_noise; $i++)
184					{
185						$size	= intval(mt_rand((int)($this->minsize / 2.3), (int)($this->maxsize / 1.7)));
186						$angle	= intval(mt_rand(0, 360));
187						$x		= intval(mt_rand(0, $this->lx));
188						$y		= intval(mt_rand(0, (int)($this->ly - ($size / 5))));
189						$this->random_color(160, 224);
190						$color	= $func2($image, $this->r, $this->g, $this->b);
191						$text	= chr(intval(mt_rand(45,250)));
192						if(count ($this->TTF_RANGE)>0){
193							@ImageTTFText($image, $size, $angle, $x, $y, $color, $this->change_TTF(), $text);
194						} else {
195							imagestring($image,5,$x,$y,$text,$color);
196						}
197					}
198				}
199				else
200				{
201					// generate grid
202					if($this->debug) echo "\n<br />-Captcha-Debug: Fill background with x-gridlines: (".(int)($this->lx / (int)($this->minsize / 1.5)).")";
203					for($i=0; $i < $this->lx; $i += (int)($this->minsize / 1.5))
204					{
205						$this->random_color(160, 224);
206						$color	= $func2($image, $this->r, $this->g, $this->b);
207						@imageline($image, $i, 0, $i, $this->ly, $color);
208					}
209					if($this->debug) echo "\n<br />-Captcha-Debug: Fill background with y-gridlines: (".(int)($this->ly / (int)(($this->minsize / 1.8))).")";
210					for($i=0 ; $i < $this->ly; $i += (int)($this->minsize / 1.8))
211					{
212						$this->random_color(160, 224);
213						$color	= $func2($image, $this->r, $this->g, $this->b);
214						@imageline($image, 0, $i, $this->lx, $i, $color);
215					}
216				}
217
218				// generate Text
219				if($this->debug) echo "\n<br />-Captcha-Debug: Fill foreground with chars and shadows: (".$this->chars.")";
220				for($i=0, $x = intval(mt_rand($this->minsize,$this->maxsize)); $i < $this->chars; $i++)
221				{
222					$text	= utf8_strtoupper(substr($private_key, $i, 1));
223					$angle	= intval(mt_rand(($this->maxrotation * -1), $this->maxrotation));
224					$size	= intval(mt_rand($this->minsize, $this->maxsize));
225					$y		= intval(mt_rand((int)($size * 1.5), (int)($this->ly - ($size / 7))));
226					$this->random_color(0, 127);
227					$color	=  $func2($image, $this->r, $this->g, $this->b);
228					$this->random_color(0, 127);
229					$shadow = $func2($image, $this->r + 127, $this->g + 127, $this->b + 127);
230					if(count($this->TTF_RANGE) > 0){
231						@ImageTTFText($image, $size, $angle, $x + (int)($size / 15), $y, $shadow, $this->change_TTF(), $text);
232						@ImageTTFText($image, $size, $angle, $x, $y - (int)($size / 15), $color, $this->TTF_file, $text);
233					} else {
234						$t_font = mt_rand(3,5);
235						imagestring($image,$t_font,$x + (int)($size / 15),$y-20,$text,$color);
236						imagestring($image,$t_font,$x,$y - (int)($size / 15)-20,$text,$color);
237					}
238					$x += (int)($size + ($this->minsize / 5));
239				}
240
241				# Generate the JPEG
242				ob_start();
243				@ImageJPEG($image, null, $this->jpegquality);
244				$jpg = ob_get_contents();
245				ob_end_clean();
246
247				@ImageDestroy($image);
248				if($this->debug) echo "\n<br />-Captcha-Debug: Destroy Imagestream.";
249
250				return $jpg;
251			}
252
253			function make_captcha( $private_key )
254			{
255				# Retrieve previously image generated from session cache
256				$t_image = session_get( CAPTCHA_IMG, null );
257
258				if( is_null( $t_image ) ) {
259					$t_image = $this->generate_captcha( $private_key );
260					if( $this->debug ) {
261						echo "\n<br />-Captcha-Debug: Caching generated image.";
262					}
263					session_set( CAPTCHA_IMG, $t_image );
264				} elseif( $this->debug ) {
265					echo "\n<br />-Captcha-Debug: Retrieved image from cache.";
266				}
267
268				# Output
269				if( $this->debug ) {
270					echo "\n<br />-Captcha-Debug: Generated image (" . strlen( $t_image ) . " bytes): "
271						. '<img src="data:image/jpeg;base64,' . base64_encode( $t_image ) . '">';
272				} else {
273					header('Content-type: image/jpeg');
274					echo $t_image;
275				}
276			}
277
278			/** @private **/
279			function makeWebsafeColors(&$image)
280			{
281				for($r = 0; $r <= 255; $r += 51)
282				{
283					for($g = 0; $g <= 255; $g += 51)
284					{
285						for($b = 0; $b <= 255; $b += 51)
286						{
287							$color = imagecolorallocate($image, $r, $g, $b);
288							//$a[$color] = array('r'=>$r,'g'=>$g,'b'=>$b);
289						}
290					}
291				}
292				if($this->debug) echo "\n<br />-Captcha-Debug: Allocate 216 websafe colors to image: (".imagecolorstotal($image).")";
293			}
294
295			function random_color($min,$max)
296			{
297				$this->r = intval(mt_rand($min,$max));
298				$this->g = intval(mt_rand($min,$max));
299				$this->b = intval(mt_rand($min,$max));
300			}
301
302			function change_TTF()
303			{
304				if(count($this->TTF_RANGE) > 0){
305					if(is_array($this->TTF_RANGE))
306					{
307						$key = array_rand($this->TTF_RANGE);
308						$this->TTF_file = $this->TTF_folder.$this->TTF_RANGE[$key];
309					}
310					else
311					{
312						$this->TTF_file = $this->TTF_folder.$this->TTF_RANGE;
313					}
314					return $this->TTF_file;
315				}
316			}
317
318	} // END CLASS masc_captcha