1: <?php
2:
3: 4: 5:
6: class Quform_Validator_FileUpload extends Quform_Validator_Abstract
7: {
8: const REQUIRED = 'fileUploadRequired';
9: const NUM_REQUIRED = 'fileNumRequired';
10: const TOO_MANY = 'fileTooMany';
11: const TOO_BIG_FILENAME = 'fileTooBigFilename';
12: const TOO_BIG = 'fileTooBig';
13: const NOT_ALLOWED_TYPE_FILENAME = 'fileNotAllowedTypeFilename';
14: const NOT_ALLOWED_TYPE = 'fileNotAllowedType';
15: const NOT_UPLOADED_FILENAME = 'fileNotUploadedFilename';
16: const NOT_UPLOADED = 'fileNotUploaded';
17: const ONLY_PARTIAL_FILENAME = 'fileOnlyPartialFilename';
18: const ONLY_PARTIAL = 'fileOnlyPartial';
19: const NO_FILE = 'noFile';
20: const MISSING_TEMP_FOLDER = 'fileMissingTempFolder';
21: const FAILED_TO_WRITE = 'fileFailedToWrite';
22: const STOPPED_BY_EXTENSION = 'fileStoppedByExtension';
23: const UNKNOWN_ERROR = 'fileUnknownError';
24: const BAD_FORMAT = 'fileBadFormat';
25:
26: const UPLOAD_ERR_TYPE = 128;
27: const UPLOAD_ERR_FILE_SIZE = 129;
28: const UPLOAD_ERR_NOT_UPLOADED = 130;
29:
30: 31: 32: 33:
34: public function __construct(array $options = array())
35: {
36: if ( ! array_key_exists('name', $options) || ! Quform::isNonEmptyString($options['name'])) {
37: throw new InvalidArgumentException("The 'name' option is required");
38: }
39:
40: parent::__construct($options);
41: }
42:
43: 44: 45: 46: 47: 48:
49: public function isValid($value)
50: {
51: $this->reset();
52:
53: $count = count($value);
54:
55: if (isset($_FILES[$this->config('name')]) && isset($_FILES[$this->config('name')]['error'])) {
56: $file = $_FILES[$this->config('name')];
57:
58: if (is_array($file['error'])) {
59: foreach ($file['error'] as $key => $error) {
60: if ($error == UPLOAD_ERR_OK) {
61:
62: if ( ! $this->isUploadedFile($file['tmp_name'][$key])) {
63:
64: $this->setFileUploadError(self::UPLOAD_ERR_NOT_UPLOADED, $file['name'][$key]);
65: return false;
66: }
67:
68: if (apply_filters('quform_disallow_empty_files', true) && $file['size'][$key] <= 0) {
69:
70: $this->setFileUploadError(UPLOAD_ERR_NO_FILE, $file['name'][$key]);
71: return false;
72: }
73:
74: if ($this->config('maximumFileSize') > 0 && $file['size'][$key] > $this->config('maximumFileSize')) {
75:
76: $this->setFileUploadError(self::UPLOAD_ERR_FILE_SIZE, $file['name'][$key]);
77: return false;
78: }
79:
80: $pathInfo = pathinfo($file['name'][$key]);
81: $extension = array_key_exists('extension', $pathInfo) ? strtolower($pathInfo['extension']) : '';
82:
83: if (count($this->config('allowedExtensions')) && ! in_array($extension, $this->config('allowedExtensions'))) {
84:
85: $this->setFileUploadError(self::UPLOAD_ERR_TYPE, $file['name'][$key]);
86: return false;
87: }
88:
89: if ( ! $this->config('allowAllFileTypes') && ! $this->isAllowedFileType($file['name'][$key])) {
90:
91: $this->setFileUploadError(self::UPLOAD_ERR_TYPE, $file['name'][$key]);
92: return false;
93: }
94:
95: $count++;
96: } elseif ($error == UPLOAD_ERR_NO_FILE) {
97: continue;
98: } else {
99: $this->setFileUploadError($error, $file['name'][$key]);
100: return false;
101: }
102: }
103: } else {
104: $this->error(self::BAD_FORMAT);
105: return false;
106: }
107: }
108:
109:
110: if ($this->config('required') && $count == 0) {
111: $this->error(self::REQUIRED);
112: return false;
113: }
114:
115:
116: if ($this->config('minimumNumberOfFiles') > 0 && $count < $this->config('minimumNumberOfFiles')) {
117: $this->error(self::NUM_REQUIRED, array(
118: 'min' => $this->config('minimumNumberOfFiles')
119: ));
120: return false;
121: }
122:
123:
124: if ($this->config('maximumNumberOfFiles') > 0 && $count > $this->config('maximumNumberOfFiles')) {
125: $this->error(self::TOO_MANY, array(
126: 'max' => $this->config('maximumNumberOfFiles')
127: ));
128: return false;
129: }
130:
131: return true;
132: }
133:
134: 135: 136: 137: 138: 139: 140:
141: protected function setFileUploadError($errorCode, $filename = '')
142: {
143: switch ($errorCode) {
144: case UPLOAD_ERR_INI_SIZE:
145: case UPLOAD_ERR_FORM_SIZE:
146: case self::UPLOAD_ERR_FILE_SIZE:
147: if (Quform::isNonEmptyString($filename)) {
148: $this->error(self::TOO_BIG_FILENAME, compact('filename'));
149: } else {
150: $this->error(self::TOO_BIG);
151: }
152: break;
153: case UPLOAD_ERR_PARTIAL:
154: if (Quform::isNonEmptyString($filename)) {
155: $this->error(self::ONLY_PARTIAL_FILENAME, compact('filename'));
156: } else {
157: $this->error(self::ONLY_PARTIAL);
158: }
159: break;
160: case UPLOAD_ERR_NO_FILE:
161: $this->error(self::NO_FILE);
162: break;
163: case UPLOAD_ERR_NO_TMP_DIR:
164: $this->error(self::MISSING_TEMP_FOLDER);
165: break;
166: case UPLOAD_ERR_CANT_WRITE:
167: $this->error(self::FAILED_TO_WRITE);
168: break;
169: case UPLOAD_ERR_EXTENSION:
170: $this->error(self::STOPPED_BY_EXTENSION);
171: break;
172: case self::UPLOAD_ERR_TYPE:
173: if (Quform::isNonEmptyString($filename)) {
174: $this->error(self::NOT_ALLOWED_TYPE_FILENAME, compact('filename'));
175: } else {
176: $this->error(self::NOT_ALLOWED_TYPE);
177: }
178: break;
179: case self::UPLOAD_ERR_NOT_UPLOADED:
180: if (Quform::isNonEmptyString($filename)) {
181: $this->error(self::NOT_UPLOADED_FILENAME, compact('filename'));
182: } else {
183: $this->error(self::NOT_UPLOADED);
184: }
185: break;
186: default:
187: $this->error(self::UNKNOWN_ERROR);
188: break;
189: }
190: }
191:
192: 193: 194: 195: 196: 197:
198: protected function isUploadedFile($filename)
199: {
200: $isUploadedFile = false;
201:
202: if (is_uploaded_file($filename)) {
203: $isUploadedFile = true;
204: } elseif (preg_match('#[/|\\\]quform[/|\\\]uploads[/|\\\]quf#', $filename)) {
205: $isUploadedFile = true;
206: }
207:
208: return apply_filters('quform_is_uploaded_file', $isUploadedFile, $filename);
209: }
210:
211: 212: 213: 214: 215: 216:
217: protected function isAllowedFileType($filename)
218: {
219: $file = wp_check_filetype($filename);
220:
221: if ( ! $file['ext'] || ! $file['type']) {
222: return false;
223: }
224:
225: return true;
226: }
227:
228: 229: 230: 231: 232: 233:
234: public static function getMessageTemplates($key = null)
235: {
236: $messageTemplates = array(
237: self::REQUIRED => __('This field is required', 'quform'),
238:
239: self::NUM_REQUIRED => sprintf(__('Please upload at least %s file(s)', 'quform'), '%min%'),
240:
241: self::TOO_MANY => sprintf(__('You cannot upload more than %s file(s)', 'quform'), '%max%'),
242:
243: self::TOO_BIG_FILENAME => sprintf(__("File '%s' exceeds the maximum allowed file size", 'quform'), '%filename%'),
244: self::TOO_BIG => __('File exceeds the maximum allowed file size', 'quform'),
245:
246: self::NOT_ALLOWED_TYPE_FILENAME => sprintf(__("File type of '%s' is not allowed", 'quform'), '%filename%'),
247: self::NOT_ALLOWED_TYPE => __('File type is not allowed', 'quform'),
248:
249: self::NOT_UPLOADED_FILENAME => sprintf(__("File '%s' is not an uploaded file", 'quform'), '%filename%'),
250: self::NOT_UPLOADED => __('File is not an uploaded file', 'quform'),
251:
252: self::ONLY_PARTIAL_FILENAME => sprintf(__("File '%s' was only partially uploaded", 'quform'), '%filename%'),
253: self::ONLY_PARTIAL => __('File was only partially uploaded', 'quform'),
254: self::NO_FILE => __('No file was uploaded', 'quform'),
255: self::MISSING_TEMP_FOLDER => __('Missing a temporary folder', 'quform'),
256: self::FAILED_TO_WRITE => __('Failed to write file to disk', 'quform'),
257: self::STOPPED_BY_EXTENSION => __('File upload stopped by extension', 'quform'),
258: self::UNKNOWN_ERROR => __('Unknown upload error', 'quform'),
259: self::BAD_FORMAT => __('Data received by the server was not in the expected format', 'quform')
260: );
261:
262: if (is_string($key)) {
263: return array_key_exists($key, $messageTemplates) ? $messageTemplates[$key] : null;
264: }
265:
266: return $messageTemplates;
267: }
268:
269: 270: 271: 272: 273: 274:
275: public static function getDefaultConfig($key = null)
276: {
277: $config = apply_filters('quform_default_config_validator_file_upload', array(
278: 'name' => '',
279: 'allowedExtensions' => array(),
280: 'maximumFileSize' => 10485760,
281: 'minimumNumberOfFiles' => 0,
282: 'maximumNumberOfFiles' => 1,
283: 'allowAllFileTypes' => false,
284: 'required' => false,
285: 'messages' => array(
286: self::REQUIRED => '',
287: self::NUM_REQUIRED => '',
288: self::TOO_MANY => '',
289: self::TOO_BIG_FILENAME => '',
290: self::TOO_BIG => '',
291: self::NOT_ALLOWED_TYPE_FILENAME => '',
292: self::NOT_ALLOWED_TYPE => '',
293: self::NOT_UPLOADED_FILENAME => '',
294: self::NOT_UPLOADED => '',
295: self::ONLY_PARTIAL_FILENAME => '',
296: self::ONLY_PARTIAL => '',
297: self::NO_FILE => '',
298: self::MISSING_TEMP_FOLDER => '',
299: self::FAILED_TO_WRITE => '',
300: self::STOPPED_BY_EXTENSION => '',
301: self::UNKNOWN_ERROR => '',
302: self::BAD_FORMAT => ''
303: )
304: ));
305:
306: $config['type'] = 'fileUpload';
307:
308: if (Quform::isNonEmptyString($key)) {
309: return Quform::get($config, $key);
310: }
311:
312: return $config;
313: }
314: }
315: