LARAVEL FRAMEWORK BASICS পর্ব-১৭: LARAVEL Validation Complete

Laravel Validation
Laravel Validation

Laravel validation কি?

সংক্ষেপে, আপনার কাছে একটি Laravel Application রয়েছে এবং আপনার এই লারাভেল দিয়ে তৈরি Application এর বিভিন্ন Form এর ডেটা গুলোকে যাচাই-বাছাই করতে হবে। Laravel validation সুবিধা দিয়ে আপনি আপনার Application এর Form এর Incoming গুলো আপনার ডিফাইন করা validation rules গুলি দ্বারা যাচাই -বাছাই করতে পারেন এবং প্রয়োজনীয় অ্যাকশন নিতে পারেন।

Laravel Framework দিয়ে তৈরি আপনার application এর incoming data গুলো যাচাই বাচাই করার জন্য অনেকগুলি উপায় রয়েছে। । এই আর্টিকেলে, আমরা Laravel Framework দিয়ে তৈরি সব ধরণের Form Input গুলো Validation করার সবগুলো উপায় নিয়ে আলোচনা করব :

Mastering Laravel with ReactJS Course

Creating a Basic Form

আমরা আমাদের কাজের সুবিধার জন্য create.blade.php নামে একটি Basic HTML Form তৈরি করব:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Laravel Form Validation</title>
  <!-- CSS only -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
  <style>
    .uper {
      margin-top: 40px;
    }
  </style>
</head>

<body>
  <div class="container">

    <div class="card uper">
      <div class="card-header">
        Register Now
      </div>
      <div class="card-body">
        <form method="post" action="{{ route('form.store') }}">
          @csrf
          <div class="form-group pb-3">
            <label for="name">Title:</label>
            <input type="text" class="form-control" name="title" />
          </div>
          <div class="form-group pb-3">
            <label for="body">Body</label>
            <textarea rows="3" class="form-control" name="body"></textarea>
          </div>

          <div class="d-grid gap-2 col-12 mx-auto">
            <button type="submit" class="btn btn-primary pb-3">Submit Information</button>
          </div>
        </form>
      </div>

    </div>
  </div>
</body>

</html>

Create a Controller File

এবার নিম্নোক্ত আর্টিসান কমান্ডের মাধ্যমে postController নামে একটি controller তৈরি করে ফেলুন :

php artisan make:controller postController

Defining The Routes

এখন, routes >> web.php ফাইলের ভিতরে নিম্নোক্ত route দুটি লিখুন।

use App\Http\Controllers\postController;

Route::get('/create', [postController::class, 'create'])->name('post.create');
Route::post('/post', [postController::class, 'store'])->name('post.store');

এখন আপনি যদি http://localhost:8000/create URL এ ভিজিট করেন তাহলে নিচের মত Form টি দেখাবে :

Laravel Form Validation
Laravel Form Validation

Laravel Form Validation এর উপায় গুলো কি ?

Laravel Framework দিয়ে Form থেকে পাঠানো ডেটা গুলোকে Validation করার চারটি ধাপ আছে :

1. Writing Validation Rules
2. Displaying Validation Error Messages
3. Customizing Validation Messages
4. Customizing Default Field Names

আসুন দেখি লারাভেল প্ল্যাটফর্মের সাথে validation পরিচালনা করার ধাপগুলো একে একে আলোচনা করা যাক :

Writing The Validation Logic

Laravel Framework এ Validation Logic গুলো আপনি তিনটি উপায়ে লিখতে পারেন। আর উপায় গুলো হচ্ছে নিম্নরূপ:

1. Illuminate\Http\Request object এর validate() Method ব্যবহার করার মাধ্যমে।
2. Illuminate\Support\Facades\Validator Facade ব্যবহারের মাধ্যমে।
3. অথবা Form Request Validation ব্যবহার করার মাধ্যমে।

Mastering Laravel with ReactJS Course

Writing Validation Logic with validate() Method

validate() Method টি ব্যবহার করে কোনো validation Rules লেখার পূর্বে আপনাকে প্রথমেই নিশ্চিত হতে হবে , আপনার কন্ট্রোলার ক্লাসে use Illuminate\Http\Request; এই লাইনটি দ্বারা Request Class টি Use করা হয়েছে কি না ? আর এই লাইনটি লিখার পরই আপনি validate() Method টি ব্যবহার করার অধিকার পাবেন। এই ক্ষেত্রে আপনি Validation Rules গুলো নিম্নোক্ত দুটি উপায়ে লিখতে পারেন :

