XF 1.2 Undelete someone

winter4w

Active member
So someones account got deleted by accident and now it shows them as a guest. How can I give them their post and likes back?
 
Never a good idea to disagree with Jake, but I *believe* that while not a complete undelete Wandigo's add-on does more than just reassociate posts with a username.
 
It's a question of what can be done without a backup.

Upon deleting a user account XenForo executes the following (from the user datawriter):

Code:
	/**
	 * Post-delete handling.
	 */
	protected function _postDelete()
	{
		$db = $this->_db;
		$userId = $this->get('user_id');
		$userIdQuoted = $db->quote($userId);

		$db->delete('xf_user_alert', "alerted_user_id = $userIdQuoted");
		$db->delete('xf_user_alert_optout', "user_id = $userIdQuoted");
		$db->delete('xf_user_change_log', "user_id = $userIdQuoted");
		$db->delete('xf_user_change_temp', "user_id = $userIdQuoted");
		$db->delete('xf_user_confirmation', "user_id = $userIdQuoted");
		$db->delete('xf_user_external_auth', "user_id = $userIdQuoted");
		$db->delete('xf_user_field_value', "user_id = $userIdQuoted");
		$db->delete('xf_user_follow', "follow_user_id = $userIdQuoted");
        $db->delete('xf_user_follow', "user_id = $userIdQuoted");
		$db->delete('xf_user_group_change', "user_id = $userIdQuoted");
		$db->delete('xf_user_group_promotion_log', "user_id = $userIdQuoted");
		$db->delete('xf_user_group_relation', "user_id = $userIdQuoted");
		$db->delete('xf_user_ignored', "ignored_user_id = $userIdQuoted");
        $db->delete('xf_user_ignored', "user_id = $userIdQuoted");
		$db->delete('xf_user_news_feed_cache', "user_id = $userIdQuoted");
		$db->delete('xf_user_trophy', "user_id = $userIdQuoted");
		$db->delete('xf_user_upgrade_active', "user_id = $userIdQuoted");
		$db->delete('xf_user_upgrade_expired', "user_id = $userIdQuoted");
		$db->delete('xf_warning', "user_id = $userIdQuoted");

		$db->delete('xf_permission_combination', "user_id = $userIdQuoted");
		$db->delete('xf_permission_entry', "user_id = $userIdQuoted");
		$db->delete('xf_permission_entry_content', "user_id = $userIdQuoted");

		if ($this->get('is_moderator'))
		{
			$db->delete('xf_moderator',  "user_id = $userIdQuoted");
			$db->delete('xf_moderator_content',  "user_id = $userIdQuoted");
		}
		if ($this->get('is_admin'))
		{
			$db->delete('xf_admin',  "user_id = $userIdQuoted");
			$db->delete('xf_admin_permission_entry',  "user_id = $userIdQuoted");
		}
		if ($this->get('is_banned'))
		{
			$db->delete('xf_user_ban',  "user_id = $userIdQuoted");
		}

		$db->delete('xf_profile_post', "profile_user_id = $userIdQuoted");

		$db->delete('xf_news_feed', "user_id = $userIdQuoted");

		$db->delete('xf_conversation_user', "owner_user_id = $userIdQuoted");
		// note: leaving records in conversation recipient to keep data somewhat intact for others

		$db->delete('xf_ip', "content_type = 'user' AND user_id = $userIdQuoted");
		// note: leaving content-associated IPs

		$db->delete('xf_forum_read', "user_id = $userIdQuoted");
		$db->delete('xf_thread_read', "user_id = $userIdQuoted");
		$db->delete('xf_forum_watch', "user_id = $userIdQuoted");
		$db->delete('xf_thread_watch', "user_id = $userIdQuoted");

		$this->getModelFromCache('XenForo_Model_Avatar')->deleteAvatar($userId, false);

		if ($this->get('user_state') == 'moderated')
		{
			$this->getModelFromCache('XenForo_Model_User')->rebuildUserModerationQueueCache();
		}

		$this->getModelFromCache('XenForo_Model_BbCode')->deleteBbCodeParseCacheForContent(
			'signature', $this->get('user_id')
		);

		$this->_getUserModel()->changeContentUser($userId, $this->get('username'), null, 0);
	}

A lot of items are permanently deleted such that they cannot be restored by any addon. Only a few items are spared from what I can see... posts, likes, and apparently conversation messages. I just examined that addon and it appears to only handle posts and likes. Nothing else is handled including profile information, custom fields, avatar, password, warnings, alerts, profile posts, follows, ignores, and conversations.

So basically the non-restore method (addon or manual queries) involves creating a new user and assigning it the posts and likes from the deleted user which is all that remains without restoring a backup. From looking at the code it appears that conversations should also remain, but you would have to update the user_ids similar to my previous query as well as recreate their inbox by inserting records into xf_conversation_user.
 
It's a question of what can be done without a backup.

Upon deleting a user account XenForo executes the following (from the user datawriter):

