4

I am 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:

// 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;
}
peterh
  • 11,875
  • 18
  • 85
  • 108
Dallby
  • 596
  • 4
  • 19

1 Answers1

2

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.

Maxime Rainville
  • 2,019
  • 23
  • 29
  • Hey thanks for the reply. I tried that code and got the following error upon submission of the form: `[Warning] crypt() expects parameter 1 to be string, array given` – Dallby Aug 28 '16 at 22:50
  • I've updated the answer. I naively assumed the ConfirmedPasswordField would return a single value if both password fields matched. It returns an array for each password field with the following keys: _Password and _ConfirmPassword. You shouldn't need to validate they both have the same value however. The ConfirmPasswordField will self-validate and your form action will not be called if they do not match. – Maxime Rainville Aug 28 '16 at 23:06
  • Excellent job. That works. Thanks for all your help. – Dallby Aug 28 '16 at 23:10