Completed
Push — master ( 6c5294...348995 )
by Michael
02:27
created

functions.image.php ➔ sf_createThumbnail()   F

Complexity

Conditions 30
Paths 8006

Size

Total Lines 120
Code Lines 84

Duplication

Lines 16
Ratio 13.33 %

Importance

Changes 0
Metric Value
cc 30
eloc 84
nc 8006
nop 2
dl 16
loc 120
rs 2
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
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 33 and the first side effect is on line 220.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
// 
3
//  ------------------------------------------------------------------------ //
4
//                XOOPS - PHP Content Management System                      //
5
//                  Copyright (c) 2000-2016 XOOPS.org                        //
6
//                         <http://xoops.org/>                               //
7
//  ------------------------------------------------------------------------ //
8
//  This program is free software; you can redistribute it and/or modify     //
9
//  it under the terms of the GNU General Public License as published by     //
10
//  the Free Software Foundation; either version 2 of the License, or        //
11
//  (at your option) any later version.                                      //
12
//                                                                           //
13
//  You may not change or alter any portion of this comment or credits       //
14
//  of supporting developers from this source code or any supporting         //
15
//  source code which is considered copyrighted (c) material of the          //
16
//  original comment or credit authors.                                      //
17
//                                                                           //
18
//  This program is distributed in the hope that it will be useful,          //
19
//  but WITHOUT ANY WARRANTY; without even the implied warranty of           //
20
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            //
21
//  GNU General Public License for more details.                             //
22
//                                                                           //
23
//  You should have received a copy of the GNU General Public License        //
24
//  along with this program; if not, write to the Free Software              //
25
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA //
26
//  ------------------------------------------------------------------------ //
27
//  Author: phppp (D.J., [email protected])                                  //
28
//  URL: http://xoopsforge.com, http://xoops.org.cn                          //
29
//  Project: Article Project                                                 //
30
//  ------------------------------------------------------------------------ //
31
32
if (!defined('NEWBB_FUNCTIONS_IMAGE')) :
33
    define('NEWBB_FUNCTIONS_IMAGE', true);
34
35
    /**
36
     * @param $source
37
     * @return string
38
     */
39
    function sf_attachmentImage($source)
