Test Failed
Push — 1.0.0-dev ( f8836a...d20bd6 )
by nguereza
04:07
created

Upload::getPhpUploadErrorMessageByCode()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 9
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 11
rs 9.9666
1
<?php
2
    defined('ROOT_PATH') or exit('Access denied');
3
    /**
4
     * TNH Framework
5
     *
6
     * A simple PHP framework using HMVC architecture
7
     *
8
     * This content is released under the GNU GPL License (GPL)
9
     *
10
     * Copyright (C) 2017 Tony NGUEREZA
11
     *
12
     * This program is free software; you can redistribute it and/or
13
     * modify it under the terms of the GNU General Public License
14
     * as published by the Free Software Foundation; either version 3
15
     * of the License, or (at your option) any later version.
16
     *
17
     * This program is distributed in the hope that it will be useful,
18
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
     * GNU General Public License for more details.
21
     *
22
     * You should have received a copy of the GNU General Public License
23
     * along with this program; if not, write to the Free Software
24
     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25
    */
26
27
28
29
    /**
30
    *    Upload
31
    *
32
    *    A complete class to upload files with php 5 or higher, but the best: very simple to use.
33
    *
34
    *    @author Olaf Erlandsen <[email protected]>
35
    *    @author http://www.webdevfreelance.com/
36
    *
37
    *    @package FileUpload
38
    *    @version 1.5
39
    */
