WordPress-Like Blog Laravel 5.7 and AdminLTE 3 (14) – Menghapus Post
Pada bagian keempat belas ini, kita akan :
- Menghapus Post dan Menyimpannya di TrashDelete an Existing Post and put it in the Trash
- Menampilkan Post yang Berada di Trash
- Menghapus Image dan Thumbnailnya
Menghapus Post
Untuk menghapus post, pertama-tama kita modifikasi resources/views/backend/blog index.blade.php dan tambahkan Form open dan Form close disini :
1 2 3 4 5 6 |
<td> {!! Form::open(['method' => 'DELETE', 'route' => ['backend.blog.destroy', $post->id] ]) !!} <a href="{{ route('backend.blog.edit', $post->id) }}" class="btn btn-sm btn-default"><i class="fa fa-edit"></i></a> <button type="submit" class="btn btn-sm btn-danger"><i class="fa fa-times"></i></button> {!! Form::close() !!} </td> |
Selanjutnya, tambahkan kode di destroy() method Backend\BlogController.php
1 2 3 4 5 6 |
public function destroy($id) { Post::findOrFail($id)->delete(); return redirect('/backend/blog')->with('message', 'Your post has been deleted'); } |
Sekarang coba untuk menghapus satu post dari halaman index :
Aksi ini akan menghapus post dari database.
Kita ingin supaya post tidak langsung terhapus dari database, namun ditampung dulu di Trash. Modifikasi kode dengan menambahkan method soft delete pada tabel post. Buatlah migration di terminal :
1 |
php artisan make:migration add_soft_deletion --table=posts |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public function up() { Schema::table('posts', function (Blueprint $table) { $table->softDeletes(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('posts', function (Blueprint $table) { $table->dropSoftDeletes(); }); } |
Jalankan migrasi dan tambahkan baris berikut di app\Post.php
1 2 3 4 5 |
use Illuminate\Database\Eloquent\SoftDeletes; class Post extends Model { use SoftDeletes; |
Sekarang, ketika kita menghapus post, post tersebut tetap ada di dalam tabel, namun field deleted_at nya akan terisi.
Dengan ini, kita dapat menempatkan kembali post yang sudah dihapus apabila kita berubah pikiran. Modifikasi destroy() method di dalam Backend\BlogController.php
1 2 3 4 5 6 |
public function destroy($id) { Post::findOrFail($id)->delete(); return redirect('/backend/blog')->with('trash-message', ['Your post has been moved to the trash', $id]); } |
Tambahkan message.blade.php di dalam folder backend/blog dan pindahkan bagian message dari index.blade.php ke dalamnya :
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@if(session('message')) <div class="alert alert-info"> {{ session('message') }} </div> @elseif(session('trash-message')) <div class="alert alert-info"> <?php list($message, $postId) = session('trash-message') ?> {{ $message }} {!! Form::open(['method'=>'PUT', 'route' => ['backend.blog.restore', $postId]]) !!} <button type="submit">Undo</button> {!! Form::close() !!} </div> @endif |
Dan gantikan dengan kode baris ini :
1 |
@include('backend.blog.message') |
Tambahkan route baru di routes/web.php
1 2 3 4 |
Route::put('/backend/blog/restore/{blog}',[ 'uses' => 'Backend\BlogController@restore', 'as' => 'backend.blog.restore', ]); |
Modifikasi Backend\BlogController.php dan tambahkan restore() method :
1 2 3 4 5 6 |
public function restore($id){ $post = Post::withTrashed()->findOrFail($id); $post->restore(); return redirect('/backend/blog')->with('message', 'Your post has been restored'); } |
Sekarang,ketika kita menghapus post, sebuah notifikasi dan tombol Undo akan muncul. Jika tombol ini ditekan, post tidak jadi dihapus.
Menampilkan Post di Dalam Trash
Kita akan menampilkan post yang sudah dihapus namun masih berada di Trash. Modifikasi index.blade.php :
1 2 3 4 5 6 |
<div class="col-md-6" style="padding-left: 10px; padding-right: 30px; padding-top: 10px; padding-bottom: 10px; "> <div class="float-right" style="color: blue;"> <a class="" href="?status=active">Active(12) </a> | <a class="" href="?status=trash">Trash </a> </div> </div> |
Buka Backend\BlogController.php dan modifikasi index() method :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public function index(Request $request) { if (($status = $request->get('status')) && $status == 'trash'){ $posts = Post::onlyTrashed()->with('category','author')->latest()->paginate($this->limit); $allPostCount = Post::onlyTrashed()->count(); $onlyTrashed = TRUE; }else{ $posts = Post::with('category','author')->latest()->paginate($this->limit); $allPostCount = Post::count(); $onlyTrashed = FALSE; } return view("backend.blog.index", compact('posts','allPostCount','onlyTrashed')); } |
Modifikasi index.blade.php, cut kode di antara <table> ke </table> , buat file baru table.blade.php dan paste kode di dalamnya :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<table class="table table-striped"> <tr> <th width="10%">Action </th> <th>Title</th> <th width="20%">Author</th> <th width="20%">Category</th> <th width="20%">Date</th> </tr> @foreach($posts as $post) <tr> <td> {!! Form::open(['method' => 'DELETE', 'route' => ['backend.blog.destroy', $post->id] ]) !!} <a href="{{ route('backend.blog.edit', $post->id) }}" class="btn btn-sm btn-default"><i class="fa fa-edit"></i></a> <button type="submit" class="btn btn-sm btn-danger"><i class="fa fa-trash"></i></button> {!! Form::close() !!} </td> <td>{{ $post->title }}</td> <td>{{ $post->author->name }}</td> <td>{{ $post->category->title }}</td> <td> <abbr title="{{ $post->formattedDate(true) }}"> {{ $post->formattedDate() }}</abbr> | {!! $post->publicationLabel() !!} </td> </tr> @endforeach </table> |
Buat file lain, table-trash.blade.php :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<table class="table table-striped"> <tr> <th width="10%">Action </th> <th>Title</th> <th width="20%">Author</th> <th width="20%">Category</th> <th width="20%">Date</th> </tr> @foreach($posts as $post) <tr> <td> {!! Form::open(['style' => 'display:inline-block' , 'method' => 'PUT', 'route' => ['backend.blog.restore', $post->id] ]) !!} <button title="Restore" class="btn btn-sm btn-default"><i class="fa fa-refresh"></i></button> {!! Form::close() !!} {!! Form::open(['style' => 'display:inline-block' ,'method' => 'DELETE', 'route' => ['backend.blog.force-destroy', $post->id] ]) !!} <button title="Hard Delete" type="submit" onclick="return confirm('Are you sure to delete the post?')" class="btn btn-sm btn-danger"><i class="fa fa-times"></i></button> {!! Form::close() !!} </td> <td>{{ $post->title }}</td> <td>{{ $post->author->name }}</td> <td>{{ $post->category->title }}</td> <td> <abbr title="{{ $post->formattedDate(true) }}"> {{ $post->formattedDate() }}</abbr> </td> </tr> @endforeach </table> |
Kita perlu menambahkan route untuk force-destroy di routes/web.php
1 2 3 4 |
Route::delete('/backend/blog/force-destroy/{blog}',[ 'uses' => 'Backend\BlogController@forceDestroy', 'as' => 'backend.blog.force-destroy', ]); |
Tambahkan forceDestroy() method di dalam Backend\BlogController.php
1 2 3 4 5 |
public function forceDestroy($id){ Post::withTrashed()->findOrFail($id)->forceDelete(); return redirect('/backend/blog?status=trash')->with('message', 'The post has been deleted permanently'); } |
Menghapus Image dan Thumbnailnya
Sebelumnya, kita telah berhasil menghapus post. Namun, jika post tersebut memiliki image, kita masih belum menghapusnya. Kita akan atasi masalah ini.
Modifikasi Backend\BlogController.php dan buat method baru, removeImage() :
1 2 3 4 5 6 7 8 9 10 11 |
private function removeImage($image){ if(!empty($image)){ $imagePath = $this->uploadPath . '/' . $image; $ext = substr(strrchr($image, '.'), 1); $thumbnail = str_replace(".{$ext}","_thumb.{$ext}", $image); $thumbnailPath = $this->uploadPath . '/' . $thumbnail; if (file_exists($imagePath) ) unlink($imagePath); if (file_exists($thumbnailPath) ) unlink($thumbnailPath); } } |
Tambahkan method ini di forceDestroy :
1 2 3 4 5 6 7 8 |
public function forceDestroy($id){ $post = Post::withTrashed()->findOrFail($id); $post->forceDelete(); $this->removeImage($post->image); return redirect('/backend/blog?status=trash')->with('message', 'The post has been deleted permanently'); } |
Modifikasi juga update() method :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public function update(Requests\PostRequest $request, $id) { $post = Post::findOrFail($id); $oldImage = $post->image; $data = $this->handleRequest($request); $post->update($data); if($oldImage !== $post->image) { $this->removeImage($oldImage); } return redirect(route('backend.blog.index'))->with('message', 'Post has been updated'); } |
Paging juga kita betulkan. Modifikasi index.blade.php pada bagian $post->render() menjadi seperti ini:
1 |
{{ $posts->appends( Request::query() )->render() }} |
Sesudahnya, kita akan membuat menu di kanan atas untuk menuju post yang sudah dipublikasi, post yang sudah dihapus, dst. Modifikasi index.blade.php :
1 2 3 4 5 6 7 8 9 10 11 12 |
<div class="col-md-6" style="padding-left: 10px; padding-right: 30px; padding-top: 10px; padding-bottom: 10px; "> <div class="pull-right" style="padding:7px 0;"> <?php $links = [];?> @foreach($statusList as $key => $value) @if($value) <?php $selected = Request::get('status') == $key ? 'selected-status' : '' ?> <?php $links[] = "<a class=\"{$selected}\" href=\"?status={$key}\">" .ucwords($key) ."({$value}) </a>"?> @endif @endforeach {!! implode(' | ', $links) !!} </div> </div> |
Modifikasi index() dan restore() method di dalam Backend\BlogController.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
public function index(Request $request) { $onlyTrashed = FALSE; if (($status = $request->get('status')) && $status == 'trash'){ $posts = Post::onlyTrashed()->with('category','author')->latest()->paginate($this->limit); $allPostCount = Post::onlyTrashed()->count(); $onlyTrashed = TRUE; } elseif($status == 'published') { $posts = Post::published()->with('category','author')->latest()->paginate($this->limit); $allPostCount = Post::published()->count(); } elseif($status == 'scheduled') { $posts = Post::scheduled()->with('category','author')->latest()->paginate($this->limit); $allPostCount = Post::scheduled()->count(); } elseif($status == 'draft') { $posts = Post::draft()->with('category','author')->latest()->paginate($this->limit); $allPostCount = Post::draft()->count(); } else{ $posts = Post::with('category','author')->latest()->paginate($this->limit); $allPostCount = Post::count(); } return view("backend.blog.index", compact('posts','allPostCount','onlyTrashed')); } public function restore($id){ $post = Post::withTrashed()->findOrFail($id); $post->restore(); return redirect()->back()->with('message', 'Your post has been restored'); } |
Tambahkan scope di dalam app\Post.php
1 2 3 4 5 6 7 |
public function scopeScheduled($query){ return $query->where("published_at", ">", Carbon::now()); } public function scopeDraft($query){ return $query->whereNull("published_at"); } |
Github commit.