Completed
Pull Request — master (#114)
by Yang
23:05
created

Captcha::create()   C

Complexity

Conditions 8
Paths 128

Size

Total Lines 60
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 0 Features 1
Metric Value
cc 8
eloc 32
nc 128
nop 2
dl 0
loc 60
rs 6.3008
c 6
b 0
f 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
     * Constructor
164
     *
165
     * @param Filesystem $files
166
     * @param Repository $config
167
     * @param ImageManager $imageManager
168
     * @param Session $session
169
     * @param Hasher $hasher
170
     * @param Str $str
171
     * @throws Exception
172
     * @internal param Validator $validator
173
     */
174
    public function __construct(
175
        Filesystem $files,
176
        Repository $config,
177
        ImageManager $imageManager,
178
        Session $session,
179
        Hasher $hasher,
180
        Str $str
181
    )
182
    {
183
        $this->files = $files;
184
        $this->config = $config;
185
        $this->imageManager = $imageManager;
186
        $this->session = $session;
187
        $this->hasher = $hasher;
188
        $this->str = $str;
189
        $this->characters = config('captcha.characters','2346789abcdefghjmnpqrtuxyzABCDEFGHJMNPQRTUXYZ');
190
    }
191
192
    /**
193
     * @param string $config
194
     * @return void
195
     */
196
    protected function configure($config)
197
    {
198
        if ($this->config->has('captcha.' . $config))
199
        {
200
            foreach($this->config->get('captcha.' . $config) as $key => $val)
201
            {
202
                $this->{$key} = $val;
203
            }
204
        }
205
    }
206
207
    /**
208
     * Create captcha image
209
     *
210
     * @param null   $text
211
     * @param string $config
212
     * @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...
213
     */
214
    public function create($text = null, $config = 'default')
215
    {
216
        $this->backgrounds = $this->files->files(__DIR__ . '/../assets/backgrounds');
217
        $this->fonts = $this->files->files(__DIR__ . '/../assets/fonts');
218
219
        if (app()->version() >= 5.5){
220
            $this->fonts = array_map(function($file) {
221
                return $file->getPathName();
222
            }, $this->fonts);
223
        }
224
225
        $this->fonts = array_values($this->fonts); //reset fonts array index
226
227
        $this->configure($config);
228
229
        $this->text = $text ?: $this->generate();
230
231
        $this->canvas = $this->imageManager->canvas(
232
            $this->width,
233
            $this->height,
234
            $this->bgColor
235
        );
236
237
        if ($this->bgImage)
238
        {
239
            $this->image = $this->imageManager->make($this->background())->resize(
240
                $this->width,
241
                $this->height
242
            );
243
            $this->canvas->insert($this->image);
244
        }
245
        else
246
        {
247
            $this->image = $this->canvas;
248
        }
249
250
        if ($this->contrast != 0)
251
        {
252
            $this->image->contrast($this->contrast);
253
        }
254
255
        $this->text();
256
257
        $this->lines();
258
259
        if ($this->sharpen)
260
        {
261
            $this->image->sharpen($this->sharpen);
262
        }
263
        if ($this->invert)
264
        {
265
            $this->image->invert($this->invert);
266
        }
267
        if ($this->blur)
268
        {
269
            $this->image->blur($this->blur);
270
        }
271
272
        return $this->image->response('png', $this->quality);
273
    }
274
275
    /**
276
     * Image backgrounds
277
     *
278
     * @return string
279
     */
280
    protected function background()
281
    {
282
        return $this->backgrounds[rand(0, count($this->backgrounds) - 1)];
283
    }
284
285
    /**
286
     * Generate captcha text
287
     *
288
     * @return string
289
     */
290
    protected function generate()
291
    {
292
        $characters = str_split($this->characters);
293
294
        $bag = '';
295
        for($i = 0; $i < $this->length; $i++)
296
        {
297
            $bag .= $characters[rand(0, count($characters) - 1)];
298
        }
299
300
        $this->session->put('captcha', [
301
            'sensitive' => $this->sensitive,
302
            'key'       => $this->hasher->make($this->sensitive ? $bag : $this->str->lower($bag))
303
        ]);
304
305
        return $bag;
306
    }
307
308
    /**
309
     * Writing captcha text
310
     */
311
    protected function text()
312
    {
313
        $marginTop = $this->image->height() / $this->length;
314
315
        $i = 0;
316
        foreach(str_split($this->text) as $char)
317
        {
318
            $marginLeft = ($i * $this->image->width() / $this->length);
319
320
            $this->image->text($char, $marginLeft, $marginTop, function($font) {
321
                $font->file($this->font());
322
                $font->size($this->fontSize());
323
                $font->color($this->fontColor());
324
                $font->align('left');
325
                $font->valign('top');
326
                $font->angle($this->angle());
327
            });
328
329
            $i++;
330
        }
331
    }
332
333
    /**
334
     * Image fonts
335
     *
336
     * @return string
337
     */
338
    protected function font()
339
    {
340
        return $this->fonts[rand(0, count($this->fonts) - 1)];
341
    }
342
343
    /**
344
     * Random font size
345
     *
346
     * @return integer
347
     */
348
    protected function fontSize()
349
    {
350
        return rand($this->image->height() - 10, $this->image->height());
351
    }
352
353
    /**
354
     * Random font color
355
     *
356
     * @return array
357
     */
358
    protected function fontColor()
359
    {
360
        if ( ! empty($this->fontColors))
361
        {
362
            $color = $this->fontColors[rand(0, count($this->fontColors) - 1)];
363
        }
364
        else
365
        {
366
            $color = [rand(0, 255), rand(0, 255), rand(0, 255)];
367
        }
368
369
        return $color;
370
    }
371
372
    /**
373
     * Angle
374
     *
375
     * @return int
376
     */
377
    protected function angle()
378
    {
379
        return rand((-1 * $this->angle), $this->angle);
380
    }
381
382
    /**
383
     * Random image lines
384
     *
385
     * @return \Intervention\Image\Image
386
     */
387
    protected function lines()
388
    {
389
        for($i = 0; $i <= $this->lines; $i++)
390
        {
391
            $this->image->line(
392
                rand(0, $this->image->width()) + $i * rand(0, $this->image->height()),
393
                rand(0, $this->image->height()),
394
                rand(0, $this->image->width()),
395
                rand(0, $this->image->height()),
396
                function ($draw) {
397
                    $draw->color($this->fontColor());
398
                }
399
            );
400
        }
401
        return $this->image;
402
    }
403
404
    /**
405
     * Captcha check
406
     *
407
     * @param $value
408
     * @return bool
409
     */
410
    public function check($value)
411
    {
412
        if ( ! $this->session->has('captcha'))
413
        {
414
            return false;
415
        }
416
417
        $key = $this->session->get('captcha.key');
418
419
        if ( ! $this->session->get('captcha.sensitive'))
420
        {
421
            $value = $this->str->lower($value);
422
        }
423
424
        $this->session->remove('captcha');
425
426
        return $this->hasher->check($value, $key);
427
    }
428
429
    /**
430
     * Generate captcha image source
431
     *
432
     * @param null $config
433
     * @return string
434
     */
435
    public function src($config = null)
436
    {
437
        return url('captcha' . ($config ? '/' . $config : '/default')) . '?' . $this->str->random(8);
438
    }
439
440
    /**
441
     * Generate captcha image html tag
442
     *
443
     * @param null $config
444
     * @return string
445
     */
446
    public function img($config = null)
447
    {
448
        return '<img src="' . $this->src($config) . '" alt="captcha">';
449
    }
450
451
}
452