Completed
Branch master (ddc2b8)
by Michael
02:46
created

XtubeThumbsNails::createThumbnail()   C

Complexity

Conditions 16
Paths 192

Size

Total Lines 53
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 16
eloc 30
nc 192
nop 5
dl 0
loc 53
rs 5.7211
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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:

1
<?php
2
/**
3
 * Module: XoopsTube
4
 *
5
 * You may not change or alter any portion of this comment or credits
6
 * of supporting developers from this source code or any supporting source code
7
 * which is considered copyrighted (c) material of the original comment or credit authors.
8
 *
9
 * PHP version 5
10
 *
11
 * @category        Module
12
 * @package         Xoopstube
13
 * @author          XOOPS Development Team
14
 * @copyright       2001-2016 XOOPS Project (http://xoops.org)
15
 * @license         GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
16
 * @link            http://xoops.org/
17
 * @since           1.0.6
18
 */
19
20
if (!defined('_PATH')) {
21
    define('_PATH', XOOPS_ROOT_PATH);
22
}
23
24
if (!defined('DEFAULT_PATH')) {
25
    define('DEFAULT_PATH', XOOPS_UPLOAD_URL . '/blank.gif');
26
}
27
28
/**
29
 * Class XtubeThumbsNails
30
 */
31
class XtubeThumbsNails
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
32
{
33
    public $_imgName      = 'blank.gif';
34
    public $_img_path     = 'uploads';
35
    public $_img_savepath = 'thumbs';
36
37
    public $_source_path  = '';
38
    public $_save_path    = '';
39
    public $_source_url   = '';
40
    public $_source_image = '';
41
    public $_save_image   = '';
42
43
    public $_usethumbs       = 0;
44
    public $_image_type      = 'gd2';
45
    public $_return_fullpath = 0;
46
47
    public $img_width   = 100;
48
    public $img_height  = 100;
49
    public $img_quality = 100;
50
    public $img_update  = 1;
51
    public $img_aspect  = 1;
52
53
    // @access private
54
    public $_img_info = array();
55
56
    /**
57
     * Constructor
58
     *
59
     * @param null $img_name
60
     * @param null $img_path
61
     * @param null $img_savepath
62
     *
63
     * @internal param string $_imgName
64
     * @internal param string $_img_path
65
     * @internal param string $_img_savepath
66
     * @return \XtubeThumbsNails
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
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)) {
71
            return false;
0 ignored issues
show
Bug introduced by
Constructors do not have meaningful return values, anything that is returned from here is discarded. Are you sure this is correct?
Loading history...
72
        }
73
74
        // The actual image we will be processing
75
        if (!null === $img_name) {
76
            $this->_imgName = (string)trim($img_name);
77
        }
78
79
        // The image path
80
        if (!null === $img_path) {
81
            $this->_img_path = (string)trim($img_path);
82
        }
83
84
        // The image save path
85
        if (!null === $img_savepath) {
86
            $this->_img_savepath = (string)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 (false === mkdir("$path_to_check", 0777)) {
93
                return false;
0 ignored issues
show
Bug introduced by
Constructors do not have meaningful return values, anything that is returned from here is discarded. Are you sure this is correct?
Loading history...
94
            }
95
        }
96
97
        return null;
98
    }
99
100
    /**
101
     * wfThumbsNails::setUseThumbs()
102
     *
103
     * @param integer $value
104
     *
105
     * @return void
106
     */
107
    public function setUseThumbs($value = 1)
108
    {
109
        $this->_usethumbs = $value;
110
    }
111
112
    /**
113
     * XtubeThumbsNails::setImageType()
114
     *
115
     * @param string $value
116
     *
117
     * @return void
118
     */
119
    public function setImageType($value = 'gd2')
120
    {
121
        $this->_image_type = $value;
122
    }
123
124
    /**
125
     * ThumbsNails::createThumbnail()
126
     *
127
     * @param int $img_width
0 ignored issues
show
Documentation introduced by
Should the type for parameter $img_width not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
128
     * @param int $img_height
0 ignored issues
show
Documentation introduced by
Should the type for parameter $img_height not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
129
     * @param int $img_quality
0 ignored issues
show
Documentation introduced by
Should the type for parameter $img_quality not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
130
     * @param int $img_update
0 ignored issues
show
Documentation introduced by
Should the type for parameter $img_update not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
131
     * @param int $img_aspect
0 ignored issues
show
Documentation introduced by
Should the type for parameter $img_aspect not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
132
     *
133
     * @return bool|string
134
     */
135
    public function createThumbnail(
136
        $img_width = null,
137
        $img_height = null,
138
        $img_quality = null,
139
        $img_update = null,
140
        $img_aspect = null
141
    ) {
142
        $this->_source_path  = XOOPS_ROOT_PATH . "/{$this->_img_path}";
143
        $this->_save_path    = XOOPS_ROOT_PATH . "/{$this->_img_path}/{$this->_img_savepath}";
144
        $this->_source_url   = XOOPS_URL . "/{$this->_img_path}";
145
        $this->_source_image = "{$this->_source_path}/{$this->_imgName}";
146
147
        if (isset($img_width) && !null === $img_width) {
148
            $this->img_width = (int)$img_width;
149
        }
150
151
        if (isset($img_height) && !null === $img_height) {
152
            $this->img_height = (int)$img_height;
153
        }
154
155
        if (isset($img_quality) && !null === $img_quality) {
156
            $this->img_quality = (int)$img_quality;
157
        }
158
159
        if (isset($img_update) && !null === $img_update) {
160
            $this->img_update = (int)$img_update;
161
        }
162
163
        if (isset($img_aspect) && !null === $img_aspect) {
164
            $this->img_aspect = (int)$img_aspect;
165
        }
166
167
        // Return false if we are not using thumb nails
168
        if (!$this->useThumbs()) {
169
            return $this->_source_url . '/' . $this->_imgName;
170
        }
171
        // Return false if the server does not have gd lib installed or activated
172
        if (!$this->checkGdLibrary()) {
173
            return $this->_source_url . '/' . $this->_imgName;
174
        }
175
176
        // Return false if the paths to the file are wrong
177
        if (!$this->checkPaths()) {
178
            return DEFAULT_PATH;
179
        }
180
181
        if (!$this->checkImage()) {
182
            return DEFAULT_PATH;
183
        }
184
185
        $image = $this->resizeThumbnail();
186
        return false === $image ? DEFAULT_PATH : $image;
187
    }
188
189
    /**
190
     * @param $value
191
     */
192
    public function setImageName($value)
193
    {
194
        $this->_imgName = (string)trim($value);
195
    }
196
197
    /**
198
     * @param $value
199
     */
200
    public function setImagePath($value)
201
    {
202
        $this->_img_path = (string)trim($value);
203
    }
204
205
    /**
206
     * @param $value
207
     */
208
    public function setImgSavePath($value)
209
    {
210
        $this->_img_savepath = (string)trim($value);
211
    }
212
213
    // ThumbsNails::resizeThumbnail()
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
214
    // @return
215
    /**
216
     * @return bool|string
217
     */
218
    public function resizeThumbnail()
0 ignored issues
show
Coding Style introduced by
resizeThumbnail uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
219
    {
220
        // Get image size and scale ratio
221
        $scale = min($this->img_width / $this->_img_info[0], $this->img_height / $this->_img_info[1]);
222
        // If the image is larger than the max shrink it
223
        $newWidth  = $this->img_width;
224
        $newHeight = $this->img_height;
225
        if ($scale < 1 && 1 == $this->img_aspect) {
226
            $newWidth  = floor($scale * $this->_img_info[0]);
227
            $newHeight = floor($scale * $this->_img_info[1]);
228
        }
229
        $newWidth  = ($newWidth > $this->_img_info[0]) ? $this->_img_info[0] : $newWidth;
230
        $newHeight = ($newHeight > $this->_img_info[0]) ? $this->_img_info[0] : $newHeight;
231
232
        $savefile          = "{$newWidth}x{$newHeight}_{$this->_imgName}";
233
        $this->_save_image = "{$this->_save_path}/{$savefile}";
234
235
        if (0 == $this->img_update && file_exists($this->_save_image)) {
236
            return $this->_return_fullpath == 1 ? $this->_source_url . "/{$this->_img_savepath}/{$savefile}" : "{$this->_img_savepath}/{$savefile}";
237
        }
238
239
        switch ($this->_image_type) {
240
            case 'im':
241
                if (!empty($GLOBALS['xoopsModuleConfig']['path_magick']) && is_dir($GLOBALS['xoopsModuleConfig']['path_magick'])) {
242
                    if (preg_match("#[A-Z]:|\\\\#Ai", __FILE__)) {
243
                        $cur_dir     = __DIR__;
244
                        $src_file_im = '"' . $cur_dir . '\\' . strtr($this->_source_image, '/', '\\') . '"';
0 ignored issues
show
Unused Code introduced by
$src_file_im is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
245
                        $new_file_im = '"' . $cur_dir . '\\' . strtr($this->_save_image, '/', '\\') . '"';
246
                    } else {
247
                        $src_file_im = escapeshellarg($this->_source_image);
0 ignored issues
show
Unused Code introduced by
$src_file_im is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
248
                        $new_file_im = escapeshellarg($this->_save_image);
249
                    }
250
                    $magick_command = $GLOBALS['xoopsModuleConfig']['path_magick']
251
                                      . '/convert -quality {$GLOBALS["xoopsModuleConfig"]["imagequality"]} -antialias -sample {$newWidth}x{$newHeight} {$src_file_im} +profile "*" ' . str_replace('\\',
252
                                                                                                                                                                                                   '/',
253
                                                                                                                                                                                                   $new_file_im)
254
                                      . '';
255
                    passthru($magick_command);
256
257
                    return $this->_source_url . "/{$this->_img_savepath}/{$savefile}";
258
                } else {
259
                    return false;
260
                }
261
262
                break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
263
264
            case 'gd1':
265
            case 'gd2':
266
            default :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a DEFAULT statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in the default statement.

switch ($expr) {
    default : //wrong
        doSomething();
        break;
}

switch ($expr) {
    default: //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
The default body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a default statement must start on the line immediately following the statement.

switch ($expr) {
    default:
        doSomething(); //right
        break;
}


switch ($expr) {
    default:

        doSomething(); //wrong
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
267
268
                $imageCreateFunction = (function_exists('imagecreatetruecolor') && 'gd2' === $this->_image_type) ? 'imagecreatetruecolor' : 'imagecreate';
269
                $imageCopyfunction   = (function_exists('ImageCopyResampled') && 'gd2' === $this->_image_type) ? 'imagecopyresampled' : 'imagecopyresized';
270
271
                switch ($this->_img_info[2]) {
272 View Code Duplication
                    case 1:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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.

Loading history...
273
                        // GIF image
274
                        $img     = function_exists('imagecreatefromgif') ? imagecreatefromgif($this->_source_image) : imagecreatefrompng($this->_source_image);
275
                        $tmp_img = $imageCreateFunction($newWidth, $newHeight);
276
                        $imageCopyfunction($tmp_img, $img, 0, 0, 0, 0, $newWidth, $newHeight, $this->_img_info[0], $this->_img_info[1]);
277
                        if (function_exists('imagegif')) {
278
                            imagegif($tmp_img, $this->_save_image);
279
                        } else {
280
                            imagepng($tmp_img, $this->_save_image);
281
                        }
282
                        imagedestroy($tmp_img);
283
                        break;
284
285 View Code Duplication
                    case 2:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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.

Loading history...
286
                        // echo $this->_save_image;
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
287
                        $img     = function_exists('imagecreatefromjpeg') ? imagecreatefromjpeg($this->_source_image) : imagecreatefrompng($this->_source_image);
288
                        $tmp_img = $imageCreateFunction($newWidth, $newHeight);
289
                        $imageCopyfunction($tmp_img, $img, 0, 0, 0, 0, $newWidth, $newHeight, $this->_img_info[0], $this->_img_info[1]);
290
                        if (function_exists('imagejpeg')) {
291
                            imagejpeg($tmp_img, $this->_save_image, $this->img_quality);
292
                        } else {
293
                            imagepng($tmp_img, $this->_save_image);
294
                        }
295
                        imagedestroy($tmp_img);
296
                        break;
297
298
                    case 3:
299
                        // PNG image
300
                        $img     = imagecreatefrompng($this->_source_image);
301
                        $tmp_img = $imageCreateFunction($newWidth, $newHeight);
302
                        $imageCopyfunction($tmp_img, $img, 0, 0, 0, 0, $newWidth, $newHeight, $this->_img_info[0], $this->_img_info[1]);
303
                        imagepng($tmp_img, $this->_save_image);
304
                        imagedestroy($tmp_img);
305
                        break;
306
                    default:
307
                        return false;
308
                }
309
                if (1 == $this->_return_fullpath) {
310
                    return $this->_source_url . "/{$this->_img_savepath}/{$savefile}";
311
                } else {
312
                    return "{$this->_img_savepath}/{$savefile}";
313
                }
314
                break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
315
        }
316
        //        return FALSE;
317
    }
318
319
    // ThumbsNails::checkPaths()
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
320
    // @return
321
    /**
322
     * @return bool
323
     */
324
    public function checkPaths()
325
    {
326
        if (file_exists($this->_source_image) || is_readable($this->_source_image)) {
327
            return true;
328
        }
329
        if (is_dir($this->_save_image) || is_writable($this->_save_image)) {
330
            return true;
331
        }
332
333
        return false;
334
    }
335
336
    /**
337
     * @return bool
338
     */
339
    public function checkImage()
340
    {
341
        $this->_img_info = getimagesize($this->_source_image, $imageinfo);
342
        if (null === $this->_img_info) {
343
            return false;
344
        }
345
346
        return true;
347
    }
348
349
    // wfsThumbs::checkGdLibrary()
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
350
    // Private function
351
    // @return false if gd lib not found on the system
352
    /**
353
     * @return array|bool
354
     */
355
    public function checkGdLibrary()
356
    {
357
        if (!extension_loaded('gd')) {
358
            return false;
359
        }
360
        $gdlib = function_exists('gd_info');
0 ignored issues
show
Unused Code introduced by
$gdlib is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
361
        if (false === $gdlib = gd_info()) {
362
            return false;
363
        }
364
365
        return $gdlib;
366
    }
367
368
    // ThumbsNails::useThumbs()
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
369
    //
370
    // @return
371
    /**
372
     * @return bool
373
     */
374
    public function useThumbs()
375
    {
376
        if ($this->_usethumbs) {
377
            return true;
378
        }
379
380
        return false;
381
    }
382
}
383