Yii : Rules Checking On Different Scenario - php

i want to check different validation in one controller.
i have problem is,
when user is registering first time at that time i want to do following validation
array('name, email, password, location, confirm_password', 'required','on'=>'create'),
array('confirm_password', 'compare', 'compareAttribute' => 'password','on'=>'create,fbuser'),
array('email','unique','on'=>'create'),
and if user is already registered with FB and trying to register at that time i want to do following validation (i don't want to validate email address in this case)
array('name, password, location, confirm_password', 'required','on'=>'fbuser'),
array('confirm_password', 'compare', 'compareAttribute' => 'password','on'=>'create,fbuser'),
this is my controller method...
public function actionCreate()
{
$model=new AppUser('create');
if(!Yii::app()->user->isGuest)
$this->redirect('/');
if(Yii::app()->request->isPostRequest)
{
if($model->isFbUser($_POST['email'])){
$model->scenario = 'fbuser';
if($model->validate())
$this->redirect(array('/Appuser/fbauth','email'=> $_POST['email']));
}
else
$model->scenario = 'create';
$model->attributes=$_POST;
if($model->save())
$this->redirect('/login');
}
$this->render('create',array(
'model'=>$model,
));
}
but its not validating properly.
can anyone help me to solve it?
Thanks in advance

I think the problem might be, that in the if (isFbUser) clause you do not assign the post data to the model before validating.
Your use of scenarios looks good to me.

Related

Laravel 5.3 Change Password

I'm building a Laravel 5.3 app and using the basic auth of laravel (artisan make:auth). Now, the "Forgot Password" functionality works fine, so if a user can't login because he doesn't know his password, he can get a mail to reset it. But now I want that logged in users can change their password as well. I found that, but this doesn't really help me. I also know that there's a ResetsPasswords trait but how do I use it? And is there already a view as well I can use?
Can somebody help me here?
You don't actually need to use the default password controller to achieve this, you can write your own function to get the same result, for example:
public function postUpdatePassword() {
$user = Auth::user();
$password = $this->request->only([
'current_password', 'new_password', 'new_password_confirmation'
]);
$validator = Validator::make($password, [
'current_password' => 'required|current_password_match',
'new_password' => 'required|min:6|confirmed',
]);
if ( $validator->fails() )
return back()
->withErrors($validator)
->withInput();
$updated = $user->update([ 'password' => bcrypt($password['new_password']) ]);
if($updated)
return back()->with('success', 1);
return back()->with('success', 0);
}
As you can see I registered a new custom validation rule to check if the new passowrd match the old one, to register the rule just go to "app/Providers/AppServiceProvider.php" and add to the boot function the next lines:
Validator::extend('current_password_match', function($attribute, $value, $parameters, $validator) {
return Hash::check($value, Auth::user()->password);
});
Now the validation rule works but you won't get the error message, to add an error message to the new rule you just created you will have to modify these lines in "resources/lang/en/validation.php":
'custom' => [
'current_password' => [
'current_password_match' => 'Current password is incorrect.',
],
],
That's it, now you can use this function to change your the current user password :)
If you want to keep your AppServiceProvider.php file clean of closures (for whatever reason; personally I like these small files neat and tidy) you can add perform the following two things:
1) Add the following to the boot() method of the AppServiceProvider.php
Validator::extend('current_password_match', 'App\Validators\PasswordMatch#check');
2) Add a new file 'app/Validators/PasswordMatch.php' in line with the closure mentioned above.
<?php
namespace App\Validators;
use Hash;
use Auth;
class PasswordMatch
{
public function check($attribute, $value, $parameters, $validator){
return Hash::check($value, Auth::user()->password);
}
}
You can then also add the validation rule messages to your extended FormRequest class messages() method like:
'current_password_match' => 'Current password is incorrect',

Laravel 5.1: How to authenticate only active users

