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