elFinderPluginWatermark::watermarkPrint_imagick()   A
last analyzed

Complexity

Conditions 5
Paths 40

Size

Total Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
nc 40
nop 7
dl 0
loc 35
rs 9.0488
c 0
b 0
f 0
1
<?php
2
/**
3
 * elFinder Plugin Watermark
4
 *
5
 * Print watermark on file upload.
6
 *
7
 * ex. binding, configure on connector options
8
 *    $opts = array(
9
 *        'bind' => array(
10
 *            'upload.presave' => array(
11
 *                'Plugin.Watermark.onUpLoadPreSave'
12
 *            )
13
 *        ),
14
 *        // global configure (optional)
15
 *        'plugin' => array(
16
 *            'Watermark' => array(
17
 *                'enable'         => true,       // For control by volume driver
18
 *                'source'         => 'logo.png', // Path to Water mark image
19
 *                'marginRight'    => 5,          // Margin right pixel
20
 *                'marginBottom'   => 5,          // Margin bottom pixel
21
 *                'quality'        => 95,         // JPEG image save quality
22
 *                'transparency'   => 70,         // Water mark image transparency ( other than PNG )
23
 *                'targetType'     => IMG_GIF|IMG_JPG|IMG_PNG|IMG_WBMP, // Target image formats ( bit-field )
24
 *                'targetMinPixel' => 200         // Target image minimum pixel size
25
 *            )
26
 *        ),
27
 *        // each volume configure (optional)
28
 *        'roots' => array(
29
 *            array(
30
 *                'driver' => 'LocalFileSystem',
31
 *                'path'   => '/path/to/files/',
32
 *                'URL'    => 'http://localhost/to/files/'
33
 *                'plugin' => array(
34
 *                    'Watermark' => array(
35
 *                         'enable'         => true,       // For control by volume driver
36
 *                        'source'         => 'logo.png', // Path to Water mark image
37
 *                        'marginRight'    => 5,          // Margin right pixel
38
 *                        'marginBottom'   => 5,          // Margin bottom pixel
39
 *                        'quality'        => 95,         // JPEG image save quality
40
 *                        'transparency'   => 70,         // Water mark image transparency ( other than PNG )
41
 *                        'targetType'     => IMG_GIF|IMG_JPG|IMG_PNG|IMG_WBMP, // Target image formats ( bit-field )
42
 *                        'targetMinPixel' => 200         // Target image minimum pixel size
43
 *                    )
44
 *                )
45
 *            )
46
 *        )
47
 *    );
48
 *
49
 * @package elfinder
50
 * @author Naoki Sawada
51
 * @license New BSD
52
 */
