6

I created a change password functionality to change the admin password.I used this toutorial.
Now I face a problem in $model->validate().
Can anyone help me??

Controller

    public function actionIndex()
    {
        $id = 1;
        $model = User::model()->findByAttributes(array('usertype' => $id));
        $model->setScenario('changePwd');

        if (isset($_POST['User'])) {
            $model->attributes = $_POST['User'];
            if ($model->validate()) {
                $model->password = md5($model->new_password);
                if ($model->save()) {
                    Yii::app()->user->setFlash('success', "Password Changed Successfully!");
                }

             } else {
                 Yii::app()->user->setFlash('error', "Change Password failed!");
             }
         }

      $this->render('index', array('model' => $model)); 
   }

Model

    class User extends CActiveRecord
{
    public $old_password;
    public $new_password;
    public $repeat_password;
    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return '{{user}}';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('usertype, firstname, lastname, email, password, mobile, gender, dob, country, area, city, address, street, housenumber, extradirection, createdon', 'required'),
            array('usertype, country, area', 'numerical', 'integerOnly'=>true),
            array('firstname, lastname, email, mobile, dob, city, street, housenumber', 'length', 'max'=>155),
            array('password', 'length', 'max'=>225),
            array('gender', 'length', 'max'=>6),
            array('status', 'length', 'max'=>1),
            array('updatedon', 'safe'),
            // The following rule is used by search().
            // @todo Please remove those attributes that should not be searched.
            array('id, usertype, firstname, lastname, email, password, mobile, gender, dob, country, area, city, address, street, housenumber, extradirection, createdon, updatedon, status', 'safe', 'on'=>'search'),
            array('old_password, new_password, repeat_password', 'required', 'on' => 'changePwd'),
            array('old_password', 'findPasswords', 'on' => 'changePwd'),
            array('repeat_password', 'compare', 'compareAttribute'=>'new_password', 'on'=>'changePwd'),
        );
    }

public function findPasswords($attribute, $params)
    {
        $user = User::model()->findByPk(Yii::app()->user->id);
        //echo '<pre>';print_r($user);echo '</pre>';
        if ($user->password != md5($this->old_password))
            $this->addError($attribute, 'Old password is incorrect.');
    }

Form

    <div class="login_con_new"> 
    <div class="form">                  
        <?php    
        $form=$this->beginWidget('CActiveForm', array(
        'id'=>'change-password-form',   
        //'action' => Yii::app()->createUrl('login/authenticate'), 
        // 'enableAjaxValidation' => FALSE,
        'enableClientValidation' => true,
        'clientOptions' => array('validateOnSubmit' => true,),
        'htmlOptions' => array(
        'class' => 'form',
        )
        ));  
        ?>  
        <div class="col-sm-6">
            <h2 class="title">Change Password</h2> 
            <?php
    foreach(Yii::app()->user->getFlashes() as $key => $message) {
        echo '<div class="flash-' . $key . '">' . $message . "</div>\n";
    }
?>
            <div class="form-group">             
            <?php echo $form->labelEx($model,'Current_password'); ?>
            <?php echo $form->passwordField($model,'old_password',array('class'=>'form-control login-field','size'=>60,'maxlength'=>222)); ?>
            <?php echo $form->error($model,'old_password'); ?>  
            </div>
            <div class="form-group"> 
            <?php echo $form->labelEx($model,'new_password'); ?>
            <?php echo $form->passwordField($model,'new_password',array('class'=>'form-control login-field','size'=>60,'maxlength'=>222)); ?>
            <?php echo $form->error($model,'new_password'); ?> 
            </div> 
            <div class="form-group"> 
            <?php echo $form->labelEx($model,'repeat_password'); ?>
            <?php echo $form->passwordField($model,'repeat_password',array('class'=>'form-control login-field','size'=>60,'maxlength'=>222)); ?>
            <?php echo $form->error($model,'repeat_password'); ?> 
            </div>          
            <div class="form-group">
            <div class="col-lg-4" style="padding-left: 0px;">
            <?php echo CHtml::submitButton('Change',array('class' => 'btn btn-success','style'=>'color:white')); ?></div>  
        </div>      
    </div>
    <?php  $this->endWidget(); ?>
</div>      </div> 

The $valid returns me false and entering the else part.

Danila Ganchar
  • 10,266
  • 13
  • 49
  • 75
MIK
  • 876
  • 1
  • 16
  • 37

4 Answers4

1

I think in this line $model = User::model()->findByAttributes(array('usertype' => $id)); you did the mistake for usertype. This is user id.

Danila Ganchar
  • 10,266
  • 13
  • 49
  • 75
senthil
  • 195
  • 1
  • 1
  • 11
  • @Danila Ganchar: I manually assigned the $id =1,because id 1 is admin.I did this for admin to change password.The problem occurs in the controller didnt override the validation. – MIK Oct 01 '15 at 04:45
  • @MohammedIqbal can you show your POST data? And show your errors in model after **validate()**? `var_dump($model->getErrors());` – Danila Ganchar Oct 01 '15 at 06:17
  • @MohammedIqbal and change this `$model = new User; $model = User::model()->findByAttributes(array('usertype'=>$id));` to `$model = User::model()->findByPk($id);` – Danila Ganchar Oct 01 '15 at 06:20
0

The best way to debug these kind of errors is to actually check why the validate is returning false.

This can be done by checking the errors on a model. You can either output all the errors in the flash message, so a user knows what to correct, or just put it in a var_dump to help you debug.

Change your controller part to have this:

