1: <?php
2:
3: /*
4: * This file is part of the Symfony package.
5: *
6: * (c) Fabien Potencier <fabien@symfony.com>
7: *
8: * For the full copyright and license information, please view the LICENSE
9: * file that was distributed with this source code.
10: */
11:
12: namespace Symfony\Component\HttpFoundation\File;
13:
14: use Symfony\Component\HttpFoundation\File\Exception\FileException;
15: use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
16:
17: /**
18: * A file uploaded through a form.
19: *
20: * @author Bernhard Schussek <bschussek@gmail.com>
21: * @author Florian Eckerstorfer <florian@eckerstorfer.org>
22: * @author Fabien Potencier <fabien@symfony.com>
23: *
24: * @api
25: */
26: class UploadedFile extends File
27: {
28: /**
29: * Whether the test mode is activated.
30: *
31: * Local files are used in test mode hence the code should not enforce HTTP uploads.
32: *
33: * @var Boolean
34: */
35: private $test = false;
36:
37: /**
38: * The original name of the uploaded file.
39: *
40: * @var string
41: */
42: private $originalName;
43:
44: /**
45: * The mime type provided by the uploader.
46: *
47: * @var string
48: */
49: private $mimeType;
50:
51: /**
52: * The file size provided by the uploader.
53: *
54: * @var string
55: */
56: private $size;
57:
58: /**
59: * The UPLOAD_ERR_XXX constant provided by the uploader.
60: *
61: * @var integer
62: */
63: private $error;
64:
65: /**
66: * Accepts the information of the uploaded file as provided by the PHP global $_FILES.
67: *
68: * The file object is only created when the uploaded file is valid (i.e. when the
69: * isValid() method returns true). Otherwise the only methods that could be called
70: * on an UploadedFile instance are:
71: *
72: * * getClientOriginalName,
73: * * getClientMimeType,
74: * * isValid,
75: * * getError.
76: *
77: * Calling any other method on an non-valid instance will cause an unpredictable result.
78: *
79: * @param string $path The full temporary path to the file
80: * @param string $originalName The original file name
81: * @param string $mimeType The type of the file as provided by PHP
82: * @param integer $size The file size
83: * @param integer $error The error constant of the upload (one of PHP's UPLOAD_ERR_XXX constants)
84: * @param Boolean $test Whether the test mode is active
85: *
86: * @throws FileException If file_uploads is disabled
87: * @throws FileNotFoundException If the file does not exist
88: *
89: * @api
90: */
91: public function __construct($path, $originalName, $mimeType = null, $size = null, $error = null, $test = false)
92: {
93: if (!ini_get('file_uploads')) {
94: throw new FileException(sprintf('Unable to create UploadedFile because "file_uploads" is disabled in your php.ini file (%s)', get_cfg_var('cfg_file_path')));
95: }
96:
97: $this->originalName = $this->getName($originalName);
98: $this->mimeType = $mimeType ?: 'application/octet-stream';
99: $this->size = $size;
100: $this->error = $error ?: UPLOAD_ERR_OK;
101: $this->test = (Boolean) $test;
102:
103: parent::__construct($path, UPLOAD_ERR_OK === $this->error);
104: }
105:
106: /**
107: * Returns the original file name.
108: *
109: * It is extracted from the request from which the file has been uploaded.
110: * Then is should not be considered as a safe value.
111: *
112: * @return string|null The original name
113: *
114: * @api
115: */
116: public function getClientOriginalName()
117: {
118: return $this->originalName;
119: }
120:
121: /**
122: * Returns the original file extension
123: *
124: * It is extracted from the original file name that was uploaded.
125: * Then is should not be considered as a safe value.
126: *
127: * @return string The extension
128: */
129: public function getClientOriginalExtension()
130: {
131: return pathinfo($this->originalName, PATHINFO_EXTENSION);
132: }
133:
134: /**
135: * Returns the file mime type.
136: *
137: * It is extracted from the request from which the file has been uploaded.
138: * Then is should not be considered as a safe value.
139: *
140: * @return string|null The mime type
141: *
142: * @api
143: */
144: public function getClientMimeType()
145: {
146: return $this->mimeType;
147: }
148:
149: /**
150: * Returns the file size.
151: *
152: * It is extracted from the request from which the file has been uploaded.
153: * Then is should not be considered as a safe value.
154: *
155: * @return integer|null The file size
156: *
157: * @api
158: */
159: public function getClientSize()
160: {
161: return $this->size;
162: }
163:
164: /**
165: * Returns the upload error.
166: *
167: * If the upload was successful, the constant UPLOAD_ERR_OK is returned.
168: * Otherwise one of the other UPLOAD_ERR_XXX constants is returned.
169: *
170: * @return integer The upload error
171: *
172: * @api
173: */
174: public function getError()
175: {
176: return $this->error;
177: }
178:
179: /**
180: * Returns whether the file was uploaded successfully.
181: *
182: * @return Boolean True if no error occurred during uploading
183: *
184: * @api
185: */
186: public function isValid()
187: {
188: return $this->error === UPLOAD_ERR_OK;
189: }
190:
191: /**
192: * Moves the file to a new location.
193: *
194: * @param string $directory The destination folder
195: * @param string $name The new file name
196: *
197: * @return File A File object representing the new file
198: *
199: * @throws FileException if the file has not been uploaded via Http
200: *
201: * @api
202: */
203: public function move($directory, $name = null)
204: {
205: if ($this->isValid()) {
206: if ($this->test) {
207: return parent::move($directory, $name);
208: } elseif (is_uploaded_file($this->getPathname())) {
209: $target = $this->getTargetFile($directory, $name);
210:
211: if (!@move_uploaded_file($this->getPathname(), $target)) {
212: $error = error_get_last();
213: throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error['message'])));
214: }
215:
216: @chmod($target, 0666 & ~umask());
217:
218: return $target;
219: }
220: }
221:
222: throw new FileException(sprintf('The file "%s" has not been uploaded via Http', $this->getPathname()));
223: }
224:
225: /**
226: * Returns the maximum size of an uploaded file as configured in php.ini
227: *
228: * @return int The maximum size of an uploaded file in bytes
229: */
230: public static function getMaxFilesize()
231: {
232: $max = trim(ini_get('upload_max_filesize'));
233:
234: if ('' === $max) {
235: return PHP_INT_MAX;
236: }
237:
238: switch (strtolower(substr($max, -1))) {
239: case 'g':
240: $max *= 1024;
241: case 'm':
242: $max *= 1024;
243: case 'k':
244: $max *= 1024;
245: }
246:
247: return (integer) $max;
248: }
249: }
250: