Laravel 5.1 Modify input before form request validation

后端 未结 5 929
感情败类
感情败类 2020-12-20 21:05

Is there a way to modify input fields inside a form request class before the validation takes place?

I want to modify some input date fields as follows but it doesn

相关标签:
5条回答
  • 2020-12-20 21:29

    I took an alternative approach to this, as I want to be able to use $model->fill($validated); in my controllers. As such, I need to ensure that checkboxes have been included as false where they would otherwise be excluded from the array.

    So, I created a trait, in app\Traits\ConvertBoolean.php, as follows:

    <?php
    
    namespace App\Traits;
    
    trait ConvertBoolean
    {
        // protected $boolean_attributes = [];
    
        /**
         * Override the FormRequest prepareForValidation() method to
         * add boolean attributes specified to the request data, setting
         * their value to the presence of the data in the original request.
         *
         * @return void
         */
        protected function prepareForValidation() {
    
            if (isset($this->boolean_attributes) && is_array($this->boolean_attributes)) {
    
                $attrs_to_add = [];
    
                foreach ($this->boolean_attributes as $attribute) {
                    $attrs_to_add[$attribute] = $this->has($attribute);
                }
    
                $this->merge($attrs_to_add);
            }
        }
    }
    

    This trait looks for the existence of an array $this->boolean_attributes in the request. If it finds it, it goes through each one and adds the attribute to the request data with the value set to the presence of the attribute in the original request data.

    It disregards the value of the HTML form's checkbox value. In most cases, this won't be a problem, but you could change the logic in the trait to look for specific values, if required.

    Now that I have this trait, I can then use it in any request, like so:

    use App\Traits\ConvertBoolean;
    
    class MyUpdateRequest extends FormRequest
    {
        use ConvertBoolean;
    
        protected $boolean_attributes = ['my_checkbox'];
    
        // ... other class code
    
    
        public function rules()
        {
            // Note that the data is added to the request data,
            // so you still need a validation rule for it, in
            // order to receive it in the validated data.
            return [
                'my_checkbox' => 'boolean',
                // other rules
            ];
        }
    }
    

    If you want to use $this->prepareForValidation() in your request, this is still possible.

    Change MyRequest, as follows:

    use App\Traits\ConvertBoolean;
    
    class MyUpdateRequest extends FormRequest
    {
        use ConvertBoolean {
            prepareForValidation as traitPrepareForValidation;
        }
    
        protected function prepareForValidation() {
    
            // the stuff you want to do in MyRequest
            // ...
    
            $this->traitPrepareForValidation();
        }
    
        // ...
    }
    
    0 讨论(0)
  • 2020-12-20 21:35

    The FormRequest has a method validationData() that return the data to validate, so i'm overriding it in my form request:

    <?php
    
    namespace App\Http\Requests;
    
    use Illuminate\Foundation\Http\FormRequest;
    
    class MyClassRequest extends FormRequest
    {
        ...
        /**
         * Get data to be validated from the request.
         *
         * @return array
         */
        public function validationData() {
            return array_merge(
                $this->all(),
                [
                    'number' => preg_replace("/[^0-9]/", "", $this->number)
                ]
            );
        }
        ...
    }
    

    It work fine i'm using Laravel 5.4 :)

    0 讨论(0)
  • 2020-12-20 21:36

    Try these steps:

    1- Middleware

    first of all you should create a middleware in app/Http/Middleware:

    <?php
    
    namespace App\Http\Middleware;
    
    use Illuminate\Foundation\Http\Middleware\TransformsRequest;
    
    class DateTimeMiddleware extends TransformsRequest
    {
        protected $fields = [
            'birth_date' => 'toGregorian',
            'created_at' => 'toDateTime',
        ];
    
        protected function transform($key, $value)
        {
            if (!array_key_exists($key, $this->fields)) {
                return $value;
            }
    
            $function = $this->fields[$key];
    
            return call_user_func($function, $value);
        }
    }
    

    with this middleware you can define fields that you want to manipulate them before calling validation and call a specific function to manipulate them.

    note: i defined toGregorian and toDateTime in my own helper functions. you can handle it with your own functions

    2- Kernel

    then modify Http/Kernel.php like bellow:

    protected $middlewareGroups = [
        'web' => [
            ...
    
            \App\Http\Middleware\EnglishStrings::class,
        ],
    
        'api' => [
            ...
        ],
    ];
    
    0 讨论(0)
  • 2020-12-20 21:38

    As of laravel 5.4 you can override the prepareForValidation method of the ValidatesWhenResolvedTrait to modify any input. Something similar should be possible for laravel 5.1.

    Example in your Request

    /**
     * Modify the input values
     *
     * @return void
     */
    protected function prepareForValidation() {
    
        // get the input
        $input = array_map('trim', $this->all());
    
        // check newsletter
        if (!isset($input['newsletter'])) {
            $input['newsletter'] = false;
        }
    
        // replace old input with new input
        $this->replace($input);
    }
    
    0 讨论(0)
  • 2020-12-20 21:39

    You can do something like the following:

    public function rules(Request $request)
    {
        if ($request->has('start_dt')){
            $request->replace('start_dt', Carbon::createFromFormat('d M Y H:i:s', $request->start_dt . ' ' . $request->start_hr . ':'. $request->start_min . ':00'));
        }
    
        if ($request->has('end_dt')){
             $request->replace('end_dt' ,Carbon::createFromFormat('d M Y H:i:s', $request->end_dt . ' ' . $request->end_hr . ':'. $request->end_min . ':00'));
        }
    
        return [
            'start_dt' => 'required|date|after:yesterday',
            'end_dt' => 'required|date|after:start_dt|before:' . Carbon::parse($request->start_dt)->addDays(30)            
        ];
    }
    
    0 讨论(0)
提交回复
热议问题