40
    {
41
        global $xoopsModuleConfig;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
42
43
        $img_path   = XOOPS_ROOT_PATH . '/' . $xoopsModuleConfig['dir_attachments'];
44
        $img_url    = XOOPS_URL . '/' . $xoopsModuleConfig['dir_attachments'];
45
        $thumb_path = $img_path . '/thumbs';
46
        $thumb_url  = $img_url . '/thumbs';
47
48
        $thumb     = $thumb_path . '/' . $source;
49
        $image     = $img_path . '/' . $source;
50
        $thumb_url = $thumb_url . '/' . $source;
51
        $image_url = $img_url . '/' . $source;
52
53
        $imginfo  = @getimagesize($image);
54
        $img_info = (count($imginfo) > 0) ? $imginfo[0] . 'X' . $imginfo[1] . ' px' : '';
55
56
        if ($xoopsModuleConfig['max_image_width'] > 0 && $xoopsModuleConfig['max_image_height'] > 0) {
57
            if ($imginfo[0] > $xoopsModuleConfig['max_image_width'] || $imginfo[1] > $xoopsModuleConfig['max_image_height']) {
58
                //if (!file_exists($thumb_path.'/'.$source) && $imginfo[0] > $xoopsModuleConfig['max_img_width']) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
66% 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...
59
                if (!file_exists($thumb_path . '/' . $source)) {
60
                    sf_createThumbnail($source, $xoopsModuleConfig['max_image_width']);
61
                }
62
            }
63
64
            if ($imginfo[0] > $xoopsModuleConfig['max_image_width'] || $imginfo[1] > $xoopsModuleConfig['max_image_height']) {
65
                $pseudo_width  = $xoopsModuleConfig['max_image_width'];
66
                $pseudo_height = $xoopsModuleConfig['max_image_width'] * ($imginfo[1] / $imginfo[0]);
67
                $pseudo_size   = "width='" . $pseudo_width . "px' height='" . $pseudo_height . "px'";
68
            }
69
            // irmtfan to fix Undefined variable: pseudo_height
70
            if (!empty($pseudo_height) && $xoopsModuleConfig['max_image_height'] > 0 && $pseudo_height > $xoopsModuleConfig['max_image_height']) {
71
                $pseudo_height = $xoopsModuleConfig['max_image_height'];
72
                $pseudo_width  = $xoopsModuleConfig['max_image_height'] * ($imginfo[0] / $imginfo[1]);
73
                $pseudo_size   = "width='" . $pseudo_width . "px' height='" . $pseudo_height . "px'";
74
            }
75
        }
76
77
        if (file_exists($thumb)) {
78
            $attachmentImage = '<a href="' . $image_url . '" title="' . $source . ' ' . $img_info . '" target="_blank">';
79
            $attachmentImage .= '<img src="' . $thumb_url . '" alt="' . $source . ' ' . $img_info . '" />';
80
            $attachmentImage .= '</a>';
81
        } elseif (!empty($pseudo_size)) {
82
            $attachmentImage = '<a href="' . $image_url . '" title="' . $source . ' ' . $img_info . '" target="_blank">';
83
            $attachmentImage .= '<img src="' . $image_url . '" ' . $pseudo_size . ' alt="' . $source . ' ' . $img_info . '" />';
84
            $attachmentImage .= '</a>';
85
        } elseif (file_exists($image)) {
86
            $attachmentImage = '<img src="' . $image_url . '" alt="' . $source . ' ' . $img_info . '" />';
87
        } else {
88
            $attachmentImage = '';
89
        }
90
91
        return $attachmentImage;
92
    }
93
94
    /**
95
     * @param $source
96
     * @param $thumb_width
97
     * @return bool
98
     */
99
    function sf_createThumbnail($source, $thumb_width)
100
    {
101
        global $xoopsModuleConfig;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
102
103
        $img_path   = XOOPS_ROOT_PATH . '/' . $xoopsModuleConfig['dir_attachments'];
104
        $thumb_path = $img_path . '/thumbs';
105
        $src_file   = $img_path . '/' . $source;
106
        $new_file   = $thumb_path . '/' . $source;
107
        //$imageLibs = sf_getImageLibs();
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...
108
109
        if (!filesize($src_file) || !is_readable($src_file)) {
110
            return false;
111
        }
112
113
        if (!is_dir($thumb_path) || !is_writable($thumb_path)) {
114
            return false;
115
        }
116
117
        $imginfo = @getimagesize($src_file);
118
119
        if (null == $imginfo) {
120
            return false;
121
        }
122
        if ($imginfo[0] < $thumb_width) {
123
            return false;
124
        }
125
126
        $newWidth  = (int)min($imginfo[0], $thumb_width);
127
        $newHeight = (int)($imginfo[1] * $newWidth / $imginfo[0]);
128
129
        if ($xoopsModuleConfig['image_lib'] == 1 or $xoopsModuleConfig['image_lib'] == 0) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
130
            if (preg_match("#[A-Z]:|\\\\#Ai", __FILE__)) {
131
                $cur_dir     = __DIR__;
132
                $src_file_im = '"' . $cur_dir . '\\' . strtr($src_file, '/', '\\') . '"';
133
                $new_file_im = '"' . $cur_dir . '\\' . strtr($new_file, '/', '\\') . '"';
134
            } else {
135
                $src_file_im = @escapeshellarg($src_file);
136
                $new_file_im = @escapeshellarg($new_file);
137
            }
138
            $path           = empty($xoopsModuleConfig['path_magick']) ? '' : $xoopsModuleConfig['path_magick'] . '/';
139
            $magick_command = $path . 'convert -quality 85 -antialias -sample ' . $newWidth . 'x' . $newHeight . ' ' . $src_file_im . ' +profile "*" ' . str_replace('\\', '/', $new_file_im) . '';
140
141
            @passthru($magick_command);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
142
            if (file_exists($new_file)) {
143
                return true;
144
            }
145
        }
