Thumbnails   F
last analyzed

Complexity

Total Complexity 67

Size/Duplication

Total Lines 338
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 144
dl 0
loc 338
rs 3.04
c 0
b 0
f 0
wmc 67

12 Methods

Rating   Name   Duplication   Size   Complexity  
A setImagePath() 0 3 1
A setUseThumbs() 0 3 1
F resizeThumbnail() 0 89 26
B __construct() 0 30 8
D createThumbnail() 0 53 16
A setImageType() 0 3 1
A checkPaths() 0 10 5
A checkGdLibrary() 0 11 3
A checkImage() 0 8 2
A setImgSavePath() 0 3 1
A useThumbs() 0 7 2
A setImageName() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like Thumbnails 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.

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 Thumbnails, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace XoopsModules\Xoopstube;
4
5
/**
6
 * Module: XoopsTube
7
 *
8
 * You may not change or alter any portion of this comment or credits
9
 * of supporting developers from this source code or any supporting source code
10
 * which is considered copyrighted (c) material of the original comment or credit authors.
11
 *
12
 * PHP version 5
13
 *
14
 * @category        Module
15
 * @package         Xoopstube
16
 * @author          XOOPS Development Team
17
 * @copyright       2001-2016 XOOPS Project (https://xoops.org)
18
 * @license         GNU GPL 2 or later (https://www.gnu.org/licenses/gpl-2.0.html)
19
 * @link            https://xoops.org/
20
 * @since           1.0.6
21
 */
22
23
use XoopsModules\Xoopstube;
24
25
if (!\defined('_PATH')) {
26
    \define('_PATH', XOOPS_ROOT_PATH);
27
}
28
29
if (!\defined('DEFAULT_PATH')) {
30
    \define('DEFAULT_PATH', XOOPS_UPLOAD_URL . '/blank.gif');
31
}
32
33
/**
34
 * Class Thumbnails
35
 */
