ExtendedFileManager   F
last analyzed

Complexity

Total Complexity 127

Size/Duplication

Total Lines 765
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 290
c 1
b 0
f 0
dl 0
loc 765
rs 2
wmc 127

32 Methods

Rating   Name   Duplication   Size   Complexity  
A getThumbURL() 0 18 5
A processPaste() 0 25 5
A getFullPath() 0 3 1
B _processFiles() 0 43 10
A __construct() 0 5 3
A processNewDir() 0 16 5
A getDiskInfo() 0 13 4
A isThumb() 0 7 2
A isThumbDir() 0 7 3
B countFiles() 0 19 7
A isValidBase() 0 3 1
A getImagesDir() 0 6 3
A isTmpFile() 0 7 2
A getDefaultThumb() 0 6 2
A _dirs() 0 26 6
A getFileURL() 0 3 1
A getDirs() 0 8 2
A processRenames() 0 30 5
C getFiles() 0 50 12
A getThumbName() 0 18 5
A _delFile() 0 19 4
A getImageInfo() 0 3 1
A processUploads() 0 17 5
A checkImageSize() 0 25 5
A deleteFiles() 0 6 2
A getImagesURL() 0 6 3
A validRelativePath() 0 18 4
A getTmpPrefix() 0 3 1
B getThumbnail() 0 53 10
A deleteDirs() 0 6 2
A _delDir() 0 5 1
A getResizedName() 0 14 5

How to fix   Complexity   

Complex Class

Complex classes like ExtendedFileManager 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 ExtendedFileManager, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * ExtendedFileManager, list images, directories, and thumbnails.
4
 * Authors: Wei Zhuo, Afru, Krzysztof Kotowicz, Raimund Meyer
5
 * Version: Updated on 08-01-2005 by Afru
6
 * Version: Updated on 04-07-2006 by Krzysztof Kotowicz
7
 * Version: Updated on 29-10-2006 by Raimund Meyer
8
 * Package: ExtendedFileManager (EFM 1.1.3)
9
 * http://www.afrusoft.com/htmlarea
10
 */
11
12
/**
13
 * We use classes from ImageManager to avoid code duplication
14
 */
15
require_once '../ImageManager/Classes/Files.php';
16
17
/**
18
 * ExtendedFileManager Class.
19
 * @author  Wei Zhuo, Afru, Krzysztof Kotowicz, Raimund Meyer
20
 * @version $Id: ExtendedFileManager.php 1171 2009-03-19 22:06:09Z ray $
21
 */
