$entry, 'type' => is_dir($full) ? 'dir' : 'file', 'size' => is_file($full) ? filesize($full) : null, 'modified' => date('Y-m-d H:i:s', filemtime($full)), 'url' => is_file($full) ? wp_upload_dir()['baseurl'] . '/' . ltrim($rel . '/' . $entry, '/') : null, ]; } usort($items, fn($a,$b) => ($a['type'] === $b['type']) ? strcmp($a['name'],$b['name']) : ($a['type']==='dir'?-1:1)); return ['path'=>$rel?:'/','items'=>$items,'count'=>count($items)]; } public static function readFile(array $args): array { $rel = $args['path'] ?? ''; $path = self::safePath($rel); if (!is_file($path)) throw new \RuntimeException("File not found: $rel"); $mime = mime_content_type($path) ?: 'application/octet-stream'; $size = filesize($path); $text_mimes = ['text/','application/json','application/xml','application/javascript']; $is_text = array_filter($text_mimes, fn($m) => str_starts_with($mime, $m)); return [ 'path' => $rel, 'size' => $size, 'mime' => $mime, 'modified' => date('Y-m-d H:i:s', filemtime($path)), 'content' => $is_text ? file_get_contents($path) : base64_encode(file_get_contents($path)), 'encoding' => $is_text ? 'text' : 'base64', ]; } public static function deleteFile(array $args): array { $rel = $args['path'] ?? ''; $path = self::safePath($rel); if (!file_exists($path)) throw new \RuntimeException("File not found: $rel"); if (is_dir($path)) throw new \RuntimeException("Use delete_directory to remove directories."); if (!unlink($path)) throw new \RuntimeException("Failed to delete: $rel"); return ['path'=>$rel,'deleted'=>true]; } public static function deleteDirectory(array $args): array { $rel = $args['path'] ?? ''; if (empty($rel)) throw new \RuntimeException("Cannot delete uploads root."); $path = self::safePath($rel); if (!is_dir($path)) throw new \RuntimeException("Directory not found: $rel"); $files = new \RecursiveIteratorIterator( new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::CHILD_FIRST ); foreach ($files as $f) { $f->isDir() ? rmdir($f->getRealPath()) : unlink($f->getRealPath()); } rmdir($path); return ['path'=>$rel,'deleted'=>true]; } public static function getUploadsInfo(array $args): array { $uploads = wp_upload_dir(); $base = $uploads['basedir']; $size = 0; foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($base)) as $f) { if ($f->isFile()) $size += $f->getSize(); } return [ 'base_dir' => $base, 'base_url' => $uploads['baseurl'], 'total_size' => $size, 'total_size_human' => size_format($size), ]; } }