Digital Sovereignty for everyone

Architectural Notes

Why login/nicename convention writes bypass wp_update_user()

ensure_login_matches_email() and ensure_nicename_matches_id() both write via a direct SQL UPDATE rather than wp_update_user(). wp_insert_user()/wp_update_user() runs its own nicename-uniqueness dedup logic, built for human-chosen slugs that can legitimately collide (john-smith vs john-smith-2). That logic was found to treat a user’s own already-correct numeric nicename as a foreign collision and “resolve” it by appending -2, compounding further on every subsequent call into values like 1015925-2-2. A nicename that is always just the numeric ID can never legitimately collide with anyone by construction, so there is nothing for that dedup logic to usefully do — going around it removes the failure mode entirely rather than working around it. It also means these writes don’t fire profile_update, so they can’t trigger other plugins’ profile_update handlers or create hook re-entrancy.

Both methods are guarded — they compare against the current value first and skip the write entirely when it’s already correct — so a no-op check costs a single cached read, and a real fix costs one row update.

Identity resolution / alias awareness

resolve_existing_user_by_email() follows lh-user-identity‘s documented alias-resolution pattern: check wp_users first, then fall back to the lh_user_identity_get_user_by_email_fallback filter (a documented no-op if lh-user-identity isn’t active). This matters because ensure_user() is the canonical entry point several other LH plugins delegate to — without alias-aware resolution, provisioning by an email that is a registered alias (rather than an account’s primary email) would return a false “no such user” result and create a duplicate account instead of recognising the existing one.

Provenance tracking

Every newly provisioned user gets usermeta recording their origin, keyed as follows:

Key Description
lh_provisioning_source Calling plugin slug, e.g. lh-membership
lh_provisioning_action What triggered it, e.g. registration, checkin
lh_provisioning_ref Optional reference ID, e.g. event ID
lh_provisioning_site_id Which site triggered creation

No custom database tables — all provenance data lives in wp_usermeta. lh_provisioning_source and lh_provisioning_action are surfaced as a “Provisioned Via” column on the Network Admin → Users screen; lh_provisioning_ref and lh_provisioning_site_id are not currently shown in any UI. Provenance is only recorded on first creation, not on subsequent ensure_user() calls against an existing account, unless explicitly requested via args['source'].

Supersedes “LH Email Usernames”

The old standalone “LH Email Usernames” plugin partially provided real-time login-matches-email enforcement (login only, via wp_update_user() plus an unconditional site-wide wp_cache_flush() on every profile update). That plugin is fully superseded by this one’s user_register/profile_update hooks and can be deactivated/removed.

If you like this plugin please consider making a donation to further development

Install LHero.org

lhero.org

Open it straight from your home screen, full screen and quicker to load.

  1. Tap the Share button . If you cannot see it, tap ••• first.
  2. Scroll down and tap Add to Home Screen.
  3. Tap Add.
  1. Tap the browser menu ⋮.
  2. Tap Install app or Add to Home screen.
  1. In the menu bar, choose File, then Add to Dock.

Use your browser's menu to install this site or add it to your home screen.