PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 1.0.94
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v1.0.94
2.11.0 2.10.0 2.10.01 2.9.1 2.9.0 2.8.1 2.8.0 2.7.7 2.7.5 2.7.0 2.6.01 2.6.0 2.5.0 2.4.01 trunk 1.0.90 1.0.91 1.0.92 1.0.93 1.0.94 1.0.95 1.0.96 1.0.97 1.0.98 1.0.99 All 78 releases
fluent-community / vendor / wpfluent / framework / src / WPFluent / Http / Request / File.php

File.php in FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses 1.0.94, at vendor/wpfluent/framework/src/WPFluent/Http/Request/File.php

424 lines 10.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCommunity\Framework\Http\Request;
4
5 use RuntimeException;
6 use FluentCommunity\Framework\Support\Util;
7 use FluentCommunity\Framework\Foundation\App;
8 use FluentCommunity\Framework\Validator\Contracts\File as Contract;
9
10 class File extends \SplFileInfo implements Contract
11 {
12 /**
13 * Original file name.
14 *
15 * @var string $originalName
16 */
17 private $originalName;
18
19 /**
20 * Mime type of the file.
21 *
22 * @var string $mimeType
23 */
24 private $mimeType;
25
26 /**
27 * File size in bytes.
28 *
29 * @var int|null $size
30 */
31 private $size;
32
33 /**
34 * File upload error.
35 *
36 * @var int $error
37 */
38 private $error;
39
40 /**
41 * HTTP File instantiator.
42 *
43 * @param $path
44 * @param $originalName
45 * @param null $mimeType
46 * @param null $size
47 * @param null $error
48 */
49 public function __construct(
50 $path,
51 $originalName,
52 $mimeType = null,
53 $size = null,
54 $error = null
55 ) {
56 $this->init($path, $size, $error);
57 $this->originalName = $this->getName($originalName);
58 $this->mimeType = $this->getFileMimeType($mimeType);
59 }
60
61 /**
62 * Init the file object with size and error.
63 *
64 * @param string $path
65 * @param int|null $size
66 * @param string|nill $error
67 * @return void
68 */
69 protected function init($path, $size, $error)
70 {
71 $this->size = $size ?: @filesize($path);
72 $this->error = $error ?: UPLOAD_ERR_OK;
73 parent::__construct($path);
74 }
75
76 /**
77 * @taken from \Symfony\Component\HttpFoundation\File\File
78 *
79 * Returns locale independent base name of the given path.
80 *
81 * @param string $name The new file name
82 *
83 * @return string containing
84 */
85 public function getName($name)
86 {
87 $originalName = str_replace('\\', '/', $name);
88 $pos = strrpos($originalName, '/');
89 $originalName = false === $pos ? $originalName : substr(
90 $originalName, $pos + 1
91 );
92
93 return $originalName;
94 }
95
96 public function getFileMimeType($mimeType)
97 {
98 $mimeType = $mimeType ?: $this->getMimeType();
99
100 if (!$mimeType) {
101 $path = $this->getPathname() ?: $this->getRealPath();
102 if ($handle = @fopen($path, 'rb')) {
103 $data = fread($handle, 8192);
104 $finfo = new \finfo(FILEINFO_MIME_TYPE);
105 $mimeType = $finfo->buffer($data);
106 fclose($handle);
107 }
108 }
109
110 return $mimeType ?: 'application/octet-stream';
111 }
112
113 /**
114 * Get the file upload error.
115 *
116 * @return int
117 */
118 public function getError()
119 {
120 return $this->error;
121 }
122
123 /**
124 * Returns whether the file was uploaded successfully.
125 *
126 * @return bool True if the file has been uploaded with HTTP and no error occurred
127 */
128 public function isValid()
129 {
130 $isOk = UPLOAD_ERR_OK === $this->getError();
131
132 return $isOk && is_uploaded_file($this->getPathname());
133 }
134
135 /**
136 * Returns the original file name.
137 *
138 * @return string The Name Of the file
139 */
140 public function getClientOriginalName()
141 {
142 return $this->originalName;
143 }
144
145 /**
146 * Returns the original file extension.
147 *
148 * It is extracted from the original file name that was uploaded.
149 * Then it should not be considered as a safe value.
150 *
151 * @return string The extension
152 */
153 public function getClientOriginalExtension()
154 {
155 return pathinfo($this->originalName, PATHINFO_EXTENSION);
156 }
157
158 /**
159 * Take an educated guess of the file's extension.
160 *
161 * @return mixed|null
162 */
163 public function guessExtension()
164 {
165 return $this->getMimeTypeAndExtension()['ext'];
166 }
167
168 /**
169 * Take an educated guess of the file's mime type.
170 *
171 * @return string
172 */
173 public function getMimeType()
174 {
175 return $this->getMimeTypeAndExtension()['type'];
176 }
177
178 /**
179 * Take an educated guess of the file's mime type and ext
180 * based on the WordsPress' get_allowed_mime_types.
181 *
182 * @return array
183 * @see https://developer.wordpress.org/reference/functions/get_allowed_mime_types
184 * @see https://developer.wordpress.org/reference/functions/wp_get_mime_types
185 */
186 public function getMimeTypeAndExtension()
187 {
188 $path = $this->getPathname();
189
190 if(!function_exists('wp_check_filetype_and_ext')) {
191 require_once ABSPATH .'wp-admin/includes/file.php';
192 }
193
194 return wp_check_filetype_and_ext($path, $this->originalName);
195 }
196
197 /**
198 * Get original HTTP file array
199 *
200 * @return array
201 */
202 public function toArray()
203 {
204 return [
205 'name' => $this->originalName,
206 'type' => $this->mimeType,
207 'tmp_name' => $this->getPathname(),
208 'error' => $this->error,
209 'size' => $this->size
210 ];
211 }
212
213 /**
214 * Returns the contents of the file.
215 *
216 * @return string the contents of the file
217 *
218 * @throws RuntimeException
219 */
220 public function getContents()
221 {
222 $level = error_reporting(0);
223 $content = file_get_contents($this->getPathname());
224 error_reporting($level);
225 if (false === $content) {
226 $error = error_get_last();
227 throw new RuntimeException($error['message']);
228 }
229
230 return $content;
231 }
232
233 /**
234 * Move the file to a new location.
235 *
236 * @param string $directory Target Path
237 * @param string $name Target file name (optional)
238 * @return self
239 * @throws RuntimeException
240 */
241 public function move($directory, $name = null)
242 {
243 $err = '';
244
245 $target = $this->getTargetFile($directory, $name);
246
247 set_error_handler(function ($_, $msg) use (&$err) { $err = $msg; });
248
249 try {
250 $renamed = rename($this->getPathname(), $target);
251 } finally {
252 restore_error_handler();
253 }
254
255 if (!$renamed) {
256 throw new RuntimeException(
257 sprintf(
258 'Could not move the file "%s" to "%s" (%s).',
259 $this->getPathname(), $target, strip_tags($err)
260 )
261 );
262 }
263
264 @chmod($target, 0666 & ~umask());
265
266 return $target;
267 }
268
269 /**
270 * Save the uploaded file.
271 *
272 * @param string $path
273 * @return self (File Object)
274 * @throws RuntimeException
275 */
276 public function save($path = null)
277 {
278 $path = $this->resolveTargetPath($path);
279
280 return $this->move($path);
281 }
282
283 /**
284 * Save the uploaded file with a given name.
285 *
286 * @param string $name
287 * @param string $path
288 * @return self (File Object)
289 * @throws RuntimeException
290 */
291 public function saveAs($name, $path = null)
292 {
293 $path = $this->resolveTargetPath($path);
294
295 return $this->move($path, $name);
296 }
297
298 /**
299 * Check that the given path exists.
300 *
301 * @param string $path
302 * @return string
303 * @throws RuntimeException
304 */
305 protected function resolveTargetPath($path)
306 {
307 if ($this->isAbsolutePath($path)) {
308
309 $pieces = array_values(
310 array_filter(
311 explode(DIRECTORY_SEPARATOR, $path)
312 )
313 );
314
315 // Sometimes developers can pass a relative directory like an
316 // absolute directory so in that case, If the root is not a
317 // real directory then make it relative and resolve it:
318 // i.e: 'a/relative/path/looks/like/an/absolute/path'
319
320 if (!is_dir(DIRECTORY_SEPARATOR.$pieces[0])) {
321 return $this->resolveTargetPath(trim($path, DIRECTORY_SEPARATOR));
322 }
323
324 $path = dirname($this->getTargetFile($path));
325
326 if (!is_dir($path)) {
327 throw new RuntimeException("Invalid file upload path: {$path}");
328 }
329
330 return $path;
331 }
332
333 $config = App::make('config');
334
335 $default = $config->get(
336 'app.file_upload_path', function() use ($config) {
337 $slug = $config->get('app.slug');
338 $uploadDir = wp_upload_dir()['basedir'];
339 $uploadDir .= DIRECTORY_SEPARATOR . $slug;
340 return $uploadDir;
341 }
342 );
343
344 $path = rtrim(
345 ($default . DIRECTORY_SEPARATOR . $path), DIRECTORY_SEPARATOR
346 );
347
348 if (is_file($path)) {
349 throw new RuntimeException("Invalid file upload path: {$path}");
350 }
351
352 if (!is_dir($path = dirname($this->getTargetFile($path)))) {
353 throw new RuntimeException("Invalid file upload path: {$path}");
354 }
355
356 return $path;
357 }
358
359 /**
360 * Check if given path is absolute.
361 *
362 * @param string $path
363 * @return boolean
364 */
365 function isAbsolutePath($path)
366 {
367 if (!$path) return false;
368
369 // For Unix-like systems
370 if (DIRECTORY_SEPARATOR === '/') {
371 return $path[0] === '/';
372 }
373
374 // For Windows
375 if (DIRECTORY_SEPARATOR === '\\') {
376 return preg_match(
377 '/^[a-zA-Z]:\\\\/', $path
378 ) || substr($path, 0, 2) === '\\\\';
379 }
380
381 return false;
382 }
383
384 /**
385 * Get the URL from the file path.
386 *
387 * @param string $path
388 * @return string
389 */
390 public function url($path = '')
391 {
392 return Util::pathToUrl($path ?: $this->getPathname());
393 }
394
395 /**
396 * Get the target file name to move (full path).
397 *
398 * @param string $directory Target Path
399 * @param string $name Target file name (optional)
400 * @return self
401 * @throws RuntimeException
402 */
403 protected function getTargetFile($directory, $name = null)
404 {
405 if (!is_dir($directory)) {
406 if (false === @mkdir($directory, 0777, true) && !is_dir($directory)) {
407 throw new RuntimeException(
408 sprintf('Unable to create the "%s" directory.', $directory)
409 );
410 }
411 } elseif (!is_writable($directory)) {
412 throw new RuntimeException(
413 sprintf('Unable to write in the "%s" directory.', $directory)
414 );
415 }
416
417 $target = rtrim($directory, "/\\") . DIRECTORY_SEPARATOR . (
418 null === $name ? $this->originalName : $this->getName($name)
419 );
420
421 return new self($target, false);
422 }
423 }
424