* Moves files from a source folder to a destination folder and updates metadata. * * @param string $sourceFolder The source folder (e.g., "root" or a subfolder). * @param string $destinationFolder The destination folder. * @param array $files An array of file names to move. * @return array An associative array with either a "success" key or an "error" key. */
($sourceFolder, $destinationFolder, $files)
| 999 | * @return array An associative array with either a "success" key or an "error" key. |
| 1000 | */ |
| 1001 | public static function moveFiles($sourceFolder, $destinationFolder, $files) |
| 1002 | { |
| 1003 | $errors = []; |
| 1004 | $storage = self::storage(); |
| 1005 | $isLocal = $storage->isLocal(); |
| 1006 | |
| 1007 | list($sourceDir, $err) = self::resolveFolderPath($sourceFolder, false); |
| 1008 | if ($err) { |
| 1009 | return ["error" => $err]; |
| 1010 | } |
| 1011 | list($destDir, $err) = self::resolveFolderPath($destinationFolder, true); |
| 1012 | if ($err) { |
| 1013 | return ["error" => $err]; |
| 1014 | } |
| 1015 | |
| 1016 | $sourceDir .= DIRECTORY_SEPARATOR; |
| 1017 | $destDir .= DIRECTORY_SEPARATOR; |
| 1018 | |
| 1019 | // Get metadata file paths. |
| 1020 | $srcMetaFile = self::getMetadataFilePath($sourceFolder); |
| 1021 | $destMetaFile = self::getMetadataFilePath($destinationFolder); |
| 1022 | |
| 1023 | $srcMetadata = file_exists($srcMetaFile) ? json_decode(file_get_contents($srcMetaFile), true) : []; |
| 1024 | $destMetadata = file_exists($destMetaFile) ? json_decode(file_get_contents($destMetaFile), true) : []; |
| 1025 | if (!is_array($srcMetadata)) { |
| 1026 | $srcMetadata = []; |
| 1027 | } |
| 1028 | if (!is_array($destMetadata)) { |
| 1029 | $destMetadata = []; |
| 1030 | } |
| 1031 | |
| 1032 | $destEncrypted = false; |
| 1033 | try { |
| 1034 | $destEncrypted = FolderCrypto::isEncryptedOrAncestor((string)$destinationFolder); |
| 1035 | } catch (\Throwable $e) { |
| 1036 | $destEncrypted = false; |
| 1037 | } |
| 1038 | $srcEncrypted = false; |
| 1039 | try { |
| 1040 | $srcEncrypted = FolderCrypto::isEncryptedOrAncestor((string)$sourceFolder); |
| 1041 | } catch (\Throwable $e) { |
| 1042 | $srcEncrypted = false; |
| 1043 | } |
| 1044 | if (!$isLocal && ($srcEncrypted || $destEncrypted)) { |
| 1045 | return ["error" => "Encrypted folders are not supported for remote storage."]; |
| 1046 | } |
| 1047 | |
| 1048 | $movedFiles = []; |
| 1049 | $safeFileNamePattern = REGEX_FILE_NAME; |
| 1050 | |
| 1051 | foreach ($files as $fileName) { |
| 1052 | // Save the original file name for metadata lookup. |
| 1053 | $originalName = basename(trim($fileName)); |
| 1054 | $basename = $originalName; |
| 1055 | |
| 1056 | // Validate the file name. |
| 1057 | if (!preg_match($safeFileNamePattern, $basename)) { |
| 1058 | $errors[] = "$basename has invalid characters."; |
no test coverage detected