146
147
        if ($xoopsModuleConfig['image_lib'] == 2 or $xoopsModuleConfig['image_lib'] == 0) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
148
            $path = empty($xoopsModuleConfig['path_netpbm']) ? '' : $xoopsModuleConfig['path_netpbm'] . '/';
149
            if (preg_match("/\.png/i", $source)) {
150
                $cmd = $path . "pngtopnm $src_file | " . $path . "pnmscale -xysize $newWidth $newHeight | " . $path . "pnmtopng > $new_file";
151
            } elseif (preg_match("/\.(jpg|jpeg)/i", $source)) {
152
                $cmd = $path . "jpegtopnm $src_file | " . $path . "pnmscale -xysize $newWidth $newHeight | " . $path . "ppmtojpeg -quality=90 > $new_file";
153
            } elseif (preg_match("/\.gif/i", $source)) {
154
                $cmd = $path . "giftopnm $src_file | " . $path . "pnmscale -xysize $newWidth $newHeight | ppmquant 256 | " . $path . "ppmtogif > $new_file";
155
            }
156
157
            @exec($cmd, $output, $retval);
0 ignored issues
show
Bug introduced by
The variable $cmd does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
158
            if (file_exists($new_file)) {
159
                return true;
160
            }
161
        }
162
163
        $type            = $imginfo[2];
164
        $supported_types = array();
165
166
        if (!extension_loaded('gd')) {
167
            return false;
168
        }
169
        if (function_exists('imagegif')) {
170
            $supported_types[] = 1;
171
        }
172
        if (function_exists('imagejpeg')) {
173
            $supported_types[] = 2;
174
        }
175
        if (function_exists('imagepng')) {
176
            $supported_types[] = 3;
177
        }
178
179
        $imageCreateFunction = function_exists('imagecreatetruecolor') ? 'imagecreatetruecolor' : 'imagecreate';
180
181
        if (in_array($type, $supported_types)) {
182
            switch ($type) {
183
                case 1:
184
                    if (!function_exists('imagecreatefromgif')) {
185
                        return false;
186
                    }
187
                    $im     = imagecreatefromgif($src_file);
188
                    $new_im = imagecreate($newWidth, $newHeight);
189
                    imagecopyresized($new_im, $im, 0, 0, 0, 0, $newWidth, $newHeight, $imginfo[0], $imginfo[1]);
190
                    imagegif($new_im, $new_file);
191
                    imagedestroy($im);
192
                    imagedestroy($new_im);
193
                    break;
194 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...
195
                    $im     = imagecreatefromjpeg($src_file);
196
                    $new_im = $imageCreateFunction($newWidth, $newHeight);
197
                    imagecopyresized($new_im, $im, 0, 0, 0, 0, $newWidth, $newHeight, $imginfo[0], $imginfo[1]);
198
                    imagejpeg($new_im, $new_file, 90);
199
                    imagedestroy($im);
200
                    imagedestroy($new_im);
201
                    break;
202 View Code Duplication
                case 3:
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...
203
                    $im     = imagecreatefrompng($src_file);
204
                    $new_im = $imageCreateFunction($newWidth, $newHeight);
205
                    imagecopyresized($new_im, $im, 0, 0, 0, 0, $newWidth, $newHeight, $imginfo[0], $imginfo[1]);
206
                    imagepng($new_im, $new_file);
207
                    imagedestroy($im);
208
                    imagedestroy($new_im);
209
                    break;
210
            }
211
        }
212
213
        if (file_exists($new_file)) {
214
            return true;
215
        } else {
216
            return false;
217
        }
218
    }
219
220
endif;
221