I want to add another condition in AuthController but I don't know how to do it.
In my Users table, I have a Active field. If a User has Active == 0, i want to not let he/she login into the system. I don't know where to add that condition in Laravel 5.1 AuthController.
Please help me with that.
Thanks a lot guys!
You can override the postLogin method of the AuthenticatesUsers trait in your AuthController:
public function postLogin(Request $request)
{
/* PLACE HERE VALIDATION CODE... */
//attempt login but not log in the user
if ( ! Auth::attempt($credentials, false, false) )
{
//wrong credentials: redirect to login
}
//CREDENTIALS OK
//get user model from last attempt
$user = Auth::getLastAttempted();
//if user is not active...
if (! $user->active)
{
//do whathever you want: for example redirect to login
}
//USER IS ACTIVE
//login the user
Auth::login($user, $request->has('remember'));
//redirect where you need
}
Check the original: vendor\laravel\framework\src\Illuminate\Foundation\Auth\AuthenticatesUsers::postLogin method, to see if you need other instructions inside your overrided method (for example input validation)
You can add your custom postLogin() function in your Auth controller which overrides the default postLogin function with this condition
Auth::attempt(array('email' => $email, 'password' => $password, 'active' => 1))
This way you will only do auth of active users only
Cheers!!
Instead of overriding the whole postLogin function, add this to your AuthController
protected function getCredentials(Request $request)
{
$crendentials=$request->only($this->loginUsername(), 'password');
$crendentials['active']=1;
return $crendentials;
}

User information in modal before submitting form in Yii

I have a form and after user submits the form and validation goes OK, I want to ask him for his email and nickname in modal window. If user fills and submit an email and nickname, I want to validate it and save it as new record or get id of existing one (in case email was already used in past). If validation is not successful, user should be able to correct values in the same modal. If everything is OK, I want to save the form including create user id.
I already have form saving and user create/find process done. I just do not know, how to put this together, to work in scenario I described above. Could anyone explain, how this should be done in Yii? I am using Yii 1.1.15 and Yii Booster. Thank you.
In Yii the _form.php view file is used both in update.php and create.php views by default.
So, you might need to do smth. similar: insert form with modal in both update.php and create.php views.
Actions and different for these, so you keep logic separate; this is the MVC basic advantage.
public function actionCreate() {
$model = new Users;
if (isset($_POST['Users'])) {
$model->attributes = $_POST['Users'];
if ($model->save()) { // here in the save() method the valadation is included
// ONLY after we validate and successfully saved we go to update action
$this->redirect(array('update', 'id' => $model->id));
}
}
$this->render('create', array(
'model' => $model,
));
}
The main thing is that when you try to save save() method the validation happend automatically.
So if validation is not successful the logic brings back to the same action (create for example) with fields populated in view since model is already having data passed into it: $model->attributes = $_POST['Users'].
If validation is successful we redirect further. Not nessesary ajax form submit, even casual submit fits here.
public function actionUpdate($id) {
$model = $this->loadModel($id);
if (isset($_POST['Users'])) {
$model->attributes = $_POST['Users'];
if ($model->save()) { // after saving EXISTING record we redirect to 'admin' action
$this->redirect(array('admin'));
}
}
$this->render('update', array(
'model' => $model,
));
}
Forms in views(update/create) you keep as originally designed.
Validation for uniqueness is simple in model rules():
array('username, email', 'unique'),
Email valadation for email syntax is seems like this:
array('email', 'email'),

Lithium and validating login form (without model) - how?