53
class elFinderPluginWatermark {
54
55
    private $opts = array();
56
    private $watermarkImgInfo = null;
0 ignored issues
show
Unused Code introduced by
The property $watermarkImgInfo is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
57
58
    public function __construct($opts) {
59
        $defaults = array(
60
            'enable'         => true,       // For control by volume driver
61
            'source'         => 'logo.png', // Path to Water mark image
62
            'marginRight'    => 5,          // Margin right pixel
63
            'marginBottom'   => 5,          // Margin bottom pixel
64
            'quality'        => 95,         // JPEG image save quality
65
            'transparency'   => 70,         // Water mark image transparency ( other than PNG )
66
            'targetType'     => IMG_GIF|IMG_JPG|IMG_PNG|IMG_WBMP, // Target image formats ( bit-field )
67
            'targetMinPixel' => 200         // Target image minimum pixel size
68
        );
69
70
        $this->opts = array_merge($defaults, $opts);
71
72
    }
73
74
    public function onUpLoadPreSave(&$path, &$name, $src, $elfinder, $volume) {
0 ignored issues
show
Unused Code introduced by
The parameter $path is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $name is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $elfinder is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
75
76
        $opts = $this->opts;
77
        $volOpts = $volume->getOptionsPlugin('Watermark');
78
        if (is_array($volOpts)) {
79
            $opts = array_merge($this->opts, $volOpts);
80
        }
81
82
        if (! $opts['enable']) {
83
            return false;
84
        }
85
86
        $srcImgInfo = getimagesize($src);
87
        if ($srcImgInfo === false) {
88
            return false;
89
        }
90
91
        // check Animation Gif
92
        if (elFinder::isAnimationGif($src)) {
93
            return false;
94
        }
95
96
        // check water mark image
97
        if (! file_exists($opts['source'])) {
98
            $opts['source'] = dirname(__FILE__) . "/" . $opts['source'];
99
        }
100
        if (is_readable($opts['source'])) {
101
            $watermarkImgInfo = getimagesize($opts['source']);
102
            if (! $watermarkImgInfo) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $watermarkImgInfo of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
103
                return false;
104
            }
105
        } else {
106
            return false;
107
        }
108
109
        $watermark = $opts['source'];
110
        $marginLeft = $opts['marginRight'];
111
        $marginBottom = $opts['marginBottom'];
112
        $quality = $opts['quality'];
113
        $transparency = $opts['transparency'];
114
115
        // check target image type
116
        $imgTypes = array(
117
            IMAGETYPE_GIF  => IMG_GIF,
118
            IMAGETYPE_JPEG => IMG_JPEG,
119
            IMAGETYPE_PNG  => IMG_PNG,
120
            IMAGETYPE_BMP  => IMG_WBMP,
121
            IMAGETYPE_WBMP => IMG_WBMP
122
        );
123
        if (! isset($imgTypes[$srcImgInfo[2]]) || ! ($opts['targetType'] & $imgTypes[$srcImgInfo[2]])) {
124
            return false;
125
        }
126
127
        // check target image size
128
        if ($opts['targetMinPixel'] > 0 && $opts['targetMinPixel'] > min($srcImgInfo[0], $srcImgInfo[1])) {
129
            return false;
130
        }
131
132
        $watermark_width = $watermarkImgInfo[0];
133
        $watermark_height = $watermarkImgInfo[1];
134
        $dest_x = $srcImgInfo[0] - $watermark_width - $marginLeft;
135
        $dest_y = $srcImgInfo[1] - $watermark_height - $marginBottom;
136
137
        if (class_exists('Imagick', false)) {
138
            return $this->watermarkPrint_imagick($src, $watermark, $dest_x, $dest_y, $quality, $transparency, $watermarkImgInfo);
139
        } else {
140
            return $this->watermarkPrint_gd($src, $watermark, $dest_x, $dest_y, $quality, $transparency, $watermarkImgInfo, $srcImgInfo);
141
        }
142
    }
143
144
    private function watermarkPrint_imagick($src, $watermark, $dest_x, $dest_y, $quality, $transparency, $watermarkImgInfo) {
0 ignored issues
show
Unused Code introduced by
The parameter $watermarkImgInfo is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
145
146
        try {
147
            // Open the original image
148
            $img = new Imagick($src);
149
150
            // Open the watermark
151
            $watermark = new Imagick($watermark);
152
153
            // Set transparency
154
            if (strtoupper($watermark->getImageFormat()) !== 'PNG') {
155
                $watermark->setImageOpacity($transparency/100);
156
            }
157
158
            // Overlay the watermark on the original image
159
            $img->compositeImage($watermark, imagick::COMPOSITE_OVER, $dest_x, $dest_y);
160
161
            // Set quality
162
            if (strtoupper($img->getImageFormat()) === 'JPEG') {
163
                $img->setImageCompression(imagick::COMPRESSION_JPEG);
164
                $img->setCompressionQuality($quality);
165
            }
166
167
            $result = $img->writeImage($src);
168
169
            $img->clear();
170
            $img->destroy();
171
            $watermark->clear();
172
            $watermark->destroy();
173
174
            return $result ? true : false;
175
        } catch (Exception $e) {
176
            return false;
177
        }
178
    }
