Completed
Push — master ( 4accea...d96bce )
by Richard
28s queued 10s
created

XoopsMediaUploader::arrayPushIfPositive()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 3
c 1
b 0
f 0
dl 0
loc 5
rs 10
cc 2
nc 2
nop 2
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 (http://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
/**
23
 * Upload Media files
24
 *
25
 * Example of usage (single file):
26
 * <code>
27
 * include_once 'uploader.php';
28
 * $allowed_mimetypes = array('image/gif', 'image/jpeg', 'image/pjpeg', 'image/x-png');
29
 * $maxfilesize = 50000;
30
 * $maxfilewidth = 120;
31
 * $maxfileheight = 120;
32
 * $randomFilename = true;
33
 * $uploader = new XoopsMediaUploader('/home/xoops/uploads', $allowed_mimetypes, $maxfilesize, $maxfilewidth, $maxfileheight, $randomFilename);
34
 * if ($uploader->fetchMedia('single_file_name')) {
35
 *     if (!$uploader->upload()) {
36
 *         echo $uploader->getErrors();
37
 *     } else {
38
 *         echo '<h4>File uploaded successfully!</h4>'
39
 *         echo 'Saved as: ' . $uploader->getSavedFileName() . '<br>';
40
 *         echo 'Full path: ' . $uploader->getSavedDestination();
41
 *     }
42
 * } else {
43
 *        echo $uploader->getErrors();
44
 * }
45
 * </code>
46
 *
47
 * Example of usage (multiple file):
48
 * <code>
49
 * include_once 'uploader.php';
50
 * $allowed_mimetypes = array('image/gif', 'image/jpeg', 'image/pjpeg', 'image/x-png');
51
 * $maxfilesize = 50000;
52
 * $maxfilewidth = 120;
53
 * $maxfileheight = 120;
54
 * $randomFilename = true;
55
 * $uploader = new XoopsMediaUploader('/home/xoops/uploads', $allowed_mimetypes, $maxfilesize, $maxfilewidth, $maxfileheight, $randomFilename);
56
 * for ($i = 0; $i < $uploader->countMedia('multiple_file_name'); $i++) {
57
 *     if ($uploader->fetchMedia('multiple_file_name')) {
58
 *        if (!$uploader->upload()) {
59
 *           echo $uploader->getErrors();
60
 *        } else {
61
 *           echo '<h4>File uploaded successfully!</h4>'
62
 *           echo 'Saved as: ' . $uploader->getSavedFileName() . '<br>';
63
 *           echo 'Full path: ' . $uploader->getSavedDestination();
64
 *        }
65
 *     } else {
66
 *        echo $uploader->getErrors();
67
 *     }
68
 * }
69
 * </code>
70
 *
71
 */
72
class XoopsMediaUploader
73
{
74
    /**
75
     * Flag indicating if unrecognized mimetypes should be allowed (use with precaution ! may lead to security issues )
76
     */
77
78
    public $allowUnknownTypes       = false;
79
    public $mediaName;
80
    public $mediaType;
81
    public $mediaSize;
82
    public $mediaTmpName;
83
    public $mediaError;
84
    public $mediaRealType           = '';
85
    public $uploadDir               = '';
86
    public $allowedMimeTypes        = array();
87
    public $deniedMimeTypes         = array(
88
        'application/x-httpd-php');
89
    public $maxFileSize             = 0;
90
    public $maxWidth;
91
    public $maxHeight;
92
    public $targetFileName;
93
    public $prefix;
94
    public $errors                  = array();
95
    public $savedDestination;
96
    public $savedFileName;
97
    public $extensionToMime         = array();
98
    public $checkImageType          = true;
99
    public $extensionsToBeSanitized = array(
100
        'php',
101
        'phtml',
102
        'phtm',
103
        'php3',
104
        'php4',
105
        'cgi',
106
        'pl',
107
        'asp',
108
        'php5',
109
        'php7',
110
    );
111
    // extensions needed image check (anti-IE Content-Type XSS)
112
    public $imageExtensions = array(
113
        1  => 'gif',
114
        2  => 'jpg',
115
        3  => 'png',
116
        4  => 'swf',
117
        5  => 'psd',
118
        6  => 'bmp',
119
        7  => 'tif',
120
        8  => 'tif',
121
        9  => 'jpc',
122
        10 => 'jp2',
123
        11 => 'jpx',
124
        12 => 'jb2',
125
        13 => 'swc',
126
        14 => 'iff',
127
        15 => 'wbmp',
128
        16 => 'xbm');
129
    public $randomFilename  = false;
130
131
    /**
132
     * Constructor
133
     *
134
     * @param string $uploadDir
135
     * @param array  $allowedMimeTypes
136
     * @param int    $maxFileSize
137
     * @param int    $maxWidth
138
     * @param int    $maxHeight
139
     * @param bool   $randomFilename
140
     */
141
142
    public function __construct($uploadDir, $allowedMimeTypes, $maxFileSize = 0, $maxWidth = null, $maxHeight = null, $randomFilename = false)
143
    {
144
        $this->extensionToMime = include $GLOBALS['xoops']->path('include/mimetypes.inc.php');
145
        if (!is_array($this->extensionToMime)) {
146
            $this->extensionToMime = array();
147
148
            return false;
149
        }
150
        if (is_array($allowedMimeTypes)) {
0 ignored issues
show
introduced by
The condition is_array($allowedMimeTypes) is always true.
Loading history...
151
            $this->allowedMimeTypes =& $allowedMimeTypes;
152
        }
153
        $this->uploadDir = $uploadDir;
154
155
        $limits = array();
156
        $limits = $this->arrayPushIfPositive($limits, $maxFileSize);
157
        $limits = $this->arrayPushIfPositive($limits, $this->return_bytes(ini_get('upload_max_filesize')));
158
        $limits = $this->arrayPushIfPositive($limits, $this->return_bytes(ini_get('post_max_size')));
159
        $limits = $this->arrayPushIfPositive($limits, $this->return_bytes(ini_get('memory_limit')));
160
        $this->maxFileSize = min($limits);
161
162
        if (isset($maxWidth)) {
163
            $this->maxWidth = (int)$maxWidth;
164
        }
165
        if (isset($maxHeight)) {
166
            $this->maxHeight = (int)$maxHeight;
167
        }
168
        if (isset($randomFilename)) {
169
            $this->randomFilename = $randomFilename;
170
        }
171
        if (!include_once $GLOBALS['xoops']->path('language/' . $GLOBALS['xoopsConfig']['language'] . '/uploader.php')) {
172
            include_once $GLOBALS['xoops']->path('language/english/uploader.php');
173
        }
174
    }
175
176
    /**
177
     * converts memory/file sizes as defined in php.ini to bytes
178
     *
179
     * @param $size_str
180
     *
181
     * @return int
182
     */
183
    public function return_bytes($size_str)
184
    {
185
        switch (substr($size_str, -1)) {
186
            case 'K':
187
            case 'k':
188
                return (int)$size_str * 1024;
189
            case 'M':
190
            case 'm':
191
                return (int)$size_str * 1048576;
192
            case 'G':
193
            case 'g':
194
                return (int)$size_str * 1073741824;
195
            default:
196
                return $size_str;
197
        }
198
    }
199
200
    /**
201
     * Count the uploaded files (in case of miltiple upload)
202
     *
203
     * @param  string $media_name Name of the file field
204
     * @return int
205
     */
206
    public function countMedia($media_name) {
207
        if (!isset($_FILES[$media_name])) {
208
            $this->setErrors(_ER_UP_FILENOTFOUND);
209
            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 integer.
Loading history...
210
        }
211
        return count($_FILES[$media_name]['name']);
212
    }
213
214
    /**
215
     * Fetch the uploaded file
216
     *
217
     * @param  string $media_name Name of the file field
218
     * @param  int    $index      Index of the file (if more than one uploaded under that name)
219
     * @return bool
220
     */
221
    public function fetchMedia($media_name, $index = null)
222
    {
223
        if (empty($this->extensionToMime)) {
224
            $this->setErrors(_ER_UP_MIMETYPELOAD);
225
226
            return false;
227
        }
228
        if (!isset($_FILES[$media_name])) {
229
            $this->setErrors(_ER_UP_FILENOTFOUND);
230
231
            return false;
232
        } elseif (is_array($_FILES[$media_name]['name']) && isset($index)) {
233
            $index           = (int)$index;
234
            $this->mediaName = get_magic_quotes_gpc() ? stripslashes($_FILES[$media_name]['name'][$index]) : $_FILES[$media_name]['name'][$index];
235
            if ($this->randomFilename) {
236
                $unique          = uniqid();
237
                $this->targetFileName = '' . $unique . '--' . $this->mediaName;
238
            }
239
            $this->mediaType    = $_FILES[$media_name]['type'][$index];
240
            $this->mediaSize    = $_FILES[$media_name]['size'][$index];
241
            $this->mediaTmpName = $_FILES[$media_name]['tmp_name'][$index];
242
            $this->mediaError   = !empty($_FILES[$media_name]['error'][$index]) ? $_FILES[$media_name]['error'][$index] : 0;
243
        } elseif (is_array($_FILES[$media_name]['name']) && !isset($index)) {
244
            $this->setErrors(_ER_UP_INDEXNOTSET);
245
246
            return false;
247
        } else {
248
            $media_name      =& $_FILES[$media_name];
249
            $this->mediaName = get_magic_quotes_gpc() ? stripslashes($media_name['name']) : $media_name['name'];
250
            if ($this->randomFilename) {
251
                $unique          = uniqid();
252
                $this->targetFileName = '' . $unique . '--' . $this->mediaName;
253
            }
254
            $this->mediaType    = $media_name['type'];
255
            $this->mediaSize    = $media_name['size'];
256
            $this->mediaTmpName = $media_name['tmp_name'];
257
            $this->mediaError   = !empty($media_name['error']) ? $media_name['error'] : 0;
258
        }
259
260
        if (($ext = strrpos($this->mediaName, '.')) !== false) {
261
            $ext = strtolower(substr($this->mediaName, $ext + 1));
262
            if (isset($this->extensionToMime[$ext])) {
263
                $this->mediaRealType = $this->extensionToMime[$ext];
264
            }
265
        }
266
        $this->errors = array();
267
        if ($this->mediaError > 0) {
268
            switch($this->mediaError){
269
                case UPLOAD_ERR_INI_SIZE:
270
                    $this->setErrors(_ER_UP_INISIZE);
271
                    return false;
272
                    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...
273
                case UPLOAD_ERR_FORM_SIZE:
274
                    $this->setErrors(_ER_UP_FORMSIZE);
275
                    return false;
276
                    break;
277
                case UPLOAD_ERR_PARTIAL:
278
                    $this->setErrors(_ER_UP_PARTIAL);
279
                    return false;
280
                    break;
281
                case UPLOAD_ERR_NO_FILE:
282
                    $this->setErrors(_ER_UP_NOFILE);
283
                    return false;
284
                    break;
285
                case UPLOAD_ERR_NO_TMP_DIR:
286
                    $this->setErrors(_ER_UP_NOTMPDIR);
287
                    return false;
288
                    break;
289
                case UPLOAD_ERR_CANT_WRITE:
290
                    $this->setErrors(_ER_UP_CANTWRITE);
291
                    return false;
292
                    break;
293
                case UPLOAD_ERR_EXTENSION:
294
                    $this->setErrors(_ER_UP_EXTENSION);
295
                    return false;
296
                    break;
297
                default:
298
                    $this->setErrors(_ER_UP_UNKNOWN);
299
                    return false;
300
                    break;
301
            }
302
        }
303
304
        if ((int)$this->mediaSize < 0) {
305
            $this->setErrors(_ER_UP_INVALIDFILESIZE);
306
307
            return false;
308
        }
309
        if ($this->mediaName == '') {
310
            $this->setErrors(_ER_UP_FILENAMEEMPTY);
311
312
            return false;
313
        }
314
        if ($this->mediaTmpName === 'none' || !is_uploaded_file($this->mediaTmpName)) {
315
            $this->setErrors(_ER_UP_NOFILEUPLOADED);
316
317
            return false;
318
        }
319
320
        return true;
321
    }
322
323
    /**
324
     * Set the target filename
325
     *
326
     * @param string $value
327
     */
328
    public function setTargetFileName($value)
329
    {
330
        $this->targetFileName = (string)trim($value);
331
    }
332
333
    /**
334
     * Set the prefix
335
     *
336
     * @param string $value
337
     */
338
    public function setPrefix($value)
339
    {
340
        $this->prefix = (string)trim($value);
341
    }
342
343
    /**
344
     * Get the uploaded filename
345
     *
346
     * @return string
347
     */
348
    public function getMediaName()
349
    {
350
        return $this->mediaName;
351
    }
352
353
    /**
354
     * Get the type of the uploaded file
355
     *
356
     * @return string
357
     */
358
    public function getMediaType()
359
    {
360
        return $this->mediaType;
361
    }
362
363
    /**
364
     * Get the size of the uploaded file
365
     *
366
     * @return int
367
     */
368
    public function getMediaSize()
369
    {
370
        return $this->mediaSize;
371
    }
372
373
    /**
374
     * Get the temporary name that the uploaded file was stored under
375
     *
376
     * @return string
377
     */
378
    public function getMediaTmpName()
379
    {
380
        return $this->mediaTmpName;
381
    }
382
383
    /**
384
     * Get the saved filename
385
     *
386
     * @return string
387
     */
388
    public function getSavedFileName()
389
    {
390
        return $this->savedFileName;
391
    }
392
393
    /**
394
     * Get the destination the file is saved to
395
     *
396
     * @return string
397
     */
398
    public function getSavedDestination()
399
    {
400
        return $this->savedDestination;
401
    }
402
403
    /**
404
     * Check the file and copy it to the destination
405
     *
406
     * @param  int $chmod
407
     * @return bool
408
     */
409
    public function upload($chmod = 0644)
410
    {
411
        if ($this->uploadDir == '') {
412
            $this->setErrors(_ER_UP_UPLOADDIRNOTSET);
413
414
            return false;
415
        }
416
        if (!is_dir($this->uploadDir)) {
417
            $this->setErrors(sprintf(_ER_UP_FAILEDOPENDIR, $this->uploadDir));
418
419
            return false;
420
        }
421
        if (!is_writable($this->uploadDir)) {
422
            $this->setErrors(sprintf(_ER_UP_FAILEDOPENDIRWRITE, $this->uploadDir));
423
424
            return false;
425
        }
426
        $this->sanitizeMultipleExtensions();
427
428
        if (!$this->checkMaxFileSize()) {
429
            return false;
430
        }
431
        if (!$this->checkMaxWidth()) {
432
            return false;
433
        }
434
        if (!$this->checkMaxHeight()) {
435
            return false;
436
        }
437
        if (!$this->checkMimeType()) {
438
            return false;
439
        }
440
        if (!$this->checkImageType()) {
441
            return false;
442
        }
443
        if (count($this->errors) > 0) {
444
            return false;
445
        }
446
447
        return $this->_copyFile($chmod);
448
    }
449
450
    /**
451
     * Copy the file to its destination
452
     *
453
     * @param $chmod
454
     * @return bool
455
     */
456
    public function _copyFile($chmod)
457
    {
458
        $matched = array();
459
        if (!preg_match("/\.([a-zA-Z0-9]+)$/", $this->mediaName, $matched)) {
460
            $this->setErrors(_ER_UP_INVALIDFILENAME);
461
462
            return false;
463
        }
464
        if (isset($this->targetFileName)) {
465
            $this->savedFileName = $this->targetFileName;
466
        } elseif (isset($this->prefix)) {
467
            $this->savedFileName = uniqid($this->prefix) . '.' . strtolower($matched[1]);
468
        } else {
469
            $this->savedFileName = strtolower($this->mediaName);
470
        }
471
472
        $this->savedFileName = iconv('UTF-8', 'ASCII//TRANSLIT', $this->savedFileName);
473
        $this->savedFileName = preg_replace('!\s+!', '_', $this->savedFileName);
474
        $this->savedFileName = preg_replace("/[^a-zA-Z0-9\._-]/", '', $this->savedFileName);
475
476
        $this->savedDestination = $this->uploadDir . '/' . $this->savedFileName;
477
        if (!move_uploaded_file($this->mediaTmpName, $this->savedDestination)) {
478
            $this->setErrors(sprintf(_ER_UP_FAILEDSAVEFILE, $this->savedDestination));
479
480
            return false;
481
        }
482
        // Check IE XSS before returning success
483
        $ext = strtolower(substr(strrchr($this->savedDestination, '.'), 1));
484
        if (in_array($ext, $this->imageExtensions)) {
485
            $info = @getimagesize($this->savedDestination);
486
            if ($info === false || $this->imageExtensions[(int)$info[2]] != $ext) {
487
                $this->setErrors(_ER_UP_SUSPICIOUSREFUSED);
488
                @unlink($this->savedDestination);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

488
                /** @scrutinizer ignore-unhandled */ @unlink($this->savedDestination);

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

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

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
489
490
                return false;
491
            }
492
        }
493
        @chmod($this->savedDestination, $chmod);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for chmod(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

493
        /** @scrutinizer ignore-unhandled */ @chmod($this->savedDestination, $chmod);

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

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

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
494
495
        return true;
496
    }
497
498
    /**
499
     * Is the file the right size?
500
     *
501
     * @return bool
502
     */
503
    public function checkMaxFileSize()
504
    {
505
        if (!isset($this->maxFileSize)) {
506
            return true;
507
        }
508
        if ($this->mediaSize > $this->maxFileSize) {
509
            $this->setErrors(sprintf(_ER_UP_FILESIZETOOLARGE, $this->maxFileSize, $this->mediaSize));
510
511
            return false;
512
        }
513
514
        return true;
515
    }
516
517
    /**
518
     * Is the picture the right width?
519
     *
520
     * @return bool
521
     */
522
    public function checkMaxWidth()
523
    {
524
        if (!isset($this->maxWidth)) {
525
            return true;
526
        }
527
        if (false !== $dimension = getimagesize($this->mediaTmpName)) {
528
            if ($dimension[0] > $this->maxWidth) {
529
                $this->setErrors(sprintf(_ER_UP_FILEWIDTHTOOLARGE, $this->maxWidth, $dimension[0]));
530
531
                return false;
532
            }
533
        } else {
534
            trigger_error(sprintf(_ER_UP_FAILEDFETCHIMAGESIZE, $this->mediaTmpName), E_USER_WARNING);
535
        }
536
537
        return true;
538
    }
539
540
    /**
541
     * Is the picture the right height?
542
     *
543
     * @return bool
544
     */
545
    public function checkMaxHeight()
546
    {
547
        if (!isset($this->maxHeight)) {
548
            return true;
549
        }
550
        if (false !== $dimension = getimagesize($this->mediaTmpName)) {
551
            if ($dimension[1] > $this->maxHeight) {
552
                $this->setErrors(sprintf(_ER_UP_FILEHEIGHTTOOLARGE, $this->maxHeight, $dimension[1]));
553
554
                return false;
555
            }
556
        } else {
557
            trigger_error(sprintf(_ER_UP_FAILEDFETCHIMAGESIZE, $this->mediaTmpName), E_USER_WARNING);
558
        }
559
560
        return true;
561
    }
562
563
    /**
564
     * Check whether or not the uploaded file type is allowed
565
     *
566
     * @return bool
567
     */
568
    public function checkMimeType()
569
    {
570
        // if the browser supplied mime type looks suspicious, refuse it
571
        $structureCheck = (bool) preg_match('/^\w+\/[-+.\w]+$/', $this->mediaType);
572
        if (false === $structureCheck) {
573
            $this->mediaType = 'invalid';
574
            $this->setErrors(_ER_UP_UNKNOWNFILETYPEREJECTED);
575
            return false;
576
        }
577
578
        if (empty($this->mediaRealType) && empty($this->allowUnknownTypes)) {
579
            $this->setErrors(_ER_UP_UNKNOWNFILETYPEREJECTED);
580
581
            return false;
582
        }
583
584
        if ((!empty($this->allowedMimeTypes) && !in_array($this->mediaRealType, $this->allowedMimeTypes)) || (!empty($this->deniedMimeTypes) && in_array($this->mediaRealType, $this->deniedMimeTypes))) {
585
            $this->setErrors(sprintf(_ER_UP_MIMETYPENOTALLOWED, htmlspecialchars($this->mediaRealType, ENT_QUOTES)));
586
587
            return false;
588
        }
589
590
        return true;
591
    }
592
593
    /**
594
     * Check whether or not the uploaded image type is valid
595
     *
596
     * @return bool
597
     */
598
    public function checkImageType()
599
    {
600
        if (empty($this->checkImageType)) {
601
            return true;
602
        }
603
604
        if (('image' === substr($this->mediaType, 0, strpos($this->mediaType, '/'))) || (!empty($this->mediaRealType) && 'image' === substr($this->mediaRealType, 0, strpos($this->mediaRealType, '/')))) {
605
            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...
606
                $this->setErrors(_ER_UP_INVALIDIMAGEFILE);
607
608
                return false;
609
            }
610
        }
611
612
        return true;
613
    }
614
615
    /**
616
     * Sanitize executable filename with multiple extensions
617
     */
618
    public function sanitizeMultipleExtensions()
619
    {
620
        if (empty($this->extensionsToBeSanitized)) {
621
            return null;
622
        }
623
624
        $patterns = array();
625
        $replaces = array();
626
        foreach ($this->extensionsToBeSanitized as $ext) {
627
            $patterns[] = "/\." . preg_quote($ext) . "\./i";
628
            $replaces[] = '_' . $ext . '.';
629
        }
630
        $this->mediaName = preg_replace($patterns, $replaces, $this->mediaName);
631
    }
632
633
    /**
634
     * Add an error
635
     *
636
     * @param string $error
637
     */
638
    public function setErrors($error)
639
    {
640
        $this->errors[] = trim($error);
641
    }
642
643
    /**
644
     * Get generated errors
645
     *
646
     * @param  bool $ashtml Format using HTML?
647
     * @return array |string    Array of array messages OR HTML string
648
     */
649
    public function &getErrors($ashtml = true)
650
    {
651
        if (!$ashtml) {
652
            return $this->errors;
653
        } else {
654
            $ret = '';
655
            if (count($this->errors) > 0) {
656
                $ret = '<h4>' . sprintf(_ER_UP_ERRORSRETURNED, htmlspecialchars($this->mediaName, ENT_QUOTES)) . '</h4>';
657
                foreach ($this->errors as $error) {
658
                    $ret .= $error . '<br>';
659
                }
660
            }
661
662
            return $ret;
663
        }
664
    }
665
666
    /**
667
     * Push value onto set.
668
     * Used in max file size calculation to eliminate -1 (unlimited) ini values
669
     *
670
     * @param array $set   array of values
671
     * @param int   $value value to push
672
     *
673
     * @return mixed
674
     */
675
    protected function arrayPushIfPositive($set, $value) {
676
        if ($value > 0) {
677
            array_push($set, $value);
678
        }
679
        return $set;
680
    }
681
}
682