1. single | delimited string ব্যবহার করার মাধ্যমে।
2. Array ব্যবহারের মাধ্যমে।

Writing Validation Rules with single “|” delimited string

    public function store(Request $request)
    {
        $validated = $request->validate([
            'title' => 'required|max:40',
            'body' => 'required|min:100'
        ]);
    }

Writing Validation Rules with an associative Array

    public function store(Request $request)
    {
        $validated = $request->validate([
            'title' => ['required','max:40'],
            'body' => ['required','min:100'],
        ]);
    }

Writing Validation Rules with Validator Facade

এছাড়াও , আপনি চাইলে validation rules গুলি Validator Facade ব্যবহার করে লিখতে পারেন। এক্ষেত্রে আপনাকে “use Illuminate\Support\Facades\Validator;” এই লাইনটি আপনার Controller Class শুরুর পূর্বে ব্যবহার করতে হবে। এবং এখানেও আপনি single | delimited string অথবা array হিসেবে Validation Rules গুলো লিখতে পারেন:

public function store(Request $request)
    {
        $validated = Validator::make($request->all(), [
            'title' => 'required|max:40',
            'body' => 'required|min:100',
        ]);
            if($validated->fails()){
                return back()->withErrors($validated->errors())->withInput();
            }
        }

একইভাবে Validator Facade এ আপনি array হিসেবেও Validation Rules গুলো লিখতে পারেন:

 public function store(Request $request)
    {
        $validated = Validator::make($request->all(), [
            'title' => ['required','max:40'],
            'body' => ['required','min:100'],
        ]);
            if($validated->fails()){
                return back()->withErrors($validated->errors())->withInput();
            }
        }

Displaying All Validation Errors

আপনি যখন Laravel-এ validation rules গুলি সংজ্ঞায়িত করেন , তখন অনেক সময় আপনি যে user input টি পান Laravel validation তা comply করেনা। Laravel validation তখন যা করে, তা হল ব্যবহারকারীকে পূর্ববর্তী পৃষ্ঠায় স্বয়ংক্রিয়ভাবে নিয়ে যায় । request input এবং validation error গুলো তখন সেশনে স্বয়ংক্রিয়ভাবে ফ্ল্যাশ করা হয়। আপনি যদি Illuminate\View\Middleware\ShareErrorsFromSession মিডলওয়্যার প্রয়োগ করেন, তখন একটি $errors ভেরিয়েবল সমস্ত অ্যাপ্লিকেশন জুড়ে ভিউ গুলোতে শেয়ার করা হয়, যাতে আপনি এটি সর্বদা ব্যবহার করতে পারেন। এই Laravel validation variable টি Illuminate\Support\MessageBag-এ instance হিসেবে পাওয়া যাবে।

আপনার প্রদত্ত Validation Rules গুলোর বিপরীতে কোনো Error তৈরি হয়েছে কিনা তা চেক করার জন্য আপনি has() অথবা any() method টি ব্যবহার করতে পারেন। এবং সব গুলো Error প্রদর্শনের জন্য আপনি all() Method টি ব্যবহার করতে পারেন :

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Laravel Form Validation</title>
  <!-- CSS only -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
  <style>
    .uper {
      margin-top: 40px;
    }
  </style>
</head>

<body>
  <div class="container">
<!-- /resources/views/post/create.blade.php -->
  
<h1>Create Post</h1>
  
@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif
    <div class="card uper">
      <div class="card-header">
        Register Now
      </div>
      <div class="card-body">
        <form method="post" action="{{ route('post.store') }}">
          @csrf
          <div class="form-group pb-3">
            <label for="name">Title:</label>
            <input type="text" class="form-control" name="title" />
          </div>
          <div class="form-group pb-3">
            <label for="body">Body</label>
            <textarea rows="3" class="form-control" name="body"></textarea>
          </div>

          <div class="d-grid gap-2 col-12 mx-auto">
            <button type="submit" class="btn btn-primary pb-3">Submit Information</button>
          </div>
        </form>
      </div>

    </div>
  </div>