22
class ExtendedFileManager
23
{
24
    /**
25
     * Configuration array.
26
     */
27
    public $config;
28
29
    /**
30
     * Array of directory information.
31
     */
32
    public $dirs;
33
34
    /**
35
     * Manager mode - image | link
36
     */
37
    public $mode;
38
39
    /**
40
     * Constructor. Create a new Image Manager instance.
41
     * @param array $config configuration array, see config.inc.php
42
     */
43
    public function __construct($config, $mode = null)
44
    {
45
        $this->config = $config;
46
47
        $this->mode = empty($mode) ? (empty($config['insert_mode']) ? 'image' : $config['insert_mode']) : $mode;
48
    }
49
50
    /**
51
     * Get the base directory.
52
     * @return string base dir, see config.inc.php
53
     */
54
    public function getImagesDir()
55
    {
56
        if ('link' == $this->mode && isset($this->config['files_dir'])) {
57
            Return $this->config['files_dir'];
58
        } else {
59
            Return $this->config['images_dir'];
60
        }
61
    }
62
63
    /**
64
     * Get the base URL.
65
     * @return string base url, see config.inc.php
66
     */
67
    public function getImagesURL()
68
    {
69
        if ('link' == $this->mode && isset($this->config['files_url'])) {
70
            Return $this->config['files_url'];
71
        } else {
72
            Return $this->config['images_url'];
73
        }
74
    }
75
76
    public function isValidBase()
77
    {
78
        return is_dir($this->getImagesDir());
79
    }
80
81
    /**
82
     * Get the tmp file prefix.
83
     * @return string tmp file prefix.
84
     */
85
    public function getTmpPrefix()
86
    {
87
        Return $this->config['tmp_prefix'];
88
    }
89
90
    /**
91
     * Get the sub directories in the base dir.
92
     * Each array element contain
93
     * the relative path (relative to the base dir) as key and the
94
     * full path as value.
95
     * @return array of sub directries
96
     * <code>array('path name' => 'full directory path', ...)</code>
97
     */
98
    public function getDirs()
99
    {
100
        if (is_null($this->dirs)) {
101
            $dirs = $this->_dirs($this->getImagesDir(), '/');
102
            ksort($dirs);
103
            $this->dirs = $dirs;
104
        }
105
        return $this->dirs;
106
    }
107
108
    /**
109
     * Recursively travese the directories to get a list
110
     * of accessable directories.
111
     * @param string $base the full path to the current directory
112
     * @param string $path the relative path name
113
     * @return array of accessiable sub-directories
114
     *                     <code>array('path name' => 'full directory path', ...)</code>
115
     */
116
    public function _dirs($base, $path)
117
    {
118
        $base = Files::fixPath($base);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::fixPath() is not static, but was called statically. ( Ignorable by Annotation )

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

118
        /** @scrutinizer ignore-call */ 
119
        $base = Files::fixPath($base);
Loading history...
119
        $dirs = [];
120
121
        if (false == $this->isValidBase()) {
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...
122
            return $dirs;
123
        }
124
125
        $d = @dir($base);
126
127
        while (false !== ($entry = $d->read())) {
128
            //If it is a directory, and it doesn't start with
129
            // a dot, and if is it not the thumbnail directory
130
            if (is_dir($base . $entry)
131
                && '.' != substr($entry, 0, 1)
132
                && false == $this->isThumbDir($entry)) {
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...
133
                $relative        = Files::fixPath($path . $entry);
134
                $fullpath        = Files::fixPath($base . $entry);
135
                $dirs[$relative] = $fullpath;
136
                $dirs            = array_merge($dirs, $this->_dirs($fullpath, $relative));
137
            }
138
        }
139
        $d->close();
140
141
        Return $dirs;
142
    }
143
144
    /**
145
     * Get all the files and directories of a relative path.
146
     * @param string $path    relative path to be base path.
147
     * @return array of file and path information.
148
     *                        <code>array(0=>array('relative'=>'fullpath',...), 1=>array('filename'=>fileinfo array(),...)</code>
149
     *                        fileinfo array: <code>array('url'=>'full url',
150
     *                        'relative'=>'relative to base',
151
     *                        'fullpath'=>'full file path',
152
     *                        'image'=>imageInfo array() false if not image,
153
     *                        'stat' => filestat)</code>
154
     */
155
    public function getFiles($path)
156
    {
157
        $files = [];
158
        $dirs  = [];
159
160
        $valid_extensions = 'image' == $this->mode ? $this->config['allowed_image_extensions'] : $this->config['allowed_link_extensions'];
161
162
        if (false == $this->isValidBase()) {
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...
163
            return [$files, $dirs];
164
        }
165
166
        $path     = Files::fixPath($path);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::fixPath() is not static, but was called statically. ( Ignorable by Annotation )

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

166
        /** @scrutinizer ignore-call */ 
167
        $path     = Files::fixPath($path);
Loading history...
167
        $base     = Files::fixPath($this->getImagesDir());
168
        $fullpath = Files::makePath($base, $path);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::makePath() is not static, but was called statically. ( Ignorable by Annotation )

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

168
        /** @scrutinizer ignore-call */ 
169
        $fullpath = Files::makePath($base, $path);
Loading history...
169
170
        $d = @dir($fullpath);
171
172
        while (false !== ($entry = $d->read())) {
173
            //not a dot file or directory
174
            if ('.' != substr($entry, 0, 1)) {
175
                if (is_dir($fullpath . $entry)
176
                    && false == $this->isThumbDir($entry)) {
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...
177
                    $relative        = Files::fixPath($path . $entry);
178
                    $full            = Files::fixPath($fullpath . $entry);
179
                    $count           = $this->countFiles($full);
180
                    $dirs[$relative] = ['fullpath' => $full, 'entry' => $entry, 'count' => $count, 'stat' => stat($fullpath . $entry)];
181
                } elseif (is_file($fullpath . $entry) && false == $this->isThumb($entry) && false == $this->isTmpFile($entry)) {
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...
182
                    $afruext = strtolower(substr(strrchr($entry, '.'), 1));
183
184
                    if (in_array($afruext, $valid_extensions)) {
185
                        $file['url']      = Files::makePath($this->config['base_url'], $path) . $entry;
186
                        $file['relative'] = $path . $entry;
187
                        $file['fullpath'] = $fullpath . $entry;
188
                        $img              = $this->getImageInfo($fullpath . $entry);
189
                        if (!is_array($img)) {
190
                            $img[0] = $img[1] = 0;
191
                        }
192
                        $file['image'] = $img;
193
                        $file['stat']  = stat($fullpath . $entry);
194
                        $file['ext']   = $afruext;
195
                        $files[$entry] = $file;
196
                    }
197
                }
198
            }
199
        }
200
        $d->close();
201
        ksort($dirs);
202
        ksort($files);
203
204
        Return [$dirs, $files];
205
    }
206
207
    /**
208
     * Count the number of files and directories in a given folder
209
     * minus the thumbnail folders and thumbnails.
210
     */
211
    public function countFiles($path)
212
    {
213
        $total = 0;
214
215
        if (is_dir($path)) {
216
            $d = @dir($path);
217
218
            while (false !== ($entry = $d->read())) {
219
                //echo $entry."<br>";
220
                if ('.' != substr($entry, 0, 1)
221
                    && false == $this->isThumbDir($entry)
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...
222
                    && false == $this->isTmpFile($entry)
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...
223
                    && false == $this->isThumb($entry)) {
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...
224
                    $total++;
225
                }
226
            }
227
            $d->close();
228
        }
229
        return $total;
230
    }
231
232
    /**
233
     * Get image size information.
234
     * @param string $file the image file
235
     * @return array of getImageSize information,
236
     *                     false if the file is not an image.
237
     */
238
    public function getImageInfo($file)
239
    {
240
        Return @getImageSize($file);
0 ignored issues
show
Bug Best Practice introduced by
The expression return @getImageSize($file) could also return false which is incompatible with the documented return type array. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
241
    }
242
243
    /**
244
     * Check if the file contains the thumbnail prefix.
245
     * @param string $file filename to be checked
246
     * @return true if the file contains the thumbnail prefix, false otherwise.
247
     */
248
    public function isThumb($file)
249
    {
250
        $len = strlen($this->config['thumbnail_prefix']);
251
        if (substr($file, 0, $len) == $this->config['thumbnail_prefix']) {
252
            Return true;
253
        } else {
254
            Return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type true.
Loading history...
255
        }
256
    }
257
258
    /**
259
     * Check if the given directory is a thumbnail directory.
260
     * @param string $entry directory name
261
     * @return true if it is a thumbnail directory, false otherwise
262
     */
263
    public function isThumbDir($entry)
264
    {
265
        if (false == $this->config['thumbnail_dir']
266
            || 0 == strlen(trim($this->config['thumbnail_dir']))) {
267
            Return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type true.
Loading history...
268
        } else {
269
            Return ($entry == $this->config['thumbnail_dir']);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $entry == $this->config['thumbnail_dir'] returns the type boolean which is incompatible with the documented return type true.
Loading history...
270
        }
271
    }
272
273
    /**
274
     * Check if the given file is a tmp file.
275
     * @param string $file file name
276
     * @return bool true if it is a tmp file, false otherwise
277
     */
278
    public function isTmpFile($file)
279
    {
280
        $len = strlen($this->config['tmp_prefix']);
281
        if (substr($file, 0, $len) == $this->config['tmp_prefix']) {
282
            Return true;
283
        } else {
284
            Return false;
285
        }
286
    }
287
288
    /**
289
     * For a given image file, get the respective thumbnail filename
290
     * no file existence check is done.
291
     * @param string $fullpathfile the full path to the image file
292
     * @return string of the thumbnail file
293
     */
294
    public function getThumbName($fullpathfile)
295
    {
296
        $path_parts = pathinfo($fullpathfile);
297
298
        $thumbnail = $this->config['thumbnail_prefix'] . $path_parts['basename'];
299
300
        if (true == $this->config['safe_mode']
301
            || 0 == strlen(trim($this->config['thumbnail_dir']))) {
302
            Return Files::makeFile($path_parts['dirname'], $thumbnail);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::makeFile() is not static, but was called statically. ( Ignorable by Annotation )

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

302
            Return Files::/** @scrutinizer ignore-call */ makeFile($path_parts['dirname'], $thumbnail);
Loading history...
303
        } else {
304
            if (strlen(trim($this->config['thumbnail_dir'])) > 0) {
305
                $path = Files::makePath($path_parts['dirname'], $this->config['thumbnail_dir']);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::makePath() is not static, but was called statically. ( Ignorable by Annotation )

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

305
                /** @scrutinizer ignore-call */ 
306
                $path = Files::makePath($path_parts['dirname'], $this->config['thumbnail_dir']);
Loading history...
306
                if (!is_dir($path)) {
307
                    Files::createFolder($path);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::createFolder() is not static, but was called statically. ( Ignorable by Annotation )

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

307
                    Files::/** @scrutinizer ignore-call */ 
308
                           createFolder($path);
Loading history...
308
                }
309
                Return Files::makeFile($path, $thumbnail);
310
            } else //should this ever happen?
311
            {
312
                //error_log('ExtendedFileManager: Error in creating thumbnail name');
313
            }
314
        }
315
    }
316
317
    /**
318
     * Similar to getThumbName, but returns the URL, base on the
319
     * given base_url in config.inc.php
320
     * @param string $relative the relative image file name,
321
     *                         relative to the base_dir path
322
     * @return string the url of the thumbnail
323
     */
324
    public function getThumbURL($relative)
325
    {
326
        $path_parts = pathinfo($relative);
327
        $thumbnail  = $this->config['thumbnail_prefix'] . $path_parts['basename'];
328
        if ('\\' == $path_parts['dirname']) {
329
            $path_parts['dirname'] = '/';
330
        }
331
332
        if (true == $this->config['safe_mode']
333
            || 0 == strlen(trim($this->config['thumbnail_dir']))) {
334
            Return Files::makeFile($this->getImagesURL(), $thumbnail);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::makeFile() is not static, but was called statically. ( Ignorable by Annotation )

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

334
            Return Files::/** @scrutinizer ignore-call */ makeFile($this->getImagesURL(), $thumbnail);
Loading history...
335
        } else {
336
            if (strlen(trim($this->config['thumbnail_dir'])) > 0) {
337
                $path     = Files::makePath($path_parts['dirname'], $this->config['thumbnail_dir']);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::makePath() is not static, but was called statically. ( Ignorable by Annotation )

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

337
                /** @scrutinizer ignore-call */ 
338
                $path     = Files::makePath($path_parts['dirname'], $this->config['thumbnail_dir']);
Loading history...
338
                $url_path = Files::makePath($this->getImagesURL(), $path);
339
                Return Files::makeFile($url_path, $thumbnail);
340
            } else //should this ever happen?
341
            {
342
                //error_log('ExtendedFileManager: Error in creating thumbnail url');
343
            }
344
        }
345
    }
346
347
    /**
348
     * For a given image file, get the respective resized filename
349
     * no file existence check is done.
350
     * @param string $fullpathfile the full path to the image file
351
     * @param int    $width        the intended width
352
     * @param int    $height       the intended height
353
     * @param bool   $mkDir        whether to attempt to make the resized_dir if it doesn't exist
354
     * @return string of the resized filename
355
     */
356
    public function getResizedName($fullpathfile, $width, $height, $mkDir = true)
357
    {
358
        $path_parts = pathinfo($fullpathfile);
359
360
        $thumbnail = $this->config['resized_prefix'] . "_{$width}x{$height}_{$path_parts['basename']}";
361
362
        if (0 == strlen(trim($this->config['resized_dir'])) || true == $this->config['safe_mode']) {
363
            Return Files::makeFile($path_parts['dirname'], $thumbnail);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::makeFile() is not static, but was called statically. ( Ignorable by Annotation )

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

363
            Return Files::/** @scrutinizer ignore-call */ makeFile($path_parts['dirname'], $thumbnail);
Loading history...
364
        } else {
365
            $path = Files::makePath($path_parts['dirname'], $this->config['resized_dir']);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::makePath() is not static, but was called statically. ( Ignorable by Annotation )

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

365
            /** @scrutinizer ignore-call */ 
366
            $path = Files::makePath($path_parts['dirname'], $this->config['resized_dir']);
Loading history...
366
            if ($mkDir && !is_dir($path)) {
367
                Files::createFolder($path);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::createFolder() is not static, but was called statically. ( Ignorable by Annotation )

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

367
                Files::/** @scrutinizer ignore-call */ 
368
                       createFolder($path);
Loading history...
368
            }
369
            Return Files::makeFile($path, $thumbnail);
370
        }
371
    }
372
373
    /**
374
     * Check if the given path is part of the subdirectories
375
     * under the base_dir.
376
     * @param string $path the relative path to be checked
377
     * @return bool true if the path exists, false otherwise
378
     */
379
    public function validRelativePath($path)
380
    {
381
        $dirs = $this->getDirs();
382
        if ('/' == $path) {
383
            Return true;
384
        }
385
        //check the path given in the url against the
386
        //list of paths in the system.
387
        for ($i = 0; $i < count($dirs); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
388
            $key = key($dirs);
389
            //we found the path
390
            if ($key == $path) {
391
                Return true;
392
            }
393
394
            next($dirs);
395
        }
396
        Return false;
397
    }
398
399
    /**
400
     * Process uploaded files, assumes the file is in
401
     * $_FILES['upload'] and $_POST['dir'] is set.
402
     * The dir must be relative to the base_dir and exists.
403
     * @return null
404
     */
405
    public function processUploads()
406
    {
407
        if (false == $this->isValidBase()) {
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...
408
            return;
409
        }
410
411
        $relative = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $relative is dead and can be removed.
Loading history...
412
413
        if (isset($_POST['dir'])) {
414
            $relative = rawurldecode($_POST['dir']);
415
        } else {
416
            return;
417
        }
418
419
        //check for the file, and must have valid relative path
420
        if (isset($_FILES['upload']) && $this->validRelativePath($relative)) {
421
            Return $this->_processFiles($relative, $_FILES['upload']);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->_processFi...ive, $_FILES['upload']) returns the type boolean which is incompatible with the documented return type null.
Loading history...
422
        }
423
    }