Is there any way to use Validator on login form from Simple Authentication in Lithium tutorial. I know that it is better to use validation in model, but with login form there's no model, so, as I understand, I need to use Validator in the SessionsController, but I don't know how to do it (
What I am trying to do is in SessionsController:
<?php
namespace app\controllers;
use lithium\security\Auth;
use lithium\storage\Session;
use lithium\util\Validator;
class SessionsController extends \lithium\action\Controller {
private $rules = array(
'password' => array(
array('notEmpty', 'message' => 'password is empty'),
),
'email' => array(
array('notEmpty', 'message' => 'email is empty'),
array('email', 'message' => 'email is not valid')
)
);
public function add() {
if ($this->request->data && Auth::check('default', $this->request)) {
return $this->redirect('/');
}
// Handle failed authentication attempts
$errors = Validator::check($this->request->data, $this->rules);
return compact('errors');
}
public function delete() {
Auth::clear('default');
return $this->redirect('/');
}
/* ... */
}
and I'm expect that after empty form was sent, it will be rendered with errors, like in user creation from tutorial. But there are no errors showed, just login form again. Can I ever validate forms without models and how to do it in Lithium?
Thanks beforehand.
The errors rendered in the form are bound to an entity, which is bound to the form when you create it with $this->form->create($user). In this case only, the errors are displayed thanks to the form helper automatically.
If your need is to check, in the controller, the incoming data, you can check $this->request->data['password'] and return errors that you need to handle by yourself in the form view (with if (!empty($errors)) for example)

Cake PHP Validation not happening

Im new to cakePHP.I just learning the way to validate the data before storing into the database.I just did the following validation to check the birth date given by the user.
class User extends AppModel {
public $name = "Users";
public $validate = array (
'birth_dt' => array ( 'rule' => 'date',
'required' => true,
'allowEmpty' => false,
'message' => 'Please Give valid date' ));
}
I expected a error message when I give wrong data in the birth_dt field.But there is no errors in case of wrong data ,bug the data is not getting store in the database.If I give the valid data also the data is not getting stored.If I remove the validation part then data getting stored in the database.
It not only happen for date ,it happen for other fields like alphaNumeric ,email which I used in my form.Any one please tell what I did wrong.
This is my controller code,
<?php
class UsersController extends AppController{
var $name = 'Users';
var $uses = array('User','Dob');
var $helpers = array('Form');
function index() {
if ($this->request->is('post')) {
if ($this->request->data) {
$this->User->save ( $this->request->data );
$this->Session->setFlash("User Added!");
$this->redirect('/users');
}
}
}
There can be multiple possible issue.Try following.
Before saving user Create new record like this->User->create();
You don't have else part. Write like following in else & check,
else {
$this->Session->setFlash(__('User could not be saved',true));
}
You can check why save() failed by examining the validationErrors array in the User model. From the UsersController it can be access via $this->User->validationErrors.
Furthermore, your controller logic isn't quite right. A was mentioned in some of the comments, you don't check if save() was successful and you always state that a user was added, even when it's not true.
Try something like this:
if($this->request->is('post') && !empty($this->data)) {
if($this->User->save($this->data)) {
$this->Session->setFlash('User added!', 'flash_good');
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('Could not add player.', 'flash_bad');
}
}
This way, when save() fails for some reason, the user will remain in that action and the form will still be populated with the data the user entered. Furthermore, if you use $this->Form->input(...) to create you form elements the validation errors will be added to the form automagically.
I think your public $validate is wrongly written
Try this
class User extends AppModel {
public $name = "Users";
//For more strict validation you should have more than one parameter
//submitted to the rule array for date which requires the user to enter
// exactly what you need. for example 01/01/12 instead of 01/01/2012
//Please check the following address
//http://book.cakephp.org/2.0/en/models/data-validation.html#Validation::date
//However, this should work fine.
public $validate = array (
'birth_dt' => array (
'rule' => array('date'),
'required' => true,
'allowEmpty' => false,
'message' => 'Please Give valid date'
)
);
}
I think best way for validation is to integrate server side and client side validation.
form fields should be validated on focus out/blur with ajax call to server side validation rules via your controllers. This will ensure consistency in server side and client side validation.
bla..bla :)
I think validate error message not show
because you use $this->redirect('/users');
when redirect cakephp will be render view that clear message error :)
You can comment line //$this->redirect('/users'); and then try again :)

Categories