</body>

</html>
Laravel Form Validation Display all errors
Laravel Form Validation Display all errors

Displaying Validation Error in Inline

এছাড়াও আপনি চাইলে Inline Error প্রদর্শনের জন্য প্রতিটি Form Input Field এ @error Blade directive ব্যবহার করতে পারেন :

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Laravel Form Validation</title>
  <!-- CSS only -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
  <style>
    .uper {
      margin-top: 40px;
    }
  </style>
</head>

<body>
  <div class="container">
<!-- /resources/views/post/create.blade.php -->
  
<h1>Create Post</h1>
  <div class="card uper">
      <div class="card-header">
        Register Now
      </div>
      <div class="card-body">
        <form method="post" action="{{ route('post.store') }}">
          @csrf
          <div class="form-group pb-3">
            <label for="name">Title:</label>
            <input type="text" class="form-control  @error('title') is-invalid @enderror" name="title" />
            @error('title')
            <div class="alert alert-danger">{{ $message }}</div>
            @enderror
          </div>
          <div class="form-group pb-3">
            <label for="body">Body</label>
            <textarea rows="3" class="form-control @error('body') is-invalid @enderror" name="body"></textarea>
            @error('body')
            <div class="alert alert-danger">{{ $message }}</div>
            @enderror
          </div>

          <div class="d-grid gap-2 col-12 mx-auto">
            <button type="submit" class="btn btn-primary pb-3">Submit Information</button>
          </div>
        </form>
      </div>

    </div>
  </div>
</body>

</html>
Laravel Validation Display Errors in Inline
Laravel Validation Display Errors in Inline

Mastering Laravel with ReactJS Course

Customizing The Error Messages

Laravel এর built-in validation rule গুলোর প্রতিটিতে একটি error message রয়েছে যা আপনার অ্যাপ্লিকেশনের lang/en/validation.php ফাইলে অবস্থিত। এই ফাইলের মধ্যে, আপনি প্রতিটি validation rule এর জন্য একটি translation entry পাবেন। আপনি আপনার অ্যাপ্লিকেশনের প্রয়োজনের উপর ভিত্তি করে এই messages গুলি পরিবর্তন বা পরিবর্ধন করতে পারেন।

তবে আপনি চাইলে Custom Validation Message গুলোকে আপনার Controller থেকেই ডিফাইন করে দিতে পারেন :

    public function store(Request $request)
    {
        $validated = $request->validate([
            'title' => 'required|max:40',
            'body' => 'required|min:100'
        ],
        [ 
            'title.required' => 'The :attribute field can not be blank value.',
            'title.max'=>'The :attribute field must not be greater than :max characters.',
            'body.required' => 'The :attribute field can not be blank value.',
            'body.min'=>'The :attribute field must be greater than :min characters.',
        ]);
      }

একই ভাবে আপনি Laravel Validator Facade এও Validation Message গুলো Customize করতে পারেন।

    public function store(Request $request)
    {
       $validated = Validator::make($request->all(), [
            'title' => ['required','max:40'],
            'body' => ['required','min:100'],
        ],
        [ 
            'title.required' => 'The :attribute field can not be blank value.',
            'title.max'=>'The :attribute field must not be greater than :max characters.',
            'body.required' => 'The :attribute field can not be blank value.',
            'body.min'=>'The :attribute field must be greater than :min characters.',
        ]);
            if($validated->fails()){
                return back()->withErrors($validated->errors())->withInput();
            } 
        }
Customizing Error Messages
Customizing Error Messages

এছাড়াও, আপনি আপনার অ্যাপ্লিকেশনের language এর জন্য messages গুলি অনুবাদ করতে অন্যান্য language এর translation ডিরেক্টরিতে এই ফাইলটির একটি কপি রাখতে পারেন। লারাভেল localization সম্পর্কে আরও জানতে, সম্পূর্ণ localization documentation দেখুন।

Customizing The form Field Name

অনেক সময় Form থেকে ডাটা পাঠানোর যে জন্য আমরা যে Form Field Name ব্যবহার করি, Validation Message গুলো প্রদর্শনের সময় আপনি ডিফল্ট Form Field এর নামের পরিবর্তে অন্য যেকোনো লেভেল ব্যবহার করতে পারেন :

    public function store(Request $request)
    {
        $validated = $request->validate([
            'title' => 'required|max:40',
            'body' => 'required|min:100'
        ],
        [ 
            'title.required' => 'The :attribute field can not be blank value.',
            'title.max'=>'The :attribute field must not be greater than :max characters.',
            'body.required' => 'The :attribute field can not be blank value.',
            'body.min'=>'The :attribute field must be greater than :min characters.',
        ],
        [
            'title' => 'Post Title',
            'body' => 'Post Content',
        ]
    );
  }
Form Input Field Level Customizing
Form Input Field Level Customizing

৩. Form Request Validation In Laravel

সাধারণত Complex Validation এর জন্য Form Request validation সুবিধা ব্যবহার করা হয়। এই Form Request ক্লাসগুলি হচ্ছে মূলত তাদের নিজস্ব Validation এবং authorization logic সহ কিছু কাস্টম ক্লাস। request class তৈরি করতে আপনি php artisan make:request formRequestClassName কমান্ডটি চালাতে পারেন। এইভাবে তৈরি করা form request class টি app/Http/Requests ডিরেক্টরিতে পাওয়া যাবে।

Mastering Laravel with ReactJS Course

আর এই form request class গুলোর তৈরির সুবিধা হচ্ছে, আপনি validation logic গুলোর সঙ্গে আপনার controller এর সাথে complicate বা গোল পাকানোর দরকার হবে না. আপনি যখন request টি type-hint করেন, তখন controller method টি তে কল করার আগেও Form request টি validated হয়ে যায়। আর যদি validation ব্যর্থ হয়, তখন ব্যবহারকারীকে স্বয়ংক্রিয়ভাবে response সহ পূর্ববর্তী লোকেশনে নিয়ে যাওয়া হয়।

প্রথমে চলুন নিম্নোক্ত কমান্ডের মাধ্যমে FormValidationRequest নামে একটি form request class তৈরি করি :

php artisan make:request PostValidationRequest

এখন আপনি app/Http/Requests ফোল্ডারের মধ্যে আপনার সদ্য তৈরি হওয়া PostValidationRequest.php ফাইলে নিচের মতো করে আপডেট করে নিন:

<?php
namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class PostValidationRequest 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<string, mixed>
     */
    public function rules()
    {
        return [
            'title' => 'required|max:20',
            'body' => 'required|min:100'
            ];
    }

     /**
     * Get the error messages for the defined validation rules.
     *
     * @return array
     */
    public function messages()
    {
        return [
            'title.required' => 'The :attribute field can not be blank value.',
            'title.max'=>'The :attribute field must not be greater than :max characters.',
            'body.required' => 'The :attribute field can not be blank value.',
            'body.min' => 'The :attribute field should be minimum :min characters'
        ];
    }

    public function attributes()
    {
        return [
            'title' => 'Post Title',
            ]; 
    }
}

এবার PostValidationRequest.php ফাইলে অবস্থিত ফাঙ্কশন গুলোর ব্যাখ্যা আসা যাক :

১. লাইন নম্বর ১৩ তে authorize function এর মাধ্যমে আমরা authorize করব কিনা, return true অথবা false এর মাধ্যমে সে বিষয়টা নির্ধারণ করি।
২. লাইন নম্বর ২৩ এ rules function এর মাধ্যমে আমরা কোন কোন Form Field Validation করব সেটি নির্ধারণ করি।
৩. লাইন নম্বর ৩৬ এ messages function এর মাধ্যমে আমরা Validation Rules গুলোর ডিফল্ট মেসেজ এর পরিবর্তিতে কাস্টম মেসেজ নির্ধারণ করি।
৪. সর্বশেষ লাইন নম্বর ৪৬ এ attributes function এর মাধ্যমে আমরা Form Field গুলোর প্রত্যেকটি ডিফল্ট নাম গুলোর একটা কাস্টম নাম নির্ধারণ করতে পারি।

এখন আপনার Controller এর store Method এর Validation টি হবে নিম্নরুপঃ

/**
     * Store a new blog post.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(PostValidationRequest $request)
    {
        $validated = $request->validated();
    }

Note:তবে অবশ্যই use App\Http\Requests\PostValidationRequest; এই লাইনটি ক্লাস শুরুর পূর্বে যুক্ত করে দিতে ভুলবেন না।

Multiple Form Validation in a Single Page

অনেকসময় আমাদেরকে একই পেজে একাধিক Form রাখার প্রয়োজন হয়। এবং প্রত্যেকটি Form কে আলাদা করে Validation এবং Error Message গুলো প্রদর্শন করতে হয়। একই পেজে একাধিক ফরম রেখে এবং তাদের প্রত্যেক কে আলাদা করে Validation Error Message গুলো প্রদর্শন করার সুবিধা প্রদানের জন্য এসেছে Laravel Multi Bag Validation.

Laravel Multi Bag Validation সুবিধা বুঝার জন্য ,প্রথমে আমাদের create.blade.php ফাইল কে নিচের মতো পরিবর্তন করে নিব:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Laravel Form Validation</title>
  <!-- CSS only -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
  <style>
    .uper {
      margin-top: 40px;
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="card uper">
      <div class="card-header">
        Create Post
      </div>
      <div class="card-body">
        <form method="post" action="{{ route('post.store') }}">
          @csrf
          <div class="form-group pb-3">
            <label for="title">Post Title:</label>
            <input type="text" class="form-control" name="title" />
          </div>
          <div class="form-group pb-3">
            <label for="body">Body:</label>
            <textarea rows="3" class="form-control" name="body"></textarea>
          </div>

          <div class="d-grid gap-2 col-12 mx-auto">
            <button type="submit" class="btn btn-primary pb-3">Create Post</button>
          </div>
        </form>
      </div>
    </div>
    <div class="card uper">
      <div class="card-header">
        Create Category
      </div>
      <div class="card-body">
        <form method="post" action="{{ route('category.store') }}">
          @csrf
          <div class="form-group pb-3">
            <label for="name">Category Name:</label>
            <input type="text" class="form-control" name="name" />
          </div>
          <div class="form-group pb-3">
            <label for="body">Description:</label>
            <textarea rows="3" class="form-control" name="description"></textarea>
          </div>

          <div class="d-grid gap-2 col-12 mx-auto">
            <button type="submit" class="btn btn-primary pb-3">Create Category</button>
          </div>
        </form>
      </div>

    </div>
  </div>
</body>

</html>
Laravel Multiple Form Validation in a Single Page
Laravel Multiple Form Validation in a Single Page

Mastering Laravel with ReactJS Course

ব্যাখ্যা: উপরের ছবিতে যেমন দেখতে পাচ্ছেন , এখানে Post এবং Category তৈরির জন্য আমাদের দুটি Form রয়েছে। এবং এই দুটি Form কে একই Controller বা ভিন্ন Controller এর সম্পূর্ণ ভিন্ন দুটি Method দিয়ে Validation করতে পারি। কিন্তু সমস্যা হচ্ছে আমরা Validation Error মেসেজ গুলোকে একই পেজে প্রদর্শন করতে হবে। আর এর জন্যই আমরা Multi Bag Validation সুবিধাটি ব্যবহার করব। তবে তার আগে আপনাকে route এ নিম্নোক্ত route গুলোকে তৈরি করে রাখতে হবে।

use App\Http\Controllers\postController;

Route::get('/create', [postController::class, 'create'])->name('post.create');
Route::post('/save-post', [postController::class, 'postStore'])->name('post.store');
Route::post('/save-category', [postController::class, 'categoryStore'])->name('category.store');

ব্যাখ্যা: এখানে ৩ নম্বর লাইনে আমরা create.blade.php ফাইলটি প্রদর্শন করব। যেখানে আমাদের Post Form এবং Category Form দুটি রয়েছে। এবং ৪ নম্বর ও ৫ নম্বর লাইনে আমরা যথাক্রমে Post Form এবং Category Form এর ডেটা সংরক্ষণের কাজ করব।

Adding Multi Bag Validation to Controller Method

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
class postController extends Controller
{
    public function create()
    {
        return view('create');
    }

    public function postStore(Request $request)
    {
        $postValidator = $request->validateWithBag('post',[
            'title' => 'required|max:40',
            'body' => 'required|min:100'
        ],
    );
   }
   public function categoryStore(Request $request)
   {
        $categoryValidator = $request->validateWithBag('category',[
            'name' => 'required|max:40',
            'description' => 'required|min:100'
        ],
    );
   }
}

ব্যাখ্যা: এখানে লাইন নম্বর ১৫ এবং ২৩ এ আমরা Validation Error গুলো validateWithBag Method ব্যবহারের মাধ্যমে post এবং category নামক দুটি Bag এ validation এরর গুলো রেখে দেই। এখন আমরা Form দুটিতে ভিন্ন ভিন্ন ব্যাগ ভর্তি এই Validation এরর গুলো প্রদর্শন করব।

আপনার create.blade.php ফাইলে নিচের মতো করে পরিবর্তন করে নিন :

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Laravel Form Validation</title>
  <!-- CSS only -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
  <style>
    .uper {
      margin-top: 40px;
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="card uper">
      <div class="card-header">
        Create Post
      </div>
<!-- /resources/views/post/create.blade.php -->
  
@if ($errors->post->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->post->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif
      <div class="card-body">
        <form method="post" action="{{ route('post.store') }}">
          @csrf
          <div class="form-group pb-3">
            <label for="title">Post Title:</label>
            <input type="text" class="form-control  @error('title','post') is-invalid @enderror" name="title" />
            @error('title','post')
            <div class="alert alert-danger">{{ $message }}</div>
            @enderror
          </div>
          <div class="form-group pb-3">
            <label for="body">Body:</label>
            <textarea rows="3" class="form-control @error('body','post') is-invalid @enderror" name="body"></textarea>
            @error('body','post')
            <div class="alert alert-danger">{{ $message }}</div>
            @enderror
          </div>

          <div class="d-grid gap-2 col-12 mx-auto">
            <button type="submit" class="btn btn-primary pb-3">Create Post</button>
          </div>
        </form>
      </div>
    </div>
    <div class="card uper">
      <div class="card-header">
        Create Category
      </div>

      @if ($errors->category->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->category->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

      <div class="card-body">
        <form method="post" action="{{ route('category.store') }}">
          @csrf
          <div class="form-group pb-3">
            <label for="name">Category Name:</label>
            <input type="text" class="form-control  @error('name','category') is-invalid @enderror" name="name" />
            @error('name','category')
            <div class="alert alert-danger">{{ $message }}</div>
            @enderror
          </div>
          <div class="form-group pb-3">
            <label for="body">Description:</label>
            <textarea rows="3" class="form-control @error('description','category') is-invalid @enderror" name="description"></textarea>
            @error('description','category')
            <div class="alert alert-danger">{{ $message }}</div>
            @enderror
          </div>

          <div class="d-grid gap-2 col-12 mx-auto">
            <button type="submit" class="btn btn-primary pb-3">Create Category</button>
          </div>
        </form>
      </div>

    </div>
  </div>
</body>

</html>
Display Validation Errors with ValidationWithBag
Display Validation Errors with ValidationWithBag

Writing Multi Bag Validation with Validator Facade

আবার আপনি যখন Validation এর জন্য Laravel Validator Facade টি ব্যবহার করবেন , তখন আপনার validateWithBag মেথড টি আপনার Controller Class এ নিম্নোক্ত উপায়ে লিখতে হবে।

<?php

namespace App\Http\Controllers;
use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;
class postController extends Controller
{
    public function create()
    {
        return view('create');
    }

    public function postStore(Request $request)
    {

    Validator::make($request->all(), [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ])->validateWithBag('post');
}
public function categoryStore(Request $request)
{

    Validator::make($request->all(), [
        'name' => 'required|max:40',
        'description' => 'required|min:100',
    ])->validateWithBag('category');
}
}

Writing Multi Bag Validation with Form Request Validation Class

এক্ষেত্রে আপনার Form Request Validation Class এ $errorBag Protected property তে আপনার error Bag এর নাম টি দিয়ে দিতে হবে।

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class PostValidationRequest extends FormRequest
{
    protected $errorBag="post";
    /**
     * 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<string, mixed>
     */
    public function rules()
    {
        return [
            'title' => 'required|max:20',
            'body' => 'required|min:100'
            ];
    }
}