40
    class Upload{
41
42
        /**
43
        *   Version
44
        *
45
        *   @since      1.5
46
        *   @version    1.0
47
        */
48
        const VERSION = '1.5';
49
50
        /**
51
        *    Upload function name
52
        *    Remember:
53
        *        Default function: move_uploaded_file
54
        *        Native options:
55
        *            - move_uploaded_file (Default and best option)
56
        *            - copy
57
        *
58
        *    @since        1.0
59
        *    @version    1.0
60
        *    @var        mixex
0 ignored issues
show
Bug introduced by
The type mixex was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
61
        */
62
        private $upload_function = 'move_uploaded_file';
63
64
        /**
65
        *    Array with the information obtained from the
66
        *    variable $_FILES or $HTTP_POST_FILES.
67
        *
68
        *    @since        1.0
69
        *    @version    1.0
70
        *    @var        array
71
        */
72
        private $file_array    = array();
73
74
        /**
75
        *    If the file you are trying to upload already exists it will
76
        *    be overwritten if you set the variable to true.
77
        *
78
        *    @since        1.0
79
        *    @version    1.0
80
        *    @var        boolean
81
        */
82
        private $overwrite_file = false;
83
84
        /**
85
        *    Input element
86
        *    Example:
87
        *        <input type="file" name="file" />
88
        *    Result:
89
        *        FileUpload::$input = file
90
        *
91
        *    @since        1.0
92
        *    @version    1.0
93
        *    @var        string
94
        */
95
        private $input;
96
97
        /**
98
        *    Path output
99
        *
100
        *    @since        1.0
101
        *    @version    1.0
102
        *    @var        string
103
        */
104
        private $destination_directory;
105
106
        /**
107
        *    Output filename
108
        *
109
        *    @since        1.0
110
        *    @version    1.0
111
        *    @var        string
112
        */
113
        private $filename;
114
115
        /**
116
        *    Max file size
117
        *
118
        *    @since        1.0
119
        *    @version    1.0
120
        *    @var        float
121
        */
122
        private $max_file_size= 0.0;
123
124
        /**
125
        *    List of allowed mime types
126
        *
127
        *    @since        1.0
128
        *    @version    1.0
129
        *    @var        array
130
        */
131
        private $allowed_mime_types = array();
132
133
        /**
134
        *    Callbacks
135
        *
136
        *    @since        1.0
137
        *    @version    1.0
138
        *    @var        array
139
        */
140
        private $callbacks = array('before' => null, 'after' => null);
141
142
        /**
143
        *    File object
144
        *
145
        *    @since        1.0
146
        *    @version    1.0
147
        *    @var        object
148
        */
149
        private $file;
150
151
        /**
152
        *    Helping mime types
153
        *
154
        *    @since        1.0
155
        *    @version    1.0
156
        *    @var        array
157
        */
158
        private $mime_helping = array(
159
            'text'      =>    array('text/plain',),
160
            'image'     =>    array(
161
                'image/jpeg',
162
                'image/jpg',
163
                'image/pjpeg',
164
                'image/png',
165
                'image/gif',
166
            ),
167
            'document'  =>    array(
168
                'application/pdf',
169
                'application/msword',
170
                'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
171
                'application/vnd.openxmlformats-officedocument.presentationml.presentation',
172
                'application/vnd.ms-powerpoint',
173
                'application/vnd.ms-excel',
174
                'application/vnd.oasis.opendocument.spreadsheet',
175
                'application/vnd.oasis.opendocument.presentation',
176
            ),
177
            'video'    =>    array(
178
                'video/3gpp',
179
                'video/3gpp',
180
                'video/x-msvideo',
181
                'video/avi',
182
                'video/mpeg4',
183
                'video/mp4',
184
                'video/mpeg',
185
                'video/mpg',
186
                'video/quicktime',
187
                'video/x-sgi-movie',
188
                'video/x-ms-wmv',
189
                'video/x-flv',
190
            ),
191
        );
192
193
        /**
194
         * The upload error message
195
         * @var array
196
         */
197
        public $error_messages = array();
198
199
        /**
200
         * The upload error message
201
         * @var string
202
         */
203
        protected $error = null;
204
205
        /**
206
         * The logger instance
207
         * @var Log
208
         */
209
        private $logger;
210
211
212
        /**
213
        *    Construct
214
        *
215
        *    @since     0.1
216
        *    @version   1.0.1
217
        *    @return    object
218
        *    @method    object    __construct
219
        */
220
        public function __construct(){
221
            $this->logger =& class_loader('Log', 'classes');
222
            $this->logger->setLogger('Library::Upload');
223
224
            Loader::lang('file_upload');
225
            $obj =& get_instance();
226
227
            $this->error_messages = array(
228
                'upload_err_ini_size' => $obj->lang->get('fu_upload_err_ini_size'),
229
                'upload_err_form_size' => $obj->lang->get('fu_upload_err_form_size'),
230
                'upload_err_partial' => $obj->lang->get('fu_upload_err_partial'),
231
                'upload_err_no_file' => $obj->lang->get('fu_upload_err_no_file'),
232
                'upload_err_no_tmp_dir' => $obj->lang->get('fu_upload_err_no_tmp_dir'),
233
                'upload_err_cant_write' => $obj->lang->get('fu_upload_err_cant_write'),
234
                'upload_err_extension' => $obj->lang->get('fu_upload_err_extension'),
235
                'accept_file_types' => $obj->lang->get('fu_accept_file_types'),
236
                'file_uploads' => $obj->lang->get('fu_file_uploads_disabled'),
237
                'max_file_size' => $obj->lang->get('fu_max_file_size'),
238
                'overwritten_not_allowed' => $obj->lang->get('fu_overwritten_not_allowed'),
239
            );
240
241
            $this->file = array(
242
                'status'                =>    false,    // True: success upload
243
                'mime'                  =>    '',       // Empty string
244
                'filename'              =>    '',       // Empty string
245
                'original'              =>    '',       // Empty string
246
                'size'                  =>    0,        // 0 Bytes
247
                'sizeFormated'          =>    '0B',     // 0 Bytes
248
                'destination'           =>    './',     // Default: ./
249
                'allowed_mime_types'    =>    array(),  // Allowed mime types
250
                'error'                 =>    null,        // File error
251
            );
252
253
            // Change dir to current dir
254
            $this->destination_directory = dirname(__FILE__) . DIRECTORY_SEPARATOR;
255
256
            // Set file array
257
            if (isset($_FILES) && is_array($_FILES)) {
258
                $this->file_array = $_FILES;
259
            } elseif (isset($HTTP_POST_FILES) && is_array($HTTP_POST_FILES)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $HTTP_POST_FILES seems to never exist and therefore isset should always be false.
Loading history...
260
                $this->file_array = $HTTP_POST_FILES;
261
            }
262
            $this->logger->info('The upload file information are : ' .stringfy_vars($this->file_array));
263
        }
264
        /**
265
        *    Set input.
266
        *    If you have $_FILES["file"], you must use the key "file"
267
        *    Example:
268
        *        $object->setInput("file");
269
        *
270
        *    @since     1.0
271
        *    @version   1.0
272
        *    @param     string      $input
273
        *    @return    boolean
274
        *    @method    boolean     setInput
275
        */
276
        public function setInput($input)
277
        {
278
            if (!empty($input) && (is_string($input) || is_numeric($input) )) {
279
                $this->input = $input;
280
            }
281
            return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Upload which is incompatible with the documented return type boolean.
Loading history...
282
        }
283
        /**
284
        *    Set new filename
285
        *    Example:
286
        *        FileUpload::setFilename("new file.txt")
287
        *    Remember:
288
        *        Use %s to retrive file extension
289
        *
290
        *    @since     1.0
291
        *    @version   1.0
292
        *    @param     string      $filename
293
        *    @return    boolean
294
        *    @method    boolean     setFilename
295
        */
296
        public function setFilename($filename)
297
        {
298
            if ($this->isFilename($filename)) {
299
                $this->filename = $filename;
300
            }
301
            return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Upload which is incompatible with the documented return type boolean.
Loading history...
302
        }
303
        /**
304
        *    Set automatic filename
305
        *
306
        *    @since     1.0
307
        *    @version   1.5
308
        *    @param     string      $extension
309
        *    @return    boolean
310
        *    @method    boolean     setAutoFilename
311
        */
312
        public function setAutoFilename()
313
        {
314
            $this->filename = sha1(mt_rand(1, 9999).uniqid());
315
            $this->filename .= time();
316
            return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Upload which is incompatible with the documented return type boolean.
Loading history...
317
        }
318
        /**
319
        *    Set file size limit
320
        *
321
        *    @since     1.0
322
        *    @version   1.0
323
        *    @param     integer     $file_size
324
        *    @return    boolean
325
        *    @method    boolean     setMaxFileSize
326
        */
327
        public function setMaxFileSize($file_size)
328
        {
329
            $file_size = $this->sizeInBytes($file_size);
330
            if (is_numeric($file_size) && $file_size > -1) {
331
                // Get php config
332
                $php_size = $this->sizeInBytes(ini_get('upload_max_filesize'));
0 ignored issues
show
Bug introduced by
ini_get('upload_max_filesize') of type string is incompatible with the type integer expected by parameter $size of Upload::sizeInBytes(). ( Ignorable by Annotation )

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

332
                $php_size = $this->sizeInBytes(/** @scrutinizer ignore-type */ ini_get('upload_max_filesize'));
Loading history...
333
                // Calculate difference
334
                if ($php_size < $file_size) {
335
                    $this->logger->warning('The upload max file size you set [' .$file_size. '] is greather than the PHP configuration for upload max file size [' .$php_size. ']');
336
                }
337
                $this->max_file_size = $file_size;
0 ignored issues
show
Documentation Bug introduced by
The property $max_file_size was declared of type double, but $file_size is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
338
            }
339
            return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Upload which is incompatible with the documented return type boolean.
Loading history...
340
        }
341
        /**
342
        *    Set array mime types
343
        *
344
        *    @since     1.0
345
        *    @version   1.0
346
        *    @param     array       $mimes
347
        *    @return    boolean
348
        *    @method    boolean     setAllowedMimeTypes
349
        */
350
        public function setAllowedMimeTypes(array $mimes)
351
        {
352
            if (count($mimes) > 0) {
353
                array_map(array($this , 'setAllowMimeType'), $mimes);
354
            }
355
            return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Upload which is incompatible with the documented return type boolean.
Loading history...
356
        }
357
        /**
358
        *    Set input callback
359
        *
360
        *    @since     1.0
361
        *    @version   1.0
362
        *    @param     mixed       $callback
363
        *    @return    boolean
364
        *    @method    boolean     setCallbackInput
365
        */
366
        public function setCallbackInput($callback)
367
        {
368
            if (is_callable($callback, false)) {
369
                $this->callbacks['input'] = $callback;
370
            }
371
            return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Upload which is incompatible with the documented return type boolean.
Loading history...
372
        }
373
        /**
374
        *    Set output callback
375
        *
376
        *    @since     1.0
377
        *    @version   1.0
378
        *    @param     mixed       $callback
379
        *    @return    boolean
380
        *    @method    boolean     setCallbackOutput
381
        */
382
        public function setCallbackOutput($callback)
383
        {
384
            if (is_callable($callback, false)) {
385
                $this->callbacks['output'] = $callback;
386
            }
387
            return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Upload which is incompatible with the documented return type boolean.
Loading history...
388
        }
389
        /**
390
        *    Append a mime type to allowed mime types
391
        *
392
        *    @since     1.0
393
        *    @version   1.0.1
394
        *    @param     string      $mime
395
        *    @return    boolean
396
        *    @method    boolean     setAllowMimeType
397
        */
398
        public function setAllowMimeType($mime)
399
        {
400
            if (!empty($mime) && is_string($mime)) {
401
                $this->allowed_mime_types[] = strtolower($mime);
402
                $this->file['allowed_mime_types'][] = strtolower($mime);
403
            } 
404
            return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Upload which is incompatible with the documented return type boolean.
Loading history...
405
        }
406
        /**
407
        *    Set allowed mime types from mime helping
408
        *
409
        *    @since     1.0.1
410
        *    @version   1.0.1
411
        *    @return    boolean
412
        *    @method    boolean    setMimeHelping
413
        */
414
        public function setMimeHelping($name)
415
        {
416
            if (!empty($name) && is_string($name)) {
417
                if (array_key_exists($name, $this->mime_helping)) {
418
                    return $this->setAllowedMimeTypes($this->mime_helping[ $name ]);
419
                }
420
            }
421
            return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Upload which is incompatible with the documented return type boolean.
Loading history...
422
        }
423
        /**
424
        *    Set function to upload file
425
        *    Examples:
426
        *        1.- FileUpload::setUploadFunction("move_uploaded_file");
427
        *        2.- FileUpload::setUploadFunction("copy");
428
        *
429
        *    @since     1.0
430
        *    @version   1.0
431
        *    @param     string      $mime
432
        *    @return    boolean
433
        *    @method    boolean     setUploadFunction
434
        */
435
        public function setUploadFunction($function)
436
        {
437
            if (!empty($function) && (is_array($function) || is_string($function) )) {
438
                if (is_callable( $function)) {
439
                    $this->upload_function = $function;
0 ignored issues
show
Documentation Bug introduced by
It seems like $function of type string or array is incompatible with the declared type mixex of property $upload_function.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
440
                }
441
            }
442
            return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Upload which is incompatible with the documented return type boolean.
Loading history...
443
        }
444
        /**
445
        *    Clear allowed mime types cache
446
        *
447
        *    @since     1.0
448
        *    @version   1.0
449
        *    @return    boolean
450
        *    @method    boolean    clearAllowedMimeTypes
451
        */
452
        public function clearAllowedMimeTypes()
453
        {
454
            $this->allowed_mime_types = array();
455
            $this->file['allowed_mime_types'] = array();
456
            return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Upload which is incompatible with the documented return type boolean.
Loading history...
457
        }
458
        /**
459
        *    Set destination output
460
        *
461
        *    @since     1.0
462
        *    @version   1.0
463
        *    @param     string      $destination_directory      Destination path
464
        *    @param     boolean     $create_if_not_exist
465
        *    @return    boolean
466
        *    @method    boolean     setDestinationDirectory
467
        */
468
        public function setDestinationDirectory($destination_directory, $create_if_not_exist = false) {
469
            $destination_directory = realpath($destination_directory);
470
            if (substr($destination_directory, -1) != DIRECTORY_SEPARATOR) {
471
                $destination_directory .= DIRECTORY_SEPARATOR;
472
            }
473
474
            if ($this->isDirpath($destination_directory)) {
475
                if ($this->dirExists($destination_directory)) {
476
                    $this->destination_directory = $destination_directory;
477
                    if (substr($this->destination_directory, -1) != DIRECTORY_SEPARATOR) {
478
                        $this->destination_directory .= DIRECTORY_SEPARATOR;
479
                    }
480
                    chdir($destination_directory);
481
                } elseif ($create_if_not_exist === true) {
482
                    if (mkdir($destination_directory, 0775, true)) {
483
                        if ($this->dirExists($destination_directory)) {
484
                            $this->destination_directory = $destination_directory;
485
                            if (substr($this->destination_directory, -1) != DIRECTORY_SEPARATOR) {
486
                                $this->destination_directory .= DIRECTORY_SEPARATOR;
487
                            }
488
                            chdir($destination_directory);
489
                        }
490
                    }
491
                    else{
492
                        $this->logger->warning('Can not create the upload directory [' .$destination_directory. ']');
493
                    }
494
                }
495
            }
496
            return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Upload which is incompatible with the documented return type boolean.
Loading history...
497
        }
498
        /**
499
        *    Check file exists
500
        *
501
        *    @since      1.0
502
        *    @version    1.0.1
503
        *    @param      string     $file_destination
504
        *    @return     boolean
505
        *    @method     boolean    fileExists
506
        */
507
        public function fileExists($file_destination)
508
        {
509
            if ($this->isFilename($file_destination)) {
510
                return (file_exists($file_destination) && is_file($file_destination));
511
            }
512
            return false;
513
        }
514
        /**
515
        *    Check dir exists
516
        *
517
        *    @since        1.0
518
        *    @version    1.0.1
519
        *    @param      string     $path
520
        *    @return     boolean
521
        *    @method     boolean    dirExists
522
        */
523
        public function dirExists($path)
524
        {
525
            if ($this->isDirpath($path)) {
526
                return (file_exists($path) && is_dir($path));
527
            }
528
            return false;
529
        }
530
        /**
531
        *    Check valid filename
532
        *
533
        *    @since     1.0
534
        *    @version   1.0.1
535
        *    @param     string      $filename
536
        *    @return    boolean
537
        *    @method    boolean     isFilename
538
        */
539
        public function isFilename($filename)
540
        {
541
            $filename = basename($filename);
542
            return (!empty($filename) && (is_string( $filename) || is_numeric($filename)));
543
        }
544
        /**
545
        *    Validate mime type with allowed mime types,
546
        *    but if allowed mime types is empty, this method return true
547
        *
548
        *    @since     1.0
549
        *    @version   1.0
550
        *    @param     string      $mime
551
        *    @return    boolean
552
        *    @method    boolean     checkMimeType
553
        */
554
        public function checkMimeType($mime)
555
        {
556
            if (count($this->allowed_mime_types) == 0) {
557
                return true;
558
            }
559
            return in_array(strtolower($mime), $this->allowed_mime_types);
560
        }
561
        /**
562
        *    Retrive status of upload
563
        *
564
        *    @since     1.0
565
        *    @version   1.0
566
        *    @return    boolean
567
        *    @method    boolean    getStatus
568
        */
569
        public function getStatus()
570
        {
571
            return $this->file['status'];
572
        }
573
        /**
574
        *    Check valid path
575
        *
576
        *    @since        1.0
577
        *    @version    1.0.1
578
        *    @param        string    $filename
579
        *    @return     boolean
580
        *    @method     boolean    isDirpath
581
        */
582
        public function isDirpath($path)
583
        {
584
            if (!empty( $path) && (is_string( $path) || is_numeric($path) )) {
585
                if (DIRECTORY_SEPARATOR == '/') {
586
                    return (preg_match( '/^[^*?"<>|:]*$/' , $path) == 1 );
587
                } else {
588
                    return (preg_match( "/^[^*?\"<>|:]*$/" , substr($path,2) ) == 1);
589
                }
590
            }
591
            return false;
592
        }
593
        /**
594
        *    Allow overwriting files
595
        *
596
        *    @since      1.0
597
        *    @version    1.0
598
        *    @return     boolean
599
        *    @method     boolean    allowOverwriting
600
        */
601
        public function allowOverwriting()
602
        {
603
            $this->overwrite_file = true;
604
            return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Upload which is incompatible with the documented return type boolean.
Loading history...
605
        }
606
        /**
607
        *    File info
608
        *
609
        *    @since      1.0
610
        *    @version    1.0
611
        *    @return     object
612
        *    @method     object    getInfo
613
        */
614
        public function getInfo()
615
        {
616
            return (object)$this->file;
617
        }
618
619
        public function isUploaded(){
620
            return isset($this->file_array[$this->input])
621
            &&
622
            is_uploaded_file($this->file_array[$this->input]['tmp_name']);
623
        }
624
        /**
625
        *    Upload file
626
        *
627
        *    @since     1.0
628
        *    @version   1.0.1
629
        *    @return    boolean
630
        *    @method    boolean    save
631
        */
632
        public function save(){
633
            //check if file upload is  allowed in the configuration
634
            if(! ini_get('file_uploads')){
635
                $this->setError($this->error_messages['file_uploads']);
636
                return false;
637
            }
638
            if (count($this->file_array) > 0) {
639
                if (array_key_exists($this->input, $this->file_array)) {
640
                    // set original filename if not have a new name
641
                    if (empty($this->filename)) {
642
                        $this->filename = $this->file_array[$this->input]['name'];
643
                    }
644
                    else{
645
                        // Replace %s for extension in filename
646
                        // Before: /[\w\d]*(.[\d\w]+)$/i
647
                        // After: /^[\s[:alnum:]\-\_\.]*\.([\d\w]+)$/iu
648
                        // Support unicode(utf-8) characters
649
                        // Example: "русские.jpeg" is valid; "Zhōngguó.jpeg" is valid; "Tønsberg.jpeg" is valid
650
                        $extension = preg_replace(
651
                            '/^[\p{L}\d\s\-\_\.\(\)]*\.([\d\w]+)$/iu',
652
                            '$1',
653
                            $this->file_array[$this->input]['name']
654
                        );
655
                        $this->filename = $this->filename.'.'.$extension;
656
                    }
657
658
                    // set file info
659
                    $this->file['mime']         = $this->file_array[$this->input]['type'];
660
                    $this->file['tmp']          = $this->file_array[$this->input]['tmp_name'];
661
                    $this->file['original']     = $this->file_array[$this->input]['name'];
662
                    $this->file['size']         = $this->file_array[$this->input]['size'];
663
                    $this->file['sizeFormated'] = $this->sizeFormat($this->file['size']);
664
                    $this->file['destination']  = $this->destination_directory . $this->filename;
665
                    $this->file['filename']     = $this->filename;
666
                    $this->file['error']        = $this->file_array[$this->input]['error'];
667
668
                    $this->logger->info('The upload file information to process is : ' .stringfy_vars($this->file));
669
670
                    //check for php upload error
671
                    if(is_numeric($this->file['error']) && $this->file['error'] > 0){
672
                        $this->setError($this->getPhpUploadErrorMessageByCode($this->file['error']));
673
                        return false;
674
                    }
675
                    
676
                    //check for mime type
677
                    if (!$this->checkMimeType($this->file['mime'])) {
678
                        $this->setError($this->error_messages['accept_file_types']);
679
                        return false;
680
                    }
681
682
                     // Check file size
683
                    if ($this->max_file_size > 0) {
684
                        if ($this->max_file_size < $this->file['size']) {
685
                            $this->setError(sprintf($this->error_messages['max_file_size'], $this->sizeFormat($this->max_file_size)));
686
                            return false;
687
                        }
688
                    }
689
690
                    // Check if exists file
691
                    if ($this->fileExists($this->destination_directory . $this->filename)) {
692
                        // Check if overwrite file
693
                        if ($this->overwrite_file === false) {
694
                            $this->setError($this->error_messages['overwritten_not_allowed']);
695
                            return false;
696
                        }
697
                    }
698
699
                    // Execute input callback
700
                    if (!empty( $this->callbacks['input'])) {
701
                        call_user_func($this->callbacks['input'], (object)$this->file);
702
                    }
703
                   
704
705
                    $this->file['status'] = call_user_func_array(
706
                        $this->upload_function, array(
707
                            $this->file_array[$this->input]['tmp_name'],
708
                            $this->destination_directory . $this->filename
709
                        )
710
                    );
711
712
                    // Execute output callback
713
                    if (!empty( $this->callbacks['output'])) {
714
                        call_user_func($this->callbacks['output'], (object)$this->file);
715
                    }
716
                    return $this->file['status'];
717
                }
718
            }
719
        }
720
721
        /**
722
        *    File size for humans.
723
        *
724
        *    @since      1.0
725
        *    @version    1.0
726
        *    @param      integer    $bytes
727
        *    @param      integer    $precision
728
        *    @return     string
729
        *    @method     string     sizeFormat
730
        */
731
        public function sizeFormat($size, $precision = 2)
732
        {
733
            if($size > 0){
734
                $base       = log($size) / log(1024);
735
                $suffixes   = array('B', 'K', 'M', 'G', 'T');
736
                return round(pow(1024, $base - floor($base)), $precision) . ( isset($suffixes[floor($base)]) ? $suffixes[floor($base)] : '');
737
            }
738
            return null;
739
        }
740
741
        
742
        /**
743
        *    Convert human file size to bytes
744
        *
745
        *    @since      1.0
746
        *    @version    1.0.1
747
        *    @param      integer    $size
748
        *    @return     string
749
        *    @method     string     sizeInBytes
750
        */
751
        public function sizeInBytes($size)
752
        {
753
            $unit = 'B';
754
            $units = array('B' => 0, 'K' => 1, 'M' => 2, 'G' => 3, 'T' => 4);
755
            $matches = array();
756
            preg_match('/(?<size>[\d\.]+)\s*(?<unit>b|k|m|g|t)?/i', $size, $matches);
757
            if (array_key_exists('unit', $matches)) {
758
                $unit = strtoupper($matches['unit']);
759
            }
760
            return (floatval($matches['size']) * pow(1024, $units[$unit]) ) ;
761
        }
762
763
        /**
764
         * Get the upload error message
765
         * @return string
766
         */
767
        public function getError(){
768
            return $this->error;
769
        }
770
771
        /**
772
         * Set the upload error message
773
         * @param string $message the upload error message to set
774
         */
775
        public function setError($message){
776
            $this->logger->info('The upload got error : ' . $message);
777
            $this->error = $message;
778
        }
779
780
        /**
781
         * Get the PHP upload error message for the given code
782
         * @param  int $code the error code
783
         * @return string the error message
784
         */
785
        private function getPhpUploadErrorMessageByCode($code){
786
            $codeMessageMaps = array(
787
                1 => $this->error_messages['upload_err_ini_size'],
788
                2 => $this->error_messages['upload_err_form_size'],
789
                3 => $this->error_messages['upload_err_partial'],
790
                4 => $this->error_messages['upload_err_no_file'],
791
                6 => $this->error_messages['upload_err_no_tmp_dir'],
792
                7 => $this->error_messages['upload_err_cant_write'],
793
                8 => $this->error_messages['upload_err_extension'],
794
            );
795
            return isset($codeMessageMaps[$code]) ? $codeMessageMaps[$code] : null;
796
        }
797
    }
798