(
StorageAdapterInterface $storage,
string $baseAbs,
int $maxFiles,
int $maxBytes,
int $maxDepth
)
| 1219 | } |
| 1220 | |
| 1221 | private static function scanFolderTreeForCopy( |
| 1222 | StorageAdapterInterface $storage, |
| 1223 | string $baseAbs, |
| 1224 | int $maxFiles, |
| 1225 | int $maxBytes, |
| 1226 | int $maxDepth |
| 1227 | ): array { |
| 1228 | $queue = [ |
| 1229 | ['abs' => $baseAbs, 'rel' => '', 'depth' => 0], |
| 1230 | ]; |
| 1231 | $folders = ['']; |
| 1232 | $filesByFolder = []; |
| 1233 | $errors = []; |
| 1234 | $fileCount = 0; |
| 1235 | $totalBytes = 0; |
| 1236 | |
| 1237 | $SKIP = FS::SKIP(); |
| 1238 | |
| 1239 | while ($queue) { |
| 1240 | $node = array_shift($queue); |
| 1241 | if (!is_array($node)) { |
| 1242 | continue; |
| 1243 | } |
| 1244 | $depth = (int)($node['depth'] ?? 0); |
| 1245 | if ($depth > $maxDepth) { |
| 1246 | return ['error' => 'Folder copy exceeds depth limit.']; |
| 1247 | } |
| 1248 | $abs = (string)($node['abs'] ?? ''); |
| 1249 | if ($abs === '') { |
| 1250 | continue; |
| 1251 | } |
| 1252 | $rel = (string)($node['rel'] ?? ''); |
| 1253 | |
| 1254 | $entries = $storage->list($abs); |
| 1255 | if (!$entries) { |
| 1256 | continue; |
| 1257 | } |
| 1258 | |
| 1259 | foreach ($entries as $name) { |
| 1260 | if ($name === '.' || $name === '..') { |
| 1261 | continue; |
| 1262 | } |
| 1263 | if ($name === '' || $name[0] === '.') { |
| 1264 | continue; |
| 1265 | } |
| 1266 | if (FS::shouldIgnoreEntry($name, $rel)) { |
| 1267 | continue; |
| 1268 | } |
| 1269 | if (!FS::isSafeSegment($name)) { |
| 1270 | continue; |
| 1271 | } |
| 1272 | |
| 1273 | $lower = strtolower($name); |
| 1274 | if (in_array($lower, $SKIP, true)) { |
| 1275 | continue; |
| 1276 | } |
| 1277 | |
| 1278 | $childAbs = $abs . DIRECTORY_SEPARATOR . $name; |
no test coverage detected