0

I'm looking for a method to keep users out of the wp_users table until they have confirmed their email address.

WordPress sends new users their password by email, which is a de facto email confirmation. But whether they confirm - and even if the email is fake - they are already added to the table. You can't distinguish those who have confirmed so they fill up your user table and provide confusion if someone later tries to register with that email (if they never got the email, or never responded, or someone else used their email address, etc.). I don't want unconfirmed users/emails in my wp_users table.

I'm looking for an approach that can either

  1. scrub unconfirmed accounts after say 48 hours, or better yet
  2. put them in an intermediate table until they confirm, then register them, and scrub entries after a 48 hour timeout

No basic plugin seems to do this. One plugin adds "unconfirmed_user_" to the beginning of the username until they confirm, then removes it, but this still leaves them in the user table, and doesn't remove them after a timeout.

BuddyPress does everything I want to do, but has a great deal of bloat, and many extra tables.

What approach would seem most elegant to achieve my goals? I'm thinking it would involve (at the minimum):

  1. an intermediate table with the username, email, generated key, and timestamp
  2. hooking in to the registration function and intercepting the signup, and stashing the user in the table (EDIT: or more simply, after native registration process, delete from the wp_users table and add them to signup table). Then email a confirmation with the key appended to a wp-login.php url
  3. intercepting logins with valid keys and deleting the entry and programmatically registering the user (essentially reversing step 2)
  4. running a cron function to delete signups after 48 hours

Is there a bloat-free plugin i missed that accomplishes this, and if not, does my approach sound right? What are the key hooks involved and have I missed any "gotchas" in my process?

  • What's to stop a new user registering with the same email, then the original confirmation email being triggered, now the old visitor has access to the account the new visitor created, security breach! In the meantime can you explain why you don't want them in the main table? That table still works even when it's super big, the wordpress.com user table works the same way and has tens of millions of entries if not more. If your user table really is full, then I suggest something has gone horribly wrong. Or is this solving a separate problem you haven't mentioned? – Tom J Nowell Aug 22 '17 at 22:12
  • The registration process would need to check against usernames/emails in the signup table too. It's not the table size that bothers me, but it prevents an accurate count of confirmed users, and makes emailing (or otherwise discerning) only confirmed users impossible. – Bob Diego Aug 22 '17 at 22:17
  • That's never been an issue for me, are you fetching the users via a raw SQL query instead of using the APIs? The APIs should be able to handle that fine – Tom J Nowell Aug 22 '17 at 22:29
  • Whether I grab users with SQL or an API, there's no way to distinguish users who have ever returned to the site after registering. A simpler approach to this would be to hook in when they "confirm" the registration (actually, log in with system-generated password) and set a flag for the user. Then I could cull users who never set this flag after 48 hours. – Bob Diego Aug 22 '17 at 22:41
  • There is, else WP wouldn't know, user_status, the activation key, there's an entire table for it in multisite – Tom J Nowell Aug 22 '17 at 22:47
0

It would appear that this is an XY problem, where Y is what you're asking ( an attempt to solve X, your real problem ), and X is the inability to retrieve only confirmed/active users

Firstly, what you wanted to do isn't quite possible in multisites, there's already a table named wp_signups for these users, that tracks the pending confirmation and necessary keys, since a user might be confirmed on one blog and not another. So deleting users that aren't confirmed for your root blog, might delete users that are confirmed on other blogs, destroying data/logins.

So I'm going to answer your original problem, in the context of a singular site, as it's significantly simpler:

SELECT * FROM $wpdb->users WHERE user_status != 2

Taken from the plugin named unconfirmed, but with the logic flipped

  • Ah, mea culpa, I've worked with the singups table forever, but assumed it was buddypress. You're right, I'm finally working without the network, and my entire premise was wrong - you're saying the user_status changes when the user confirms registration (resets password). If this is so, you've provided a query that returns the validated users, and pointed the way to a cron function that could remove unvalidated users - if I wanted that - after 48 hours. Can you confirm my understanding? (I'll "check" your answer) – Bob Diego Aug 22 '17 at 22:53
  • To be clear, I am using a single site setup. It appears that the user_status is not used in this configuration - did I misunderstand your answer, or did you assume I was using network sites? If so, this still suggests a useful flag for designating validated users in single site. – Bob Diego Aug 22 '17 at 23:06
  • I'm saying that in a multisite setup, the concept of an unconfirmed user doesn't exist in the way you think it does. A user can be both confirmed and unconfirmed at the same time depending on the blog providing context – Tom J Nowell Aug 22 '17 at 23:22
  • As for on a single site, you now have the means to count the users, or retrieve their emails without removing them. Removal is now completely unnecessary, and I would strongly advise against it – Tom J Nowell Aug 22 '17 at 23:23
  • I may be missing something - the documentation for user_status seems to state it's unused for single sites, and tests on my own install supports that. Can you explain the mechanism you are suggesting for identifying which users have validated their registration in a single site setup? – Bob Diego Aug 22 '17 at 23:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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