Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like Image often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Image, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
26 | class Image |
||
27 | { |
||
28 | protected static $supportedExtensions = array('jpg', 'jpeg', 'gif', 'png'); |
||
29 | |||
30 | /** |
||
31 | * Image width. |
||
32 | * |
||
33 | * @var int $witdh |
||
34 | */ |
||
35 | protected $width; |
||
36 | |||
37 | /** |
||
38 | * Image height. |
||
39 | * |
||
40 | * @var int $height |
||
41 | */ |
||
42 | protected $height; |
||
43 | |||
44 | /** |
||
45 | * Image MIME type. |
||
46 | * |
||
47 | * @var string $mime |
||
48 | */ |
||
49 | protected $mime; |
||
50 | |||
51 | /** |
||
52 | * Number of bits for each color. |
||
53 | * |
||
54 | * @var string $mime |
||
55 | */ |
||
56 | protected $bits; |
||
57 | |||
58 | /** |
||
59 | * Number of color channels (i.e. 3 for RGB pictures and 4 for CMYK pictures). |
||
60 | * |
||
61 | * @var int $channels |
||
62 | */ |
||
63 | protected $channels; |
||
64 | |||
65 | /** |
||
66 | * GD image. |
||
67 | * |
||
68 | * @var resource $gdImage |
||
69 | */ |
||
70 | protected $gdImage; |
||
71 | |||
72 | /** |
||
73 | * The size of the image produced by the `getData()` method. |
||
74 | * |
||
75 | * @var int $dataSize |
||
76 | */ |
||
77 | protected $dataSize; |
||
78 | |||
79 | /** |
||
80 | * Quality of rescaled image. |
||
81 | * |
||
82 | * @var int |
||
83 | */ |
||
84 | protected $resizeQuality; |
||
85 | |||
86 | /** |
||
87 | * The factory method. |
||
88 | * |
||
89 | * @param string $data |
||
90 | * @param bool $bmpSupport |
||
91 | * |
||
92 | * @return Image |
||
93 | */ |
||
94 | public static function create($data, $bmpSupport = false) |
||
98 | |||
99 | /** |
||
100 | * Parses the image size from a string in the form of `[width]x[height]`, |
||
101 | * for example 278x219. |
||
102 | * |
||
103 | * @param string $size WxH string |
||
104 | * |
||
105 | * @return array An array with width and height values array([width], [height]), |
||
106 | * for the example above: array(278, 219). |
||
107 | */ |
||
108 | public static function parseSize($size) |
||
114 | |||
115 | /** |
||
116 | * Checks if a given exception is supported by the Image class. |
||
117 | * |
||
118 | * @param string $extension |
||
119 | * @param bool $bmpSupport |
||
120 | * |
||
121 | * @return bool |
||
122 | */ |
||
123 | public static function isSupportedExtension($extension, $bmpSupport = false) |
||
133 | |||
134 | /** |
||
135 | * Returns the MIME type for a given extension. |
||
136 | * |
||
137 | * @param string $extension |
||
138 | * |
||
139 | * @return string MIME type |
||
140 | */ |
||
141 | public static function mimeTypeFromExtension($extension) |
||
156 | |||
157 | /** |
||
158 | * Constructor. |
||
159 | * |
||
160 | * @param string $imageData image data |
||
161 | * @param bool $bmpSupport `true` if bitmaps are supported (be aware of poor efficiency!). |
||
162 | * |
||
163 | * @throws CKFinderException in case the image could not be initialized properly. |
||
164 | */ |
||
165 | |||
166 | public function __construct($imageData, $bmpSupport = false) |
||
218 | |||
219 | /** |
||
220 | * Returns the aspect ratio size as associative array: |
||
221 | * @code |
||
222 | * array |
||
223 | * ( |
||
224 | * [width] => 80 |
||
225 | * [heigth] => 120 |
||
226 | * ) |
||
227 | * @endcode |
||
228 | * |
||
229 | * @param int $maxWidth requested width |
||
230 | * @param int $maxHeight requested height |
||
231 | * @param int $actualWidth original width |
||
232 | * @param int $actualHeight original height |
||
233 | * @param bool $useHigherFactor defines which factor should be used to calculate the new |
||
234 | * size. For example: |
||
235 | * - original image size 800x400 |
||
236 | * - calculateAspectRatio(300, 200, 800, 400, false) will return 300x150 |
||
237 | * - calculateAspectRatio(300, 200, 800, 400, true) will return 400x200 |
||
238 | * |
||
239 | * @return array |
||
240 | */ |
||
241 | public static function calculateAspectRatio($maxWidth, $maxHeight, $actualWidth, $actualHeight, $useHigherFactor = false) |
||
279 | |||
280 | |||
281 | /** |
||
282 | * @link http://pl.php.net/manual/pl/function.imagecreatefromjpeg.php |
||
283 | * function posted by e dot a dot schultz at gmail dot com |
||
284 | * |
||
285 | * @param $imageWidth |
||
286 | * @param $imageHeight |
||
287 | * @param $imageBits |
||
288 | * @param $imageChannels |
||
289 | * |
||
290 | * @return bool |
||
291 | */ |
||
292 | public function setMemory($imageWidth, $imageHeight, $imageBits, $imageChannels) |
||
343 | |||
344 | /** |
||
345 | * @link http://pl.php.net/manual/en/function.imagecopyresampled.php |
||
346 | * Replacement to `imagecopyresampled` that will deliver results that are almost identical except |
||
347 | * MUCH faster (very typically 30 times faster). |
||
348 | * |
||
349 | * @static |
||
350 | * @access public |
||
351 | * @param resource $dstImage |
||
352 | * @param resource $srcImage |
||
353 | * @param int $dstX |
||
354 | * @param int $dstY |
||
355 | * @param int $srcX |
||
356 | * @param int $srcY |
||
357 | * @param int $dstW |
||
358 | * @param int $dstH |
||
359 | * @param int $srcW |
||
360 | * @param int $srcH |
||
361 | * @param int $quality |
||
362 | * |
||
363 | * @return boolean |
||
364 | */ |
||
365 | public function fastCopyResampled(&$dstImage, $srcImage, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH, $quality = 3) |
||
389 | |||
390 | /** |
||
391 | * Source: http://pl.php.net/imagecreate |
||
392 | * (optimized for speed and memory usage, but yet not very efficient). |
||
393 | * |
||
394 | * @param string $data bitmap data |
||
395 | * |
||
396 | * @return resource |
||
397 | */ |
||
398 | public function createFromBmp($data) |
||
527 | |||
528 | /** |
||
529 | * Resizes an image to a given size keeping the aspect ratio. |
||
530 | * |
||
531 | * @param int $maxWidth maximum width |
||
532 | * @param int $maxHeight maximum height |
||
533 | * @param int $quality quality |
||
534 | * @param bool $useHigherFactor |
||
535 | * |
||
536 | * @return Image $this |
||
537 | */ |
||
538 | public function resize($maxWidth, $maxHeight, $quality = 80, $useHigherFactor = false) |
||
573 | |||
574 | /** |
||
575 | * Returns image data. |
||
576 | * |
||
577 | * @param string $format Returned image format mimetype (current image mimetype is used if not set). |
||
578 | * @param int $quality Image quelity (used for JPG images only) |
||
579 | * |
||
580 | * @return string image data |
||
581 | */ |
||
582 | public function getData($format = null, $quality = 80) |
||
612 | |||
613 | /** |
||
614 | * Returns GD image resource. |
||
615 | * |
||
616 | * @return resource GD image resource |
||
617 | */ |
||
618 | public function getGDImage() |
||
622 | |||
623 | /** |
||
624 | * Returns the size of image data produced by the `getData()` method. |
||
625 | * |
||
626 | * @return int image data size in bytes |
||
627 | */ |
||
628 | public function getDataSize() |
||
632 | |||
633 | /** |
||
634 | * Returns image width in pixels. |
||
635 | * |
||
636 | * @return int image width |
||
637 | */ |
||
638 | public function getWidth() |
||
642 | |||
643 | /** |
||
644 | * Returns image height in pixels. |
||
645 | * |
||
646 | * @return int image height |
||
647 | */ |
||
648 | public function getHeight() |
||
652 | |||
653 | /** |
||
654 | * Returns image MIME type. |
||
655 | * |
||
656 | * @return string MIME type |
||
657 | */ |
||
658 | public function getMimeType() |
||
662 | |||
663 | public function crop($x, $y, $width, $height) |
||
683 | |||
684 | public function rotate($degrees, $bgcolor = 0) |
||
697 | |||
698 | public function getInfo() |
||
708 | |||
709 | public function __destruct() |
||
715 | } |
||
716 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.