Completed
Push — master ( dc597d...b6f006 )
by Lee
07:27
created

UploadFile::getFileType()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Lavibi\Popoya;
4
5
class UploadFile extends AbstractValidator
6
{
7
    const NO_LIMIT_SIZE = 0;
8
    const ALL_TYPE = [];
9
10
    /**
11
     * Error code : PHP upload error code.
12
     */
13
    const PHP_INI_SIZE = 'ini_size';
14
    const PHP_FORM_SIZE = 'form_size';
15
    const PHP_PARTIAL = 'partial';
16
    const PHP_NO_FILE = 'no_file';
17
    const PHP_NO_TMP_DIR = 'no_tmp_dir';
18
    const PHP_CANT_WRITE = 'cant_write';
19
    const PHP_EXTENSION = 'err_extension';
20
21
    /**
22
     * Error code : Unknown error
23
     */
24
    const NO_UPLOADED_FILE = 'no_uploaded_file';
25
26
    /**
27
     * Error code : Not valid type
28
     */
29
    const NOT_VALID_TYPE = 'not_valid_type';
30
31
    const LARGE_SIZE = 'large_size';
32
33
    /**
34
     * Error messages
35
     *
36
     * @var array
37
     */
38
    protected $messages = [
39
        self::PHP_INI_SIZE => 'Uploaded file exceeds the defined PHP INI size.',
40
        self::PHP_FORM_SIZE => 'Uploaded file exceeds the defined form size.',
41
        self::PHP_PARTIAL => 'Uploaded file was only partially uploaded.',
42
        self::PHP_NO_FILE => 'Uploaded file was not uploaded.',
43
        self::PHP_NO_TMP_DIR => 'Missing a temporary folder.',
44
        self::PHP_CANT_WRITE => 'Failed to write uploaded file to disk.',
45
        self::PHP_EXTENSION => 'Uploaded file was stopped by extension.',
46
        self::NO_UPLOADED_FILE => 'No uploaded file.',
47
        self::NOT_VALID_TYPE => 'Uploaded file has not valid type.',
48
        self::LARGE_SIZE => 'Uploaded file was too large.'
49
    ];
50
51
    /**
52
     * Size limit upload file, in byte.
53
     *
54
     * @param int $size
55
     *
56
     * @return $this
57
     */
58
    public function hasMaxSize($size)
59
    {
60
        $this->options['maxsize'] = (int) $size;
61
62
        return $this;
63
    }
64
65
    /**
66
     * Set allow file type (image/gif, image/png ...)
67
     *
68
     * @param string $type
69
     *
70
     * @return $this
71
     */
72
    public function allowType($type)
73
    {
74
        $this->options['type'][] = (string) $type;
75
76
        return $this;
77
    }
78
79
    /**
80
     * Validate.
81
     *
82
     * @param [] $value
0 ignored issues
show
Documentation introduced by
The doc-type [] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
83
     *
84
     * @return boolean
85
     */
86
    public function isValid($value)
87
    {
88
        $this->value = $value;
89
90
        if (!$this->isValidUploadFile($value['tmp_name'], $value['error'])) {
91
            return false;
92
        }
93
94
        if (!$this->isValidSize($value['size'])) {
95
            return false;
96
        }
97
98
        $value['type'] = $this->getFileType($value['tmp_name']);
99
100
        if (!$this->isValidFileType($value['type'])) {
101
            return false;
102
        }
103
104
        $this->standardValue = [
105
            'name' => $value['name'],
106
            'type' => $value['type'],
107
            'path' => $value['tmp_name'],
108
            'ext' => $this->getFileExt($value['name']),
109
            'size' => $value['size']
110
        ];
111
112
        return true;
113
    }
114
115
    /**
116
     * Validate uploaded file.
117
     *
118
     * @param string $path
119
     * @param int $error
120
     *
121
     * @return boolean
122
     */
123
    protected function isValidUploadFile($path, $error)
124
    {
125
        $case = [
126
            \UPLOAD_ERR_INI_SIZE => self::PHP_INI_SIZE,
127
            \UPLOAD_ERR_FORM_SIZE => self::PHP_FORM_SIZE,
128
            \UPLOAD_ERR_PARTIAL => self::PHP_PARTIAL,
129
            \UPLOAD_ERR_NO_FILE => self::PHP_NO_FILE,
130
            \UPLOAD_ERR_NO_TMP_DIR => self::PHP_NO_TMP_DIR,
131
            \UPLOAD_ERR_CANT_WRITE => self::PHP_CANT_WRITE,
132
            \UPLOAD_ERR_EXTENSION => self::PHP_EXTENSION
133
        ];
134
135
        if (isset($case[$error])) {
136
            $this->setError($case[$error]);
137
            return false;
138
        }
139
140
        if (!is_uploaded_file($path)) {
141
            $this->setError(self::NO_UPLOADED_FILE);
142
            return false;
143
        }
144
145
        return true;
146
    }
147
148
    /**
149
     * Validate size of uploaded file.
150
     *
151
     * @param int $size
152
     *
153
     * @return boolean
154
     */
155
    protected function isValidSize($size)
156
    {
157
        if ($this->options['maxsize'] === 0) {
158
            return true;
159
        }
160
161
        if ($size > $this->options['maxsize']) {
162
            $this->setError(self::LARGE_SIZE);
163
            return false;
164
        }
165
166
        return true;
167
    }
168
169
    protected function isValidFileType($type)
170
    {
171
        // Allow all mines
172
        if ($this->options['type'] === []) {
173
            return true;
174
        }
175
176
        // Not valid mine
177
        if (!in_array($type, $this->options['type'])) {
178
            $this->setError(self::NOT_VALID_TYPE);
179
            return false;
180
        }
181
182
        return true;
183
    }
184
185
    /**
186
     * Init.
187
     *
188
     * Set default options.
189
     */
190
    protected function init()
191
    {
192
        $this->defaultOptions = [
193
            'maxsize' => self::NO_LIMIT_SIZE,
194
            'type' => self::ALL_TYPE
195
        ];
196
    }
197
198
    /**
199
     * Get file type
200
     *
201
     * TODO: move to new project
202
     *
203
     * @param string $file File path
204
     * @return string
205
     */
206
    protected function getFileType($file)
207
    {
208
        $finfo = new \finfo();
209
        $type = $finfo->file($file, FILEINFO_MIME_TYPE);
210
211
        return $type;
212
    }
213
214
    /**
215
     * Get file extension
216
     *
217
     * TODO: move to new project
218
     *
219
     * @param string $file File name
220
     * @return string
221
     *
222
     *
223
     */
224
    protected function getFileExt($file)
225
    {
226
        $part = explode('.', $file);
227
228
        if (count($part) === 1) {
229
            return '';
230
        }
231
232
        return strtolower(end($part));
233
    }
234
}
235