I am porting a module from Drupal 7 to Drupal 9. The code uses hook_user_presave() to save two fields on the fly into the user profile data.

 * Implements hook_user_presave().
function affiliate_user_presave(&$edit, $account, $category) {
  $edit['data']['affiliate_optin'] = isset($edit['affiliate_optin']) ? $edit['affiliate_optin'] : 0;
  $edit['data']['affiliate_homepage'] = isset($edit['affiliate_homepage']) ? $edit['affiliate_homepage'] : FALSE;

The similar one in Drupal 9 seems to be hook_entity_presave().

 * Implements hook_ENTITY_TYPE_presave() for user entities.
function uber_affiliate_user_presave(UserInterface $account) {
  // code here

However there is only a single parameter to the function and so the edit values in the user profile form submit are not available here. So this means that there are better alternatives in Drupal 9.

I am thinking of writing an event subscriber, but it won't get the form submitted values.

  • 1
    Does this old change record answer the question? drupal.org/node/1554986
    – mona lisa
    Sep 28, 2022 at 11:09
  • Well this looks a good start. However how do I get the values in form submit into presave. This seems to have been predesigned that way in Drupal 7 with the $edit parameter?
    – Binny
    Sep 28, 2022 at 16:33

1 Answer 1


As pointed out from @cilefen, the $edit parameter has been removed from the parameter passed to hook_user_presave(), which (starting from Drupal 8) is now documented under hook_ENTITY_TYPE_presave(). $edit argument removed from hook_user_update/insert/presave() is the relevant change record.

The only way to get the submitted form values is to add a form submission handler to the form with hook_form_alter() or hook_form_FORM_ID_alter(). Form submission handlers, like form validation handlers(), have access to the submitted values via $form_state->getValue(), to get a single submitted value, or $form_state->getValues(), to get an array containing all the submitted values.

Also, what that code saves in $edit['data'] now needs to be saved with UserData::set(). Since that class is used to implement a service, the correct code to use it is similar to the following one.

$user_data = Drupal::service('user.data');
$user_data->set($module, $uid, $name, $value);

The parameters are the following.

  • $module
    the machine name of the module that is saving the data
  • $uid
    the user ID to which the data is associated
  • $name
    the name associated with the saved data
  • $data
    the data to save

To get the already saved data, or to check it has been already saved, there is UserData::get(). Passing $module, $uid, and $name that method will return NULL when the data hasn't been yet saved.

The change record that documents the new user.data service is users.data column replaced with user_data API.

  • I think hook_ENTITY_presave is called before form submit is handler is called as I am not able to get the values inside hook_user_presave.
    – Binny
    Sep 29, 2022 at 5:27
  • hook_ENTITY_TYPE_presave() is invoked from the form submission handler for the form to edit an entity or create an entity. The answer isn't suggesting to use that hook, but to add a form submission handler to the edit form.
    – apaderno
    Sep 29, 2022 at 7:04
  • The only way to get the submitted form values is to add a form submission handler to the form with hook_form_alter() or hook_form_FORM_ID_alter(). How to add a form submission handler has not changed, passing from Drupal 7 to Drupal 8.
    – apaderno
    Sep 29, 2022 at 7:06
  • Thanks got it now.
    – Binny
    Sep 30, 2022 at 9:16

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.