Related
No Model Validations are happening On Update. $model->validate() returns true always. So save happens even if wrong data
Following is change password functionality
View
<?php echo $form->passwordField($model, 'currentpassword', array('class'=>'form-control','required'=>'required', 'value'=>'', 'maxlength'=>'40', 'pattern'=>'[a-zA-Z0-9-]{6,40}', 'title'=>'Password should be 6-40 characters containing a-z and 0-9')); ?>
<?php echo $form->error($model, 'currentpassword'); ?>
<?php echo $form->passwordField($model, 'password', array('class'=>'form-control','required'=>'required', 'value'=>'', 'maxlength'=>'40', 'pattern'=>'[a-zA-Z0-9-]{6,40}', 'title'=>'Password should be 6-40 characters containing a-z and 0-9')); ?>
<?php echo $form->error($model, 'password'); ?>
<?php echo $form->passwordField($model, 'confirmpassword', array('class'=>'form-control','required'=>'required', 'value'=>'', 'maxlength'=>'40', 'pattern'=>'[a-zA-Z0-9-]{6,40}', 'title'=>'Password should be 6-40 characters containing a-z and 0-9')); ?>
<?php echo $form->error($model, 'confirmpassword'); ?>
Controller
public function actionChangepassword()
{
$this->layout = (Yii::app()->request->isAjaxRequest) ? '//layouts/ajax' : '//layouts/precolumn2';
$model = new User('changepassword');
$data = array();
if (isset($_POST['User'])) {
$model = User::model()->findByPk(Yii::app()->User->getId());
$model->attributes=$_POST['User'];
if ($model->save()) {
$message = array(
'type' =>'success',
'message' =>'Password Changed.');
$data['message'] = $message;
}
}
$data['model'] = $model;
$this->render('changepassword',$data);
}
Model
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('name, user_type_id', 'required','on'=>'signup'),
array('name, email', 'length', 'max'=>255),
array('email', 'required','on'=>array('recover','signup')),
array('email', 'exists','on'=> 'recover'),
array('email', 'unique'),
array('email', 'email'),
array('user_login_count, user_like_count, user_share_count, user_view_count, user_comment_count, user_rating_count', 'numerical', 'integerOnly'=>true),
array('password', 'length', 'max'=>100),
array('password, confirmpassword', 'required','on'=>array('signup','resetpassword','changepassword')),
array('confirmpassword', 'compare', 'compareAttribute'=>'password','on'=>array('signup','resetpassword','changepassword'),'message'=>'Passwords dont match'),
array('currentpassword', 'compareCurrentPassword','on'=>array('changepassword')),
);
}
Check out your line $model = User::model()->findByPk(Yii::app()->User->getId());
Looks like you need to set the scenario in there as you're creating a new user without the 'changepassword' scenario.
For example:
$model = User::model('changepassword')->findByPk(Yii::app()->User->getId());
How can i update, some field, forexample firstname or lastname or email without doing any change on password field
My model
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('username, salt, password, firstname, lastname, email', 'required', 'on' ),
array('superuser, status', 'numerical', 'integerOnly'=>true),
array('username, password, salt', 'length', 'max'=>32),
array('firstname, lastname,image', 'length', 'max'=>80),
array('email', 'length', 'max'=>128),
array('id, username, password, salt, firstname, lastname, email, superuser, status', 'safe', 'on'=>'search'),
);
}
AND in model i have
public function beforeValidate()
{
$this->salt = '1294455567';
return parent::beforeValidate();
}
you can do like this also...
public function beforeSave()
{
if(!$this->getIsNewRecord())
unset($this->password);
return parent::beforeSave();
}
Hope it may help you..
You can use Yii scenarions. For example in your model you has next validation rules:
public function rules()
{
return array(
array('username, salt, password, firstname, lastname, email', 'required', 'on' => 'create'),
array('email, username, firstname, lastname', 'someValidationRuleOrMethod', 'on' => 'update'),
);
}
When you need to create new user, need to set validation scenario:
$model = new User('create');
//some code
$model->validate();
Or:
$model = new User();
$model->scenario = 'create';
//some code
$model->validate();
When you need update exists user - use update scenario instead create:
$model = User::model()->findByPk($someId);
$model->scenarion = 'update';
//some code
$model->validate();
Also, I found this receipt on Russian Yii blog.
UPD You can use static method to hash password, and can call it every where:
public static function hashPassword($password)
{
return CPasswordHelper::hashPassword($password);
}
Create a User model object for single user, then update by assigning new value for field:
...
$user = User::model()->find("`t`.`username` = :USER", array(':USER' => 'example.user'));
$user->firstname = 'New First Name';
$user->lastname = 'New Last Name';
$user->email = 'email#user.new';
# Now update User here
if($user->update()) {
echo 'Updated';
}
...
Hi all what i have done is here....
My controller ::
public function actionUpdate($id){
$model=$this->loadModel($id,'User');
$oldImage = $model->image;
// $old_password = $model->password;
$model->password = '';
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['User']))
{
$model->attributes=$_POST['User'];
//If image not uploaded then set old image
if(!$this->uploadImage($model)){
$model->image = $oldImage;
}
if($model->save()){
Yii::app()->user->setFlash('success', "Data Updated successfully"); // Flash Message
$this->redirect(array('admin','id'=>$model->user_id));
}
}
$this->render('update',array(
'model'=>$model,
));
}
My Model
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('first_name, last_name, password, email,repeat_password', 'required',"on"=>'create'),
array('first_name, last_name, email', 'required',"on"=>'update'),
array('first_name, last_name', 'length', 'max'=>100),
array('password', 'length', 'max'=>30,'min'=>6),
array('repeat_password', 'compare', 'compareAttribute' => 'password', 'message'=>'Confirm Password must be same as password'),
array('email', 'length', 'max'=>50),
array('email', 'unique'),
//array('image', 'file', 'types'=>'jpg, gif, png'),
array('image', 'safe'),
// The following rule is used by search().
// #todo Please remove those attributes that should not be searched.
array('user_id, first_name, last_name, email', 'safe', 'on'=>'search'),
);
}
public function beforeSave(){
if(!empty($this->password))
$this->password = md5($this->password);
else
unset($this->password);
return parent::beforeSave();
}
My View ::
<?php
// If user update profile or update data then don't show password
if( ((#Yii::app()->request->getParam('act')!=="profile") && empty($_GET["id"])) || #$_GET["act"]=='changepwd' )
{
?>
<div class="row">
<?php echo $form->labelEx($model,'password'); ?>
<?php echo $form->passwordField($model,'password',array('maxlength'=>20,'minlength'=>6)); ?>
<?php echo $form->error($model,'password'); ?>
</div>
<div class="row"><!-- Confirm password -->
<?php echo $form->labelEx($model,'Confirm Password'); ?>
<?php echo $form->passwordField($model,'repeat_password',array('maxlength'=>20,'minlength'=>6)); ?>
<?php echo $form->error($model,'repeat_password'); ?>
</div>
<?php } ?>
public function actionUpdate($id) {
$model=$this->loadModel($id);
if(isset($_POST['User']))
{
$password = $model->password;
$model->attributes=$_POST['User'];
if($password === $model->password) {
$model->password = $password;
} else {
$model->password = md5(SALT . $model->password);
}
if($model->save())
$this->redirect(array('view','id'=>$model->id));
}
$this->render('update',array(
'model'=>$model,
));
}
here is my code, when i am calling this method an error occured and say "Invalid argument supplied for foreach() ". Anyone? any idea ?
$state = array(
'state_status_id' => '4',
'fax_format_preference_id' => '2',
'state_reference_code' => $state_ref->reference_code,
'leap_fqdn' => $leap_fqdn ,
'description' => $state_ref->name."--".$leap_fqdn,
);
$model = new States;
$model->setAttributes($state, false);
$model->setIsNewRecord(true);
$res = $model->save();
here is stack info:
public function createValidators(){
$validators=new CList;
foreach($this->rules() as $rule)
{
if(isset($rule[0],$rule[1])) // attributes, validator name
$validators->add(CValidator::createValidator($rule[1],$this,$rule[0],array_slice($rule,2)));
else
throw new CException(Yii::t('yii','{class} has an invalid validation rule. The rule must specify attributes to be validated and the validator name.',
array('{class}'=>get_class($this))));
}
return $validators;
}
this is Rule method, i don't know why this is not working while same things is working fine in other models and controllers.
public function rules()
{
//Rules for admins editing state information
if(Roles::has_permission('update','all_states'))
{
return array(
array('state_status_id, fax_format_preference_id, state_reference_code, leap_fqdn, description', 'required'),
array('state_status_id, fax_format_preference_id', 'length', 'max'=>10),
array('leap_fqdn', 'length', 'max'=>128),
array('description', 'length', 'max'=>255),
array('updated_at,default_user_role', 'safe'),
// Please remove those attributes that should not be searched.
array(' state_status_id, fax_format_preference_id, created_at, updated_at, state_reference_code, leap_fqdn, description', 'safe', 'on'=>'search'),
);
}
if(Roles::has_permission('update','state_state'))
{
return array(
array('fax_format_preference_id', 'required'),
array('fax_format_preference_id', 'length', 'max'=>10),
array('updated_at', 'safe'),
);
}
}
Apparently in your case (which causes the error) both condition checks are false, hence rules-method returns nothing.
Try to add return array(); to the rules method, it will be sort of fallback in case both checks fail.
public function rules()
{
// your current code
return array(); //fallback
}
I am creating change password functionality, all things are working fine except the old password validation rule.here is my code
public function rules()
{
return array(
array('is_active', 'numerical', 'integerOnly'=>true),
array('first_name, joining_date,last_name, employee_code, username, password, role', 'required','on'=>array('create')),
array('employee_code', 'numerical', 'integerOnly'=>true),
array('username','email'),
array('username','valid_username','on'=>array('create')),
//array('username', 'contraints', 'readOnly'=>true, 'on'=>'update'),
array('currentPassword, newPassword, newPasswordRepeat', 'required','on'=>array('change')),
//array('newPassword', 'length', 'min' => 6, 'max'=>20, 'message'=>Yii::t("translation", "{attribute} is too short.")),
//array('newPassword','ext.SPasswordValidator.SPasswordValidator', 'preset' => 'strong', 'max' => 41),
array('newPassword', 'compare', 'compareAttribute'=>'newPasswordRepeat','on'=>array('change')),
array('currentPassword', 'equalPasswords','on'=>array('change')),
array('verifyCode', 'captcha', 'allowEmpty'=>!CCaptcha::checkRequirements(),'on'=>array('forgotPassword')),
array('joining_date', 'safe'),
array('user_id, first_name, last_name, employee_code, username, password, role, joining_date, pending_regular_leave, pending_medical_leave, allocated_regular_leave, allocated_medical_leave, is_active', 'safe', 'on'=>'search'),
);
}
My change password function is
public function equalPasswords($attribute, $params)
{
$user = Users::model()->findByPk(Yii::app()->user->id);
if ($user->password != md5($attribute))
{
$this->addError($attribute, 'Old password is incorrect.');
}
}
Update method
:
public function actionChange()
{
$model=new Users;
$model->setScenario('change');
if (isset($_POST['Users'])) {
$model->setAttributes($_POST['Users']);
if($model->validate())
{
$pass = md5($_POST['Users']['newPassword']);
$userModel = Users::model()->findByPk(Yii::app()->user->id);
$userModel->password = $pass;
$data = $userModel->update();
Yii::app()->user->setFlash('success',"Password changed successfully!");
}
}
$this->render('change_password', array('model'=>$model,true));
}
when i try to change password with all the correct parameters (correct old password,new password,retype password) it update the password but also shows me error that your old password does not correct .please help me to resolve this as i am new to Yii.
Thanks in advanced.
I'm not sure but you can try once.
$user = Users::model()->findByPk(Yii::app()->user->id);
if ($user->password != md5($this->attributes['currentPassword']))
{
$this->addError($attribute, 'Old password is incorrect.');
}
change md5($attribute) to md5($this->attributes['currentPassword']
And add this in your rules
public function rules()
{
public $currentPassword;
// your rules here
}
In the validator you receive the attribute name, not the value in $attribute. To get the value you'd have to:
$value = $this->$attribute;
problem defenition
i have one model called 'user.php'
i have some validation rules on the same as follows
i am now going to create a password reset form
in that form i have a text box name email (same email used in user model)
in password reset form i would like to check wheather this user is a registered one if it a registered one will send the password reset link
I DONT KNOW HOW TO VAIDATE THIS EMAIL FIELD , ANY HELP HIGHLY APPRECIABLE AS I AM NEW IN YII
user.php
class Users extends CActiveRecord
{
public $cpassword;
public static function model($className=__CLASS__)
{
return parent::model($className);
}
public function tableName()
{
return 'users';
}
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('email, password, user_type , cpassword','required'),
array('email', 'length', 'max'=>200),
array('email', 'unique'),
array('email', 'email'),
array('password', 'length', 'max'=>300),
array('cpassword', 'length', 'max'=>300),
array('user_type', 'length', 'max'=>5),
array('cpassword', 'compare', 'compareAttribute' => 'password'),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('id, email, password, user_type ', 'safe', 'on'=>'search'),
);
}
public function relations()
{
return array(
);
}
public function attributeLabels()
{
return array(
'id' => 'ID',
'email' => 'Email',
'password' => 'Password',
'user_type' => 'User Type',
'cpassword' => 'Confirm Password'
);
}
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id);
$criteria->compare('email',$this->email,true);
$criteria->compare('password',$this->password,true);
$criteria->compare('user_type',$this->user_type,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
public function beforesave()
{
$this->password=md5($this->password);
return true;
}
}
You can check on the submit with something like:
$user = User::model()->find("email = '".trim($model->email)."'");
if (!empty($user)){
// users exists
} else {
// user does not exist
}
If you really want to use the model, you can setup a rule where email must be unique like so:
array('email', 'unique', 'message' => 'Email already in use'),
You can then check if the model validates on the submit, specifically the email field. If it doesnt validate the email address exists
Last, you can validate a single model attribute like so:
if($model->validate(array('attribute_name'))
// valid
}
Here is one way of doing the complete action (not the best way but the easiest to understand!)
public function actionResetpassword(){
$model = new User;
if(isset($_POST['User'])){
$model->attributes = $_POST['User']; // this is the form as completed by the user
$user = User::model()->find("email = '".trim($model->email)."'");
if (!empty($user)){
// send user their new email
$this->render("passwordreset"); // user exists, render confirmtion page
} else {
// user does not exist, render form and pass $error_message variable with messasge
$this->render("resetpassword",array(
"model" => $model,
"error_message" => "No such user found!",
));
}
} else {
// this will be rendered if the user has not submitted the form yet
$this->render("resetpassword",array(
"model" => $model,
));
}
}
public function rules() {
$action = Yii::app()->controller->action->id;
if($action == 'login'){
return array(array('username,password', 'required'), array('password', 'length', 'min'=>6, 'max'=>12), array('rememberMe', 'boolean'), array('password', 'authenticate'), array('id, jsid, email, username, password, status', 'safe', 'on'=>'search'));
}else{
return array( array('oldpassword,password1,password2', 'required'), array('password1,password2, oldpassword', 'length', 'min'=>6, 'max'=>12),array('password1', 'compare', 'compareAttribute'=>'password2'), array('id, jsid, email, username, password, status', 'safe', 'on'=>'search'),);
}
}