Fitur Laravel Yang Wajib Digunakan

Intania Mentari
6 min read5 days ago

--

Photo by Mohammad Rahmani on Unsplash

Ketika masih belajar menggunakan Laravel, saya hanya menggunakan model, view dan controller untuk membangun sebuah project fullstack. Di masa itu saya merasa hal tersebut sudah cukup efektif dalam membuat code yang baik. Setelah setahun saya terbiasa menggunakan Laravel di masa kuliah, saya kemudian mulai mencari pekerjaan berbasis Laravel.

Setelah saya terjun di dunia kerja, saya melihat bahwa Laravel itu sangat menyeramkan bagi saya, karena ada fitur-fitur asing dan sulit saya terima pada saat itu. “Mengapa menggunakan cara ini jika kita ada pilihan bisa membuatnya di Controller?” dan pertanyaan lainnya di benak saya.

Namun seiring saya menggunakannya dan belajar dengan kerumitan ini di awal, ternyata itulah cara yang cukup baik untuk memaksimalkan penggunaan fitur framework ini. Berikut adalah beberapa yang paling sering saya gunakan ketika menggunakan Laravel dan cukup familiar untuk saya jabarkan

Helpers

Saya biasa menggunakan helpers untuk membuat variabel yang sering dipanggil atau transformasi data yang tidak terlalu rumit, misal format harga, mata uang, variabel status payment, dan lainnya.

Helpers — Response JSON

namespace App\Helpers;

class ResponseHelper
{
// Response Json
public static function simpleResponse($message, $success = true, $status = 200)
{
return response()->json([
'success' => $success,
'message' => $message,
], $status);
}
}

berikut contoh penggunaannya di controller

namespace App\Http\Controllers\API;

use App\Helpers\ResponseHelper;

class ActivityApiController extends Controller
{
// some code

if($generalSetting->cod == 1 && $cod_reservation > $date_selected) {
return ResponseHelper::simpleResponse("You cannot place an order within 24 hours. Please choose a date starting from tomorrow.", false, 422);
}
}

Helpers — Variabel Status Payment

namespace App\Helpers;

class PaymentStatusHelper
{
// status payment
const XENDIT = [
'PENDING' => 'PENDING',
'PAID' => 'PAID',
'EXPIRED' => 'EXPIRED'
];
}

berikut contoh penggunaannya di Controller

namespace App\Http\Controllers\API;

use App\Helpers\PaymentStatusHelper;


class XenditApiController extends Controller
{
public function webhook(Request $request, $type)
{
if($status == PaymentStatusHelper::XENDIT['PAID']) {
// some code
}
}
}

Middleware

Saya menggunakan middleware biasanya untuk authentication, membedakan halaman user yang sudah login dan juga yang belum. Berikut adalah contohnya

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class CheckLogin
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
public function handle(Request $request, Closure $next)
{
if (!session()->has('role') && !session()->has('id')) {
return redirect()->route('login');
}

return $next($request);
}
}

kemudian saya mendaftarkan middleware saya di kernel.php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
protected $routeMiddleware = [
// some middleware
'check.login' => \App\Http\Middleware\CheckLogin::class
];
}

setelah itu saya pasang di web.php

Route::middleware(['check.login'])->group(function () {
// some code
});

Requests

Saya membuat request untuk melakukan proses validasi input dari user. berikut adalah contoh codenya

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class AdditionalDiscountRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}

/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
"disc_name" => "required|string",
"disc" => "required|numeric",
"days" => "required|numeric",
"pricing_code" => 'required|array',
];
}

/**
* Filter input sebelum digunakan di controller.
*/
public function filtered()
{
return $this->except(['_token', '_method']);
}
}

setelah itu saya memanggil request validation yang dibuat ke dalam controller

namespace App\Http\Controllers;

use App\Http\Requests\AdditionalDiscountRequest;