424
425
    /**
426
     * Process upload files. The file must be an
427
     * uploaded file. Any duplicate
428
     * file will be renamed. See Files::copyFile for details
429
     * on renaming.
430
     * @param string $relative the relative path where the file
431
     *                         should be copied to.
432
     * @param array  $file     the uploaded file from $_FILES
433
     * @return bool true if the file was processed successfully,
434
     *                         false otherwise
435
     */
436
    public function _processFiles($relative, $file)
437
    {
438
        if (0 != $file['error']) {
439
            Return false;
440
        }
441
442
        if (!is_uploaded_file($file['tmp_name'])) {
443
            Files::delFile($file['tmp_name']);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::delFile() is not static, but was called statically. ( Ignorable by Annotation )

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

443
            Files::/** @scrutinizer ignore-call */ 
444
                   delFile($file['tmp_name']);
Loading history...
444
            Return false;
445
        }
446
447
        $valid_extensions = 'image' == $this->mode ? $this->config['allowed_image_extensions'] : $this->config['allowed_link_extensions'];
448
        $max_size         = 'image' == $this->mode ? $this->config['max_filesize_kb_image'] : $this->config['max_filesize_kb_link'];
449
        $afruext          = strtolower(substr(strrchr($file['name'], '.'), 1));
450
451
        if (!in_array($afruext, $valid_extensions)) {
452
            Files::delFile($file['tmp_name']);
453
            Return 'Cannot upload $extension=' . $afruext . '$ Files. Permission denied.';
0 ignored issues
show
Bug Best Practice introduced by
The expression return 'Cannot upload $e...es. Permission denied.' returns the type string which is incompatible with the documented return type boolean.
Loading history...
454
        }
455
456
        if ($file['size'] > ($max_size * 1024)) {
457
            Files::delFile($file['tmp_name']);
458
            Return 'Unble to upload file. Maximum file size [$max_size=' . $max_size . '$ KB] exceeded.';
0 ignored issues
show
Bug Best Practice introduced by
The expression return 'Unble to upload ...ize . '$ KB] exceeded.' returns the type string which is incompatible with the documented return type boolean.
Loading history...
459
        }
