Wiki

Clone wiki

suitcms / BaseForm

Back To Home

BaseForm (App\Http\Form\Admin\BaseForm)

Note: This class is different from Laravel Form Request

The goal of this class is to validate and filter user's post request. You must keep this statement, "User's Input cannot be trusted", on your mind. To accomplish that, application must filter and validate user's input so that user's input are ready to be consumed by application.

This class capable of doing these task easly by overiding some method:

  1. Flexible rules.
  2. Changed attributes name and error messages.
  3. Alter user input before being validated, such as trim, change to boolean, etc.
  4. Alter user input after being validated for being used outside of the class.

Defining Rules

To define rules you need to implements rules(). Here are the simple implementation of menu form.

#!php
<?php

    protected $parentList = [];

    protected function rules()
    {
        $rules = [
            'title' => 'required',
            'order' => 'required|integer',
            'is_link' => 'required|in:0,1',
            'url' => 'required|max:255',
            'parent_id' => 'in:'.$this->implode('parentList'),
            'description' => ''
        ];

        return $rules;
    }
?>

From above code, the form will receive six input from user. Input title, order, is_link, and url are required. For parent_id it called implode() method. This method used to implode array into string with coma-separated used for validation. Now the question is when was the parentList being assinged. The answer is on The Controller. It being assigned on the controller because the controller who passes all possibility to the view and maybe has some complecated logic which is depend on user request parameter. For description there is no rules and must be defined with empty string because BaseForm only process input which has beed defined on rules.

Here is the other example for more complex rules. In this case is, there is slug field which is must be unique And this class is being used on Create form and edit form. To differ between create and edit, controller must pass an attribute to this object, in this case pageId. I'm suggest there is no query operation on baseForm to reduce complexity. In this case also has array rules (categories), The base for validation is we must added rule for each element on it. we must iterate user input. And don't forget to check if user's input is array or not because at this stage form hasn't ensured it.

#!php
<?php
    protected function rules()
    {
        $rules = [
            'title' => 'required',
            'parent_id' => 'in:'.$this->implode('parentList'),
            'user_id' => 'required|in:'.$this->implode('authorList'),
            'categories' => 'array',
            'description' => 'required',
            'url_prefix' => '',
            'body' => 'required',
            'tags' => '',
            'slug' => 'alpha_dash|unique:pages,slug',
            'published' => 'required|in:0,1',
            'layout' => 'required|in:'.$this->implode('layoutList')
        ];

        if (!is_null($this->pageId)) {
            $rules['slug'] .= ','.$this->pageId;
            $rules['slug'] .= '|required';
        }

        if (is_array($this->request->input('categories'))) {
            foreach ($this->request->input('categories') as $key => $categoryId) {
                $rules["categories.$key"] = 'in:'.$this->implode('categoryList');
            }
        }
        return $rules;
    }
?>

Additional function to generate rules:

#!php
<?php
    protected function rules()
    {
        $rules = [
            'attachments' => array
        ];

        $rules = $this->arrayRules('attachments', [
            'name' => 'required',
            'file' => 'required'
        ]);
    }
?>

Filtering

Here is the second thing must be done if application face input from users. The most common is trimming user input. To accomplish this you must override preProcessInput() method. This method is being called right before user's input being validated. Here is the example of this method using the same case on the second example.

#!php
<?php
    protected function preProcessInput()
    {
        parent::preProcessInput();

        $this->filterInput('trim', ['title', 'body', 'description', 'slug']);
        $this->filterInput('strtolower', ['slug', 'tags']);
    }
?>

There are two filter being done on this method. They are trimming and lower case some input. If you want to modified user's input right after being validate you can override postProcessInput().

Next: Resource Controller

Updated