Passed
Branch master (8a72e9)
by compolom
12:56
created

AbstractImage::resizeByPercent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 1
rs 10
1
<?php
2
3
namespace Compolomus\Compomage;
4
5
use Compolomus\Compomage\Interfaces\ImageInterface;
6
use Exception;
7
use InvalidArgumentException;
8
use LogicException;
9
use RuntimeException;
10
use SplFileObject;
11
12
abstract class AbstractImage implements ImageInterface
13
{
14
    protected const POSITIONS = [
15
        'NORTHWEST' => ['x' => 0, 'y' => 0, 'padX' => 10, 'padY' => 10],
16
        'NORTH' => ['x' => 1, 'y' => 0, 'padX' => 0, 'padY' => 10],
17
        'NORTHEAST' => ['x' => 2, 'y' => 0, 'padX' => -10, 'padY' => 10],
18
        'WEST' => ['x' => 0, 'y' => 1, 'padX' => 10, 'padY' => 0],
19
        'CENTER' => ['x' => 1, 'y' => 1, 'padX' => 0, 'padY' => 0],
20
        'EAST' => ['x' => 2, 'y' => 1, 'padX' => -10, 'padY' => 0],
21
        'SOUTHWEST' => ['x' => 0, 'y' => 2, 'padX' => 10, 'padY' => -10],
22
        'SOUTH' => ['x' => 1, 'y' => 2, 'padX' => 0, 'padY' => -10],
23
        'SOUTHEAST' => ['x' => 2, 'y' => 2, 'padX' => -10, 'padY' => -10]
24
    ];
25
26
    protected $image;
27
28
    protected $width;
29
30
    protected $height;
31
32
    protected $orientation;
33
34
    /**
35
     * @param int $value
36
     * @param int $range
37
     * @return bool
38
     */
39
    protected function compareRangeValue(int $value, int $range): bool
40
    {
41
        return in_array(abs($value), range(0, $range), true);
42
    }
43
44
    /**
45
     * @param int $width
46
     * @param int $height
47
     * @param Image $background
48
     * @return ImageInterface
49
     */
50
    protected function setBackground(int $width, int $height, Image $background): ImageInterface
51
    {
52
        $this->orientation === 'vertical'
53
            ? $this->resizeByHeight($height)
54
            : $this->resizeByWidth($width);
55
56
        $background->watermark($this, 'CENTER');
57
58
        $this->setImage($background->getImage());
59
        $this->setSizes();
60
61
        return $this;
62
    }
63
64 15
    protected function setOrientation(): void
65
    {
66 15
        $this->orientation = $this->getWidth() < $this->getHeight() ? 'vertical' : 'horizontal';
67
    }
68
69
    public function getOrientation(): string
70
    {
71
        return $this->orientation;
72
    }
73
74
    /**
75
     * @param string $mode
76
     * @param int $param
77
     * @return ImageInterface
78
     * @throws InvalidArgumentException
79
     */
80 2
    public function resizeBy(string $mode, int $param): ImageInterface
81
    {
82 2
        switch ($mode) {
83 2
            case 'width':
84 1
                return $this->resizeByWidth($param);
85 2
            case 'height':
86 1
                return $this->resizeByHeight($param);
87 2
            case 'percent':
88 1
                return $this->resizeByPercent($param);
89
            default:
90 1
                throw new InvalidArgumentException('Unsupported mode type by resize');
91
        }
92
    }
93
94
    /**
95
     * @param int $width
96
     * @return ImageInterface
97
     */
98 1
    public function resizeByWidth(int $width): ImageInterface
99
    {
100 1
        return $this->resize($width, (int) ($this->getHeight() * ($width / $this->getWidth())));
101
    }
102
103
    /**
104
     * @return int
105
     */
106 15
    public function getHeight(): int
107
    {
108 15
        return $this->height;
109
    }
110
111
    /**
112
     * @param int $height
113
     */
114 15
    protected function setHeight(int $height): void
115
    {
116 15
        $this->height = $height;
117
    }
118
119
    /**
120
     * @return int
121
     */
122 15
    public function getWidth(): int
123
    {
124 15
        return $this->width;
125
    }
126
127
    /**
128
     * @param int $width
129
     */
130 15
    protected function setWidth(int $width): void
131
    {
132 15
        $this->width = $width;
133
    }
134
135
    /**
136
     * @param int $height
137
     * @return ImageInterface
138
     */
139 1
    public function resizeByHeight(int $height): ImageInterface
140
    {
141 1
        return $this->resize((int) ($this->getWidth() * ($height / $this->getHeight())), $height);
142
    }
143
144
    /**
145
     * @param int $percent
146
     * @return ImageInterface
147
     */
148 1
    public function resizeByPercent(int $percent): ImageInterface
149
    {
150 1
        return $this->resize(
151 1
            (int) ($this->getWidth() * ($percent / 100)),
152 1
            (int) ($this->getHeight() * ($percent / 100))
153
        );
154
    }
155
156
    abstract protected function newImage(int $width, int $height);
157
158
    /**
159
     * @param ImageInterface|Image $watermark
160
     * @param string $position
161
     * @return ImageInterface
162
     * @throws InvalidArgumentException
163
     */
164 1
    public function watermark($watermark, string $position): ImageInterface
165
    {
166 1
        if (!array_key_exists(strtoupper($position), self::POSITIONS)) {
167 1
            throw new InvalidArgumentException('Wrong position');
168
        }
169
170
        return $this->prepareWatermark(
171
            $watermark,
172
            (int) ((($this->getWidth() - $watermark->getWidth()) / 2) * self::POSITIONS[strtoupper($position)]['x']) + self::POSITIONS[strtoupper($position)]['padX'],
0 ignored issues
show
Bug introduced by
The method getWidth() does not exist on Compolomus\Compomage\Interfaces\ImageInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Compolomus\Compomage\Interfaces\ImageInterface. ( Ignorable by Annotation )

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

172
            (int) ((($this->getWidth() - $watermark->/** @scrutinizer ignore-call */ getWidth()) / 2) * self::POSITIONS[strtoupper($position)]['x']) + self::POSITIONS[strtoupper($position)]['padX'],
Loading history...
173
            (int) ((($this->getHeight() - $watermark->getHeight()) / 2) * self::POSITIONS[strtoupper($position)]['y']) + self::POSITIONS[strtoupper($position)]['padY']
0 ignored issues
show
Bug introduced by
The method getHeight() does not exist on Compolomus\Compomage\Interfaces\ImageInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Compolomus\Compomage\Interfaces\ImageInterface. ( Ignorable by Annotation )

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

173
            (int) ((($this->getHeight() - $watermark->/** @scrutinizer ignore-call */ getHeight()) / 2) * self::POSITIONS[strtoupper($position)]['y']) + self::POSITIONS[strtoupper($position)]['padY']
Loading history...
174
        );
175
    }
176
177
    /**
178
     * @param ImageInterface|Image $watermark
179
     * @param int $x
180
     * @param int $y
181
     * @return ImageInterface
182
     */
183
    abstract protected function prepareWatermark($watermark, int $x, int $y): ImageInterface;
184
185
    /**
186
     * @param int $width
187
     * @param int $height
188
     * @return ImageInterface
189
     */
190 2
    public function thumbnail(int $width, int $height): ImageInterface
191
    {
192 2
        $newHeight = $height;
193 2
        $newWidth = $width;
194
195 2
        ($this->getWidth() / $this->getHeight()) >= ($width / $height)
196 1
            ? $newWidth = (int) ($this->getWidth() / ($this->getHeight() / $height))
197 1
            : $newHeight = (int) ($this->getHeight() / ($this->getWidth() / $width));
198
199 2
        return $this->prepareThumbnail($width, $height, $newWidth, $newHeight);
0 ignored issues
show
Unused Code introduced by
The call to Compolomus\Compomage\Abs...age::prepareThumbnail() has too many arguments starting with $newWidth. ( Ignorable by Annotation )

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

199
        return $this->/** @scrutinizer ignore-call */ prepareThumbnail($width, $height, $newWidth, $newHeight);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
200
    }
201
202
    /**
203
     * @param int $width
204
     * @param int $height
205
     * @return ImageInterface
206
     */
207
    abstract protected function prepareThumbnail(int $width, int $height): ImageInterface;
208
209
    /**
210
     * @return string chunked base64
211
     */
212
    public function getBase64(): string
213
    {
214
        return base64_encode((string) $this);
215
216
    }
217
218
    /**
219
     * @param $image
220
     */
221 15
    protected function setImage($image): void
222
    {
223 15
        $this->image = $image;
224
    }
225
226 15
    public function getImage()
227
    {
228 15
        return $this->image;
229
    }
230
231
    /**
232
     * System method
233
     *
234
     * @param void
235
     */
236
    abstract protected function setSizes(): void;
237
238
    /**
239
     * @param string $image
240
     * @throws Exception
241
     */
242 17
    protected function init(string $image): void
243
    {
244
        switch ($image) {
245
            // base64
246 17
            case base64_encode(base64_decode($image, true)) === $image:
247 3
                $this->getImageByBase64($image);
248 2
                break;
249
            // URL
250 16
            case (0 === strpos($image, 'http')):
251 3
                $this->getImageByURL($image);
252 2
                break;
253
            // Local file
254
            default:
255 15
                $this->tmp(file_get_contents($image));
256
        }
257
    }
258
259
    /**
260
     * @param string $base64
261
     * @return void
262
     * @throws Exception
263
     */
264 3
    protected function getImageByBase64(string $base64): void
265
    {
266 3
        $this->tmp(base64_decode($base64));
267
    }
268
269
    /**
270
     * @param string $source
271
     * @return ImageInterface
272
     */
273
    abstract protected function tmp(string $source): ImageInterface;
274
275
    /**
276
     * @param string $url
277
     * @return InvalidArgumentException|null
278
     * @throws Exception
279
     * @throws InvalidArgumentException
280
     * @throws LogicException
281
     * @throws RuntimeException
282
     */
283 3
    protected function getImageByURL(string $url): ?InvalidArgumentException
284
    {
285 3
        if (@!getimagesize($url)) {
286 1
            throw new InvalidArgumentException('Unsupported image type');
287
        }
288 2
        $upload = new SplFileObject($url, 'rb');
289 2
        $image = '';
290 2
        while (!$upload->eof()) {
291 2
            $image .= $upload->fgets();
292
        }
293 2
        $this->tmp($image);
294
295 2
        return null;
296
    }
297
}
298