460
461
        if (!empty($this->config['max_foldersize_mb']) && (Files::dirSize($this->getImagesDir())) + $file['size'] > ($this->config['max_foldersize_mb'] * 1048576)) {
0 ignored issues
show
Bug Best Practice introduced by
The method Files::dirSize() is not static, but was called statically. ( Ignorable by Annotation )

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

461
        if (!empty($this->config['max_foldersize_mb']) && (Files::/** @scrutinizer ignore-call */ dirSize($this->getImagesDir())) + $file['size'] > ($this->config['max_foldersize_mb'] * 1048576)) {
Loading history...
462
            Files::delFile($file['tmp_name']);
463
            Return ('Cannot upload. Maximum folder size reached. Delete unwanted files and try again.');
0 ignored issues
show
Bug Best Practice introduced by
The expression return 'Cannot upload. M...d files and try again.' returns the type string which is incompatible with the documented return type boolean.
Loading history...
464
        }
465
466
        //now copy the file
467
        $path   = Files::makePath($this->getImagesDir(), $relative);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::makePath() is not static, but was called statically. ( Ignorable by Annotation )

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

467
        /** @scrutinizer ignore-call */ 
468
        $path   = Files::makePath($this->getImagesDir(), $relative);
Loading history...
468
        $result = Files::copyFile($file['tmp_name'], $path, $file['name']);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::copyFile() is not static, but was called statically. ( Ignorable by Annotation )

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

468
        /** @scrutinizer ignore-call */ 
469
        $result = Files::copyFile($file['tmp_name'], $path, $file['name']);
Loading history...
469
470
        //no copy error
471
        if (!is_int($result)) {
0 ignored issues
show
introduced by
The condition is_int($result) is always false.
Loading history...
472
            Files::delFile($file['tmp_name']);
473
            Return 'File "$file=' . $file['name'] . '$" successfully uploaded.';
0 ignored issues
show
Bug Best Practice introduced by
The expression return 'File "$file=' . ...successfully uploaded.' returns the type string which is incompatible with the documented return type boolean.
Loading history...
474
        }
475
476
        //delete tmp files.
477
        Files::delFile($file['tmp_name']);
478
        Return false;
479
    }
