1: <?php
2:
3: /**
4: * Jyxo PHP Library
5: *
6: * LICENSE
7: *
8: * This source file is subject to the new BSD license that is bundled
9: * with this package in the file license.txt.
10: * It is also available through the world-wide-web at this URL:
11: * https://github.com/jyxo/php/blob/master/license.txt
12: */
13:
14: /**
15: * File upload processing.
16: *
17: * @category Jyxo
18: * @package Jyxo_Input
19: * @subpackage Validator
20: * @copyright Copyright (c) 2005-2011 Jyxo, s.r.o.
21: * @license https://github.com/jyxo/php/blob/master/license.txt
22: * @author Jakub Tománek
23: */
24: class Jyxo_Input_Validator_Upload extends Jyxo_Input_Validator_AbstractValidator implements Jyxo_Input_FilterInterface, Jyxo_Input_Validator_ErrorMessage
25: {
26: /**
27: * Return an error if no file was uploaded at all.
28: *
29: * @var boolean
30: */
31: private $requireUpload = true;
32:
33: /**
34: * File index in the $_FILES array.
35: *
36: * @var string
37: */
38: private $name;
39:
40: /**
41: * Error message in case the validation fails.
42: *
43: * @var string
44: */
45: private $error;
46:
47: /**
48: * Upload failed, because no file was uploaded; but no file is required.
49: *
50: * @var boolean
51: */
52: private $failedEmpty = false;
53:
54: /**
55: * Sets if a file is required to be uploaded.
56: *
57: * @param boolean $flag Does the file have to be uploaded
58: * @return Jyxo_Input_Validator_Upload
59: */
60: public function requireUpload($flag = true)
61: {
62: $this->requireUpload = $flag;
63: return $this;
64: }
65:
66: /**
67: * Checks if the file was successfully uploaded.
68: *
69: * @param Jyxo_Input_Upload|string $file File index in the $_FILES array
70: * @return boolean
71: */
72: public function isValid($file)
73: {
74: $valid = false;
75: if (!$file instanceof Jyxo_Input_Upload) {
76: $file = new Jyxo_Input_Upload($file);
77: }
78: if ($file->tmpName() && $this->isUploaded($file->tmpName())) {
79: $valid = true;
80: } else {
81: $postMaxSize = ini_get('post_max_size');
82: $mul = substr($postMaxSize, -1);
83: $mul = ($mul == 'M' ? 1048576 : ($mul == 'K' ? 1024 : ($mul == 'G' ? 1073741824 : 1)));
84: if (isset($_SERVER['CONTENT_LENGTH'])) {
85: if ($_SERVER['CONTENT_LENGTH'] > $mul * (int) $postMaxSize && $postMaxSize) {
86: $this->error = _('The file you are trying to upload is too big.');
87: } else {
88: $this->setError($file->error());
89: }
90: } elseif ($this->requireUpload) {
91: $this->error = _('No file was uploaded.');
92: } else {
93: $this->failedEmpty = true;
94: }
95: }
96:
97: return $valid;
98: }
99:
100: /**
101: * Sets upload errors.
102: *
103: * @param integer $error Error code
104: */
105: private function setError($error)
106: {
107: switch ($error) {
108: case UPLOAD_ERR_PARTIAL:
109: $this->error = _('The uploaded file was only partially uploaded.');
110: break;
111: case UPLOAD_ERR_NO_FILE:
112: if ($this->requireUpload) {
113: $this->error = _('No file was uploaded.');
114: } else {
115: $this->failedEmpty = true;
116: }
117: break;
118: case UPLOAD_ERR_NO_TMP_DIR:
119: $this->error = _('Missing a temporary folder.');
120: break;
121: case UPLOAD_ERR_EXTENSION:
122: $this->error = _('File upload stopped by extension.');
123: break;
124: case UPLOAD_ERR_INI_SIZE:
125: case UPLOAD_ERR_FORM_SIZE:
126: $this->error = _('The file you are trying to upload is too big.');
127: break;
128: default:
129: $this->error = _('Unknown upload error.');
130: break;
131: }
132: }
133:
134: /**
135: * Checks if the file was uploaded.
136: *
137: * @param string $file File index in the $_FILES array
138: * @return boolean
139: */
140: protected function isUploaded($file)
141: {
142: // Ugly ugly eeeew yuk hack, that is unfortunately needed sometimes
143: if (defined('IS_TEST') && IS_TEST) {
144: return true;
145: } else {
146: return is_uploaded_file($file);
147: }
148: }
149:
150: /**
151: * Sets that the file fas successfully uploaded.
152: *
153: * @param Jyxo_Input_Upload $in Uploaded file
154: * @return Jyxo_Input_Upload
155: */
156: public function filter($in)
157: {
158: if (!$this->error && !$this->failedEmpty) {
159: $in->confirmUpload();
160: }
161: return $in;
162: }
163:
164: /**
165: * Returns error message in case of upload error.
166: *
167: * @return string
168: */
169: public function getError()
170: {
171: return $this->error;
172: }
173: }
174: