diff --git a/app/DataTables/Logs/AuditLogsDataTable.php b/app/DataTables/Logs/AuditLogsDataTable.php new file mode 100644 index 0000000..350ea93 --- /dev/null +++ b/app/DataTables/Logs/AuditLogsDataTable.php @@ -0,0 +1,120 @@ +eloquent($query) + ->rawColumns(['description', 'properties', 'action']) + ->editColumn('id', function (Activity $model) { + return $model->id; + }) + ->editColumn('subject_id', function (Activity $model) { + if (!isset($model->subject)) { + return ''; + } + + if (isset($model->subject->name)) { + return $model->subject->name; + } + + return $model->subject->user()->first()->name; + }) + ->editColumn('causer_id', function (Activity $model) { + return $model->causer ? $model->causer->name : __('System'); + }) + ->editColumn('properties', function (Activity $model) { + $content = $model->properties; + + return view('pages.log.audit._details', compact('content')); + }) + ->editColumn('created_at', function (Activity $model) { + return $model->created_at->format('d M, Y H:i:s'); + }) + ->addColumn('action', function (Activity $model) { + return view('pages.log.audit._action-menu', compact('model')); + }); + } + + /** + * Get query source of dataTable. + * + * @param Activity $model + * + * @return \Illuminate\Database\Eloquent\Builder + */ + public function query(Activity $model) + { + return $model->newQuery(); + } + + /** + * Optional method if you want to use html builder. + * + * @return \Yajra\DataTables\Html\Builder + */ + public function html() + { + return $this->builder() + ->setTableId('audit-log-table') + ->columns($this->getColumns()) + ->minifiedAjax() + ->stateSave(true) + ->orderBy(6) + ->responsive() + ->autoWidth(false) + ->parameters([ + 'scrollX' => true, + 'drawCallback' => 'function() { KTMenu.createInstances(); }', + ]) + ->addTableClass('align-middle table-row-dashed fs-6 gy-5'); + } + + /** + * Get columns. + * + * @return array + */ + protected function getColumns() + { + return [ + Column::make('id')->title('Log ID'), + Column::make('log_name')->title(__('Location')), + Column::make('description'), + Column::make('subject_type'), + Column::make('subject_id')->title(__('Subject')), + Column::make('causer_id')->title(__('Causer')), + Column::make('created_at'), + Column::computed('action') + ->exportable(false) + ->printable(false) + ->addClass('text-center') + ->responsivePriority(-1), + Column::make('properties')->addClass('none'), + ]; + } + + /** + * Get filename for export. + * + * @return string + */ + protected function filename() : string + { + return 'DataLogs_'.date('YmdHis'); + } +} diff --git a/app/DataTables/Logs/SystemLogsDataTable.php b/app/DataTables/Logs/SystemLogsDataTable.php new file mode 100644 index 0000000..c64385f --- /dev/null +++ b/app/DataTables/Logs/SystemLogsDataTable.php @@ -0,0 +1,143 @@ +collection($query) + ->rawColumns(['action', 'level']) + ->editColumn('id', function (Collection $model) { + return Str::limit($model->get('id'), 5, ''); + }) + ->editColumn('file_path', function (Collection $model) { + return Str::limit($model->get('file_path')); + }) + ->editColumn('message', function (Collection $model) { + return Str::limit($model->get('context')->message, 95); + }) + ->editColumn('date', function (Collection $model) { + return $model->get('date')->format('d M, Y H:i:s'); + }) + ->editColumn('level', function (Collection $model) { + $styles = [ + 'emergency' => 'danger', + 'alert' => 'warning', + 'critical' => 'danger', + 'error' => 'danger', + 'warning' => 'warning', + 'notice' => 'success', + 'info' => 'info', + 'debug' => 'primary', + ]; + $style = 'info'; + if (isset($styles[$model->get('level')])) { + $style = $styles[$model->get('level')]; + } + $value = $model->get('level'); + + return '
'.$value.'
'; + }) + ->editColumn('context', function (Collection $model) { + $content = $model->get('context'); + + return view('pages.log.system._details', compact('content')); + }) + ->addColumn('action', function (Collection $model) { + return view('pages.log.system._action-menu', compact('model')); + }); + } + + /** + * Get query source of dataTable. + * + * @param LogReader $model + * + * @return Collection + */ + public function query(LogReader $model) + { + $data = collect(); + + $model->setLogPath(storage_path('logs')); + + try { + $data = $model->get()->merge($data); + } catch (UnableToRetrieveLogFilesException $exception) { + } + + $data = $data->map(function ($a) { + return (collect($a))->only(['id', 'date', 'environment', 'level', 'file_path', 'context']); + }); + + return $data; + } + + /** + * Optional method if you want to use html builder. + * + * @return \Yajra\DataTables\Html\Builder + */ + public function html() + { + return $this->builder() + ->setTableId('system-log-table') + ->columns($this->getColumns()) + ->minifiedAjax() + ->stateSave(true) + ->orderBy(3) + ->responsive() + ->autoWidth(false) + ->parameters(['scrollX' => true]) + ->addTableClass('align-middle table-row-dashed fs-6 gy-5'); + } + + /** + * Get columns. + * + * @return array + */ + protected function getColumns() + { + return [ + Column::make('id')->title('Log ID')->width(50), + Column::make('message'), + Column::make('level'), + Column::make('date')->width(130), + Column::computed('action') + ->exportable(false) + ->printable(false) + ->addClass('text-center') + ->responsivePriority(-1), + Column::make('environment')->addClass('none'), + Column::make('file_path')->title(__('Log Path'))->addClass('none'), + Column::make('context')->addClass('none'), + ]; + } + + /** + * Get filename for export. + * + * @return string + */ + protected function filename() : string + { + return 'SystemLogs_'.date('YmdHis'); + } +} diff --git a/app/DataTables/Users/PermissionsDataTable.php b/app/DataTables/Users/PermissionsDataTable.php new file mode 100644 index 0000000..83a504b --- /dev/null +++ b/app/DataTables/Users/PermissionsDataTable.php @@ -0,0 +1,102 @@ +eloquent($query) + ->filter(function ($query) { + if (request()->has('search')) { + $search = request()->get('search'); + $query->where('name', 'like', "%" . $search['value'] . "%"); + } + }) + ->rawColumns(['action','role']) + ->addIndexColumn() + ->addColumn('name', function (PermissionGroup $model) { + return $model->name; + }) + ->addColumn('role', function (PermissionGroup $model){ + $role = $model->roles($model); + return view('pages.users.permissions._checkbox', compact('role')); + }) + ->addColumn('action', function (PermissionGroup $model) { + return view('pages.users.permissions._action', compact('model')); + }); + } + + /** + * Get query source of dataTable. + * + * @param \App\Models\PermissionGroup $model + * @return \Illuminate\Database\Eloquent\Builder + */ + public function query(PermissionGroup $model) + { + return $model->newQuery(); + } + + /** + * Optional method if you want to use html builder. + * + * @return \Yajra\DataTables\Html\Builder + */ + public function html() + { + return $this->builder() + ->setTableId('user-permissions-table') + ->columns($this->getColumns()) + ->minifiedAjax() + ->orderBy(1,'asc') + ->stateSave(false) + ->responsive() + ->autoWidth(false) + ->parameters([ + 'scrollX' => true, + 'drawCallback' => 'function() { KTMenu.createInstances(); }', + ]) + ->addTableClass('align-middle table-row-dashed fs-6 gy-5'); + } + + /** + * Get columns. + * + * @return array + */ + protected function getColumns() + { + return [ + Column::make('DT_RowIndex')->title('No')->orderable(false)->searchable(false), + Column::make('name')->title('Name'), + Column::make('role')->title('Assign To'), + Column::computed('action') + ->exportable(false) + ->printable(false) + ->addClass('text-center') + ->responsivePriority(-1), + + ]; + } + + /** + * Get filename for export + * @return string + */ + protected function filename() : string + { + return 'Permissions_' . date('YmdHis'); + } + } diff --git a/app/DataTables/Users/RolesDataTable.php b/app/DataTables/Users/RolesDataTable.php new file mode 100644 index 0000000..3b6f6a5 --- /dev/null +++ b/app/DataTables/Users/RolesDataTable.php @@ -0,0 +1,96 @@ +eloquent($query) + ->rawColumns(['action']) + ->addIndexColumn() + ->filter(function ($query) { + if (request()->has('search')) { + $search = request()->get('search'); + $query->where('name', 'like', "%" . $search['value'] . "%"); + } + }) + ->addColumn('action', function (Role $model) { + return view('pages.users.roles._action', compact('model')); + }); + } + + /** + * Get query source of dataTable. + * + * @param \App\Models\Role $model + * @return \Illuminate\Database\Eloquent\Builder + */ + public function query(Role $model) + { + return $model->newQuery(); + } + + /** + * Optional method if you want to use html builder. + * + * @return \Yajra\DataTables\Html\Builder + */ + public function html() + { + return $this->builder() + ->setTableId('user-roles-table') + ->columns($this->getColumns()) + ->minifiedAjax() + ->orderBy(1,'asc') + ->stateSave(false) + ->responsive() + ->autoWidth(false) + ->parameters([ + 'scrollX' => true, + 'drawCallback' => 'function() { KTMenu.createInstances(); }', + ]) + ->addTableClass('align-middle table-row-dashed fs-6 gy-5'); + + } + + /** + * Get columns. + * + * @return array + */ + protected function getColumns() + { + return [ + Column::make('DT_RowIndex')->title('No')->orderable(false)->searchable(false), + Column::make('name'), + Column::computed('action') + ->exportable(false) + ->printable(false) + ->addClass('text-center') + ->responsivePriority(-1), + + ]; + } + + /** + * Get filename for export. + * + * @return string + */ + protected function filename() : string + { + return 'Roles_' . date('YmdHis'); + } +} diff --git a/app/DataTables/Users/UsersDataTable.php b/app/DataTables/Users/UsersDataTable.php new file mode 100644 index 0000000..cfea84c --- /dev/null +++ b/app/DataTables/Users/UsersDataTable.php @@ -0,0 +1,108 @@ +eloquent($query) + ->filter(function ($query) { + $search = request()->get('search'); + if ($search['value']!=="") { + $query->where('first_name', 'like', "%" . $search['value'] . "%") + ->orWhere('email', 'like', "%" . $search['value'] . "%") + ->orWhereRelation('info','phone', 'like', "%" . $search['value'] . "%"); + } + }) + ->rawColumns(['first_name','action']) + ->addIndexColumn() + ->editColumn('first_name', function (User $model) { + return view('pages.users._avatar', compact('model')); + }) + ->editColumn('email', function (User $model) { + return $model->email; + }) + ->addColumn('phone', function (User $model) { + return $model->info->phone; + }) + ->addColumn('action', function (User $model) { + return view('pages.users._action', compact('model')); + }); + } + + /** + * Get query source of dataTable. + * + * @param \App\Models\User $model + * @return \Illuminate\Database\Eloquent\Builder + */ + public function query(User $model) + { + return $model->newQuery(); + } + + /** + * Optional method if you want to use html builder. + * + * @return \Yajra\DataTables\Html\Builder + */ + public function html() + { + return $this->builder() + ->setTableId('users-table') + ->columns($this->getColumns()) + ->minifiedAjax() + ->orderBy(1,'asc') + ->stateSave(false) + ->responsive() + ->autoWidth(false) + ->parameters([ + 'scrollX' => true, + 'drawCallback' => 'function() { KTMenu.createInstances(); }', + ]) + ->addTableClass('align-middle table-row-dashed fs-6 gy-5'); + } + + /** + * Get columns. + * + * @return array + */ + protected function getColumns() + { + return [ + Column::make('DT_RowIndex')->title('No')->orderable(false)->searchable(false), + Column::make('first_name')->title(__('Name')), + Column::make('email'), + Column::make('phone'), + Column::computed('action') + ->exportable(false) + ->printable(false) + ->addClass('text-center') + ->responsivePriority(-1), + ]; + } + + /** + * Get filename for export. + * + * @return string + */ + protected function filename() : string + { + return 'Users_' . date('YmdHis'); + } +} diff --git a/app/Http/Controllers/DirectoratController.php b/app/Http/Controllers/DirectoratController.php index 19bf454..9d0be94 100644 --- a/app/Http/Controllers/DirectoratController.php +++ b/app/Http/Controllers/DirectoratController.php @@ -7,6 +7,7 @@ use App\Http\Requests\StoreDirectoratRequest; use App\Http\Requests\UpdateDirectoratRequest; use App\Models\Directorat; use Illuminate\Http\Request; +use Spatie\Activitylog\Facades\CauserResolver; class DirectoratController extends Controller { @@ -18,6 +19,8 @@ class DirectoratController extends Controller //$this->user = Auth::guard('web')->user(); return $next($request); }); + + //CauserResolver::setCauser($this->user); } /** @@ -96,7 +99,9 @@ class DirectoratController extends Controller // Update the Directorat... if($validated){ try{ + CauserResolver::setCauser($this->user); $directorat->update($validated); + //return redirect()->route('directorat.index')->with('success', 'Directorat updated successfully.'); echo json_encode(['status' => 'success', 'message' => 'Directorat updated successfully.']); }catch(\Exception $e){ @@ -114,6 +119,5 @@ class DirectoratController extends Controller public function destroy(Directorat $directorat){ $directorat->delete(); echo json_encode(['status' => 'success', 'message' => 'Directorat deleted successfully.']); - //return redirect()->route('directorat.index')->with('success', 'Directorat deleted successfully.'); } } diff --git a/app/Http/Controllers/Logs/AuditLogsController.php b/app/Http/Controllers/Logs/AuditLogsController.php new file mode 100644 index 0000000..2001944 --- /dev/null +++ b/app/Http/Controllers/Logs/AuditLogsController.php @@ -0,0 +1,35 @@ +render('pages.log.audit.index'); + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * + * @return \Illuminate\Http\Response + */ + public function destroy($id) + { + $activity = Activity::find($id); + + // Delete from db + $activity->delete(); + } +} diff --git a/app/Http/Controllers/Logs/SystemLogsController.php b/app/Http/Controllers/Logs/SystemLogsController.php new file mode 100644 index 0000000..1b31d47 --- /dev/null +++ b/app/Http/Controllers/Logs/SystemLogsController.php @@ -0,0 +1,32 @@ +render('pages.log.system.index'); + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * + * @return \Illuminate\Http\Response + */ + public function destroy($id, LogReader $logReader) + { + return $logReader->find($id)->delete(); + } +} diff --git a/app/Http/Controllers/Users/PermissionsController.php b/app/Http/Controllers/Users/PermissionsController.php new file mode 100644 index 0000000..fdbd1ad --- /dev/null +++ b/app/Http/Controllers/Users/PermissionsController.php @@ -0,0 +1,203 @@ +middleware(function ($request, $next) { + $this->user = Auth::guard('web')->user(); + return $next($request); + }); + } + + /** + * Display a listing of the resource. + * + * @return \Illuminate\Http\Response + */ + public function index(PermissionsDataTable $dataTable) + { + /* if (is_null($this->user) || !$this->user->can('permission.read')) { + abort(403, 'Sorry !! You are Unauthorized to view any permission !'); + }*/ + return $dataTable->render('pages.users.permissions.index'); + } + + /** + * Show the form for creating a new resource. + * + * @return \Illuminate\Http\Response + */ + public function create() + { + + } + + /** + * Store a newly created resource in storage. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\Response + */ + public function store(Request $request) + { + /*if (is_null($this->user) || !$this->user->can('permission.create')) { + abort(403, 'Sorry !! You are Unauthorized to create any permission !'); + }*/ + + // Validation Data + $validate = $request->validate([ + 'name' => 'required|max:100|unique:permission_groups' + ], [ + 'name.requried' => 'Please give a permission name' + ]); + + if($validate){ + try{ + // Process Data + $group = PermissionGroup::create(['name' => $request->name]); + + $group_name = strtolower($request->name); + $data = [ + $group_name.'.create', + $group_name.'.read', + $group_name.'.update', + $group_name.'.delete', + $group_name.'.authorize', + $group_name.'.report' + ]; + + foreach($data as $permission){ + Permission::create([ + 'name' => $permission, + 'guard_name' => 'web', + 'permission_group_id' => $group->id + ]); + } + + echo json_encode(['status' => 'success', 'message' => 'Permission created successfully.']); + }catch(\Exception $e){ + echo json_encode(['status' => 'error', 'message' => 'Permission created failed.']); + } + } + + return false; + } + + /** + * Display the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function show($id) + { + // + } + + /** + * Show the form for editing the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function edit($id) + { + /*if (is_null($this->user) || !$this->user->can('permission.update')) { + abort(403, 'Sorry !! You are Unauthorized to edit any permission !'); + }*/ + + $permission = PermissionGroup::find($id); + echo json_encode($permission); + } + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\Response + */ + public function update(Request $request, $id) + { + /* if (is_null($this->user) || !$this->user->can('permission.update')) { + abort(403, 'Sorry !! You are Unauthorized to edit any permission !'); + }*/ + + // Validation Data + $validated = $request->validate([ + 'name' => 'required|max:100|unique:permission_groups,name,' . $id + ], [ + 'name.requried' => 'Please give a permission name' + ]); + + if ($validated) { + try { + // Process Data + $group = PermissionGroup::find($id); + $group->name = $request->name; + + if($group->save()){ + $permissions = Permission::where('permission_group_id', $group->id)->get(); + + $data = [ + $group_name . '.create', + $group_name . '.read', + $group_name . '.update', + $group_name . '.delete', + $group_name . '.authorize', + $group_name . '.report' + ]; + + $i = 0; + foreach($permissions as $permission){ + $permission->name = $data[$i]; + $permission->save(); + + $i++; + } + } + + echo json_encode(['status' => 'success', 'message' => 'Permission updated successfully.']); + } catch (\Exception $e) { + echo json_encode(['status' => 'error', 'message' => 'Permission updated failed.']); + } + } + + return false; + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function destroy($id) + { + /*if (is_null($this->user) || !$this->user->can('permission.delete')) { + abort(403, 'Sorry !! You are Unauthorized to delete any role !'); + }*/ + + + $permission = PermissionGroup::find($id); + if (!is_null($permission)) { + if($permission->delete()){ + Permission::where('permission_group_id',$id)->delete(); + } + } + + echo json_encode(['status' => 'success', 'message' => 'Permission deleted successfully.']); + } +} diff --git a/app/Http/Controllers/Users/RolesController.php b/app/Http/Controllers/Users/RolesController.php new file mode 100644 index 0000000..2a4f5c3 --- /dev/null +++ b/app/Http/Controllers/Users/RolesController.php @@ -0,0 +1,190 @@ +middleware(function ($request, $next) { + $this->user = Auth::guard('web')->user(); + return $next($request); + }); + } + + /** + * Display a listing of the resource. + * + * @return \Illuminate\Http\Response + */ + public function index(RolesDataTable $dataTable) + { + /*if (is_null($this->user) || !$this->user->can('role.read')) { + abort(403, 'Sorry !! You are Unauthorized to view any role !'); + }*/ + $permissiongroups = PermissionGroup::all(); + + return $dataTable->render('pages.users.roles.index', compact('permissiongroups')); + } + + /** + * Show the form for creating a new resource. + * + * @return \Illuminate\Http\Response + */ + public function create() + { + } + + /** + * Store a newly created resource in storage. + * + * @param \Illuminate\Http\Request $request + * + * @return \Illuminate\Http\Response + */ + public function store(Request $request) + { + /*if (is_null($this->user) || !$this->user->can('role.create')) { + abort(403, 'Sorry !! You are Unauthorized to create any role !'); + }*/ + + // Validation Data + $validated = $request->validate([ + 'name' => 'required|max:100|unique:roles' + ], [ + 'name.requried' => 'Please give a role name' + ]); + + + if($validated){ + try { + // Process Data + $role = Role::create(['name' => $request->name, 'guard_name' => 'web']); + + $permissions = $request->input('permissions'); + + if (!empty($permissions)) { + $role = Role::find($role->id); + $role->syncPermissions($permissions); + } + + echo json_encode(['status' => 'success', 'message' => 'Role Created Successfully']); + } catch (\Exception $e) { + echo json_encode(['status' => 'error', 'message' => 'Role Created Failed']); + } + } + + return false; + } + + /** + * Display the specified resource. + * + * @param int $id + * + * @return \Illuminate\Http\Response + */ + public function show($id) + { + // + } + + /** + * Show the form for editing the specified resource. + * + * @param int $id + * + * @return \Illuminate\Http\Response + */ + public function edit($id) + { + /* if (is_null($this->user) || !$this->user->can('role.update')) { + abort(403, 'Sorry !! You are Unauthorized to edit any role !'); + }*/ + + $role = Role::findById($id, 'web'); + $permissions = Permission::all(); + $permissiongroups = PermissionGroup::all(); + + $_array = [ + 'role' => $role, + 'permissions' => $permissions, + 'permissiongroups' => $permissiongroups + ]; + setcookie('role', json_encode($role), time() + (86400 * 30), "/"); + setcookie('perissions', json_encode($permissions), time() + (86400 * 30), "/"); + + echo json_encode($_array); + } + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * + * @return \Illuminate\Http\Response + */ + public function update(Request $request, $id) + { + /* if (is_null($this->user) || !$this->user->can('role.update')) { + abort(403, 'Sorry !! You are Unauthorized to edit any role !'); + }*/ + + // Validation Data + $request->validate([ + 'name' => 'required|max:100|unique:roles,name,' . $id + ], [ + 'name.requried' => 'Please give a role name' + ]); + + $role = Role::findById($id, 'web'); + $permissions = $request->input('permissions'); + + $role->name = $request->name; + $role->save(); + + if (!empty($permissions)) { + $role->syncPermissions($permissions); + } + + session()->flash('success', 'Role has been updated !!'); + return redirect()->route('user.roles.index'); + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * + * @return \Illuminate\Http\Response + */ + public function destroy($id) + { + /*if (is_null($this->user) || !$this->user->can('role.delete')) { + abort(403, 'Sorry !! You are Unauthorized to delete any role !'); + }*/ + + + $role = Role::findById($id, 'web'); + if (!is_null($role)) { + $role->delete(); + } + + session()->flash('success', 'Role has been deleted !!'); + return redirect()->route('user.roles.index'); + } + } diff --git a/app/Http/Controllers/Users/UsersController.php b/app/Http/Controllers/Users/UsersController.php new file mode 100644 index 0000000..bae1593 --- /dev/null +++ b/app/Http/Controllers/Users/UsersController.php @@ -0,0 +1,211 @@ +middleware(function ($request, $next) { + $this->user = Auth::guard('web')->user(); + return $next($request); + }); + } + + /** + * Display a listing of the resource. + * + * @return \Illuminate\Http\Response + */ + + public function index(UsersDataTable $dataTable) + { + if (is_null($this->user) || !$this->user->can('user.read')) { + abort(403, 'Sorry !! You are Unauthorized to view any users !'); + } + + return $dataTable->render('pages.users.index'); + } + + /** + * Show the form for creating a new resource. + * + * @return \Illuminate\Http\Response + */ + public function create() + { + if (is_null($this->user) || !$this->user->can('user.create')) { + abort(403, 'Sorry !! You are Unauthorized to create any users !'); + } + + $roles = Role::all(); + return view('pages.users.create', compact('roles')); + } + + /** + * Store a newly created resource in storage. + * + * @param \Illuminate\Http\Request $request + * + * @return \Illuminate\Http\Response + */ + public function store(Request $request) + { + if (is_null($this->user) || !$this->user->can('user.create')) { + abort(403, 'Sorry !! You are Unauthorized to create any users !'); + } + // Validation Data + $request->validate([ + 'first_name' => 'required|max:50', + 'last_name' => 'max:50', + 'email' => 'required|max:100|email|unique:users', + 'password' => 'required|min:6|confirmed', + 'phone' => 'unique:user_infos|numeric' + ]); + + // Create New User + $user = new User(); + $user->first_name = $request->first_name; + $user->last_name = $request->last_name; + $user->email = $request->email; + $user->password = Hash::make($request->password); + + if($user->save()){ + $userInfo = new UserInfo(); + $userInfo->user_id = $user->id; + $userInfo->phone = $request->phone; + $userInfo->save(); + } + + if ($request->roles) { + $user->assignRole($request->roles); + } + + session()->flash('success', 'User has been created !!'); + return redirect()->route('users.index'); + } + + /** + * Display the specified resource. + * + * @param int $id + * + * @return \Illuminate\Http\Response + */ + public function show($id) + { + if (is_null($this->user) || !$this->user->can('user.read')) { + abort(403, 'Sorry !! You are Unauthorized to view any users !'); + } + } + + /** + * Show the form for editing the specified resource. + * + * @param int $id + * + * @return \Illuminate\Http\Response + */ + public function edit($id) + { + if (is_null($this->user) || !$this->user->can('user.update')) { + abort(403, 'Sorry !! You are Unauthorized to update any users !'); + } + + $user = User::with(['info'])->find($id); + $roles = Role::all(); + return view('pages.users.edit', compact('user', 'roles')); + } + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * + * @return \Illuminate\Http\Response + */ + public function update(Request $request, $id) + { + if (is_null($this->user) || !$this->user->can('user.update')) { + abort(403, 'Sorry !! You are Unauthorized to update any users !'); + } + + // Create New User + $user = User::find($id); + $userInfo = userInfo::where('user_id', $user->id)->first(); + + // Validation Data + if ($request->password !== '') { + $request->validate([ + 'first_name' => 'required|max:50', + 'last_name' => 'max:50', + 'email' => 'required|max:100|email|unique:users,email,' . $id, + 'password' => 'nullable|min:6|confirmed', + 'phone' => 'numeric|unique:user_infos,phone,'.$userInfo->id + ]); + } else { + $request->validate([ + 'first_name' => 'required|max:50', + 'last_name' => 'max:50', + 'email' => 'required|max:100|email|unique:users,email,' . $id, + 'phone' => 'numeric|unique:user_infos,phone,'.$userInfo->id + ]); + } + + $user->first_name = $request->first_name; + $user->last_name = $request->last_name; + $user->email = $request->email; + if ($request->password) { + $user->password = Hash::make($request->password); + } + if($user->save()){ + $userInfo->phone = $request->phone; + $userInfo->save(); + } + + $user->roles()->detach(); + if ($request->roles) { + $user->assignRole($request->roles); + } + + session()->flash('success', 'User has been updated !!'); + return redirect()->route('users.index'); + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * + * @return \Illuminate\Http\Response + */ + public function destroy($id) + { + if (is_null($this->user) || !$this->user->can('user.delete')) { + abort(403, 'Sorry !! You are Unauthorized to delete any users !'); + } + + $user = User::find($id); + $info = UserInfo::where(['user_id' => $user->id])->first(); + if (!is_null($user)) { + $user->delete(); + $info->delete(); + } + + session()->flash('success', 'User has been deleted !!'); + return redirect()->route('users.index'); + } + } diff --git a/app/Models/Directorat.php b/app/Models/Directorat.php index 85853fb..5f238bd 100644 --- a/app/Models/Directorat.php +++ b/app/Models/Directorat.php @@ -7,10 +7,11 @@ use Spatie\Activitylog\Traits\LogsActivity; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; +use Wildside\Userstamps\Userstamps; class Directorat extends Model { - use LogsActivity, HasFactory, SoftDeletes; + use LogsActivity, HasFactory, SoftDeletes, Userstamps; protected $fillable = [ 'kode', @@ -20,7 +21,7 @@ class Directorat extends Model public function getActivitylogOptions(): LogOptions { return LogOptions::defaults()->logAll() - ->useLogName('system'); + ->useLogName('master data'); } public function subDirectorat() diff --git a/app/Models/Permission.php b/app/Models/Permission.php new file mode 100644 index 0000000..02aed77 --- /dev/null +++ b/app/Models/Permission.php @@ -0,0 +1,23 @@ +logAll() + ->useLogName('master data'); + } + + public function group() + { + return $this->hasOne(PermissionGroup::class); + } +} diff --git a/app/Models/PermissionGroup.php b/app/Models/PermissionGroup.php new file mode 100644 index 0000000..d710e08 --- /dev/null +++ b/app/Models/PermissionGroup.php @@ -0,0 +1,55 @@ +logAll() + ->useLogName('master data'); + } + + public function permission(){ + return $this->hasMany(Permission::class); + } + + public function roles($group){ + $permission = Permission::where('permission_group_id', $group->id)->first(); + + $data = []; + + $roles = Role::all(); + + foreach($roles as $role){ + if($role->hasPermissionTo($permission->name)){ + array_push($data,$role); + } + } + + return $data; + } + + public static function getpermissionsByGroupId($id) + { + $permissions = DB::table('permissions') + ->select('name', 'id') + ->where('permission_group_id', $id) + ->get(); + return $permissions; + } + +} diff --git a/composer.json b/composer.json index 0d67670..fa85860 100644 --- a/composer.json +++ b/composer.json @@ -7,12 +7,15 @@ "require": { "php": "^8.0.2", "guzzlehttp/guzzle": "^7.2", + "jackiedo/log-reader": "2.*", "laracasts/flash": "^3.2", "laravel/framework": "^10.0", "laravel/sanctum": "^3.0", "laravel/tinker": "^2.7", "laravelcollective/html": "^6.4", "spatie/laravel-activitylog": "^4.7", + "spatie/laravel-permission": "^5.10", + "wildside/userstamps": "^2.3", "yajra/laravel-datatables": "^10.0", "yajra/laravel-datatables-oracle": "^10.3.1" }, diff --git a/composer.lock b/composer.lock index fd3a170..e8254d8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b9f7e562d6d509796b8064720f017880", + "content-hash": "9e90063b659e638d19ae81dade0a7fc4", "packages": [ { "name": "brick/math", @@ -1041,6 +1041,72 @@ ], "time": "2021-10-07T12:57:01+00:00" }, + { + "name": "jackiedo/log-reader", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/JackieDo/Laravel-Log-Reader.git", + "reference": "c5bfb0f361383089934cd4059d7a37b9c2640609" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/JackieDo/Laravel-Log-Reader/zipball/c5bfb0f361383089934cd4059d7a37b9c2640609", + "reference": "c5bfb0f361383089934cd4059d7a37b9c2640609", + "shasum": "" + }, + "require": { + "illuminate/cache": "^9.0|^8.0|^7.0|^6.0|5.*|^10.0", + "illuminate/config": "^9.0|^8.0|^7.0|^6.0|5.*|^10.0", + "illuminate/console": "^9.0|^8.0|^7.0|^6.0|5.*|^10.0", + "illuminate/http": "^9.0|^8.0|^7.0|^6.0|5.*|^10.0", + "illuminate/pagination": "^9.0|^8.0|^7.0|^6.0|5.*|^10.0", + "illuminate/support": "^9.0|^8.0|^7.0|^6.0|5.*|^10.0", + "nesbot/carbon": "^2.0|~1.20" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Jackiedo\\LogReader\\LogReaderServiceProvider" + ], + "aliases": { + "LogReader": "Jackiedo\\LogReader\\Facades\\LogReader" + } + } + }, + "autoload": { + "psr-4": { + "Jackiedo\\LogReader\\": "src/Jackiedo/LogReader" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jackie Do", + "email": "anhvudo@gmail.com" + } + ], + "description": "An easy log reader and management tool for Laravel", + "keywords": [ + "Viewer", + "laravel", + "log", + "log-manager", + "log-reader", + "log-viewer", + "logs", + "reader" + ], + "support": { + "issues": "https://github.com/JackieDo/Laravel-Log-Reader/issues", + "source": "https://github.com/JackieDo/Laravel-Log-Reader/tree/2.3.0" + }, + "time": "2023-02-18T21:01:57+00:00" + }, { "name": "laracasts/flash", "version": "3.2.2", @@ -3869,6 +3935,88 @@ ], "time": "2023-03-14T16:41:21+00:00" }, + { + "name": "spatie/laravel-permission", + "version": "5.10.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-permission.git", + "reference": "d08b3ffc5870cce4a47a39f22174947b33c191ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-permission/zipball/d08b3ffc5870cce4a47a39f22174947b33c191ae", + "reference": "d08b3ffc5870cce4a47a39f22174947b33c191ae", + "shasum": "" + }, + "require": { + "illuminate/auth": "^7.0|^8.0|^9.0|^10.0", + "illuminate/container": "^7.0|^8.0|^9.0|^10.0", + "illuminate/contracts": "^7.0|^8.0|^9.0|^10.0", + "illuminate/database": "^7.0|^8.0|^9.0|^10.0", + "php": "^7.3|^8.0" + }, + "require-dev": { + "orchestra/testbench": "^5.0|^6.0|^7.0|^8.0", + "phpunit/phpunit": "^9.4", + "predis/predis": "^1.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.x-dev", + "dev-master": "5.x-dev" + }, + "laravel": { + "providers": [ + "Spatie\\Permission\\PermissionServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\Permission\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Permission handling for Laravel 6.0 and up", + "homepage": "https://github.com/spatie/laravel-permission", + "keywords": [ + "acl", + "laravel", + "permission", + "permissions", + "rbac", + "roles", + "security", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-permission/issues", + "source": "https://github.com/spatie/laravel-permission/tree/5.10.1" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2023-04-12T17:08:32+00:00" + }, { "name": "symfony/console", "version": "v6.2.8", @@ -4099,16 +4247,16 @@ }, { "name": "symfony/error-handler", - "version": "v6.2.7", + "version": "v6.2.9", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "61e90f94eb014054000bc902257d2763fac09166" + "reference": "e95f1273b3953c3b5e5341172dae838bacee11ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/61e90f94eb014054000bc902257d2763fac09166", - "reference": "61e90f94eb014054000bc902257d2763fac09166", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/e95f1273b3953c3b5e5341172dae838bacee11ee", + "reference": "e95f1273b3953c3b5e5341172dae838bacee11ee", "shasum": "" }, "require": { @@ -4150,7 +4298,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v6.2.7" + "source": "https://github.com/symfony/error-handler/tree/v6.2.9" }, "funding": [ { @@ -4166,7 +4314,7 @@ "type": "tidelift" } ], - "time": "2023-02-14T08:44:56+00:00" + "time": "2023-04-11T16:03:19+00:00" }, { "name": "symfony/event-dispatcher", @@ -4474,16 +4622,16 @@ }, { "name": "symfony/http-kernel", - "version": "v6.2.8", + "version": "v6.2.9", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "9563229e56076070d92ca30c089e801e8a4629a3" + "reference": "02246510cf7031726f7237138d61b796b95799b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/9563229e56076070d92ca30c089e801e8a4629a3", - "reference": "9563229e56076070d92ca30c089e801e8a4629a3", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/02246510cf7031726f7237138d61b796b95799b3", + "reference": "02246510cf7031726f7237138d61b796b95799b3", "shasum": "" }, "require": { @@ -4565,7 +4713,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.2.8" + "source": "https://github.com/symfony/http-kernel/tree/v6.2.9" }, "funding": [ { @@ -4581,7 +4729,7 @@ "type": "tidelift" } ], - "time": "2023-03-31T12:00:10+00:00" + "time": "2023-04-13T16:41:43+00:00" }, { "name": "symfony/mailer", @@ -6333,6 +6481,61 @@ }, "time": "2022-06-03T18:03:27+00:00" }, + { + "name": "wildside/userstamps", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/WildsideUK/Laravel-Userstamps.git", + "reference": "371cfbf5fda1872cc487888c6a8ac01e3e8249aa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/WildsideUK/Laravel-Userstamps/zipball/371cfbf5fda1872cc487888c6a8ac01e3e8249aa", + "reference": "371cfbf5fda1872cc487888c6a8ac01e3e8249aa", + "shasum": "" + }, + "require": { + "illuminate/support": "^5.2|^6.0|^7.0|^8.0|^9.0|^10.0", + "php": ">=5.5.9" + }, + "require-dev": { + "illuminate/database": "^5.2|^6.0|^7.0|^8.0|^9.0|^10.0", + "orchestra/testbench": "^3.1|^4.0|^5.0|^6.0|^7.0|^8.0", + "phpunit/phpunit": "^5.0|^6.0|^7.0|^8.4|^9.0|^10.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Wildside\\Userstamps\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "WILDSIDE", + "email": "hello@wildside.uk", + "homepage": "https://wildside.uk" + } + ], + "description": "Laravel Userstamps provides an Eloquent trait which automatically maintains `created_by` and `updated_by` columns on your model, populated by the currently authenticated user in your application.", + "keywords": [ + "created_by", + "deleted_by", + "eloquent", + "laravel", + "updated_by", + "userstamps" + ], + "support": { + "issues": "https://github.com/WildsideUK/Laravel-Userstamps/issues", + "source": "https://github.com/WildsideUK/Laravel-Userstamps/tree/2.3.0" + }, + "time": "2023-02-15T09:35:24+00:00" + }, { "name": "yajra/laravel-datatables", "version": "v10.1.0", @@ -7362,40 +7565,40 @@ }, { "name": "nunomaduro/collision", - "version": "v7.4.0", + "version": "v7.5.0", "source": { "type": "git", "url": "https://github.com/nunomaduro/collision.git", - "reference": "42bab217d4913d6610f341d0468cec860aae165e" + "reference": "bbbc6fb9c1ee88f8aa38e47abd15c465f946f85e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/collision/zipball/42bab217d4913d6610f341d0468cec860aae165e", - "reference": "42bab217d4913d6610f341d0468cec860aae165e", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/bbbc6fb9c1ee88f8aa38e47abd15c465f946f85e", + "reference": "bbbc6fb9c1ee88f8aa38e47abd15c465f946f85e", "shasum": "" }, "require": { - "filp/whoops": "^2.15.1", + "filp/whoops": "^2.15.2", "nunomaduro/termwind": "^1.15.1", "php": "^8.1.0", - "symfony/console": "^6.2.7" + "symfony/console": "^6.2.8" }, "conflict": { - "phpunit/phpunit": "<10.0.17" + "phpunit/phpunit": "<10.1.0" }, "require-dev": { - "brianium/paratest": "^7.1.2", - "laravel/framework": "^10.5.1", - "laravel/pint": "^1.7.0", - "laravel/sail": "^1.21.3", + "brianium/paratest": "^7.1.3", + "laravel/framework": "^10.7.1", + "laravel/pint": "^1.8.0", + "laravel/sail": "^1.21.4", "laravel/sanctum": "^3.2.1", "laravel/tinker": "^2.8.1", "nunomaduro/larastan": "^2.5.1", - "orchestra/testbench-core": "^8.2.0", - "pestphp/pest": "^2.3.0", - "phpunit/phpunit": "^10.0.19", - "sebastian/environment": "^6.0.0", - "spatie/laravel-ignition": "^2.0.0" + "orchestra/testbench-core": "^8.4.2", + "pestphp/pest": "^2.5.0", + "phpunit/phpunit": "^10.1.0", + "sebastian/environment": "^6.0.1", + "spatie/laravel-ignition": "^2.1.0" }, "type": "library", "extra": { @@ -7454,7 +7657,7 @@ "type": "patreon" } ], - "time": "2023-03-31T08:17:12+00:00" + "time": "2023-04-14T10:39:16+00:00" }, { "name": "phar-io/manifest", @@ -7569,16 +7772,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "10.0.2", + "version": "10.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "20800e84296ea4732f9a125e08ce86b4004ae3e4" + "reference": "fc4f5ee614fa82d50ecf9014b51af0a9561f3df8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/20800e84296ea4732f9a125e08ce86b4004ae3e4", - "reference": "20800e84296ea4732f9a125e08ce86b4004ae3e4", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/fc4f5ee614fa82d50ecf9014b51af0a9561f3df8", + "reference": "fc4f5ee614fa82d50ecf9014b51af0a9561f3df8", "shasum": "" }, "require": { @@ -7606,7 +7809,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.0-dev" + "dev-main": "10.1-dev" } }, "autoload": { @@ -7634,7 +7837,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.0.2" + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.0" }, "funding": [ { @@ -7642,7 +7846,7 @@ "type": "github" } ], - "time": "2023-03-06T13:00:19+00:00" + "time": "2023-04-13T07:08:27+00:00" }, { "name": "phpunit/php-file-iterator", @@ -7887,16 +8091,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.0.19", + "version": "10.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "20c23e85c86e5c06d63538ba464e8054f4744e62" + "reference": "5a477aea03e61329132935689ae2d73f418f5e25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/20c23e85c86e5c06d63538ba464e8054f4744e62", - "reference": "20c23e85c86e5c06d63538ba464e8054f4744e62", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/5a477aea03e61329132935689ae2d73f418f5e25", + "reference": "5a477aea03e61329132935689ae2d73f418f5e25", "shasum": "" }, "require": { @@ -7910,7 +8114,7 @@ "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", "php": ">=8.1", - "phpunit/php-code-coverage": "^10.0", + "phpunit/php-code-coverage": "^10.1", "phpunit/php-file-iterator": "^4.0", "phpunit/php-invoker": "^4.0", "phpunit/php-text-template": "^3.0", @@ -7936,7 +8140,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.0-dev" + "dev-main": "10.1-dev" } }, "autoload": { @@ -7968,7 +8172,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.0.19" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.1.0" }, "funding": [ { @@ -7984,7 +8188,7 @@ "type": "tidelift" } ], - "time": "2023-03-27T11:46:33+00:00" + "time": "2023-04-14T05:15:09+00:00" }, { "name": "sebastian/cli-parser", diff --git a/config/app.php b/config/app.php index 78912cd..9d34f7a 100644 --- a/config/app.php +++ b/config/app.php @@ -196,6 +196,9 @@ return [ App\Providers\RouteServiceProvider::class, Yajra\DataTables\DataTablesServiceProvider::class, + Jackiedo\LogReader\LogReaderServiceProvider::class, + + Spatie\Permission\PermissionServiceProvider::class, ], @@ -212,6 +215,7 @@ return [ 'aliases' => Facade::defaultAliases()->merge([ // 'ExampleClass' => App\Example\ExampleClass::class, + 'LogReader' => Jackiedo\LogReader\Facades\LogReader::class, ])->toArray(), ]; diff --git a/config/log-reader.php b/config/log-reader.php new file mode 100644 index 0000000..b6694a6 --- /dev/null +++ b/config/log-reader.php @@ -0,0 +1,91 @@ + storage_path('logs'), + + /* + |-------------------------------------------------------------------------- + | Default log filename + |-------------------------------------------------------------------------- + | + | This is default log filename that you want read from + | automatically. In Laravel, normally this name is 'laravel.log'. + | This string is compatible with format string in sprintf() + | function in PHP, it's mean you can set '*.*' to read all log + | files + | + */ + + 'filename' => null, + + /* + |-------------------------------------------------------------------------- + | Environment's log to read + |-------------------------------------------------------------------------- + | + | This is information to limit reading logs entry on specify + | environment. Example: local, product... You can set null if want + | read from all environment + | + */ + + 'environment' => null, + + /* + |-------------------------------------------------------------------------- + | Level's log to read + |-------------------------------------------------------------------------- + | + | This array is information to limit reading logs entry from + | specify levels. Example: ['error', 'warning']. You can set null + | if want read from all levels. + | + */ + + 'level' => null, + + /* + |-------------------------------------------------------------------------- + | Default sort field + |-------------------------------------------------------------------------- + | + | This is default field to sort by when reading + | + */ + + 'order_by_field' => 'date', + + /* + |-------------------------------------------------------------------------- + | Default sort direction + |-------------------------------------------------------------------------- + | + | This is default direction to sort by when reading + | + */ + + 'order_by_direction' => 'asc', + + /* + |-------------------------------------------------------------------------- + | Default log parser + |-------------------------------------------------------------------------- + | + | This is the default class used to parse log entries. + | + | If this setting is not set, the 'Jackiedo\LogReader\LogParser' class will + | be used. + | + */ + + 'default_log_parser' => null, +]; diff --git a/config/permission.php b/config/permission.php new file mode 100644 index 0000000..5b6e184 --- /dev/null +++ b/config/permission.php @@ -0,0 +1,161 @@ + [ + + /* + * When using the "HasPermissions" trait from this package, we need to know which + * Eloquent model should be used to retrieve your permissions. Of course, it + * is often just the "Permission" model but you may use whatever you like. + * + * The model you want to use as a Permission model needs to implement the + * `Spatie\Permission\Contracts\Permission` contract. + */ + + 'permission' => Spatie\Permission\Models\Permission::class, + + /* + * When using the "HasRoles" trait from this package, we need to know which + * Eloquent model should be used to retrieve your roles. Of course, it + * is often just the "Role" model but you may use whatever you like. + * + * The model you want to use as a Role model needs to implement the + * `Spatie\Permission\Contracts\Role` contract. + */ + + 'role' => Spatie\Permission\Models\Role::class, + + ], + + 'table_names' => [ + + /* + * When using the "HasRoles" trait from this package, we need to know which + * table should be used to retrieve your roles. We have chosen a basic + * default value but you may easily change it to any table you like. + */ + + 'roles' => 'roles', + + /* + * When using the "HasPermissions" trait from this package, we need to know which + * table should be used to retrieve your permissions. We have chosen a basic + * default value but you may easily change it to any table you like. + */ + + 'permissions' => 'permissions', + + /* + * When using the "HasPermissions" trait from this package, we need to know which + * table should be used to retrieve your models permissions. We have chosen a + * basic default value but you may easily change it to any table you like. + */ + + 'model_has_permissions' => 'model_has_permissions', + + /* + * When using the "HasRoles" trait from this package, we need to know which + * table should be used to retrieve your models roles. We have chosen a + * basic default value but you may easily change it to any table you like. + */ + + 'model_has_roles' => 'model_has_roles', + + /* + * When using the "HasRoles" trait from this package, we need to know which + * table should be used to retrieve your roles permissions. We have chosen a + * basic default value but you may easily change it to any table you like. + */ + + 'role_has_permissions' => 'role_has_permissions', + ], + + 'column_names' => [ + /* + * Change this if you want to name the related pivots other than defaults + */ + 'role_pivot_key' => null, //default 'role_id', + 'permission_pivot_key' => null, //default 'permission_id', + + /* + * Change this if you want to name the related model primary key other than + * `model_id`. + * + * For example, this would be nice if your primary keys are all UUIDs. In + * that case, name this `model_uuid`. + */ + + 'model_morph_key' => 'model_id', + + /* + * Change this if you want to use the teams feature and your related model's + * foreign key is other than `team_id`. + */ + + 'team_foreign_key' => 'team_id', + ], + + /* + * When set to true, the method for checking permissions will be registered on the gate. + * Set this to false, if you want to implement custom logic for checking permissions. + */ + + 'register_permission_check_method' => true, + + /* + * When set to true the package implements teams using the 'team_foreign_key'. If you want + * the migrations to register the 'team_foreign_key', you must set this to true + * before doing the migration. If you already did the migration then you must make a new + * migration to also add 'team_foreign_key' to 'roles', 'model_has_roles', and + * 'model_has_permissions'(view the latest version of package's migration file) + */ + + 'teams' => false, + + /* + * When set to true, the required permission names are added to the exception + * message. This could be considered an information leak in some contexts, so + * the default setting is false here for optimum safety. + */ + + 'display_permission_in_exception' => false, + + /* + * When set to true, the required role names are added to the exception + * message. This could be considered an information leak in some contexts, so + * the default setting is false here for optimum safety. + */ + + 'display_role_in_exception' => false, + + /* + * By default wildcard permission lookups are disabled. + */ + + 'enable_wildcard_permission' => false, + + 'cache' => [ + + /* + * By default all permissions are cached for 24 hours to speed up performance. + * When permissions or roles are updated the cache is flushed automatically. + */ + + 'expiration_time' => \DateInterval::createFromDateString('24 hours'), + + /* + * The cache key used to store all permissions. + */ + + 'key' => 'spatie.permission.cache', + + /* + * You may optionally indicate a specific cache driver to use for permission and + * role caching using any of the `store` drivers listed in the cache.php config + * file. Using 'default' here means to use the `default` set in cache.php. + */ + + 'store' => 'default', + ], +]; diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php index cf6b776..d51e598 100644 --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -21,6 +21,11 @@ return new class extends Migration $table->string('password'); $table->rememberToken(); $table->timestamps(); + $table->softDeletes(); + + $table->unsignedBigInteger('created_by')->nullable(); + $table->unsignedBigInteger('updated_by')->nullable(); + $table->unsignedBigInteger('deleted_by')->nullable(); }); } diff --git a/database/migrations/2014_10_12_100000_create_password_resets_table.php b/database/migrations/2014_10_12_100000_create_password_resets_table.php index fcacb80..3d3536e 100644 --- a/database/migrations/2014_10_12_100000_create_password_resets_table.php +++ b/database/migrations/2014_10_12_100000_create_password_resets_table.php @@ -17,6 +17,11 @@ return new class extends Migration $table->string('email')->index(); $table->string('token'); $table->timestamp('created_at')->nullable(); + $table->softDeletes(); + + $table->unsignedBigInteger('created_by')->nullable(); + $table->unsignedBigInteger('updated_by')->nullable(); + $table->unsignedBigInteger('deleted_by')->nullable(); }); } diff --git a/database/migrations/2019_08_19_000000_create_failed_jobs_table.php b/database/migrations/2019_08_19_000000_create_failed_jobs_table.php index 1719198..579b7f6 100644 --- a/database/migrations/2019_08_19_000000_create_failed_jobs_table.php +++ b/database/migrations/2019_08_19_000000_create_failed_jobs_table.php @@ -21,6 +21,11 @@ return new class extends Migration $table->longText('payload'); $table->longText('exception'); $table->timestamp('failed_at')->useCurrent(); + $table->softDeletes(); + + $table->unsignedBigInteger('created_by')->nullable(); + $table->unsignedBigInteger('updated_by')->nullable(); + $table->unsignedBigInteger('deleted_by')->nullable(); }); } diff --git a/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php b/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php index 6c81fd2..b1259f9 100644 --- a/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php +++ b/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php @@ -22,6 +22,11 @@ return new class extends Migration $table->timestamp('last_used_at')->nullable(); $table->timestamp('expires_at')->nullable(); $table->timestamps(); + $table->softDeletes(); + + $table->unsignedBigInteger('created_by')->nullable(); + $table->unsignedBigInteger('updated_by')->nullable(); + $table->unsignedBigInteger('deleted_by')->nullable(); }); } diff --git a/database/migrations/2023_04_10_024720_create_directorats_table.php b/database/migrations/2023_04_10_024720_create_directorats_table.php index 98b7b8e..b13f980 100644 --- a/database/migrations/2023_04_10_024720_create_directorats_table.php +++ b/database/migrations/2023_04_10_024720_create_directorats_table.php @@ -17,6 +17,10 @@ return new class extends Migration $table->string('name',50); $table->timestamps(); $table->softDeletes(); + + $table->unsignedBigInteger('created_by')->nullable(); + $table->unsignedBigInteger('updated_by')->nullable(); + $table->unsignedBigInteger('deleted_by')->nullable(); }); } diff --git a/database/migrations/2023_04_10_024731_create_sub_directorats_table.php b/database/migrations/2023_04_10_024731_create_sub_directorats_table.php index 93946c3..85b84a0 100644 --- a/database/migrations/2023_04_10_024731_create_sub_directorats_table.php +++ b/database/migrations/2023_04_10_024731_create_sub_directorats_table.php @@ -18,6 +18,10 @@ return new class extends Migration $table->string('name',50); $table->timestamps(); $table->softDeletes(); + + $table->unsignedBigInteger('created_by')->nullable(); + $table->unsignedBigInteger('updated_by')->nullable(); + $table->unsignedBigInteger('deleted_by')->nullable(); }); } diff --git a/database/migrations/2023_04_10_024809_create_jobs_table.php b/database/migrations/2023_04_10_024809_create_jobs_table.php index 058edfa..2ab00aa 100644 --- a/database/migrations/2023_04_10_024809_create_jobs_table.php +++ b/database/migrations/2023_04_10_024809_create_jobs_table.php @@ -19,6 +19,10 @@ return new class extends Migration $table->string('name',50); $table->timestamps(); $table->softDeletes(); + + $table->unsignedBigInteger('created_by')->nullable(); + $table->unsignedBigInteger('updated_by')->nullable(); + $table->unsignedBigInteger('deleted_by')->nullable(); }); } diff --git a/database/migrations/2023_04_10_024820_create_sub_jobs_table.php b/database/migrations/2023_04_10_024820_create_sub_jobs_table.php index 9d29c0e..5fef9ca 100644 --- a/database/migrations/2023_04_10_024820_create_sub_jobs_table.php +++ b/database/migrations/2023_04_10_024820_create_sub_jobs_table.php @@ -20,6 +20,10 @@ return new class extends Migration $table->string('name',50); $table->timestamps(); $table->softDeletes(); + + $table->unsignedBigInteger('created_by')->nullable(); + $table->unsignedBigInteger('updated_by')->nullable(); + $table->unsignedBigInteger('deleted_by')->nullable(); }); } diff --git a/database/migrations/2023_04_11_043320_create_activity_log_table.php b/database/migrations/2023_04_11_043320_create_activity_log_table.php index 7c05bc8..cab9761 100644 --- a/database/migrations/2023_04_11_043320_create_activity_log_table.php +++ b/database/migrations/2023_04_11_043320_create_activity_log_table.php @@ -17,6 +17,10 @@ class CreateActivityLogTable extends Migration $table->json('properties')->nullable(); $table->timestamps(); $table->index('log_name'); + + $table->unsignedBigInteger('created_by')->nullable(); + $table->unsignedBigInteger('updated_by')->nullable(); + $table->unsignedBigInteger('deleted_by')->nullable(); }); } diff --git a/database/migrations/2023_04_14_034926_create_sub_sub_jobs_table.php b/database/migrations/2023_04_14_034926_create_sub_sub_jobs_table.php index e56bf68..6a0ff14 100644 --- a/database/migrations/2023_04_14_034926_create_sub_sub_jobs_table.php +++ b/database/migrations/2023_04_14_034926_create_sub_sub_jobs_table.php @@ -21,6 +21,10 @@ return new class extends Migration $table->string('name'); $table->timestamps(); $table->softDeletes(); + + $table->unsignedBigInteger('created_by')->nullable(); + $table->unsignedBigInteger('updated_by')->nullable(); + $table->unsignedBigInteger('deleted_by')->nullable(); }); } diff --git a/database/migrations/2023_04_15_221620_create_permission_tables.php b/database/migrations/2023_04_15_221620_create_permission_tables.php new file mode 100644 index 0000000..04c3278 --- /dev/null +++ b/database/migrations/2023_04_15_221620_create_permission_tables.php @@ -0,0 +1,141 @@ +bigIncrements('id'); // permission id + $table->string('name'); // For MySQL 8.0 use string('name', 125); + $table->string('guard_name'); // For MySQL 8.0 use string('guard_name', 125); + $table->timestamps(); + + $table->unique(['name', 'guard_name']); + }); + + Schema::create($tableNames['roles'], function (Blueprint $table) use ($teams, $columnNames) { + $table->bigIncrements('id'); // role id + if ($teams || config('permission.testing')) { // permission.testing is a fix for sqlite testing + $table->unsignedBigInteger($columnNames['team_foreign_key'])->nullable(); + $table->index($columnNames['team_foreign_key'], 'roles_team_foreign_key_index'); + } + $table->string('name'); // For MySQL 8.0 use string('name', 125); + $table->string('guard_name'); // For MySQL 8.0 use string('guard_name', 125); + $table->timestamps(); + if ($teams || config('permission.testing')) { + $table->unique([$columnNames['team_foreign_key'], 'name', 'guard_name']); + } else { + $table->unique(['name', 'guard_name']); + } + }); + + Schema::create($tableNames['model_has_permissions'], function (Blueprint $table) use ($tableNames, $columnNames, $teams) { + $table->unsignedBigInteger(PermissionRegistrar::$pivotPermission); + + $table->string('model_type'); + $table->unsignedBigInteger($columnNames['model_morph_key']); + $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_model_id_model_type_index'); + + $table->foreign(PermissionRegistrar::$pivotPermission) + ->references('id') // permission id + ->on($tableNames['permissions']) + ->onDelete('cascade'); + if ($teams) { + $table->unsignedBigInteger($columnNames['team_foreign_key']); + $table->index($columnNames['team_foreign_key'], 'model_has_permissions_team_foreign_key_index'); + + $table->primary([$columnNames['team_foreign_key'], PermissionRegistrar::$pivotPermission, $columnNames['model_morph_key'], 'model_type'], + 'model_has_permissions_permission_model_type_primary'); + } else { + $table->primary([PermissionRegistrar::$pivotPermission, $columnNames['model_morph_key'], 'model_type'], + 'model_has_permissions_permission_model_type_primary'); + } + + }); + + Schema::create($tableNames['model_has_roles'], function (Blueprint $table) use ($tableNames, $columnNames, $teams) { + $table->unsignedBigInteger(PermissionRegistrar::$pivotRole); + + $table->string('model_type'); + $table->unsignedBigInteger($columnNames['model_morph_key']); + $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_roles_model_id_model_type_index'); + + $table->foreign(PermissionRegistrar::$pivotRole) + ->references('id') // role id + ->on($tableNames['roles']) + ->onDelete('cascade'); + if ($teams) { + $table->unsignedBigInteger($columnNames['team_foreign_key']); + $table->index($columnNames['team_foreign_key'], 'model_has_roles_team_foreign_key_index'); + + $table->primary([$columnNames['team_foreign_key'], PermissionRegistrar::$pivotRole, $columnNames['model_morph_key'], 'model_type'], + 'model_has_roles_role_model_type_primary'); + } else { + $table->primary([PermissionRegistrar::$pivotRole, $columnNames['model_morph_key'], 'model_type'], + 'model_has_roles_role_model_type_primary'); + } + }); + + Schema::create($tableNames['role_has_permissions'], function (Blueprint $table) use ($tableNames) { + $table->unsignedBigInteger(PermissionRegistrar::$pivotPermission); + $table->unsignedBigInteger(PermissionRegistrar::$pivotRole); + + $table->foreign(PermissionRegistrar::$pivotPermission) + ->references('id') // permission id + ->on($tableNames['permissions']) + ->onDelete('cascade'); + + $table->foreign(PermissionRegistrar::$pivotRole) + ->references('id') // role id + ->on($tableNames['roles']) + ->onDelete('cascade'); + + $table->primary([PermissionRegistrar::$pivotPermission, PermissionRegistrar::$pivotRole], 'role_has_permissions_permission_id_role_id_primary'); + }); + + app('cache') + ->store(config('permission.cache.store') != 'default' ? config('permission.cache.store') : null) + ->forget(config('permission.cache.key')); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + $tableNames = config('permission.table_names'); + + if (empty($tableNames)) { + throw new \Exception('Error: config/permission.php not found and defaults could not be merged. Please publish the package configuration before proceeding, or drop the tables manually.'); + } + + Schema::drop($tableNames['role_has_permissions']); + Schema::drop($tableNames['model_has_roles']); + Schema::drop($tableNames['model_has_permissions']); + Schema::drop($tableNames['roles']); + Schema::drop($tableNames['permissions']); + } +} diff --git a/database/migrations/2023_04_15_225705_create_permission_groups_table.php b/database/migrations/2023_04_15_225705_create_permission_groups_table.php new file mode 100644 index 0000000..7842625 --- /dev/null +++ b/database/migrations/2023_04_15_225705_create_permission_groups_table.php @@ -0,0 +1,38 @@ +id(); + $table->string('name'); + $table->timestamps(); + $table->softDeletes(); + + $table->unsignedBigInteger('created_by')->nullable(); + $table->unsignedBigInteger('updated_by')->nullable(); + $table->unsignedBigInteger('deleted_by')->nullable(); + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('permission_groups'); + } + }; diff --git a/database/migrations/2023_04_15_225909_update_permissions_table.php b/database/migrations/2023_04_15_225909_update_permissions_table.php new file mode 100644 index 0000000..7aad149 --- /dev/null +++ b/database/migrations/2023_04_15_225909_update_permissions_table.php @@ -0,0 +1,28 @@ +foreignIdFor(PermissionGroup::class); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropForeignKey('permission_group_id'); + Schema::dropColumn('permission_group_id'); + } +}; diff --git a/database/seeders/LabelSeeder.php b/database/seeders/LabelSeeder.php index 14eb384..c6d3fc2 100644 --- a/database/seeders/LabelSeeder.php +++ b/database/seeders/LabelSeeder.php @@ -6,6 +6,7 @@ use App\Models\Directorat; use App\Models\Job; use App\Models\SubDirectorat; use App\Models\SubJob; +use App\Models\SubSubJob; use Faker\Generator; use Illuminate\Database\Seeder; diff --git a/resources/views/layout/partials/sidebar-layout/_page-title.blade.php b/resources/views/layout/partials/sidebar-layout/_page-title.blade.php index 48f3974..b297ada 100644 --- a/resources/views/layout/partials/sidebar-layout/_page-title.blade.php +++ b/resources/views/layout/partials/sidebar-layout/_page-title.blade.php @@ -5,13 +5,20 @@ @endphp -

{{ ucfirst(str_replace('-',' ',$route[0])) }}

+

+ @if(count($route) > 1) + @if($route[1] !== 'index') + {{ $route[1] }} + @endif + @endif + {{ ucfirst(str_replace('-',' ',$route[0])) }} +

diff --git a/resources/views/layout/partials/sidebar-layout/_toolbar.blade.php b/resources/views/layout/partials/sidebar-layout/_toolbar.blade.php index 4dff460..3c72fbe 100644 --- a/resources/views/layout/partials/sidebar-layout/_toolbar.blade.php +++ b/resources/views/layout/partials/sidebar-layout/_toolbar.blade.php @@ -15,6 +15,14 @@ + @elseif(isset($route[2]) && $route[2] == 'index' && $route[0] == 'user') + +
+ + Add {{ str_replace('-',' ',$route[1]) }} {{ str_replace('-',' ',$route[0]) }} + +
+ @endif diff --git a/resources/views/layout/partials/sidebar-layout/sidebar/_menu.blade.php b/resources/views/layout/partials/sidebar-layout/sidebar/_menu.blade.php index 9e059ea..1a63660 100644 --- a/resources/views/layout/partials/sidebar-layout/sidebar/_menu.blade.php +++ b/resources/views/layout/partials/sidebar-layout/sidebar/_menu.blade.php @@ -141,7 +141,7 @@ -