/class/captcha/image/scripts/image.php

https://gitlab.com/VoyaTrax/vtCMS2 · PHP · 413 lines · 267 code · 51 blank · 95 comment · 34 complexity · 940896cd3391d9f00525637d407e157d MD5 · raw file

  1. <?php
  2. /**
  3. * CAPTCHA class For XOOPS
  4. *
  5. * You may not change or alter any portion of this comment or credits
  6. * of supporting developers from this source code or any supporting source code
  7. * which is considered copyrighted (c) material of the original comment or credit authors.
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. *
  12. * @copyright (c) 2000-2016 XOOPS Project (www.xoops.org)
  13. * @license GNU GPL 2 (http://www.gnu.org/licenses/gpl-2.0.html)
  14. * @since 2.3.0
  15. * @author Taiwen Jiang <phppp@users.sourceforge.net>
  16. * @package class
  17. * @subpackage CAPTCHA
  18. */
  19. include '../../../../mainfile.php';
  20. error_reporting(0);
  21. $xoopsLogger->activated = false;
  22. /*
  23. if (empty($_SERVER['HTTP_REFERER']) || !preg_match("/^" . preg_quote(XOOPS_URL, '/') . "/", $_SERVER['HTTP_REFERER'])) {
  24. exit();
  25. }
  26. */
  27. /**
  28. * Class XoopsCaptchaImageHandler
  29. */
  30. class XoopsCaptchaImageHandler
  31. {
  32. public $config = array();
  33. public $code;
  34. public $mode = 'gd';
  35. public $invalid = false;
  36. public $font;
  37. public $spacing;
  38. public $width;
  39. public $height;
  40. public $captcha_handler;
  41. /**
  42. *
  43. */
  44. public function __construct()
  45. {
  46. xoops_load('XoopsCaptcha');
  47. $this->captcha_handler = XoopsCaptcha::getInstance();
  48. $this->config = $this->captcha_handler->loadConfig('image');
  49. }
  50. public function loadImage()
  51. {
  52. $this->generateCode();
  53. $this->createImage();
  54. }
  55. /**
  56. * Create Code
  57. */
  58. public function generateCode()
  59. {
  60. if ($this->invalid) {
  61. return false;
  62. }
  63. if ($this->mode === 'bmp') {
  64. $this->config['num_chars'] = 4;
  65. $this->code = mt_rand(pow(10, $this->config['num_chars'] - 1), (int)str_pad('9', $this->config['num_chars'], '9'));
  66. } else {
  67. $raw_code = md5(uniqid(mt_rand(), 1));
  68. if (!empty($this->config['skip_characters'])) {
  69. $valid_code = str_replace($this->config['skip_characters'], '', $raw_code);
  70. $this->code = substr($valid_code, 0, $this->config['num_chars']);
  71. } else {
  72. $this->code = substr($raw_code, 0, $this->config['num_chars']);
  73. }
  74. if (!$this->config['casesensitive']) {
  75. $this->code = strtoupper($this->code);
  76. }
  77. }
  78. $this->captcha_handler->setCode($this->code);
  79. return true;
  80. }
  81. /**
  82. * @return string|void
  83. */
  84. public function createImage()
  85. {
  86. if ($this->invalid) {
  87. header('Content-type: image/gif');
  88. readfile(XOOPS_ROOT_PATH . '/images/subject/icon2.gif');
  89. return null;
  90. }
  91. if ($this->mode === 'bmp') {
  92. return $this->createImageBmp();
  93. } else {
  94. return $this->createImageGd();
  95. }
  96. }
  97. /**
  98. * @param string $name
  99. * @param string $extension
  100. *
  101. * @return array|mixed
  102. */
  103. public function getList($name, $extension = '')
  104. {
  105. $items = array();
  106. xoops_load('XoopsCache');
  107. if ($items = XoopsCache::read("captcha_captcha_{$name}")) {
  108. return $items;
  109. }
  110. require_once XOOPS_ROOT_PATH . '/class/xoopslists.php';
  111. $file_path = XOOPS_ROOT_PATH . "/class/captcha/image/{$name}";
  112. $files = XoopsLists::getFileListAsArray($file_path);
  113. foreach ($files as $item) {
  114. if (empty($extension) || preg_match("/(\.{$extension})$/i", $item)) {
  115. $items[] = $item;
  116. }
  117. }
  118. XoopsCache::write("captcha_captcha_{$name}", $items);
  119. return $items;
  120. }
  121. /**#@+
  122. * Create CAPTCHA iamge with GD
  123. * Originated by DuGris' SecurityImage
  124. */
  125. // --------------------------------------------------------------------------- //
  126. // Class : SecurityImage 1.5 //
  127. // Author: DuGris aka L. Jen <http://www.dugris.info> //
  128. // Email : DuGris@wanadoo.fr //
  129. // Licence: GNU //
  130. // Project: The XOOPS Project //
  131. // --------------------------------------------------------------------------- //
  132. public function createImageGd()
  133. {
  134. $this->loadFont();
  135. $this->setImageSize();
  136. $this->oImage = imagecreatetruecolor($this->width, $this->height);
  137. $background = imagecolorallocate($this->oImage, 255, 255, 255);
  138. imagefilledrectangle($this->oImage, 0, 0, $this->width, $this->height, $background);
  139. switch ($this->config['background_type']) {
  140. default:
  141. case 0:
  142. $this->drawBars();
  143. break;
  144. case 1:
  145. $this->drawCircles();
  146. break;
  147. case 2:
  148. $this->drawLines();
  149. break;
  150. case 3:
  151. $this->drawRectangles();
  152. break;
  153. case 4:
  154. $this->drawEllipses();
  155. break;
  156. case 5:
  157. $this->drawPolygons();
  158. break;
  159. case 100:
  160. $this->createFromFile();
  161. break;
  162. }
  163. $this->drawBorder();
  164. $this->drawCode();
  165. header('Content-type: image/jpeg');
  166. imagejpeg($this->oImage);
  167. imagedestroy($this->oImage);
  168. }
  169. public function loadFont()
  170. {
  171. $fonts = $this->getList('fonts', 'ttf');
  172. $this->font = XOOPS_ROOT_PATH . '/class/captcha/image/fonts/' . $fonts[array_rand($fonts)];
  173. }
  174. public function setImageSize()
  175. {
  176. $MaxCharWidth = 0;
  177. $MaxCharHeight = 0;
  178. $oImage = imagecreatetruecolor(100, 100);
  179. $text_color = imagecolorallocate($oImage, mt_rand(0, 100), mt_rand(0, 100), mt_rand(0, 100));
  180. $FontSize = $this->config['fontsize_max'];
  181. for ($Angle = -30; $Angle <= 30; ++$Angle) {
  182. for ($i = 65; $i <= 90; ++$i) {
  183. $CharDetails = imageftbbox($FontSize, $Angle, $this->font, chr($i), array());
  184. $_MaxCharWidth = abs($CharDetails[0] + $CharDetails[2]);
  185. if ($_MaxCharWidth > $MaxCharWidth) {
  186. $MaxCharWidth = $_MaxCharWidth;
  187. }
  188. $_MaxCharHeight = abs($CharDetails[1] + $CharDetails[5]);
  189. if ($_MaxCharHeight > $MaxCharHeight) {
  190. $MaxCharHeight = $_MaxCharHeight;
  191. }
  192. }
  193. }
  194. imagedestroy($oImage);
  195. $this->height = $MaxCharHeight + 2;
  196. $this->spacing = (int)(($this->config['num_chars'] * $MaxCharWidth) / $this->config['num_chars']);
  197. $this->width = ($this->config['num_chars'] * $MaxCharWidth) + ($this->spacing / 2);
  198. }
  199. /**
  200. * Return random background
  201. *
  202. * @return array
  203. */
  204. public function loadBackground()
  205. {
  206. $RandBackground = null;
  207. if ($backgrounds = $this->getList('backgrounds', '(gif|jpg|png)')) {
  208. $RandBackground = XOOPS_ROOT_PATH . '/class/captcha/image/backgrounds/' . $backgrounds[array_rand($backgrounds)];
  209. }
  210. return $RandBackground;
  211. }
  212. /**
  213. * Draw Image background
  214. */
  215. public function createFromFile()
  216. {
  217. if ($RandImage = $this->loadBackground()) {
  218. $ImageType = @getimagesize($RandImage);
  219. switch (@$ImageType[2]) {
  220. case 1:
  221. $BackgroundImage = imagecreatefromgif($RandImage);
  222. break;
  223. case 2:
  224. $BackgroundImage = imagecreatefromjpeg($RandImage);
  225. break;
  226. case 3:
  227. $BackgroundImage = imagecreatefrompng($RandImage);
  228. break;
  229. }
  230. }
  231. if (!empty($BackgroundImage)) {
  232. imagecopyresized($this->oImage, $BackgroundImage, 0, 0, 0, 0, imagesx($this->oImage), imagesy($this->oImage), imagesx($BackgroundImage), imagesy($BackgroundImage));
  233. imagedestroy($BackgroundImage);
  234. } else {
  235. $this->drawBars();
  236. }
  237. }
  238. /**
  239. * Draw Code
  240. */
  241. public function drawCode()
  242. {
  243. for ($i = 0; $i < $this->config['num_chars']; ++$i) {
  244. // select random greyscale colour
  245. $text_color = imagecolorallocate($this->oImage, mt_rand(0, 100), mt_rand(0, 100), mt_rand(0, 100));
  246. // write text to image
  247. $Angle = mt_rand(10, 30);
  248. if ($i % 2) {
  249. $Angle = mt_rand(-10, -30);
  250. }
  251. // select random font size
  252. $FontSize = mt_rand($this->config['fontsize_min'], $this->config['fontsize_max']);
  253. $CharDetails = imageftbbox($FontSize, $Angle, $this->font, $this->code[$i], array());
  254. $CharHeight = abs($CharDetails[1] + $CharDetails[5]);
  255. // calculate character starting coordinates
  256. $posX = ($this->spacing / 2) + ($i * $this->spacing);
  257. $posY = 2 + ($this->height / 2) + ($CharHeight / 4);
  258. imagefttext($this->oImage, $FontSize, $Angle, $posX, $posY, $text_color, $this->font, $this->code[$i], array());
  259. }
  260. }
  261. /**
  262. * Draw Border
  263. */
  264. public function drawBorder()
  265. {
  266. $rgb = mt_rand(50, 150);
  267. $border_color = imagecolorallocate($this->oImage, $rgb, $rgb, $rgb);
  268. imagerectangle($this->oImage, 0, 0, $this->width - 1, $this->height - 1, $border_color);
  269. }
  270. /**
  271. * Draw Circles background
  272. */
  273. public function drawCircles()
  274. {
  275. for ($i = 1; $i <= $this->config['background_num']; ++$i) {
  276. $randomcolor = imagecolorallocate($this->oImage, mt_rand(190, 255), mt_rand(190, 255), mt_rand(190, 255));
  277. imagefilledellipse($this->oImage, mt_rand(0, $this->width - 10), mt_rand(0, $this->height - 3), mt_rand(10, 20), mt_rand(20, 30), $randomcolor);
  278. }
  279. }
  280. /**
  281. * Draw Lines background
  282. */
  283. public function drawLines()
  284. {
  285. for ($i = 0; $i < $this->config['background_num']; ++$i) {
  286. $randomcolor = imagecolorallocate($this->oImage, mt_rand(190, 255), mt_rand(190, 255), mt_rand(190, 255));
  287. imageline($this->oImage, mt_rand(0, $this->width), mt_rand(0, $this->height), mt_rand(0, $this->width), mt_rand(0, $this->height), $randomcolor);
  288. }
  289. }
  290. /**
  291. * Draw Rectangles background
  292. */
  293. public function drawRectangles()
  294. {
  295. for ($i = 1; $i <= $this->config['background_num']; ++$i) {
  296. $randomcolor = imagecolorallocate($this->oImage, mt_rand(190, 255), mt_rand(190, 255), mt_rand(190, 255));
  297. imagefilledrectangle($this->oImage, mt_rand(0, $this->width), mt_rand(0, $this->height), mt_rand(0, $this->width), mt_rand(0, $this->height), $randomcolor);
  298. }
  299. }
  300. /**
  301. * Draw Bars background
  302. */
  303. public function drawBars()
  304. {
  305. for ($i = 0; $i <= $this->height;) {
  306. $randomcolor = imagecolorallocate($this->oImage, mt_rand(190, 255), mt_rand(190, 255), mt_rand(190, 255));
  307. imageline($this->oImage, 0, $i, $this->width, $i, $randomcolor);
  308. $i += 2.5;
  309. }
  310. for ($i = 0; $i <= $this->width;) {
  311. $randomcolor = imagecolorallocate($this->oImage, mt_rand(190, 255), mt_rand(190, 255), mt_rand(190, 255));
  312. imageline($this->oImage, $i, 0, $i, $this->height, $randomcolor);
  313. $i += 2.5;
  314. }
  315. }
  316. /**
  317. * Draw Ellipses background
  318. */
  319. public function drawEllipses()
  320. {
  321. for ($i = 1; $i <= $this->config['background_num']; ++$i) {
  322. $randomcolor = imagecolorallocate($this->oImage, mt_rand(190, 255), mt_rand(190, 255), mt_rand(190, 255));
  323. imageellipse($this->oImage, mt_rand(0, $this->width), mt_rand(0, $this->height), mt_rand(0, $this->width), mt_rand(0, $this->height), $randomcolor);
  324. }
  325. }
  326. /**
  327. * Draw polygons background
  328. */
  329. public function drawPolygons()
  330. {
  331. for ($i = 1; $i <= $this->config['background_num']; ++$i) {
  332. $randomcolor = imagecolorallocate($this->oImage, mt_rand(190, 255), mt_rand(190, 255), mt_rand(190, 255));
  333. $coords = array();
  334. for ($j = 1; $j <= $this->config['polygon_point']; ++$j) {
  335. $coords[] = mt_rand(0, $this->width);
  336. $coords[] = mt_rand(0, $this->height);
  337. }
  338. imagefilledpolygon($this->oImage, $coords, $this->config['polygon_point'], $randomcolor);
  339. }
  340. }
  341. /**#@-*/
  342. /**
  343. * Create CAPTCHA image with BMP
  344. *
  345. * TODO
  346. * @param string $file
  347. * @return string
  348. */
  349. public function createImageBmp($file = '')
  350. {
  351. $image = '';
  352. if (empty($file)) {
  353. header('Content-type: image/bmp');
  354. echo $image;
  355. } else {
  356. return $image;
  357. }
  358. return null;
  359. }
  360. }
  361. $image_handler = new XoopsCaptchaImageHandler();
  362. $image_handler->loadImage();