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
![]() |
|||||
173 | (int) ((($this->getHeight() - $watermark->getHeight()) / 2) * self::POSITIONS[strtoupper($position)]['y']) + self::POSITIONS[strtoupper($position)]['padY'] |
||||
0 ignored issues
–
show
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
![]() |
|||||
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
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
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. ![]() |
|||||
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 |