PageRenderTime 61ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/system/libraries/drivers/Captcha.php

http://github.com/ushahidi/Ushahidi_Web
PHP | 228 lines | 110 code | 31 blank | 87 comment | 9 complexity | 14f47df40ae6db25d6f308b6c628db20 MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php defined('SYSPATH') OR die('No direct access allowed.');
  2. /**
  3. * Captcha driver class.
  4. *
  5. * $Id: Captcha.php 3917 2009-01-21 03:06:22Z zombor $
  6. *
  7. * @package Captcha
  8. * @author Kohana Team
  9. * @copyright (c) 2007-2008 Kohana Team
  10. * @license http://kohanaphp.com/license.html
  11. */
  12. abstract class Captcha_Driver {
  13. // The correct Captcha challenge answer
  14. protected $response;
  15. // Image resource identifier and type ("png", "gif" or "jpeg")
  16. protected $image;
  17. protected $image_type = 'png';
  18. /**
  19. * Constructs a new challenge.
  20. *
  21. * @return void
  22. */
  23. public function __construct()
  24. {
  25. // Generate a new challenge
  26. $this->response = $this->generate_challenge();
  27. // Store the correct Captcha response in a session
  28. Event::add('system.post_controller', array($this, 'update_response_session'));
  29. }
  30. /**
  31. * Generate a new Captcha challenge.
  32. *
  33. * @return string the challenge answer
  34. */
  35. abstract public function generate_challenge();
  36. /**
  37. * Output the Captcha challenge.
  38. *
  39. * @param boolean html output
  40. * @return mixed the rendered Captcha (e.g. an image, riddle, etc.)
  41. */
  42. abstract public function render($html);
  43. /**
  44. * Stores the response for the current Captcha challenge in a session so it is available
  45. * on the next page load for Captcha::valid(). This method is called after controller
  46. * execution (in the system.post_controller event) in order not to overwrite itself too soon.
  47. *
  48. * @return void
  49. */
  50. public function update_response_session()
  51. {
  52. Kohana::log('info'," Captcha--> updateresponse= " . strtoupper($this->response));
  53. Session::instance()->set('captcha_response', sha1(strtoupper($this->response)));
  54. }
  55. /**
  56. * Validates a Captcha response from a user.
  57. *
  58. * @param string captcha response
  59. * @return boolean
  60. */
  61. public function valid($response)
  62. {
  63. return (sha1(strtoupper($response)) === Session::instance()->get('captcha_response'));
  64. }
  65. /**
  66. * Returns the image type.
  67. *
  68. * @param string filename
  69. * @return string|FALSE image type ("png", "gif" or "jpeg")
  70. */
  71. public function image_type($filename)
  72. {
  73. switch (strtolower(substr(strrchr($filename, '.'), 1)))
  74. {
  75. case 'png':
  76. return 'png';
  77. case 'gif':
  78. return 'gif';
  79. case 'jpg':
  80. case 'jpeg':
  81. // Return "jpeg" and not "jpg" because of the GD2 function names
  82. return 'jpeg';
  83. default:
  84. return FALSE;
  85. }
  86. }
  87. /**
  88. * Creates an image resource with the dimensions specified in config.
  89. * If a background image is supplied, the image dimensions are used.
  90. *
  91. * @throws Kohana_Exception if no GD2 support
  92. * @param string path to the background image file
  93. * @return void
  94. */
  95. public function image_create($background = NULL)
  96. {
  97. // Check for GD2 support
  98. if ( ! function_exists('imagegd2'))
  99. throw new Kohana_Exception('captcha.requires_GD2');
  100. // Create a new image (black)
  101. $this->image = imagecreatetruecolor(Captcha::$config['width'], Captcha::$config['height']);
  102. // Use a background image
  103. if ( ! empty($background))
  104. {
  105. // Create the image using the right function for the filetype
  106. $function = 'imagecreatefrom'.$this->image_type($background);
  107. $this->background_image = $function($background);
  108. // Resize the image if needed
  109. if (imagesx($this->background_image) !== Captcha::$config['width']
  110. OR imagesy($this->background_image) !== Captcha::$config['height'])
  111. {
  112. imagecopyresampled
  113. (
  114. $this->image, $this->background_image, 0, 0, 0, 0,
  115. Captcha::$config['width'], Captcha::$config['height'],
  116. imagesx($this->background_image), imagesy($this->background_image)
  117. );
  118. }
  119. // Free up resources
  120. imagedestroy($this->background_image);
  121. }
  122. }
  123. /**
  124. * Fills the background with a gradient.
  125. *
  126. * @param resource gd image color identifier for start color
  127. * @param resource gd image color identifier for end color
  128. * @param string direction: 'horizontal' or 'vertical', 'random' by default
  129. * @return void
  130. */
  131. public function image_gradient($color1, $color2, $direction = NULL)
  132. {
  133. $directions = array('horizontal', 'vertical');
  134. // Pick a random direction if needed
  135. if ( ! in_array($direction, $directions))
  136. {
  137. $direction = $directions[array_rand($directions)];
  138. // Switch colors
  139. if (mt_rand(0, 1) === 1)
  140. {
  141. $temp = $color1;
  142. $color1 = $color2;
  143. $color2 = $temp;
  144. }
  145. }
  146. // Extract RGB values
  147. $color1 = imagecolorsforindex($this->image, $color1);
  148. $color2 = imagecolorsforindex($this->image, $color2);
  149. // Preparations for the gradient loop
  150. $steps = ($direction === 'horizontal') ? Captcha::$config['width'] : Captcha::$config['height'];
  151. $r1 = ($color1['red'] - $color2['red']) / $steps;
  152. $g1 = ($color1['green'] - $color2['green']) / $steps;
  153. $b1 = ($color1['blue'] - $color2['blue']) / $steps;
  154. if ($direction === 'horizontal')
  155. {
  156. $x1 =& $i;
  157. $y1 = 0;
  158. $x2 =& $i;
  159. $y2 = Captcha::$config['height'];
  160. }
  161. else
  162. {
  163. $x1 = 0;
  164. $y1 =& $i;
  165. $x2 = Captcha::$config['width'];
  166. $y2 =& $i;
  167. }
  168. // Execute the gradient loop
  169. for ($i = 0; $i <= $steps; $i++)
  170. {
  171. $r2 = $color1['red'] - floor($i * $r1);
  172. $g2 = $color1['green'] - floor($i * $g1);
  173. $b2 = $color1['blue'] - floor($i * $b1);
  174. $color = imagecolorallocate($this->image, $r2, $g2, $b2);
  175. imageline($this->image, $x1, $y1, $x2, $y2, $color);
  176. }
  177. }
  178. /**
  179. * Returns the img html element or outputs the image to the browser.
  180. *
  181. * @param boolean html output
  182. * @return mixed html string or void
  183. */
  184. public function image_render($html)
  185. {
  186. // Output html element
  187. if ($html)
  188. return '<img alt="Captcha" src="'.url::site('captcha/'.Captcha::$config['group']).'/'.rand(10000,99999).'" width="'.Captcha::$config['width'].'" height="'.Captcha::$config['height'].'" />';
  189. // Send the correct HTTP header
  190. header('Content-Type: image/'.$this->image_type);
  191. // Pick the correct output function
  192. $function = 'image'.$this->image_type;
  193. $function($this->image);
  194. // Free up resources
  195. imagedestroy($this->image);
  196. }
  197. } // End Captcha Driver