1: <?php
2:
3: /*
4: * The MIT License
5: *
6: * Copyright 2017 David Schoenbauer <dschoenbauer@gmail.com>.
7: *
8: * Permission is hereby granted, free of charge, to any person obtaining a copy
9: * of this software and associated documentation files (the "Software"), to deal
10: * in the Software without restriction, including without limitation the rights
11: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12: * copies of the Software, and to permit persons to whom the Software is
13: * furnished to do so, subject to the following conditions:
14: *
15: * The above copyright notice and this permission notice shall be included in
16: * all copies or substantial portions of the Software.
17: *
18: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24: * THE SOFTWARE.
25: */
26:
27: namespace DSchoenbauer\FileUpload;
28:
29: use finfo;
30:
31: /**
32: * One class to manage all PHP file upload needs
33: *
34: * @author David Schoenbauer <dschoenbauer@gmail.com>
35: * @since 1.0.0
36: */
37: class FileUpload {
38:
39: private $allowedTypes = [];
40: private $allowedFileSize = 0;
41:
42: /**
43: * @param array $allowedTypes array of allowed mime types. The key must be the file extention
44: * @param integer $allowedFileSize maximum file size in megabytes
45: */
46: public function __construct(array $allowedTypes = [], $allowedFileSize = 0) {
47: $this->setAllowedTypes($allowedTypes)->setAllowedFileSize($allowedFileSize);
48: }
49:
50: /**
51: * Defines which file types are allowed
52: * @return array
53: */
54: function getAllowedTypes() {
55: return $this->allowedTypes;
56: }
57:
58: /**
59: * Defines which file types are allowed
60: * @param array $allowedTypes expects an array with a file extention as the key and the value as the mime-type
61: * @return $this
62: */
63: function setAllowedTypes(array $allowedTypes) {
64: $this->allowedTypes = $allowedTypes;
65: return $this;
66: }
67:
68: /**
69: * Provides the maximum allowed file size in megabytes
70: * @return integer returns the maximum file size allowed
71: */
72: public function getAllowedFileSize() {
73: return $this->allowedFileSize;
74: }
75:
76: /**
77: * Provide the maximum allowed file size in megabytes
78: * @param integer $allowedFileSize File size in megabytes
79: * @return $this
80: */
81: public function setAllowedFileSize($allowedFileSize) {
82: $this->allowedFileSize = $allowedFileSize * 1024 * 1024;
83: return $this;
84: }
85: /**
86: * Manages the aspects of the uploading of a file to a server
87: * @param type $fileHandle key of the file that will be found in the $_FILES array
88: * @param string $targetFile path and file name of the file. Extention of original file will be applied to this.
89: * @return string computed path of uploaded file
90: * @throws Exception\InvalidParametersException
91: * @throws Exception\NoFileSentException
92: * @throws Exception\FileTooLargeIniException
93: * @throws Exception\FileTooLargeFormException
94: * @throws Exception\UnknownErrorException
95: * @throws Exception\FileTooLargePhpException
96: * @throws Exception\UnsupportedFileType
97: * @throws Exception\FileFailedToMoveException
98: */
99:
100: public function handleFile($fileHandle, $targetFile) {
101: if (!isset($_FILES[$fileHandle]['error']) || is_array($_FILES[$fileHandle]['error'])) {
102: throw new Exception\InvalidParametersException();
103: }
104: switch ($_FILES[$fileHandle]['error']) {
105: case UPLOAD_ERR_OK:
106: break;
107: case UPLOAD_ERR_NO_FILE:
108: throw new Exception\NoFileSentException();
109: case UPLOAD_ERR_INI_SIZE:
110: throw new Exception\FileTooLargeIniException();
111: case UPLOAD_ERR_FORM_SIZE:
112: throw new Exception\FileTooLargeFormException();
113: default:
114: throw new Exception\UnknownErrorException();
115: }
116:
117: if ($_FILES[$fileHandle]['size'] > $this->getAllowedFileSize()) {
118: throw new Exception\FileTooLargePhpException($this->getAllowedFileSize());
119: }
120:
121: $finfo = new finfo(FILEINFO_MIME_TYPE);
122: if (false === $ext = array_search(
123: $finfo->file($_FILES[$fileHandle]['tmp_name']), $this->getAllowedTypes(), true
124: )) {
125: throw new Exception\UnsupportedFileType(array_keys($this->getAllowedTypes()));
126: }
127:
128: $targetFile .= "." . $ext;
129: //var_dump($_FILES[$fileHandle]['tmp_name'], $targetFile, dirname($targetFile),is_writable(dirname($targetFile)));
130:
131: if (!move_uploaded_file($_FILES[$fileHandle]['tmp_name'], $targetFile)) {
132: throw new Exception\FileFailedToMoveException();
133: }
134: return $targetFile;
135: }
136:
137: }
138: