Updating Media dependent modules to versions compatible with core Media.
[yaffs-website] / vendor / symfony / http-foundation / File / UploadedFile.php
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 use Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser;
17
18 /**
19  * A file uploaded through a form.
20  *
21  * @author Bernhard Schussek <bschussek@gmail.com>
22  * @author Florian Eckerstorfer <florian@eckerstorfer.org>
23  * @author Fabien Potencier <fabien@symfony.com>
24  */
25 class UploadedFile extends File
26 {
27     private $test = false;
28     private $originalName;
29     private $mimeType;
30     private $size;
31     private $error;
32
33     /**
34      * Accepts the information of the uploaded file as provided by the PHP global $_FILES.
35      *
36      * The file object is only created when the uploaded file is valid (i.e. when the
37      * isValid() method returns true). Otherwise the only methods that could be called
38      * on an UploadedFile instance are:
39      *
40      *   * getClientOriginalName,
41      *   * getClientMimeType,
42      *   * isValid,
43      *   * getError.
44      *
45      * Calling any other method on an non-valid instance will cause an unpredictable result.
46      *
47      * @param string      $path         The full temporary path to the file
48      * @param string      $originalName The original file name of the uploaded file
49      * @param string|null $mimeType     The type of the file as provided by PHP; null defaults to application/octet-stream
50      * @param int|null    $size         The file size provided by the uploader
51      * @param int|null    $error        The error constant of the upload (one of PHP's UPLOAD_ERR_XXX constants); null defaults to UPLOAD_ERR_OK
52      * @param bool        $test         Whether the test mode is active
53      *                                  Local files are used in test mode hence the code should not enforce HTTP uploads
54      *
55      * @throws FileException         If file_uploads is disabled
56      * @throws FileNotFoundException If the file does not exist
57      */
58     public function __construct($path, $originalName, $mimeType = null, $size = null, $error = null, $test = false)
59     {
60         $this->originalName = $this->getName($originalName);
61         $this->mimeType = $mimeType ?: 'application/octet-stream';
62         $this->size = $size;
63         $this->error = $error ?: UPLOAD_ERR_OK;
64         $this->test = (bool) $test;
65
66         parent::__construct($path, UPLOAD_ERR_OK === $this->error);
67     }
68
69     /**
70      * Returns the original file name.
71      *
72      * It is extracted from the request from which the file has been uploaded.
73      * Then it should not be considered as a safe value.
74      *
75      * @return string|null The original name
76      */
77     public function getClientOriginalName()
78     {
79         return $this->originalName;
80     }
81
82     /**
83      * Returns the original file extension.
84      *
85      * It is extracted from the original file name that was uploaded.
86      * Then it should not be considered as a safe value.
87      *
88      * @return string The extension
89      */
90     public function getClientOriginalExtension()
91     {
92         return pathinfo($this->originalName, PATHINFO_EXTENSION);
93     }
94
95     /**
96      * Returns the file mime type.
97      *
98      * The client mime type is extracted from the request from which the file
99      * was uploaded, so it should not be considered as a safe value.
100      *
101      * For a trusted mime type, use getMimeType() instead (which guesses the mime
102      * type based on the file content).
103      *
104      * @return string|null The mime type
105      *
106      * @see getMimeType()
107      */
108     public function getClientMimeType()
109     {
110         return $this->mimeType;
111     }
112
113     /**
114      * Returns the extension based on the client mime type.
115      *
116      * If the mime type is unknown, returns null.
117      *
118      * This method uses the mime type as guessed by getClientMimeType()
119      * to guess the file extension. As such, the extension returned
120      * by this method cannot be trusted.
121      *
122      * For a trusted extension, use guessExtension() instead (which guesses
123      * the extension based on the guessed mime type for the file).
124      *
125      * @return string|null The guessed extension or null if it cannot be guessed
126      *
127      * @see guessExtension()
128      * @see getClientMimeType()
129      */
130     public function guessClientExtension()
131     {
132         $type = $this->getClientMimeType();
133         $guesser = ExtensionGuesser::getInstance();
134
135         return $guesser->guess($type);
136     }
137
138     /**
139      * Returns the file size.
140      *
141      * It is extracted from the request from which the file has been uploaded.
142      * Then it should not be considered as a safe value.
143      *
144      * @return int|null The file size
145      */
146     public function getClientSize()
147     {
148         return $this->size;
149     }
150
151     /**
152      * Returns the upload error.
153      *
154      * If the upload was successful, the constant UPLOAD_ERR_OK is returned.
155      * Otherwise one of the other UPLOAD_ERR_XXX constants is returned.
156      *
157      * @return int The upload error
158      */
159     public function getError()
160     {
161         return $this->error;
162     }
163
164     /**
165      * Returns whether the file was uploaded successfully.
166      *
167      * @return bool True if the file has been uploaded with HTTP and no error occurred
168      */
169     public function isValid()
170     {
171         $isOk = UPLOAD_ERR_OK === $this->error;
172
173         return $this->test ? $isOk : $isOk && is_uploaded_file($this->getPathname());
174     }
175
176     /**
177      * Moves the file to a new location.
178      *
179      * @param string $directory The destination folder
180      * @param string $name      The new file name
181      *
182      * @return File A File object representing the new file
183      *
184      * @throws FileException if, for any reason, the file could not have been moved
185      */
186     public function move($directory, $name = null)
187     {
188         if ($this->isValid()) {
189             if ($this->test) {
190                 return parent::move($directory, $name);
191             }
192
193             $target = $this->getTargetFile($directory, $name);
194
195             set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; });
196             $moved = move_uploaded_file($this->getPathname(), $target);
197             restore_error_handler();
198             if (!$moved) {
199                 throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error)));
200             }
201
202             @chmod($target, 0666 & ~umask());
203
204             return $target;
205         }
206
207         throw new FileException($this->getErrorMessage());
208     }
209
210     /**
211      * Returns the maximum size of an uploaded file as configured in php.ini.
212      *
213      * @return int The maximum size of an uploaded file in bytes
214      */
215     public static function getMaxFilesize()
216     {
217         $iniMax = strtolower(ini_get('upload_max_filesize'));
218
219         if ('' === $iniMax) {
220             return PHP_INT_MAX;
221         }
222
223         $max = ltrim($iniMax, '+');
224         if (0 === strpos($max, '0x')) {
225             $max = intval($max, 16);
226         } elseif (0 === strpos($max, '0')) {
227             $max = intval($max, 8);
228         } else {
229             $max = (int) $max;
230         }
231
232         switch (substr($iniMax, -1)) {
233             case 't': $max *= 1024;
234             // no break
235             case 'g': $max *= 1024;
236             // no break
237             case 'm': $max *= 1024;
238             // no break
239             case 'k': $max *= 1024;
240         }
241
242         return $max;
243     }
244
245     /**
246      * Returns an informative upload error message.
247      *
248      * @return string The error message regarding the specified error code
249      */
250     public function getErrorMessage()
251     {
252         static $errors = array(
253             UPLOAD_ERR_INI_SIZE => 'The file "%s" exceeds your upload_max_filesize ini directive (limit is %d KiB).',
254             UPLOAD_ERR_FORM_SIZE => 'The file "%s" exceeds the upload limit defined in your form.',
255             UPLOAD_ERR_PARTIAL => 'The file "%s" was only partially uploaded.',
256             UPLOAD_ERR_NO_FILE => 'No file was uploaded.',
257             UPLOAD_ERR_CANT_WRITE => 'The file "%s" could not be written on disk.',
258             UPLOAD_ERR_NO_TMP_DIR => 'File could not be uploaded: missing temporary directory.',
259             UPLOAD_ERR_EXTENSION => 'File upload was stopped by a PHP extension.',
260         );
261
262         $errorCode = $this->error;
263         $maxFilesize = UPLOAD_ERR_INI_SIZE === $errorCode ? self::getMaxFilesize() / 1024 : 0;
264         $message = isset($errors[$errorCode]) ? $errors[$errorCode] : 'The file "%s" was not uploaded due to an unknown error.';
265
266         return sprintf($message, $this->getClientOriginalName(), $maxFilesize);
267     }
268 }