ব্যাখ্যা: লাইন নম্বর ৯ এ লক্ষ্য করুন , আমরা $errorBag Protected Property তে আমাদের Error Bag এর নাম হিসেবে post নামটি ব্যবহার করেছি।

Stopping On First Validation Failure

কখনও কখনও আপনি প্রথম validation failure হলে পরবর্তী validation rules গুলো রান করা বন্ধ করতে চাইতে পারেন। এটি করতে, attribute এ bail rule এসাইন করতে পারেন:

   /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */

    public function store(Request $request)
    {
        $validated = $request->validate([
            'title' => 'bail|required|max:40',
            'body' => 'required|min:100'
        ]);
    }

উপরের উদাহরণে, name field এর required rule fail হলে, max rule চেক করা হবে না। Rules গুলিকে যে ক্রমানুসারে বরাদ্দ করা হয়েছে সে অনুযায়ী validated করা হবে৷

Validating simple nested attributes

অনেক সময় আমাদের form এ একটি নির্দিষ্ট Field এর একাধিক Nested Field থাকে , আপনার form টি অনেকটা এই রকম :

referral.blade.php

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Laravel Form Validation</title>
  <!-- CSS only -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
<div class="container">
@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif
    <div class="card uper">
      <div class="card-header">
        <!-- Form Name -->
        Referral form | Add below
      </div>