480
481
    public function getDiskInfo()
482
    {
483
        if (empty($this->config['max_foldersize_mb'])) {
484
            return '';
485
        }
486
487
        $tmpFreeSize = ($this->config['max_foldersize_mb'] * 1048576) - Files::dirSize($this->getImagesDir());
0 ignored issues
show
Bug Best Practice introduced by
The method Files::dirSize() is not static, but was called statically. ( Ignorable by Annotation )

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

487
        $tmpFreeSize = ($this->config['max_foldersize_mb'] * 1048576) - Files::/** @scrutinizer ignore-call */ dirSize($this->getImagesDir());
Loading history...
488
489
        if (!is_numeric($tmpFreeSize) || $tmpFreeSize < 0) {
0 ignored issues
show
introduced by
The condition is_numeric($tmpFreeSize) is always true.
Loading history...
490
            $tmpFreeSize = 0;
491
        }
492
493
        Return 'Total Size : $max_foldersize_mb=' . $this->config['max_foldersize_mb'] . '$ MB, Free Space: $free_space=' . Files::formatSize($tmpFreeSize) . '$';
0 ignored issues
show
Bug Best Practice introduced by
The method Files::formatSize() is not static, but was called statically. ( Ignorable by Annotation )

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

493
        Return 'Total Size : $max_foldersize_mb=' . $this->config['max_foldersize_mb'] . '$ MB, Free Space: $free_space=' . Files::/** @scrutinizer ignore-call */ formatSize($tmpFreeSize) . '$';
Loading history...
494
    }
495
496
    /**
497
     * Get the URL of the relative file.
498
     * basically appends the relative file to the
499
     * base_url given in config.inc.php
500
     * @param string $relative a file the relative to the base_dir
501
     * @return string the URL of the relative file.
502
     */
503
    public function getFileURL($relative)
