These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace IrishDan\ResponsiveImageBundle; |
||
4 | |||
5 | use Intervention\Image\ImageManager; |
||
6 | |||
7 | /** |
||
8 | * Class ImageMaker |
||
9 | * |
||
10 | * @package ResponsiveImageBundle |
||
11 | */ |
||
12 | class ImageMaker |
||
13 | { |
||
14 | use CoordinateLengthCalculator; |
||
15 | |||
16 | /** |
||
17 | * @var |
||
18 | */ |
||
19 | private $compression; |
||
20 | /** |
||
21 | * @var |
||
22 | */ |
||
23 | private $cropCoordinates = []; |
||
24 | /** |
||
25 | * @var |
||
26 | */ |
||
27 | private $driver; |
||
28 | /** |
||
29 | * @var FileManager |
||
30 | */ |
||
31 | private $fileManager; |
||
32 | /** |
||
33 | * @var |
||
34 | */ |
||
35 | private $focusCoordinates = []; |
||
36 | /** |
||
37 | * @var |
||
38 | */ |
||
39 | private $img; |
||
40 | /** |
||
41 | * @var |
||
42 | */ |
||
43 | private $manager; |
||
44 | /** |
||
45 | * @var array |
||
46 | */ |
||
47 | private $styleData = []; |
||
48 | |||
49 | /** |
||
50 | * Imager constructor. |
||
51 | * |
||
52 | * @param FileManager $system |
||
53 | * @param array $responsiveImageConfig |
||
54 | * @internal param $driver |
||
55 | * @internal param $compression |
||
56 | */ |
||
57 | public function __construct(FileManager $system, $responsiveImageConfig = []) |
||
58 | { |
||
59 | $this->fileManager = $system; |
||
60 | if (!empty($responsiveImageConfig['debug'])) { |
||
61 | $this->debug = $responsiveImageConfig['debug']; |
||
0 ignored issues
–
show
|
|||
62 | } |
||
63 | if (!empty($responsiveImageConfig['image_driver'])) { |
||
64 | $this->driver = $responsiveImageConfig['image_driver']; |
||
65 | } |
||
66 | if (!empty($responsiveImageConfig['image_compression'])) { |
||
67 | $this->compression = $responsiveImageConfig['image_compression']; |
||
68 | } |
||
69 | } |
||
70 | |||
71 | /** |
||
72 | * Separates the crop and focus coordinates from the image object and stores them. |
||
73 | * |
||
74 | * @param $cropFocusCoords |
||
75 | */ |
||
76 | public function setCoordinateGroups($cropFocusCoords) |
||
77 | { |
||
78 | // x1, y1, x2, y2:x3, y3, x4, y4 |
||
79 | $coordsSets = explode(':', $cropFocusCoords); |
||
80 | $this->cropCoordinates = explode(', ', $coordsSets[0]); |
||
81 | $this->focusCoordinates = explode(', ', $coordsSets[1]); |
||
82 | } |
||
83 | |||
84 | /** |
||
85 | * Returns the style information of a defined style. |
||
86 | * |
||
87 | * @param array $style |
||
88 | */ |
||
89 | public function setStyleData($style = []) |
||
90 | { |
||
91 | $this->styleData['effect'] = empty($style['effect']) ? null : $style['effect']; |
||
92 | $this->styleData['width'] = empty($style['width']) ? null : $style['width']; |
||
93 | $this->styleData['height'] = empty($style['height']) ? null : $style['height']; |
||
94 | $this->styleData['greyscale'] = empty($style['greyscale']) ? null : $style['greyscale']; |
||
95 | } |
||
96 | |||
97 | protected function scaleImage($width, $height) |
||
98 | { |
||
99 | $this->img->resize($width, $height, function ($constraint) { |
||
100 | $constraint->aspectRatio(); |
||
101 | }); |
||
102 | } |
||
103 | |||
104 | protected function setImage($source, $driver = 'gd') |
||
105 | { |
||
106 | if (empty($this->manager)) { |
||
107 | $this->manager = new ImageManager(['driver' => $driver]); |
||
108 | } |
||
109 | $this->img = $this->manager->make($source); |
||
110 | } |
||
111 | |||
112 | /** |
||
113 | * Performs the image manipulation using current style information |
||
114 | * and user defined crop and focus rectangles. |
||
115 | * |
||
116 | * @param $source |
||
117 | * @param $destination |
||
118 | * @param array $style |
||
119 | * @param null $cropFocusCoords |
||
120 | * @return string |
||
121 | */ |
||
122 | public function createImage($source, $destination, array $style = [], $cropFocusCoords = null) |
||
123 | { |
||
124 | $this->setImage($source, $this->driver); |
||
125 | |||
126 | if (!empty($style)) { |
||
127 | $this->setStyleData($style); |
||
128 | } |
||
129 | |||
130 | if (!empty($cropFocusCoords)) { |
||
131 | $this->setCoordinateGroups($cropFocusCoords); |
||
132 | } |
||
133 | |||
134 | if (!empty($this->styleData)) { |
||
135 | switch ($this->styleData['effect']) { |
||
136 | case 'scale': |
||
137 | // Do the crop rectangle first |
||
138 | // then scale the image |
||
139 | $this->doCropRectangle(); |
||
140 | $this->scaleImage($this->styleData['width'], $this->styleData['height']); |
||
141 | break; |
||
142 | |||
143 | case 'crop': |
||
144 | // If there's no focus rectangle, |
||
145 | // just cut out the crop rectangle. |
||
146 | if (empty($this->getCoordinates('focus'))) { |
||
147 | $this->doCropRectangle(); |
||
148 | } else { |
||
149 | |||
150 | $focusOffsetFinder = new FocusCropDataCalculator( |
||
151 | $this->getCoordinates('crop'), |
||
152 | $this->getCoordinates('focus'), |
||
153 | $this->styleData['width'], |
||
154 | $this->styleData['height'] |
||
155 | ); |
||
156 | |||
157 | $focusCropData = $focusOffsetFinder->getFocusCropData(); |
||
158 | if (!empty($focusCropData)) { |
||
159 | $this->cropImage($focusCropData['width'], $focusCropData['height'], $focusCropData['x'], $focusCropData['y']); |
||
160 | } |
||
161 | } |
||
162 | |||
163 | $this->img->fit($this->styleData['width'], $this->styleData['height'], function ($constraint) { |
||
164 | $constraint->upsize(); |
||
165 | }); |
||
166 | |||
167 | break; |
||
168 | } |
||
169 | |||
170 | // Do greyscale. |
||
171 | if (!empty($this->styleData['greyscale'])) { |
||
172 | $this->img->greyscale(); |
||
173 | } |
||
174 | } |
||
175 | |||
176 | return $this->saveImage($destination, $source); |
||
177 | } |
||
178 | |||
179 | protected function cropImage($width, $height, $xOffset, $yOffset) |
||
180 | { |
||
181 | $this->img->crop( |
||
182 | round($width), |
||
183 | round($height), |
||
184 | round($xOffset), |
||
185 | round($yOffset) |
||
186 | ); |
||
187 | } |
||
188 | |||
189 | /** |
||
190 | * Crops out defined crop area. |
||
191 | */ |
||
192 | protected function doCropRectangle() |
||
193 | { |
||
194 | // Get the offset. |
||
195 | $cropCoords = $this->getCoordinates('crop'); |
||
196 | if (!empty($cropCoords)) { |
||
197 | $x1 = $cropCoords[0]; |
||
198 | $y1 = $cropCoords[1]; |
||
199 | |||
200 | // Get the lengths. |
||
201 | // @TODO: Methods not existing |
||
202 | $newWidth = $this->getLength('x', $cropCoords); |
||
203 | $newHeight = $this->getLength('y', $cropCoords); |
||
204 | |||
205 | // Do the initial crop. |
||
206 | $this->img->crop($newWidth, $newHeight, $x1, $y1); |
||
207 | } |
||
208 | } |
||
209 | |||
210 | /** |
||
211 | * Returns either the crop or focus rectangle coordinates. |
||
212 | * |
||
213 | * @param string $type |
||
214 | * @return mixed |
||
215 | */ |
||
216 | protected function getCoordinates($type = 'crop') |
||
217 | { |
||
218 | $coords = $this->{$type . 'Coordinates'}; |
||
219 | $valid = 0; |
||
220 | foreach ($coords as $id => $coord) { |
||
221 | if ($coord > 0) { |
||
222 | $valid++; |
||
223 | } |
||
224 | $coords[$id] = round($coord); |
||
225 | } |
||
226 | |||
227 | if ($valid == 0) { |
||
228 | return false; |
||
229 | } |
||
230 | |||
231 | return $coords; |
||
232 | } |
||
233 | |||
234 | /** |
||
235 | * Saves the new image. |
||
236 | * |
||
237 | * @param $destination |
||
238 | * @param $source |
||
239 | * @return string |
||
240 | */ |
||
241 | protected function saveImage($destination, $source) |
||
242 | { |
||
243 | // Check if directory exists and if not create it. |
||
244 | $this->fileManager->directoryExists($destination, true); |
||
245 | |||
246 | // Get the file name from source path. |
||
247 | $filename = $this->fileManager->getFilenameFromPath($source); |
||
248 | $fullPath = $destination . '/' . $filename; |
||
249 | |||
250 | $this->img->save($fullPath, $this->compression); |
||
251 | |||
252 | return $fullPath; |
||
253 | } |
||
254 | |||
255 | /** |
||
256 | * Gets vertical or horizontal length between two coordinates (x, y, x2, y2). |
||
257 | * |
||
258 | * @param string $type |
||
259 | * @param array $coords |
||
260 | * @return mixed |
||
261 | */ |
||
262 | View Code Duplication | protected function getLength($type = 'x', array $coords) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
263 | { |
||
264 | $type = strtolower($type); |
||
265 | if ($type == 'x') { |
||
266 | return $coords[2] - $coords[0]; |
||
267 | } else { |
||
268 | return $coords[3] - $coords[1]; |
||
269 | } |
||
270 | } |
||
271 | } |
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: