Custom placeholders for custom validation rules in Laravel 5

I created a custom validation rule set in my Laravel application. First, I created the validators.php file, which is located in the App\Http directory:

 /** * Require a certain number of parameters to be present. * * @param int $count * @param array $parameters * @param string $rule * @return void * @throws \InvalidArgumentException */ function requireParameterCount($count, $parameters, $rule) { if (count($parameters) < $count): throw new InvalidArgumentException("Validation rule $rule requires at least $count parameters."); endif; } /** * Validate the width of an image is less than the maximum value. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ $validator->extend('image_width_max', function ($attribute, $value, $parameters) { requireParameterCount(1, $parameters, 'image_width_max'); list($width, $height) = getimagesize($value); if ($width >= $parameters[0]): return false; endif; return true; }); 

Then I add, including this to my AppServiceProvider.php file (as well as adding use Illuminate\Validation\Factory; at the top of this file):

 public function boot(Factory $validator) { require_once app_path('Http/validators.php'); } 

Then, in my form request file, I can invoke a custom validation rule, for example:

 $rules = [ 'image' => 'required|image|image_width:50,800', ]; 

Then, in the Laravel validation.php file located in the resources/lang/en directory, I add another key / value to the array to display an error message if the check returns false and fails, for example:

 'image_width' => 'The :attribute width must be between :min and :max pixels.', 

Everything works fine, it checks the image correctly, displays an error message if it fails, but I'm not sure how to replace :min and :max values โ€‹โ€‹declared in the form request file (50,800), in the same way :attribute is replaced with the name form fields. Therefore, it currently displays:

The image width must be between :min and :max pixels.

While I want it to display as follows

The image width must be between 50 and 800 pixels.

I saw some replace* functions in the main Validator.php file (vendor/laravel/framework/src/Illumiate/Validation/) , but I cannot figure out how to make it work with my own validation rule.

+5
source share
3 answers

I haven't used it that way, but you can probably use:

 $validator->replacer('image_width_max', function ($message, $attribute, $rule, $parameters) { return str_replace([':min', ':max'], [$parameters[0], $parameters[1]], $message); }); 
+9
source

Here is the solution I used:

In composer.json:

 "autoload": { "classmap": [ "app/Validators" ], 

In app / providers / AppServiceProvider.php:

 public function boot() { $this->app->validator->resolver( function ($translator, $data, $rules, $messages) { return new CustomValidator($translator, $data, $rules, $messages); }); } 

In the app /Validators/CustomValidator.php

 namespace App\Validators; use Illuminate\Support\Facades\DB; use Illuminate\Validation\Validator as Validator; class CustomValidator extends Validator { // This is my custom validator to check unique with public function validateUniqueWith($attribute, $value, $parameters) { $this->requireParameterCount(4, $parameters, 'unique_with'); $parameters = array_map('trim', $parameters); $parameters[1] = strtolower($parameters[1] == '' ? $attribute : $parameters[1]); list($table, $column, $withColumn, $withValue) = $parameters; return DB::table($table)->where($column, '=', $value)->where($withColumn, '=', $withValue)->count() == 0; } // All you have to do is create this function changing // 'validate' to 'replace' in the function name protected function replaceUniqueWith($message, $attribute, $rule, $parameters) { return str_replace([':name'], $parameters[4], $message); } } 

: the name is replaced with $ parameters [4] in this replaceUniqueWith function

In the app /resources/lang/en/validation.php

 <?php return [ 'unique_with' => 'The :attribute has already been taken in the :name.', ]; 

In my controller, I invoke this validator as follows:

 $organizationId = session('organization')['id']; $this->validate($request, [ 'product_short_title' => "uniqueWith:products,short_title, organization_id,$organizationId, Organization", ]); 

This is how it looks in my form :)

enter image description here

+1
source

I use something similar in Laravel 5.4:

AppServiceProvider.php

 public function boot() { \Validator::extend('contains_field', 'App\Validators\ ContainsFieldValidator@validate '); \Validator::replacer('contains_field', 'App\Validators\ ContainsFieldValidator@replace '); } 

App \ Validators \ ContainsFieldValidator.php

 class ContainsFieldValidator { public function validate($attribute, $value, $parameters, Validator $validator) { $required = $parameters[0]; $requiredDefault = isset($parameters[1]) ?: null; if (!$required && !$requiredDefault) { return false; } $requiredValue = isset($validator->attributes()[$required]) ? $validator->attributes()[$required] : $requiredDefault; return !(strpos($value, $requiredValue) === false); } public function replace($message, $attribute, $rule, $parameters) { return str_replace([':required'], str_replace('_', ' ', $parameters[0]), $message); } } 
0
source

Source: https://habr.com/ru/post/1216376/


All Articles