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) { if ($zipMedia) {
return response()->json($zipMedia->getUrl(), 200); return response()->json($zipMedia->getUrl(), 200);
} else { } else {
$tests_api = $project->getMedia('project_tests_api'); // Perbaiki collection name sesuai database
$tests_web = $project->getMedia('project_tests_web'); $tests = $project->getMedia('project_tests');
$tests_images = $project->getMedia('project_tests_images');
// 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'); $tempDir = storage_path('app/public/assets/projects/' . $project->title . '/zips');
if (!is_dir($tempDir)) mkdir($tempDir); 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(); $path = $test->getPath();
$filename = $test->file_name; $filename = $test->file_name;
copy($path, $tempDir . '/tests/api/' . $filename); copy($path, $tempDir . '/' . $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);
} }
$zipPath = $tempDir . '/tests.zip'; $zipPath = $tempDir . '/tests.zip';
$zip = new ZipArchive; $zip = new ZipArchive;
if ($zip->open($zipPath, ZipArchive::CREATE) === TRUE) { if ($zip->open($zipPath, ZipArchive::CREATE) === TRUE) {
$zip->addEmptyDir('api'); $files = Storage::files('public/assets/projects/' . $project->title . '/zips');
$zip->addEmptyDir('web'); foreach ($files as $file) {
$zip->addEmptyDir('web/images'); // Skip jika file adalah zip itu sendiri
$api_files = Storage::files('public/assets/projects/' . $project->title . '/zips/tests/api'); if (basename(storage_path('app/' . $file)) !== 'tests.zip') {
foreach ($api_files as $file) { $zip->addFile(storage_path('app/' . $file), basename($file));
$zip->addFile(storage_path('app/' . $file), 'api/' . 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(); $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 { } else {
throw new Exception('Failed to create zip archive'); 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')) { if ($request->hasFile('folder_path')) {
$project_title = Project::find($project_id)->title; $project_title = Project::find($project_id)->title;
$project_title = str_replace([' ', '/', '\\'], '-', $project_title);
$file = $request->file('folder_path'); $file = $request->file('folder_path');
$file_name = $file->getClientOriginalName(); $file_name = $file->getClientOriginalName();
$folder_path = 'public/tmp/submissions/' . $request->user()->id . '/' . $project_title; $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); $file->storeAs($folder_path, $file_name);
TemporaryFile::create([ TemporaryFile::create([
@ -144,7 +163,6 @@ public function upload(Request $request, $project_id)
public function submit(Request $request) public function submit(Request $request)
{ {
try { try {
$request->validate([ $request->validate([
'project_id' => 'required|exists:projects,id', 'project_id' => 'required|exists:projects,id',
@ -161,34 +179,55 @@ public function submit(Request $request)
$submission = new Submission(); $submission = new Submission();
$submission->user_id = $request->user()->id; $submission->user_id = $request->user()->id;
$submission->project_id = $request->project_id; $submission->project_id = $request->project_id;
if ($request->has('folder_path')) { if ($request->has('folder_path')) {
$submission->type = Submission::$FILE; $submission->type = Submission::$FILE;
$submission->path = $request->folder_path; $submission->path = $request->folder_path;
$temporary_file = TemporaryFile::where('folder_path', $request->folder_path)->first(); $temporary_file = TemporaryFile::where('folder_path', $request->folder_path)->first();
if ($temporary_file) { // Debug: Cek apakah temporary file ada
$path = storage_path('app/' . $request->folder_path . '/' . $temporary_file->file_name); if (!$temporary_file) {
$submission->addMedia($path)->toMediaCollection('submissions', 'nodejs_public_submissions_files'); \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))) { if ($this->is_dir_empty(storage_path('app/' . $request->folder_path))) {
rmdir(storage_path('app/' . $request->folder_path)); rmdir(storage_path('app/' . $request->folder_path));
} }
$temporary_file->delete(); $temporary_file->delete();
}
} else { } else {
$submission->type = Submission::$URL; $submission->type = Submission::$URL;
$submission->path = $request->github_url; $submission->path = $request->github_url;
} }
$submission->status = Submission::$PENDING; $submission->status = Submission::$PENDING;
$submission->start = now(); $submission->start = now();
$submission->save(); $submission->save();
return response()->json([ return response()->json([
'message' => 'Submission created successfully', 'message' => 'Submission created successfully',
'submission' => $submission, 'submission' => $submission,
], 201); ], 201);
} catch (\Throwable $th) { } catch (\Throwable $th) {
\Log::error('Submission error: ' . $th->getMessage() . ' | Line: ' . $th->getLine() . ' | File: ' . $th->getFile());
return response()->json([ return response()->json([
'message' => 'Submission failed', 'message' => 'Submission failed',
'error' => $th->getMessage(), 'error' => $th->getMessage(),
@ -707,7 +746,7 @@ public function changeSourceCode($submission_id)
$user = Auth::user(); $user = Auth::user();
$submission = Submission::where('id', $submission_id)->where('user_id', $user->id)->first(); $submission = Submission::where('id', $submission_id)->where('user_id', $user->id)->first();
if ($submission) { if ($submission) {
return view('submissions.change_source_code', compact('submission')); return view('nodejs.submissions.change_source_code', compact('submission'));
} }
return redirect()->route('submissions'); return redirect()->route('submissions');
} }
@ -747,7 +786,7 @@ public function update(Request $request)
if ($temporary_file) { if ($temporary_file) {
$path = storage_path('app/' . $request->folder_path . '/' . $temporary_file->file_name); $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))) { if ($this->is_dir_empty(storage_path('app/' . $request->folder_path))) {
rmdir(storage_path('app/' . $request->folder_path)); rmdir(storage_path('app/' . $request->folder_path));
} }

View File

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

View File

@ -10,7 +10,7 @@
use App\Models\NodeJS\ExecutionStep; use App\Models\NodeJS\ExecutionStep;
use App\Models\NodeJS\ProjectExecutionStep; use App\Models\NodeJS\ProjectExecutionStep;
class NodeJS_Seeder extends Seeder class NodeJSSeeder extends Seeder
{ {
/** /**
* Run the database seeds. * Run the database seeds.
@ -179,6 +179,7 @@ public function run(): void
//zips //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/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/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 //tests
$project_asynchronous_programming->addMedia(storage_path('projects/asynchronous-programming/tests/unit/modul1-unit.test.js'))->preservingOriginal()->toMediaCollection('project_tests', 'nodejs_public_projects_files'); $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 @php
$guidesCount = count($project->getMedia('project_guides')); $guidesCount = count($project->getMedia('project_guides'));
$supplementsCount = count($project->getMedia('project_supplements')); $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 @endphp
<div> <div>
@if ($guidesCount > 0) @if ($guidesCount > 0)