In this section we will see how to add wishlist system in laravel 9. For this tutorial we will use Laravel Markable. The Laravel Markable package allows you to manage your wishlists. It also allows users to create and edit their own wishlists. We need to create a product and add the wishlist.
Step 1: Install Laravel & Connect Database
Run below command to create laravel project.
composer create-project laravel/laravel laravel-wishlist
Now, you have to connect the laravel app to the database, hence open the .env configuration file and add the database credentials as suggested below.
.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=database_name
DB_USERNAME=database_user_name
DB_PASSWORD=database_password
Step 2: Install Breeze
Install laravel breeze via composer:
composer require laravel/breeze --dev
Next, run below command.
php artisan breeze:install
And final install Dependencies
npm install && npm run dev
php artisan migrate
Step 3: Create Product Modal Migration Seeder and Controller
Run below command to create model, migration and controller
php artisan make:model Product -mcr
create_products_table.php
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->double('price');
$table->text('description');
$table->string('image');
$table->timestamps();
});
}
app/Models/Product.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
use HasFactory;
protected $fillable = [
'name',
'price',
'image',
'description',
];
}
Step 4: Create Product Seeder
php artisan make:seeder ProductSeeder
Now add dummy data in seeder.
database/seeders/ProductSeeder.php
<?php
namespace Database\Seeders;
use App\Models\Product;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class ProductSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$products = [
[
'name' => 'Fesh milk 250ml',
'price' => 250,
'description' => 'lorem ipsum',
'image' => 'https://cdn.pixabay.com/photo/2016/12/06/18/27/milk-1887234__340.jpg'
],
[
'name' => '12 Egs',
'price' => 6,
'description' => 'lorem ipsum',
'image' => 'https://cdn.pixabay.com/photo/2016/07/23/15/24/egg-1536990__340.jpg'
],
[
'name' => 'Wine 500ml',
'price' => 50,
'description' => 'lorem ipsum',
'image' => 'https://cdn.pixabay.com/photo/2015/11/07/12/00/alcohol-1031713__340.png'
],
[
'name' => 'Homey 100ml',
'price' => 12,
'description' => 'lorem ipsum',
'image' => 'https://cdn.pixabay.com/photo/2017/01/06/17/49/honey-1958464__340.jpg'
]
];
Product::insert($products);
}
}
database/seeders/DatabaseSeeder.php
<?php
namespace Database\Seeders;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
$this->call(ProductSeeder::class);
// \App\Models\User::factory(10)->create();
// \App\Models\User::factory()->create([
// 'name' => 'Test User',
// 'email' => '[email protected]',
// ]);
}
}
app/Http/Controllers/ProductController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Product;
class ProductController extends Controller
{
public function productList()
{
$products = Product::all();
return view('products', compact('products'));
}
}
Step 5: Install & Setup Laravel Markable For Wishlist
You can install the package via composer:
composer require maize-tech/laravel-markable
publishes favorite migration.
php artisan vendor:publish --tag="markable-migration-favorite"
You can publish the config file with:
php artisan vendor:publish --tag="markable-config"
Migrate table with seeder.
php artisan migrate:fresh --seed
Step 6: Add Markable Favorite in Product Modal
app/Models/Product.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Maize\Markable\Markable;
use Maize\Markable\Models\Favorite;
class Product extends Model
{
use HasFactory, Markable;
protected $fillable = [
'name',
'price',
'image',
'description',
];
protected static $marks = [
Favorite::class,
];
}
Step 7: Create Wishlist Controller and Routes
Copy the following code below to create a wishlist controller.
php artisan make:controller WishlistController
Add a favoriteAdd and favoriteRemove method to the Wishlist class to add items to the wishlist. This method should be called after an item has been added to the list, but before it's added to the shopping cart. If a product is added and then removed, this method should remove it from the list.
app/Http/Controllers/WishlistController.php
<?php
namespace App\Http\Controllers;
use App\Models\Product;
use Maize\Markable\Models\Favorite;
use Illuminate\Http\Request;
class WishlistController extends Controller
{
public function wishlist()
{
$products = Product::whereHasFavorite(
auth()->user()
)->get();
// dd($products);
return view('wishlist',compact('products'));
}
public function favoriteAdd($id)
{
$product = Product::find($id);
$user = auth()->user();
Favorite::add($product, $user);
session()->flash('success', 'Product is Added to Favorite Successfully !');
return redirect()->route('wishlist');
}
public function favoriteRemove($id)
{
$product = Product::find($id);
$user = auth()->user();
Favorite::remove($product, $user);
session()->flash('success', 'Product is Remove to Favorite Successfully !');
return redirect()->route('wishlist');
}
}
web.php
<?php
use App\Http\Controllers\ProductController;
use App\Http\Controllers\WishlistController;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Route::get('products', [ProductController::class, 'productList'])->name('products.list');
Route::post('favorite-add/{id}', [WishlistController::class, 'favoriteAdd'])->name('favorite.add');
Route::delete('favorite-remove/{id}', [WishlistController::class, 'favoriteRemove'])->name('favorite.remove');
Route::get('wishlist', [WishlistController::class, 'wishlist'])->name('wishlist');
Route::get('/dashboard', function () {
return view('dashboard');
})->middleware(['auth'])->name('dashboard');
require __DIR__.'/auth.php';
Step 8: Add Wishlist in Laravel Blade View Files
resources/views/products.blade.php
<x-app-layout>
<x-slot name="header">
<h2 class="text-xl font-semibold leading-tight text-gray-800">
{{ __('Product List') }}
</h2>
</x-slot>
<div class="container px-12 py-8 mx-auto">
<h3 class="text-2xl font-bold text-purple-700">Our Product</h3>
<div class="h-1 bg-red-500 w-36"></div>
<div class="grid grid-cols-1 gap-6 mt-6 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
@foreach ($products as $product)
<div class="w-full max-w-sm mx-auto overflow-hidden bg-white rounded-md shadow-md">
<img src="{{ url($product->image) }}" alt="" class="w-full max-h-60">
<div class="flex items-end justify-end w-full bg-cover">
</div>
<div class="px-5 py-3">
<h3 class="text-gray-700 uppercase">{{ $product->name }}</h3>
<span class="mt-2 text-gray-500">${{ $product->price }}</span>
<form action="{{ route('favorite.add', $product->id) }}" method="POST"
enctype="multipart/form-data">
@csrf
<button class="p-2 bg-red-100 rounded hover:bg-red-600">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" class="w-6 h-6 text-red-700 hover:text-red-100">
<path stroke-linecap="round" stroke-linejoin="round"
d="M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12z" />
</svg>
</button>
</form>
</div>
</div>
@endforeach
</div>
</div>
</x-app-layout>
resources/views/wishlist.blade.php
<x-app-layout>
<x-slot name="header">
<h2 class="text-xl font-semibold leading-tight text-gray-800">
{{ __('wishlist') }}
</h2>
</x-slot>
<div class="py-12">
<div class="mx-auto max-w-7xl sm:px-6 lg:px-8">
<div class="overflow-hidden bg-white shadow-sm sm:rounded-lg">
<div class="p-6 bg-white border-b border-gray-200">
Wishlist List
@if ($message = Session::get('success'))
<div class="p-4 mb-3 bg-green-400 rounded">
<p class="text-green-800">{{ $message }}</p>
</div>
@endif
<div class="flex flex-col">
<div class="overflow-x-auto">
<div class="p-1.5 w-full inline-block align-middle">
<div class="overflow-hidden border rounded-lg">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th
scope="col"
class="px-6 py-3 text-xs font-bold text-left text-gray-500 uppercase"
>
ID
</th>
<th
scope="col"
class="px-6 py-3 text-xs font-bold text-left text-gray-500 uppercase"
>
Product Name
</th>
<th
scope="col"
class="px-6 py-3 text-xs font-bold text-left text-gray-500 uppercase"
>
Price
</th>
<th
scope="col"
class="px-6 py-3 text-xs font-bold text-left text-gray-500 uppercase"
>
Image
</th>
<th
scope="col"
class="px-6 py-3 text-xs font-bold text-right text-gray-500 uppercase"
>
Delete
</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
@foreach ($products as $product)
<tr>
<td
class="px-6 py-4 text-sm font-medium text-gray-800 whitespace-nowrap"
>
{{ $product->id }}
</td>
<td
class="px-6 py-4 text-sm text-gray-800 whitespace-nowrap"
>
{{ $product->name }}
</td>
<td
class="px-6 py-4 text-sm text-gray-800 whitespace-nowrap"
>
{{ $product->price }}
</td>
<td
class="px-6 py-4 text-sm text-gray-800 whitespace-nowrap"
>
<img src="{{ $product->image }}" alt="{{ $product->image }}" class="w-12 h-12">
</td>
<td
class="px-6 py-4 text-sm font-medium text-right whitespace-nowrap"
>
<form action="{{ route('favorite.remove',$product->id) }}" method="POST"
onsubmit="return confirm('{{ trans('are You Sure ? ') }}');"
style="display: inline-block;">
<input type="hidden" name="_method" value="DELETE">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="submit" class="px-4 py-2 text-white bg-red-700 rounded"
value="Delete">
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</x-app-layout>
Step 9: Run Laravel and vite server
php artisan serve
//and next terminal
npm run dev