Repository navigation
Conversation
…ame. `email_exists()` now matches email addresses case-insensitively regardless of the database collation, so a second account cannot be created with an address that only differs in letter case (for example `abc@example.com` and `ABc@example.com`). With the default case-insensitive collation of the users table, the existing lookup already ignores letter case and uses the `user_email` index, so no extra query is made. The `LOWER()` fallback, which cannot use the index, only runs when the `user_email` column has a case-sensitive collation or the collation cannot be determined. This is detected once per request by the new private `_wp_is_user_email_case_sensitive()` function, and can be overridden with the `wp_is_user_email_case_sensitive` filter. The Users list table also flags users on the current page whose email address is shared with another account, ignoring letter case, so that existing duplicates can be found and cleaned up. The lookup only uses the addresses on the current page and is index-friendly on case-insensitive collations. See #66238.
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
|
Please add the AI disclosure to the PR description: wordpress-develop/.github/pull_request_template.md Lines 22 to 33 in 79ff428 |
| * user, ignoring letter case. Keys are user IDs. | ||
| * | ||
| * @since 7.2.0 | ||
| * @var true[] |
There was a problem hiding this comment.
| * @var true[] | |
| * @var array<int, true> |
There was a problem hiding this comment.
This being said, I'm not sure an associative array is needed here. It could just be list<int>, without any mapping.
| * @global wpdb $wpdb WordPress database abstraction object. | ||
| * | ||
| * @param int[] $user_ids IDs of the users to check. | ||
| * @return true[] Array keyed by the IDs of users whose email address is shared. |
There was a problem hiding this comment.
| * @return true[] Array keyed by the IDs of users whose email address is shared. | |
| * @return array<int, true> Array keyed by the IDs of users whose email address is shared. |
There was a problem hiding this comment.
But note above, how this could just return list<int>. An associative array seems unnecessary.
| * @param int[] $user_ids IDs of the users to check. | ||
| * @return true[] Array keyed by the IDs of users whose email address is shared. | ||
| */ | ||
| protected function get_duplicate_email_user_ids( $user_ids ) { |
There was a problem hiding this comment.
| protected function get_duplicate_email_user_ids( $user_ids ) { | |
| protected function get_duplicate_email_user_ids( array $user_ids ): array { |
| function _wp_is_user_email_case_sensitive() { | ||
| global $wpdb; | ||
|
|
||
| static $is_case_sensitive = array(); |
There was a problem hiding this comment.
Why is this an array when it only ever has one item in it?
Trac ticket: https://core.trac.wordpress.org/ticket/66238
What
email_exists()now matches emails case-insensitively regardless of the DB collation, soABc@example.comcan't be registered whenabc@example.comexists. The Users list table flags existing case-variant duplicates so they can be cleaned up.Index tradeoff (from Trac feedback)
The
LOWER(user_email)lookup now only runs when theuser_emailcolumn has a case-sensitive collation (*_bin,*_cs) or the collation can't be determined. With the default*_cicollation, the existing indexed lookup already ignores case, so no extra query is made.The list table check only queries the email addresses on the current page, using
user_email IN (...)on*_cicollations so the index is used.Collation detection is cached per request in the private
_wp_is_user_email_case_sensitive()and can be overridden with thewp_is_user_email_case_sensitivefilter.Testing
npm run test:php -- --group 66238(covers both the case-insensitive and case-sensitive paths).abc@example.com, then try to addABc@example.com: it should be rejected with "This email address is already registered".