179
180
    private function watermarkPrint_gd($src, $watermark, $dest_x, $dest_y, $quality, $transparency, $watermarkImgInfo, $srcImgInfo) {
181
182
        $watermark_width = $watermarkImgInfo[0];
183
        $watermark_height = $watermarkImgInfo[1];
184
185
        $ermsg = '';
186
        switch ($watermarkImgInfo['mime']) {
187
            case 'image/gif':
188
                if (imagetypes() & IMG_GIF) {
189
                    $oWatermarkImg = imagecreatefromgif($watermark);
190
                } else {
191
                    $ermsg = 'GIF images are not supported';
192
                }
193
                break;
194
            case 'image/jpeg':
195
                if (imagetypes() & IMG_JPG) {
196
                    $oWatermarkImg = imagecreatefromjpeg($watermark) ;
197
                } else {
198
                    $ermsg = 'JPEG images are not supported';
199
                }
200
                break;
201
            case 'image/png':
202
                if (imagetypes() & IMG_PNG) {
203
                    $oWatermarkImg = imagecreatefrompng($watermark) ;
204
                } else {
205
                    $ermsg = 'PNG images are not supported';
206
                }
207
                break;
208
            case 'image/wbmp':
209
                if (imagetypes() & IMG_WBMP) {
210
                    $oWatermarkImg = imagecreatefromwbmp($watermark);
211
                } else {
212
                    $ermsg = 'WBMP images are not supported';
213
                }
214
                break;
215
            default:
216
                $oWatermarkImg = false;
217
                $ermsg = $watermarkImgInfo['mime'].' images are not supported';
218
                break;
219
        }
220
221
        if (! $ermsg) {
222
            switch ($srcImgInfo['mime']) {
223
                case 'image/gif':
224
                    if (imagetypes() & IMG_GIF) {
225
                        $oSrcImg = imagecreatefromgif($src);
226
                    } else {
227
                        $ermsg = 'GIF images are not supported';
228
                    }
229
                    break;
230
                case 'image/jpeg':
231
                    if (imagetypes() & IMG_JPG) {
232
                        $oSrcImg = imagecreatefromjpeg($src) ;
233
                    } else {
234
                        $ermsg = 'JPEG images are not supported';
235
                    }
236
                    break;
237
                case 'image/png':
238
                    if (imagetypes() & IMG_PNG) {
239
                        $oSrcImg = imagecreatefrompng($src) ;
240
                    } else {
241
                        $ermsg = 'PNG images are not supported';
242
                    }
243
                    break;
244
                case 'image/wbmp':
245
                    if (imagetypes() & IMG_WBMP) {
246
                        $oSrcImg = imagecreatefromwbmp($src);
247
                    } else {
248
                        $ermsg = 'WBMP images are not supported';
249
                    }
250
                    break;
251
                default:
252
                    $oSrcImg = false;
253
                    $ermsg = $srcImgInfo['mime'].' images are not supported';
254
                    break;
255
            }
256
        }
257
258
        if ($ermsg || false === $oSrcImg || false === $oWatermarkImg) {
0 ignored issues
show
Bug introduced by
The variable $oSrcImg 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...
Bug introduced by
The variable $oWatermarkImg 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...
259
            return false;
260
        }
261
262
        if ($srcImgInfo['mime'] === 'image/png') {
263
            if (function_exists('imagecolorallocatealpha')) {
264
                $bg = imagecolorallocatealpha($oSrcImg, 255, 255, 255, 127);
265
                imagefill($oSrcImg, 0, 0 , $bg);
266
            }
267
        }
268
269
        if ($watermarkImgInfo['mime'] === 'image/png') {
270
            imagecopy($oSrcImg, $oWatermarkImg, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height);
271
        } else {
272
            imagecopymerge($oSrcImg, $oWatermarkImg, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height, $transparency);
273
        }
274
275
        switch ($srcImgInfo['mime']) {
276
            case 'image/gif':
277
                imagegif($oSrcImg, $src);
278
                break;
279
            case 'image/jpeg':
280
                imagejpeg($oSrcImg, $src, $quality);
281
                break;
282
            case 'image/png':
283
                if (function_exists('imagesavealpha') && function_exists('imagealphablending')) {
284
                    imagealphablending($oSrcImg, false);
285
                    imagesavealpha($oSrcImg, true);
286
                }
287
                imagepng($oSrcImg, $src);
288
                break;
289
            case 'image/wbmp':
290
                imagewbmp($oSrcImg, $src);
291
                break;
292
        }
293
294
        imageDestroy($oSrcImg);
295
        imageDestroy($oWatermarkImg);
296
297
        return true;
298
    }
299
}
300