Repository Pattern + Spatie Laravel Permission: Managing Roles and Permissions Effectively

Hòa Nguyễn Coder

Published in Web Developer · Đã đăng vào tháng 12 3, 2024 8:22 PM

Ae chắc sử đã dùng Laravel và đã sử dụng qua! spatie/laravel-permission rồi, thư viện này rất tuyệt với giúp chúng ta cấu hình Role, Persmission,...

Nay mình cũng sử dụng nhưng, mình cấu hình nó vào Repository để tiện cho việc gọi và tái sử dụng sau này 

Về phần cài đặt thì mọi người có thể vào trang của spatie/laravel-permission

Okay, mình sẽ tích hợp như sau:

/App/Http/Repository/RepositoryInterface.php


<?php

namespace App\Repositories\Interfaces;

interface RepositoryInterface
{
    /**
     * Get all
     * @return mixed
     */
    public function getAll();

    /**
     * Get one
     * @param $id
     * @return mixed
     */
    public function find($id);

     /**
     * Get one
     * @param $id
     * @return mixed
     */
    public function findOrFail($id);

    /**
     * Create
     * @param array $attributes
     * @return mixed
     */
    public function create($attributes = []);

    /**
     * Update
     * @param $id
     * @param array $attributes
     * @return mixed
     */
    public function update($id, $attributes = []);

    /**
     * Delete
     * @param $id
     * @return mixed
     */
    public function delete($id);

    public function getColumn($col,$id);
}

/App/Http/Repository/RoleRepositoryInterface.php


namespace App\Repositories\Interfaces;
use App\Repositories\Interfaces\RepositoryInterface;
interface RoleRepositoryInterface extends RepositoryInterface{
    public function getPermissionsByRole(string $role) : \Illuminate\Support\Collection;
}

/App/Http/Repository/BaseRepository.php


<?php

namespace App\Repositories;

use App\Repositories\Interfaces\RepositoryInterface;

abstract class BaseRepository implements RepositoryInterface
{
    //model muốn tương tác
    protected $model;

   //khởi tạo
    public function __construct()
    {
        $this->setModel();
    }

    //lấy model tương ứng
    abstract public function getModel();

    /**
     * Set model
     */
    public function setModel()
    {
        $this->model = app()->make(
            $this->getModel()
        );
    }

    public function getAll()
    {
        return $this->model->all();
    }

    public function find($id)
    {
        $result = $this->model->find($id);

        return $result;
    }

    public function findOrFail($id)
    {

        $result = $this->model->findOrFail($id);
        return $result;
    }

    public function create($attributes = [])
    {
        return $this->model->create($attributes);
    }

    public function update($id, $attributes = [])
    {
        $result = $this->find($id);
        if ($result) {
            $result->update($attributes);
            return $result;
        }

        return false;
    }

    public function delete($id)
    {
        $result = $this->find($id);
        if ($result) {
            $result->delete();

            return true;
        }

        return false;
    }
     /* 
        @id : id cua category
    */
    public function getColumn($col=NULL,$id=NULL){
        if($id!=NULL && $col!=NULL){
           
            return $this->model->select($col)->find($id);
        }
    }
}

/App/Http/Repository/RoleRepository.php

Ở đây chúng ta cần return về Role Models mà thư viện đã hổ trợ cho chúng , bạn xem chổ hàm getModel(), mình có return về \Spatie\Permission\Models\Role::class


namespace App\Repositories;
use App\Repositories\BaseRepository;
use App\Repositories\Interfaces\RoleRepositoryInterface;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
class RoleRepository extends BaseRepository implements RoleRepositoryInterface{

   //lấy model tương ứng
   public function getModel()
   {
       return \Spatie\Permission\Models\Role::class;
   }

   /* 
     @params : string name
     Lấy dánh sách Persmission của Role 
   */
    public function getPermissionsByRole(string $roleName): \Illuminate\Support\Collection
    {
        $role = Role::findByName($roleName, 'web'); // Nếu bạn sử dụng guard 'web'
        
        if (!$role) {
            throw new \Illuminate\Database\Eloquent\ModelNotFoundException("Role '{$roleName}' not found.");
        }
    
        return $role->permissions; // Trả về danh sách quyền
    }
  
}

Cấu hình trong Provider 


namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Repositories\UserRepository;
use App\Repositories\RoleRepository;
use App\Repositories\Interfaces\UserRepositoryInterface;
use App\Repositories\Interfaces\RoleRepositoryInterface;
class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        //
    }

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        $this->app->singleton(UserRepositoryInterface::class,UserRepository::class);
        $this->app->singleton(RoleRepositoryInterface::class,RoleRepository::class);
    }
}


Sử dụng trong Controller 


namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Repositories\Interfaces\UserRepositoryInterface;
use App\Repositories\Interfaces\RoleRepositoryInterface;
class UserController extends Controller
{

    protected $userRepo, $roleRepo;
    public function __construct(   
    UserRepositoryInterface $userRepo,
    RoleRepositoryInterface $roleRepo
    )
    {
        $this->userRepo = $userRepo;
        $this->roleRepo = $roleRepo;
    }
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        $users = $this->userRepo->getAll();

        $roles = $this->roleRepo->getPermissionsByRole('super-admin');
        $role = $this->roleRepo->find(1);
        $role_column = $this->roleRepo->getColumn('name',1);
        dd($roles);

        return view('admin.user.list',compact('users','rolers'));
    }

}

Kết quả chúng ta sẽ được như sau:

Nếu bạn thấy đem lại kiến thức bổ ích, hãy Click xem quảng cáo trên trang website của mình nhé! 🚀