Completed
Pull Request — master (#132)
by
unknown
02:04
created

Captcha::fontSize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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