Passed
Push — master ( 20faea...42b488 )
by Lee
01:26
created

Upload::allowType()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 5
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Lavibi\Popoya;
4
5
class Upload 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 1
    public function hasMaxSize($size)
59
    {
60 1
        $this->options['maxsize'] = (int) $size;
61
62 1
        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 1
    public function allowType($type)
73
    {
74 1
        $this->options['type'][] = (string) $type;
75
76 1
        return $this;
77
    }
78
79
    /**
80
     * Validate.
81
     *
82
     * @param array $value
83
     *
84
     * @return boolean
85
     */
86 8
    public function isValid($value)
87
    {
88 8
        $this->value = $value;
89
90 8
        if (!$this->isValidUploadFile($value['tmp_name'], $value['error'])) {
91 2
            return false;
92
        }
93
94 6
        if (!$this->isValidSize($value['size'])) {
95 1
            return false;
96
        }
97
98 6
        $value['type'] = $this->getFileType($value['tmp_name']);
99
100 6
        if (!$this->isValidFileType($value['type'])) {
101 2
            return false;
102
        }
103
104 5
        $this->standardValue = [
105 5
            'name' => $value['name'],
106 5
            'type' => $value['type'],
107 5
            'path' => $value['tmp_name'],
108 5
            'ext' => $this->getFileExt($value['name']),
109 5
            'size' => $value['size']
110
        ];
111
112 5
        return true;
113
    }
114
115
    /**
116
     * Validate uploaded file.
117
     *
118
     * @param string $path
119
     * @param int $error
120
     *
121
     * @return boolean
122
     */
123 8
    protected function isValidUploadFile($path, $error)
124
    {
125
        $case = [
126 8
            UPLOAD_ERR_INI_SIZE => self::PHP_INI_SIZE,
127 8
            UPLOAD_ERR_FORM_SIZE => self::PHP_FORM_SIZE,
128 8
            UPLOAD_ERR_PARTIAL => self::PHP_PARTIAL,
129 8
            UPLOAD_ERR_NO_FILE => self::PHP_NO_FILE,
130 8
            UPLOAD_ERR_NO_TMP_DIR => self::PHP_NO_TMP_DIR,
131 8
            UPLOAD_ERR_CANT_WRITE => self::PHP_CANT_WRITE,
132 8
            UPLOAD_ERR_EXTENSION => self::PHP_EXTENSION
133
        ];
134
135 8
        if (isset($case[$error])) {
136 1
            $this->setError($case[$error]);
137 1
            return false;
138
        }
139
140 7
        if (!is_uploaded_file($path)) {
141 1
            $this->setError(self::NO_UPLOADED_FILE);
142 1
            return false;
143
        }
144
145 6
        return true;
146
    }
147
148
    /**
149
     * Validate size of uploaded file.
150
     *
151
     * @param int $size
152
     *
153
     * @return boolean
154
     */
155 6
    protected function isValidSize($size)
156
    {
157 6
        if ($this->options['maxsize'] === 0) {
158 6
            return true;
159
        }
160
161 1
        if ($size > $this->options['maxsize']) {
162 1
            $this->setError(self::LARGE_SIZE);
163 1
            return false;
164
        }
165
166 1
        return true;
167
    }
168
169 6
    protected function isValidFileType($type)
170
    {
171
        // Allow all mines
172 6
        if ($this->options['type'] === []) {
173 3
            return true;
174
        }
175
176
        // Not valid mine
177 4
        if (!in_array($type, $this->options['type'])) {
178 2
            $this->setError(self::NOT_VALID_TYPE);
179 2
            return false;
180
        }
181
182 3
        return true;
183
    }
184
185
    /**
186
     * Init.
187
     *
188
     * Set default options.
189
     */
190 8
    protected function init()
191
    {
192 8
        $this->defaultOptions = [
193 8
            'maxsize' => self::NO_LIMIT_SIZE,
194 8
            'type' => self::ALL_TYPE
195
        ];
196 8
    }
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 6
    protected function getFileType($file)
207
    {
208 6
        $finfo = new \finfo();
209 6
        $type = $finfo->file($file, FILEINFO_MIME_TYPE);
210
211 6
        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 5
    protected function getFileExt($file)
225
    {
226 5
        $part = explode('.', $file);
227
228 5
        if (count($part) === 1) {
229
            return '';
230
        }
231
232 5
        return strtolower(end($part));
233
    }
234
}
235