XoopsMediaUploader   F
last analyzed

Complexity

Total Complexity 103

Size/Duplication

Total Lines 616
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 292
dl 0
loc 616
rs 2
c 2
b 0
f 0
wmc 103

23 Methods

Rating   Name   Duplication   Size   Complexity  
A setTargetFileName() 0 3 1
A getMediaType() 0 3 1
B upload() 0 39 10
A getErrors() 0 14 4
A countMedia() 0 7 2
A arrayPushIfPositive() 0 5 2
A setPrefix() 0 3 1
A getSavedFileName() 0 3 1
B return_bytes() 0 14 7
A checkMaxFileSize() 0 12 3
A checkImageType() 0 15 6
B __construct() 0 31 7
A sanitizeMultipleExtensions() 0 13 3
A getMediaSize() 0 3 1
B _copyFile() 0 43 9
F fetchMedia() 0 103 25
A setErrors() 0 3 1
A getSavedDestination() 0 3 1
A checkMaxWidth() 0 16 4
A getMediaTmpName() 0 3 1
B checkMimeType() 0 23 8
A getMediaName() 0 3 1
A checkMaxHeight() 0 16 4

How to fix   Complexity   

Complex Class

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

1
<?php
2
/**
3
 * XOOPS file uploader
4
 *
5
 * You may not change or alter any portion of this comment or credits
6
 * of supporting developers from this source code or any supporting source code
7
 * which is considered copyrighted (c) material of the original comment or credit authors.
8
 * This program is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
13
 * @license             GNU GPL 2 (https://www.gnu.org/licenses/gpl-2.0.html)
14
 * @package             kernel
15
 * @since               2.0.0
16
 * @author              Kazumi Ono (http://www.myweb.ne.jp/, http://jp.xoops.org/)
17
 * @author              Taiwen Jiang <[email protected]>
18
 */
19
20
defined('XOOPS_ROOT_PATH') || exit('Restricted access');
21
22
use Xmf\Request;
23
24
/**
25
 * Upload Media files
26
 *
27
 * Example of usage (single file):
28
 * <code>
29
 * include_once __DIR__ . '/uploader.php';
30
 * $allowed_mimetypes = array('image/gif', 'image/jpeg', 'image/pjpeg', 'image/x-png');
31
 * $maxfilesize = 50000;
32
 * $maxfilewidth = 120;
33
 * $maxfileheight = 120;
34
 * $randomFilename = true;
35
 * $uploader = new XoopsMediaUploader('/home/xoops/uploads', $allowed_mimetypes, $maxfilesize, $maxfilewidth, $maxfileheight, $randomFilename);
36
 * if ($uploader->fetchMedia('single_file_name')) {
37
 *     if (!$uploader->upload()) {
38
 *         echo $uploader->getErrors();
39
 *     } else {
40
 *         echo '<h4>File uploaded successfully!</h4>'
41
 *         echo 'Saved as: ' . $uploader->getSavedFileName() . '<br>';
42
 *         echo 'Full path: ' . $uploader->getSavedDestination();
43
 *     }
44
 * } else {
45
 *        echo $uploader->getErrors();
46
 * }
47
 * </code>
48
 *
49
 * Example of usage (multiple file):
50
 * <code>
51
 * include_once __DIR__ . '/uploader.php';
52
 * $allowed_mimetypes = array('image/gif', 'image/jpeg', 'image/pjpeg', 'image/x-png', 'image/webp');
53
 * $maxfilesize = 50000;
54
 * $maxfilewidth = 120;
55
 * $maxfileheight = 120;
56
 * $randomFilename = true;
57
 * $uploader = new XoopsMediaUploader('/home/xoops/uploads', $allowed_mimetypes, $maxfilesize, $maxfilewidth, $maxfileheight, $randomFilename);
58
 * for ($i = 0; $i < $uploader->countMedia('multiple_file_name'); $i++) {
59
 *     if ($uploader->fetchMedia('multiple_file_name')) {
60
 *        if (!$uploader->upload()) {
61
 *           echo $uploader->getErrors();
62
 *        } else {
63
 *           echo '<h4>File uploaded successfully!</h4>'
64
 *           echo 'Saved as: ' . $uploader->getSavedFileName() . '<br>';
65
 *           echo 'Full path: ' . $uploader->getSavedDestination();
66
 *        }
67
 *     } else {
68
 *        echo $uploader->getErrors();
69
 *     }
70
 * }
71
 * </code>
72
 *
73
 */
