resize()   F
last analyzed

Complexity

Conditions 41
Paths > 20000

Size

Total Lines 175
Code Lines 117

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 41
eloc 117
nc 23814
nop 12
dl 0
loc 175
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/**
3
 * bulletproof\utils\resize
4
 *
5
 * Image resize function for bulletproof library
6
 *
7
 * PHP support 5.3+
8
 *
9
 * @package     bulletproof
10
 * @version     3.2.0
11
 * @author      https://twitter.com/_samayo
12
 * @link        https://github.com/samayo/bulletproof
13
 * @license     MIT
14
 */
15
16
17
namespace Bulletproof\Utils;
18
19
/*
20
 *
21
 * @param      string      $image        Path to the image
22
 * @param      string      $mimeType     The mime type of the image
23
 * @param      integer     $imgWidth     The original image width
24
 * @param      integer     $imgHeight    The original image height
25
 * @param      integer     $newWidth     The new image width (to be resized to)
26
 * @param      integer     $newHeight    The new image height (to be resized to)
27
 * @param      boolean     $ratio        Whether to keep the ratio or no
28
 * @param      boolean     $upsize       Whether to allow upsizing of the image or no
29
 * @param      boolean     $cropToSize   Whether to crop image to size or no. If set to true $ratio is ignored.
30
 * @param      array       $quality      Sets what quality should be used for
31
 *                                       JPEG or what compression should be used
32
 *                                       for PNG. See following example: *
33
 *                                              array(
34
 *                                                   'jpg' => array(
35
 *                                                                  'orig'     => true,  // (bool) whether to use same quality as original image (requires ImageMagick)
36
 *                                                                  'fallback' => 80,    // (int)  fallback if original image quality can not be detected or is not set. Accepted values are 1-100
37
 *                                                                  'max'      => 85,    // (int)  Maximal quality, if detected quality is more than this value, than this will be used. Accepted values are 1-100
38
 *                                                                  'min'      => 60     // (int)  Minimal quality, if detected quality is less than this value, than this will be used. Accepted values are 1-100
39
 *                                                                  ),
40
 *                                                   'png' => 9 // (int) PNG compression level. Accepted values are 0-9. Default is zlib's default which is currently ( 11/2018 ) equal to 6
41
 *                                                  );
42
 *
43
 *                                       Any of the values can be left out. See following example:
44
 *                                               array( 'jpg' => array( 'fallback' => 80 ) ) // this will set JPG quality to 80 on JPGs
45
 *
46
 * @param      string      $destination  Accepts either folder path or file.
47
 *                                       Script can handle both relative and
48
 *                                       absolute paths. Folder path needs to
49
 *                                       end with '/' (forward slash). If left empty (or set to false) it will overwrite original image
50
 * @param      integer     $permission   The permission for destination folder (if it will be created by script)
51
 *
52
 * @throws     \Exception  (description)
53
 *
54
 * @return     boolean     True on success false on failure
55
 *
56
 */
