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.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 1.1.0 All 77 releases
fluent-community / vendor / wpfluent / framework / src / WPFluent / Support / 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/Support/File.php

560 lines 14.2 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\Support;
4
5 /**
6 * Class File
7 *
8 * A wrapper for the WordPress Filesystem API.
9 */
10 class File
11 {
12 /**
13 * Instance of the WordPress Filesystem API.
14 *
15 * @var \WP_Filesystem_Base|false
16 */
17 protected static $filesystem;
18
19 /**
20 * Initialize or return the WordPress Filesystem API instance.
21 *
22 * @return \WP_Filesystem_Base
23 */
24 public static function init()
25 {
26 return static::fileSystem();
27 }
28
29 /**
30 * Initialize or return the WordPress Filesystem API instance.
31 *
32 * @return \WP_Filesystem_Base
33 */
34 public static function fileSystem()
35 {
36 global $wp_filesystem;
37
38 if (isset($wp_filesystem)) {
39 return $wp_filesystem;
40 }
41
42 if (!function_exists('WP_Filesystem')) {
43 require_once ABSPATH . 'wp-admin/includes/file.php';
44 }
45
46 if (!WP_Filesystem()) {
47 throw new \Exception(
48 'Could not initialize the WordPress filesystem.'
49 );
50 }
51
52 if (
53 !isset($wp_filesystem) ||
54 !($wp_filesystem instanceof \WP_Filesystem_Base)
55 ) {
56 throw new \Exception(
57 'The WordPress filesystem object is not set or is invalid.'
58 );
59 }
60
61 return $wp_filesystem;
62 }
63
64 /**
65 * Check if a file or directory exists.
66 *
67 * @param string $path
68 * @return bool
69 */
70 public static function exists($path)
71 {
72 return static::fileSystem()->exists($path);
73 }
74
75 /**
76 * Read the contents of a file.
77 *
78 * @param string $path
79 * @return string
80 */
81 public static function get($path)
82 {
83 return static::fileSystem()->get_contents($path);
84 }
85
86 /**
87 * Read the contents of a file.
88 *
89 * @param string $path
90 * @return string
91 */
92 public static function read($path)
93 {
94 return static::get($path);
95 }
96
97 /**
98 * Read the contents of a file as lines of array.
99 *
100 * @param string $path
101 * @return string
102 */
103 public static function getArray($path)
104 {
105 return static::fileSystem()->get_contents_array($path);
106 }
107
108 /**
109 * Read the contents of a file as lines of array.
110 *
111 * @param string $path
112 * @return string
113 */
114 public static function readAsArray($path)
115 {
116 return static::getArray($path);
117 }
118
119 /**
120 * Write contents to a file.
121 *
122 * @param string $path
123 * @param string $contents
124 * @param int|false $mode The file permissions as octal number.
125 * @return bool
126 */
127 public static function put($path, $contents, $mode = false)
128 {
129 return static::fileSystem()->put_contents(
130 $path, $contents, $mode
131 );
132 }
133
134 /**
135 * Write contents to a file.
136 *
137 * @param string $path
138 * @param string $contents
139 * @param int|false $mode The file permissions as octal number.
140 * @return bool
141 */
142 public static function write($path, $contents, $mode = false)
143 {
144 return static::put($path, $contents, $mode);
145 }
146
147 /**
148 * Append contents to a file.
149 *
150 * @param string $path
151 * @param string $contents
152 * @return bool
153 */
154 public static function append($path, $contents)
155 {
156 $existingContents = static::exists($path) ? static::get($path) : '';
157
158 $newContents = $existingContents . $contents;
159
160 return static::put($path, $newContents);
161 }
162
163 /**
164 * Prepend contents to a file.
165 *
166 * @param string $path
167 * @param string $contents
168 * @return bool
169 */
170 public static function prepend($path, $contents)
171 {
172 $existingContents = static::exists($path) ? static::get($path) : '';
173
174 $newContents = $contents . $existingContents;
175
176 return static::put($path, $newContents);
177 }
178
179
180 /**
181 * Delete a file or directory.
182 *
183 * @param string $path
184 * @param bool $recursive
185 * @return bool
186 */
187 public static function delete($path, $recursive = true)
188 {
189 return static::fileSystem()->delete($path, $recursive);
190 }
191
192 /**
193 * Delete a file or directory.
194 *
195 * @param string $path
196 * @param bool $recursive
197 * @return bool
198 */
199 public static function deleteDirectory($path, $recursive = true)
200 {
201 return static::fileSystem()->delete($path, $recursive, 'd');
202 }
203
204 /**
205 * Delete a file or directory.
206 *
207 * @param string $path
208 * @param bool $recursive
209 * @return bool
210 */
211 public static function rmdir($path, $recursive = true)
212 {
213 return static::fileSystem()->delete($path, $recursive, 'd');
214 }
215
216 /**
217 * Create a directory.
218 *
219 * @param string $path
220 * @param int $chmod
221 * @param string|int|false $chown Optional. A user name or number.
222 * @param string|int|false $chgrp Optional. A group name or number.
223 * @return bool
224 */
225 public static function mkdir(
226 $path, $chmod = FS_CHMOD_DIR, $chown = false, $chgrp = false
227 )
228 {
229 return static::fileSystem()->mkdir($path, $chmod, $chown, $chgrp);
230 }
231
232 /**
233 * Create a directory.
234 *
235 * @param string $path
236 * @param int $chmod
237 * @param string|int|false $chown Optional. A user name or number.
238 * @param string|int|false $chgrp Optional. A group name or number.
239 * @return bool
240 */
241 public static function makeDirectory(
242 $path, $chmod = FS_CHMOD_DIR, $chown = false, $chgrp = false
243 )
244 {
245 return static::mkdir($path, $chmod, $chown, $chgrp);
246 }
247
248 /**
249 * List files and directories in a path.
250 *
251 * @param string $path
252 * @param bool $withHidden
253 * @param bool $recurse
254 * @return array An associative array with details.
255 */
256 public static function list($path, $withHidden = true, $recurse = false)
257 {
258 return static::fileSystem()->dirlist($path, $withHidden, $recurse);
259 }
260
261 /**
262 * Get the list of files and directories as plain array.
263 *
264 * @param string $path
265 * @param bool $withHidden
266 * @return array
267 */
268 public static function getList($path, $withHidden = true)
269 {
270 return array_values(array_map(function ($item) {
271 return $item['name'];
272 }, static::list($path, $withHidden)));
273 }
274
275 /**
276 * List files in a path.
277 *
278 * @param string $path
279 * @param bool $withHidden
280 * @param bool $recurse
281 * @return array An associative array with details.
282 */
283 public static function files($path, $withHidden = true, $recurse = false)
284 {
285 $list = static::list($path, $withHidden, $recurse);
286
287 return array_filter($list, function ($item) {
288 return $item['type'] === 'f';
289 });
290 }
291
292 /**
293 * Get the list of files as plain array.
294 *
295 * @param string $path
296 * @param bool $withHidden
297 * @return array
298 */
299 public static function getFiles($path, $withHidden = true)
300 {
301 return array_values(array_map(function($item) {
302 return $item['name'];
303 }, static::files($path, $withHidden)));
304 }
305
306 /**
307 * List directories in a path.
308 *
309 * @param string $path
310 * @param bool $withHidden
311 * @param bool $recurse
312 * @return array An associative array with details.
313 */
314 public static function directories($path, $withHidden = true, $recurse = true)
315 {
316 $list = static::list($path, $withHidden, $recurse);
317
318 return array_filter($list, function ($item) {
319 return $item['type'] === 'd';
320 });
321 }
322
323 /**
324 * Get the list of directories as plain array.
325 *
326 * @param string $path
327 * @param bool $withHidden
328 * @return array
329 */
330 public static function getDirectories($path, $withHidden = true)
331 {
332 return array_values(array_map(function($item) {
333 return $item['name'];
334 }, static::directories($path, $withHidden)));
335 }
336
337 /**
338 * Copy a file.
339 *
340 * @param string $source
341 * @param string $dest
342 * @param bool $overwrite
343 * @return bool
344 */
345 public static function copy($source, $dest, $overwrite = true)
346 {
347 return static::fileSystem()->copy($source, $dest, $overwrite);
348 }
349
350 /**
351 * Move a file.
352 *
353 * @param string $source
354 * @param string $destination
355 * @param bool $overwrite
356 * @return bool
357 */
358 public static function move($source, $destination, $overwrite = false)
359 {
360 return static::copy(
361 $source, $destination, $overwrite
362 ) && static::delete($source);
363 }
364
365 /**
366 * Get file metadata.
367 *
368 * @param string $path
369 * @return array|false
370 */
371 public static function getInfo($path)
372 {
373 if (!static::exists($path)) {
374 return false;
375 }
376
377 $fs = static::fileSystem();
378
379 $metadata = [
380 'path' => $path,
381 'size' => $fs->size($path),
382 'atime' => $fs->atime($path),
383 'mtime' => $fs->mtime($path),
384 'mode' => $fs->getchmod($path),
385 'is_dir' => $fs->is_dir($path),
386 'is_file' => $fs->is_file($path)
387 ];
388
389 if ($metadata['is_file']) {
390 $metadata['is_image'] = static::isImage($path);
391 if ($metadata['is_image']) {
392 $metadata['image_meta'] = static::getImageMetadata($path);
393 }
394 }
395
396 return $metadata;
397 }
398
399 /**
400 * Get file/dir metadata using stat.
401 *
402 * @param string $path
403 * @return array|false
404 */
405 public static function getStats($path)
406 {
407 if (!static::exists($path)) {
408 return false;
409 }
410
411 clearstatcache();
412
413 $stat = stat($path);
414
415 // Convert permissions to a readable format (e.g., "rw-r--r--")
416 // Get the last 3 characters (user, group, others)
417 $permissions = substr(sprintf('%o', $stat['mode']), -3);
418
419 $permissionsString = '';
420 $permissionsString .= ($stat['mode'] & 0x0100) ? 'r' : '-'; // Owner read
421 $permissionsString .= ($stat['mode'] & 0x0080) ? 'w' : '-'; // Owner write
422 $permissionsString .= ($stat['mode'] & 0x0040) ? 'x' : '-'; // Owner execute
423 $permissionsString .= ($stat['mode'] & 0x0020) ? 'r' : '-'; // Group read
424 $permissionsString .= ($stat['mode'] & 0x0010) ? 'w' : '-'; // Group write
425 $permissionsString .= ($stat['mode'] & 0x0008) ? 'x' : '-'; // Group execute
426 $permissionsString .= ($stat['mode'] & 0x0004) ? 'r' : '-'; // Others read
427 $permissionsString .= ($stat['mode'] & 0x0002) ? 'w' : '-'; // Others write
428 $permissionsString .= ($stat['mode'] & 0x0001) ? 'x' : '-'; // Others execute
429
430 $permissionsNumeric = (int) substr(sprintf('%o', $stat['mode']), -3);
431
432 $metadata = [
433 'path' => $path,
434 'size' => $stat['size'],
435 'size_string' => size_format($stat['size']),
436 'last_modified_timestamp' => $stat['mtime'],
437 'last_modified_at' => date('Y-m-d H:i:s', $stat['mtime']),
438 'last_access_timestamp' => $stat['atime'],
439 'last_accessed_at' => date('Y-m-d H:i:s', $stat['atime']),
440 'last_change_timestamp' => $stat['ctime'],
441 'last_changed_at' => date('Y-m-d H:i:s', $stat['ctime']),
442 'permission' => $permissionsNumeric,
443 'permission_string' => $permissionsString,
444 'is_dir' => ($stat['mode'] & 0040000) === 0040000,
445 'is_file' => ($stat['mode'] & 0100000) === 0100000
446 ];
447
448 if ($metadata['is_file']) {
449 $metadata['is_image'] = static::isImage($path);
450 if ($metadata['is_image']) {
451 $metadata['image_meta'] = static::getImageMetadata($path);
452 }
453 }
454
455 return $metadata;
456 }
457
458
459 /**
460 * Searches for metadata in the first 8 KB of a file.
461 *
462 * @param string $file
463 * @param array $keys
464 * @return array
465 */
466 public static function getMetaData($file, $keys = [])
467 {
468 $data = [];
469
470 if (!file_exists($file)) {
471 return $data;
472 }
473
474 $content = file_get_contents($file, false, null, 0, 8 * 1024);
475
476 if ($content === false) {
477 return $data;
478 }
479
480 $content = str_replace("\r", "\n", $content);
481
482 $pattern = '/^(?:[ \t]*<\?php)?[ \t\/*#@]*(.*?):(.*)$/mi';
483
484 if (preg_match_all($pattern, $content, $matches)) {
485 foreach ($matches[1] as $key => $value) {
486 $name = str_replace(' ', '_', strtolower(trim($value)));
487 $data[$name] = trim($matches[2][$key]);
488 }
489 }
490
491 $normalizedKeys = array_map(function ($key) {
492 return strtolower(str_replace(' ', '_', $key));
493 }, $keys);
494
495 return $keys ? array_intersect_key(
496 $data, array_flip($normalizedKeys)
497 ) : $data;
498 }
499
500 /**
501 * Check if a file is an image based on its MIME type.
502 *
503 * @param string $path
504 * @return bool
505 */
506 public static function isImage($path)
507 {
508 return file_is_valid_image($path);
509 }
510
511 /**
512 * Get image metadata using EXIF.
513 *
514 * @param string $path
515 * @return array|false
516 */
517 public static function getImageMetadata($path)
518 {
519 if (!static::exists($path)) {
520 return false;
521 }
522
523 return wp_read_image_metadata($path) ?: false;
524 }
525
526 /**
527 * Dynamically handle calls to the filesystem API.
528 *
529 * @param string $method
530 * @param array $args
531 * @return mixed
532 */
533 public function __call($method, $args)
534 {
535 $fs = static::fileSystem();
536
537 if (!method_exists($fs, $method)) {
538 $method = strtolower(
539 preg_replace([
540 '/([a-z\d])([A-Z])/', '/([^_])([A-Z][a-z])/'
541 ], '$1_$2', $method)
542 );
543 }
544
545 return $fs->{$method}(...$args);
546 }
547
548 /**
549 * Dynamically handle static calls to the filesystem API.
550 *
551 * @param string $method
552 * @param array $args
553 * @return mixed
554 */
555 public static function __callStatic($method, $args)
556 {
557 return (new static)->{$method}(...$args);
558 }
559 }
560