barryvdh / laravel-elfinder

elFinder bundle for Laravel
745 stars 171 forks source link

Unable to rename folder using S3 #319

Open mtariq786 opened 1 year ago

mtariq786 commented 1 year ago

Its working fine on local storage however there is issue on s3 when renaming folder it pops up error i.e image

cdo9 commented 7 months ago

Hey, did you find a solution?

yaminsaiyed commented 1 month ago

I would like to request the addition of the following two functions to the vendor/barryvdh/laravel-elfinder/src/ElfinderController.php

function renameS3Folder($oldFolder, $newFolder)
{
    // Ensure both oldFolder and newFolder have trailing slashes
    $oldFolder = rtrim($oldFolder, '/') . '/';
    $newFolder = rtrim($newFolder, '/');

    // Extract the parent directory from the old folder path
    $parentDirectory = dirname($oldFolder) . '/';

    // Combine the parent directory with the new folder name
    $newFullFolderPath = $parentDirectory . basename($newFolder) . '/';

    try {
        // List all files and directories in the old folder
        $items = Storage::disk('s3')->allFiles($oldFolder);
        $directories = Storage::disk('s3')->allDirectories($oldFolder);

        // Rename files within the old folder
        foreach ($items as $file) {
            // Calculate the new file path
            $newFilePath = str_replace($oldFolder, $newFullFolderPath, $file);

            // Copy the file to the new location
            Storage::disk('s3')->copy($file, $newFilePath);

            // Delete the old file
            Storage::disk('s3')->delete($file);
        }

        // Rename child directories
        foreach ($directories as $dir) {
            // Calculate the new directory path
            $newDirPath = str_replace($oldFolder, $newFullFolderPath, $dir);

            // Create the new directory
            Storage::disk('s3')->makeDirectory($newDirPath);

            // Move files from the old directory to the new directory
            $filesInSubDir = Storage::disk('s3')->allFiles($dir);
            foreach ($filesInSubDir as $fileInSubDir) {
                $newFileInSubDirPath = str_replace($oldFolder, $newFullFolderPath, $fileInSubDir);
                Storage::disk('s3')->copy($fileInSubDir, $newFileInSubDirPath);
                Storage::disk('s3')->delete($fileInSubDir);
            }

            // Delete the old subdirectory if it’s empty
            if (count(Storage::disk('s3')->allFiles($dir)) === 0 && count(Storage::disk('s3')->allDirectories($dir)) === 0) {
                Storage::disk('s3')->deleteDirectory($dir);
            }
        }

        // Optionally, delete the old folder if empty
        if (count(Storage::disk('s3')->allFiles($oldFolder)) === 0 && count(Storage::disk('s3')->allDirectories($oldFolder)) === 0) {
            Storage::disk('s3')->deleteDirectory($oldFolder);
        }

        return response()->json(['message' => 'Folder and files renamed successfully']);
    } catch (\Exception $e) {
        // Log the error for debugging
        \Log::error("Error renaming folder: " . $e->getMessage());
        return response()->json(['error' => 'Failed to rename folder or files'], 500);
    }
}

function checkFileOrFolder($path)
{
    // Check if it's a folder (prefix) by checking for files
    $files = Storage::disk('s3')->files($path);

    if (!empty($files)) {
        // return "Folder exists and contains files.";
        return true;
    } elseif (Storage::disk('s3')->exists($path)) {
        return false;
        //return "File exists.";
    } else {
        return false;
        // return "Neither file nor folder exists.";
    }
}

image

and after that add below lines into your showConnector function

$encoded = str_replace('fls2_', '', request()->target ?? '');
$decoded_name = base64_decode($encoded);

if (request()->cmd == "rename" && $this->checkFileOrFolder($decoded_name)) {
    return $this->renameS3Folder($decoded_name . "/", request()->name . "/");
}

Note: Also you can Override the Package Functionality into your code its working for me also you can reload filemanager after rename the folder