74
class XoopsMediaUploader
75
{
76
    /**
77
     * Flag indicating if unrecognized mimetypes should be allowed (use with precaution ! may lead to security issues )
78
     */
79
80
    public $allowUnknownTypes       = false;
81
    public $mediaName;
82
    public $mediaType;
83
    public $mediaSize;
84
    public $mediaTmpName;
85
    public $mediaError;
86
    public $mediaRealType           = '';
87
    public $uploadDir               = '';
88
    public $allowedMimeTypes        = array();
89
    public $deniedMimeTypes         = array(
90
        'application/x-httpd-php');
91
    public $maxFileSize             = 0;
92
    public $maxWidth;
93
    public $maxHeight;
94
    public $targetFileName;
95
    public $prefix;
96
    public $errors                  = array();
97
    public $savedDestination;
98
    public $savedFileName;
99
    public $extensionToMime         = array();
100
    public $checkImageType          = true;
101
    public $extensionsToBeSanitized = array(
102
        'php',
103
        'phtml',
104
        'phtm',
105
        'php3',
106
        'php4',
107
        'cgi',
108
        'pl',
109
        'asp',
110
        'php5',
111
        'php7',
112
    );
113
    // extensions needed image check (anti-IE Content-Type XSS)
114
    public $imageExtensions = array(
115
        1  => 'gif',
116
        2  => 'jpg',
117
        3  => 'png',
118
        4  => 'swf',
119
        5  => 'psd',
120
        6  => 'bmp',
121
        7  => 'tif',
122
        8  => 'tif',
123
        9  => 'jpc',
124
        10 => 'jp2',
125
        11 => 'jpx',
126
        12 => 'jb2',
127
        13 => 'swc',
128
        14 => 'iff',
129
        15 => 'wbmp',
130
        16 => 'xbm',
131
        17 => 'webp');
132
    public $randomFilename  = false;
133
134
    /**
135
     * Constructor
136
     *
137
     * @param string $uploadDir
138
     * @param array  $allowedMimeTypes
139
     * @param int    $maxFileSize
140
     * @param int    $maxWidth
141
     * @param int    $maxHeight
142
     * @param bool   $randomFilename
143
     */
144
145
    public function __construct($uploadDir, $allowedMimeTypes, $maxFileSize = 0, $maxWidth = null, $maxHeight = null, $randomFilename = false)
146
    {
147
        $this->extensionToMime = include $GLOBALS['xoops']->path('include/mimetypes.inc.php');
148
        if (!is_array($this->extensionToMime)) {
149
            $this->extensionToMime = array();
150
151
            return false;
152
        }
153
        if (is_array($allowedMimeTypes)) {
0 ignored issues
show
introduced by
The condition is_array($allowedMimeTypes) is always true.
Loading history...
154
            $this->allowedMimeTypes =& $allowedMimeTypes;
155
        }
156
        $this->uploadDir = $uploadDir;
157
158
        $limits = array();
159
        $limits = $this->arrayPushIfPositive($limits, $maxFileSize);
160
        $limits = $this->arrayPushIfPositive($limits, $this->return_bytes(ini_get('upload_max_filesize')));
161
        $limits = $this->arrayPushIfPositive($limits, $this->return_bytes(ini_get('post_max_size')));
162
        $limits = $this->arrayPushIfPositive($limits, $this->return_bytes(ini_get('memory_limit')));
163
        $this->maxFileSize = min($limits);
164
165
        if (isset($maxWidth)) {
166
            $this->maxWidth = (int)$maxWidth;
167
        }
168
        if (isset($maxHeight)) {
169
            $this->maxHeight = (int)$maxHeight;
170
        }
171
        if (isset($randomFilename)) {
172
            $this->randomFilename = $randomFilename;
173
        }
174
        if (!include_once $GLOBALS['xoops']->path('language/' . $GLOBALS['xoopsConfig']['language'] . '/uploader.php')) {
175
            include_once $GLOBALS['xoops']->path('language/english/uploader.php');
176
        }
177
    }
178
179
    /**
180
     * converts memory/file sizes as defined in php.ini to bytes
181
     *
182
     * @param $size_str
183
     *
184
     * @return int
185
     */
186
    public function return_bytes($size_str)
187
    {
188
        switch (substr($size_str, -1)) {
189
            case 'K':
190
            case 'k':
191
                return (int)$size_str * 1024;
192
            case 'M':
193
            case 'm':
194
                return (int)$size_str * 1048576;
195
            case 'G':
196
            case 'g':
197
                return (int)$size_str * 1073741824;
198
            default:
199
                return $size_str;
200
        }
201
    }
202
203
    /**
204
     * Count the uploaded files (in case of miltiple upload)
205
     *
206
     * @param  string $media_name Name of the file field
207
     * @return int|false
208
     */
209
    public function countMedia($media_name) {
210
        if (!Request::hasVar($media_name, 'FILES')) {
211
            $this->setErrors(_ER_UP_FILENOTFOUND);
212
            return false;
213
        }
214
        $files = Request::getArray($media_name, [], 'FILES');
215
        return count($files['name']);
216
    }
217
218
    /**
219
     * Fetch the uploaded file
220
     *
221
     * @param  string $media_name Name of the file field
222
     * @param  int    $index      Index of the file (if more than one uploaded under that name)
223
     * @return bool
224
     */
225
    public function fetchMedia($media_name, $index = null)
226
    {
227
        if (empty($this->extensionToMime)) {
228
            $this->setErrors(_ER_UP_MIMETYPELOAD);
229
230
            return false;
231
        }
232
233
        if (!Request::hasVar($media_name, 'FILES')) {
234
            $this->setErrors(_ER_UP_FILENOTFOUND);
235
            return false;
236
        }
237
238
        $files = Request::getArray($media_name, [], 'FILES');
239
240
        if (is_array($files['name']) && isset($index)) {
241
            $index = (int)$index;
242
            $this->mediaName = $files['name'][$index];
243
            if ($this->randomFilename) {
244
                $unique = uniqid();
245
                $this->targetFileName = $unique . '--' . $this->mediaName;
246
            }
247
            $this->mediaType    = $files['type'][$index];
248
            $this->mediaSize    = $files['size'][$index];
249
            $this->mediaTmpName = $files['tmp_name'][$index];
250
            $this->mediaError   = !empty($files['error'][$index]) ? $files['error'][$index] : 0;
251
        } elseif (is_array($files['name']) && !isset($index)) {
252
            $this->setErrors(_ER_UP_INDEXNOTSET);
253
            return false;
254
        } else {
255
            $file = $files;
256
            $this->mediaName = $file['name'];
257
            if ($this->randomFilename) {
258
                $unique = uniqid();
259
                $this->targetFileName = $unique . '--' . $this->mediaName;
260
            }
261
            $this->mediaType    = $file['type'];
262
            $this->mediaSize    = $file['size'];
263
            $this->mediaTmpName = $file['tmp_name'];
264
            $this->mediaError   = !empty($file['error']) ? $file['error'] : 0;
265
        }
266
267
        if (($ext = strrpos($this->mediaName, '.')) !== false) {
268
            $ext = strtolower(substr($this->mediaName, $ext + 1));
269
            if (isset($this->extensionToMime[$ext])) {
270
                $this->mediaRealType = $this->extensionToMime[$ext];
271
            }
272
        }
273
        $this->errors = array();
274
        if ($this->mediaError > 0) {
275
            switch($this->mediaError){
276
                case UPLOAD_ERR_INI_SIZE:
277
                    $this->setErrors(_ER_UP_INISIZE);
278
                    return false;
279
                    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...
280
                case UPLOAD_ERR_FORM_SIZE:
281
                    $this->setErrors(_ER_UP_FORMSIZE);
282
                    return false;
283
                    break;
284
                case UPLOAD_ERR_PARTIAL:
285
                    $this->setErrors(_ER_UP_PARTIAL);
286
                    return false;
287
                    break;
288
                case UPLOAD_ERR_NO_FILE:
289
                    $this->setErrors(_ER_UP_NOFILE);
290
                    return false;
291
                    break;
292
                case UPLOAD_ERR_NO_TMP_DIR:
293
                    $this->setErrors(_ER_UP_NOTMPDIR);
294
                    return false;
295
                    break;
296
                case UPLOAD_ERR_CANT_WRITE:
297
                    $this->setErrors(_ER_UP_CANTWRITE);
298
                    return false;
299
                    break;
300
                case UPLOAD_ERR_EXTENSION:
301
                    $this->setErrors(_ER_UP_EXTENSION);
302
                    return false;
303
                    break;
304
                default:
305
                    $this->setErrors(_ER_UP_UNKNOWN);
306
                    return false;
307
                    break;
308
            }
309
        }
310
311
        if ((int)$this->mediaSize < 0) {
312
            $this->setErrors(_ER_UP_INVALIDFILESIZE);
313
314
            return false;
315
        }
316
        if ($this->mediaName == '') {
317
            $this->setErrors(_ER_UP_FILENAMEEMPTY);
318
319
            return false;
320
        }
321
        if ($this->mediaTmpName === 'none' || !is_uploaded_file($this->mediaTmpName)) {
322
            $this->setErrors(_ER_UP_NOFILEUPLOADED);
323
324
            return false;
325
        }
326
327
        return true;
328
    }
329
330
    /**
331
     * Set the target filename
332
     *
333
     * @param string $value
334
     */
335
    public function setTargetFileName($value)
336
    {
337
        $this->targetFileName = (string)trim($value);
338
    }
339
340
    /**
341
     * Set the prefix
342
     *
343
     * @param string $value
344
     */
345
    public function setPrefix($value)
346
    {
347
        $this->prefix = (string)trim($value);
348
    }
349
350
    /**
351
     * Get the uploaded filename
352
     *
353
     * @return string
354
     */
355
    public function getMediaName()
356
    {
357
        return $this->mediaName;
358
    }
359
360
    /**
361
     * Get the type of the uploaded file
362
     *
363
     * @return string
364
     */
365
    public function getMediaType()
366
    {
367
        return $this->mediaType;
368
    }
369
370
    /**
371
     * Get the size of the uploaded file
372
     *
373
     * @return int
374
     */
375
    public function getMediaSize()
376
    {
377
        return $this->mediaSize;
378
    }
379
380
    /**
381
     * Get the temporary name that the uploaded file was stored under
382
     *
383
     * @return string
384
     */
385
    public function getMediaTmpName()
386
    {
387
        return $this->mediaTmpName;
388
    }
389
390
    /**
391
     * Get the saved filename
392
     *
393
     * @return string
394
     */
395
    public function getSavedFileName()
396
    {
397
        return $this->savedFileName;
398
    }
399
400
    /**
401
     * Get the destination the file is saved to
402
     *
403
     * @return string
404
     */
405
    public function getSavedDestination()
406
    {
407
        return $this->savedDestination;
408
    }
409
410
    /**
411
     * Check the file and copy it to the destination
412
     *
413
     * @param  int $chmod
414
     * @return bool
415
     */
416
    public function upload($chmod = 0644)
417
    {
418
        if ($this->uploadDir == '') {
419
            $this->setErrors(_ER_UP_UPLOADDIRNOTSET);
420
421
            return false;
422
        }
423
        if (!is_dir($this->uploadDir)) {
424
            $this->setErrors(sprintf(_ER_UP_FAILEDOPENDIR, $this->uploadDir));
425
426
            return false;
427
        }
428
        if (!is_writable($this->uploadDir)) {
429
            $this->setErrors(sprintf(_ER_UP_FAILEDOPENDIRWRITE, $this->uploadDir));
430
431
            return false;
432
        }
433
        $this->sanitizeMultipleExtensions();
434
435
        if (!$this->checkMaxFileSize()) {
436
            return false;
437
        }
438
        if (!$this->checkMaxWidth()) {
439
            return false;
440
        }
441
        if (!$this->checkMaxHeight()) {
442
            return false;
443
        }
444
        if (!$this->checkMimeType()) {
445
            return false;
446
        }
447
        if (!$this->checkImageType()) {
448
            return false;
449
        }
450
        if (count($this->errors) > 0) {
451
            return false;
452
        }
453
454
        return $this->_copyFile($chmod);
455
    }
456
457
    /**
458
     * Copy the file to its destination
459
     *
460
     * @param int $chmod
461
     * @return bool
462
     */
463
    public function _copyFile($chmod)
464
    {
465
        $matched = array();
466
        if (!preg_match("/\.([a-zA-Z0-9]+)$/", $this->mediaName, $matched)) {
467
            $this->setErrors(_ER_UP_INVALIDFILENAME);
468
            return false;
469
        }
470
471
        if (isset($this->targetFileName)) {
472
            $this->savedFileName = $this->targetFileName;
473
        } elseif (isset($this->prefix)) {
474
            $this->savedFileName = uniqid($this->prefix, false) . '.' . strtolower($matched[1]); //TODO: for true, need to increase size of image_name field in image table
475
        } else {
476
            $this->savedFileName = strtolower($this->mediaName);
477
        }
478
479
        $this->savedFileName = iconv('UTF-8', 'ASCII//TRANSLIT', $this->savedFileName);
480
        $this->savedFileName = preg_replace('!\s+!', '_', $this->savedFileName);
481
        $this->savedFileName = preg_replace("/[^a-zA-Z0-9\._-]/", '', $this->savedFileName);
482
483
        $this->savedDestination = $this->uploadDir . '/' . $this->savedFileName;
484
485
        if (!move_uploaded_file($this->mediaTmpName, $this->savedDestination)) {
486
            $this->setErrors(sprintf(_ER_UP_FAILEDSAVEFILE, $this->savedDestination));
487
            return false;
488
        }
489
490
        // Check for IE XSS vulnerability for image files
491
        $ext = strtolower(substr(strrchr($this->savedDestination, '.'), 1));
492
        if (in_array($ext, $this->imageExtensions)) {
493
            $info = getimagesize($this->savedDestination);
494
            if ($info === false || $this->imageExtensions[(int) $info[2]] != $ext) {
495
                $this->setErrors(_ER_UP_SUSPICIOUSREFUSED);
496
                unlink($this->savedDestination);
497
                return false;
498
            }
499
        }
500
501
        if (false === chmod($this->savedDestination, $chmod)) {
502
            $this->setErrors(_ER_UP_MODE_NOT_CHANGED);
503
        }
504
505
        return true;
506
    }
507
508
    /**
509
     * Is the file the right size?
510
     *
511
     * @return bool
512
     */
513
    public function checkMaxFileSize()
514
    {
515
        if (!isset($this->maxFileSize)) {
516
            return true;
517
        }
518
        if ($this->mediaSize > $this->maxFileSize) {
519
            $this->setErrors(sprintf(_ER_UP_FILESIZETOOLARGE, $this->maxFileSize, $this->mediaSize));
520
521
            return false;
522
        }
523
524
        return true;
525
    }
526
527
    /**
528
     * Is the picture the right width?
529
     *
530
     * @return bool
531
     */
532
    public function checkMaxWidth()
533
    {
534
        if (!isset($this->maxWidth)) {
535
            return true;
536
        }
537
        if (false !== $dimension = getimagesize($this->mediaTmpName)) {
538
            if ($dimension[0] > $this->maxWidth) {
539
                $this->setErrors(sprintf(_ER_UP_FILEWIDTHTOOLARGE, $this->maxWidth, $dimension[0]));
540
541
                return false;
542
            }
543
        } else {
544
            trigger_error(sprintf(_ER_UP_FAILEDFETCHIMAGESIZE, $this->mediaTmpName), E_USER_WARNING);
545
        }
546
547
        return true;
548
    }
549
550
    /**
551
     * Is the picture the right height?
552
     *
553
     * @return bool
554
     */
555
    public function checkMaxHeight()
556
    {
557
        if (!isset($this->maxHeight)) {
558
            return true;
559
        }
560
        if (false !== $dimension = getimagesize($this->mediaTmpName)) {
561
            if ($dimension[1] > $this->maxHeight) {
562
                $this->setErrors(sprintf(_ER_UP_FILEHEIGHTTOOLARGE, $this->maxHeight, $dimension[1]));
563
564
                return false;
565
            }
566
        } else {
567
            trigger_error(sprintf(_ER_UP_FAILEDFETCHIMAGESIZE, $this->mediaTmpName), E_USER_WARNING);
568
        }
569
570
        return true;
571
    }
572
573
    /**
574
     * Check whether or not the uploaded file type is allowed
575
     *
576
     * @return bool
577
     */
578
    public function checkMimeType()
579
    {
580
        // if the browser supplied mime type looks suspicious, refuse it
581
        $structureCheck = (bool) preg_match('/^\w+\/[-+.\w]+$/', $this->mediaType);
582
        if (false === $structureCheck) {
583
            $this->mediaType = 'invalid';
584
            $this->setErrors(_ER_UP_UNKNOWNFILETYPEREJECTED);
585
            return false;
586
        }
587
588
        if (empty($this->mediaRealType) && empty($this->allowUnknownTypes)) {
589
            $this->setErrors(_ER_UP_UNKNOWNFILETYPEREJECTED);
590
591
            return false;
592
        }
593
594
        if ((!empty($this->allowedMimeTypes) && !in_array($this->mediaRealType, $this->allowedMimeTypes)) || (!empty($this->deniedMimeTypes) && in_array($this->mediaRealType, $this->deniedMimeTypes))) {
595
            $this->setErrors(sprintf(_ER_UP_MIMETYPENOTALLOWED, htmlspecialchars($this->mediaRealType, ENT_QUOTES | ENT_HTML5)));
596
597
            return false;
598
        }
599
600
        return true;
601
    }
602
603
    /**
604
     * Check whether or not the uploaded image type is valid
605
     *
606
     * @return bool
607
     */
608
    public function checkImageType()
609
    {
610
        if (empty($this->checkImageType)) {
611
            return true;
612
        }
613
614
        if (('image' === substr($this->mediaType, 0, strpos($this->mediaType, '/'))) || (!empty($this->mediaRealType) && 'image' === substr($this->mediaRealType, 0, strpos($this->mediaRealType, '/')))) {
615
            if (!($info = @getimagesize($this->mediaTmpName))) {
0 ignored issues
show
Unused Code introduced by
The assignment to $info is dead and can be removed.
Loading history...
616
                $this->setErrors(_ER_UP_INVALIDIMAGEFILE);
617
618
                return false;
619
            }
620
        }
621
622
        return true;
623
    }
624
625
    /**
626
     * Sanitize executable filename with multiple extensions
627
     */
628
    public function sanitizeMultipleExtensions()
629
    {
630
        if (empty($this->extensionsToBeSanitized)) {
631
            return null;
632
        }
633
634
        $patterns = array();
635
        $replaces = array();
636
        foreach ($this->extensionsToBeSanitized as $ext) {
637
            $patterns[] = "/\." . preg_quote($ext, '/') . "\./i";
638
            $replaces[] = '_' . $ext . '.';
639
        }
640
        $this->mediaName = preg_replace($patterns, $replaces, $this->mediaName);
641
    }
642
643
    /**
644
     * Add an error
645
     *
646
     * @param string $error
647
     */
648
    public function setErrors($error)
649
    {
650
        $this->errors[] = trim($error);
651
    }
652
653
    /**
654
     * Get generated errors
655
     *
656
     * @param  bool $ashtml Format using HTML?
657
     * @return array |string    Array of array messages OR HTML string
658
     */
659
    public function &getErrors($ashtml = true)
660
    {
661
        if (!$ashtml) {
662
            return $this->errors;
663
        } else {
664
            $ret = '';
665
            if (count($this->errors) > 0) {
666
                $ret = '<h4>' . sprintf(_ER_UP_ERRORSRETURNED, htmlspecialchars($this->mediaName, ENT_QUOTES | ENT_HTML5)) . '</h4>';
667
                foreach ($this->errors as $error) {
668
                    $ret .= $error . '<br>';
669
                }
670
            }
671
672
            return $ret;
673
        }
674
    }
675
676
    /**
677
     * Push value onto set.
678
     * Used in max file size calculation to eliminate -1 (unlimited) ini values
679
     *
680
     * @param array $set   array of values
681
     * @param int   $value value to push
682
     *
683
     * @return mixed
684
     */
685
    protected function arrayPushIfPositive($set, $value) {
686
        if ($value > 0) {
687
            array_push($set, $value);
688
        }
689
        return $set;
690
    }
691
}
692