57
function resize($image, $mimeType, $imgWidth, $imgHeight, $newWidth, $newHeight, $ratio = false, $upsize = true, $cropToSize = false, $quality = array(), $destination = false, $permission = 0755)
58
{
59
    // Checks whether image cropping is enabled
60
    if ($cropToSize) {
61
        $source_aspect_ratio = $imgWidth / $imgHeight;
62
        $thumbnail_aspect_ratio = $newWidth / $newHeight;
63
64
        // Adjust cropping area and position depending on original and cropped image
65
        if ($thumbnail_aspect_ratio < $source_aspect_ratio) {
66
            $src_h = $imgHeight;
67
            $src_w = $imgHeight * $thumbnail_aspect_ratio;
68
            $src_x = (int) (($imgWidth - $src_w)/2);
69
            $src_y = 0;
70
        } else {
71
            $src_w = $imgWidth;
72
            $src_h = (int) ($imgWidth / $thumbnail_aspect_ratio);
73
            $src_x = 0;
74
            $src_y = (int) (($imgHeight - $src_h)/2);
75
        }
76
77
        // Checks whether image upsizing is enabled
78
        if (!$upsize) {
79
            $newHeightOrig = $newHeight;
80
            $newWidthOrig = $newWidth;
0 ignored issues
show
Unused Code introduced by
The assignment to $newWidthOrig is dead and can be removed.
Loading history...
81
82
            // If the given width is larger than the image width, then resize it
83
            if ($newWidth > $imgWidth) {
84
                $newWidth = $imgWidth;
85
                $newHeight = (int) ($newWidth / $imgWidth * $imgHeight);
86
                if ($newHeight > $newHeightOrig) {
87
                    $newHeight = $newHeightOrig;
88
                    $src_h = $newHeight;
89
                    $src_y = (int) (($imgHeight - $src_h)/2);
90
                }
91
92
                $src_x=0;
93
                $src_w = $imgWidth;
94
            }
95
96
            // If the given height is larger then the image height, then resize it.
97
            if ($newHeightOrig > $imgHeight) {
98
                $newHeight = $imgHeight;
99
                $src_y=0;
100
                $src_h = $imgHeight;
101
                $src_w = (int) ($src_h * ( $newWidth / $newHeight ));
102
                $src_x = (int) (($imgWidth - $src_w)/2);
103
            }
104
        }
105
    } else {
106
107
        // First, calculate the height.
108
        $height = (int) ($newWidth / $imgWidth * $imgHeight);  //  75
109
110
        // If the height is too large, set it to the maximum height and calculate the width.
111
        if ($height > $newHeight) {
112
            $height = $newHeight;
113
            $newWidth = (int) ($height / $imgHeight * $imgWidth);
114
        }
115
116
        // If we don't allow upsizing check if the new width or height are too big.
117
        if (!$upsize) {
118
            // If the given width is larger than the image width, then resize it
119
            if ($newWidth > $imgWidth) {
120
                $newWidth = $imgWidth;
121
                $newHeight = (int) ($newWidth / $imgWidth * $imgHeight);
122
            }
123
124
            // If the given height is larger then the image height, then resize it.
125
            if ($newHeight > $imgHeight) {
126
                $newHeight = $imgHeight;
127
                $newWidth = (int) ($height / $imgHeight * $imgWidth);
128
            }
129
        }
130
131
        if ($ratio == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
132
            $source_aspect_ratio = $imgWidth / $imgHeight;
133
            $thumbnail_aspect_ratio = $newWidth / $newHeight;
134
            if ($imgWidth <= $newWidth && $imgHeight <= $newHeight) {
135
                $newWidth = $imgWidth;
136
                $newHeight = $imgHeight;
137
            } elseif ($thumbnail_aspect_ratio > $source_aspect_ratio) {
138
                $newWidth = (int) ($newHeight * $source_aspect_ratio);
139
                $newHeight = $newHeight;
140
            } else {
141
                $newWidth = $newWidth;
142
                $newHeight = (int) ($newWidth / $source_aspect_ratio);
143
            }
144
        }
145
146
        $src_x = 0;
147
        $src_y = 0;
148
        $src_w = $imgWidth;
149
        $src_h = $imgHeight;
150
    }
151
152
    $imgString = file_get_contents($image);
153
154
    $imageFromString = imagecreatefromstring($imgString);
155
    $tmp = imagecreatetruecolor($newWidth, $newHeight);
156
    imagealphablending($tmp, false);
157
    imagesavealpha($tmp, true);
158
    imagecopyresampled(
159
        $tmp,
160
        $imageFromString,
161
        0,
162
        0,
163
        $src_x,
164
        $src_y,
165
        $newWidth,
166
        $newHeight,
167
        $src_w,
168
        $src_h
169
    );
170
171
    if ($destination !== false) {  // checks if was destination provided
172
        if(substr( $destination, -1 ) == '/' ) { // check whether prowided destination was folder or file.
173
            $create = !is_dir($destination) ? @mkdir($destination, $permission, true) : true; // if it was folder, it will crtete it if needed
174
            if ($create) {
175
                $path_parts = pathinfo($image);
176
                $destination = $destination . $path_parts['basename'];
0 ignored issues
show
Bug introduced by
Are you sure $destination of type false|string can be used in concatenation? ( Ignorable by Annotation )

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

176
                $destination = /** @scrutinizer ignore-type */ $destination . $path_parts['basename'];
Loading history...
177
            } else {
178
                return false; // TODO: throw error/exception
179
            }
180
        }
181
182
    } else {
183
        $destination = $image;
184
    }
185
186
    $path_parts = pathinfo($destination);
187
    $create = !is_dir($path_parts['dirname'].'/') ? @mkdir($path_parts['dirname'].'/', $permission, true) : true;
188
    if (!$create) {
189
        return false; // TODO: throw error/exception
190
    }
191
192
    switch ($mimeType) {
193
        case "jpeg":
194
        case "jpg":
195
            $q = 90; // function's default value - if everything else fails, this is used.
196
            if( false !== $image ) {
0 ignored issues
show
introduced by
The condition false !== $image is always true.
Loading history...
197
                if ((!empty($quality['jpg']['fallback'])) AND ( (int) $quality['jpg']['fallback'] ) AND ( $quality['jpg']['fallback'] > 0 ) AND ( $quality['jpg']['fallback'] <=100 ) ) {
198
                    $q = $quality['jpg']['fallback'];
199
                }
200
201
                if ((!empty($quality['jpg']['orig'])) AND true ===$quality['jpg']['orig'] ){
202
                    if (extension_loaded('imagick')){
203
                        $im = new \Imagick($image);
204
                        $q = $im->getImageCompressionQuality();
205
                    }
206
                }
207
208
                if((!empty($quality['jpg']['max'])) AND $quality['jpg']['max'] < $q ){
209
                    $q = $quality['jpg']['max'];
210
                }
211
212
                if((!empty($quality['jpg']['min'])) AND $quality['jpg']['min'] > $q ){
213
                    $q = $quality['jpg']['min'];
214
                }
215
            }
216
            return imagejpeg($tmp, $destination, $q );
217
            break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
218
        case "png":
219
            if ((!empty($quality['png'])) AND ( (int) $quality['png'] ) AND ( $quality['png'] >= -1 ) AND ( $quality['png'] <=9 ) ) {
220
                $q = $quality['png'];
221
            } else {
222
                $q = -1; // -1 is zlib's default value which is currently ( 11/2018 ) equal to 6
223
            }
224
            return imagepng($tmp, $destination, $q );
225
            break;
226
        case "gif":
227
            return imagegif($tmp, $destination);
228
            break;
229
        default:
230
            throw new \Exception(" Only jpg, jpeg, png and gif files can be resized ");
231
            break;
232
    }
233
}
234