Search code examples
phplaravelziplaravel-8php-ziparchive

Laravel download and extract archives


Is there a way to shorten or make it easier to save and decompress an archive in laravel like below?

    public function upload(Request $request, string $slug)
    {
        $request->validate([
            "zipfile" => 'required'
        ]);

        $game = Game::where('slug', $slug)->first();

        if ($request->user()->id != $game->user_id) {
            return response([
                "status" => "invalid",
                "message" => "User is not author of the game"
            ], 400);
        }

        $version = Version::create([
            "game_id" => $game->id,
            "version" => now(),
            "path" => "/$game->slug/temp/index.html",
        ]);

        $dir_path = $game->slug . '/';
        $file = $request->file('zipfile');
        $zip = new ZipArchive();
        $file_new_path = $file->storeAs($dir_path . $version->id, 'zipname', 'public');
        $zipFile = $zip->open(Storage::disk('public')->path($file_new_path));
        if ($zipFile === TRUE) {
            $zip->extractTo(Storage::disk('public')->path($dir_path . $version->id));
            $zip->close();
        } else {
            return response([
                "status" => "invalid",
                "message" => "ZIP file extraction fails"
            ], 400);
        }
        $url = Storage::url($dir_path . $version->id);

        if (file_exists(Storage::disk('public')->path($dir_path . $version->id . "/thumbnail.png"))) {
            $game->thumbnail = url($url . "/thumbnail.png");
            $game->save();
        }
        $version->path = url($url . "/index.html");
        $version->save();
        return response($version);
    }

This code is quite working, but it looks very large, I would like to make it smaller


Solution

  • public function upload(Request $request, string $slug)
    {
        $request->validate([
            "zipfile" => 'required'
        ]);
    
        $game = Game::where('slug', $slug)->first();
    
        if ($request->user()->id != $game->user_id) {
            return response([
                "status" => "invalid",
                "message" => "User is not the author of the game"
            ], 400);
        }
    
        $version = Version::create([
            "game_id" => $game->id,
            "version" => now(),
            "path" => "/$game->slug/temp/index.html",
        ]);
    
        $dir_path = $game->slug . '/';
        $file = $request->file('zipfile');
        $file_new_path = $file->storeAs($dir_path . $version->id, 'zipname', 'public');
        $zipFile = new \ZipArchive();
        $zipFile->open(Storage::disk('public')->path($file_new_path));
    
        if ($zipFile->extractTo(Storage::disk('public')->path($dir_path . $version->id))) {
            $zipFile->close();
    
            $url = Storage::url($dir_path . $version->id);
    
            $thumbnailPath = $dir_path . $version->id . "/thumbnail.png";
            if (Storage::disk('public')->exists($thumbnailPath)) {
                $game->thumbnail = url($url . "/thumbnail.png");
                $game->save();
            }
    
            $version->path = url($url . "/index.html");
            $version->save();
    
            return response($version);
        } else {
            return response([
                "status" => "invalid",
                "message" => "ZIP file extraction fails"
            ], 400);
        }
    }
    

    So i made this changes:

    • Removed the else condition after $zipFile->close(). Since the extraction is done inside the if statement, you can assume it's successful if the code execution reaches that point.
    • Utilized Storage::disk('public')->exists($thumbnailPath) to check if the thumbnail file exists instead of file_exists().
    • Reorganized the code to improve readability.

    By applying these changes, you can make the code more concise and easier to understand.