36
class Thumbnails
37
{
38
    public $_imgName      = 'blank.gif';
39
    public $_img_path     = 'uploads';
40
    public $_img_savepath = 'thumbs';
41
    public $_source_path  = '';
42
    public $_save_path    = '';
43
    public $_source_url   = '';
44
    public $_source_image = '';
45
    public $_save_image   = '';
46
    public $_usethumbs       = 0;
47
    public $_image_type      = 'gd2';
48
    public $_return_fullpath = 0;
49
    public $img_width   = 100;
50
    public $img_height  = 100;
51
    public $img_quality = 100;
52
    public $img_update  = 1;
53
    public $img_aspect  = 1;
54
    // @access private
55
    public $_img_info = [];
56
57
    /**
58
     * Constructor
59
     *
60
     * @param null $img_name
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $img_name is correct as it would always require null to be passed?
Loading history...
61
     * @param null $img_path
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $img_path is correct as it would always require null to be passed?
Loading history...
62
     * @param null $img_savepath
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $img_savepath is correct as it would always require null to be passed?
Loading history...
63
     *
64
     * @internal param string $_imgName
65
     * @internal param string $_img_path
66
     * @internal param string $_img_savepath
67
     */
68
    public function __construct($img_name = null, $img_path = null, $img_savepath = null)
69
    {
70
        if (!\preg_match('/\.(jpg|gif|png|jpeg)$/i', $img_name)) {
0 ignored issues
show
Bug introduced by
$img_name of type null is incompatible with the type string expected by parameter $subject of preg_match(). ( Ignorable by Annotation )

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

70
        if (!\preg_match('/\.(jpg|gif|png|jpeg)$/i', /** @scrutinizer ignore-type */ $img_name)) {
Loading history...
71
            return false;
72
        }
73
74
        // The actual image we will be processing
75
        if (!null === $img_name) {
0 ignored issues
show
introduced by
The condition ! null === $img_name is always false.
Loading history...
76
            $this->_imgName = \trim($img_name);
77
        }
78
79
        // The image path
80
        if (!null === $img_path) {
0 ignored issues
show
introduced by
The condition ! null === $img_path is always false.
Loading history...
81
            $this->_img_path = \trim($img_path);
82
        }
83
84
        // The image save path
85
        if (!null === $img_savepath) {
0 ignored issues
show
introduced by
The condition ! null === $img_savepath is always false.
Loading history...
86
            $this->_img_savepath = \trim($img_savepath);
87
        }
88
89
        $path_to_check = XOOPS_ROOT_PATH . "/$img_path/$img_savepath";
90
91
        if (!\is_dir($path_to_check)) {
92
            if (!\mkdir($path_to_check, 0777) && !\is_dir($path_to_check)) {
93
                return false;
94
            }
95
        }
96
97
        return null;
98
    }
99
100
    /**
101
     * wfThumbsNails::setUseThumbs()
102
     *
103
     * @param int $value
104
     */
105
    public function setUseThumbs($value = 1)
106
    {
107
        $this->_usethumbs = $value;
108
    }
109
110
    /**
111
     * XtubeThumbsNails::setImageType()
112
     *
113
     * @param string $value
114
     */
115
    public function setImageType($value = 'gd2')
116
    {
117
        $this->_image_type = $value;
118
    }
119
120
    /**
121
     * ThumbsNails::createThumbnail()
122
     *
123
     * @param int $img_width
124
     * @param int $img_height
125
     * @param int $img_quality
126
     * @param int $img_update
127
     * @param int $img_aspect
128
     *
129
     * @return bool|string
130
     */
131
    public function createThumbnail(
132
        $img_width = null,
133
        $img_height = null,
134
        $img_quality = null,
135
        $img_update = null,
136
        $img_aspect = null
137
    ) {
138
        $this->_source_path  = XOOPS_ROOT_PATH . "/{$this->_img_path}";
139
        $this->_save_path    = XOOPS_ROOT_PATH . "/{$this->_img_path}/{$this->_img_savepath}";
140
        $this->_source_url   = XOOPS_URL . "/{$this->_img_path}";
141
        $this->_source_image = "{$this->_source_path}/{$this->_imgName}";
142
143
        if (isset($img_width) && !null === $img_width) {
0 ignored issues
show
introduced by
The condition ! null === $img_width is always false.
Loading history...
144
            $this->img_width = (int)$img_width;
145
        }
146
147
        if (isset($img_height) && !null === $img_height) {
0 ignored issues
show
introduced by
The condition ! null === $img_height is always false.
Loading history...
148
            $this->img_height = (int)$img_height;
149
        }
150
151
        if (isset($img_quality) && !null === $img_quality) {
0 ignored issues
show
introduced by
The condition ! null === $img_quality is always false.
Loading history...
152
            $this->img_quality = (int)$img_quality;
153
        }
154
155
        if (isset($img_update) && !null === $img_update) {
0 ignored issues
show
introduced by
The condition ! null === $img_update is always false.
Loading history...
156
            $this->img_update = (int)$img_update;
157
        }
158
159
        if (isset($img_aspect) && !null === $img_aspect) {
0 ignored issues
show
introduced by
The condition ! null === $img_aspect is always false.
Loading history...
160
            $this->img_aspect = (int)$img_aspect;
161
        }
162
163
        // Return false if we are not using thumbnails
164
        if (!$this->useThumbs()) {
165
            return $this->_source_url . '/' . $this->_imgName;
166
        }
167
        // Return false if the server does not have gd lib installed or activated
168
        if (!$this->checkGdLibrary()) {
169
            return $this->_source_url . '/' . $this->_imgName;
170
        }
171
172
        // Return false if the paths to the file are wrong
173
        if (!$this->checkPaths()) {
174
            return DEFAULT_PATH;
175
        }
176
177
        if (!$this->checkImage()) {
178
            return DEFAULT_PATH;
179
        }
180
181
        $image = $this->resizeThumbnail();
182
183
        return false === $image ? DEFAULT_PATH : $image;
184
    }
185
186
    /**
187
     * @param $value
188
     */
189
    public function setImageName($value)
190
    {
191
        $this->_imgName = \trim($value);
192
    }
193
194
    /**
195
     * @param $value
196
     */
197
    public function setImagePath($value)
198
    {
199
        $this->_img_path = \trim($value);
200
    }
201
202
    /**
203
     * @param $value
204
     */
205
    public function setImgSavePath($value)
206
    {
207
        $this->_img_savepath = \trim($value);
208
    }
209
210
    // ThumbsNails::resizeThumbnail()
211
    // @return
212
213
    /**
214
     * @return bool|string
215
     */
216
    public function resizeThumbnail()
217
    {
218
        // Get image size and scale ratio
219
        $scale = \min($this->img_width / $this->_img_info[0], $this->img_height / $this->_img_info[1]);
220
        // If the image is larger than the max shrink it
221
        $newWidth  = $this->img_width;
222
        $newHeight = $this->img_height;
223
        if ($scale < 1 && 1 == $this->img_aspect) {
224
            $newWidth  = \floor($scale * $this->_img_info[0]);
225
            $newHeight = \floor($scale * $this->_img_info[1]);
226
        }
227
        $newWidth  = ($newWidth > $this->_img_info[0]) ? $this->_img_info[0] : $newWidth;
228
        $newHeight = ($newHeight > $this->_img_info[0]) ? $this->_img_info[0] : $newHeight;
229
230
        $savefile          = "{$newWidth}x{$newHeight}_{$this->_imgName}";
231
        $this->_save_image = "{$this->_save_path}/{$savefile}";
232
233
        if (0 == $this->img_update && \file_exists($this->_save_image)) {
234
            return 1 == $this->_return_fullpath ? $this->_source_url . "/{$this->_img_savepath}/{$savefile}" : "{$this->_img_savepath}/{$savefile}";
235
        }
236
237
        switch ($this->_image_type) {
238
            case 'im':
239
                if (!empty($GLOBALS['xoopsModuleConfig']['path_magick']) && \is_dir($GLOBALS['xoopsModuleConfig']['path_magick'])) {
240
                    if (\preg_match('#[A-Z]:|\\\\#Ai', __FILE__)) {
241
                        $cur_dir     = __DIR__;
242
                        $src_file_im = '"' . $cur_dir . '\\' . \str_replace('/', '\\', $this->_source_image) . '"';
0 ignored issues
show
Unused Code introduced by
The assignment to $src_file_im is dead and can be removed.
Loading history...
243
                        $new_file_im = '"' . $cur_dir . '\\' . \str_replace('/', '\\', $this->_save_image) . '"';
244
                    } else {
245
                        $src_file_im = \escapeshellarg($this->_source_image);
246
                        $new_file_im = \escapeshellarg($this->_save_image);
247
                    }
248
                    $magick_command = $GLOBALS['xoopsModuleConfig']['path_magick'] . '/convert -auto-orient -quality {$GLOBALS["xoopsModuleConfig"]["imagequality"]} -antialias -sample {$newWidth}x{$newHeight} {$src_file_im} +profile "*" ' . \str_replace('\\', '/', $new_file_im) . '';
249
                    \passthru($magick_command);
250
251
                    return $this->_source_url . "/{$this->_img_savepath}/{$savefile}";
252
                }
253
254
                return false;
255
                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...
256
            case 'gd1':
257
            case 'gd2':
258
            default:
259
260
                $imageCreateFunction = (\function_exists('imagecreatetruecolor') && 'gd2' === $this->_image_type) ? 'imagecreatetruecolor' : 'imagecreate';
261
                $imageCopyfunction   = (\function_exists('ImageCopyResampled') && 'gd2' === $this->_image_type) ? 'imagecopyresampled' : 'imagecopyresized';
262
263
                switch ($this->_img_info[2]) {
264
                    case 1:
265
                        // GIF image
266
                        $img     = \function_exists('imagecreatefromgif') ? \imagecreatefromgif($this->_source_image) : \imagecreatefrompng($this->_source_image);
267
                        $tmp_img = $imageCreateFunction($newWidth, $newHeight);
268
                        $imageCopyfunction($tmp_img, $img, 0, 0, 0, 0, $newWidth, $newHeight, $this->_img_info[0], $this->_img_info[1]);
269
                        if (\function_exists('imagegif')) {
270
                            \imagegif($tmp_img, $this->_save_image);
271
                        } else {
272
                            \imagepng($tmp_img, $this->_save_image);
273
                        }
274
                        \imagedestroy($tmp_img);
275
                        break;
276
                    case 2:
277
                        // echo $this->_save_image;
278
                        $img     = \function_exists('imagecreatefromjpeg') ? \imagecreatefromjpeg($this->_source_image) : \imagecreatefrompng($this->_source_image);
279
                        $tmp_img = $imageCreateFunction($newWidth, $newHeight);
280
                        $imageCopyfunction($tmp_img, $img, 0, 0, 0, 0, $newWidth, $newHeight, $this->_img_info[0], $this->_img_info[1]);
281
                        if (\function_exists('imagejpeg')) {
282
                            \imagejpeg($tmp_img, $this->_save_image, $this->img_quality);
283
                        } else {
284
                            \imagepng($tmp_img, $this->_save_image);
285
                        }
286
                        \imagedestroy($tmp_img);
287
                        break;
288
                    case 3:
289
                        // PNG image
290
                        $img     = \imagecreatefrompng($this->_source_image);
291
                        $tmp_img = $imageCreateFunction($newWidth, $newHeight);
292
                        $imageCopyfunction($tmp_img, $img, 0, 0, 0, 0, $newWidth, $newHeight, $this->_img_info[0], $this->_img_info[1]);
293
                        \imagepng($tmp_img, $this->_save_image);
294
                        \imagedestroy($tmp_img);
295
                        break;
296
                    default:
297
                        return false;
298
                }
299
                if (1 == $this->_return_fullpath) {
300
                    return $this->_source_url . "/{$this->_img_savepath}/{$savefile}";
301
                }
302
303
                return "{$this->_img_savepath}/{$savefile}";
304
                break;
305
        }
306
        //        return FALSE;
307
    }
308
309
    // ThumbsNails::checkPaths()
310
    // @return
311
312
    /**
313
     * @return bool
314
     */
315
    public function checkPaths()
316
    {
317
        if (\file_exists($this->_source_image) || \is_readable($this->_source_image)) {
318
            return true;
319
        }
320
        if (\is_dir($this->_save_image) || \is_writable($this->_save_image)) {
321
            return true;
322
        }
323
324
        return false;
325
    }
326
327
    /**
328
     * @return bool
329
     */
330
    public function checkImage()
331
    {
332
        $this->_img_info = \getimagesize($this->_source_image, $imageinfo);
333
        if (null === $this->_img_info) {
334
            return false;
335
        }
336
337
        return true;
338
    }
339
340
    // wfsThumbs::checkGdLibrary()
341
    // Private function
342
    // @return false if gd lib not found on the system
343
344
    /**
345
     * @return array|bool
346
     */
347
    public function checkGdLibrary()
348
    {
349
        if (!\extension_loaded('gd')) {
350
            return false;
351
        }
352
        $gdlib = \function_exists('gd_info');
0 ignored issues
show
Unused Code introduced by
The assignment to $gdlib is dead and can be removed.
Loading history...
353
        if (false === $gdlib = gd_info()) {
354
            return false;
355
        }
356
357
        return $gdlib;
358
    }
359
360
    // ThumbsNails::useThumbs()
361
    //
362
    // @return
363
364
    /**
365
     * @return bool
366
     */
367
    public function useThumbs()
368
    {
369
        if ($this->_usethumbs) {
370
            return true;
371
        }
372
373
        return false;
374
    }
375
}
376