504
    {
505
        Return Files::makeFile($this->getImagesURL(), $relative);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::makeFile() is not static, but was called statically. ( Ignorable by Annotation )

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

505
        Return Files::/** @scrutinizer ignore-call */ makeFile($this->getImagesURL(), $relative);
Loading history...
506
    }
507
508
    /**
509
     * Get the fullpath to a relative file.
510
     * @param string $relative the relative file.
511
     * @return string the full path, .ie. the base_dir + relative.
512
     */
513
    public function getFullPath($relative)
514
    {
515
        Return Files::makeFile($this->getImagesDir(), $relative);;
0 ignored issues
show
Bug Best Practice introduced by
The method Files::makeFile() is not static, but was called statically. ( Ignorable by Annotation )

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

515
        Return Files::/** @scrutinizer ignore-call */ makeFile($this->getImagesDir(), $relative);;
Loading history...
516
    }
517
518
    /**
519
     * Get the default thumbnail.
520
     * @return string default thumbnail, empty string if
521
     * the thumbnail doesn't exist.
522
     */
523
    public function getDefaultThumb()
524
    {
525
        if (is_file($this->config['default_thumbnail'])) {
526
            Return $this->config['default_thumbnail'];
527
        } else {
528
            Return '';
529
        }
530
    }
531
532
    /**
533
     * Checks image size. If the image size is less than default size
534
     * returns the original size else returns default size to display thumbnail
535
     */
536
    public function checkImageSize($relative)
537
    {
538
        $fullpath = Files::makeFile($this->getImagesDir(), $relative);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::makeFile() is not static, but was called statically. ( Ignorable by Annotation )

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

538
        /** @scrutinizer ignore-call */ 
539
        $fullpath = Files::makeFile($this->getImagesDir(), $relative);
Loading history...
539
540
        $afruext = strtolower(substr(strrchr($relative, '.'), 1));
541
542
        if (!in_array($afruext, $this->config['thumbnail_extensions'])) {
543
            $imgInfo = [0, 0];
544
            Return $imgInfo;
545
        } else {
546
            $imgInfo = @getImageSize($fullpath);
547
            //not an image
548
            if (!is_array($imgInfo)) {
549
                $imgInfo = [0, 0];
550
                Return $imgInfo;
551
            } else {
552
                if ($imgInfo[0] > $this->config['thumbnail_width']) {
553
                    $imgInfo[0] = $this->config['thumbnail_width'];
554
                }
555
556
                if ($imgInfo[1] > $this->config['thumbnail_height']) {
557
                    $imgInfo[1] = $this->config['thumbnail_height'];
558
                }
559
560
                Return $imgInfo;
561
            }
562
        }
563
    }
564
565
    /**
566
     * Get the thumbnail url to be displayed.
567
     * If the thumbnail exists, and it is up-to-date
568
     * the thumbnail url will be returns. If the
569
     * file is not an image, a default image will be returned.
570
     * If it is an image file, and no thumbnail exists or
571
     * the thumbnail is out-of-date (i.e. the thumbnail
572
     * modified time is less than the original file)
573
     * then a thumbs.php?img=filename.jpg is returned.
574
     * The thumbs.php url will generate a new thumbnail
575
     * on the fly. If the image is less than the dimensions
576
     * of the thumbnails, the image will be display instead.
577
     * @param string $relative the relative image file.
578
     * @return string the url of the thumbnail, be it
579
     *                         actually thumbnail or a script to generate the
580
     *                         thumbnail on the fly.
581
     */
582
    public function getThumbnail($relative)
583
    {
584
        global $IMConfig;
585
586
        $fullpath = Files::makeFile($this->getImagesDir(), $relative);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::makeFile() is not static, but was called statically. ( Ignorable by Annotation )

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

586
        /** @scrutinizer ignore-call */ 
587
        $fullpath = Files::makeFile($this->getImagesDir(), $relative);
Loading history...
587
588
        //not a file???
589
        if (!is_file($fullpath)) {
590
            Return $this->getDefaultThumb();
591
        }
592
593
        $afruext = strtolower(substr(strrchr($relative, '.'), 1));
594
595
        if (!in_array($afruext, $this->config['thumbnail_extensions'])) {
596
            if (is_file('icons/' . $afruext . '.gif')) {
597
                Return ('icons/' . $afruext . '.gif');
598
            } else {
599
                Return $this->getDefaultThumb();
600
            }
601
        }
602
603
        $imgInfo = @getImageSize($fullpath);
604
605
        //not an image
606
        if (!is_array($imgInfo)) {
607
            Return $this->getDefaultThumb();
608
        }
609
610
        //Returning original image as thumbnail without Image Library by Afru
611
        if (!$this->config['img_library']) {
612
            Return $this->getFileURL($relative);
613
        }
614
615
        //the original image is smaller than thumbnails,
616
        //so just return the url to the original image.
617
        if ($imgInfo[0] <= $this->config['thumbnail_width']
618
            && $imgInfo[1] <= $this->config['thumbnail_height']) {
619
            Return $this->getFileURL($relative);
620
        }
621
622
        $thumbnail = $this->getThumbName($fullpath);
623
624
        //check for thumbnails, if exists and
625
        // it is up-to-date, return the thumbnail url
626
        if (is_file($thumbnail)) {
627
            if (filemtime($thumbnail) >= filemtime($fullpath)) {
628
                Return $this->getThumbURL($relative);
629
            }
630
        }
631
632
        //well, no thumbnail was found, so ask the thumbs.php
633
        //to generate the thumbnail on the fly.
634
        Return $IMConfig['backend_url'] . '__function=thumbs&img=' . rawurlencode($relative) . "&mode=$this->mode";
635
    }
