Fred Moras
Fred Moras

Reputation: 29

Laravel form request passedValidation() and $request->validated()

I 'm trying to implement a cast method in a formRequest just after validation, using passedValidation() function.

Everything looks good but the cast made in passedValidation() don't appear in $request->validated(), but is visible in $request->all().

My form request

<?php
    
    namespace App\Http\Requests\Models\Company;
    
    use App\Http\Requests\CustomFormRequest;
    use Illuminate\Support\Facades\Auth;
    use Propaganistas\LaravelPhone\PhoneNumber;
    

    class CompanyFormRequest extends CustomFormRequest
    {
 
        protected function prepareForValidation()
        {
            $this->merge([
                             'is_presting' => !$this->missing('is_presting') 
                                             && $this->input('is_presting'),
                         ]);
        }
    
        public function rules () : array
        {
           
            
            return [
                'name' => [ 'required' , 'string' ] ,
                'street' => [ 'string' , 'nullable' ] ,
                'city' => [ 'string' , 'nullable' ] ,
                'post_code' => [ 'string' , 'nullable' ] ,
                'TVA' => [ 'string' , 'nullable' ] ,
                'language' => [ 'required' , 'string' ] ,
                'bank' => [ 'string' , 'nullable' ] ,
                'email' => [ 'string' , 'email' , 'nullable' ] ,
                'website' => [ 'string' , 'url' , 'nullable' ] ,
                'latitude' => [ 'numeric' , 'nullable' ] ,
                'longitude' => [ 'numeric' , 'nullable' ] ,
                'reference' => [ 'string' , 'nullable' ] ,
                'is_presting' => [ 'boolean' ] ,
                'phone_country' => [ 'required_with:phone_field' , 'string' ] ,
                'phone_field' => [ 'required_with:phone_country' , 'phone:'.$this->input('phone_country') ] ,
            
            ];
        }
        
        public function authorize () : bool
        {
            return app () -> runningInConsole () 
                || ( Auth ::check () && Auth ::user () -> can ( 'manage_content' ) );
        }
    
        protected function passedValidation ()
        {
           $this->merge( [
                             'phone_field' => 
                                 (string) PhoneNumber ::make ( $this -> input ( 'phone_field' ) , 
                                                               $this -> input ( 'phone_country' ) )
                         ]);
        }
    
    }

$request->all() before validation

array:16 [▼
  "name" => "De Greef SCA"
  "street" => "chemin Gérard 527"
  "city" => "Tournai"
  "post_code" => "6485"
  "TVA" => "BE0958232035"
  "language" => "fr_FR"
  "bank" => "BE96227410211607"
  "phone_field" => "0471321102"
  "phone_country" => "BE"
  "email" => "[email protected]"
  "website" => "http://devos.org/ab-et-itaque-a.html"
  "latitude" => -64.420589
  "longitude" => 65.667543
  "reference" => "OMZ"
  "active" => true
  "is_presting" => true
]

$request->validated() after validation

array:16 [▼
  "name" => "De Greef SCA"
  "street" => "chemin Gérard 527"
  "city" => "Tournai"
  "post_code" => "6485"
  "TVA" => "BE0958232035"
  "language" => "fr_FR"
  "bank" => "BE96227410211607"
  "phone_field" => "0471321102"
  "phone_country" => "BE"
  "email" => "[email protected]"
  "website" => "http://devos.org/ab-et-itaque-a.html"
  "latitude" => -64.420589
  "longitude" => 65.667543
  "reference" => "OMZ"
  "active" => true
  "is_presting" => true
]

$request->all() after validation

array:16 [▼
  "name" => "De Greef SCA"
  "street" => "chemin Gérard 527"
  "city" => "Tournai"
  "post_code" => "6485"
  "TVA" => "BE0958232035"
  "language" => "fr_FR"
  "bank" => "BE96227410211607"
  "phone_field" => "+32471321102"
  "phone_country" => "BE"
  "email" => "[email protected]"
  "website" => "http://devos.org/ab-et-itaque-a.html"
  "latitude" => -64.420589
  "longitude" => 65.667543
  "reference" => "OMZ"
  "active" => true
  "is_presting" => true
]

We see in $request->all() after the validation that the cast is well executed on 'phone_field' but why doesn't it appear in $request->validated() ???

thanks.

Upvotes: 2

Views: 7173

Answers (2)

Donkarnash
Donkarnash

Reputation: 12845

Guess you probably need to merge with the validated data. If you are on recent version of Laravel you can use the safe() method

$validated = $request->safe()->merge([
    'phone_field' => (string) PhoneNumber::make ( 
        $this->input('phone_field'), $this->input('phone_country') 
    )
)];

If you want the FormRequest class to encapsulate the merging, you can define a custom method say validatedWithCasts and then use this method in the controller or where ever else


class CompanyFormRequest extends CustomFormRequest
{
 
    // ...other methods and rules
    
    public function validatedWithCasts ()
    {
        return $this->safe()->merge([
            'phone_field' => (string) PhoneNumber::make ( 
                $this->input('phone_field'), $this->input('phone_country') 
            )

        ]);
    }
    
}

Then in controller you can use it like

$request->validatedWithCasts();

Upvotes: 0

yahyaman
yahyaman

Reputation: 496

It is because $request->all() & $request->validated() have different implementation on different classes. You can see it in FormRequest source code. In short:

  • $request->all() take input in the $request as it present on function call
  • on the other hand, $request->validated() was actually calling validated() function on underlying Validator object. If you trace it, all the inputs was passed when FormRequest was creating Validator object. Hence, anything you do with $request input in passedValidation() did not affect input that was already passed to Validator object.

I hope my explanation is understandable.

Upvotes: 1

Related Questions