Dallby Dallby - 3 months ago 19
PHP Question

Silverstripe: ConfirmedPasswordField not saving new password

Hi guys I'm trying to allow users to update their password on the front end. All the other fields update, except for this one. I'm on Silverstripe Version 3.4.0. This probably isn't the best way to handle this, but I'm relatively new to SS so be gentle.:

// Edit & Save your details
public function EditMyDetails() {
//Include JS for updating details
Requirements::javascript('module-memberprofiles/javascript/MemberProfileUpdate.js');
Requirements::set_force_js_to_bottom(true);

$fields = new FieldList(
$leftCol = CompositeField::create(
TextField::create('FirstName', 'First Name')
->setFieldHolderTemplate('UserDetails_FieldHolder'),
TextField::create('Surname', 'Surname')
->setFieldHolderTemplate('UserDetails_FieldHolder'),
CompositeField::create(
TextField::create('Address', ''),
TextField::create('Suburb', ''),
CompositeField::create(
DropdownField::create('State', '', singleton('Member')->dbObject('State')->enumValues())->setFieldHolderTemplate('UserDetails_StatePostCode'),
TextField::create('PostCode', '')->setFieldHolderTemplate('UserDetails_StatePostCode')
)->addExtraClass('row')
)
->addExtraClass('userdetails-address wrap')
->setFieldHolderTemplate('UserDetails_AddressHolder'),
TextField::create('Phone', 'Phone')
->setFieldHolderTemplate('UserDetails_FieldHolder'),
TextField::create('Email', 'Email')
->setFieldHolderTemplate('UserDetails_FieldHolder')
)->setFieldHolderTemplate('UserDetails_CompositeField'),
$rightCol = CompositeField::create(
ConfirmedPasswordField::create('Password', 'Change Password', null, null, $showOnClick = true)
)->setFieldHolderTemplate('UserDetails_CompositeField')
);

$actions = new FieldList(new FormAction('SaveMyDetails', 'Save Profile'));

$validation = new RequiredFields(array('FirstName','Surname','Email'));

$form = new Form ( $this, 'EditUserDetails', $fields, $actions, $validation);
$form->loadDataFrom(Member::currentUser());
$form->setTemplate('MemberProfilePage_UserDetailsForm');

return $form;
}

public function SaveMyDetails($data, $form) {
$table = Member::currentUser();
$members = Member::get();
$emailExists = $members->filter(array(
'Email' => $data['Email'],
'ID:not' => $table->ID
));

if( $emailExists->count() > 0 ) {
$form->sessionMessage('Sorry, that email address already exists. Please try again','bad');
return $this->redirectBack();
} else {
$form->sessionMessage('Your details have been updated.','good');
}

$form->saveInto($table);
$table->write();
$this->redirectBack();

return $this;
}

Answer

Like any other good CMS, SilverStripe will not store passwords in plain text in the database for security reasons. The password needs to be hashed, so you can not set it directly.

That's why your call to $form->saveInto($table); doesn't touch the password.

The SilverStripe Member class has a changePassword() method you can call to update the password. Call it just after saving your form data into your Member object:

$form->saveInto($table);
$table->changePassword($data['Password']['_Password']);
$table->write();

I haven't tested this code snippet, but I'm pretty sure it will work.

On a related topic, you might want to have look at the Member Profile plugin.

Hope this helps.