if($valid)
{
    $model->password = md5($model->new_password);
    if($model->save())
    {    
        Yii::app()->user->setFlash('success', "Password Changed Successfully!");
        // $this->redirect(array('dashboard/index', 'id' => 1));
    } 
    else
    {
        Yii::app()->user->setFlash('error', "Change Password failed!");
    }
}
else
{
    var_dump($model->errors);
    die();
}

It will show you the validation error in an array. Displaying which attribute has which validation error.

If you only want to validate and save the password fields. You can pass them in the validate and save method.

$model->validate(array('password')) and $model->save(TRUE, array('password'))
ThomasVdBerge
  • 7,483
  • 4
  • 44
  • 62
0

You can use senario for update. Like: http://www.yiiframework.com/forum/index.php/topic/31357-priority-to-rules-with-a-scenario/

Ishan Shah
  • 1,665
  • 2
  • 20
  • 42
  • Instead of posting links to an external site providing the answer, it is better to post the answer here. Links may get broken etc... – SnIpY Oct 01 '15 at 07:46
  • dear this is official yii framwork site. so it rare case to broken link. – Ishan Shah Oct 01 '15 at 08:46
-1

I found a method I dont know whether the answer is in correct method or not.
I found that the problem occurs during validation.so created an another model called changepassword for this operation ,only validate the three attributes which I given in rules.
And it worked fine.

   <?php 
class Changepassword extends CActiveRecord
{
    public $old_password;
    public $new_password;
    public $repeat_password;
    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return '{{user}}';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            // array('usertype, firstname, lastname, email, password, mobile, gender, dob, country, area, city, address, street, housenumber, extradirection, createdon', 'required'),
            // array('usertype, country, area', 'numerical', 'integerOnly'=>true),
            // array('firstname, lastname, email, mobile, dob, city, street, housenumber', 'length', 'max'=>155),
            // array('password', 'length', 'max'=>225),
            // array('gender', 'length', 'max'=>6),
            // array('status', 'length', 'max'=>1),
            // array('updatedon', 'safe'),
            // The following rule is used by search().
            // @todo Please remove those attributes that should not be searched.
            array('id, usertype, firstname, lastname, email, password, mobile, gender, dob, country, area, city, address, street, housenumber, extradirection, createdon, updatedon, status', 'safe', 'on'=>'search'),
            array('old_password, new_password, repeat_password', 'required', 'on' => 'changePwd'),
            array('old_password, new_password, repeat_password','length','max'=>225),
            array('old_password', 'findPasswords', 'on' => 'changePwd'),
            array('repeat_password', 'compare', 'compareAttribute'=>'new_password', 'on'=>'changePwd'),
        );
    }

public function findPasswords($attribute, $params)
    {
        $user = User::model()->findByPk(Yii::app()->user->id);
        if ($user->password != md5($this->old_password))
            $this->addError($attribute, 'Old password is incorrect.');
    }
    /**
     * @return array relational rules.
     */
    public function relations()
    {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
            'events' => array(self::HAS_MANY, 'Events', 'createdby'),
            'eventsJoinees' => array(self::HAS_MANY, 'EventsJoinee', 'userid'),
            'eventsRatings' => array(self::HAS_MANY, 'EventsRating', 'userid'),
            'usertype0' => array(self::BELONGS_TO, 'UserroleMaster', 'usertype'),
            'area0' => array(self::BELONGS_TO, 'AreaMaster', 'area'),
            'country0' => array(self::BELONGS_TO, 'CountryMaster', 'country'),
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'old_password'=>'Current Password',
            'new_password'=> 'New Password',
            'repeat_password'=>'Confirm Password',
        );
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     *
     * Typical usecase:
     * - Initialize the model fields with values from filter form.
     * - Execute this method to get CActiveDataProvider instance which will filter
     * models according to data in model fields.
     * - Pass data provider to CGridView, CListView or any similar widget.
     *
     * @return CActiveDataProvider the data provider that can return the models
     * based on the search/filter conditions.
     */
    public function search()
    {
        // @todo Please modify the following code to remove attributes that should not be searched.

        $criteria=new CDbCriteria;

        $criteria->compare('id',$this->id);
        $criteria->compare('usertype',$this->usertype);
        $criteria->compare('firstname',$this->firstname,true);
        $criteria->compare('lastname',$this->lastname,true);
        $criteria->compare('email',$this->email,true);
        $criteria->compare('password',$this->password,true);
        $criteria->compare('mobile',$this->mobile,true);
        $criteria->compare('gender',$this->gender,true);
        $criteria->compare('dob',$this->dob,true);
        $criteria->compare('country',$this->country);
        $criteria->compare('area',$this->area);
        $criteria->compare('city',$this->city,true);
        $criteria->compare('address',$this->address,true);
        $criteria->compare('street',$this->street,true);
        $criteria->compare('housenumber',$this->housenumber,true);
        $criteria->compare('extradirection',$this->extradirection,true);
        $criteria->compare('createdon',$this->createdon,true);
        $criteria->compare('updatedon',$this->updatedon,true);
        $criteria->compare('status',$this->status,true);

        return new CActiveDataProvider($this, array(
            'criteria'=>$criteria,
        ));
    }

    /**
     * Returns the static model of the specified AR class.
     * Please note that you should have this exact method in all your CActiveRecord descendants!
     * @param string $className active record class name.
     * @return User the static model class
     */
    public static function model($className=__CLASS__)
    {
        return parent::model($className);
    }
}

?>

Friends if anyone get correct method please post it.

MIK
  • 876
  • 1
  • 16
  • 37