InputFilter với Form

Trong ví dụ trước Contact V.2, bạn đã tạo ra form model và tiến hành kiểm tra dữ liệu form với isValid(), tuy nhiên ở ví dụ đó isValid() luôn trả về true vì bạn chưa thêm bộ lọc + xác thực dữ liệu vào form.

Để thêm một bộ lọc + kiểm tra dữ liệu vào form bạn cần tạo ra một InputFilter và đưa vào đó các Input cho phần tử nào của Form cần kiểm tra, lọc dữ liệu. Để tạo ra InputFilter đọc phần: InputFilter trong ZF

Sau khi có InputFilter chứa các Input cần xác thực cho phần tử mong muốn của Form, đưa vào Form bằng phương thức

$form->setInputFilter($inputfilter);

Lúc này khi bạn setData(), isValid() thì Form sẽ dùng InputFilter để lọc và kiểm tra dữ liệu.

Ứng dụng InputFilter vào Form

Trở lại ví dụ Contact V.2, bạn sẽ nâng cấp bằng cách thêm bộ lọc + kiểm tra dữ liệu Input cho các phần tử FORM: email, subject, content, phone

Toàn bộ code tạo ra và đưa InputFilter nằm ở phương thức setInputFilter() mới xây dựng, như vậy toàn bộ code của lơp ContactForm2 đó là:

module/Application/src/Form/ContactForm2.php

<?php
namespace Application\Form;
use Zend\Form\Form;
use Zend\InputFilter\InputFilter;

class ContactForm2 extends Form
{

    /**
     * ContactForm2 constructor.
     */
    public function __construct()
    {
        //Định nghĩa tên cho form
        parent::__construct('contact-form2');
        // Set POST method for this form
        $this->setAttribute('method', 'post');
        $this->setAttribute('class', 'p-4 bg-light');



        $this->addElements();


    }

    public function setAction($url) {
        $this->setAttribute('action', $url);
        return $this;
    }
    public function addInputFilter() {
        $inputfilter = new InputFilter();

        //Input email: loại bỏ khoảng trắng, phải là địa chỉ email
        $inputfilter->add(
            [
                'name' => 'email',
                'filters' => [
                    [
                        'name' => 'StringTrim'
                    ]
                ],
                'validators' => [
                    [
                        'name' => 'EmailAddress'
                    ],
                ],

            ]
        );
        //Input subject: chuyển thành chữ HOA, loại bỏ khoảng trắng
        //chiều dài 5 - 30
        $inputfilter->add(
            [
                'name' => 'subject',
                'filters' => [
                    [
                        'name' => 'StringToUpper'
                    ],
                    [
                        'name' => 'StringTrim'
                    ]
                ],
                'validators' => [
                    [
                        'name' => 'StringLength',
                        'options' => [
                            'encoding' => 'UTF-8',
                            'max' => 30,
                            'min' => 5
                        ]
                    ],
                ],

            ]
        );
        //Input body: loại bỏ khoảng trắng
        //chiều dài tối thiểu 5
        $inputfilter->add(
            [
                'name' => 'body',
                'filters' => [
                    [
                        'name' => 'StringTrim'
                    ]
                ],
                'validators' => [
                    [
                        'name' => 'StringLength',
                        'options' => [
                            'min' => 5
                        ]
                    ],
                ],

            ]
        );
        //Input phone: loại bỏ khoảng trắng
        //phải là các chữ số
        $inputfilter->add(
            [
                'name' => 'phone',
                'filters' => [
                    [
                        'name' => 'StringTrim'
                    ]
                ],
                'validators' => [
                    [
                        'name' => 'Digits',
                    ],
                ],

            ]
        );


    $this->setInputFilter($inputfilter);
    }
    
