Laravel validation using class - laravel

I am trying to use Laravel validation : as described here
I am not going to place entire rule class, as it is straight from artisan make:rule.
PROBLEM:
When I try to test 'false' here:
function passes($attribute, $value)
{
return false; //testing 'false' logs me out
}
This is how I use it in controller:
$this->validate($request, [
'image_64' => ['required', new \App\Rules\Base64Rule]
]);
It is like redirect isn't going to form page, but index page - which in my case logs user out (among other things).
Is there any protected var to mark proper redirect route, when method 'passes' returns false?
Anyone came across something like this?
EDIT
Sam,
As I mentioned, rule class is pristine - freshly generated:
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class Base64Rule implements Rule
{
/**
* Create a new rule instance.
*
* #return void
*/
public function __construct()
{
}
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
return false;
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'The validation error message.';
}
}
If I run on top of my controller anything like:
use App\Rules\Base64Rule;
$rule = new Base64Rule;
dd($rule->passes('image_64', 'udfshjbfisuusoshgosghosh'));
I get whatever I have in rule's method passes().
If I use in rule's method passes() return true; it works right.
If I use in rule's method passes() dd('some'), I get 'some' in that controller test.
When test is 'false' and regular validation code is used:
use App\Rules\Base64Rule;
$this->validate($request, [
'image_64' => ['required', new Base64Rule]
]);
... I get redirected to index page.
I have to follow request/response and see, where Laravel fails and why ... I guess. And is it my code, or a bug.

Related

Laravel API REST for index() returns a json html string to the home page

I'm using Laravel api with a resource controller.
My api route
Route::apiResource('todos', TodoController::class)->middleware('auth:api');
Controller
public function index(TodoRequest $request): JsonResponse
{
$response = new Response();
// $withDeleted = $request->has('withDeleted') ? true : false;
$todos = $this->todoService->getAllTodosWithLists($request->query('withDeleted'));
$response->setMessage(ServerMessages::TODOS_RETRIEVE_SUCCESS);
return response()->json(
$response->build($todos),
$response->getCode($todos)
);
}
class TodoRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
* Must match with FrontEnd fields
*
* #return array
*/
public function rules(): array
{
return [
'content' => 'required'
];
}
/**
* Get custom messages for validator errors.
*
* #return array
*/
public function messages(): array
{
return ['required' => 'The :attribute must not be left blanked.'];
}
}
My problem is everytime I add the TodoRequest in my parameter's it always return a response redirecting back to the default Laravel homepage.
Note: I am passing a query parameter inside my $request i.e withDeleted and probably will add more filters. This app was originally made in Lumen which perfectly well, and I did some migration to the latest Laravel 9 framework.

Laravel conditional validation rule for array items

I have the following working validation rule which checks to make sure each recipient,cc,bcc list of emails contain valid email addresses:
return [
'recipients.*' => 'email',
'cc.*' => 'email',
'bcc.*' => 'email',
];
I need to also be able to allow the string ###EMAIL### as well as email validation for each of these rules and struggling to create a custom validation rule in Laravel 5.8 (it can't be upgraded at this time).
Any idea how to go about this? If it were a higher version of Laravel I was thinking something like (not tested) to give you an idea of what I'm trying to do:
return [
'recipients.*' => 'exclude_if:recipients.*,###EMAIL###|email',
'cc.*' => 'exclude_if:recipients.*,###EMAIL###|email',
'bcc.*' => 'exclude_if:recipients.*,###EMAIL###|email',
];
In 5.8 you can create Custom Rule Object Let's see how we can actually make it work.
Create your rule with php artisan make:rule EmailRule
Make it to look like this
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class EmailRule implements Rule
{
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
if ($value === '###EMAIL###' or filter_var($value, FILTER_VALIDATE_EMAIL)) {
return true;
}
return false;
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'The :attribute must be valid email or ###EMAIL###.';
}
}
Include in your rules so it looks like
return [
'recipients.*' => [new EmailRule()],
'cc.*' => [new EmailRule()],
'bcc.*' => [new EmailRule()],
];
Write a test (optional)

How to validate images array type using rule object with custom message in Laravel

