<?php namespace App\Http\Controllers; use App\Models\Permission; use App\Models\Role; use App\Rules\uniqueForSchool; use App\Services\BootstrapTableService; use App\Services\CachingService; use App\Services\ResponseService; use Auth; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Validator; use Throwable; class RoleController extends Controller { /** * @var array|string[] */ private array $reserveRole; private CachingService $cache; public function __construct(CachingService $cache) { $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']]); $this->reserveRole = [ 'Super Admin', 'School Admin', 'Teacher', 'Guardian', 'Student' ]; $this->cache = $cache; } public function index() { ResponseService::noFeatureThenRedirect('Staff Management'); ResponseService::noAnyPermissionThenRedirect(['role-list', 'role-create', 'role-edit', 'role-delete']); $roles = Role::orderBy('id', 'DESC')->get(); return view('roles.index', compact('roles')); } public function list(Request $request) { ResponseService::noFeatureThenRedirect('Staff Management'); ResponseService::noPermissionThenRedirect('role-list'); $offset = request('offset', 0); $limit = request('limit', 10); $sort = request('sort', 'id'); $order = request('order', 'DESC'); // If user is school admin or super admin, then show all roles if (Auth::user() && Auth::user()->school_id) { $sql = Role::where('editable', 1)->whereNot('name', 'Teacher'); } else { $sql = Role::where('editable', 1)->whereNot('name', 'Teacher'); } if (!empty($request->search)) { $search = $request->search; $sql->where(function ($query) use ($search) { $query->where('id', 'LIKE', "%$search%")->orwhere('name', 'LIKE', "%$search%"); }); } $total = $sql->count(); if ($offset >= $total && $total > 0) { $lastPage = floor(($total - 1) / $limit) * $limit; // calculate last page offset $offset = $lastPage; } $sql->orderBy($sort, $order)->skip($offset)->take($limit); $res = $sql->get(); $bulkData = array(); $bulkData['total'] = $total; $rows = array(); $no = 1; foreach ($res as $row) { $operate = BootstrapTableService::button('fa fa-eye', route('roles.show', $row->id), ['btn-gradient-success'], ['title' => 'View']); if (Auth::user()->can('role-edit')) { $operate .= BootstrapTableService::editButton(route('roles.edit', $row->id), false); } if ($row->custom_role != 0 && Auth::user()->can('role-delete')) { $operate .= BootstrapTableService::deleteButton(route('roles.destroy', $row->id)); } $tempRow = $row->toArray(); $tempRow['no'] = $no++; $tempRow['operate'] = $operate; $rows[] = $tempRow; } $bulkData['rows'] = $rows; return response()->json($bulkData); } public function create() { ResponseService::noFeatureThenRedirect('Staff Management'); ResponseService::noPermissionThenRedirect('role-create'); $permission = Permission::whereHas('roles', static function ($q) { $q->where('name', '!=', 'Teacher'); })->orderBy('name')->get(); return view('roles.create', compact('permission')); } public function store(Request $request) { ResponseService::noFeatureThenRedirect('Staff Management'); ResponseService::noPermissionThenRedirect('role-create'); try { $this->validate($request, [ 'name' => [ 'required', new uniqueForSchool('roles', 'name', null, Auth::user()->school_id) ], 'permission' => 'required' ]); if (in_array($request->name, $this->reserveRole)) { return redirect()->back()->with('error', $request->name . " " . trans("is not a valid Role name Because it's Reserved Role")); } DB::beginTransaction(); $role = Role::create(['name' => $request->input('name'), 'school_id' => Auth::user()->school_id]); $role->syncPermissions($request->input('permission')); DB::commit(); return redirect()->route('roles.index')->with('success', trans('Data Stored Successfully')); } catch (Throwable $e) { DB::rollBack(); return redirect()->back()->with('error', $e->getMessage()); } } public function show($id) { ResponseService::noFeatureThenRedirect('Staff Management'); ResponseService::noPermissionThenRedirect('role-list'); $role = Role::findOrFail($id); $rolePermissions = Permission::join("role_has_permissions", "role_has_permissions.permission_id", "=", "permissions.id")->where("role_has_permissions.role_id", $id)->orderBy('name')->get(); return view('roles.show', compact('role', 'rolePermissions')); } public function edit($id) { ResponseService::noFeatureThenRedirect('Staff Management'); ResponseService::noPermissionThenRedirect('role-edit'); $role = Role::findOrFail($id); if ($role->name == "Teacher") { $permission = Permission::orderBy('name')->get(); } else { $permission = Permission::whereHas('roles', static function ($q) { $q->where('name', '!=', 'Teacher'); })->orderBy('name')->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')); } public function update(Request $request, $id) { ResponseService::noFeatureThenRedirect('Staff Management'); ResponseService::noPermissionThenRedirect('role-edit'); try { DB::beginTransaction(); $validator = Validator::make($request->all(), [ 'name' => 'required', 'permission' => 'required' ], [ 'permission.required' => 'Please select at least one permission.' ]); if ($validator->fails()) { ResponseService::validationError($validator->errors()->first()); } if (in_array($request->name, $this->reserveRole)) { ResponseService::errorResponse($request->name . " " . trans("is not a valid Role name Because it's Reserved Role")); } $role = Role::findOrFail($id); $role->name = $request->input('name'); $role->save(); $role->syncPermissions($request->input('permission')); DB::commit(); ResponseService::successResponse('Data Updated Successfully'); } catch (Throwable $e) { DB::rollBack(); return redirect()->back()->with('error', $e->getMessage()); } } public function destroy($id) { try { ResponseService::noFeatureThenRedirect('Staff Management'); ResponseService::noPermissionThenSendJson('role-delete'); $role = Role::withCount('users')->findOrFail($id); if ($role->users_count) { ResponseService::errorResponse('cannot_delete_because_data_is_associated_with_other_data'); } else { Role::findOrFail($id)->delete(); ResponseService::successResponse('Data Deleted Successfully'); } } catch (Throwable $e) { DB::rollBack(); ResponseService::logErrorResponse($e); ResponseService::errorResponse(); } } }