636
637
    /**
638
     * Delete and specified files.
639
     * @return bool true if delete, false otherwise
640
     */
641
    public function deleteFiles()
642
    {
643
        if (isset($_GET['delf'])) {
644
            return $this->_delFile(rawurldecode($_GET['delf']));
645
        }
646
        return false;
647
    }
648
649
    /**
650
     * Delete and specified directories.
651
     * @return bool true if delete, false otherwise
652
     */
653
    public function deleteDirs()
654
    {
655
        if (isset($_GET['deld'])) {
656
            return $this->_delDir(rawurldecode($_GET['deld']));
657
        } else {
658
            Return false;
659
        }
660
    }
661
662
    /**
663
     * Delete the relative file, and any thumbnails.
664
     * @param string $relative the relative file.
665
     * @return bool true if deleted, false otherwise.
666
     */
667
    public function _delFile($relative)
668
    {
669
        $fullpath = Files::makeFile($this->getImagesDir(), $relative);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::makeFile() is not static, but was called statically. ( Ignorable by Annotation )

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

669
        /** @scrutinizer ignore-call */ 
670
        $fullpath = Files::makeFile($this->getImagesDir(), $relative);
Loading history...
670
671
        $afruext = strtolower(substr(strrchr($relative, '.'), 1));
672
673
        $valid_extensions = 'image' == $this->mode ? $this->config['allowed_image_extensions'] : $this->config['allowed_link_extensions'];
674
675
        if (!in_array($afruext, $valid_extensions)) {
676
            return false;
677
        }
678
679
        //check that the file is an image
680
        if (is_array($this->getImageInfo($fullpath))) {
0 ignored issues
show
introduced by
The condition is_array($this->getImageInfo($fullpath)) is always true.
Loading history...
681
            $thumbnail = $this->getThumbName($fullpath);
682
            Files::delFile($thumbnail);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::delFile() is not static, but was called statically. ( Ignorable by Annotation )

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

682
            Files::/** @scrutinizer ignore-call */ 
683
                   delFile($thumbnail);
Loading history...
683
        }
684
685
        Return Files::delFile($fullpath);
686
    }
687
688
    /**
689
     * Delete directories recursively.
690
     * @param string $relative the relative path to be deleted.
691
     * @return bool true if deleted, false otherwise.
692
     */
693
    public function _delDir($relative)
694
    {
695
        $fullpath = Files::makePath($this->getImagesDir(), $relative);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::makePath() is not static, but was called statically. ( Ignorable by Annotation )

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

695
        /** @scrutinizer ignore-call */ 
696
        $fullpath = Files::makePath($this->getImagesDir(), $relative);
Loading history...
696
        //	if($this->countFiles($fullpath) <= 0)
697
        return Files::delFolder($fullpath, true); //delete recursively.
0 ignored issues
show
Bug Best Practice introduced by
The method Files::delFolder() is not static, but was called statically. ( Ignorable by Annotation )

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

697
        return Files::/** @scrutinizer ignore-call */ delFolder($fullpath, true); //delete recursively.
Loading history...
698
        //else
699
        //Return false;
700
    }
701
702
    /**
703
     * Create new directories.
704
     * If in safe_mode, nothing happens.
705
     * @return bool true if created, false otherwise.
706
     */
707
    public function processNewDir()
708
    {
709
        if (true == $this->config['safe_mode']) {
710
            Return false;
711
        }
712
713
        if (isset($_GET['newDir']) && isset($_GET['dir'])) {
714
            $newDir   = rawurldecode($_GET['newDir']);
715
            $dir      = rawurldecode($_GET['dir']);
716
            $path     = Files::makePath($this->getImagesDir(), $dir);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::makePath() is not static, but was called statically. ( Ignorable by Annotation )

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

716
            /** @scrutinizer ignore-call */ 
717
            $path     = Files::makePath($this->getImagesDir(), $dir);
Loading history...
717
            $fullpath = Files::makePath($path, Files::escape($newDir));
0 ignored issues
show
Bug Best Practice introduced by
The method Files::escape() is not static, but was called statically. ( Ignorable by Annotation )

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

717
            $fullpath = Files::makePath($path, Files::/** @scrutinizer ignore-call */ escape($newDir));
Loading history...
718
            if (is_dir($fullpath)) {
719
                Return false;
720
            }
721
722
            Return Files::createFolder($fullpath);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::createFolder() is not static, but was called statically. ( Ignorable by Annotation )

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

722
            Return Files::/** @scrutinizer ignore-call */ createFolder($fullpath);
Loading history...
723
        }
724
    }
