shigg
shigg

Reputation: 802

Laravel validation modify request before validation. return original if failed

I have a WYSIWYG editor. When users keep pressing space in the editor, the input will be like this.

"<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</p>"

To prevent this I modified the all method in Request class like this to remove whitespace and tags.

public function all()
{
    $input = parent::all();

    $input['body'] = strip_tags(preg_replace('/\s+/', '', str_replace('&nbsp;',"", $input['body'])));
    //modify input here

    return $input;
}

This works great.

However, the problem here is if other validation rules fail, the return value from old helper function is modified by the method.

So, if the original input is like this

"""
<p>&nbsp;<iframe src="//www.youtube.com/embed/Mb5xcH9PcI0" width="560" height="314" allowfullscreen="allowfullscreen"></iframe></p>\r\n
<p>This is the body.</p>
"""

And if other validation rules fail I get this as an old input.

"Thisisthebody."

So, is there any way to get original request inputs as an old input when validations failed?

Here is my form request.

<?php

namespace App\Http\Requests;

use App\Http\Requests\Request;
use Illuminate\Validation\Factory as ValidationFactory;

class ArticleRequest extends Request
{

public function all()
{
    $input = parent::all();

    $input['body'] = strip_tags(preg_replace('/\s+/', '', str_replace('&nbsp;',"", $input['body'])));
    //modify input here

    return $input;
}

/**
 * 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 [
        'title' => 'required|min:3|max:40',
        'tags.*' => 'required',
        'body'  => 'required|min:50',
        //up to 6mb
        'thumbnail'=>'image|file|max:10240'
    ];
}

public function messages()
{
   return [
        'title.required'  => 'タイトルを入力してください',
        'title.min'  => 'タイトルは3文字以上でお願いします',
        'title.max'  => 'タイトルは40文字以下でお願いします',
        'body.min'  => '本文は50文字以上お書きください',
        'body.required'  => '本文を入力してください',
        'tags.*.required'  => 'タグを選んでください',
        'thumbnail.image'  => '画像の形式はjpeg, bmp, png, svgのいずれかをアップロードできます',
        'thumbnail.file'  => 'フォームから画像をもう一度アップロードしてください',
        'thumbnail.max'  => 'ファイルは10MBまでアップロードできます',
   ];
}
}

Upvotes: 4

Views: 1960

Answers (1)

Unamata Sanatarai
Unamata Sanatarai

Reputation: 6647

Create a custom validator which strips the tags, counts characters but does not modify the content itself.

Validator::extend('strip_min', function ($attribute, $value, $parameters, $validator) {

    $validator->addReplacer('strip_min', function($message, $attribute, $rule, $parameters){
        return str_replace([':min'], $parameters, $message);
    });

    return strlen(
        strip_tags(
            preg_replace(
                '/\s+/', 
                '', 
                str_replace('&nbsp;',"", $value)
            )
        )
    ) >= $parameters[0];
});

and in your validation.php lang file add:

'strip_min' => 'The :attribute must be at least :strip_min characters.'   

source: https://stackoverflow.com/a/33414725/2119863

Upvotes: 0

Related Questions