Passed
Push — master ( e89a22...38e786 )
by Petr
08:13
created

ColourfulText   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 105
Duplicated Lines 0 %

Test Coverage

Coverage 19.51%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 37
dl 0
loc 105
ccs 8
cts 41
cp 0.1951
rs 10
c 1
b 0
f 0
wmc 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A checkFillCaptcha() 0 4 2
A set() 0 10 1
B getImage() 0 76 6
A addRule() 0 2 1
1
<?php
2
3
namespace kalanis\kw_forms\Controls\Security\Captcha;
4
5
6
use ArrayAccess;
7
use kalanis\kw_forms\Exceptions\RenderException;
8
use kalanis\kw_rules\Interfaces\IRules;
9
10
11
/**
12
 * Class ColourfulText
13
 * @package kalanis\kw_forms\Controls\Security\Captcha
14
 * "Colourful" fill variant of captcha
15
 */
16
class ColourfulText extends AGraphical
17
{
18 2
    public function set(string $alias, ArrayAccess &$session, string $errorMessage, string $font = '/usr/share/fonts/truetype/freefont/freesans.ttf'): AGraphical
19
    {
20 2
        $this->font = $font;
21 2
        $text = $this->generateRandomString(6);
22
23 2
        $this->setEntry($alias, null, $text);
24 2
        $this->fillSession($alias, $session, $text);
25 2
        $this->setAttribute('id', $this->getKey());
26 2
        parent::addRule(IRules::SATISFIES_CALLBACK, $errorMessage, [$this, 'checkFillCaptcha']);
27 2
        return $this;
28
    }
29
30
    public function addRule(/** @scrutinizer ignore-unused */ string $ruleName, /** @scrutinizer ignore-unused */ string $errorText, /** @scrutinizer ignore-unused */ ...$args): void
31
    {
32
        // no additional rules applicable
33
    }
34
35
    /**
36
     * @param mixed $value
37
     * @return bool
38
     */
39
    public function checkFillCaptcha($value): bool
40
    {
41
        $formName = $this->getKey() . '_last';
42
        return $this->session->offsetExists($formName) && (strval($this->session->offsetGet($formName)) == strval($value));
43
    }
44
45
    protected function getImage(string $text): string
46
    {
47
        $width = 200;
48
        $height = 100;
49
        $image = @imagecreate($width, $height);
50
        if (false === $image) {
51
            // @codeCoverageIgnoreStart
52
            // problems with gd library
53
            throw new RenderException($this->renderError);
54
        }
55
        // @codeCoverageIgnoreEnd
56
57
        # Set the background and the text color of the CAPTCHA image using the imagecolorallocate PHP function:
58
        # set the captcha image  -  text will be white rendered on black
59
        # we don't random here to be sure that the text is visible
60
//        $bg_color = intval(imagecolorallocate($image, 255, 255, 255));
61
        $captcha_color = intval(imagecolorallocate($image, 150, 0, 150));
62
        # The resulting CAPTCHA image will include some generated lines, dots, and rectangles.
63
        # But before that, you generate random colors for it, using the imagecolorallocate function:
64
        # backstage colors  -  lines, dots and rectangles
65
        $line_color = intval(imagecolorallocate($image, mt_rand(0, 255), 0, 255));
66
        $dots_color = intval(imagecolorallocate($image, mt_rand(0, 255), 255, mt_rand(0, 255)));
67
        $rect_color = intval(imagecolorallocate($image, 0, mt_rand(50, 127), 50));
68
        # Add some "security" marks. For this, you will draw with random colors some dots, rectangles,
69
        # and lines in the background of the CAPTCHA to make sure that a robot application can not identify
70
        # and extract the CAPTCHA text (in addition, the text is rendered with different sizes and fonts,
71
        # and at different coordinates). To generate random dots for the background of the CAPTCHA image,
72
        # you use the imagefilledellipse PHP function with random x and y coordinates for the center, width,
73
        # and height. The x coordinate of the center will be a number between 0 and the width of the ellipse;
74
        # the y coordinate of the center is a number between 0 and the height of the ellipse. The width and
75
        # height of the ellipse are random numbers between 0 and 3, for obtaining ellipses with dot aspect.
76
        # generate random dots
77
        for ($i = 0; $i < ($width * $height); $i++) {
78
            imagefilledellipse($image, mt_rand(0, $width), mt_rand(0, $height), mt_rand(0,3), mt_rand(0,3), $dots_color);
79
        }
80
        # To generate random lines using the imageline PHP function, randomly generate the lengths and the
81
        # coordinates of the lines as in the below code:
82
        # generate random lines
83
        for ($i=0; $i < ($width + $height) / 3; $i++) {
84
            imageline($image, mt_rand(0, $width), mt_rand(0, $height), mt_rand(0, $width), mt_rand(0, $height), $line_color);
85
        }
86
        # To generate random rectangles using the imagerectangle PHP function, randomly generate the sizes
87
        # of the rectangles as in the below code:
88
        # generate random rectangles
89
        for ($i=0; $i < ($width + $height) / 3; $i++) {
90
            imagerectangle($image, mt_rand(0, $width), mt_rand(0, $height), mt_rand(0, $width), mt_rand(0, $height), $rect_color);
91
        }
92
        # Create a bounding box of text using TrueType fonts. To do that, you can use the imagettfbbox PHP function:
93
        # create bounding box in pixels for a TrueType text
94
        $tb = imagettfbbox($height * 0.40, 0, $this->font, $text);
95
        if (false === $tb) {
96
            // @codeCoverageIgnoreStart
97
            throw new RenderException($this->renderError);
98
        }
99
        // @codeCoverageIgnoreEnd
100
101
        # The most important step is writing the generated text on top of the generated image using the TrueType
102
        # font. For this, you need the imagettftext PHP function.
103
        $urcX = ($width - $tb[4])/2; # tb[4] = upper right corner, X position
104
        $urcY = ($height - $tb[5])/2; # tb[5] = upper right corner, Y position
105
        # write the given text into the image using TrueType font
106
        imagettftext($image, mt_rand(intval($height * 0.30), intval($height * 0.40)), 0, $urcX, $urcY, $captcha_color, $this->font, $text);
107
        # For a nice design, you can go further and apply image filters. For example, you can apply
108
        # IMG_FILTER_NEGATE and IMG_FILTER_SMOOTH PHP predefined image filters using the imagefilter PHP function:
109
        #apply two image filters
110
        //  imagefilter($image,IMG_FILTER_NEGATE);
111
        //  imagefilter($image,IMG_FILTER_SMOOTH,1);
112
        # Output the CAPTCHA image into variable:
113
114
        ob_start();
115
        imagepng($image);
116
        $img = strval(ob_get_contents());
117
        ob_end_clean();
118
        imagedestroy($image);
119
120
        return $img;
121
    }
122
}
123