class AdditionalDiscountController extends Controller
{
/**
* Store a newly Additional Discount
*/
public function store(AdditionalDiscountRequest $request)
{
$this->addDiscountService->createAdditionalService($request->filtered());
Alert::success('Sukses!', 'Data telah berhasil ditambahkan.');

return redirect()->route('corporate.additional.discount.index');
}
}

Email

Fitur ini biasanya saya gunakan untuk mengirimkan invoice atau pesan notifikasi. Awalnya cukup ribet membuatnya, tapi setelah saya bisa membuat satu fungsi, saya bisa gunakan untuk membuat email-email lainnya 😂. Awalnya saya akan setting .env terlebih dahulu, berikut adalah contoh codenya

MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=test@gmail.com
MAIL_PASSWORD=jpjxjjpurpoxgehx
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"

kemudian saya membuat emailnya

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class InvoiceMail extends Mailable
{
use Queueable, SerializesModels;
public $clientName, $subject, $pdfPath, $fileName;

/**
* Create a new message instance.
*
* @return void
*/
public function __construct($clientName, $subject, $pdfPath, $fileName)
{
$this->clientName = $clientName;
$this->subject = $subject;
$this->pdfPath = $pdfPath;
$this->fileName = $fileName;
}

/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->view('emails.payment-cc')
->subject($this->subject)
->with([
'clientName' => $this->clientName
])
->attach($this->pdfPath, [
'as' => $this->fileName,
'mime' => 'application/pdf',
]);
}
}

setelah email jadi, saya membuat view emailnya

Dear {{ $clientName }},<br><br>
You have received a booking. Please check an attachment to see the details.<br><br>
Thank You,<br>
<strong>Admin</strong>

kemudian saya akan menggunakan email ini di controller

public function sendEmailToAdmin($email, $clientName, $pdfPath, $file_name)
{
Mail::to($email)->send(new InvoiceMail(
$clientName,
'Invoice',
$pdfPath,
$file_name
));
}

Services

Fitur dari laravel ini saya gunakan untuk memisahkan proses yang membutuhkan logika atau perhitungan dengan alur prosesnya. Alur proses tetap saya letakkan di controller, tetapi proses logikanya saya pisahkan ke dalam service.

Saya sebelumnya agak rumit dengan konsep service ini, karena codenya terlihat sangat kompleks karena biasanya tersebar di beberapa service dan dipanggil di satu controller, tapi di lain sisi, cara ini bisa membuat code reuseable karena bisa dipanggil di banyak controller yang ada hanya dengan satu code yang saya letakan di service.

Untuk membuatnya, pertama-tama saya membuat terlebih dahulu servicenya

namespace App\Services;

use App\Helpers\ResponseHelper;
use App\Models\PaymentInstapay;
use App\Services\Contracts\IInstapayService;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;

class InstapayService implements IInstapayService
{
/**
* Create invoice and get link payment
*/
public function createInvoice($reservation_code, array $instapay, $reservationId)
{
try {
$baseURL = config('app.instapay.endpoint');

$secretKey = config('app.instapay.secret_key');
$clientKey = config('app.instapay.client_key');

$base64Token = base64_encode($clientKey . ':' . $secretKey);

$paymentInstapay = PaymentInstapay::create([
'reservation_id' => $reservationId,
]);

$response = Http::withHeaders([
'Authorization' => 'Basic ' . $base64Token,
'Content-Type' => 'application/json',
])->post($baseURL, [
'order_id' => $this->uniqOrderIdInstapay(),
'amount' => $instapay['amount'],
'description' => $instapay['description'],
'customer_details' => $instapay['customer_details'],
'callback_url' => $instapay['callback_url'],
'success_redirect_url' => $instapay['success_redirect_url'],
'failed_redirect_url' => $instapay['failed_redirect_url'],
'admin_fee_paid_by_customer' => $instapay['admin_fee_paid_by_customer'],
]);

if(!$response->json('public_id')) {
throw new HttpResponseException(ResponseHelper::simpleResponse('Payment process failed, an error occurred in the payment gateway.', false, 422));
} else {
$paymentInstapay->update([
'public_id' => $response->json('public_id')
]);

info(['link payment instapay', $response->json()]);

return $response->json('invoice_url');
}

} catch (HttpResponseException $e) {
throw new HttpResponseException(ResponseHelper::simpleResponse('Payment process failed, an error occurred in the payment gateway.', false, 422));
}
}

/**
* Uniq id order instapay
*/
public function uniqOrderIdInstapay(): string
{
return str_replace(['-', ' '], ['_', '.'], Str::uuid()->toString());
}
}

