I manually created a Validator, but i can't find a method to get the validated data.
For Request, validated data return from $request->validate([...])
For FormRequest, it's return from $formRequest->validated()
But with Validator, i don't see a method like those 2 above.
Assuming that you're using Validator facade:
use Illuminate\Support\Facades\Validator;
$validator = Validator::make($request->all(), $rules, $messages, $attributes);
if ($validator->fails()) {
return $validator->errors();
}
//If validation passes, return valid fields
return $validator->valid();
https://laravel.com/api/5.5/Illuminate/Validation/Validator.html#method_valid
If you use the Validator facade with make it will return a validator instance. This validator instance has methods like validate(), fails() and so on. You can look those methods up in the validator class or in the laravel api-documentation.
Writing The Validation Logic
public function store(Request $request)
{
$validatedData = $request->validate([
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
// The blog post is valid...
}
Displaying The Validation Errors
<!-- /resources/views/post/create.blade.php -->
<h1>Create Post</h1>
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
<!-- Create Post Form -->
Related
my validation is working correctly. but didn't show any message. I mention the below.
in controller
$fields = collect([
'monthly_fees',
'admission',
'due_advance',
'session_fee',
'library',
'sports',
'poor_funds',
'fine',
'reciept',
'milad',
'scout',
'development',
'registration',
'f_tutorial',
's_tutorial',
't_tutorial',
'f_exam',
's_exam',
't_exam',
'labratory',
'transport',
'syllabus',
'certificate',
'testimonial',
'generator',
'extra'
]);
$rules = $fields->mapWithKeys(function ($field) use ($fields) {
return [
$field => 'required_without_all:' . $fields->reject(function ($item) use ($field) {
return $item == $field;
})->implode(',')
];
})->toArray();
$this->validate($request, $rules);
in views
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul class="text-center">
#foreach($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
I also use these lines of codes in the controller but didn't work.
if($this->validate()->fails()) {
return redirect()->back()->with('error','Please Input minimum 1 field...');
}
I want to do minimum 1 field is required. I have 26 input fields. I always use these codes for single use. but this time want to validate minimum One field required. These codes validate the required but didn't show any messages though I mentioned the errors in blade. can you please help me with these errors? thanks in advance.
I solved my problems. here i used $this->vatidate(...);
it was wrong for me. then I used Validator package and returns a custom message with redirect if fails. then it works.
blade.php
......
<tr>
<td>{{ Form::label('cameraMac', 'Mac: ') }}</td>
<td>{{ Form::text('cameraMac')}}</td>
</tr>
......
controller.php
$data = Input::all();
function transform($cameraMac) {
return strtoupper($cameraMac);
}
//validation here
$user = User::find($data['user_id']);
if($data["cameraMac"])
{
$user->camera_id = transform($data["cameraMac"]);
Cloud_camera::create(['id' => transform($data["cameraMac"]), 'user_id' => $user->id]);
}
$user->save();
I need to transform the cameraMac to primary key to store in db. How can I use function transform() in the validation rule 'nullable|unique:cloud_cameras,id|size:6'. That's to say, how can I call this function in the validation process.
If you need to somehow transform the input data you can use the merge method:
Input::merge(['cameraMac' => transform(Input::get('cameraMac')]);
$this->validate(Input::getFacadeRoot(), [
'cameraMac' => 'nullable|unique:cloud_cameras,id|size:6'
]);
As a personal preference I would instead type-hint Illuminate\Http\Request $request in the controller method and then
$request->merge(['cameraMac' => transform($request->cameraMac)]);
$this->validate($request, ['cameraMac' => 'nullable|unique:cloud_cameras,id|size:6'
]);
I'd consider defining a middleware.
The middleware will perform the transformation and merge the result back to the request before hitting the controller.
class TransformId {
public function handle(Request $request, Closure $next) {
// shout out to #alepeino
$request->merge(['cameraMac' => transform($request->cameraMac)]);
return $next($request);
}
}
Are you shure, that you want the field cameraMac be nullable as a (more or less) primary key?
You should also use the int validation for using the size validation.
The third parameter of unique validation is the except which will ignore the given ID.
Your validation in the controller could look like this
$except_id = $request->input('cameraMac', null);
$this->validate($request, [
'cameraMac' => 'nullable|unique:cloud_cameras,id,'.$except_id.'|int|size:6'
]);
One example how you can show errors of your validation in the views will be this
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
For now I trans the input data first, then validate it in the below way.
But I'm looking a way to call this funciton in the validation.
$data = Input::all();
$data['cameraMac'] = transform($data['cameraMac']);
$rules = array(
'id' => 'required|unique:cloud_printers,id|size:6',
'cameraMac' => 'unique:cloud_cameras,id|size:6',
);
$validator = Validator::make($data, $rules);
if ($validator->fails())
return Redirect::back()->withInput()->withErrors($validator);
You can define a custom validation rule:
Validator::extend('transformUpper', function ($attribute, $value, $parameters, $validator) {
return strtoupper($value);
});
Then use the new rule in the Request as usual:
$this->validate($request, [
'cameraMac' => 'required|transformUpper'
]);
I have this validator for input called "name":
Regex:/^[A-Za-z0-9\\s\\-\\/,.]*$/|min:5|max:50
But, I want to use this validator in multiple forms in my website.
How can i do this without to copy this validator in all the forms validations?
My database contains table called "settings", every row presents setting of the website. Each setting contain Json code that save the setting data.
I want to create custom validator that check if the input value equals to one of the values in the Json code in my database.
I have Json code like this:
[{"US":"United States", "UK":"United Kingdom"}]
And I want to check if the value of the input equals to one of the values in the Json code. How can I do this?
I know you said, across your website. However, I would think that you're ensuring that the use of forms using the same validators are relatively within the same state.
Here's an example that helped me get to where I needed to be! I hope it serves as a good enough guide!:
MessageBag documentation here: http://laravel.com/docs/5.0/validation#error-messages-and-views
public function postLogin(Request $request)
public function postLogin(Request $request)
{
$validator = Validator::make($request->all(), [
'email' => 'required|email', 'password' => 'required',
]);
if ($validator->fails())
{
return redirect($this->loginPath())->withErrors($validator, 'loginErrors');
}
$credentials = $this->getCredentials($request);
if (Auth::attempt($credentials, $request->has('remember'))) {
return redirect()->intended($this->redirectPath());
}
return redirect($this->loginPath())
->withInput($request->only('email', 'remember'))
->withErrors([
'email' => $this->getFailedLoginMessage(),
], 'loginErrors');
}
Now you can look for errors inside of your view:
#if (!$errors->loginErrors->isEmpty())
<div class="form_error_login">
<strong>Whoops!</strong> There were some problems with your input.<br> <br>
<ul>
#foreach ($errors->loginErrors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
For the Modals (if you use them):
<script>
$findError = $('div').find ('div');
if ( $findError.hasClass('form_error_login')){
$('#modalLogin').foundation('reveal', 'open');
}
if ( $findError.hasClass('form_error_register')){
$('#modalRegister').foundation('reveal', 'open');
}
</script>
Reference:
https://laracasts.com/discuss/channels/laravel/authcontroller-loginregistration-on-same-page
I am trying to validate a simple form by using Laravel's validator. Looks like validation works fine but i am unable to display errors. Form and controller looks like this.
Form
<h3>Add a New Team</h3>
<form method="POST" action="/teams">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<div class="form-group">
<input class="form-control" name="team_name" value="{{ old('team_name') }}" />
</div>
<div class="form-group">
<button type="submit" class="btn bg-primary">Add Team</button>
</div>
</form>
#if(count($errors))
<div class="alert alert-danger">
<ul>
#foreach($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
Controller Method
public function store(Request $request) {
$this->validate($request, [
'team_name' => 'required|min:10'
]);
$team = new Team;
$team->team_name = $request->team_name;
$team->save();
return back();
}
If i remove web middleware group from my routes, errors displays fine.
Currently my routes.php file looks like this
Route::group(['middleware' => ['web']], function () {
Route::get('/teams', 'TeamsController#create');
Route::post('/teams', 'TeamsController#store');
});
How do i fix this problem ? Any help would be appreciated.
why do use the validation looks like laravel 4 while you are using laravel 5!!
in laravel 5 you need first to make Request class that handle your validation
php artisan make:request RequestName
you will find the request class that you make in
'app/http/Requests/RequestName.php'
and in the rules function you can handle your validation
public function rules()
{
return [
// put your validation rules here
'team_name' => 'required|min:10'
];
}
finally in your controller
use App\Http\Requests\RequestName;
public function store(RequestName $request) {
Team::create($request->all());
return Redirect::back();
}
for more illustration here
I recommend you to use Laravel Form Request
run
artisan make:request TeamRequest
add some logic and rules
class TeamRequest extends Request {
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true; //you can put here any other variable or condition
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
// put your validation rules here
];
}
}
then your contorller code will be like so:
public function store(TeamRequest $request)
{
$team = Team::create($request->all());
return back();
}
you no longer need to validate request and redirect back with errors and other stuff, laravel will do it for you
And you code looks more clean and neat, isn't it?
Write below code in your controller :
// define rules
$rules = array(
'team_name' => 'required|min:10'
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails())
{
// something
return Redirect::back()
->withErrors($validator) // send back all errors to the login form
->withInput();
}
else
{
// something
// save your data
$team = new Team;
$team->team_name = $request->team_name;
$team->save();
}
change in View File :
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
After a little bit research, i have found that Laravel 5.2 has a RouteServiceProvider and it includes web middleware group for all routes. So i do not have to add the web middleware group to my routes manually. I just removed it from routes.php and problem solved.
If i remove web middleware group from my routes, errors displays fine.
In Laravel 5.2 the web midddleware is automatically applied to your routes in routes.php so no need to apply web middleware again. It is defined in mapWebRoutes() method of RouteServiceProvider.
I am trying to get validation errors to show up in Laravel.
I have a UserController set up like so:
<?php
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
//Use Request;
Use Flash;
Use Illuminate\Http\Request;
class UserController extends Controller
{
/**
* Show the profile for the given user.
*
* #param int $id
* #return Response
*/
public function showProfile($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}
public function store(Request $request) {
$this->validate($request, [
'email' => 'required|unique:users|email|max:255',
]);
if($this) {
$input = Request::all();
User::create($input);
return redirect('/');
}
else {
return redirect('/')->withErrors($validator);
}
}
}
In my view (layout.blade.php), I have included:
#if (count($errors) > 0)
#foreach ($errors->all() as $error)
{{!! $errors !!}}
#endforeach
#endif
To account for the route, I have:
Route::group(['middleware' => ['web']], function () {
Route::get('/', function (){
return view('home');
});
});
Unfortunately, when I enter "bad" data that shouldn't be verified, I am not seeing any error (but it is not being stored in the db, so there's that).
One other note, when the blade template is rendered, I am seeing an extra "}" bracket, which I'm not sure why that is there.
In laravel version 5.2.41, the middleware web is thrown out.
Means adding the routes inside Route::group(['middleware' => ['web']], function () { will make the validation not work.
There are a couple things wrong or that can be improved here. The store method on the UserController has a lot of weird issues. $this will always be true because objects are true in php. Also, you pass in $validator into withErrors which doesn't make sense because there's no variable validator.
public function store(Request $request) {
$this->validate($request, [
'email' => 'required|unique:users|email|max:255',
]);
User::create(Request::all());
return redirect('/');
}
The validate method will throw an Illuminate\Foundation\Validation\ValidationException if there is a validation error. This exception should be listed in the $dontReport instance variable in App\Exceptions\Handler as seen below:
protected $dontReport = [
AuthorizationException::class,
HttpException::class,
ModelNotFoundException::class,
ValidationException::class,
];
If you have changed these values, removed, or modified the ValidatesRequest trait you may have broken this functionality.
Your error reporting code is not correct either:
#foreach ($errors->all() as $error)
{!! $errors->first() !!}
#endforeach
There are 3 changes here. First I removed the outer errors size check, this doesn't really get you anything. Next, I fixed your extra } error, the syntax for un-escaping data is {!! $errors->first() !!}. Lastly, I called ->first() this returns the first error associated with that particular field.
I think it's important to note that the validation exception will create a redirect response to the previous page. The logic for determining the previous page can be found in Illuminate\Routing\UrlGenerator::previous().
The errors block should be:
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
Assuming you're using Bootstrap for the alerts.
You also don't have $validator defined. You need to do something like this:
$validator = Validator::make($request->all(), [
'email' => 'required|unique:users|email|max:255',
]);
Instead of $this->validate().
That should do it.
If it is still not working and you have tried several things like
Moving ShareErrorsFromSession::class from $middlewareGroups to $middleware
Removing the web.php to web middleware
Try modifying the request headers to
Accept: application/json
Or you can also create a new middleware that will modify the request header like this:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class ModifyAcceptHeaderMiddleware
{
public function handle(Request $request, Closure $next)
{
$request->headers->set('Accept', 'application/json');
return $next($request);
}
}
Try to remove "\Illuminate\Session\Middleware\StartSession::class" from 'middleware' in Kernel.php, it must be only in the 'web' group.
#if(count(($errors->all()) > 0))
#foreach($errors->all() as $error)
<div class="alert alert-danger">
{{$error}}
</div>
#endforeach
#endif