<form class="form-horizontal" method="POST" action="{{ route('save.referral') }}">
@csrf
<div id="email" class="form-group">
  <label class="col-md-4 control-label" for="personal-email">Personal Email</label>
<div class="col-md-4 margin-bottom pt-2 pb-2">
  <input id="email" name="email[personal]" type="text" placeholder="Enter Your Personal Email" class="form-control input-md p">
</div>

  <label class="col-md-4 control-label" for="official-email">Official Email</label>
<div class="col-md-4 margin-bottom pt-2 pb-2">
  <input id="official-email" name="email[official]" type="text" placeholder="Enter Your Official Email" class="form-control input-md">
</div>
</div>

<div id="items" class="form-group">
  <label class="col-md-4 control-label" for="name">Referral Name</label>
<div class="col-md-4 margin-bottom pb-2">
  <input id="referral-name" name="referral-name" type="text" placeholder="Enter name of referral" class="form-control input-md">
</div>
</div>


<button id="add" class="add-more btn btn-info uppercase col-2" type="button">+ Add another referral</button> 
<button class="delete btn btn-danger uppercase col-2">- Remove referral</button>
    </div>
    <input type="submit" class="btn btn-primary" value="Save">
</div>
</form>


<script>
    $(document).ready(function() {
      var x=0;
  $(".delete").hide();
  //when the Add Field button is clicked
  $("#add").click(function(e) {
    x++;
      $(".delete").fadeIn("1500");
    //Append a new row of code to the "#items" div
    $("#items").append(
      '<div class="next-referral col-2"><input id="referral-name" name="referral-name['+x+']" type="text" placeholder="Enter name of referral" class="form-control input-md"></div>'
    );
  });
  $("body").on("click", ".delete", function(e) {
    $(".next-referral").last().remove();
  });
});
</script>
</body>
</html>

এবার web.php File এ নিম্নোক্ত route গুলো লিখে ফেলুন :

use App\Http\Controllers\postController;

Route::get('/referral', [postController::class, 'referral'])->name('create.referral');
Route::post('/save-referral', [postController::class, 'referralStore'])->name('save.referral');

এবং আপনার Post Controller এ নিম্নোক্ত মেথড টি লিখুন :

  public function referral()
    {
        return view('referral');
    }

আউটপুট অনেকটা নিম্নরূপ :

Laravel Simple Nested Field Validation
Laravel Simple Nested Field Validation

তখন আমাদের Validation Rules গুলো apply হবে নিম্নরুপঃ

 public function referralStore(Request $request)
    {
        $validated = $request->validate([
            'email.personal' => ['email','required'],
            'email.official' => ['email','required'],
            'referral-name' =>['required','string','max:255'],
            'referral-name.*' =>['required','string','max:255'],
        ]);
    }

অন্যদিকে, যদি আপনার Form এর ফিল্ড এর নাম যদি ভার্শন জাতীয় হয় , অর্থাৎ ডট যুক্ত (v1.0 এই রকম ) হয়। , তাহলে আপনাকে ব্যাকস্ল্যাশের মাধ্যমে “ডট” কে ইগনোর করতে হবে :

