user_delete() should not remove the content created by user

Created on 16 March 2018, almost 7 years ago
Updated 23 April 2024, 9 months ago

Problem/Motivation

I had to remove users from a site programmatically and I was surprised that their content disappeared as well without any notice or trace: there were no entries in the watchdog.

I checked /admin/config/people/accounts and realized, that there is no option to delete the user's content upon the deletion of the user:

When cancelling a user account
Disable the account and keep its content.
Disable the account and unpublish its content.
Delete the account and make its content belong to the Anonymous user.

So regardless of the settings the user's content should have been remained.

Steps to reproduce

1. Create a new user , check it's uid.
2. Create a node with this new user.
3. Delete the user programmatically, I did it the following way:

3.1. create a file userdelete.php with the following content in your projects web root:
<?php
$userId = 2; // replace 2 with the uid of your user
$user = \Drupal\user\Entity\User::load($userId);
$user->delete();

3.2. run it with drush:
drush php-script userdelete.php

4. Check if the node is deleted - for me it was deleted without any notice, and trace in the watchdog.

Proposed resolution

Probably the delete() method in User should respect the settings, maybe it could provide a way to delete the user's content (and in this case create watchdog entries!), but the current silent and traceless deletion should not be the default behavior.

There is a node_user_predelete($account) hook which deletes the user's nodes upon user->delete() - maybe that should be changed.

✨ Feature request
Status

Active

Version

11.0 πŸ”₯

Component
User moduleΒ  β†’

Last updated 7 days ago

Created by

πŸ‡­πŸ‡ΊHungary pedrop

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡¨πŸ‡¦Canada liquidcms

    We just released code which syncs user accounts to Active Directory accounts. Shocked to see that 20% of our site's content was also deleted as one of the editorial team had recently quit the group (so no longer listed in AD). Never knew about user_cancel() but if it's required at all, should the default case not ALWAYS be to NOT to delete content?

    Looking at what all else was wiped; although this editor also created a lot of taxonomy terms and even though those are not specifically tagged with an owner; they do, for some reason, have a translation owner. But those did not get deleted. Nor did any of his blocks. So seems a bit inconsistent - and silly.

    As it is somewhat related; i never understood the options when using the UI:

    • Disable the account and keep its content.
    • Disable the account and unpublish its content.
    • Delete the account and make its content belong to the Anonymous user. This action cannot be undone.
    • Delete the account and its content. This

    action cannot be undone.

    - Why an option to assign to Anon? Would this not give anon access to all this content (perhaps not?).

    - Why is the obvious (and preferred default) option not even listed here: delete user and assign to UID 1?

  • πŸ‡¬πŸ‡§United Kingdom catch

    Assigning to anonymous doesn't give users access to edit content, unless you set up permissions to give anonymous users editing permissions explicitly.

    Assigning content to user 1 would mean that on Drupal.org a deleted user's content would appear as if it was authored by Dries. On many other sites that account is blocked.

    I don't see how this would be preferred over assigning to anonymous.

    Changing the default to assign the content to anonymous (or anything less destructive) seems like a good idea but probably best in a new issue.

  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    I guess for better and self-explaining DX there should be an API method like

    $user->cancel();
    

    which by default respects the configured cancel method:

    \Drupal::config('user.settings')->get('cancel_method');
    

    when canceling the given user.

    It could also provide an optional argument to override the cancelation method:

    $user->cancel('user_cancel_block');
    
  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica
Production build 0.71.5 2024