Validator Does Not Show Errors At Blade - php

I have a Controller method like this:
use Validator;
public function insert(Request $request)
{
$data = Validator::make(request()->all(),[
'title' => 'required',
'name' => 'required|alpha_num',
'activation' => 'nullable',
'cachable' => 'nullable'
])->validated();
$wallet = new Wallet();
$wallet->title = $data['title'];
$wallet->name = $data['name'];
if (!empty($data['activation'])) {
$wallet->is_active = 1;
} else {
$wallet->is_active = 0;
}
if (!empty($data['cachable'])) {
$wallet->is_cachable = 1;
} else {
$wallet->is_cachable = 0;
}
$wallet->save();
return redirect(url('admin/wallets/index'));
}
And then I tried showing errors like this:
#error("name")
<div class="alert alert-danger">{{$message}}</div>
#enderror
But the problem is, it does not print any error when I fill the form incorrectly.
So how to fix this and show errors properly?
Here is the form itself, however it submits data to the DB correctly:
<form action="{{ route('insertWallet') }}" method="POST" enctype="multipart/form-data">
#csrf
<label for="title" class="control-label">Title</label>
<br>
<input type="text" id="title-shop" name="title" class="form-control" value="" autofocus>
#error("title")
<div class="alert alert-danger">{{$message}}</div>
#enderror
<label for="title" class="control-label">Name</label>
<br>
<input type="text" id="title-shop" name="name" class="form-control" value="" autofocus>
#error("name")
<div class="alert alert-danger">{{$message}}</div>
#enderror
<input class="form-check-input" type="checkbox" name="cachable" value="cashable" id="cacheStatus">
<label class="form-check-label" for="cacheStatus">
With Cash
</label>
<input class="form-check-input" type="checkbox" name="activaton" value="active" id="activationStatus">
<label class="form-check-label" for="activationStatus">
Be Active
</label>
<button class="btn btn-success">Submit</button>
</form>

check the official documentation here
add the following code
if($data->fails()){
return redirect(url('admin/wallets/index'))->withErrors($data)->withInput();
}
And after that save your data in your database