Actually, I tried to create rule object which is able to validate every image type in array of images and not only enough but also, I must to show custom message in override message function in rule object.
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class ImagesArray implements Rule
{
/**
* Create a new rule instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
return [$attribute => 'mimes:jpeg,jpg,png' ];
here i need to validate these file types.
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'The validation error message.';
here, I need to show my custom messgae.
}
}
You should use Request.
For example, create q request class: php artisan make:request MyRequest.
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class MyRequest extends FormRequest
{
/**
* 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 [
'image' => 'mimes:jpeg,jpg,png',
];
}
public function messages()
{
return [
'image.mimes' => 'This image is not supported.',
];
}
}
In your controller import class MyRequest and in the method use MyRequest
e.g:
public function store(MyRequest $request)
{ // your code
}
Let me know if that was helpful. Thanks!
When validating arrays or nested parameters, you should use . in your rules access a specific array index. but if you want to apply a rule to every index on that array, you can use .*.
$validator = Validator::make($request->all(), [
'image.*' => 'mimes:jpeg,jpg,png',
], [
'image.*' => 'Invalid file type.',
]);
Or if you're using Request Forms
public function rules(){
return [
'image.*' => 'mimes:jpeg,jpg,png',
];
}
public function mesages(){
return [
'image.*' => 'Invalid file type.',
];
}
For more info, see Laravel's Documentation on Validation Arrays

My controller is ignoring my custom validation rule

I need a custom validation rule for my application. As a proof of concept I created a simple validation rule. For testing purposes, the passes method returns false. I added the validation to my controller, but even though the validator returns false, the controller proceeds as though the validation succeeded. I used the debugger to confirm that the passes method is indeed being hit and is returning false.
Why am I doing wrong?
Here's my rule class:
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class UniqueAgent implements Rule
{
protected $id;
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #param mixed $id
*/
public function setId($id): void
{
$this->id = $id;
}
/**
* UniqueAgent constructor.
*/
public function __construct($id)
{
$this->setId($id);
}
public function passes($attribute, $value)
{
// TODO: Implement passes() method.
return false;
}
public function message()
{
// TODO: Implement message() method.
}
}
Here's the controller code:
public function update(Request $request, $id)
{
// UniqueAgent rule returns 'false'
$validateData = $request->validate([
'agency' => [
'required',
new UniqueAgent($id)
]
]);
$agent = Agent::findOrFail($id)
$agent->agency = $request->input('agency');
$agent->save();
}
Thanks
Problem solved. For anyone interested, I hadn't added a return value to the message method of the UniqueAgent class. I added a return "some string" and now the controller redirects the client to view and displays the error message.
In my opinion, this is a poor design. If not returning a message string causes the class not to perform as intended, it shouldn't just fail quietly. In my opinion, it would be better for if the controller simply did what it does when the validation fails (i.e., redirects to the view), with or without an error message.

validation failure but already redirect into controller laravel

I try to validate input, but when input incorrect not show error and redirect to another url.My code is something like this:
$rules = [
'point' => 'required|numeric|min:0|max:10',
'id_tieuchi' => 'required|numeric|min:1'
];
and
foreach ($data as $value)
{
$validator = Validator::make( $value, $rules);
}
I also using syntax into foreach but not working because controller not understand what's user in base url ../evaluate/$user/edit:
if ($validator->fails())
return redirect('evaluate/{user}/edit')->withInput()->with('message',$validator->messages()->all());
Laravel comes with Requests that will handle this logic for you. You can leverage them like so:
In App\Http\Requests, create a FooRequest.php and add this code to it:
<?php
namespace App\Http\Requests;
class FooRequest extends Request
{
/**
* 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 [
'point' => 'required|numeric|min:0|max:10',
'id_tieuchi' => 'required|numeric|min:1'
];
}
}
And in your FooController.php, be sure to add this to the top of the file:
use App\Http\Requests\FooRequest;
Then in your controller method, use the FooRequest as such:
public function bar(FooRequest $request)
{
// Do stuff here...
}
The FooRequest will validate whatever input you send to the bar method. If validation errors exist, it will automatically redirect back to whatever page you came from with the errors in the validator. If validation passes, it will enter the bar method with the items in the request in $request.
For more information, read about validation in Laravel.

Resources