    private function addElements()
    {
        //Xem thêm: https://xuanthulab.net/cac-phan-tu-co-ban-cua-zend-form.html

        // Add "email" field
        $this->add([
            'type'  => 'email',
            'name' => 'email',
            'attributes' => [
                'id' => 'email',
                'class' => 'form-control'
            ],
            'options' => [
                'label' => 'Email address',
            ],
        ]);

        // Add "subject" field
        $this->add([
            'type'  => 'text',
            'name' => 'subject',
            'attributes' => [
                'id' => 'subject',
                'class' => 'form-control'

            ],
            'options' => [
                'label' => 'Tiêu đề liên hệ',
            ],
        ]);

        // Add "body" field
        $this->add([
            'type'  => 'textarea',
            'name' => 'body',
            'attributes' => [
                'id' => 'body',
                'class' => 'form-control'

            ],
            'options' => [
                'label' => 'Nội dung',
            ],
        ]);
        // Add "phone" field
        $this->add([
            'type'  => 'text',
            'name' => 'phone',
            'attributes' => [
                'id' => 'phone',
                'class' => 'form-control'

            ],
            'options' => [
                'label' => 'Tel',
            ],
        ]);

        // Add the submit button
        $this->add([
            'type'  => 'submit',
            'name' => 'submit',
            'attributes' => [
                'class' => 'btn btn-warning',

                'value' => 'Gửi liên hệ',
            ],
        ]);

        $this->addInputFilter();
    }

}

Chạy ứng dụng, nếu bạn nhập dữ liệu không đúng, ví dụ phone nhập có ký tự chữ, để trống tiêu đề ... thì khi valid sẽ false và thông báo lỗi xuất hiện ở View

Các lỗi Valid hiện thị ở View như trên, nó được Render bởi View Helper: formelementerrors, nếu thích tùy chọn cách hiện thị này, bạn có thể thay đổi formelementerrors về View Helper do bạn tự xây dựng theo hướng dẫn: tùy chọn hiện thị lỗi valid ở View với Zend Form

Dịch các thông báo Validator

Trong thông báo lỗi của Validator sử dụng tiếng Anh, như ví dụ trên bạn thấy thông báo: The input is less than 5 characters long

Dịch sang ngôn ngữ khác các thông báo này thì Zend đã hỗ trợ file dữ liệu để dịch từ thư viện zend-i18n-resources nhưng rất tiếc là không có dữ liệu Tiếng Việt. Điều này nghĩa là bạn phải tự dịch.

Bước 1 - Dịch file ngôn ngữ

Đầu tiên cần tải file gốc dịch tiếng anh của các thông báo lỗi Validator về (Download), lưu vào một thư mục của dự án ví dụ tại: module/Application/languages/vi/Zend_Validate.php

Trong file này là mảng PHP chứa thông tin về các dòng thông báo lỗi, phân chia cho từng loại Validator, nhiệm vụ của bạn là dịch phần giá trị (sau ký hiệu =>) sang tiếng Việt.

Ví dụ

// Zend\Validator\StringLength
"Invalid type given. String expected" => "Sai kiểu. Cần nhập chuỗi",
"The input is less than %min% characters long" => "Số ký tự phải lớn hơn %min%",
"The input is more than %max% characters long" => "Số kỹ tự phải nhỏ hơn %max%",

Bước 2 - Tạo bộ dịch

Tạo ra một lớp chuyên về dịch mà các Validator sẽ dùng tới, lớp này đơn giản là kế thừa Zend\I18n\Translator\Translator và triển khai giao diện Zend\Validator\Translator\TranslatorInterface

Giả sử bộ dịch của bạn có tên là TranslateVn thì toàn bộ mã chỉ cần như sau

module/Application/src/Validator/Translate/TranslateVn.php

<?php
namespace Application\Validator\Translate;

use Zend\I18n\Translator\Translator;
use Zend\Validator\Translator\TranslatorInterface;

class TranslateVn extends Translator implements TranslatorInterface
{
    //Bạn không cần triển khai một phương thức nào
}

Bước 3 - Ứng dụng bộ dịch

Để bộ dịch hoạt động cho các Validator, tại các Action mà trước khi gọi hàm isValid của form, bạn chỉ cần thêm đoạn mã này vào:


$translator = new TranslateVn();
$translator->addTranslationFile(
    'phpArray',
    'module/Application/languages/vi/Zend_Validate.php'
);

AbstractValidator::setDefaultTranslator($translator);

Từ đây các thông báo tiếng Anh sẽ dịch sang câu mà bạn đã dịch ở file nguồn trên, ví dụ:

contact