feat: fix unzip

This commit is contained in:
BillieFaiqul 2025-05-26 21:35:46 +07:00
parent 61982c6275
commit 901e1aca33
11 changed files with 83 additions and 53 deletions

View File

@ -119,54 +119,42 @@ public function download(Request $request, $project_id)
if ($zipMedia) {
return response()->json($zipMedia->getUrl(), 200);
} else {
$tests_api = $project->getMedia('project_tests_api');
$tests_web = $project->getMedia('project_tests_web');
$tests_images = $project->getMedia('project_tests_images');
// Perbaiki collection name sesuai database
$tests = $project->getMedia('project_tests');
// Tambahkan pengecekan apakah ada file tests
if (count($tests) === 0) {
return response()->json(["message" => "no tests available"], 404);
}
$tempDir = storage_path('app/public/assets/projects/' . $project->title . '/zips');
if (!is_dir($tempDir)) mkdir($tempDir);
if (!is_dir($tempDir . '/tests')) mkdir($tempDir . '/tests');
if (!is_dir($tempDir . '/tests/api')) mkdir($tempDir . '/tests/api');
if (!is_dir($tempDir . '/tests/web')) mkdir($tempDir . '/tests/web');
if (!is_dir($tempDir . '/tests/web/images')) mkdir($tempDir . '/tests/web/images');
foreach ($tests_api as $test) {
// Copy semua file tests ke tempDir
foreach ($tests as $test) {
$path = $test->getPath();
$filename = $test->file_name;
copy($path, $tempDir . '/tests/api/' . $filename);
}
foreach ($tests_web as $test) {
$path = $test->getPath();
$filename = $test->file_name;
copy($path, $tempDir . '/tests/web/' . $filename);
}
foreach ($tests_images as $test) {
$path = $test->getPath();
$filename = $test->file_name;
copy($path, $tempDir . '/tests/web/images/' . $filename);
copy($path, $tempDir . '/' . $filename);
}
$zipPath = $tempDir . '/tests.zip';
$zip = new ZipArchive;
if ($zip->open($zipPath, ZipArchive::CREATE) === TRUE) {
$zip->addEmptyDir('api');
$zip->addEmptyDir('web');
$zip->addEmptyDir('web/images');
$api_files = Storage::files('public/assets/projects/' . $project->title . '/zips/tests/api');
foreach ($api_files as $file) {
$zip->addFile(storage_path('app/' . $file), 'api/' . basename($file));
$files = Storage::files('public/assets/projects/' . $project->title . '/zips');
foreach ($files as $file) {
// Skip jika file adalah zip itu sendiri
if (basename(storage_path('app/' . $file)) !== 'tests.zip') {
$zip->addFile(storage_path('app/' . $file), basename($file));
}
}
$api_files = Storage::files('public/assets/projects/' . $project->title . '/zips/tests/web');
foreach ($api_files as $file) {
$zip->addFile(storage_path('app/' . $file), 'web/' . basename($file));
}
$image_files = Storage::files('public/assets/projects/' . $project->title . '/zips/tests/web/images');
foreach ($image_files as $file) {
$zip->addFile(storage_path('app/' . $file), 'web/images/' . basename($file));
}
$zip->close();
Process::fromShellCommandline("rm -rf {$tempDir}/tests")->run();
// Hapus file individual setelah di-zip
foreach ($files as $file) {
if (basename(storage_path('app/' . $file)) !== 'tests.zip') {
unlink(storage_path('app/' . $file));
}
}
} else {
throw new Exception('Failed to create zip archive');
}

View File

@ -126,10 +126,29 @@ public function upload(Request $request, $project_id)
{
if ($request->hasFile('folder_path')) {
$project_title = Project::find($project_id)->title;
$project_title = str_replace([' ', '/', '\\'], '-', $project_title);
$file = $request->file('folder_path');
$file_name = $file->getClientOriginalName();
$folder_path = 'public/tmp/submissions/' . $request->user()->id . '/' . $project_title;
// Hapus temporary file lama jika ada
TemporaryFile::where('folder_path', $folder_path)->delete();
// Hapus folder lama jika ada
$full_folder_path = storage_path('app/' . $folder_path);
if (is_dir($full_folder_path)) {
// Hapus semua file di folder
$files = glob($full_folder_path . '/*');
foreach($files as $file_to_delete) {
if(is_file($file_to_delete)) {
unlink($file_to_delete);
}
}
rmdir($full_folder_path);
}
// Upload file baru
$file->storeAs($folder_path, $file_name);
TemporaryFile::create([
@ -144,7 +163,6 @@ public function upload(Request $request, $project_id)
public function submit(Request $request)
{
try {
$request->validate([
'project_id' => 'required|exists:projects,id',
@ -161,34 +179,55 @@ public function submit(Request $request)
$submission = new Submission();
$submission->user_id = $request->user()->id;
$submission->project_id = $request->project_id;
if ($request->has('folder_path')) {
$submission->type = Submission::$FILE;
$submission->path = $request->folder_path;
$temporary_file = TemporaryFile::where('folder_path', $request->folder_path)->first();
if ($temporary_file) {
$path = storage_path('app/' . $request->folder_path . '/' . $temporary_file->file_name);
$submission->addMedia($path)->toMediaCollection('submissions', 'nodejs_public_submissions_files');
if ($this->is_dir_empty(storage_path('app/' . $request->folder_path))) {
rmdir(storage_path('app/' . $request->folder_path));
}
$temporary_file->delete();
// Debug: Cek apakah temporary file ada
if (!$temporary_file) {
\Log::error('TemporaryFile not found for folder_path: ' . $request->folder_path);
return response()->json(['message' => 'Temporary file not found'], 400);
}
$file_path = storage_path('app/' . $request->folder_path . '/' . $temporary_file->file_name);
// Debug: Cek apakah file fisik ada
if (!file_exists($file_path)) {
\Log::error('Physical file not found: ' . $file_path);
return response()->json(['message' => 'Physical file not found'], 400);
}
try {
$submission->addMedia($file_path)->toMediaCollection('submissions', 'nodejs_public_submissions_files');
} catch (\Exception $e) {
\Log::error('Media collection error: ' . $e->getMessage());
return response()->json(['message' => 'Failed to add media: ' . $e->getMessage()], 500);
}
// Cleanup
if ($this->is_dir_empty(storage_path('app/' . $request->folder_path))) {
rmdir(storage_path('app/' . $request->folder_path));
}
$temporary_file->delete();
} else {
$submission->type = Submission::$URL;
$submission->path = $request->github_url;
}
$submission->status = Submission::$PENDING;
$submission->start = now();
$submission->save();
return response()->json([
'message' => 'Submission created successfully',
'submission' => $submission,
], 201);
} catch (\Throwable $th) {
\Log::error('Submission error: ' . $th->getMessage() . ' | Line: ' . $th->getLine() . ' | File: ' . $th->getFile());
return response()->json([
'message' => 'Submission failed',
'error' => $th->getMessage(),
@ -707,7 +746,7 @@ public function changeSourceCode($submission_id)
$user = Auth::user();
$submission = Submission::where('id', $submission_id)->where('user_id', $user->id)->first();
if ($submission) {
return view('submissions.change_source_code', compact('submission'));
return view('nodejs.submissions.change_source_code', compact('submission'));
}
return redirect()->route('submissions');
}
@ -747,7 +786,7 @@ public function update(Request $request)
if ($temporary_file) {
$path = storage_path('app/' . $request->folder_path . '/' . $temporary_file->file_name);
$submission->addMedia($path)->toMediaCollection('submissions', 'public_submissions_files');
$submission->addMedia($path)->toMediaCollection('submissions', 'nodejs_public_submissions_files');
if ($this->is_dir_empty(storage_path('app/' . $request->folder_path))) {
rmdir(storage_path('app/' . $request->folder_path));
}

View File

@ -1,9 +1,9 @@
<?php
namespace App\Jobs;
namespace App\Jobs\NodeJS;
use App\Models\ExecutionStep;
use App\Models\Submission;
use App\Models\NodeJS\ExecutionStep;
use App\Models\NodeJS\Submission;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

View File

@ -10,7 +10,7 @@
use App\Models\NodeJS\ExecutionStep;
use App\Models\NodeJS\ProjectExecutionStep;
class NodeJS_Seeder extends Seeder
class NodeJSSeeder extends Seeder
{
/**
* Run the database seeds.
@ -179,6 +179,7 @@ public function run(): void
//zips
$project_asynchronous_programming->addMedia(storage_path('projects/asynchronous-programming/zips/guides.zip'))->preservingOriginal()->toMediaCollection('project_zips', 'nodejs_public_projects_files');
$project_asynchronous_programming->addMedia(storage_path('projects/asynchronous-programming/zips/supplements.zip'))->preservingOriginal()->toMediaCollection('project_zips', 'nodejs_public_projects_files');
$project_asynchronous_programming->addMedia(storage_path('projects/asynchronous-programming/zips/tests.zip'))->preservingOriginal()->toMediaCollection('project_zips', 'nodejs_public_projects_files');
//tests
$project_asynchronous_programming->addMedia(storage_path('projects/asynchronous-programming/tests/unit/modul1-unit.test.js'))->preservingOriginal()->toMediaCollection('project_tests', 'nodejs_public_projects_files');

View File

@ -11,7 +11,9 @@
@php
$guidesCount = count($project->getMedia('project_guides'));
$supplementsCount = count($project->getMedia('project_supplements'));
$testsCount = count($project->getMedia('project_tests_api')) + count($project->getMedia('project_tests_web'));
$testsIndividualCount = count($project->getMedia('project_tests'));
$testsZipExists = $project->getMedia('project_zips')->where('file_name', 'tests.zip')->first();
$testsCount = $testsIndividualCount > 0 || $testsZipExists ? max($testsIndividualCount, 1) : 0;
@endphp
<div>
@if ($guidesCount > 0)