Passed
Branch next (0e91a1)
by compolom
04:02
created

AbstractImage::thumbnail()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 11
ccs 7
cts 7
cp 1
rs 9.9
c 0
b 0
f 0
cc 2
nc 2
nop 2
crap 2
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
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 $width;
27
28
    protected $height;
29
30
    /**
31
     * @return \Imagick|resource
32
     */
33
    abstract public function getImage();
34
35
    /**
36
     * @param string $mode
37
     * @param int $param
38
     * @return ImageInterface
39
     * @throws InvalidArgumentException
40
     */
41 2
    public function resizeBy(string $mode, int $param): ImageInterface
42
    {
43 2
        switch ($mode) {
44 2
            case 'width':
45 1
                return $this->resizeByWidth($param);
46 2
            case 'height':
47 1
                return $this->resizeByHeight($param);
48 2
            case 'percent':
49 1
                return $this->resizeByPercent($param);
50
            default:
51 1
                throw new InvalidArgumentException('Unsupported mode type by resize');
52
        }
53
    }
54
55
    /**
56
     * @param int $width
57
     * @return ImageInterface
58
     */
59 1
    public function resizeByWidth(int $width): ImageInterface
60
    {
61 1
        return $this->resize($width, $this->getHeight() * ($width / $this->getWidth()));
62
    }
63
64
    /**
65
     * @param int $width
66
     * @param int $height
67
     * @return ImageInterface
68
     */
69
    abstract protected function resize(int $width, int $height): ImageInterface;
70
71
    /**
72
     * @return int
73
     */
74 4
    public function getHeight(): int
75
    {
76 4
        return $this->height;
77
    }
78
79
    /**
80
     * @param int $height
81
     */
82 13
    protected function setHeight(int $height): void
83
    {
84 13
        $this->height = $height;
85 13
    }
86
87
    /**
88
     * @return int
89
     */
90 5
    public function getWidth(): int
91
    {
92 5
        return $this->width;
93
    }
94
95
    /**
96
     * @param int $width
97
     */
98 13
    protected function setWidth(int $width): void
99
    {
100 13
        $this->width = $width;
101 13
    }
102
103
    /**
104
     * @param int $height
105
     * @return ImageInterface
106
     */
107 1
    public function resizeByHeight(int $height): ImageInterface
108
    {
109 1
        return $this->resize($this->getWidth() * ($height / $this->getHeight()), $height);
110
    }
111
112
    /**
113
     * @param int $percent
114
     * @return ImageInterface
115
     */
116 1
    public function resizeByPercent(int $percent): ImageInterface
117
    {
118 1
        $width = $this->getWidth() * ($percent / 100);
119 1
        $height = $this->getHeight() * ($percent / 100);
120 1
        return $this->resize($width, $height);
121
    }
122
123
    /**
124
     * @param Image $watermark
125
     * @param string $position
126
     * @return ImageInterface
127
     * @throws InvalidArgumentException
128
     */
129 1
    public function watermark(Image $watermark, string $position): ImageInterface
130
    {
131 1
        if (!array_key_exists(strtoupper($position), self::POSITIONS)) {
132 1
            throw new InvalidArgumentException('Wrong position');
133
        }
134
135
        return $this->prepareWatermark(
136
            $watermark,
137
            (int)((($this->getWidth() - $watermark->getWidth()) / 2) * self::POSITIONS[strtoupper($position)]['x']) + self::POSITIONS[strtoupper($position)]['padX'],
138
            (int)((($this->getHeight() - $watermark->getHeight()) / 2) * self::POSITIONS[strtoupper($position)]['y']) + self::POSITIONS[strtoupper($position)]['padY']
139
        );
140
    }
141
142
    /**
143
     * @param Image $watermark
144
     * @param int $x
145
     * @param int $y
146
     * @return ImageInterface
147
     */
148
    abstract protected function prepareWatermark(Image $watermark, int $x, int $y): ImageInterface;
149
150
    /**
151
     * @param int $width
152
     * @param int $height
153
     * @return ImageInterface
154
     */
155 2
    public function thumbnail(int $width, int $height): ImageInterface
156
    {
157 2
        $newHeight = $height;
158 2
        $newWidth = $width;
159
160 2
        $this->getWidth() / $this->getHeight() >= $width / $height
161 1
            ? $newWidth = (int)($this->getWidth() / ($this->getHeight() / $height))
162 1
            : $newHeight = (int)($this->getHeight() / ($this->getWidth() / $width));
163
164 2
        return $this->prepareThumbnail($width, $height, $newWidth, $newHeight);
0 ignored issues
show
Unused Code introduced by
The call to AbstractImage::prepareThumbnail() has too many arguments starting with $newWidth.

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.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
165
    }
166
167
    /**
168
     * @param int $width
169
     * @param int $height
170
     * @return ImageInterface
171
     */
172
    abstract protected function prepareThumbnail(int $width, int $height): ImageInterface;
173
174
    /**
175
     * @return string chunked base64
176
     */
177 1
    public function getBase64(): string
178
    {
179 1
        return base64_encode((string)$this);
180
181
    }
182
183
    /**
184
     * @return string
185
     */
186
    abstract public function __toString(): string;
187
188
    /**
189
     * @param $image
190
     */
191
    abstract protected function setImage($image): void;
192
193
    /**
194
     * System method
195
     *
196
     * @param void
197
     */
198
    abstract protected function setSizes(): void;
199
200
    /**
201
     * @param string $image
202
     * @throws Exception
203
     */
204 14
    protected function init(string $image): void
205
    {
206
        switch ($image) {
207
            // base64
208 14
            case base64_encode(base64_decode($image, true)) === $image:
209 4
                $this->getImageByBase64($image);
210 3
                break;
211
            // URL
212 12
            case (0 === strpos($image, 'http')):
213 3
                $this->getImageByURL($image);
214 2
                break;
215
            // Local file
216
            default:
217 11
                $this->tmp(file_get_contents($image));
218
        }
219 12
    }
220
221
    /**
222
     * @param string $base64
223
     * @return void
224
     * @throws Exception
225
     */
226 4
    protected function getImageByBase64(string $base64): void
227
    {
228 4
        $this->tmp(base64_decode($base64));
229 3
    }
230
231
    /**
232
     * @param string $source
233
     * @return ImageInterface
234
     */
235
    abstract protected function tmp(string $source): ImageInterface;
236
237
    /**
238
     * @param string $url
239
     * @return InvalidArgumentException|null
240
     * @throws Exception
241
     * @throws InvalidArgumentException
242
     * @throws LogicException
243
     * @throws RuntimeException
244
     */
245 3
    protected function getImageByURL(string $url): ?InvalidArgumentException
246
    {
247 3
        if (@!getimagesize($url)) {
248 1
            throw new InvalidArgumentException('Unsupported image type');
249
        }
250 2
        $upload = new SplFileObject($url, 'rb');
251 2
        $image = '';
252 2
        while (!$upload->eof()) {
253 2
            $image .= $upload->fgets();
254
        }
255 2
        $this->tmp($image);
256
257 2
        return null;
258
    }
259
}
260