3

I wrote a custom feeds fetcher class that does an authentication call before it gets the feed. In its settings, I have username and password fields in the form. I tried to set the field #type to password, but it seemed not to use the #default_value element, thus obliterating the saved password when you hit the 'save' button.

This maintains the password, but shows it in plaintext:

$form['password'] = array(
  '#type' => 'textfield',
  '#title' => t('Password'),
  '#description' => t(''),
  '#default_value' => $this->config['password'],
);

This shows dots for the password, but does not populate the field using the #default_value, causing you to have to enter the password any time you want to change and save any value on the form:

$form['password'] = array(
  '#type' => 'password',
  '#title' => t('Password'),
  '#description' => t(''),
  '#default_value' => $this->config['password'],
);

I need to be able to have the user enter a password and have it stay no matter what other values they change on the form and save. Does this preclude me from using the password field type, since it appears not to use the #default_value element?

4 Answers 4

3

You can try to add your default value directly with #attributes option just like that :

$form['password'] = array(
  '#type' => 'password',
  '#title' => t('Password'),
  '#description' => t(''),
  '#attributes' => array('value' => $this->config['password']),
);

After I'm not sure if you will be able to get that value on validate and submitcallback, you should check.

3

This is a pretty common use-case, but you wouldn't want to re-expose the password to the client at any point by setting a password field's default value. So either the user can change a password by updating the password input, or leave it unchanged by leaving the field blank.

To implement this in code, you can add another submit handler to your form:

$form['password'] = array(
    '#type' => 'password',
    '#title' => t('Password'),
    '#description' => t(''),
);

$form['#submit'] = array_merge(array('my_default_password'), (array) $form['#submit']);

And in this handler, put the password back in:

function my_default_password($form, &$form_state) {
    if (empty($form_state['values']['password'])) {
        $form_state['values']['password'] = variable_get('the_password');
    }
}

This way you don't have to expose the existing password to the user, which wouldn't be considered a good security practice, but you also get the expected workflow.

Note that I assumed the default password is stored in 'the_password' variable, but your code likely would have it elsewhere.

2

A password field can't have a default value, that makes no sense. It would be written in plaintext in the attribute so all that password specific stuff would be pointless (*, copy-protection, ...).

Either use a normal textfield with a default value (that's what most of those forms do I think) or leave it empty, add some special code to only overwrite the existing value if not empty and add a corresponding description.

1
  • 2
    > A password field can't have a default value, that makes no sense. Password tags with default values are perfectly valid X?HTML. It may make no sense to you, but it may be useful to others. The point is: we (i.e. Drupal and framework developers in general) should not try to dictate what is good or bad to other developers, by crippling our interfaces, just because something does not smell good to you personally. Maybe you should write to the W3C and ask them to forbid default values for password fields in the next revision of the X?HTML DTD. But in the meantime, there's no excuses to prevent t
    – user16117
    Mar 29, 2013 at 1:47
0

I was able to accomplish this with validation and hook_update_N. In my case, I had a settings page with a few form elements, one of them being a password field. If they filled out other settings, but not the password and clicked Save, it would set the password to a blank string.

In my case, I validated the form like this in mymodule.module:

<?php    

function mymodule_form_callback($form, &$form_state) {
  $form = array();
  // code for other elements here...
  $form['my_password_field'] = array(
    '#type' => 'password_confirm',
    '#title' => t('Enter password'),
  );      
  return $form;
}

function mymodule_form_callback_validate($form, &$form_state) {
  if (empty($form_state['values']['my_password_field'])) {
    $form_state['values']['my_password_field'] = variable_get('my_password_field');
  }
}

Then created a default value in mymodule.install:

<?php

function mymodule_update_7001() {
  variable_set('my_password_field', 'Jabron1jabroni');
}

To get this default to be set initially, you have to run Drupal updates in the UI or with drush updb -y if you use Drush.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.