@prefix sioc: <http://rdfs.org/sioc/ns#> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix content: <http://purl.org/rss/1.0/modules/content/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

<https://lhero.org/?post_type=lh-portfolio-doc&#038;p=147304>
  a sioc:Post ;
  dc:title "Changelog" ;
  dcterms:identifier 147304 ;
  dc:modified "2026-09-13T14:11:25Z"^^xsd:dateTime ;
  dc:created "2026-09-13T14:09:44Z"^^xsd:dateTime ;
  sioc:link <https://lhero.org/portfolio/lh-user-provisioning/changelog/> ;
  sioc:has_creator <https://lhero.org/author/1/#account> ;
  sioc:has_container <https://lhero.org/#posts> ;
  content:encoded "<ul class=\"lh_portfolio-meta\"><li><strong>Type:</strong> Doc-section</li><li><strong>Part of:</strong> <a href=\"https://lhero.org/portfolio/lh-user-provisioning/\">LH User Provisioning</a></li></ul><ul class=\"lh_portfolio-changelog\"><li><strong>1.3.1:</strong> Trim readme.md down to the minimal rule-2 shape (one-paragraph description, installation, links to the canonical portfolio doc home and changelog doc-section) now that full documentation lives in lh-portfolio.</li><li><strong>1.3.0:</strong> Two changes. First, ensure_nicename_matches_id() now writes via a direct SQL UPDATE instead of wp_update_user() — this is the actual fix for the 1.2.1 collision bug (that release added a guard, but the underlying write still routed through wp_update_user(), whose nicename-uniqueness dedup logic was found to still misfire against a user&#039;s own already-correct nicename in some cases, since that logic is designed for human-chosen slugs that can legitimately collide and a numeric ID-derived nicename never can). Second, added user_register/profile_update hooks (priority 20) so login-matches-email and nicename-matches-ID are now enforced in real time for every user created or updated anywhere on the network, not just accounts provisioned through this plugin&#039;s own API — both guarded, both raw SQL, so a no-op check is a single cached read and there&#039;s no re-entrancy risk. This supersedes the old standalone &quot;LH Email Usernames&quot; plugin, which can now be deactivated/removed.</li><li><strong>1.2.1:</strong> Fixed a real bug: ensure_nicename_matches_id() had no early-return guard (unlike its sibling ensure_login_matches_email()), so it called wp_update_user() unconditionally on every invocation — including the redundant calls that already happen twice per provisioning (create_user() then user_cleanup()) and again on every later cleanup/login/cron pass. WordPress&#039;s own nicename-uniqueness check in wp_update_user() found the user&#039;s own current nicename already present under what it read as a different login context and &quot;resolved&quot; it by appending -2; each further redundant call repeated this against the previous call&#039;s output, compounding into nicenames like 1015925-2-2 or worse. Added the same before-and-after guard ensure_login_matches_email() already used, so the write is skipped whenever the nicename is already correct. Also extended integrity_check()&#039;s query to independently check user_nicename != ID (previously it only checked user_login != user_email), so the accounts already left with a compounded nicename self-heal on the next hourly run instead of needing a manual fix. (Superseded by 1.3.0 — the guard alone wasn&#039;t sufficient; the fix was moving off wp_update_user() entirely for this field.)</li><li><strong>1.2.0:</strong> Added a &quot;Provisioned Via&quot; column to the Network Admin → Users screen (wpmu_users_columns / manage_users_custom_column), showing each user&#039;s lh_provisioning_source and lh_provisioning_action usermeta. Previously this provenance data was written on every provision but never surfaced anywhere in wp-admin. Users with no provenance meta show an em dash.</li><li><strong>1.1.0:</strong> Fixed alias-compliance gap: ensure_user() previously called a bare get_user_by(&#039;email&#039;, $email), bypassing LH User Identity&#039;s documented alias-resolution pattern. An email that was a registered alias (rather than an account&#039;s primary email) would return a false &quot;no such user&quot; result and create a duplicate account instead of recognising the existing one. Added resolve_existing_user_by_email(), which checks wp_users then falls back to the lh_user_identity_get_user_by_email_fallback filter, and used it in ensure_user(). Also exposed this as a new public wrapper function, lh_user_provisioning_resolve_user(), for other LH plugins that need alias-aware &quot;does this user exist&quot; checks without creating a user.</li><li><strong>1.0.0:</strong> Initial release.</li></ul>"^^rdf:XMLLiteral ;
  sioc:content "Type: Doc-sectionPart of: LH User Provisioning1.3.1: Trim readme.md down to the minimal rule-2 shape (one-paragraph description, installation, links to the canonical portfolio doc home and changelog doc-section) now that full documentation lives in lh-portfolio.1.3.0: Two changes. First, ensure_nicename_matches_id() now writes via a direct SQL UPDATE instead of wp_update_user() — this is the actual fix for the 1.2.1 collision bug (that release added a guard, but the underlying write still routed through wp_update_user(), whose nicename-uniqueness dedup logic was found to still misfire against a user&#039;s own already-correct nicename in some cases, since that logic is designed for human-chosen slugs that can legitimately collide and a numeric ID-derived nicename never can). Second, added user_register/profile_update hooks (priority 20) so login-matches-email and nicename-matches-ID are now enforced in real time for every user created or updated anywhere on the network, not just accounts provisioned through this plugin&#039;s own API — both guarded, both raw SQL, so a no-op check is a single cached read and there&#039;s no re-entrancy risk. This supersedes the old standalone &quot;LH Email Usernames&quot; plugin, which can now be deactivated/removed.1.2.1: Fixed a real bug: ensure_nicename_matches_id() had no early-return guard (unlike its sibling ensure_login_matches_email()), so it called wp_update_user() unconditionally on every invocation — including the redundant calls that already happen twice per provisioning (create_user() then user_cleanup()) and again on every later cleanup/login/cron pass. WordPress&#039;s own nicename-uniqueness check in wp_update_user() found the user&#039;s own current nicename already present under what it read as a different login context and &quot;resolved&quot; it by appending -2; each further redundant call repeated this against the previous call&#039;s output, compounding into nicenames like 1015925-2-2 or worse. Added the same before-and-after guard ensure_login_matches_email() already used, so the write is skipped whenever the nicename is already correct. Also extended integrity_check()&#039;s query to independently check user_nicename != ID (previously it only checked user_login != user_email), so the accounts already left with a compounded nicename self-heal on the next hourly run instead of needing a manual fix. (Superseded by 1.3.0 — the guard alone wasn&#039;t sufficient; the fix was moving off wp_update_user() entirely for this field.)1.2.0: Added a &quot;Provisioned Via&quot; column to the Network Admin → Users screen (wpmu_users_columns / manage_users_custom_column), showing each user&#039;s lh_provisioning_source and lh_provisioning_action usermeta. Previously this provenance data was written on every provision but never surfaced anywhere in wp-admin. Users with no provenance meta show an em dash.1.1.0: Fixed alias-compliance gap: ensure_user() previously called a bare get_user_by(&#039;email&#039;, $email), bypassing LH User Identity&#039;s documented alias-resolution pattern. An email that was a registered alias (rather than an account&#039;s primary email) would return a false &quot;no such user&quot; result and create a duplicate account instead of recognising the existing one. Added resolve_existing_user_by_email(), which checks wp_users then falls back to the lh_user_identity_get_user_by_email_fallback filter, and used it in ensure_user(). Also exposed this as a new public wrapper function, lh_user_provisioning_resolve_user(), for other LH plugins that need alias-aware &quot;does this user exist&quot; checks without creating a user.1.0.0: Initial release." ;
  sioc:topic <https://lhero.org/?taxonomy=author&term=cap-1> .

<https://lhero.org/author/1/#account> rdfs:seeAlso <https://lhero.org/author/1/?feed=lhrdf&format=turtle> .
<https://lhero.org/?taxonomy=author&term=cap-1> rdfs:seeAlso <https://lhero.org/?taxonomy=author&term=cap-1&feed=lhrdf&format=turtle> .