725
726
    /**
727
     * Renames files if certain GET variables are set
728
     * @return bool
729
     */
730
    public function processRenames()
731
    {
732
        if (!empty($_GET['rename']) && !empty($_GET['renameTo'])) {
733
            // new file name (without path and extension)
734
            $newName = Files::escape(rawurldecode($_GET['renameTo']));
0 ignored issues
show
Bug Best Practice introduced by
The method Files::escape() is not static, but was called statically. ( Ignorable by Annotation )

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

734
            /** @scrutinizer ignore-call */ 
735
            $newName = Files::escape(rawurldecode($_GET['renameTo']));
Loading history...
735
            $newName = str_replace('.', '', $newName);
736
737
            // path to file (from base images directory)
738
            $oldName = rawurldecode($_GET['rename']);
739
740
            // strip parent dir ("..") to avoid escaping from base directiory
741
            $oldName = preg_replace('#\.\.#', '', $oldName);
742
743
            if (is_dir($oldPath = Files::makeFile($this->getImagesDir(), $_GET['dir'] . $oldName))) {
0 ignored issues
show
Bug Best Practice introduced by
The method Files::makeFile() is not static, but was called statically. ( Ignorable by Annotation )

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

743
            if (is_dir($oldPath = Files::/** @scrutinizer ignore-call */ makeFile($this->getImagesDir(), $_GET['dir'] . $oldName))) {
Loading history...
744
                $newPath = Files::makeFile($this->getImagesDir(), $_GET['dir'] . $newName);
745
                return Files::rename($oldPath, $newPath);
0 ignored issues
show
Bug Best Practice introduced by
The expression return Files::rename($oldPath, $newPath) returns the type integer which is incompatible with the documented return type boolean.
Loading history...
Bug Best Practice introduced by
The method Files::rename() is not static, but was called statically. ( Ignorable by Annotation )

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

745
                return Files::/** @scrutinizer ignore-call */ rename($oldPath, $newPath);
Loading history...
746
            } else {
747
                // path to old file
748
                $oldPath = Files::makeFile($this->getImagesDir(), $oldName);
749
750
                $ret = Files::renameFile($oldPath, $newName);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::renameFile() is not static, but was called statically. ( Ignorable by Annotation )

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

750
                /** @scrutinizer ignore-call */ 
751
                $ret = Files::renameFile($oldPath, $newName);
Loading history...
751
                if (true === $ret) {
0 ignored issues
show
introduced by
The condition true === $ret is always false.
Loading history...
752
                    // delete old thumbnail
753
                    Files::delFile($this->getThumbname($oldPath));
754
                }
755
            }
756
            return $ret;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $ret also could return the type integer which is incompatible with the documented return type boolean.
Loading history...
757
        }
758
759
        return null;
760
    }
761
762
    public function processPaste()
763
    {
764
        switch ($_GET['paste']) {
765
            case 'copyFile':
766
                $src  = Files::makeFile($this->getImagesDir(), $_GET['srcdir'] . $_GET['file']);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::makeFile() is not static, but was called statically. ( Ignorable by Annotation )

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

766
                /** @scrutinizer ignore-call */ 
767
                $src  = Files::makeFile($this->getImagesDir(), $_GET['srcdir'] . $_GET['file']);
Loading history...
767
                $file = $_GET['file'];
768
                $dest = Files::makeFile($this->getImagesDir(), $_GET['dir']);
769
                return Files::copyFile($src, $dest, $file);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::copyFile() is not static, but was called statically. ( Ignorable by Annotation )

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

769
                return Files::/** @scrutinizer ignore-call */ copyFile($src, $dest, $file);
Loading history...
770
                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...
771
            case 'copyDir':
772
                $basePath = $this->getImagesDir();
773
                $src      = $_GET['srcdir'] . $_GET['file'];
774
                $dest     = $_GET['dir'] . $_GET['file'];
775
                return Files::copyDir($basePath, $src, $dest);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::copyDir() is not static, but was called statically. ( Ignorable by Annotation )

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

775
                return Files::/** @scrutinizer ignore-call */ copyDir($basePath, $src, $dest);
Loading history...
776
                break;
777
            case 'moveFile':
778
                $src  = Files::makeFile($this->getImagesDir(), $_GET['srcdir'] . $_GET['file']);
779
                $dest = Files::makeFile($this->getImagesDir(), $_GET['dir'] . $_GET['file']);
780
                return Files::rename($src, $dest);
0 ignored issues
show
Bug Best Practice introduced by
The method Files::rename() is not static, but was called statically. ( Ignorable by Annotation )

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

780
                return Files::/** @scrutinizer ignore-call */ rename($src, $dest);
Loading history...
781
                break;
782
            case 'moveDir':
783
                $src  = Files::makeFile($this->getImagesDir(), $_GET['srcdir'] . $_GET['file']);
784
                $dest = Files::makeFile($this->getImagesDir(), $_GET['dir'] . $_GET['file']);
785
                return Files::rename($src, $dest);
786
                break;
787
        }
788
    }
789
}
790
791
792