Completed
Push — master ( 381acc...51a483 )
by Evgenii
01:28
created

Imagenator::setRowHeight()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 6
rs 10
cc 3
nc 2
nop 1
1
<?php
2
3
namespace floor12\imagenator;
4
5
use floor12\imagenator\exception\FontNotFoundException;
6
use floor12\imagenator\exception\ImageNotFoundException;
7
use floor12\imagenator\exception\InvalidFontSizeException as InvalidFontSizeExceptionAlias;
8
use floor12\imagenator\exception\InvalidHexColorException;
9
use floor12\imagenator\exception\InvalidPositionValueException;
10
use floor12\imagenator\exception\InvalidRowHeightException;
11
use floor12\imagenator\exception\InvalidWordPerPageException;
12
13
class Imagenator
14
{
15
    const DEFAULT_IMAGE = __DIR__ . '/../assets/default.png';
16
    /**
17
     * @var string Path to TTF font file
18
     */
19
    protected $font = __DIR__ . '/../assets/Rubik.ttf';
20
    /**
21
     * @var string
22
     */
23
    protected $text = "Dont forget to put some text here :-)";
24
    /**
25
     * @var false|resource
26
     */
27
    protected $image;
28
    /**
29
     * @var int
30
     */
31
    protected $imageWidth;
32
    /**
33
     * @var int
34
     */
35
    protected $imageHeight;
36
    /**
37
     * @var int
38
     */
39
    protected $wordsPerRow = 7;
40
    /**
41
     * @var int
42
     */
43
    protected $rowHeight = 8;
44
    /**
45
     * @var int
46
     */
47
    protected $textPositionPercentY = 50;
48
    /**
49
     * @var int
50
     */
51
    protected $textPositionPercentX = 5;
52
    /**
53
     * @var int Default color is white
54
     */
55
    private $textColor = '16777215';
56
    /**
57
     * @var int
58
     */
59
    private $fontSizeInPercents = 5;
60
61
    /**
62
     * Imagenator constructor.
63
     * @param string $backgroundImagePath
64
     * @throws ImageNotFoundException
65
     */
66
    public function __construct(string $backgroundImagePath = self::DEFAULT_IMAGE)
67
    {
68
        $this->loadImage($backgroundImagePath);
69
    }
70
71
    /**
72
     * @param string $backgroundImagePath
73
     * @throws ImageNotFoundException
74
     */
75
    protected function loadImage(string $backgroundImagePath)
76
    {
77
        if (!file_exists($backgroundImagePath))
78
            throw new ImageNotFoundException();
79
        $this->image = imagecreatefrompng($backgroundImagePath);
80
        list($this->imageWidth, $this->imageHeight) = getimagesize($backgroundImagePath);
81
    }
82
83
    /**
84
     * @param string $resultImagePath
85
     * @return bool
86
     * @throws FontNotFoundException
87
     */
88
    public function generate(string $resultImagePath): bool
89
    {
90
        $this->putTextToImage();
91
        return $this->saveImage($resultImagePath);
92
    }
93
94
    /**
95
     * @param string $pathToSave
96
     * @return bool
97
     */
98
    protected function saveImage(string $pathToSave): bool
99
    {
100
        return imagepng($this->image, $pathToSave) && imagedestroy($this->image);
0 ignored issues
show
Bug introduced by
It seems like $this->image can also be of type boolean; however, parameter $image of imagepng() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

100
        return imagepng(/** @scrutinizer ignore-type */ $this->image, $pathToSave) && imagedestroy($this->image);
Loading history...
Bug introduced by
It seems like $this->image can also be of type boolean; however, parameter $image of imagedestroy() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

100
        return imagepng($this->image, $pathToSave) && imagedestroy(/** @scrutinizer ignore-type */ $this->image);
Loading history...
101
    }
102
103
    /**
104
     * @throws FontNotFoundException
105
     */
106
    protected function putTextToImage(): void
107
    {
108
        if (!file_exists($this->font))
109
            throw new FontNotFoundException();
110
111
        $wordsArray = explode(' ', $this->text);
112
        $strings = array_chunk($wordsArray, $this->wordsPerRow);
113
        $positionStartY = $this->imageHeight / 100 * $this->textPositionPercentY;
114
        $rowHeightInPx = $this->imageHeight / 100 * $this->rowHeight;
115
        $fontSizeInPx = $this->imageHeight / 100 * $this->fontSizeInPercents;
116
        $positionX = $this->imageWidth / 100 * $this->textPositionPercentX;
117
        foreach ($strings as $stringNumber => $wordsArray) {
118
            $string = implode(' ', $wordsArray);
119
            $positionY = $positionStartY + $stringNumber * $rowHeightInPx;
120
            imagettftext($this->image, $fontSizeInPx, 0, $positionX, $positionY, $this->textColor, $this->font, $string);
0 ignored issues
show
Bug introduced by
It seems like $this->image can also be of type boolean; however, parameter $image of imagettftext() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

120
            imagettftext(/** @scrutinizer ignore-type */ $this->image, $fontSizeInPx, 0, $positionX, $positionY, $this->textColor, $this->font, $string);
Loading history...
121
        }
122
123
    }
124
125
    /**
126
     * @param string $text
127
     * @return self
128
     */
129
    public function setText(string $text): self
130
    {
131
        $this->text = $text;
132
        return $this;
133
    }
134
135
    /**
136
     * @param string $font
137
     * @return self
138
     */
139
    public function setFont(string $font): self
140
    {
141
        $this->font = $font;
142
        return $this;
143
    }
144
145
    /**
146
     * @param string $colorInHex
147
     * @return self
148
     * @throws InvalidHexColorException
149
     */
150
    public function setColor(string $colorInHex): self
151
    {
152
        $colorInHex = str_replace('#', '', $colorInHex);
153
154
        if (!ctype_xdigit($colorInHex) || strlen($colorInHex) !== 6)
155
            throw new InvalidHexColorException();
156
157
        $red = hexdec(substr($colorInHex, 0, 2));
158
        $green = hexdec(substr($colorInHex, 2, 2));
159
        $blue = hexdec(substr($colorInHex, 4, 2));
160
        $this->textColor = imagecolorallocate($this->image, $red, $green, $blue);
0 ignored issues
show
Bug introduced by
It seems like $this->image can also be of type boolean; however, parameter $image of imagecolorallocate() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

160
        $this->textColor = imagecolorallocate(/** @scrutinizer ignore-type */ $this->image, $red, $green, $blue);
Loading history...
Bug introduced by
It seems like $red can also be of type double; however, parameter $red of imagecolorallocate() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

160
        $this->textColor = imagecolorallocate($this->image, /** @scrutinizer ignore-type */ $red, $green, $blue);
Loading history...
Bug introduced by
It seems like $blue can also be of type double; however, parameter $blue of imagecolorallocate() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

160
        $this->textColor = imagecolorallocate($this->image, $red, $green, /** @scrutinizer ignore-type */ $blue);
Loading history...
Bug introduced by
It seems like $green can also be of type double; however, parameter $green of imagecolorallocate() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

160
        $this->textColor = imagecolorallocate($this->image, $red, /** @scrutinizer ignore-type */ $green, $blue);
Loading history...
161
        return $this;
162
    }
163
164
    /**
165
     * @param int $size
166
     * @return Imagenator
167
     * @throws InvalidFontSizeExceptionAlias
168
     */
169
    public function setFontSize(int $size)
170
    {
171
        if ($size < 1 || $size > 20)
172
            throw new InvalidFontSizeExceptionAlias();
173
        $this->fontSizeInPercents = $size;
174
        return $this;
175
    }
176
177
    /**
178
     * @param int $wordsPerRow
179
     * @return Imagenator
180
     * @throws InvalidWordPerPageException
181
     */
182
    public function setWordsPerRow(int $wordsPerRow)
183
    {
184
        if ($wordsPerRow < 1 || $wordsPerRow > 30)
185
            throw new InvalidWordPerPageException();
186
        $this->wordsPerRow = $wordsPerRow;
187
        return $this;
188
    }
189
190
    /**
191
     * @param int $percent
192
     * @return Imagenator
193
     * @throws InvalidPositionValueException
194
     */
195
    public function setPositionX(int $percent)
196
    {
197
        if ($percent < 1 || $percent > 100)
198
            throw new InvalidPositionValueException();
199
        $this->textPositionPercentX = $percent;
200
        return $this;
201
    }
202
203
    /**
204
     * @param int $percent
205
     * @return Imagenator
206
     * @throws InvalidPositionValueException
207
     */
208
    public function setPositionY(int $percent)
209
    {
210
        if ($percent < 1 || $percent > 100)
211
            throw new InvalidPositionValueException();
212
        $this->textPositionPercentY = $percent;
213
        return $this;
214
    }
215
216
    /**
217
     * @param int $percent
218
     * @return Imagenator
219
     * @throws InvalidRowHeightException
220
     */
221
    public function setRowHeight(int $percent)
222
    {
223
        if ($percent < 1 || $percent > 30)
224
            throw new InvalidRowHeightException();
225
        $this->rowHeight = $percent;
226
        return $this;
227
    }
228
}
229