I have a method like this in my UserController:
public function verifyUsername()
{
$rules = array(
'username' => 'required|max:30|unique:users,username'
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails())
{
return Response::json(array(
'success' => 'false',
'errors' => $validator->messages()
), 400);
}
else
{
return Response::json(array(
'success' => 'true'
));
}
}
I want to have a URL route like this:
/users/verify/username/{username}
How can I pass the username variable from the route to the method in the controller?
You pass in a array with uses set to the ControllerName#methodName
You might want to look at Named Routes for more information.
routes.php
Route::get('users/verify/username/{username}',
array('uses' => 'UserController#verifyUsername'));
Controller
public function verifyUsername($username)
{
//it would be nice if this works, but I don't think it will
$validator = Validator::make(Input::get('username'), $rules);
// something like this should work
$data = ['username' => $username];
$validator = Validator::make($data, $rules);
}
Related
i have some laravel code like this
public function update_password(Request $request)
{
$data = array(
'password_current' => $request->input('password_current'),
'password_new' => $request->input('password_new'),
'password_new_confirmation' => $request->input('password_new_confirmation'),
);
$rules = [
'password_current' => 'required',
'password_new' => 'required|confirmed',
'password_new_confirmation' => 'required',
];
$validator = Validator::make($data, $rules);
if ($validator->fails()) {
return redirect()->action('Editor\ProfileController#edit_password')->withInput()->withErrors(['New password confirmation failed!']);
} else {
$user = $this->UserRepository->get_one(Auth::user()->id);
if(Hash::check($request->input('password_current'), $user->password))
{
$this->UserRepository->change_password(Auth::user()->id, $request->input('password_new'));
return redirect()->action('Editor\ProfileController#show');
} else {
return redirect()->action('Editor\ProfileController#edit_password')->withInput()->withErrors(['Current password mismatch!']);
}
}
}
but when i run the program, the program notification is FatalThrowableError, Call to a member function get_one() on null. i change with other script in google but no one is work.
$user = $this->UserRepository->get_one(Auth::user()->id);
anyone ever had this problem?
I try to change script like
use Auth;
$user_id = Auth::user()->id;
and still not work.
I have a form where users can edit a branch's info, once the user submits that form, the update() method checks for the validity of the submitted data such as the description must be unique to every subscriber. While the validation WORKS, it doesn't redirect to the exact url/page that I want if the validation fails. It stays in the same edit form.
here's the code of my update() method:
public function update(Request $request, $id)
{
$description = $request->input('description');
$message = $request->input('message');
$subscriber_id = auth()->user()->subscriber_id;
$messages = [
'description.unique' => 'Branch already exists!',
];
$this->validate($request, [
'description' => Rule::unique('branches')->where(function ($query) use($subscriber_id) {
return $query->where('subscriber_id', $subscriber_id);
})
], $messages);
Branch::where('id', $id)->update([
'description' => $description,
'message' => $message,
]);
return redirect('branches')->with('success', 'Branch info successfully updated!');
}
Note: the url of the edit form is /branch/edit/{id} while the page I want to redirect after submission is /branches.
Is my validation wrong? Did I miss something?
Thanks! :)
According to the laravel docs you can redirect to a different route by using the Validator facade
public function update(Request $request, $id)
{
$description = $request->input('description');
$message = $request->input('message');
$subscriber_id = auth()->user()->subscriber_id;
$messages = [
'description.unique' => 'Branch already exists!',
];
$validator = Validator::make($request->all(), [
'description' => Rule::unique('branches')->where(function ($query) use($subscriber_id) {
return $query->where('subscriber_id', $subscriber_id);
})
],
$messages);
if ($validator->fails()) {
return redirect('/branches')
->withErrors($validator)
->withInput();
}
Branch::where('id', $id)->update([
'description' => $description,
'message' => $message,
]);
return redirect('branches')->with('success', 'Branch info successfully updated!');
}
Make sure you use the Validator facade at the beginning of your controller file use Validator;
My route
Route::put('/users/{$id}', 'ApiController#profileUpdate')->name('user.update');
//profile update function
public function profileUpdate(Request $request){
try{
$validator = $this->validatorProfile($request->all());
if ($validator->fails()) {
$messages = $validator->messages();
return response()->json([
'status' => 400,
'error' => true,
'result' => false ,
'message'=> $messages,
'data' => []
]);
}
$id = $request->id;
$token = $request->header('authorization');
$user_id = JWTAuth::toUser($token)->id;
$user = User::find($user_id);
$data = $request->only('location','state','country','name');
$result = $user->profiles()->where(['user_id' => $$id])->update([
'location' => $data['location'],
'state' => $data['state'],
'country' => $data['country'],
]);
$result1 = $user->where(['id' => $user_id])->update([
'name' => $data['name'],
]);
return response()->json([
'status' => 200,
'error' => false,
'result' => true,
'message'=> "profile updated",
'data' => $data
]);
}
catch(Exception $e){
return response()->json([
'status' => 400,
'error' => true,
'result' => false,
'message'=> $e,
'data' => []
]);
dd($e);
}
}
Help me to find my mistake.
My url
http://localhost/project/public/api/v1/users/1
When i hit it on postman it give 404 error.
You will have to adjust your route parameter choice of naming. {$id} isn't going to work, but {id} will work just fine. Also the $$id reference in the code probably should be just $id.
As Alexey Mezenin has pointed out, it additionally would be good to add the $id parameter to your controller method to accept the route parameter.
Side Note:
When you are calling $request->id you are probably trying to get the route parameter, but that may not always return that. If there is any input in the Request named id that will be returned before a route parameter named id. It only tries to return a route parameter as a fallback.
$request->input('id') explicitly ask for an input named id.
$request->route('id') explicitly ask for a route parameter named id.
$request->id could be an input named id or a route parameter named id.
Since you're trying to pass ID, you need to add it as an argument. So, change this:
public function profileUpdate(Request $request)
To:
public function profileUpdate(Request $request, $id)
I'm trying to implement one of Laravel's new features "Custom Validation Rules" and I'm running into the following error:
Object of class Illuminate\Validation\Validator could not be converted to string
I'm following the steps in this video:
New in Laravel 5.5: Project: Custom validation rule classes (10/14)
It's an attempt Mailgun API's Email Validation tool.
Simple form that requests: first name, last name, company, email and message
Here is my code:
web.php
Route::post('contact', 'StaticPageController#postContact');
StaticPageController.php
use Validator;
use App\Http\Validation\ValidEmail as ValidEmail;
public function postContact(Request $request) {
return Validator::make($request->all(), [
'firstname' => 'required|max:90',
'lastname' => 'required|max:120',
'company' => 'max:120',
'email' => [
'required', 'string', 'max:255',
new ValidEmail(new \GuzzleHttp\Client)
],
'message' => 'required',
]);
}
ValidEmail.php
<?php
namespace App\Http\Validation;
use Illuminate\Contracts\Validation\Rule;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Client as Guzzle;
class ValidEmail implements Rule
{
protected $client;
protected $message = 'Sorry, invalid email address.';
public function __construct(Guzzle $client)
{
$this->client = $client;
}
public function passes($attribute, $value)
{
$response = $this->getMailgunResponse($value);
}
public function message()
{
return $this->message;
}
protected function getMailgunResponse($address)
{
$request = $this->client->request('GET', 'https://api.mailgun.net/v3/address/validate', [
'query' => [
'api_key' => env('MAILGUN_KEY'),
'address' => $address
]
]);
dd(json_decode($request->getBody()));
}
}
Expectation
I'm expecting to see something like this:
{
+"address": "test#e2.com"
+"did_you_mean": null
+"is_disposable_address": false
+"is_role_address": false
+"is_valid": false
+"parts": {
...
}
}
Any help is much appreciated. I've been trying to get this simple example to work for over two hours now. Hopefully someone with my experience can help!
In your controller
Try this:
$validator = Validator::make($request->all(), [
'firstname' => 'required|max:90',
'lastname' => 'required|max:120',
'company' => 'max:120',
'email' => [
'required', 'string', 'max:255',
new ValidEmail(new \GuzzleHttp\Client)
],
'message' => 'required',
]);
if ($validator->fails()) {
return redirect()->back()
->withErrors($validator)
->withInput();
}
// if valid ...
According to your route, the postContact method is the method to handle the route. That means the return value of this method should be the response you want to see.
You are returning a Validator object, and then Laravel is attempting to convert that to a string for the response. Validator objects cannot be converted to strings.
You need to do the validation, and then return the correct response based on that validation. You can read more about manual validators in the documenation here.
In short, you need something like this:
public function postContact(Request $request) {
$validator = Validator::make($request->all(), [
'firstname' => 'required|max:90',
'lastname' => 'required|max:120',
'company' => 'max:120',
'email' => [
'required', 'string', 'max:255',
new ValidEmail(new \GuzzleHttp\Client)
],
'message' => 'required',
]);
// do your validation
if ($validator->fails()) {
// return your response for failed validation
}
// return your response on successful validation
}
I have default validation rule in controller Laravel:
$validator = Validator::make($request->all(), [
'email' => 'required|email',
'phone' => 'required|numeric',
'code' => 'required|string|min:3|max:4',
'timezone' => 'required|numeric',
'country' => 'required|integer',
'agreement' => 'accepted'
]);
I tried this, but dont know how to transfer some parameters inside function:
public function boot()
{
Validator::extend('phone_unique', function($attribute, $value, $parameters) {
return substr($value, 0, 3) == '+44';
});
}
How can I extent this validation by my own rule? For example I need to validate concatination of inputs:
$phone = $request->code.' '.$request->phone
After check if $phone are exists in database
I want to use this method:
> $validator->sometimes('phone', 'required|alpha_dash|max:25', function
> ($input) {
> if ((Auth::user()->phone == $input->phone)) {
> return false;
>
> } else {
>
> $t = User::where("phone", $input->phone)->get();
> return ($t->count() > 0) ? false : false;
>
> }
> });
It does not work under all conditions (True, False) inside.
I added new validation nickname_unique:
$validator = Validator::make($request->all(), [
'email' => 'required|email',
'code' => 'required|string|min:3|max:4',
'phone' => 'required|phone_unique',
'timezone' => 'required|numeric',
'country' => 'required|integer',
'nickname' => 'required|alpha_dash|max:25',
'agreement' => 'accepted'
], [
'phone_unique' => 'Phone already exists!',
'nickname_unique' => 'Nickname is busy!',
]);
It does not work, even not call validation rule below previos:
Validator::extend('nickname_unique', function ($attribute, $value, $parameters, $validator) {
dd("Here");
});
You can define your custom validator inside AppServiceProvider like this:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Validator;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
Validator::extend('phone_unique', function ($attribute, $value, $parameters, $validator) {
$inputs = $validator->getData();
$code = $inputs['code'];
$phone = $inputs['phone'];
$concatenated_number = $code . ' ' . $phone;
$except_id = (!empty($parameters)) ? head($parameters) : null;
$query = User::where('phone', $concatenated_number);
if(!empty($except_id)) {
$query->where('id', '<>', $except);
}
return $query->exists();
});
/**
* Register the service provider.
*
* #return void
*/
public function register()
{
//
}
}
You can get all the inputs passed to the validator, by accessing $validator property - getData()
You can just add an extra parameter to your rules array after your custom validation rule (just after the colon) like this:
'phone' => 'required|phone_unique:1',
Pass the id to be ignored while checking entries into the db
The custom validator Closure receives four arguments: the name of the $attribute being validated, the $value of the attribute, an array of $parameters passed to the rule, and the Validator instance.
Now you can call the validator like this:
$validator = Validator::make($request->all(), [
'email' => 'required|email',
'code' => 'required|string|min:3|max:4',
'phone' => 'required|phone_unique:1',
'timezone' => 'required|numeric',
'country' => 'required|integer',
'agreement' => 'accepted'
], [
'phone_unique' => 'Phone already exists!', // <---- pass a message for your custom validator
]);
See more about Custom Validation Rules.
I am writing this answer because I believe bunch of people are looking for some good answer for this topic. So I decided to share my code that I am using for booking site, where I want to check that IS NOT arrival_date > departure_date.
My version of Laravel is 5.3.30
public function postSolitudeStepTwo(Request $request)
{
$rules = [
'arrival_date' => 'required|date',
'departure_date' => 'required|departure_date_check',
'occasional_accompaniment_requested' => 'required|integer',
'accommodation' => 'required|integer',
'are_you_visiting_director' => 'required|integer',
];
if ($request->input('are_you_visiting_director') == 1) {
$rules['time_in_lieu'] = 'required|integer';
}
$messages = [
'departure_date_check' => 'Departure date can\'t be smaller then Arrival date.Please check your dates.'
];
$validation = validator(
$request->toArray(),
$rules,
$messages
);
//If validation fail send back the Input with errors
if($validation->fails()) {
//withInput keep the users info
return redirect()->back()->withInput()->withErrors($validation->messages());
} else {
MySession::setSessionData('arrival_date', $request);
MySession::setSessionData('departure_date', $request);
MySession::setSessionData('occasional_accompaniment_requested', $request);
MySession::setSessionData('accommodation', $request);
MySession::setSessionData('are_you_visiting_director', $request);
MySession::setSessionData('time_in_lieu', $request);
MySession::setSessionData('comment_solitude_step2_1', $request);
//return $request->session()->all();
return redirect("/getSolitudeStepThree");
}
}
My controller is StepController and there I have declared a method as you can see called postSolitudeStepTwo. I declare the rules and on departure date notice that for the rule we have required|departure_date_check. That will be the name of the method in
app/Providers/AppServiceProvider.php
The code there looks like this:
public function boot()
{
Validator::extend('departure_date_check', function ($attribute, $value, $parameters, $validator) {
$inputs = $validator->getData();
$arrivalDate = $inputs['arrival_date'];
$departureDate = $inputs['departure_date'];
$result = true;
if ($arrivalDate > $departureDate) {
$result = false;
}
return $result;
});
}
As the Laravel documentation 5.3 Custom validation rules we need to extend the Validator facade, the signature of that method has to be:
Validator::extend(name_of_the_function, function ($attribute, $value, $parameters, $validator) {
And I believe the rest is clear.
Hope it will help somebody.
$messsages = array(
'email.required'=>'Email is Required',
'phone.required'=>'Phone number is Required',
);
$rules = array(
'email' => 'required',
'phone' => 'required',
);
$validator = Validator::make(Input::all(), $rules,$messsages);
if ($validator->fails()):
$this->throwValidationException($request, $validator);
endif;