PageRenderTime 58ms CodeModel.GetById 19ms app.highlight 33ms RepoModel.GetById 1ms app.codeStats 0ms

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