kemudian saya buat contract nya. Biasanya contract dibuat pertama kali, tetapi saya lebih nyaman membuat contract setelah service dibuat. Sebenarnya contract ini digunakan agar service yang dibuat tipe data parameter dan return-nya tidak melenceng dari ketentuan yang diharapkan. Berikut adalah codenya

namespace App\Services\Contracts;

interface IInstapayService
{
public function createInvoice($reservation_code, array $instapay_data, $reservationPaymentId);
}

Agar service bisa diakses, kita perlu registrasi ke dalam file AppServiceProvider.php beserta contractnya

namespace App\Providers;

use App\Services\Contracts\IInstapayService;
use App\Services\InstapayService;

class AppServiceProvider extends ServiceProvider
{
public function register()
{
// service registration list..
$this->app->bind(IInstapayService::class, InstapayService::class);
}
}

setelah itu kita bisa panggil codenya di controller

namespace App\Http\Controllers\API;

use App\Services\Contracts\IInstapayService;


class ReservationApiController extends Controller
{
protected $instapayService;

public function __construct(IInstapayService $instapayService){
$this->instapayService = $instapayService;
}

public function paymentWithInstapay($request, $code, $totalAll, $reservationId)
{
$instapay_request = [
'amount' => (int) ceil($totalAll),
'description' => "Payment",
'customer_details' => [
'full_name' => $request['full_name'],
'email' => $request['email'],
'phone' => $request['phone']
],
'callback_url' => config('app.base_url') . '/api/v1/webhook/instapay',
'success_redirect_url' => config('app.base_url') . '/api/v1/success',
'failed_redirect_url' => config('app.base_url') . '/api/v1/failed',
'admin_fee_paid_by_customer' => 'true',
];

return $this->instapayService->createInvoice(
$code, $instapay_request, $reservationId
);
}
}

Menyebarkan data ke semua view yang ada

Ada saat dimana saya ingin membagikan data yang sama ke semua view yang ada. Daripada saya mengulang codenya di controller, saya tambahkan di AppServiceProvider.php

public function boot()
{
Schema::defaultStringLength(191);
$user = Users::where('id', session('id'))->first();

// share data with static way
View::share('auth', $user);

// share data to all view with condition
View::composer('*', function ($view) {
$userId = session('id');
$role = session('role');

if ($role === 'corporate' && $userId) {
$user = Users::find($userId);

if ($user) {
$properties = explode(',', $user->property);
$activities = Activity::whereIn('act_code', $properties)
->select(['id', 'act_code', 'act_name'])
->get();

$view->with('activities', $activities);
$view->with('auth', $user);
}
}
});
}

penggunaannya di view sudah secara otomatis bisa digunakan seperti contoh berikut ini

@if(auth)
<p>Welcome, {{ auth->name }}!</p>
@endif

@if(activities)
<ul>
@foreach(activities as activity)
<li>{{ activity.act_name }}</li>
@endforeach
</ul>
@endif

Bagian-bagian ini adalah yang paling sering saya gunakan di dalam project Laravel, semoga info ini membantu!

Terima kasih sudah mampir dan membaca sampai sini! Semoga tulisan ini bermanfaat. Kalau suka, dukung aku di Trakteer🍹 atau Ko-Fi ☕.
Keep learning, keep growing! ✨

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Intania Mentari
Intania Mentari

Written by Intania Mentari

Hello! Welcome to my little blog. I'm a backend programmer in software house and my basic programming language is PHP. Nice to meet you ❤️

No responses yet

Write a response