Complete Part 4

This commit is contained in:
Thuan Bui
2025-05-06 08:39:59 +09:00
parent c5903a0576
commit 6cf8bace52
6 changed files with 93 additions and 8 deletions
+6 -5
View File
@@ -4,11 +4,12 @@
👉 Code cho từng phần nằm ở **các branch riêng**:
| Phần | Tiêu đề | Branch |
| ---- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| 1 | File Upload cơ bản trong Laravel | [`part-1-basic-upload`](https://github.com/10h30/laravel-file-upload-series/tree/part-1-basic-upload) |
| 2 | Validation & Bảo mật khi upload | [`part-2-validation-security`](https://github.com/10h30/laravel-file-upload-series/tree/part-2-validation-security) |
| 3 | Upload cùng lúc nhiều file | [`part-3-multiple-file-upload`](https://github.com/10h30/laravel-file-upload-series/tree/part-3-multiple-file-upload) |
| Phần | Tiêu đề | Branch |
| ---- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| 1 | File Upload cơ bản trong Laravel | [`part-1-basic-upload`](https://github.com/10h30/laravel-file-upload-series/tree/part-1-basic-upload) |
| 2 | Validation & Bảo mật khi upload | [`part-2-validation-security`](https://github.com/10h30/laravel-file-upload-series/tree/part-2-validation-security) |
| 3 | Upload cùng lúc nhiều file | [`part-3-multiple-file-upload`](https://github.com/10h30/laravel-file-upload-series/tree/part-3-multiple-file-upload) |
| 4 | Hiển thị và xoá các file đã upload | [`part-4-manage-uploads`](https://github.com/10h30/laravel-file-upload-series/tree/part-4-manage-uploads) |
| |
> 📖 Mỗi branch tương ứng với một phần trong series blog. Bạn có thể clone và chạy từng phần riêng biệt để dễ theo dõi.
+22 -2
View File
@@ -2,6 +2,7 @@
namespace App\Http\Controllers;
use App\Models\Upload;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
@@ -14,7 +15,8 @@ class UploadController extends Controller
*/
public function index()
{
return view('upload');
$uploads = Upload::latest()->get();
return view('upload', compact('uploads'));
}
/**
@@ -65,8 +67,14 @@ class UploadController extends Controller
// Lưu file bằng storeAs với tên file mới
$storedFilePath = $file->storeAs($directory, $finalFilename, $disk); // Trả về đường dẫn tương đối: 'uploads/ten_file_cuoi_cung.jpg'
$storedFilePaths[] = $storedFilePath; // Thêm đường dẫn file đã lưu vào array $storedFilePaths
}
// Tạo bản ghi mới trong table uploads của database
Upload::create([
'filename' => $storedFilePath,
'original_filename' => $originalFilename,
]);
}
// Chuyển hướng về trang trước đó
return back()->with('success', 'You have successfully uploaded ' . $numberOfFiles . ' files')
@@ -75,4 +83,16 @@ class UploadController extends Controller
// Gửi kèm array các tên file gốc vào session flash data với key 'original_filenames'
->with('original_filenames', $originalFilenames);
}
public function destroy(Upload $upload)
{
// Xoá file vật lý khỏi disk 'public' dựa vào đường dẫn lưu trong $upload->filename
Storage::disk('public')->delete($upload->filename);
// Xoá bản ghi tương ứng trong database
$upload->delete();
// Chuyển hướng người dùng về trang trước đó với thông báo thành công
return back()->with('success', 'You have successfully deleted ' . $upload->original_filename);
}
}
+13
View File
@@ -0,0 +1,13 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Upload extends Model
{
protected $fillable = [
'filename',
'original_filename'
];
}
@@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('uploads', function (Blueprint $table) {
$table->id();
$table->string('filename');
$table->string('original_filename');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('uploads');
}
};
+22 -1
View File
@@ -47,7 +47,7 @@
@if (session("stored_paths") && is_array(session("stored_paths")))
<div class="mt-4">
<p>Uploaded Files:</p>
{{-- Lặp qua array các đường dẫn file đã lưu. $index chỉ số, $path đường dẫn --}}
{{-- Lặp qua array các đường dẫn file đã lưu. $index chỉ số, $path đường dẫn --}}
@foreach (session("stored_paths") as $index => $path)
<div class="border p-4 mt-2">
<p class="text-sm text-gray-600">Original Filename:
@@ -63,6 +63,27 @@
</div>
@endif
@if (count($uploads) > 0)
<div class="container mx-auto mt-10 p-10 bg-white rounded-lg shadow-md max-w-md">
@foreach ($uploads as $upload)
<li class="flex items-center justify-between mb-4">
<a class="flex items-center gap-4 py-2" href="{{ $upload->filename }}" target="_blank">
<img src="{{ $upload->filename }}" alt="{{ $upload->filename }}" width="50" height="50">
<span>{{ $upload->original_filename }}</span>
</a>
<form action="{{ route("upload.destroy", $upload->id) }}"
method="POST"
style="display:inline;"
onsubmit="return confirm('Are you sure you want to delete this file?');">
@csrf
@method("DELETE")
<button type="submit" class="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded">Delete</button>
</form>
</li>
@endforeach
</div>
@endif
</body>
</html>
+1
View File
@@ -10,3 +10,4 @@ Route::get('/', function () {
Route::get('/upload', [UploadController::class, 'index'])->name('upload.index');
Route::post('/upload', [UploadController::class, 'store'])->name('upload.store');
Route::delete('/upload/{upload}', [UploadController::class, 'destroy'])->name('upload.destroy');