Code:
    /**
     * Post-delete handling.
     */
    protected function _postDelete()
    {
        $db = $this->_db;
        $userId = $this->get('user_id');
        $userIdQuoted = $db->quote($userId);

        $db->delete('xf_user_alert', "alerted_user_id = $userIdQuoted");
        $db->delete('xf_user_alert_optout', "user_id = $userIdQuoted");
        $db->delete('xf_user_change_log', "user_id = $userIdQuoted");
        $db->delete('xf_user_change_temp', "user_id = $userIdQuoted");
        $db->delete('xf_user_confirmation', "user_id = $userIdQuoted");
        $db->delete('xf_user_external_auth', "user_id = $userIdQuoted");
        $db->delete('xf_user_field_value', "user_id = $userIdQuoted");
        $db->delete('xf_user_follow', "follow_user_id = $userIdQuoted");
        $db->delete('xf_user_follow', "user_id = $userIdQuoted");
        $db->delete('xf_user_group_change', "user_id = $userIdQuoted");
        $db->delete('xf_user_group_promotion_log', "user_id = $userIdQuoted");
        $db->delete('xf_user_group_relation', "user_id = $userIdQuoted");
        $db->delete('xf_user_ignored', "ignored_user_id = $userIdQuoted");
        $db->delete('xf_user_ignored', "user_id = $userIdQuoted");
        $db->delete('xf_user_news_feed_cache', "user_id = $userIdQuoted");
        $db->delete('xf_user_trophy', "user_id = $userIdQuoted");
        $db->delete('xf_user_upgrade_active', "user_id = $userIdQuoted");
        $db->delete('xf_user_upgrade_expired', "user_id = $userIdQuoted");
        $db->delete('xf_warning', "user_id = $userIdQuoted");

        $db->delete('xf_permission_combination', "user_id = $userIdQuoted");
        $db->delete('xf_permission_entry', "user_id = $userIdQuoted");
        $db->delete('xf_permission_entry_content', "user_id = $userIdQuoted");

        if ($this->get('is_moderator'))
        {
            $db->delete('xf_moderator',  "user_id = $userIdQuoted");
            $db->delete('xf_moderator_content',  "user_id = $userIdQuoted");
        }
        if ($this->get('is_admin'))
        {
            $db->delete('xf_admin',  "user_id = $userIdQuoted");
            $db->delete('xf_admin_permission_entry',  "user_id = $userIdQuoted");
        }
        if ($this->get('is_banned'))
        {
            $db->delete('xf_user_ban',  "user_id = $userIdQuoted");
        }

        $db->delete('xf_profile_post', "profile_user_id = $userIdQuoted");

        $db->delete('xf_news_feed', "user_id = $userIdQuoted");

        $db->delete('xf_conversation_user', "owner_user_id = $userIdQuoted");
        // note: leaving records in conversation recipient to keep data somewhat intact for others

        $db->delete('xf_ip', "content_type = 'user' AND user_id = $userIdQuoted");
        // note: leaving content-associated IPs

        $db->delete('xf_forum_read', "user_id = $userIdQuoted");
        $db->delete('xf_thread_read', "user_id = $userIdQuoted");
        $db->delete('xf_forum_watch', "user_id = $userIdQuoted");
        $db->delete('xf_thread_watch', "user_id = $userIdQuoted");

        $this->getModelFromCache('XenForo_Model_Avatar')->deleteAvatar($userId, false);

        if ($this->get('user_state') == 'moderated')
        {
            $this->getModelFromCache('XenForo_Model_User')->rebuildUserModerationQueueCache();
        }

        $this->getModelFromCache('XenForo_Model_BbCode')->deleteBbCodeParseCacheForContent(
            'signature', $this->get('user_id')
        );

        $this->_getUserModel()->changeContentUser($userId, $this->get('username'), null, 0);
    }

A lot of items are permanently deleted such that they cannot be restored by any addon. Only a few items are spared from what I can see... posts, likes, and apparently conversation messages. I just examined that addon and it appears to only handle posts and likes. Nothing else is handled including profile information, custom fields, avatar, password, warnings, alerts, profile posts, follows, ignores, and conversations.

So basically the non-restore method (addon or manual queries) involves creating a new user and assigning it the posts and likes from the deleted user which is all that remains without restoring a backup. From looking at the code it appears that conversations should also remain, but you would have to update the user_ids similar to my previous query as well as recreate their inbox by inserting records into xf_conversation_user.
I did this and all it did was restore ownership of the post but not the post count. http://xenforo.com/community/threads/restore-a-deleted-user-account.16628/

UPDATE xf_post SET user_id = x WHERE username ='oldusername';
UPDATE xf_thread SET user_id = x WHERE username ='oldusername';

Can you tell me what else I need to do to restore as much as possible?
 
I did this and all it did was restore ownership of the post but not the post count. http://xenforo.com/community/threads/restore-a-deleted-user-account.16628/

UPDATE xf_post SET user_id = x WHERE username ='oldusername';
UPDATE xf_thread SET user_id = x WHERE username ='oldusername';

Can you tell me what else I need to do to restore as much as possible?

To rebuild post counts:

http://xenforo.com/community/resources/rebuild-user-post-counts-query.363/

And this script might be useful also if you need to rebuild likes:

http://xenforo.com/community/thread...t-profile-post-like-caches.42384/#post-457352
 
I knew Jake would be right. Then again, in the scheme of things reassociating the posts with (what appears to be) the once deleted member is 98% of what's really important to everyone (aside from the member who was deleted).
 
Is it possible to merge all guest posts "user id 0" to a single user so I at least can search and//or have similar threads find posts made by deleted users? It appears once a user is deleted, it does a lot more harm than I ever expected.

If there is anything I can do to merge all deleted accounts and threads/posts into one username so the guest is at least back into an active state, that would be so helpful.
 
Thanks, I have been looking at this, but from some user experiences I don't think its updated for 1.4.6 . I've left two posts on Jon's add-on with no response. I'm reluctant to start the process only to find it creates errors that require me to repair back. But, if it worked, I would be so happy.

Have you tried it?
 
Top Bottom