$request->validate([
    'title' => 'required|unique:posts|max:255',
    'v1\.0' => 'required',
]);

Validating arrays and nested attributes

এছাড়াও আমাদের Form টি আরো জটিল হতে পারে , অর্থাৎ আমাদের ফর্মে পুনরাবৃত্তিযোগ্য Field আরো কমপ্লেক্স হতে পারে। অনেকটা নিম্নরুপঃ

<div class="form-group pb-3">
          <label for="child1">Child1 Information:</label>
          <div class="form-inline">
          <label for="child1_name">Child1 Name:</label>
          <input type="text" name="child[0][name]" />
          <label for="child1_name">Child1 Age:</label>
          <input type="text" name="child[0][age]" />
          </div>
</div>

          <div class="form-group pb-3">
          <label for="child1">Child2 Information:</label>
          <div class="form-inline">
          <label for="child1_name">Child2 Name:</label>
          <input type="text" name="child[1][name]" />
          <label for="child1_name">Child1 Age:</label>
          <input type="text" name="child[1][age]" />
          </div>
</div>

এক্ষেত্রে আপনার Controller এ অবস্থিত Validation হবে নিম্নরূপ :

        $validated = $request->validate([
            'child.*.name' => 'required|string|max:255',
            'child.*.age' => 'required|nullable|number',
        ]);
    }

Mastering Laravel with ReactJS Course

একটি XHR request এর ক্ষেত্রে, ব্যবহারকারী একটি validation error গুলোর একটি JSON HTTP response 422 status code পায়।

আপনি এমনকি একটি “after” validation hook ব্যবহার করে আপনার form request কে “enrich” বা উন্নত করতে পারেন। এর জন্য withValidator method টি ব্যবহার করা যেতে পারে। যেহেতু ইতিমধ্যে সম্পূর্ণরূপে তৈরি validator ইতিমধ্যেই প্রাপ্ত হয়েছে, এখন Laravel validation rule গুলি মূল্যায়ন করার আগে আপনি যেকোন method কে কল করতে সক্ষম হবেন৷

Authenticated user এর তথ্য পরীক্ষা করতে, আপনি user method টি রান করতে পারেন, কারণ base Laravel request class টি form request দ্বারা extended হয়। যখন authorize method টি false return করে তখন একটি 403 স্ট্যাটাস কোড তৈরি করা হয় এবং আপনার controller method এর কোনো ব্যবহার হবে না। আর যখন authorize method রিটার্ন true দিবে তখন আপনি অ্যাপ্লিকেশনের অন্যান্য অংশে authorization logic গুলো ব্যবহার করতে পারবেন।

আমি মাসুদ আলম, বাংলাদেশের ৩৬ তম Zend Certified Engineer । ২০০৯ সালে কম্পিউটার সাইন্স থেকে বেচেলর ডিগ্রী অর্জন করি। দীর্ঘ ১৫ বছর আমি Winux Soft, SSL Wireless, IBCS-PRIMAX, Max Group, Canadian International Development Agency (CIDA), Care Bangladesh, World Vision, Hellen Keller, Amarbebsha Ltd সহ বিভিন্ন দেশি বিদেশী কোম্পানিতে ডেটা সাইন্স, মেশিন লার্নিং, বিগ ডেটা, ওয়েব ডেভেলপমেন্ট এবং সফটওয়্যার ডেভেলপমেন্ট এর উপর বিভিন্ন লিডিং পজিশন এ চাকরি এবং প্রজেক্ট লিড করি। এছাড়াও বাংলাদেশের ১৮৫ জন জেন্ড সার্টিফাইড ইঞ্জিনিয়ার এর মধ্যে ১২০ এরও অধিক ছাত্র আমার হাতে জেন্ড সার্টিফাইড ইঞ্জিনিয়ার হয়েছেন। বর্তমানে w3programmers ট্রেনিং ইনস্টিটিউট এ PHP এর উপর Professional এবং Advance Zend Certified PHP -8.2 Engineering, Laravel Mastering Course with ReactJS, Python Beginning To Advance with Blockchain, Machine Learning and Data Science, Professional WordPress Plugin Development Beginning to Advance কোর্স করাই। আর অবসর সময়ে w3programmers.com এ ওয়েব টেকনোলজি নিয়ে লেখালেখি করি।

Leave a Reply