Bu eğitimde, Laravel 11 uygulamasında spatie/laravel-permission paketini kullanarak kullanıcı rolleri ve izinlerini nasıl yöneteceğinizi paylaşacağım.
Laravel 11 uygulamasında roller ve izinler için Spatie GitHub paketini kullanıyoruz. Aşağıdaki adımları takip ederek Laravel 11'de ACL (Erişim Kontrol Listesi) oluşturabilirsiniz.
Spatie role permission composer paketi, Laravel 11'de ACL oluşturmanın bir yolunu sağlar. Bu paket, bir kullanıcıya nasıl rol atanacağını, bir kullanıcıya nasıl izin verileceğini ve rollere nasıl izin atanacağını açıklar. Laravel 11 uygulamasında adım adım rol ve izin oluşturmayı anlatacağım.
Roller ve izinler, farklı roller ve izinlerle birden fazla kullanıcı türü oluşturmanıza olanak tanır. Örneğin, bazı kullanıcılar yalnızca ürün modülünün listesini görebilirken, diğerleri ürün modülünü düzenleyebilir ve silebilir.
Bu örnekte, aşağıda listelenen üç modül oluşturuldu:
- Kullanıcı Yönetimi
- Rol Yönetimi
- Ürün Yönetimi
Bir kullanıcı kaydettikten sonra, herhangi bir rolünüz olmayacaktır. Bu yüzden Kullanıcı Yönetimi modülünden detaylarınızı düzenleyerek kendinize admin rolü atayabilirsiniz. Ardından, rol-list, rol-create, rol-edit, rol-delete, ürün-list, ürün-create, ürün-edit, ürün-delete gibi izinlere sahip kendi rolünüzü oluşturabilirsiniz. Yeni bir kullanıcı atayıp bu durumu test edebilirsiniz.
Adım 1: Laravel 11'i Kurun
İlk olarak, sıfırdan başlıyoruz ve Laravel 11'in yeni bir sürümünü elde etmemiz gerekiyor. Bunun için aşağıdaki komutu kullanarak bir Laravel 11 uygulaması kuracağız. Terminal ya da komut istemcinizi açın ve şu komutu çalıştırın:
composer create-project laravel/laravel example-app
Adım 2: spatie/laravel-permission Paketini Kurun
Şimdi, ACL (Erişim Kontrol Listesi) için Spatie paketini kurmamız gerekiyor; bu şekilde paketin sunduğu yöntemleri kullanabiliriz. Ayrıca, form koleksiyon paketini de kuracağız. Terminalinizi açın ve aşağıdaki komutu çalıştırın:
composer require spatie/laravel-permission
Spatie paketi üzerinde özelleştirmeler yapabiliriz. Eğer siz de değişiklikler yapmak istiyorsanız, aşağıdaki komutu çalıştırarak yapılandırma dosyasını config/permission.php konumuna ve migration (göç) dosyalarını projeye ekleyebilirsiniz:
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
Şimdi, permission.php dosyasını ve bir migration dosyasını görebilirsiniz. Migration dosyalarını çalıştırmak için şu komutu kullanın:
php artisan migrate
Adım 3: Ürünler İçin Migration Oluşturma
Bu adımda, products (ürünler) tablosu için migration dosyasını oluşturacağız. Aşağıdaki komutu kullanarak bir migration oluşturabilirsiniz:
php artisan make:migration create_products_table
Açılan migration dosyasına aşağıdaki kodu ekleyin:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Migration'ları çalıştır.
*
* @return void
*/
public function up(): void
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->text('detail');
$table->timestamps();
});
}
/**
* Migration'ları geri al.
*
* @return void
*/
public function down(): void
{
Schema::dropIfExists('products');
}
};
Migration'ı çalıştırarak ürünler tablosunu oluşturun:
php artisan migrate
Adım 4: Modelleri Oluşturma
Bu adımda, User ve Product tabloları için modelleri oluşturacağız. Laravel'de yeni bir proje başlattığınızda, User modeli zaten gelir. Bu yüzden sadece kodu güncelleyeceğiz. Product modeli için ise yeni bir model oluşturmanız gerekecek.
1. User Modeli
app/Models/User.php dosyasını şu şekilde güncelleyin:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use HasFactory, Notifiable, HasRoles;
/**
* Kitle atama için uygun olan özellikler.
*
* @var array
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* Serileştirme için gizli tutulacak özellikler.
*
* @var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* Dönüştürülmesi gereken özellikler.
*
* @return array
*/
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
}
2. Product Modeli
Yeni bir model oluşturmak için şu komutu çalıştırabilirsiniz:
php artisan make:model Product
Oluşan app/Models/Product.php dosyasını şu şekilde düzenleyin:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
use HasFactory;
/**
* Kitle atama için uygun olan özellikler.
*
* @var array
*/
protected $fillable = [
'name', 'detail'
];
}
Adım 5: Middleware Ekleme
Spatie paketi, kendi yerleşik middleware'lerini sağlar. Bu middleware'ler şu şekildedir:
rolepermission
Bu middleware'leri kullanabilmek için, app.php dosyasına eklememiz gerekiyor. Aşağıdaki şekilde bootstrap/app.php dosyasını güncelleyebilirsiniz:
<?php
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
$middleware->alias([
'role' => \Spatie\Permission\Middleware\RoleMiddleware::class,
'permission' => \Spatie\Permission\Middleware\PermissionMiddleware::class,
'role_or_permission' => \Spatie\Permission\Middleware\RoleOrPermissionMiddleware::class,
]);
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();
Bu adımda, role, permission ve role_or_permission middleware'lerini projeye ekledik. Artık bu middleware'leri route (yönlendirme) veya controller düzeyinde kullanabilirsiniz.
Adım 6: Kimlik Doğrulama Oluşturma
Laravel 11 uygulamanıza kimlik doğrulama (auth) eklemek için birkaç adımı takip etmelisiniz.
1. Laravel UI Paketini Yükleyin
Öncelikle, kimlik doğrulama işlevselliğini sağlayacak olan laravel/ui paketini yüklemeniz gerekiyor. Terminalinizde şu komutu çalıştırın:
composer require laravel/ui
2. Auth Scaffolding Oluşturma
Kimlik doğrulama arayüzünü ve gerekli bileşenleri oluşturmak için Laravel UI komutunu kullanacağız. Aşağıdaki komutu çalıştırarak kimlik doğrulama scaffolding'ini oluşturun:
php artisan ui bootstrap --auth
Bu komut, giriş (login) ve kayıt (register) sayfalarının yanı sıra, logout, parola sıfırlama gibi diğer kimlik doğrulama özelliklerini sağlar.
3. NPM Kurulumu
Oluşturulan kimlik doğrulama arayüzünün daha düzgün bir şekilde görüntülenebilmesi için npm komutlarını çalıştırmamız gerekiyor. İlk olarak, npm'yi yüklemek için şu komutu çalıştırın:
npm install
4. NPM Build Çalıştırma
Son olarak, npm run build komutunu çalıştırarak kaynak dosyaları derleyin ve daha iyi bir layout görünümü elde edin:
npm run build
Bu işlemler tamamlandığında, Laravel 11 uygulamanızda kimlik doğrulama işlemi başarılı bir şekilde oluşturulmuş olacaktır.
Adım 7: Rotaları (Routes) Oluşturma
Bu adımda, kullanıcılar, ürünler ve roller modülleri için gerekli rotaları ekleyeceğiz. Bu rotalarda, roller ve ürünler için yetkilendirme kontrollerini içeren middleware kullanacağız. Aşağıda, routes/web.php dosyasına eklemeniz gereken rotalar bulunmaktadır:
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\HomeController;
use App\Http\Controllers\RoleController;
use App\Http\Controllers\UserController;
use App\Http\Controllers\ProductController;
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/home', [HomeController::class, 'index'])->name('home');
// Auth middleware ile korunan rotalar
Route::group(['middleware' => ['auth']], function() {
Route::resource('roles', RoleController::class);
Route::resource('users', UserController::class);
Route::resource('products', ProductController::class);
});
Açıklamalar:
-
Auth Rotaları:
Auth::routes();komutu ile kimlik doğrulama için Laravel'in varsayılan rotalarını ekledik. Bu rotalar giriş, kayıt ve şifre sıfırlama gibi işlevleri içerir. -
Ana Sayfa Rotası:
/homerotası, kimlik doğrulaması başarılı olduğunda kullanıcıyı ana sayfaya yönlendirir. -
Role, User ve Product Rotaları: Bu rotalar, RoleController, UserController ve ProductController'ı kullanarak CRUD işlemlerini gerçekleştirir. auth middleware'i ile korunmuştur, yani bu rotalara sadece giriş yapmış kullanıcılar erişebilir.
Bu rotalarla birlikte kullanıcılar, roller ve ürünler için tam yetkilendirilmiş bir yönetim sistemi oluşturmuş olacaksınız.
Adım 8: Controller'ları Ekleme
Bu adımda, kullanıcılar, ürünler ve roller için üç ayrı controller oluşturacağız. Aşağıda, her bir modül için controller kodları bulunmaktadır:
1. UserController
Bu controller, kullanıcı yönetimi işlemlerini (listeleme, ekleme, düzenleme, silme) gerçekleştirir.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User;
use Spatie\Permission\Models\Role;
use DB;
use Hash;
use Illuminate\Support\Arr;
use Illuminate\View\View;
use Illuminate\Http\RedirectResponse;
class UserController extends Controller
{
public function index(Request $request): View
{
$data = User::latest()->paginate(5);
return view('users.index',compact('data'))
->with('i', ($request->input('page', 1) - 1) * 5);
}
public function create(): View
{
$roles = Role::pluck('name','name')->all();
return view('users.create',compact('roles'));
}
public function store(Request $request): RedirectResponse
{
$this->validate($request, [
'name' => 'required',
'email' => 'required|email|unique:users,email',
'password' => 'required|same:confirm-password',
'roles' => 'required'
]);
$input = $request->all();
$input['password'] = Hash::make($input['password']);
$user = User::create($input);
$user->assignRole($request->input('roles'));
return redirect()->route('users.index')
->with('success', 'User created successfully');
}
public function show($id): View
{
$user = User::find($id);
return view('users.show',compact('user'));
}
public function edit($id): View
{
$user = User::find($id);
$roles = Role::pluck('name','name')->all();
$userRole = $user->roles->pluck('name','name')->all();
return view('users.edit',compact('user','roles','userRole'));
}
public function update(Request $request, $id): RedirectResponse
{
$this->validate($request, [
'name' => 'required',
'email' => 'required|email|unique:users,email,'.$id,
'password' => 'same:confirm-password',
'roles' => 'required'
]);
$input = $request->all();
if (!empty($input['password'])) {
$input['password'] = Hash::make($input['password']);
} else {
$input = Arr::except($input,array('password'));
}
$user = User::find($id);
$user->update($input);
DB::table('model_has_roles')->where('model_id',$id)->delete();
$user->assignRole($request->input('roles'));
return redirect()->route('users.index')
->with('success', 'User updated successfully');
}
public function destroy($id): RedirectResponse
{
User::find($id)->delete();
return redirect()->route('users.index')
->with('success', 'User deleted successfully');
}
}
2. ProductController
Bu controller, ürün yönetimi işlemlerini gerçekleştirir (listeleme, ekleme, düzenleme, silme) ve Spatie Permission ile yetkilendirme kullanır.
<?php
namespace App\Http\Controllers;
use App\Models\Product;
use Illuminate\Http\Request;
use Illuminate\View\View;
use Illuminate\Http\RedirectResponse;
class ProductController extends Controller
{
function __construct()
{
$this->middleware('permission:product-list|product-create|product-edit|product-delete', ['only' => ['index','show']]);
$this->middleware('permission:product-create', ['only' => ['create','store']]);
$this->middleware('permission:product-edit', ['only' => ['edit','update']]);
$this->middleware('permission:product-delete', ['only' => ['destroy']]);
}
public function index(): View
{
$products = Product::latest()->paginate(5);
return view('products.index',compact('products'))
->with('i', (request()->input('page', 1) - 1) * 5);
}
public function create(): View
{
return view('products.create');
}
public function store(Request $request): RedirectResponse
{
request()->validate([
'name' => 'required',
'detail' => 'required',
]);
Product::create($request->all());
return redirect()->route('products.index')
->with('success', 'Product created successfully.');
}
public function show(Product $product): View
{
return view('products.show',compact('product'));
}
public function edit(Product $product): View
{
return view('products.edit',compact('product'));
}
public function update(Request $request, Product $product): RedirectResponse
{
request()->validate([
'name' => 'required',
'detail' => 'required',
]);
$product->update($request->all());
return redirect()->route('products.index')
->with('success', 'Product updated successfully');
}
public function destroy(Product $product): RedirectResponse
{
$product->delete();
return redirect()->route('products.index')
->with('success', 'Product deleted successfully');
}
}
2. RoleController
Aşağıda, RoleController için tamamlayıcı kod örneği bulunmaktadır. Bu controller, kullanıcı rolleri ile ilgili işlemleri (listeleme, ekleme, düzenleme, silme) yönetir ve Spatie/Permission paketini kullanarak yetkilendirme işlemleri gerçekleştirir.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
use DB;
use Illuminate\View\View;
use Illuminate\Http\RedirectResponse;
class RoleController extends Controller
{
// Middleware'lar, gerekli izinlere göre yönlendirmeler yapar.
function __construct()
{
$this->middleware('permission:role-list|role-create|role-edit|role-delete', ['only' => ['index','store']]);
$this->middleware('permission:role-create', ['only' => ['create','store']]);
$this->middleware('permission:role-edit', ['only' => ['edit','update']]);
$this->middleware('permission:role-delete', ['only' => ['destroy']]);
}
// Roller listesini görüntüleme
public function index(Request $request): View
{
$roles = Role::orderBy('id', 'DESC')->paginate(5);
return view('roles.index', compact('roles'))
->with('i', ($request->input('page', 1) - 1) * 5);
}
// Yeni rol oluşturma formunu gösterme
public function create(): View
{
$permission = Permission::get();
return view('roles.create', compact('permission'));
}
// Yeni rolü veritabanına kaydetme
public function store(Request $request): RedirectResponse
{
$this->validate($request, [
'name' => 'required|unique:roles,name',
'permission' => 'required',
]);
$permissionsID = array_map(
function ($value) { return (int)$value; },
$request->input('permission')
);
$role = Role::create(['name' => $request->input('name')]);
$role->syncPermissions($permissionsID);
return redirect()->route('roles.index')
->with('success', 'Role created successfully');
}
// Belirtilen rolü görüntüleme
public function show($id): View
{
$role = Role::find($id);
$rolePermissions = Permission::join("role_has_permissions", "role_has_permissions.permission_id", "=", "permissions.id")
->where("role_has_permissions.role_id", $id)
->get();
return view('roles.show', compact('role', 'rolePermissions'));
}
// Mevcut rolü düzenleme formunu gösterme
public function edit($id): View
{
$role = Role::find($id);
$permission = Permission::get();
$rolePermissions = DB::table("role_has_permissions")->where("role_has_permissions.role_id", $id)
->pluck('role_has_permissions.permission_id', 'role_has_permissions.permission_id')
->all();
return view('roles.edit', compact('role', 'permission', 'rolePermissions'));
}
// Rolü güncelleme
public function update(Request $request, $id): RedirectResponse
{
$this->validate($request, [
'name' => 'required',
'permission' => 'required',
]);
$role = Role::find($id);
$role->name = $request->input('name');
$role->save();
$permissionsID = array_map(
function ($value) { return (int)$value; },
$request->input('permission')
);
$role->syncPermissions($permissionsID);
return redirect()->route('roles.index')
->with('success', 'Role updated successfully');
}
// Belirtilen rolü silme
public function destroy($id): RedirectResponse
{
DB::table("roles")->where('id', $id)->delete();
return redirect()->route('roles.index')
->with('success', 'Role deleted successfully');
}
}
Açıklama
-
Middleware Kullanımı: Bu controller, belirli yollar için izinleri kontrol etmek için middleware kullanır. Bu, kullanıcının yalnızca yetkili olduğu eylemleri gerçekleştirmesine izin verir.
-
CRUD İşlemleri: Rol oluşturma, listeleme, güncelleme ve silme işlemleri, uygun doğrulama ve izin kontrolleriyle gerçekleştirilir.
-
Permission Yönetimi: Rol oluşturulurken veya güncellenirken, kullanıcının izinleri de senkronize edilir.
Bu controller'ı kullanarak uygulamanızda rollerle ilgili yönetim işlevselliğini tamamlamış olursunuz.
Adım 9: Blade Dosyalarını Ekle
Bu adımda aşağıdaki dosyaları oluşturacağız:
Tema Düzeni
resources/views/layouts/app.blade.php
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Fontlar -->
<link rel="dns-prefetch" href="//fonts.bunny.net">
<link href="https://fonts.bunny.net/css?family=Nunito" rel="stylesheet">
<!-- Scriptler -->
@vite(['resources/sass/app.scss', 'resources/js/app.js'])
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" />
</head>
<body>
<div id="app">
<nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
<div class="container">
<a class="navbar-brand" href="{{ url('/') }}">
Laravel 11 Kullanıcı Rolleri ve İzinleri Eğitimi
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<!-- Sol Taraf Menü -->
<ul class="navbar-nav me-auto">
</ul>
<!-- Sağ Taraf Menü -->
<ul class="navbar-nav ms-auto">
<!-- Kimlik Doğrulama Bağlantıları -->
@guest
@if (Route::has('login'))
<li class="nav-item">
<a class="nav-link" href="{{ route('login') }}">{{ __('Giriş Yap') }}</a>
</li>
@endif
@if (Route::has('register'))
<li class="nav-item">
<a class="nav-link" href="{{ route('register') }}">{{ __('Kayıt Ol') }}</a>
</li>
@endif
@else
<li><a class="nav-link" href="{{ route('users.index') }}">Kullanıcıları Yönet</a></li>
<li><a class="nav-link" href="{{ route('roles.index') }}">Rolleri Yönet</a></li>
<li><a class="nav-link" href="{{ route('products.index') }}">Ürünleri Yönet</a></li>
<li class="nav-item dropdown">
<a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
{{ Auth::user()->name }}
</a>
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="{{ route('logout') }}"
onclick="event.preventDefault();
document.getElementById('logout-form').submit();">
{{ __('Çıkış Yap') }}
</a>
<form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-none">
@csrf
</form>
</div>
</li>
@endguest
</ul>
</div>
</div>
</nav>
<main class="py-4">
<div class="container">
<div class="row justify-content-center">
<div class="col-md-12">
<div class="card">
<div class="card-body">
@yield('content')
</div>
</div>
</div>
</div>
</div>
</main>
</div>
</body>
</html>
Kullanıcı Modülü
resources/views/users/index.blade.php
@extends('layouts.app')
@section('content')
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2>Kullanıcı Yönetimi</h2>
</div>
<div class="pull-right">
<a class="btn btn-success mb-2" href="{{ route('users.create') }}"><i class="fa fa-plus"></i> Yeni Kullanıcı Oluştur</a>
</div>
</div>
</div>
@session('success')
<div class="alert alert-success" role="alert">
{{ $value }}
</div>
@endsession
<table class="table table-bordered">
<tr>
<th>No</th>
<th>İsim</th>
<th>Email</th>
<th>Roller</th>
<th width="280px">İşlem</th>
</tr>
@foreach ($data as $key => $user)
<tr>
<td>{{ ++$i }}</td>
<td>{{ $user->name }}</td>
<td>{{ $user->email }}</td>
<td>
@if(!empty($user->getRoleNames()))
@foreach($user->getRoleNames() as $v)
<label class="badge bg-success">{{ $v }}</label>
@endforeach
@endif
</td>
<td>
<a class="btn btn-info btn-sm" href="{{ route('users.show',$user->id) }}"><i class="fa-solid fa-list"></i> Göster</a>
<a class="btn btn-primary btn-sm" href="{{ route('users.edit',$user->id) }}"><i class="fa-solid fa-pen-to-square"></i> Düzenle</a>
<form method="POST" action="{{ route('users.destroy', $user->id) }}" style="display:inline">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger btn-sm"><i class="fa-solid fa-trash"></i> Sil</button>
</form>
</td>
</tr>
@endforeach
</table>
{!! $data->links('pagination::bootstrap-5') !!}
@endsection
resources/views/users/show.blade.php
@extends('layouts.app')
@section('content')
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2>Yeni Kullanıcı Oluştur</h2>
</div>
<div class="pull-right">
<a class="btn btn-primary btn-sm mb-2" href="{{ route('users.index') }}"><i class="fa fa-arrow-left"></i> Geri</a>
</div>
</div>
</div>
@if (count($errors) > 0)
<div class="alert alert-danger">
<strong>Kimlik Hatası!</strong> Girdiğiniz bilgileri kontrol edin.<br><br>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form method="POST" action="{{ route('users.store') }}">
@csrf
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>İsim:</strong>
<input type="text" name="name" placeholder="İsim" class="form-control">
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>E-posta:</strong>
<input type="email" name="email" placeholder="E-posta" class="form-control">
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Şifre:</strong>
<input type="password" name="password" placeholder="Şifre" class="form-control">
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Şifreyi Onayla:</strong>
<input type="password" name="confirm-password" placeholder="Şifreyi Onayla" class="form-control">
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Rol:</strong>
<select name="roles[]" class="form-control" multiple="multiple">
@foreach ($roles as $value => $label)
<option value="{{ $value }}">
{{ $label }}
</option>
@endforeach
</select>
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12 text-center">
<button type="submit" class="btn btn-primary btn-sm mt-2 mb-3"><i class="fa-solid fa-floppy-disk"></i> Gönder</button>
</div>
</div>
</form>
@endsection
resources/views/users/edit.blade.php
@extends('layouts.app')
@section('content')
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2>Kullanıcıyı Düzenle</h2>
</div>
<div class="pull-right">
<a class="btn btn-primary btn-sm mb-2" href="{{ route('users.index') }}"><i class="fa fa-arrow-left"></i> Geri</a>
</div>
</div>
</div>
@if (count($errors) > 0)
<div class="alert alert-danger">
<strong>Kimlik Hatası!</strong> Girdiğiniz bilgileri kontrol edin.<br><br>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form method="POST" action="{{ route('users.update', $user->id) }}">
@csrf
@method('PUT')
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>İsim:</strong>
<input type="text" name="name" placeholder="İsim" class="form-control" value="{{ $user->name }}">
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>E-posta:</strong>
<input type="email" name="email" placeholder="E-posta" class="form-control" value="{{ $user->email }}">
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Şifre:</strong>
<input type="password" name="password" placeholder="Şifre" class="form-control">
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Şifreyi Onayla:</strong>
<input type="password" name="confirm-password" placeholder="Şifreyi Onayla" class="form-control">
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Rol:</strong>
<select name="roles[]" class="form-control" multiple="multiple">
@foreach ($roles as $value => $label)
<option value="{{ $value }}" {{ isset($userRole[$value]) ? 'selected' : ''}}>
{{ $label }}
</option>
@endforeach
</select>
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12 text-center">
<button type="submit" class="btn btn-primary btn-sm mt-2 mb-3"><i class="fa-solid fa-floppy-disk"></i> Gönder</button>
</div>
</div>
</form>
@endsection
resources/views/users/show.blade.php
@extends('layouts.app')
@section('content')
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2>Kullanıcıyı Göster</h2>
</div>
<div class="pull-right">
<a class="btn btn-primary" href="{{ route('users.index') }}"> Geri</a>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>İsim:</strong>
{{ $user->name }}
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>E-posta:</strong>
{{ $user->email }}
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Roller:</strong>
@if(!empty($user->getRoleNames()))
@foreach($user->getRoleNames() as $v)
<label class="badge badge-success">{{ $v }}</label>
@endforeach
@endif
</div>
</div>
</div>
@endsection
resources/views/roles/index.blade.php
@extends('layouts.app')
@section('content')
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2>Rol Yönetimi</h2>
</div>
<div class="pull-right">
@can('role-create')
<a class="btn btn-success btn-sm mb-2" href="{{ route('roles.create') }}"><i class="fa fa-plus"></i> Yeni Rol Oluştur</a>
@endcan
</div>
</div>
</div>
@session('success')
<div class="alert alert-success" role="alert">
{{ $value }}
</div>
@endsession
<table class="table table-bordered">
<tr>
<th width="100px">No</th>
<th>İsim</th>
<th width="280px">Eylem</th>
</tr>
@foreach ($roles as $key => $role)
<tr>
<td>{{ ++$i }}</td>
<td>{{ $role->name }}</td>
<td>
<a class="btn btn-info btn-sm" href="{{ route('roles.show',$role->id) }}"><i class="fa-solid fa-list"></i> Göster</a>
@can('role-edit')
<a class="btn btn-primary btn-sm" href="{{ route('roles.edit',$role->id) }}"><i class="fa-solid fa-pen-to-square"></i> Düzenle</a>
@endcan
@can('role-delete')
<form method="POST" action="{{ route('roles.destroy', $role->id) }}" style="display:inline">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger btn-sm"><i class="fa-solid fa-trash"></i> Sil</button>
</form>
@endcan
</td>
</tr>
@endforeach
</table>
{!! $roles->links('pagination::bootstrap-5') !!}
@endsection
resources/views/roles/create.blade.php
@extends('layouts.app')
@section('content')
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2>Yeni Rol Oluştur</h2>
</div>
<div class="pull-right">
<a class="btn btn-primary btn-sm mb-2" href="{{ route('roles.index') }}"><i class="fa fa-arrow-left"></i> Geri</a>
</div>
</div>
</div>
@if (count($errors) > 0)
<div class="alert alert-danger">
<strong>Kimlik Hatası!</strong> Girdiğiniz bilgileri kontrol edin.<br><br>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form method="POST" action="{{ route('roles.store') }}">
@csrf
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>İsim:</strong>
<input type="text" name="name" placeholder="İsim" class="form-control">
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>İzinler:</strong>
<br/>
@foreach($permission as $value)
<label><input type="checkbox" name="permission[{{$value->id}}]" value="{{$value->id}}" class="name">
{{ $value->name }}</label>
<br/>
@endforeach
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12 text-center">
<button type="submit" class="btn btn-primary btn-sm mb-3"><i class="fa-solid fa-floppy-disk"></i> Gönder</button>
</div>
</div>
</form>
@endsection
resources/views/roles/edit.blade.php
@extends('layouts.app')
@section('content')
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2>Rolü Düzenle</h2>
</div>
<div class="pull-right">
<a class="btn btn-primary btn-sm mb-2" href="{{ route('roles.index') }}"><i class="fa fa-arrow-left"></i> Geri</a>
</div>
</div>
</div>
@if (count($errors) > 0)
<div class="alert alert-danger">
<strong>Kimlik Hatası!</strong> Girdiğiniz bilgileri kontrol edin.<br><br>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form method="POST" action="{{ route('roles.update', $role->id) }}">
@csrf
@method('PUT')
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>İsim:</strong>
<input type="text" name="name" placeholder="İsim" class="form-control" value="{{ $role->name }}">
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>İzinler:</strong>
<br/>
@foreach($permission as $value)
<label><input type="checkbox" name="permission[{{$value->id}}]" value="{{$value->id}}" class="name" {{ in_array($value->id, $rolePermissions) ? 'checked' : ''}}>
{{ $value->name }}</label>
<br/>
@endforeach
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12 text-center">
<button type="submit" class="btn btn-primary btn-sm mb-3"><i class="fa-solid fa-floppy-disk"></i> Gönder</button>
</div>
</div>
</form>
@endsection
resources/views/roles/show.blade.php
@extends('layouts.app')
@section('content')
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2>Rolü Göster</h2>
</div>
<div class="pull-right">
<a class="btn btn-primary" href="{{ route('roles.index') }}"> Geri</a>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>İsim:</strong>
{{ $role->name }}
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>İzinler:</strong>
@if(!empty($rolePermissions))
@foreach($rolePermissions as $v)
<label class="label label-success">{{ $v->name }},</label>
@endforeach
@endif
</div>
</div>
</div>
@endsection
resources/views/products/index.blade.php
@extends('layouts.app')
@section('content')
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2>Ürünler</h2>
</div>
<div class="pull-right">
@can('product-create')
<a class="btn btn-success btn-sm mb-2" href="{{ route('products.create') }}"><i class="fa fa-plus"></i> Yeni Ürün Oluştur</a>
@endcan
</div>
</div>
</div>
@session('success')
<div class="alert alert-success" role="alert">
{{ $value }}
</div>
@endsession
<table class="table table-bordered">
<tr>
<th>No</th>
<th>İsim</th>
<th>Ayrıntılar</th>
<th width="280px">Eylem</th>
</tr>
@foreach ($products as $product)
<tr>
<td>{{ ++$i }}</td>
<td>{{ $product->name }}</td>
<td>{{ $product->detail }}</td>
<td>
<form action="{{ route('products.destroy',$product->id) }}" method="POST">
<a class="btn btn-info btn-sm" href="{{ route('products.show',$product->id) }}"><i class="fa-solid fa-list"></i> Göster</a>
@can('product-edit')
<a class="btn btn-primary btn-sm" href="{{ route('products.edit',$product->id) }}"><i class="fa-solid fa-pen-to-square"></i> Düzenle</a>
@endcan
@csrf
@method('DELETE')
@can('product-delete')
<button type="submit" class="btn btn-danger btn-sm"><i class="fa-solid fa-trash"></i> Sil</button>
@endcan
</form>
</td>
</tr>
@endforeach
</table>
{!! $products->links() !!}
@endsection
resources/views/products/create.blade.php
@extends('layouts.app')
@section('content')
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2>Yeni Ürün Ekle</h2>
</div>
<div class="pull-right">
<a class="btn btn-primary btn-sm" href="{{ route('products.index') }}"><i class="fa fa-arrow-left"></i> Geri</a>
</div>
</div>
</div>
@if ($errors->any())
<div class="alert alert-danger">
<strong>Kimlik Hatası!</strong> Girdiğiniz bilgileri kontrol edin.<br><br>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form action="{{ route('products.store') }}" method="POST">
@csrf
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>İsim:</strong>
<input type="text" name="name" class="form-control" placeholder="İsim">
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Ayrıntılar:</strong>
<textarea class="form-control" style="height:150px" name="detail" placeholder="Ayrıntılar"></textarea>
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12 text-center">
<button type="submit" class="btn btn-primary btn-sm mb-3 mt-2"><i class="fa-solid fa-floppy-disk"></i> Gönder</button>
</div>
</div>
</form>
@endsection
resources/views/products/edit.blade.php
@extends('layouts.app')
@section('content')
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2>Ürünü Düzenle</h2>
</div>
<div class="pull-right">
<a class="btn btn-primary btn-sm mb-2" href="{{ route('products.index') }}"><i class="fa fa-arrow-left"></i> Geri</a>
</div>
</div>
</div>
@if ($errors->any())
<div class="alert alert-danger">
<strong>Kimlik Hatası!</strong> Girdiğiniz bilgileri kontrol edin.<br><br>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form action="{{ route('products.update',$product->id) }}" method="POST">
@csrf
@method('PUT')
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>İsim:</strong>
<input type="text" name="name" value="{{ $product->name }}" class="form-control" placeholder="İsim">
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Ayrıntılar:</strong>
<textarea class="form-control" style="height:150px" name="detail" placeholder="Ayrıntılar">{{ $product->detail }}</textarea>
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12 text-center">
<button type="submit" class="btn btn-primary btn-sm mb-2 mt-2"><i class="fa-solid fa-floppy-disk"></i> Gönder</button>
</div>
</div>
</form>
@endsection
resources/views/products/show.blade.php
@extends('layouts.app')
@section('content')
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2>Ürünü Göster</h2>
</div>
<div class="pull-right">
<a class="btn btn-primary" href="{{ route('products.index') }}"> Geri</a>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>İsim:</strong>
{{ $product->name }}
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Ayrıntılar:</strong>
{{ $product->detail }}
</div>
</div>
</div>
@endsection
Adım 10: İzinler ve Admin Kullanıcısı için Seeder Oluşturma
Bu adımda, izinler için bir seeder oluşturacağız. Şu anda sabit izinlerimiz var, bu nedenle aşağıda listelenen izinleri bir seeder kullanarak oluşturacağız. Ancak, isterseniz daha fazla izin de ekleyebilirsiniz.
-
role-list -
role-create -
role-edit -
role-delete -
product-list -
product-create -
product-edit -
product-delete
Öncelikle aşağıdaki komutla bir seeder oluşturun:
php artisan make:seeder PermissionTableSeeder
Aşağıdaki kodu PermissionTableSeeder seeder'ına yerleştirin:
database/seeders/PermissionTableSeeder.php
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Permission;
class PermissionTableSeeder extends Seeder
{
/**
* Veritabanı seed işlemlerini çalıştır.
*/
public function run(): void
{
$permissions = [
'role-list',
'role-create',
'role-edit',
'role-delete',
'product-list',
'product-create',
'product-edit',
'product-delete'
];
foreach ($permissions as $permission) {
Permission::create(['name' => $permission]);
}
}
}
Bundan sonra, PermissionTableSeeder seeder'ını çalıştırmak için aşağıdaki komutu çalıştırın:
php artisan db:seed --class=PermissionTableSeeder
Şimdi bir admin kullanıcısı oluşturmak için yeni bir seeder oluşturun.
php artisan make:seeder CreateAdminUserSeeder
database/seeders/CreateAdminUserSeeder.php
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use App\Models\User;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
class CreateAdminUserSeeder extends Seeder
{
/**
* Veritabanı seed işlemlerini çalıştır.
*/
public function run(): void
{
$user = User::create([
'name' => 'Aydın Yağız',
'email' => 'admin@gmail.com',
'password' => bcrypt('123456')
]);
$role = Role::create(['name' => 'Admin']);
$permissions = Permission::pluck('id','id')->all();
$role->syncPermissions($permissions);
$user->assignRole([$role->id]);
}
}
Ardından, seeder'ı aşağıdaki komut ile çalıştırın:
php artisan db:seed --class=CreateAdminUserSeeder
Laravel Uygulamasını Çalıştırma:
Tüm gerekli adımlar tamamlandı, şimdi aşağıdaki komutu yazarak Laravel uygulamasını çalıştırın:
php artisan serve
Web tarayıcınıza gidin, verilen URL'yi yazın ve uygulamanın çıktısını görüntüleyin:
Şimdi aşağıdaki kimlik bilgileri ile giriş yapabilirsiniz:
- Email:
admin@gmail.com - Password:
123456
Artık uygulamayı çalıştırıp kontrol edebilirsiniz.
