Membuat Pendaftaran Siswa Baru (PSB) dengan Laravel (Bagian Ketiga)
Pada tutorial PSB Bagian Ketiga ini, kita akan mempelajari bagaimana mengkustomisasi Auth Register dan mengimplementasikan login dengan multiuser atau login multilevel.
Kustomisasi Auth Register
Form Register bawaan laravel hanya ada empat kolom isian, sementara data isian yang diperlukan untuk PSB Online lebih dari itu, sesuai dengan kolom tabel yang ada di table users dan biodata. Oleh karena itu diperlukan penambahan kolom (field) pada form register.
Untuk kustomisasi Auth Register agar sesuai dengan kebutuhan PSB Online, kita akan mengedit tiga file, yaitu:
- Merubah nama menu Register menjadi menu Pendaftaran pada file
app.blade.php
- Mengedit file
registerController.php
- Mengedit file blade
register.blade.php
Editapp.blade.php
Edit file app.blade.php
yang terletak pada folder resource->views->layouts
dan ubah kata Register menjadi Pendaftaran pada kode baris ke-48.
Kode awal
<li class="nav-item"> <a class="nav-link" href="{{ route('register') }}">{{ __('Register') }}</a> </li>
Menjadi
<li class="nav-item"> <a class="nav-link" href="{{ route('register') }}">{{ __('Pendaftaran') }}</a> </li>
EditregisterController.php
File registerController.php
terletak pada folder app->Http->Controllers->Auth
<?php namespace App\Http\Controllers\Auth; use App\User; use App\Http\Controllers\Controller; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Validator; use Illuminate\Foundation\Auth\RegistersUsers; class RegisterController extends Controller { /* |-------------------------------------------------------------------------- | Register Controller |-------------------------------------------------------------------------- | | This controller handles the registration of new users as well as their | validation and creation. By default this controller uses a trait to | provide this functionality without requiring any additional code. | */ use RegistersUsers; /** * Where to redirect users after registration. * * @var string */ protected $redirectTo = '/home'; /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware('guest'); } /** * Get a validator for an incoming registration request. * * @param array $data * @return \Illuminate\Contracts\Validation\Validator */ protected function validator(array $data) { return Validator::make($data, [ 'name' => ['required', 'string', 'max:255'], 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'], 'password' => ['required', 'string', 'min:6', 'confirmed'], ]); } /** * Create a new user instance after a valid registration. * * @param array $data * @return \App\User */ protected function create(array $data) { return User::create([ 'name' => $data['name'], 'email' => $data['email'], 'password' => Hash::make($data['password']), ]); } }
Silakan ubah kode di atas menjadi seperti kode di bawah ini
<?php namespace App\Http\Controllers\Auth; use App\User; use App\Biodata; use App\Http\Controllers\Controller; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Validator; use Illuminate\Foundation\Auth\RegistersUsers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Input; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\File; class RegisterController extends Controller { /* |-------------------------------------------------------------------------- | Register Controller |-------------------------------------------------------------------------- | | This controller handles the registration of new users as well as their | validation and creation. By default this controller uses a trait to | provide this functionality without requiring any additional code. | */ use RegistersUsers; /** * Where to redirect users after registration. * * @var string */ protected $redirectTo = '/home'; /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware('guest'); } /** * Show the application registration form. * * @return \Illuminate\Http\Response */ public function showRegistrationForm() { $biodata = Biodata::all(); return view('auth.register', compact('biodata')); } /** * Handle a registration request for the application. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function register(Request $request) { $validator = Validator::make($request->all(), [ 'email' => 'required|string|email|max:255|unique:users', 'password' => 'required|string|min:6|confirmed', 'nama' => 'required|string|max:255', 'nis' => 'required|string|max:45', 'tempat_lahir' => 'required|string|max:45', 'tanggal_lahir' => 'required', 'nem' => 'required|string|max:45', 'no_ijazah' => 'required|string|max:45', 'nama_ortu' => 'required|string|max:100', 'pekerjaan_ortu' => 'required|string|max:100', 'telp' => 'required|string|max:45', 'alamat' => 'required', ], $messages = [ 'email.required' => 'E-Mail tidak boleh kosong !', 'password.required' => 'Password tidak boleh kosong', 'nama.required' => 'Nama tidak boleh kosong!', 'nis.required' => 'Nama tidak boleh kosong!', 'tempat_lahir.required' => 'Nama tidak boleh kosong!', 'tanggal_lahir.required' => 'Nama tidak boleh kosong!', 'nem.required' => 'Nama tidak boleh kosong!', 'no_ijazah.required' => 'Nama tidak boleh kosong!', 'nama_ortu.required' => 'Nama tidak boleh kosong!', 'pekerjaan_ortu.required' => 'Nama tidak boleh kosong!', 'telp.required' => 'Nama tidak boleh kosong!', 'alamat.required' => 'Nama tidak boleh kosong!', ]); if($validator->fails()) { return back()->withErrors($validator)->withInput(); } //Table Users $user = new User; $user->email = Input::get('email'); $user->password = Hash::make(Input::get('password')); $user->level = 1; $user->save(); //Table Biodata $user_id = $user->id; $biodata = new Biodata; $biodata->user_id = $user_id; $biodata->nama = Input::get('nama'); $biodata->nis = Input::get('nis'); $biodata->tempat_lahir = Input::get('tempat_lahir'); $biodata->tanggal_lahir = Input::get('tanggal_lahir'); $biodata->nem = Input::get('nem'); $biodata->no_ijazah = Input::get('no_ijazah'); $biodata->nama_ortu = Input::get('nama_ortu'); $biodata->pekerjaan_ortu = Input::get('pekerjaan_ortu'); $biodata->telp = Input::get('telp'); $biodata->alamat = Input::get('alamat'); $biodata->save(); return redirect()->back()->with('success', 'Registrasi Anda telah berhasil!. Silakan login dengan menggunakan email dan password Anda.'); } }
Editregister.blade.php
File register.blade.php
terletak pada folder resources->views->auth
. Silakan edit dan sesuaikan seperti kode berikut:
@extends('layouts.app') @section('content') <div class="container"> <div class="row justify-content-center"> <div class="col-md-9"> <div class="card"> <div class="card-header">{{ __('Form Pedaftaran PSB') }}</div> <div class="card-body"> @if(session()->has('success')) <div class="alert alert-success">{{ session()->get('success') }}</div> @endif <form method="POST" action="{{ route('register') }}"> @csrf <div class="form-group row"> <label for="nama" class="col-md-4 col-form-label text-md-right">{{ __('Nama Lengkap') }}</label> <div class="col-md-6"> <input id="nama" type="text" class="form-control{{ $errors->has('nama') ? ' is-invalid' : '' }}" name="nama" value="{{ old('nama') }}" required autofocus> @if ($errors->has('nama')) <span class="invalid-feedback" role="alert"> <strong>{{ $errors->first('nama') }}</strong> </span> @endif </div> </div> <div class="form-group row"> <label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label> <div class="col-md-6"> <input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required> @if ($errors->has('email')) <span class="invalid-feedback" role="alert"> <strong>{{ $errors->first('email') }}</strong> </span> @endif </div> </div> <div class="form-group row"> <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label> <div class="col-md-5"> <input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required> @if ($errors->has('password')) <span class="invalid-feedback" role="alert"> <strong>{{ $errors->first('password') }}</strong> </span> @endif </div> </div> <div class="form-group row"> <label for="password-confirm" class="col-md-4 col-form-label text-md-right">{{ __('Confirm Password') }}</label> <div class="col-md-5"> <input id="password-confirm" type="password" class="form-control" name="password_confirmation" required> </div> </div> <div class="form-group row"> <label for="nis" class="col-md-4 col-form-label text-md-right">{{ __('NIS') }}</label> <div class="col-md-4"> <input id="nis" type="text" class="form-control{{ $errors->has('nis') ? ' is-invalid' : '' }}" name="nis" value="{{ old('nis') }}" required autofocus> @if ($errors->has('nis')) <span class="invalid-feedback" role="alert"> <strong>{{ $errors->first('nis') }}</strong> </span> @endif </div> </div> <div class="form-group row"> <label for="tempat_lahir" class="col-md-4 col-form-label text-md-right">{{ __('Tempat Lahir') }}</label> <div class="col-md-5"> <input id="tempat_lahir" type="text" class="form-control{{ $errors->has('tempat_lahir') ? ' is-invalid' : '' }}" name="tempat_lahir" value="{{ old('tempat_lahir') }}" required autofocus> @if ($errors->has('tempat_lahir')) <span class="invalid-feedback" role="alert"> <strong>{{ $errors->first('tempat_lahir') }}</strong> </span> @endif </div> </div> <div class="form-group row"> <label for="tanggal_lahir" class="col-md-4 col-form-label text-md-right">{{ __('Tanggal Lahir') }}</label> <div class="col-md-4"> <input id="tanggal_lahir" type="text" class="form-control{{ $errors->has('tanggal_lahir') ? ' is-invalid' : '' }}" name="tanggal_lahir" value="{{ old('tanggal_lahir') }}" required autofocus> <small id="passwordHelpBlock" class="form-text text-danger"> Format: YYYY-MM-DD, contoh 1990-11-29. </small> @if ($errors->has('tanggal_lahir')) <span class="invalid-feedback" role="alert"> <strong>{{ $errors->first('tanggal_lahir') }}</strong> </span> @endif </div> </div> <div class="form-group row"> <label for="nem" class="col-md-4 col-form-label text-md-right">{{ __('NEM') }}</label> <div class="col-md-4"> <input id="nem" type="text" class="form-control{{ $errors->has('nem') ? ' is-invalid' : '' }}" name="nem" value="{{ old('nem') }}" required autofocus> @if ($errors->has('nem')) <span class="invalid-feedback" role="alert"> <strong>{{ $errors->first('nem') }}</strong> </span> @endif </div> </div> <div class="form-group row"> <label for="no_ijazah" class="col-md-4 col-form-label text-md-right">{{ __('Nomor Ijazah') }}</label> <div class="col-md-4"> <input id="no_ijazah" type="text" class="form-control{{ $errors->has('no_ijazah') ? ' is-invalid' : '' }}" name="no_ijazah" value="{{ old('no_ijazah') }}" required autofocus> @if ($errors->has('no_ijazah')) <span class="invalid-feedback" role="alert"> <strong>{{ $errors->first('no_ijazah') }}</strong> </span> @endif </div> </div> <div class="form-group row"> <label for="nama_ortu" class="col-md-4 col-form-label text-md-right">{{ __('Nama Orang Tua') }}</label> <div class="col-md-6"> <input id="nama_ortu" type="text" class="form-control{{ $errors->has('nama_ortu') ? ' is-invalid' : '' }}" name="nama_ortu" value="{{ old('nama_ortu') }}" required autofocus> @if ($errors->has('nama_ortu')) <span class="invalid-feedback" role="alert"> <strong>{{ $errors->first('nama_ortu') }}</strong> </span> @endif </div> </div> <div class="form-group row"> <label for="pekerjaan_ortu" class="col-md-4 col-form-label text-md-right">{{ __('Pekerjaan Orang Tua') }}</label> <div class="col-md-6"> <input id="pekerjaan_ortu" type="text" class="form-control{{ $errors->has('pekerjaan_ortu') ? ' is-invalid' : '' }}" name="pekerjaan_ortu" value="{{ old('pekerjaan_ortu') }}" required autofocus> @if ($errors->has('pekerjaan_ortu')) <span class="invalid-feedback" role="alert"> <strong>{{ $errors->first('pekerjaan_ortu') }}</strong> </span> @endif </div> </div> <div class="form-group row"> <label for="telp" class="col-md-4 col-form-label text-md-right">{{ __('Telp/Handphone') }}</label> <div class="col-md-4"> <input id="telp" type="text" class="form-control{{ $errors->has('telp') ? ' is-invalid' : '' }}" name="telp" value="{{ old('telp') }}" required autofocus> @if ($errors->has('telp')) <span class="invalid-feedback" role="alert"> <strong>{{ $errors->first('telp') }}</strong> </span> @endif </div> </div> <div class="form-group row"> <label for="alamat" class="col-md-4 col-form-label text-md-right">{{ __('Alamat Lengkap') }}</label> <div class="col-md-6"> <textarea id="alamat" type="text" class="form-control{{ $errors->has('alamat') ? ' is-invalid' : '' }}" name="alamat" value="{{ old('alamat') }}" rows="3"></textarea> @if ($errors->has('alamat')) <span class="invalid-feedback" role="alert"> <strong>{{ $errors->first('alamat') }}</strong> </span> @endif </div> </div> <div class="form-group row mb-0"> <div class="col-md-6 offset-md-4"> <button type="submit" class="btn btn-primary"> {{ __('Daftar') }} </button> </div> </div> </form> </div> </div> </div> </div> </div> @endsection
Output form pendaftaran akan tampak seperti gambar di bawah ini:
Sekarang tiba saatnya untuk mengecek apakah modifikasi di atas berhasil. Lakukan test pendaftaran, jika berhasil akan ada notifikasi dalam bentuk flash, bahwa pendafaran sukse dan data tersimpan ke dalam database.
Login Multiuser
Saat ini ketika admin ataupun pendaftar (calon siswa) berhasil login akan diarahkan pada dashboard yang sama, yaitu pada home.blade.php. Tentu kondisi ini kurang efektif dan fleksibel, mengingat hak akses kedua tipe user sangat berbeda. Admin mempunyai hak akses yang jauh lebih banyak dibanding pendaftar. Solusinya adalah membuat login multiuser, di mana ketika yang login dengan level 0 berarti level admin (super user), sebaliknya user yang levelnya bernilai 1 adalah user dengan level user biasa (calon siswa).
Membuat login multiuser sesuai hak akses, ada 3 langkah yang harus dilakukan, yaitu:
- Membuat Custom Helper.
- Membuat Middleware CheckPermission.
- Modifikasi Routing, Controller dan Blade View.
1. Membuat Custom Helper
Custom Helpers bertujuan untuk mengecek level user sesuai role atau hak akses. File helpers.php yang akan kita buat diletakan pada folder app/Http/helpsers.php
. Silakan buat file tersebut dan isi dengan kode berikut:
<?php function checkPermission($permissions){ $userAccess = getMyPermission(auth()->user()->level); foreach ($permissions as $key => $value) { if($value == $userAccess){ return true; } } return false; } function getMyPermission($id) { switch ($id) { case 0: return 'admin'; break; case 1: return 'pendaftar'; break; default: return 'user'; break; } } ?>
Selanjutnya, file helpers tersebut harus didaftarkan pada file composer.json
yaitu pada blok kode “autoload” antara baris kode “psr-4” dan “classmap”, seperti kode di bawah ini.
composer.json
"autoload": { "psr-4": { "App\\": "app/" }, "files": [ "app/Http/helpers.php" ], "classmap": [ "database/seeds", "database/factories" ] },
Kemudian, agar file helpers dapat diload, jalankan kode berikut:
composer dump-autoload
Sekarang fungsi checkPermission() dapat digunakan di mana saja pada aplikasi PSB Online.
2. Membuat Middleware CheckPermission
Kustom middleware yang akan kita buat bertujuan mengecek level user sesuai dengan hak akses, di mana level=0 mempunyai role admin dan level=1 sebagai pendaftar atau user biasa. Silakan buat kustom middleware dengan perintah berikut:
php artisan make:middleware CheckPermission
Perintah di atas akan membuat file middleware yang disimpan pada folder app/Http/Middleware/CheckPermission.php
. Silakan edit dan sesuaikan seperti kode berikut:
app/Http/Middleware/CheckPermission.php
<?php namespace App\Http\Middleware; use Closure; class CheckPermission { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next, $permission) { $permission = explode('|', $permission); if(checkPermission($permission)){ return $next($request); } return response()->view('errors.check-permission'); } }
Langkah terakhir dalam membuat middleware di atas, kita harus mendaftarkan file CheckPermission.php
ke dalam file Kernel.php
. Buka file Kernel.php
dan tambahkan kode
'check-permission' => \App\Http\Middleware\CheckPermission::class,
pada bagian akhir blok kode protected $routeMiddleware
, sehingga hasil akhirnya seperti di bawah ini:
app/Http/Kernel.php
..... protected $routeMiddleware = [ 'auth' => \App\Http\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, 'can' => \Illuminate\Auth\Middleware\Authorize::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, 'check-permission' => \App\Http\Middleware\CheckPermission::class, ]; .....
3. Modifikasi Routing, Controller dan Blade View
Pada tahap ini, kita akan menambahkan daftar route dengan membagi 2 tipe routing, yaitu untuk routing Admin dan routing pendaftar. Edit dan sesuaikan file web.php
seperti baris kode berikut:
routes/web.php
<?php /* |-------------------------------------------------------------------------- | Web Routes |-------------------------------------------------------------------------- | | Here is where you can register web routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | contains the "web" middleware group. Now create something great! | */ Route::get('/', function () { return view('welcome'); }); Auth::routes(); Route::get('/home', 'HomeController@index')->name('home'); // ROUTES ADMIN Route::group(['middleware' => 'check-permission:admin'], function () { Route::group(['prefix' => 'admin'], function () { Route::get('/dashboard', 'AdminController@index')->name('admin.dashboard'); }); }); // ROUTES PENDAFTAR Route::group(['middleware' => 'check-permission:pendaftar'], function () { Route::group(['prefix' => 'pendaftar'], function () { Route::get('/dashboard', 'PendaftarController@index')->name('pendaftar.dashboard'); }); });
app/Http/Controllers/HomeController.php
Buka file HomeController.php
dan edit seperti kode berikut:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use App\User; use Auth; class HomeController extends Controller { /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware('auth'); } /** * Show the application dashboard. * * @return \Illuminate\Http\Response */ public function index(Request $request) { $level = Auth::user()->level; switch ($level) { case '0': return redirect()->action('AdminController@index'); break; case '1': return redirect()->action('PendaftarController@index'); break; default: echo "PSB Online!"; break; } } }
Pada file routing (web.php), terlihat ada dua controller yang belum kita buat yaitu AdminController.php
dan PendaftarController.php
dengan fungsi index di dalamnya. Dua controller tersebut dimaksudkan, ketika yang login adalah user dengan level=0 (admin) akan diarahkan ke dashboard admin, sementara jika yang login user dengan level=1 (pendaftar) akan diarahkan ke dashboard pendaftar.
Mari kita buat dua controller tersebut dengan perintah berikut:
php artisan make:controller AdminController php artisan make:controller PendaftarController
Buka dan edit kedua file controller seperti kode berikut:
app/Http/Controllers/AdminController.php
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class AdminController extends Controller { public function __construct() { $this->middleware('auth'); } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { $title = 'Dashboard Admin'; return view('admin', compact('title')); } }
app/Http/Controllers/PendaftarController.php
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class PendaftarController extends Controller { public function __construct() { $this->middleware('auth'); } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { $title = 'Dashboard Admin'; return view('pendaftar', compact('title')); } }
Pada AdminController terdapat fungsi index di mana variable data di return ke view blade admin (baris kode ke-25). Artinya data akan dikembalikan ke file admin.blade.php
. Silakan buat file view dengan nama admin.blade.php
dan sesuaikan isinya dengan kode berikut:
resources/view/admin.blade.php
@extends('layouts.app') @section('content') <div class="container"> <div class="row justify-content-center"> <div class="col-md-8"> <div class="card"> <div class="card-header">Dashboard Admin</div> <div class="card-body"> @if (session('status')) <div class="alert alert-success" role="alert"> {{ session('status') }} </div> @endif <p>Anda login sebagai <strong><span class="text-danger">{{ Auth::user()->Biodata->nama }}</span></strong></p> </div> </div> </div> </div> </div> @endsection
Begitu pula untuk PendaftarController, kita harus buat file view dengan nama pendaftar.blade.php (baris kode ke-23).
resources/view/pendaftar.blade.php
@extends('layouts.app') @section('content') <div class="container"> <div class="row justify-content-center"> <div class="col-md-8"> <div class="card"> <div class="card-header">Dashboard Calon Siswa</div> <div class="card-body"> @if (session('status')) <div class="alert alert-success" role="alert"> {{ session('status') }} </div> @endif <p>Anda login sebagai <strong>{{ Auth::user()->Biodata->nama }}</strong></p> </div> </div> </div> </div> </div> @endsection
Setelah selesai membuat dua file view, sekarang saatnya kita testing dengan login sebagai admin dan juga login sebagai pendaftar.
Login sebagai Admin
Login sebagai Pendaftar