Trying to validate if there are only spaces in input box.
This is my validations:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Validator;
use App\Rules\allAreSpaces;
class StoreUser 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 [
'email' => 'required|email|max:64',
'phone' => 'bail|required|numeric|phone_min|phone_max|unique:users|not_in:0',
'password' => [new allAreSpaces, 'required', 'min:8', 'max:16', 'confirmed'],
'password_confirmation' => 'required',
];
}
public function messages()
{
return [
'email.required' => 'Email address cannot be empty',
'email.email' => 'Enter a valid Email address',
'email.max' => 'Email address cannot exceed 64 characters',
'email.unique' => 'Email already exists',
'phone.required' => 'Mobile number cannot be empty',
'phone.numeric' => 'Mobile number has to be numeric',
'phone.phone_min' => 'Mobile number should contain a minimum 5 characters',
'phone.phone_max' => 'Mobile number cannot exceed 11 characters',
'phone.unique' => 'Mobile number already exists',
'phone.not_in' => 'Enter a valid mobile number ',
'password.required' => 'Password cannot be empty',
'password.min' => 'Password should contain minimum 8 characters',
'password.max' => 'Password cannot exceed 16 characters',
'password.confirmed' => 'Password mismatch.Retry',
'password_confirmation.required' => 'Confirm Password cannot be empty',
];
}
public function withValidator(Validator $validator)
{
$email = $this->request->get( 'email' ); // Start with
$user = \App\User::Where('email', $email)->first();
if($user && $user->activated == 0){
$row = \App\User::find($user->id);
$row->delete();
}else{
$validator->sometimes('email', 'unique:users', function ($input) {
return true;
});
}
}
}
The following is the custom rule object that i was created:
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class allAreSpaces 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)
{
if(strlen($value) > 0){
if (strlen(trim($value)) == 0){
return false;
}
}
return true;
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'Password cannot contain space character alone';
}
}
Initially its returning, 'Password cannot contain space character alone'. but after i type some spaces then submit it shows 'Password cannot be empty'. But i want 'Password cannot contain space character alone' if the typed characters are only spaces.
Eventhough i did use the following code, its not showing if the input has some spaces, instead it shows, 'Password cannot be empty'.
public function passes($attribute, $value)
{
return false;
}
i was wondering why is that?
Have you checked the global middleware, that is ran for all routes in your application which is set in your HTTP Kernel? These might come into play:
"By default, Laravel includes the TrimStrings and ConvertEmptyStringsToNull middleware in your application's global middleware stack. These middleware are listed in the stack by the App\Http\Kernel class. These middleware will automatically trim all incoming string fields on the request, as well as convert any empty string fields to null. This allows you to not have to worry about these normalization concerns in your routes and controllers.
If you would like to disable this behavior, you may remove the two middleware from your application's middleware stack by removing them from the $middleware property of your App\Http\Kernel class."
Laravel 5.5 Docs - Requests - Input trimming and normalization
This might be relevant as well, goes into some complications that can happen because of these middleware:
"By default, Laravel includes the TrimStrings and ConvertEmptyStringsToNull middleware in your application's global middleware stack. These middleware are listed in the stack by the App\Http\Kernel class. Because of this, you will often need to mark your "optional" request fields as nullable if you do not want the validator to consider null values as invalid. "
Laravel 5.5 Docs - Validation - A note on optional fields
Related
i have a problem in showing error for users this is my Auth Login Controller :
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo = RouteServiceProvider::HOME;
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
public function login(Request $request)
{
$input = $request->all();
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:8',
]);
if(auth()->attempt(array('email' => $input['email'], 'password' => $input['password'])))
{
if (auth()->user()->type == 'admin') {
return redirect()->route('admin.home');
}else if (auth()->user()->type == 'manager') {
return redirect()->route('manager.home');
}else{
return redirect()->route('home');
}
}else{
return redirect()->route('login')
->with('error','Email-Address And Password Are Wrong.');
}
$messages = [
'email.required' => 'Email is required',
'email.email' => 'Invalid email format',
'password.required' => 'Password is required',
'password.min' => 'Password must be at least 8 characters',
];
}
}
This is the LoginController from the default app in laravel i don't know why the messages of password wrong can't be showed in screen when i type wrong pass
i want to show users error if they use wrong password and this is the github link :
https://github.com/ElGrandeAchraf/skipshiftProjectCode.git
And Thank you For your attention.
It appears that the error message is not being displayed because it is being set on the redirect rather than being passed back to the view. In the else block of the login method, try replacing
return redirect()->route('login')->with('error','Email-Address And Password Are Wrong.');
With
return back()->withInput()->withErrors(['email' => 'Email-Address And Password Are Wrong.']);
This will pass the error message back to the view so it can be displayed.
Also, you can use $messages validation rules to show custom error messages, and you should call it before validate function like this:
$messages = [
'email.required' => 'Email is required',
'email.email' => 'Invalid email format',
'password.required' => 'Password is required',
'password.min' => 'Password must be at least 8 characters',
];
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:8',
], $messages);
Please note that this is just one possible solution and that it may not be the only problem you're facing in your code. You should also check the routes, views, and other related files, and make sure that everything is set up correctly.
Not sure if I was looking at the right Blade file, but in your resources/views/login.blade.php file I haven't seen anywhere that you would actually have the code to show errors. The controller doesn't do that for you automatically.
I you are returning with('error') then you should show it in Blade, something like:
#if (session('error'))
<div class="error">{{ session('error') }}</div>
#endif
Although there are quite a lot of questions concerning Yii2 captchas as well as problems with saving, I couldn't find and answer that solved my problem. Hope someone can help:
In my website I included a contact form along with a captcha. Therefor I added code to the model, to the IndexController and the form as described here: https://yii2-cookbook-test.readthedocs.io/forms-captcha/#how-add-captcha-to-a-form
The captcha is displayed and prevents from submitting the form if the code wasn't entered correctly. However, if I include the captcha validation rules, the message is not saved to the database. So there seems to be something wrong with the validation rule.
['verifyCode', 'captcha', 'captchaAction' => '/contact/index/captcha']
I just don't see what is wrong here. When I comment it out, it the model is saved but the captcha isn't validated. Leaving the part with "captchaAction" out leads to an Invalid Captcha ID error, the solution is to include the captchaAction as described here: Yii2 Invalid CAPTCHA action ID in module
Does anyone have an idea of what might be wrong here? Running in circles...
Form:
...
<div class="form-group">
<div><?= Yii::t('ContactModule.form', 'Please enter the letters from the image.'); ?></div>
<?= $form->field($model, 'verifyCode')->widget(Captcha::class, [
'captchaAction' => '/contact/index/captcha',
])->label(false); ?>
</div>
...
Model:
class Contact extends ActiveRecord{
public $verifyCode;
/**
* #inheritdoc
*/
public static function tableName()
{
return 'contact';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['name','email','message'], 'required'], //Checking that all the fields are required
['email', 'email'], // Validating that email is a valid email
[['name'],'string', 'max' => 50], //Verifying that name is not greater than its max length
[['email'], 'string', 'max' => 50], //Verifying that email is not greater than its max length
[['message'], 'string', 'max' => 255],//Verifying that message is not greater than its max length
['state', 'boolean'],
[['date'], 'date', 'format' => 'php:Y-m-d'],
['verifyCode', 'captcha', 'captchaAction' => '/contact/index/captcha'],
];
}
...
Controller
class IndexController extends Controller
{
public $subLayout = "#contact/views/layouts/default";
/**
* #inheritdoc
*/
public function actions()
{
return [
'captcha' => [
'class' => 'yii\captcha\CaptchaAction',
]
];
}
/**
* Renders the index view for the module
*
* #return string
*/
public function actionIndex()
{
$model = new Contact();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
$model->save();
...
In request I got attribute that defines validation rules and flow. Let's say it is account_type: business, personal.
Each value changes validation flow and requires different attributes to be present ir request.
Let's say I have following custom rules methods:
public function validateAccountTypeBusiness($attribute, $value, $parameters, Validator $validator)
{
// check is present:
// Company address
// VAT number
}
public function validateAccountTypePersonal($attribute, $value, $parameters, Validator $validator)
{
// check is present:
// User mobile phone
}
Since each rule requires more than single attribute to be presented in this request depending on account type ( vat number, company name, etc ) returning false would be not informative to user because generated response notices that account type is invalid without any details which actual attributes is missing.
The question is: how I can append more rules to be validated in this validation custom rule?
Following not working:
public function validateAccountTypeBusiness($attribute, $value, $parameters, Validator $validator)
{
$validator->addRules([
'company_address' => 'required|string',
'vat_number' => 'required',
]);
}
If you follow Complex Conditional Validation, you can validate using the following way
Step 1: Create Validator instance with static rules which would be same in both the cases(business or personal account) like name,check,phone,email,etc.
$v = Validator::make($data, [
'email' => 'required|email',
'name' => 'required|alpha',
'phone' => 'required|numeric',
'check' => 'required' //common in both account type
//add more rules as required
]);
Step 2: Add specific rules with condition
$v->sometimes('VAT', 'required|max:50', function ($input) {
return $input->account_type == 'business';
});
$v->sometimes('Company_address', 'required|max:500|alpha', function ($input) {
return $input->account_type == 'business';
});
$v->sometimes('user_mobile', 'required|numeric', function ($input) {
return $input->account_type == 'personal';
});
Parameters for sometimes() method :
The first argument passed to the sometimes method is the name of the
field we are conditionally validating. The second argument is the
rules we want to add. If the Closure passed as the third argument
returns true, the rules will be added.
As per my understanding, Custom validation rule can be used for only one parameter & you're trying to club them together.
This is one of many ways to approach your problem. Hope it helps.
<?php
namespace App\Http\Controllers;
use Validator;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class AccountController extends Controller
{
/**
* Store a new user account.
*
* #param Request $request
* #return Response
*/
public function store(Request $request)
{
if($request->input('account_type' == 'business') {
// Validation for business account
$validator = Validator::make($request->all(), [
'company_address' => 'required|string',
'vat_number' => 'required',
]);
}
else {
// Validation for personal account
$validator = Validator::make($request->all(), [
'contact_number' => 'required',
]);
}
if ($validator->fails()) {
return redirect('account/create')
->withErrors($validator)
->withInput();
}
// Store the user account...
}
}
Reference -
Manually creating validators -
https://laravel.com/docs/5.4/validation#manually-creating-validators
Trying my hand on learning laravel.
I have a user form which post to this route
Route::post('users/add','usersController#store')->middleware('admin');
The store function in the usersController calls another function called validateForm which basically validates the input from the form ,like so
class usersController extends Controller
{
/*
*Store a user in database
*/
function store(){
$input=Request::all();
// create the validation rules ------------------------
$rules = array(
'name' => 'required', // just a normal required validation
'lastname' => 'required', // just a normal required validation
'email' => 'required|email|unique:users', // required and must be unique in the users table
'password' => 'required',
);
$validationResponse=$this->validateForm($input,$rules);
if($validationResponse=="passed"){
$user=new \App\User;
$user->name=$input['name'];
$user->email=$input['email'];
$user->lastname=$input['lastname'];
$user->password=\Hash::make($input['password']);
$user->userlevel=isset($input['isAdmin'])?1:0;
$user->save();
return redirect('users');
}
else{
return Redirect::to('users/create')
->withErrors($validationResponse)->withInput();
}
}
/*
*validate user form input
*/
function validateForm($input,$rules){
// do the validation ----------------------------------
// validate against the inputs from our form
$validator = Validator::make($input, $rules);
// check if the validator failed -----------------------
if ($validator->fails()) {
// get the error messages from the validator
$messages = $validator->messages();
return $messages;
}
else{
return 'passed';
}
}
}
Now this is fine for accesing from the userController, but what if I have another controller say projectsController and I want to access the same funtion i.e. validateForm
Where I should put this common function and how can I access it from any controller?
Laravel built in answer to this is Form Request
Just create a form request using php artisan make:request UserCheck, and put in your validation rules in the method rules
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules() {
return [
'name' => 'required', // just a normal required validation
'lastname' => 'required', // just a normal required validation
'email' => 'required|email|unique:users', // required and must be unique in the users table
'password' => 'required',
]; }
And call it
/*
* Store a user in database
*/
public function store(UserCheck $request)
{
// The incoming request is valid...
}
I'm trying to make yii2 to validate my ActiveForm field that should be numeric and of 8 characters long.
Following is what I tried in the default LoginForm model of yii2/advanced/backend, but unfortunately the isNumeric validator simply doesn't kick in:
public function rules()
{
return [
// username and password are both required
[['username', 'password'], 'required'],
// username should be numeric
['username', 'isNumeric'],
// username should be numeric
['username', 'string', 'length'=>8],
// password is validated by validatePassword()
['password', 'validatePassword'],
];
}
/**
* Validates if the username is numeric.
* This method serves as the inline validation for username.
*
* #param string $attribute the attribute currently being validated
* #param array $params the additional name-value pairs given in the rule
*/
public function isNumeric($attribute, $params)
{
if (!is_numeric($this->username))
$this->addError($attribute, Yii::t('app', '{attribute} must be numeric', ['{attribute}'=>$attribute]));
}
/**
* Validates the password.
* This method serves as the inline validation for password.
*
* #param string $attribute the attribute currently being validated
* #param array $params the additional name-value pairs given in the rule
*/
public function validatePassword($attribute, $params)
{
if (!$this->hasErrors()) {
$user = $this->getUser();
if (!$user || !$user->validatePassword($this->password)) {
$this->addError($attribute, 'Incorrect username or password.');
}
}
}
I also tried adding a scenario as suggested in a related post (https://stackoverflow.com/a/27817221/2037924) but that only worked (as in displayed the error) if I did not include the password field in the scenario.
Is this a good way to achieve this at all, or can you think of a better way of doing it?
Note: the reason I define username as string is because the numbers may contain leading 0's.
Try with integer data type:
[['username'], 'integer'],
[['username'], 'string', 'min' => 8],
It will validate both numeric and length. This will do the trick.
Read more about the validations here: http://www.yiiframework.com/doc-2.0/guide-tutorial-core-validators.html#number
This works fine for me using the contact form from yii2-basic
/**
* #return array the validation rules.
*/
public function rules()
{
return [
// name, email, subject and body are required
[['name', 'email', 'subject', 'body'], 'required'],
// email has to be a valid email address
['email', 'email'],
['subject', 'is8NumbersOnly'],
// verifyCode needs to be entered correctly
['verifyCode', 'captcha'],
];
}
public function is8NumbersOnly($attribute)
{
if (!preg_match('/^[0-9]{8}$/', $this->$attribute)) {
$this->addError($attribute, 'must contain exactly 8 digits.');
}
}
public function rules()
{
return [
// username should be numeric
['username', 'match', 'pattern' => '/^\d{8}$/', 'message' => 'Field must contain exactly 8 digits.],
// ...
];
}
try this:
public function rules()
{
return [
// name, email, subject and body are required
[['name', 'email', 'subject', 'body'], 'required'],
// email has to be a valid email address
['email', 'email'],
[['subject'], 'number'],
[['subject'], 'string', 'max' => 8, 'min' => 8],
// verifyCode needs to be entered correctly
['verifyCode', 'captcha'],
];
}