laravel validate with user function - php

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'
]);

Related

How to get validated data from Validator instance in Laravel?

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 -->

get user input using Request in laravel and pass it for validation

i am new to laravel.Here i have a form where i have to fill up a name field and send it to controllers store() method for validation. Otherwise it will show custom error.But whenever i submit the form with or without input i am getting the following error.
Argument 1 passed to Illuminate\Validation\Factory::make() must be of
the type array, string given, called in
C:\xampp\htdocs\mylaravel\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php
on line 221 and defined
for experiment purpose i am catching the user input using the following format
$data = $request->input('name');
create.blade.php:
<h1>login form</h1>
#if($errors->has())
<div><span> Opps !! </span></br>
<ul>
#foreach ($errors->all() as $error)
<li> {{ $error }}</li>
#endforeach
</ul>
</div>
#endif
{!!Form::open(array('url'=>'user','method'=>'POST', 'files'=>true)) !!}
{!!Form::label('name','Your name')!!}
{!!Form::text('name')!!}
</br>
{!!Form::submit('submit')!!}
{!!Form::close()!!}
store() method in userController.php file:
public function store(Request $request)
{
//
$data = $request->input('name');
$rules = array(
'name' => 'unique:users,name|required|alpha_num'
);
// Create a new validator instance.
$validator = Validator::make($data, $rules);
if($validator->fails()){
$errors=$validator->messages();
return Redirect::route('user.create')->withErrors($validator);
}else{
return Redirect::route('user.index');
}
}
}
According to your error,Validator expects it parameters to be array, but you are passing a string there as $data= $request->input('name') . So, you should pass array in Validator::make() . Below code should work for you.
$validator = Validator::make($request->all(), [
'name' => 'unique:users,name|required|alpha_num'
]);
Here is the doc if you want to explore more .
You need to pass array inside Validator::make.
Right now your are passing string in the form of $data variable.
For example :
$validator = Validator::make(
array('name' => 'Dayle'),
array('name' => 'required|min:5')
);
DOCS : https://laravel.com/docs/4.2/validation
you have pass your params as array in validation,so your code will be
public function store(Request $request)
{
//
$data = $request->all();
$rules = array(
'name' => 'unique:users,name|required|alpha_num'
);
// Create a new validator instance.
$validator = Validator::make($data, $rules);
if($validator->fails()){
$errors=$validator->messages();
return Redirect::route('user.create')->withErrors($validator);
}else{
return Redirect::route('user.index');
}
}
}

Laravel 5.2 validation errors not appearing

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

How to push only validation error messages into an array using Laravel

I have a validator, it has error messages, and my goal is to get only error messages with the field names.
$validator = Validator::make(
array(
'firstField' => Input::get('firstFieldName');
'secondField' => Input::get('secondFieldName');
),
array(
'firstField' => 'required';
'secondField' => 'required';
)
);
if($validator->fails()){
return $validator->messages();
}
So, this piece of code is returning some values to my js file as following
function getErrorMessages(){
//Some UI functions
var myDiv = document.getElementById('messageDivID');
$.post('validationRoute', function(returedValidatorMessageData)){
for(var a in returedValidatorMessageData){
myDiv.innerHTML = myDiv.value + a;
}
}
}
Problem is, the only values i get from post request is like firstField secondField but i'd like to get like firstField is required message. What would be the easiest way ?
Thanks in advance.
Laravel's messages() method returns array with this format:
[
"first_name" => [
"First name is required."
]
]
Where keys are name of the field and values are arrays of error messages. So just modify your js using values instead of keys. Example:
for (var key in returedValidatorMessageData){
console.log(returedValidatorMessageData[key]);
}
It's not a perfect approach i know, but created my own way as the answer :
if($validator->fails()){
//get all the messages
$errorArray = $validator->errors()->all(':message');
//& operator means changes will affect $errorArray
foreach($errorArray as &$a){
$a = ucfirst($a); //uppercases first letter (you can do this in laravel config too)
$a = '<li>'.$a.'</li>'; //add to list
}
//add a string at the beginning of error message
array_unshift($errorArray, '<p><b>The error messages are following :</b></p>');
//implode and return the value
return implode(' ',$errorArray);
}
You should search in laravel official documentation... in the view use this
<!-- /resources/views/post/create.blade.php -->
<h1>Create Post</h1>
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
<!-- Create Post Form -->
in controller :
public function name(Request $request)
{
$validator = Validator::make($request->all(), [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
if ($validator->fails()) {
return redirect('post/create')
->withErrors($validator)
->withInput();
}
// Store the blog post...
}
}

Laravel update method passing through model name instead of ID

I am having an issue with my resource route when calling the update method.
I get this error:
Creating default object from empty value
The controller:
public function update($id)
{
$input = Input::all();
$validation = Validator::make($input, Vehicle::$rules, Vehicle::$messages);
if ($validation->passes())
{
$this->vehicle->update($id, $input);
return Redirect::route('admin.vehicles.index')->with('success', 'Car Updated');
}
return Redirect::back()
->withInput()
->withErrors($validation);
}
repository:
public function update($id, $input)
{
$vehicle = Vehicle::find($id);
$vehicle->VRM = $input['VRM'];
$vehicle->make = $input['make'];
$vehicle->model = $input['model'];
$vehicle->description = $input['description'];
$vehicle->save();
}
Route:
Route::resource('/admin/vehicles', 'VehiclesController');
If I print the ID then it shows {vehicle}.
My form is this:
{{ Form::open(['route' => 'admin.vehicles.update', 'class' => 'form-horizontal edit-vehicle-form', 'method' => 'PATCH']) }}
// input fields etc
{{ Form::close() }}
I think there is something wrong with the form possibly? Since when the error is thrown the URL is:
http://localhost/admin/vehicles/%7Bvehicles%7D
Never had any issues before with using resource routes with CRUD applications and cant see where this is going wrong?
You need the id in update route...
{{ Form::open(['route' => array('admin.vehicles.update', $vehicle->id), 'class' => 'form-horizontal edit-vehicle-form', 'method' => 'PATCH']) }}

Categories