Test Failed
Push — 1.0.0-dev ( 76319a...aa9039 )
by nguereza
02:25
created

Upload::setCallbackOutput()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 2
b 0
f 0
nc 2
nop 1
dl 0
loc 5
rs 10
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 MIT License (MIT)
9
     *
10
     * Copyright (c) 2017 TNH Framework
11
     *
12
     * Permission is hereby granted, free of charge, to any person obtaining a copy
13
     * of this software and associated documentation files (the "Software"), to deal
14
     * in the Software without restriction, including without limitation the rights
15
     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
     * copies of the Software, and to permit persons to whom the Software is
17
     * furnished to do so, subject to the following conditions:
18
     *
19
     * The above copyright notice and this permission notice shall be included in all
20
     * copies or substantial portions of the Software.
21
     *
22
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
     * SOFTWARE.
29
     */
30
31
    /**
32
     *    Upload
33
     *
34
     *    A complete class to upload files with php 5 or higher, but the best: very simple to use.
35
     *
36
     *    @author Olaf Erlandsen <[email protected]>
37
     *    @author http://www.webdevfreelance.com/
38
     *
39
     *    @package FileUpload
40
     *    @version 1.5
41
     */
42
    class Upload extends BaseClass {
43
44
        /**
45
         *   Version
46
         *
47
         *   @since      1.5
48
         *   @version    1.0
49
         */
50
        const VERSION = '1.5';
51
52
        /**
53
         *    Upload function name
54
         *    Remember:
55
         *        Default function: move_uploaded_file
56
         *        Native options:
57
         *            - move_uploaded_file (Default and best option)
58
         *            - copy
59
         *
60
         *    @since        1.0
61
         *    @version    1.0
62
         *    @var        string
63
         */
64
        private $uploadFunction = 'move_uploaded_file';
65
66
        /**
67
         *    Array with the information obtained from the
68
         *    variable $_FILES or $HTTP_POST_FILES.
69
         *
70
         *    @since        1.0
71
         *    @version    1.0
72
         *    @var        array
73
         */
74
        private $uploadedFileData = array();
75
76
        /**
77
         *    If the file you are trying to upload already exists it will
78
         *    be overwritten if you set the variable to true.
79
         *
80
         *    @since        1.0
81
         *    @version    1.0
82
         *    @var        boolean
83
         */
84
        private $overwriteFile = false;
85
86
        /**
87
         *    Input element
88
         *    Example:
89
         *        <input type="file" name="file" />
90
         *    Result:
91
         *        FileUpload::$input = file
92
         *
93
         *    @since        1.0
94
         *    @version    1.0
95
         *    @var        string
96
         */
97
        private $input;
98
99
        /**
100
         *    Path output
101
         *
102
         *    @since        1.0
103
         *    @version    1.0
104
         *    @var        string
105
         */
106
        private $destinationDirectory;
107
108
        /**
109
         *    Output filename
110
         *
111
         *    @since        1.0
112
         *    @version    1.0
113
         *    @var        string
114
         */
115
        private $filename;
116
117
        /**
118
         *    Max file size
119
         *
120
         *    @since        1.0
121
         *    @version    1.0
122
         *    @var        float
123
         */
124
        private $maxFileSize = 0.0;
125
126
        /**
127
         *    List of allowed mime types
128
         *
129
         *    @since        1.0
130
         *    @version    1.0
131
         *    @var        array
132
         */
133
        private $allowedMimeTypes = array();
134
135
        /**
136
         *    Callbacks
137
         *
138
         *    @since        1.0
139
         *    @version    1.0
140
         *    @var        array
141
         */
142
        private $callbacks = array();
143
144
        /**
145
         *    File object
146
         *
147
         *    @since        1.0
148
         *    @version    1.0
149
         *    @var        object
150
         */
151
        private $file;
152
153
        /**
154
         *    Helping mime types
155
         *
156
         *    @since        1.0
157
         *    @version    1.0
158
         *    @var        array
159
         */
160
        private $mimeHelping = array(
161
            'text'      =>    array('text/plain',),
162
            'image'     =>    array(
163
                'image/jpeg',
164
                'image/jpg',
165
                'image/pjpeg',
166
                'image/png',
167
                'image/gif',
168
            ),
169
            'document'  =>    array(
170
                'application/pdf',
171
                'application/msword',
172
                'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
173
                'application/vnd.openxmlformats-officedocument.presentationml.presentation',
174
                'application/vnd.ms-powerpoint',
175
                'application/vnd.ms-excel',
176
                'application/vnd.oasis.opendocument.spreadsheet',
177
                'application/vnd.oasis.opendocument.presentation',
178
            ),
179
            'video'    =>    array(
180
                'video/3gpp',
181
                'video/3gpp',
182
                'video/x-msvideo',
183
                'video/avi',
184
                'video/mpeg4',
185
                'video/mp4',
186
                'video/mpeg',
187
                'video/mpg',
188
                'video/quicktime',
189
                'video/x-sgi-movie',
190
                'video/x-ms-wmv',
191
                'video/x-flv',
192
            ),
193
        );
194
195
        /**
196
         * The upload error message
197
         * @var array
198
         */
199
        public $errorMessages = array();
200
201
        /**
202
         * The upload error message
203
         * @var string
204
         */
205
        protected $error = null;
206
207
208
        /**
209
         *    Construct
210
         *
211
         *    @since     0.1
212
         *    @version   1.0.1
213
         *    @return    object
214
         *    @method    object    __construct
215
         */
216
        public function __construct() {
217
            parent::__construct();
218
219
            get_instance()->loader->lang('file_upload');
220
            $this->errorMessages = array(
221
                                    'upload_err_ini_size'     => get_instance()->lang->get('fu_upload_err_ini_size'),
222
                                    'upload_err_form_size'    => get_instance()->lang->get('fu_upload_err_form_size'),
223
                                    'upload_err_partial'      => get_instance()->lang->get('fu_upload_err_partial'),
224
                                    'upload_err_no_file'      => get_instance()->lang->get('fu_upload_err_no_file'),
225
                                    'upload_err_no_tmp_dir'   => get_instance()->lang->get('fu_upload_err_no_tmp_dir'),
226
                                    'upload_err_cant_write'   => get_instance()->lang->get('fu_upload_err_cant_write'),
227
                                    'upload_err_extension'    => get_instance()->lang->get('fu_upload_err_extension'),
228
                                    'accept_file_types'       => get_instance()->lang->get('fu_accept_file_types'),
229
                                    'file_uploads'            => get_instance()->lang->get('fu_file_uploads_disabled'),
230
                                    'max_file_size'           => get_instance()->lang->get('fu_max_file_size'),
231
                                    'overwritten_not_allowed' => get_instance()->lang->get('fu_overwritten_not_allowed'),
232
                                );
233
234
            $this->file = array(
235
                'status'                =>    false, // True: success upload
236
                'mime'                  =>    '', // Empty string
237
                'filename'              =>    '', // Empty string
238
                'original'              =>    '', // Empty string
239
                'size'                  =>    0, // 0 Bytes
240
                'sizeFormated'          =>    '0B', // 0 Bytes
241
                'destination'           =>    './', // Default: ./
242
                'allowed_mime_types'    =>    array(), // Allowed mime types
243
                'error'                 =>    null, // File error
244
            );
245
246
            // Change dir to current dir
247
            $this->destinationDirectory = dirname(__FILE__) . DIRECTORY_SEPARATOR;
248
249
            // Set file array
250
            $this->uploadedFileData = get_instance()->globalvar->files();
251
            $this->logger->info('The upload file information are : ' . stringfy_vars($this->uploadedFileData));
252
        }
253
254
        /**
255
         *    Set input.
256
         *    If you have $_FILES["file"], you must use the key "file"
257
         *    Example:
258
         *        $object->setInput("file");
259
         *
260
         *    @since     1.0
261
         *    @version   1.0
262
         *    @param     string      $input
263
         *    @return    object
264
         *    @method    boolean     setInput
265
         */
266
        public function setInput($input) {
267
            $this->input = $input;
268
            return $this;
269
        }
270
271
        /**
272
         *    Get the file input name
273
         *    @return    string
274
         */
275
        public function getInput() {
276
            return $this->input;
277
        }
278
279
        /**
280
         * Set the file array data generally in constructor this is already set using $_FILES 
281
         * super global
282
         * @param array $fileData the new value
283
         *
284
         * @return object the current instance
285
         */
286
        public function setUploadedFileData(array $fileData){
287
            $this->uploadedFileData = $fileData;
288
            return $this;
289
        }
290
291
         /**
292
         *    Get the uploade file array
293
         *    @return    array
294
         */
295
        public function getUploadedFileData() {
296
            return $this->uploadedFileData;
297
        }
298
299
300
        /**
301
         *    Set new filename
302
         *    Example:
303
         *        FileUpload::setFilename("new file.txt")
304
         *    Remember:
305
         *        Use %s to retrive file extension
306
         *
307
         *    @since     1.0
308
         *    @version   1.0
309
         *    @param     string      $filename
310
         *    @return    object
311
         *    @method    boolean     setFilename
312
         */
313
        public function setFilename($filename) {
314
            if ($this->isFilename($filename)) {
315
                $this->filename = $filename;
316
            }
317
            return $this;
318
        }
319
320
        /**
321
         *    Set automatic filename
322
         *
323
         *    @since     1.0
324
         *    @version   1.5
325
         *    @param     string      $extension
326
         *    @return    object
327
         *    @method    boolean     setAutoFilename
328
         */
329
        public function setAutoFilename() {
330
            $this->filename = sha1(mt_rand(1, 9999) . uniqid()) . time();
331
            return $this;
332
        }
333
334
         /**
335
         *    Get the filename
336
         *    @return    string
337
         */
338
        public function getFilename() {
339
            return $this->filename;
340
        }
341
342
        /**
343
         *    Set file size limit
344
         *
345
         *    @since     1.0
346
         *    @version   1.0
347
         *    @param     double     $fileSize
348
         *    @return    object
349
         *    @method    boolean     setMaxFileSize
350
         */
351
        public function setMaxFileSize($fileSize) {
352
            $fileSize = $this->sizeInBytes($fileSize);
353
            if (is_numeric($fileSize) && $fileSize > -1) {
354
                // Get PHP upload max file size config
355
                $phpMaxUploadSize = $this->sizeInBytes((int) ini_get('upload_max_filesize'));
356
                // Calculate difference
357
                if ($phpMaxUploadSize < $fileSize) {
358
                    $this->logger->warning('The upload max file size you set [' . $fileSize . '] '
359
                            . 'is greather than the PHP configuration for upload max file size [' . $phpMaxUploadSize . ']');
360
                }
361
                $this->maxFileSize = $fileSize;
362
            }
363
            return $this;
364
        }
365
366
         /**
367
         *    Get the max file size
368
         *    @return    double|int
369
         */
370
        public function getMaxFileSize() {
371
            return $this->maxFileSize;
372
        }
373
374
         /**
375
         *    Append a mime type to allowed mime types
376
         *
377
         *    @since     1.0
378
         *    @version   1.0.1
379
         *    @param     string      $mime
380
         *    @return    object
381
         *    @method    boolean     setAllowMimeType
382
         */
383
        public function setAllowMimeType($mime) {
384
            if (!empty($mime) && is_string($mime)) {
385
                $this->allowedMimeTypes[] = strtolower($mime);
386
                $this->file['allowed_mime_types'][] = strtolower($mime);
387
            } 
388
            return $this;
389
        }
390
391
        /**
392
         *    Set array mime types
393
         *
394
         *    @since     1.0
395
         *    @version   1.0
396
         *    @param     array       $mimes
397
         *    @return    object
398
         *    @method    boolean     setAllowedMimeTypes
399
         */
400
        public function setAllowedMimeTypes(array $mimes) {
401
            array_map(array($this, 'setAllowMimeType'), $mimes);
402
            return $this;
403
        }
404
405
        /**
406
         *    Set allowed mime types from mime helping
407
         *
408
         *    @since     1.0.1
409
         *    @version   1.0.1
410
         *    @return    object
411
         *    @method    boolean    setMimeHelping
412
         */
413
        public function setMimeHelping($name) {
414
            if (!empty($name) 
415
                && is_string($name) 
416
                 && array_key_exists($name, $this->mimeHelping)) {
417
                    return $this->setAllowedMimeTypes($this->mimeHelping[$name]);
418
            }
419
            return $this;
420
        }
421
422
        /**
423
         *    Clear allowed mime types cache
424
         *
425
         *    @since     1.0
426
         *    @version   1.0
427
         *    @return    object
428
         *    @method    boolean    clearAllowedMimeTypes
429
         */
430
        public function clearAllowedMimeTypes() {
431
            $this->allowedMimeTypes = array();
432
            $this->file['allowed_mime_types'] = array();
433
            return $this;
434
        }
435
436
        /**
437
         *    Get the list of mimes type allowed
438
         *    @return    array
439
         */
440
        public function getAllowMimeType() {
441
            return $this->allowedMimeTypes;
442
        }
443
444
        /**
445
         *    Set input callback
446
         *
447
         *    @since     1.0
448
         *    @version   1.0
449
         *    @param     mixed       $callback
450
         *    @return    object
451
         *    @method    boolean     setCallbackInput
452
         */
453
        public function setCallbackInput($callback) {
454
            if (is_callable($callback, false)) {
455
                $this->callbacks['input'] = $callback;
456
            }
457
            return $this;
458
        }
459
460
        /**
461
         *    Set output callback
462
         *
463
         *    @since     1.0
464
         *    @version   1.0
465
         *    @param     mixed       $callback
466
         *    @return    object
467
         *    @method    boolean     setCallbackOutput
468
         */
469
        public function setCallbackOutput($callback) {
470
            if (is_callable($callback, false)) {
471
                $this->callbacks['output'] = $callback;
472
            }
473
            return $this;
474
        }
475
476
        /**
477
         *    Get the list of callbacks for "input" and "output"
478
         *    @return    array
479
         */
480
        public function getCallbacks() {
481
            return $this->callbacks;
482
        }
483
484
        /**
485
         *    Set function to upload file
486
         *    Examples:
487
         *        1.- FileUpload::setUploadFunction("move_uploaded_file");
488
         *        2.- FileUpload::setUploadFunction("copy");
489
         *
490
         *    @since     1.0
491
         *    @version   1.0
492
         *    @param     string      $function
493
         *    @return    object
494
         *    @method    boolean     setUploadFunction
495
         */
496
        public function setUploadFunction($function) {
497
            if (is_callable($function)) {
498
                $this->uploadFunction = $function;
499
            }
500
            return $this;
501
        }
502
503
         /**
504
         *    Get the upload function name like "copy", "move_uploaded_file"
505
         *    @return    string
506
         */
507
        public function getUploadFunction() {
508
            return $this->uploadFunction;
509
        }
510
511
        /**
512
         *    Allow overwriting files
513
         *
514
         *    @since      1.0
515
         *    @version    1.0
516
         *    @return     object
517
         *    @method     boolean    allowOverwriting
518
         */
519
        public function allowOverwriting($status = true) {
520
            $this->overwriteFile = $status;
521
            return $this;
522
        }
523
524
         /**
525
         *    Get the allow overwriting
526
         *    @return    boolean
527
         */
528
        public function isAllowOverwriting() {
529
            return $this->overwriteFile ;
530
        }
531
532
        /**
533
         *    Set destination output
534
         *
535
         *    @since     1.0
536
         *    @version   1.0
537
         *    @param     string      $directory      Destination path
538
         *    @param     boolean     $autoCreate
539
         *    @return    object
540
         *    @method    boolean     setDestinationDirectory
541
         */
542
        public function setDestinationDirectory($directory, $autoCreate = false) {
543
            $dir = realpath($directory);
544
            if (substr($dir, -1) != DIRECTORY_SEPARATOR) {
545
                $dir .= DIRECTORY_SEPARATOR;
546
            }
547
            if ($this->isDirpath($dir)) {
548
                if ($this->dirExists($dir)) {
549
                    $this->destinationDirectory = $dir;
550
                    chdir($dir);
551
                } else if ($autoCreate === true) {
552
                    if (mkdir($dir, 0775, true)) {
553
                        $this->destinationDirectory = $dir;
554
                        chdir($dir);
555
                    } else {
556
                        $this->logger->warning('Can not create the upload directory [' . $directory . ']');
557
                    }
558
                }
559
            }
560
            return $this;
561
        }
562
563
        /**
564
         *    Get the destination directory
565
         *    @return    string
566
         */
567
        public function getDestinationDirectory() {
568
            return $this->destinationDirectory ;
569
        }
570
571
        /**
572
         * Check if the file is uploaded
573
         * @return boolean
574
         */
575
        public function isUploaded() {
576
            return isset($this->uploadedFileData[$this->input])
577
                        && is_uploaded_file($this->uploadedFileData[$this->input]['tmp_name']);
578
        }
579
580
        /**
581
         *    Upload file
582
         *
583
         *    @since     1.0
584
         *    @version   1.0.1
585
         *    @return    boolean
586
         *    @method    boolean    save
587
         */
588
        public function save() {
589
            if (count($this->uploadedFileData) > 0 && array_key_exists($this->input, $this->uploadedFileData)) {
590
                // set original filename if not have a new name
591
                if (empty($this->filename)) {
592
                    $this->filename = $this->uploadedFileData[$this->input]['name'];
593
                } else {
594
                    // Replace %s for extension in filename
595
                    // Before: /[\w\d]*(.[\d\w]+)$/i
596
                    // After: /^[\s[:alnum:]\-\_\.]*\.([\d\w]+)$/iu
597
                    // Support unicode(utf-8) characters
598
                    // Example: "русские.jpeg" is valid; "Zhōngguó.jpeg" is valid; "Tønsberg.jpeg" is valid
599
                    $extension = preg_replace(
600
                        '/^[\p{L}\d\s\-\_\.\(\)]*\.([\d\w]+)$/iu',
601
                        '$1',
602
                        $this->uploadedFileData[$this->input]['name']
603
                    );
604
                    $this->filename = $this->filename . '.' . $extension;
605
                }
606
607
                // set file info
608
                $this->file['mime']         = $this->uploadedFileData[$this->input]['type'];
609
                $this->file['tmp']          = $this->uploadedFileData[$this->input]['tmp_name'];
610
                $this->file['original']     = $this->uploadedFileData[$this->input]['name'];
611
                $this->file['size']         = $this->uploadedFileData[$this->input]['size'];
612
                $this->file['sizeFormated'] = $this->sizeFormat($this->file['size']);
613
                $this->file['destination']  = $this->destinationDirectory . $this->filename;
614
                $this->file['filename']     = $this->filename;
615
                $this->file['error']        = $this->uploadedFileData[$this->input]['error'];
616
617
                $this->logger->info('The upload file information to process is : ' . stringfy_vars($this->file));
618
619
                $error = $this->uploadHasError();
620
                if ($error) {
621
                    return false;
622
                }
623
                // Execute input callback
624
                $this->runCallback('input');
625
626
                $this->file['status'] = call_user_func_array(
627
                    $this->uploadFunction, array(
628
                        $this->uploadedFileData[$this->input]['tmp_name'],
629
                        $this->destinationDirectory . $this->filename
630
                    )
631
                );
632
633
                // Execute output callback
634
                $this->runCallback('output');
635
636
                return $this->file['status'];
637
            }
638
            return false;
639
        }
640
641
        /**
642
         * Get the upload error message
643
         * @return string
644
         */
645
        public function getError() {
646
            return $this->error;
647
        }
648
649
         /**
650
         *    Retrive status of upload
651
         *
652
         *    @since     1.0
653
         *    @version   1.0
654
         *    @return    boolean
655
         *    @method    boolean    getStatus
656
         */
657
        public function getStatus() {
658
            return $this->file['status'];
659
        }
660
661
        /**
662
         *    File info
663
         *
664
         *    @since      1.0
665
         *    @version    1.0
666
         *    @return     object
667
         *    @method     object    getInfo
668
         */
669
        public function getInfo() {
670
            return (object) $this->file;
671
        }
672
673
674
        /**
675
         *    Check file exists
676
         *
677
         *    @since      1.0
678
         *    @version    1.0.1
679
         *    @param      string     $file
680
         *    @return     boolean
681
         *    @method     boolean    fileExists
682
         */
683
        protected function fileExists($file) {
684
            return $this->isFilename($file) 
685
                                && file_exists($file) 
686
                                && is_file($file);
687
        }
688
689
        /**
690
         *    Check dir exists
691
         *
692
         *    @since        1.0
693
         *    @version    1.0.1
694
         *    @param      string     $path
695
         *    @return     boolean
696
         *    @method     boolean    dirExists
697
         */
698
        protected function dirExists($path) {
699
            return $this->isDirpath($path) 
700
                                && file_exists($path) 
701
                                && is_dir($path);
702
        }
703
704
        /**
705
         *    Check valid filename
706
         *
707
         *    @since     1.0
708
         *    @version   1.0.1
709
         *    @param     string      $filename
710
         *    @return    boolean
711
         *    @method    boolean     isFilename
712
         */
713
        protected function isFilename($filename) {
714
            $filename = basename($filename);
715
            return (!empty($filename) && (is_string($filename) || is_numeric($filename)));
716
        }
717
718
        /**
719
         *    Validate mime type with allowed mime types,
720
         *    but if allowed mime types is empty, this method return true
721
         *
722
         *    @since     1.0
723
         *    @version   1.0
724
         *    @param     string      $mime
725
         *    @return    boolean
726
         *    @method    boolean     checkMimeType
727
         */
728
        protected function checkMimeType($mime) {
729
            if (count($this->allowedMimeTypes) == 0) {
730
                return true;
731
            }
732
            return in_array(strtolower($mime), $this->allowedMimeTypes);
733
        }
734
       
735
       
736
        /**
737
         *    Check valid path
738
         *
739
         *    @since        1.0
740
         *    @version    1.0.1
741
         *    @param        string    $filename
742
         *    @return     boolean
743
         *    @method     boolean    isDirpath
744
         */
745
        protected function isDirpath($path) {
746
            if (!empty($path) && (is_string($path) || is_numeric($path))) {
747
                if (DIRECTORY_SEPARATOR == '/') {
748
                    return (preg_match('/^[^*?"<>|:]*$/', $path) == 1);
749
                } else {
750
                    return (preg_match("/^[^*?\"<>|:]*$/", substr($path, 2)) == 1);
751
                }
752
            }
753
            return false;
754
        }
755
756
        /**
757
         *    File size for humans.
758
         *
759
         *    @since      1.0
760
         *    @version    1.0
761
         *    @param      integer    $bytes
762
         *    @param      integer    $precision
763
         *    @return     string
764
         *    @method     string     sizeFormat
765
         */
766
        protected function sizeFormat($size, $precision = 2) {
767
            if ($size > 0) {
768
                $base       = log($size) / log(1024);
769
                $suffixes   = array('B', 'K', 'M', 'G', 'T');
770
                $suf = '';
771
                if (isset($suffixes[floor($base)])) {
772
                    $suf = $suffixes[floor($base)];
773
                }
774
                return round(pow(1024, $base - floor($base)), $precision) . $suf;
775
            }
776
            return null;
777
        }
778
779
        
780
        /**
781
         *    Convert human file size to bytes
782
         *
783
         *    @since      1.0
784
         *    @version    1.0.1
785
         *    @param      integer|double    $size
786
         *    @return     integer|double
787
         *    @method     string     sizeInBytes
788
         */
789
        protected function sizeInBytes($size) {
790
            $unit = 'B';
791
            $units = array('B' => 0, 'K' => 1, 'M' => 2, 'G' => 3, 'T' => 4);
792
            $matches = array();
793
            preg_match('/(?<size>[\d\.]+)\s*(?<unit>b|k|m|g|t)?/i', $size, $matches);
794
            if (array_key_exists('unit', $matches)) {
795
                $unit = strtoupper($matches['unit']);
796
            }
797
            return (floatval($matches['size']) * pow(1024, $units[$unit]));
798
        }
799
800
        /**
801
         * Set the upload error message
802
         * @param string $message the upload error message to set
803
         */
804
        protected function setError($message) {
805
            $this->logger->info('The file upload got error : ' . $message);
806
            $this->error = $message;
807
        }
808
809
        /**
810
         * Run the callbacks in the file uploaded
811
         * @param string $type the type of callback "input" or "output"
812
         * @return void 
813
         */
814
        protected function runCallback($type) {
815
            if (!empty($this->callbacks[$type])) {
816
                call_user_func($this->callbacks[$type], (object) $this->file);
817
            }
818
        }
819
820
        /**
821
         * Check if file upload has error
822
         * @return boolean
823
         */
824
        protected function uploadHasError() {
825
            //check if file upload is  allowed in the configuration
826
            if (!ini_get('file_uploads')) {
827
                $this->setError($this->errorMessages['file_uploads']);
828
                return true;
829
            }
830
831
                //check for php upload error
832
            if (is_numeric($this->file['error']) && $this->file['error'] > 0) {
833
                $this->setError($this->getPhpUploadErrorMessageByCode($this->file['error']));
834
                return true;
835
            }
836
            
837
            //check for mime type
838
            if (!$this->checkMimeType($this->file['mime'])) {
839
                $this->setError($this->errorMessages['accept_file_types']);
840
                return true;
841
            }
842
843
                // Check file size
844
            if ($this->maxFileSize > 0 && $this->maxFileSize < $this->file['size']) {
845
                $this->setError(sprintf($this->errorMessages['max_file_size'], $this->sizeFormat($this->maxFileSize)));
846
                return true;
847
            }
848
849
            // Check if exists file
850
            if ($this->fileExists($this->destinationDirectory . $this->filename) && $this->overwriteFile === false) {
851
                $this->setError($this->errorMessages['overwritten_not_allowed']);
852
                return true;
853
            }
854
            return false;
855
        }
856
857
        /**
858
         * Get the PHP upload error message for the given code
859
         * @param  int $code the error code
860
         * @return string the error message
861
         */
862
        protected function getPhpUploadErrorMessageByCode($code) {
863
            $codeMessageMaps = array(
864
                1 => $this->errorMessages['upload_err_ini_size'],
865
                2 => $this->errorMessages['upload_err_form_size'],
866
                3 => $this->errorMessages['upload_err_partial'],
867
                4 => $this->errorMessages['upload_err_no_file'],
868
                6 => $this->errorMessages['upload_err_no_tmp_dir'],
869
                7 => $this->errorMessages['upload_err_cant_write'],
870
                8 => $this->errorMessages['upload_err_extension'],
871
            );
872
            return isset($codeMessageMaps[$code]) ? $codeMessageMaps[$code] : null;
873
        }
874
    }
875