Completed
Pull Request — master (#118)
by
unknown
01:20
created

Captcha::generate()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 27
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 18
nc 5
nop 0
dl 0
loc 27
rs 8.5806
c 0
b 0
f 0
1
<?php
2
3
namespace Mews\Captcha;
4
5
/**
6
 * Laravel 5 Captcha package
7
 *
8
 * @copyright Copyright (c) 2015 MeWebStudio
9
 * @version 2.x
10
 * @author Muharrem ERİN
11
 * @contact [email protected]
12
 * @web http://www.mewebstudio.com
13
 * @date 2015-04-03
14
 * @license http://www.opensource.org/licenses/mit-license.php The MIT License
15
 */
16
17
use Exception;
18
use Illuminate\Config\Repository;
19
use Illuminate\Hashing\BcryptHasher as Hasher;
20
use Illuminate\Filesystem\Filesystem;
21
use Illuminate\Support\Str;
22
use Intervention\Image\ImageManager;
23
use Illuminate\Session\Store as Session;
24
25
/**
26
 * Class Captcha
27
 * @package Mews\Captcha
28
 */
29
class Captcha
30
{
31
32
    /**
33
     * @var Filesystem
34
     */
35
    protected $files;
36
37
    /**
38
     * @var Repository
39
     */
40
    protected $config;
41
42
    /**
43
     * @var ImageManager
44
     */
45
    protected $imageManager;
46
47
    /**
48
     * @var Session
49
     */
50
    protected $session;
51
52
    /**
53
     * @var Hasher
54
     */
55
    protected $hasher;
56
57
    /**
58
     * @var Str
59
     */
60
    protected $str;
61
62
    /**
63
     * @var ImageManager->canvas
64
     */
65
    protected $canvas;
66
67
    /**
68
     * @var ImageManager->image
69
     */
70
    protected $image;
71
72
    /**
73
     * @var array
74
     */
75
    protected $backgrounds = [];
76
77
    /**
78
     * @var array
79
     */
80
    protected $fonts = [];
81
82
    /**
83
     * @var array
84
     */
85
    protected $fontColors = [];
86
87
    /**
88
     * @var int
89
     */
90
    protected $length = 5;
91
92
    /**
93
     * @var int
94
     */
95
    protected $width = 120;
96
97
    /**
98
     * @var int
99
     */
100
    protected $height = 36;
101
102
    /**
103
     * @var int
104
     */
105
    protected $angle = 15;
106
107
    /**
108
     * @var int
109
     */
110
    protected $lines = 3;
111
112
    /**
113
     * @var string
114
     */
115
    protected $characters;
116
117
    /**
118
     * @var string
119
     */
120
    protected $text;
121
122
    /**
123
     * @var int
124
     */
125
    protected $contrast = 0;
126
127
    /**
128
     * @var int
129
     */
130
    protected $quality = 90;
131
132
    /**
133
     * @var int
134
     */
135
    protected $sharpen = 0;
136
137
    /**
138
     * @var int
139
     */
140
    protected $blur = 0;
141
142
    /**
143
     * @var bool
144
     */
145
    protected $bgImage = true;
146
147
    /**
148
     * @var string
149
     */
150
    protected $bgColor = '#ffffff';
151
152
    /**
153
     * @var bool
154
     */
155
    protected $invert = false;
156
157
    /**
158
     * @var bool
159
     */
160
    protected $sensitive = false;
161
162
    /**
163
     * @var bool
164
     */
165
    protected $math = false;
166
167
    /**
168
     * Constructor
169
     *
170
     * @param Filesystem $files
171
     * @param Repository $config
172
     * @param ImageManager $imageManager
173
     * @param Session $session
174
     * @param Hasher $hasher
175
     * @param Str $str
176
     * @throws Exception
177
     * @internal param Validator $validator
178
     */
179
    public function __construct(
180
        Filesystem $files,
181
        Repository $config,
182
        ImageManager $imageManager,
183
        Session $session,
184
        Hasher $hasher,
185
        Str $str
186
    )
187
    {
188
        $this->files = $files;
189
        $this->config = $config;
190
        $this->imageManager = $imageManager;
191
        $this->session = $session;
192
        $this->hasher = $hasher;
193
        $this->str = $str;
194
        $this->characters = config('captcha.characters','2346789abcdefghjmnpqrtuxyzABCDEFGHJMNPQRTUXYZ');
195
    }
196
197
    /**
198
     * @param string $config
199
     * @return void
200
     */
201
    protected function configure($config)
202
    {
203
        if ($this->config->has('captcha.' . $config))
204
        {
205
            foreach($this->config->get('captcha.' . $config) as $key => $val)
206
            {
207
                $this->{$key} = $val;
208
            }
209
        }
210
    }
211
212
    /**
213
     * Create captcha image
214
     *
215
     * @param string $config
216
     * @return ImageManager->response
0 ignored issues
show
Documentation introduced by
The doc-type ImageManager->response could not be parsed: Unknown type name "ImageManager-" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
217
     */
218
    public function create($config = 'default')
219
    {
220
        $this->backgrounds = $this->files->files(__DIR__ . '/../assets/backgrounds');
221
        $this->fonts = $this->files->files(__DIR__ . '/../assets/fonts');
222
        
223
        if (app()->version() >= 5.5){
224
            $this->fonts = array_map(function($file) {
225
                return $file->getPathName();
226
            }, $this->fonts);
227
        }
228
        
229
        $this->fonts = array_values($this->fonts); //reset fonts array index
230
231
        $this->configure($config);
232
233
        $this->text = $this->generate();
234
235
        $this->canvas = $this->imageManager->canvas(
236
            $this->width,
237
            $this->height,
238
            $this->bgColor
239
        );
240
241
        if ($this->bgImage)
242
        {
243
            $this->image = $this->imageManager->make($this->background())->resize(
244
                $this->width,
245
                $this->height
246
            );
247
            $this->canvas->insert($this->image);
248
        }
249
        else
250
        {
251
            $this->image = $this->canvas;
252
        }
253
254
        if ($this->contrast != 0)
255
        {
256
            $this->image->contrast($this->contrast);
257
        }
258
259
        $this->text();
260
261
        $this->lines();
262
263
        if ($this->sharpen)
264
        {
265
            $this->image->sharpen($this->sharpen);
266
        }
267
        if ($this->invert)
268
        {
269
            $this->image->invert($this->invert);
270
        }
271
        if ($this->blur)
272
        {
273
            $this->image->blur($this->blur);
274
        }
275
276
        return $this->image->response('png', $this->quality);
277
    }
278
279
    /**
280
     * Image backgrounds
281
     *
282
     * @return string
283
     */
284
    protected function background()
285
    {
286
        return $this->backgrounds[rand(0, count($this->backgrounds) - 1)];
287
    }
288
289
    /**
290
     * Generate captcha text
291
     *
292
     * @return string
293
     */
294
    protected function generate()
295
    {
296
        $characters = str_split($this->characters);
297
298
        $bag = '';
299
        $key = '';
0 ignored issues
show
Unused Code introduced by
$key is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
300
301
        if ($this->math) {
302
            $x = random_int(10, 30);
303
            $y = random_int(1, 9);
304
            $bag = "$x + $y = ";
305
            $key = $x + $y;
306
            $key .= '';
307
        } else {
308
            for ($i = 0; $i < $this->length; $i++) {
309
                $bag .= $characters[rand(0, count($characters) - 1)];
310
            }
311
            $key = $this->sensitive ? $bag : $this->str->lower($bag);
312
        }
313
314
        $this->session->put('captcha', [
315
            'sensitive' => $this->sensitive,
316
            'key'       => $this->hasher->make($key)
317
        ]);
318
319
        return $bag;
320
    }
321
322
    /**
323
     * Writing captcha text
324
     */
325
    protected function text()
326
    {
327
        $marginTop = $this->image->height() / $this->length;
328
329
        $i = 0;
330
        foreach(str_split($this->text) as $char)
331
        {
332
            $marginLeft = ($i * $this->image->width() / $this->length);
333
334
            $this->image->text($char, $marginLeft, $marginTop, function($font) {
335
                $font->file($this->font());
336
                $font->size($this->fontSize());
337
                $font->color($this->fontColor());
338
                $font->align('left');
339
                $font->valign('top');
340
                $font->angle($this->angle());
341
            });
342
343
            $i++;
344
        }
345
    }
346
347
    /**
348
     * Image fonts
349
     *
350
     * @return string
351
     */
352
    protected function font()
353
    {
354
        return $this->fonts[rand(0, count($this->fonts) - 1)];
355
    }
356
357
    /**
358
     * Random font size
359
     *
360
     * @return integer
361
     */
362
    protected function fontSize()
363
    {
364
        return rand($this->image->height() - 10, $this->image->height());
365
    }
366
367
    /**
368
     * Random font color
369
     *
370
     * @return array
371
     */
372
    protected function fontColor()
373
    {
374
        if ( ! empty($this->fontColors))
375
        {
376
            $color = $this->fontColors[rand(0, count($this->fontColors) - 1)];
377
        }
378
        else
379
        {
380
            $color = [rand(0, 255), rand(0, 255), rand(0, 255)];
381
        }
382
383
        return $color;
384
    }
385
386
    /**
387
     * Angle
388
     *
389
     * @return int
390
     */
391
    protected function angle()
392
    {
393
        return rand((-1 * $this->angle), $this->angle);
394
    }
395
396
    /**
397
     * Random image lines
398
     *
399
     * @return \Intervention\Image\Image
400
     */
401
    protected function lines()
402
    {
403
        for($i = 0; $i <= $this->lines; $i++)
404
        {
405
            $this->image->line(
406
                rand(0, $this->image->width()) + $i * rand(0, $this->image->height()),
407
                rand(0, $this->image->height()),
408
                rand(0, $this->image->width()),
409
                rand(0, $this->image->height()),
410
                function ($draw) {
411
                    $draw->color($this->fontColor());
412
                }
413
            );
414
        }
415
        return $this->image;
416
    }
417
418
    /**
419
     * Captcha check
420
     *
421
     * @param $value
422
     * @return bool
423
     */
424
    public function check($value)
425
    {
426
        if ( ! $this->session->has('captcha'))
427
        {
428
            return false;
429
        }
430
431
        $key = $this->session->get('captcha.key');
432
433
        if ( ! $this->session->get('captcha.sensitive'))
434
        {
435
            $value = $this->str->lower($value);
436
        }
437
438
        $this->session->remove('captcha');
439
440
        return $this->hasher->check($value, $key);
441
    }
442
443
    /**
444
     * Generate captcha image source
445
     *
446
     * @param null $config
447
     * @return string
448
     */
449
    public function src($config = null)
450
    {
451
        return url('captcha' . ($config ? '/' . $config : '/default')) . '?' . $this->str->random(8);
452
    }
453
454
    /**
455
     * Generate captcha image html tag
456
     *
457
     * @param null $config
458
     * @return string
459
     */
460
    public function img($config = null)
461
    {
462
        return '<img src="' . $this->src($config) . '" alt="captcha">';
463
    }
464
465
}
466