(string $folder, string $user, array $perms, int $maxScan = 20000, ?int $maxDepth = null)
| 201 | } |
| 202 | |
| 203 | public static function countVisibleDeep(string $folder, string $user, array $perms, int $maxScan = 20000, ?int $maxDepth = null): array |
| 204 | { |
| 205 | $storage = self::storage(); |
| 206 | $folder = ACL::normalizeFolder($folder); |
| 207 | if (!$storage->isLocal()) { |
| 208 | return self::countVisibleDeepRemote($folder, $user, $perms, $maxScan, $maxDepth); |
| 209 | } |
| 210 | |
| 211 | $canViewFolder = ACL::isAdmin($perms) |
| 212 | || ACL::canRead($user, $perms, $folder) |
| 213 | || ACL::canReadOwn($user, $perms, $folder); |
| 214 | if (!$canViewFolder) { |
| 215 | return ['folders' => 0, 'files' => 0, 'bytes' => 0, 'truncated' => false]; |
| 216 | } |
| 217 | |
| 218 | if ($maxDepth !== null) { |
| 219 | $maxDepth = (int)$maxDepth; |
| 220 | if ($maxDepth <= 0) { |
| 221 | $maxDepth = null; |
| 222 | } |
| 223 | } |
| 224 | |
| 225 | $base = realpath(self::uploadRoot()); |
| 226 | if ($base === false) { |
| 227 | return ['folders' => 0, 'files' => 0, 'bytes' => 0, 'truncated' => false]; |
| 228 | } |
| 229 | |
| 230 | if ($folder === 'root') { |
| 231 | $dir = $base; |
| 232 | $relPrefix = ''; |
| 233 | } else { |
| 234 | $parts = array_filter(explode('/', $folder), fn($p) => $p !== ''); |
| 235 | foreach ($parts as $seg) { |
| 236 | if (!self::isSafeSegment($seg)) { |
| 237 | return ['folders' => 0, 'files' => 0, 'bytes' => 0, 'truncated' => false]; |
| 238 | } |
| 239 | } |
| 240 | $guess = $base . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $parts); |
| 241 | $dir = self::safeReal($base, $guess); |
| 242 | if ($dir === null || !is_dir($dir)) { |
| 243 | return ['folders' => 0, 'files' => 0, 'bytes' => 0, 'truncated' => false]; |
| 244 | } |
| 245 | $relPrefix = implode('/', $parts); |
| 246 | } |
| 247 | |
| 248 | $SKIP = FS::SKIP(); |
| 249 | |
| 250 | $folderCount = 0; |
| 251 | $fileCount = 0; |
| 252 | $totalBytes = 0; |
| 253 | $scanned = 0; |
| 254 | $truncated = false; |
| 255 | |
| 256 | $stack = [[$dir, $relPrefix, 0]]; |
| 257 | while ($stack) { |
| 258 | [$curAbs, $curRel, $depth] = array_pop($stack); |
| 259 | |
| 260 | $relForAcl = ($curRel === '' ? 'root' : $curRel); |
no test coverage detected