You are not returning any errors, you are just redirecting back to the view without any data.
Your fix would be to have your validator as this:
$data = Validator::validate(request()->all(),[
'title' => 'required',
'name' => 'required|alpha_num',
'activation' => 'nullable',
'cachable' => 'nullable'
]);
See that I have changed Validator::make to Validator::validate. As the documentation states:
If the validation rules pass, your code will keep executing normally; however, if validation fails, an exception will be thrown and the proper error response will automatically be sent back to the user.
If validation fails during a traditional HTTP request, a redirect response to the previous URL will be generated. If the incoming request is an XHR request, a JSON response containing the validation error messages will be returned.
So, if your validation passes, it will save all the validated data into $data, as you did with ->validated() (but you don't have to write it here), and if it fails, it will automatically throw an Exception, in this case ValidationException, so Laravel will automatically handle it and redirect back with to the same URL and with the errors. So it now should work...
This is the Validator::validate source code and this is the validate source code for the validator validate method.

Related

When Use PUT or PATCH For Updating Data

I want to edit some information which is retrieved from the DB, at the edit.blade.php:
<form action="{{ route('updateWallet', ['id'=>$wallet->id]) }}" method="POST" enctype="multipart/form-data">
#csrf
<label for="title" class="control-label">Title</label>
<input type="text" id="title-shop" name="title" class="form-control" value="{{ $wallet->title }}" autofocus>
<input class="form-check-input" type="checkbox" name="cachable" value="cashable" id="cacheStatus" #php if(($wallet->is_cachable) == 1) {echo 'checked';} #endphp>
<label class="form-check-label" for="cacheStatus">
With Cash
</label>
<input class="form-check-input" type="checkbox" name="activaton" value="active" id="activationStatus" #php if(($wallet->is_active) == 1) {echo 'checked';} #endphp>
<label class="form-check-label" for="activationStatus">
Active
</label>
<button class="btn btn-success">Submit</button>
</form>
And the route for this goes here:
Route::post('wallets/update/{wallet}','Wallet\WalletController#update')->name('updateWallet');
Then at the Controller:
public function update(Request $request, Wallet $wallet)
{
try {
$data = $request->validate([
'title' => 'required',
'activation' => 'nullable',
'cachable' => 'nullable'
]);
$wallet->title = $data['title'];
if (!empty($data['activation'])) {
$wallet->is_active = 1;
} else {
$wallet->is_active = 0;
}
if (!empty($data['cachable'])) {
$wallet->is_cachable = 1;
} else {
$wallet->is_cachable = 0;
}
$wallet->save();
flash()->overlay('Updated!', 'Your data edited successfully.', 'success');
}catch (\Exception $e) {
dd($e);
}
return redirect(url('admin/wallets/index'));
}
It works fine and perfect since I'm not adding any method name in the blade.
But when I try this, I get this error:
The PUT method is not supported for this route. Supported methods: POST.
And also when I add method('PATCH') instead of method('PUT'), I get this:
The PATCH method is not supported for this route. Supported methods: POST.
So what is going wrong here?
When is the proper time for using PUT and PATCH methods and how to properly use them?
it's standard to use post request when we are storing something for the first time and put/patch request when we are updating something. you can use post request in both though.
but html form method accepts either get or post request. you can't use put/patch/delete on form method attribute. we use method spoofing to use those request with form using method('PUT') which creates a new input field.
<input type="hidden" name="_method" value="PUT">
this determines the form request type. but for this to work your form submit url needs to be declared as a put route (patch if you want to use patch request)
Route::put('wallets/update/{wallet}','Wallet\WalletController#update')->name('updateWallet');
changing method in form won't change your defined route type. you have to change it yourself. you have to determine which type of request you will use and both form and route have to use the same type of request.
When you change method in form at blade file, You must to change method in route file:
Route::put('wallets/update/{wallet}','Wallet\WalletController#update')->name('updateWallet');
And change method put in form:
<form>
{{ method_field('PUT') }}
</form>

Unable to preserve input values after form validation Codeigniter 4

This is a question I have seen asked before but I have been unable to find an answer for the newer version of Codeigniter.
Controller
<?php
namespace App\Controllers;
class SendEmail extends BaseController
{
public function index($validation = NULL){
// Load form helper
helper('form');
// Instantiate session
$session = \Config\Services::session();
// Set css, javascript, and flashdata
$data = [
'css' => array('contact.css'),
'js' => array('contact.js'),
'validation' => $validation,
'success' => $session->get('success')
];
// Show views
echo view('templates/header', $data);
echo view('contact', $data);
echo view('templates/footer', $data);
}
public function sendEmail(){
// Instantiate request
$request = $this->request;
// Captcha API
$captchaUser = $request->getPost('g-recaptcha-response');
// Captcha Key loaded from a file left out of the repo
$captchaConfig = config('Config\\Credentials');
$captchaKey = $captchaConfig->captchaKey;
$captchaOptions = [
'secret' => $captchaKey,
'response' => $captchaUser
];
$client = \Config\Services::curlrequest();
$captchaResponse = $client->request('POST', 'https://www.google.com/recaptcha/api/siteverify', ['form_params' => $captchaOptions]);
$captchaObj = json_decode($captchaResponse->getBody());
// Load validation library
$validation = \Config\Services::validation();
// Set validation rules
$validation->setRules([
'name' => 'required|alpha_dash|alpha_space',
'email' => 'required|valid_email',
'subject' => 'required|alpha_numeric_punct',
'message' => 'required|alpha_numeric_punct'
]);
// Validate inputs
if (!$this->validate($validation->getRules())){
// Run index function to show the contact page again
$this->index($this->validator);
}
// Validate captcha
elseif(!$validation->check($captchaObj->success, 'required')){
$validation->setError('captcha','Did not pass captcha. Please try again.');
$this->index($validation->getErrors());
}
else{
// Set variables to input
$name = $request->getPost('name');
$email = $request->getPost('email');
$subject = $request->getPost('subject');
$message = $request->getPost('message');
// Load email class
$emailC = \Config\Services::email();
// Set email settings
$emailC->setFrom('bensirpent07#benkuhman.com', $name);
$emailC->setReplyTo($email);
$emailC->setTo('benkuhman#gmail.com');
$emailC->setSubject($subject);
$emailC->setMessage($message);
// Testing section
echo '<br>'.$name.'<br>'.$email.'<br>'.$subject.'<br>'.$message;
/* Temporarily disabled for testing purposes
// Send email
if($emailC->send(false)){
// Redirect
return redirect()->to(base_url().'/contact')->with('success', true);
}else{
// Display error
throw new \CodeIgniter\Database\Exceptions\DatabaseException();
};
*/
}
}
}
Contact View
<div class="container">
<div class="row">
<div class="col">
<div class="alert alert-success align-center" id="message-alert" <?php if($success){echo 'style="display:block"';} ?>>Message successfully sent!</div>
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6">
<?php echo form_open('send_email', ['id'=>'contactForm'])?>
<div class="form-group">
<label for="name">Name</label>
<input name="name" type="text" class="form-control" id="name" aria-describedby="name" placeholder="Name" required>
<p class="invalid"><?php if(isset($validation)&&$validation->hasError('name')){echo $validation->getError('name');}?></p>
</div>
<div class="form-group">
<label for="email">E-Mail</label>
<input name="email" type="email" class="form-control" id="email" aria-describedby="email" placeholder="E-mail" required>
<small id="emailHelp" class="form-text">I'll never share your email with anyone else.</small>
<?php //echo $validation->email;?>
<p class="invalid"><?php if(isset($validation)&&$validation->hasError('email')){echo $validation->getError('email');}?></p>
</div>
<div class="form-group">
<label for="subject">Subject</label>
<input name="subject" type="text" class="form-control" id="subject" placeholder="Subject" required>
<p class="invalid"><?php if(isset($validation)&&$validation->hasError('subject')){echo $validation->getError('subject');}?></p>
</div>
<div class="form-group">
<label for="message">Message</label>
<textarea name="message" rows="5" class="form-control" id="message" placeholder="Type your message here." required></textarea>
<p class="invalid"><?php if(isset($validation)&&$validation->hasError('message')){echo $validation->getError('message');}?></p>
</div>
<button id="submitButton" type="submit" class="btn btn-primary g-recaptcha" data-sitekey="6Ldf07AZAAAAAAflQCaJcWgGFCWevCswpIrm0mJN" data-callback='onSubmit' data-action='submit'>Submit</button>
<p class="invalid"><?php if(isset($validation)&&$validation->hasError('captcha')){echo $validation->getError('captcha');}?></p>
<?php echo form_close()?>
</div>
</div>
</div>
<script>
function onSubmit(token) {
document.getElementById("contactForm").submit();
}
</script>
<script src="https://www.google.com/recaptcha/api.js"></script>
From my understanding of the way validation used to work in CodeIgniter, is that when you loaded your view after a form validation it would update the values with what was previously entered. This does not seem to be the case for CodeIgniter 4. I've also tried directly loading the views rather than calling the index function on validation fail. Still would not fill in the form values.
Now I could just pass these values to the index function via $data array. Which is the fix I'm going to use for now. This is more so a sanity check to see if there is something basic I'm missing or if I'm incorrectly using the validation format for CodeIgniter 4.
in CI4 you can use old() function to preserve the input value upon form validation:
View file:
<input type="tel" name="phone" value="<?= old('phone'); ?>">
In Controller you must use withInput() in the redirect() code:
$validation = \Config\Services::validation();
$request = \Config\Services::request();
// your input validation rules
$validation->setRules(...)
if($request->getMethod() == "post" && ! $validation->withRequest($request)->run()) {
return redirect()->back()->withInput()->with('error', $this->validation->getErrors());
} else {
// form validation success
}

validator not working with input type date in Laravel

I am a newbe of Laravel 6. I made an app to create meetings.
The user creates a meeting by a form with many inputs and in the controller there is a validator that checks if the inputs are filled in.
Every field works well with the validator except for the two inputs type time ("start" and "end").
When I submit the form and I let one of those fields blank the validator doesn't work correctly because it appears an exception message:
InvalidArgumentException Illegal operator and value combination.
Furthermore in the tools for developers appears the following error:
Failed to load resource: the server responded with a status of 500 (Internal Server Error)
I tried changing required with required|date_format:H:i for both fields but it didn't work as well.
I tried even removing CheckTime that is a custom rule that checks if the end of the meeting be after the beginning but I failed.
input "start"
<label for="start" class="col-sm-2">Start Hour:</label>
#if (old('start') !== null)
<input type="time" class="form-control col-sm-6" id="start" name="start" value="{{ old('start') }}">
#elseif (isset($id))
<input type="time" class="form-control col-sm-6" id="start" name="start" value="{{ $meeting->start_hour }}">
#else
<input type="time" class="form-control col-sm-6" value = "{{ old('start') }}" id="start" name="start">
#endif
input "end"
<label for="end" class="col-sm-2">End Hour:</label>
#if (old('end') !== null)
<input type="time" class="form-control col-sm-6" id="end" name="end" value="{{ old('end') }}">
#elseif (isset($id))
<input type="time" class="form-control col-sm-6" id="end" name="end" value="{{ $meeting->end_hour }}">
#else
<input type="time" class="form-control col-sm-6" value = "{{ old('end') }}" id="end" name="end">
#endif
validator:
public function insert_meeting(Request $request)
{
$this->validate($request, [
'participants' => [ 'required', new CheckParticipantInsert() ],
'description' => 'required',
'room' => [ 'required', new CheckRoomInsert() ],
'date_meeting' => [ 'required', new CheckDateTime() ],
'start' => [ 'required', new CheckTime() ],
'end' => 'required',
]);
$participants_mail = $this->convertIdToName(request('participants'));
$mail_response = $this->send_mail_create($request, $participants_mail);
$meeting = new Meeting();
$participants = request('participants');
$meeting->id_participants = implode(';', $participants);
$meeting->description = request('description');
$meeting->id_room = request('room');
$meeting->date = request('date_meeting');
$meeting->start_hour = request('start');
$meeting->end_hour = request('end');
$meeting->save();
if($mail_response) {
$message_correct = "The meeting has been correctly inserted. The emails to advise the participants have been sent.";
return redirect()->route('home')->with('success', $message_correct);
} else {
$message_correct = "The meeting has been correctly inserted.";
$mail_not_sent = "The emails to advise the participants could not be sent";
return redirect()->route('home')->with('success', $message_correct)->with('mail_not_sent', $mail_not_sent);
}
}
In theory both fields are required so I don't understand why appears an exception error and by the way why the validator doesn't let simply a similar message in the view: The start field is required or . The end field is required . Is someone able to help me?

form input cleared after submit data using laravel fram work

I have multiple data base connection when I validate name of product I send message product name is exist before to view and here problem is appeared.
Message appeared in view but all form inputs is cleared.
How I recover this problem taking in consideration if product name not exist. validation executing correctly and if found error in validation it appeared normally and form input not cleared.
this my controller code.
public function add(Request $request)
{
// start add
if($request->isMethod('post'))
{
if(isset($_POST['add']))
{
// start validatio array
$validationarray=$this->validate($request,[
//'name' =>'required|max:25|min:1|unique:mysql2.products,name|alpha',
'name' =>'required|alpha',
'price' =>'required|numeric',
]);
// check name is exist
$query = dBHelper::isExist('mysql2','products','`status`=? AND `deleted` =? AND `name`=?',array(1,1,$validationarray['name']));
if(!$query) {
$product=new productModel();
// start add
$product->name = $request->input('name');
$product->save();
$add = $product->id;
$poducten = new productEnModel();
$poducten->id_product = $add;
$poducten->name = $request->input('name');
$poducten->price = $request->input('price');
$poducten->save();
$dataview['message'] = 'data addes';
} else {
$dataview['message'] = 'name is exist before';
}
}
}
$dataview['pagetitle']="add product geka";
return view('productss.add',$dataview);
}
this is my view
#extends('layout.header')
#section('content')
#if(isset($message))
{{$message}}
#endif
#if(count($errors)>0)
<div class="alert alert-danger">
<ul>
#foreach($errors->all() as $error)
<li>{{$error}}</li>
#endforeach
</ul>
</div>
#endif
<form role="form" action="add" method="post" enctype="multipart/form-data">
{{csrf_field()}}
<div class="box-body">
<div class="form-group{{$errors->has('name')?'has-error':''}}">
<label for="exampleInputEmail1">Employee Name</label>
<input type="text" name="name" value="{{Request::old('name')}}" class="form-control" id="" placeholder="Enter Employee Name">
</div>
<div class="form-group">
<label for="exampleInputEmail1">Email Address</label>
<input type="text" name="price" value="{{Request::old('price')}}" class="form-control" id="" placeholder="Enter Employee Email Address">
</div>
</div>
<!-- /.box-body -->
<div class="box-footer">
<button type="submit" name="add" class="btn btn-primary">Add</button>
</div>
</form>
#endsection
this is my route
Route::get('/products/add',"produtController#add");
Route::post('/products/add',"produtController#add");
You can create your own custom validate function like below. I guess this should help you.
Found it from https://laravel.com/docs/5.8/validation#custom-validation-rules -> Using Closures
$validationarray = $this->validate($request,
[
'name' => [
'required',
'alpha',
function ($attribute, $value, $fail) {
//$attribute->input name, $value for that value.
//or your own way to collect data. then check.
//make your own condition.
if(true !=dBHelper::isExist('mysql2','products','`status`=? AND `deleted` =? AND `name`=?',array(1,1,$value))) {
$fail($attribute.' is failed custom rule. There have these named product.');
}
},
],
'price' => [
'required',
'numeric',
]
]);
First way you can throw validation exception manually. Here you can find out how can you figure out.
Second way (I recommend this one) you can generate a custom validation rule. By the way your controller method will be cleaner.

Laravel 5.4 MethodNotAllowedHttpException error when enter wrong password after clearing cache

I have login form with two text fields email, password.when I tried to login with credentails it's working fine but when clear cache and then tried to login it gives the 'MethodNotAllowedHttp' exception.I am not getting the issue why it's showing this error. My code is as follows:
Route::post('users/login/5', 'administrator\usersController#login')->name('sl');
usersController.php
namespace App\Http\Controllers\administrator;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\Validator;
use Session;
class FreeusersController extends Controller {
function login(Request $request) {
$type = $request->segment(3);
//print_r($request);
echo "type=".$type;
echo $request->input('email');
echo $request->input('password');
die("sss");
if ($request->isMethod('post') && !empty($type)) {
$this->validate($request, [
'email' => 'required|min:5,max:50',
'password' => 'required|min:5,max:50'
]);
switch ($type) {
case 5:
$condArr = ['email' => $request->input('email'), 'password' => $request->input('password'), 'type' => '5', 'role' => 'father'];
break;
case 4:
$condArr = ['email' => $request->input('email'), 'password' => $request->input('password'), 'type' => '4', 'status' => true];
break;
}
if (Auth::attempt($condArr)) {
return redirect('administrator/dashboard');
} else {
return redirect(url()->previous())->withErrors(['password' => 'Invalid credentials'])->withInput();
}
} else {
return redirect("/");
}
}
}
<form action="/users/login/5" id="login-form" method="post" class="smart-form client-form">
{{ csrf_field() }}
<fieldset>
<section>
<label class="label">Email</label>
<label class="input"> <i class="icon-append fa fa-user"></i>
<input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}">
</section>
<section>
<label class="label">Password</label>
<label class="input"> <i class="icon-append fa fa-lock"></i>
<input id="password" type="password" class="form-control" name="password">
</section>
</fieldset>
<footer>
<button type="submit" class="btn btn-primary">
LogIn
</button>
</footer>
</form>
You have to clear routes:
php artisan route:cache
Then it will remember that login action is post.
I think you are getting this error because you when you are calling this url there is another url with something like users/{id} which means anything after users/. May be you are using resource route. So, when you call url users/login/5 its taking login/5 as $id of that users/{id} url.
But that url is for GET method. You are calling this with post method, as a result you are getting this error.
Solution
You can try calling your url using route method like:
action="{{route('sl', ['id'=>5])}}"
If it doesn't work then you can change your route to something else. For example:
Route::post('user/login/5', 'administrator\usersController#login')->name('sl');
Here you can use user instead of users because you already have a url with a users. Don't forget to change your action too.
First look at your routes with php artisan route:list.
Then are you sure of your request verb ? Look in your navigator console to look at your requests.

Categories