diff --git a/.wordpress-org/blueprints/blueprint.json b/.wordpress-org/blueprints/blueprint.json index 75651f33..617fcdfc 100644 --- a/.wordpress-org/blueprints/blueprint.json +++ b/.wordpress-org/blueprints/blueprint.json @@ -15,7 +15,7 @@ "step": "installPlugin", "pluginZipFile": { "resource": "url", - "url": "https:\/\/downloads.wordpress.org\/plugin\/ultimate-member.2.10.3.zip" + "url": "https:\/\/downloads.wordpress.org\/plugin\/ultimate-member.2.10.4.zip" }, "options": { "activate": true diff --git a/README.md b/README.md index 45927cc6..a7a83c83 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ GNU Version 2 or Any Later Version ### IMPORTANT: PLEASE UPDATE THE PLUGIN TO AT LEAST VERSION 2.6.7 IMMEDIATELY. VERSION 2.6.7 PATCHES SECURITY PRIVILEGE ESCALATION VULNERABILITY. PLEASE SEE [THIS ARTICLE](https://docs.ultimatemember.com/article/1866-security-incident-update-and-recommended-actions) FOR MORE INFORMATION -[Official Release Version: 2.10.3](https://github.com/ultimatemember/ultimatemember/releases/tag/2.10.3). +[Official Release Version: 2.10.4](https://github.com/ultimatemember/ultimatemember/releases/tag/2.10.4). ## Changelog diff --git a/includes/common/actions/class-users.php b/includes/common/actions/class-users.php index e3309b6a..d3430d80 100644 --- a/includes/common/actions/class-users.php +++ b/includes/common/actions/class-users.php @@ -45,6 +45,8 @@ if ( ! class_exists( 'um\common\actions\Users' ) ) { } public function status_check() { + // Make the control checking of the empty user statuses inside the function `get_empty_status_users`. + // Maybe some users were approved manually or deleted and we need to reset the admin notice. $total_users = UM()->common()->users()::get_empty_status_users(); if ( empty( $total_users ) ) { return; @@ -114,8 +116,11 @@ if ( ! class_exists( 'um\common\actions\Users' ) ) { foreach ( $results as $user_id ) { $res = UM()->common()->users()->approve( $user_id, true, true ); - if ( $res ) { + if ( $res || UM()->common()->users()->has_status( $user_id, 'approved' ) ) { ++$um_empty_status_users[0]; + } else { + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log + error_log( 'Cannot set `approved` status for the user with ID:' . $user_id ); } } @@ -135,7 +140,19 @@ if ( ! class_exists( 'um\common\actions\Users' ) ) { 'pages' => $pages, ) ); + } else { + // Make the control checking of the empty user statuses. + // Maybe some users were approved manually or deleted and we need to reset the admin notice. + $total_users = UM()->common()->users()::get_empty_status_users(); + if ( empty( $total_users ) ) { + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log + error_log( 'There aren\'t users with empty `account_status`. Maybe some users were approved manually or deleted.' ); + } } + } else { + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log + error_log( 'There aren\'t users with empty `account_status`. Maybe some users were approved manually or deleted.' ); + delete_option( '_um_log_empty_status_users' ); } } } diff --git a/includes/common/class-users.php b/includes/common/class-users.php index 392c29d2..1701b913 100644 --- a/includes/common/class-users.php +++ b/includes/common/class-users.php @@ -840,18 +840,23 @@ class Users { global $wpdb; $total_users = $wpdb->get_var( - "SELECT COUNT(u.ID) + "SELECT COUNT(DISTINCT u.ID) FROM {$wpdb->users} u LEFT JOIN {$wpdb->usermeta} um ON u.ID = um.user_id AND um.meta_key = 'account_status' LEFT JOIN {$wpdb->usermeta} um2 ON u.ID = um2.user_id AND um2.meta_key = '_um_registration_in_progress' WHERE ( um.meta_value IS NULL OR um.meta_value = '' ) AND - um2.meta_value IS NULL OR um2.meta_value != '1'" + ( um2.meta_value IS NULL OR um2.meta_value != '1' )" ); $total_users = absint( $total_users ); - // In WordPress, an underscore prefix before the option name (e.g., _my_option_name) is commonly used to indicate that the option is private. - // This option has a format: {updated_users}/{total_users_for_update}. - update_option( '_um_log_empty_status_users', array( 0, $total_users ) ); + if ( $total_users > 0 ) { + // In WordPress, an underscore prefix before the option name (e.g., _my_option_name) is commonly used to indicate that the option is private. + // This option has a format: {updated_users}/{total_users_for_update}. + update_option( '_um_log_empty_status_users', array( 0, $total_users ) ); + } else { + // Delete option for the cases when there aren't empty `account_status` users. But admin notice is still displayed. + delete_option( '_um_log_empty_status_users' ); + } return $total_users; } diff --git a/readme.txt b/readme.txt index 53fa0b0c..60ee643c 100644 --- a/readme.txt +++ b/readme.txt @@ -6,7 +6,7 @@ Tags: community, member, membership, user-profile, user-registration Requires PHP: 7.0 Requires at least: 6.2 Tested up to: 6.8 -Stable tag: 2.10.2 +Stable tag: 2.10.3 License: GPLv3 License URI: http://www.gnu.org/licenses/gpl-3.0.txt @@ -167,6 +167,12 @@ No specific extensions are needed. But we highly recommended keep active these P IMPORTANT: PLEASE UPDATE THE PLUGIN TO AT LEAST VERSION 2.6.7 IMMEDIATELY. VERSION 2.6.7 PATCHES SECURITY PRIVILEGE ESCALATION VULNERABILITY. PLEASE SEE [THIS ARTICLE](https://docs.ultimatemember.com/article/1866-security-incident-update-and-recommended-actions) FOR MORE INFORMATION += 2.10.4 2025-05-xx = + +**Bugfixes** + +* Fixed: The Action Scheduler action `um_set_default_account_status`. Case when some users were approved manually or deleted, and we need to reset the admin notice. Added `error_log()` to the wrong conditions. + = 2.10.3 2025-04-24 = **Enhancements** @@ -237,72 +243,6 @@ IMPORTANT: PLEASE UPDATE THE PLUGIN TO AT LEAST VERSION 2.6.7 IMMEDIATELY. VERSI **Cached and optimized/minified assets(JS/CSS) must be flushed/re-generated after upgrade** -= 2.9.2 2025-01-14 = - -**Enhancements** - -* Added: Compatibility with the new [Ultimate Member - Zapier](https://ultimatemember.com/extensions/zapier/) extension -* Added: Only approved user Reset Password setting defined as true by default -* Added: `UM()->is_new_ui()` function for future enhancements related to new UI -* Added: Filter hook `um_before_user_submitted_registration_data` -* Tweak: Changed hook's priority for initialization of email templates paths -* Tweak: Removed `load_plugin_textdomain` due to (article)[https://make.wordpress.org/core/2024/10/21/i18n-improvements-6-7/#Enhanced-support-for-only-using-PHP-translation-files] - -**Bugfixes** - -* Fixed: Security issue CVE ID: CVE-2025-0308 -* Fixed: Security issue CVE ID: CVE-2025-0318 -* Fixed: Using placeholders in email templates when Action Scheduler is active. Using `fetch_user_id` attribute for fetching necessary user before sending email -* Fixed: PHP 8.4 compatibility. Using WordPress native `wp_is_mobile()` instead of MobileDetect library -* Fixed: PHP errors related to `UM()->localize()` function -* Fixed: PHP errors in user meta header when `last_update` meta is empty -* Fixed: Small CSS changes and avoid duplicates -* Fixed: Removed ms-native show password button for type="password" field in UM forms -* Fixed: Define scalable attribute for cropper - -**Deprecated** - -* Fully deprecated `UM()->mobile()` function -* Fully deprecated `UM()->localize()` function -* Fully deprecated `um_language_textdomain` filter hook - -**Templates required update** - -* account.php - -**Cached and optimized/minified assets(JS/CSS) must be flushed/re-generated after upgrade** - -= 2.9.1 2024-11-15 = - -**Enhancements** - -* Added: `um_image_upload_validation` hook for 3rd-party validation during upload images - -**Bugfixes** - -* Fixed: "Load textdomain just in time" issue -* Fixed: Capabilities checking in the wp-admin > Users list table -* Fixed: File/image upload on the role specific profile form -* Fixed: Issues when the form's custom fields meta has a wrong format -* Fixed: Validation of the "Registration Default Role" slug -* Fixed: Allowed query variables via registered REST API class only when REST_REQUEST is defined - -= 2.9.0 2024-11-12 = - -**Enhancements** - -* Added: Action Scheduler (version 3.8.1) for email sending. More info is [here](https://actionscheduler.org/). -* Added: Supporting new `wp_register_block_metadata_collection()` function for registering WP Blocks - -**Bugfixes** - -* Fixed: `ajax_image_upload()` and `ajax_resize_image()` handlers vulnerability. CVE ID: CVE-2024-10528 -* Fixed: Disabling user status column wp-admin > Users screen -* Fixed: User status filter on wp-admin > Users on mobile devices -* Fixed: Extra unwrapping of the WP Editor field's value - -**Cached and optimized/minified assets(JS/CSS) must be flushed/re-generated after upgrade** - [See changelog for all versions](https://plugins.svn.wordpress.org/ultimate-member/trunk/changelog.txt). == Upgrade Notice == diff --git a/tests/generate-empty-status-users.php b/tests/generate-empty-status-users.php index 55e26ae2..65b6a90b 100644 --- a/tests/generate-empty-status-users.php +++ b/tests/generate-empty-status-users.php @@ -5,12 +5,36 @@ function um_test_generate_random_string( $length = 10 ) { return substr( str_shuffle( str_repeat( $x = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil( $length / strlen( $x ) ) ) ), 1, $length ); } +function api_call() { + $response = wp_remote_get( 'https://randomuser.me/api/?results=1000' ); + + if ( is_wp_error( $response ) ) { + return 'Something went wrong!'; + } + + $body = wp_remote_retrieve_body( $response ); + + $data = json_decode( $body ); + + $users = array(); + foreach ( $data->results as $user ) { + $users[] = array( + 'first' => $user->name->first, + 'last' => $user->name->last, + 'email' => $user->email, + 'username' => $user->login->username, + ); + } + + return $users; +} + +$users = api_call(); for ( $i = 0; $i < 1000; $i++ ) { - $random_user_name = um_test_generate_random_string( 8 ); // Generate a random user name - $random_user_email = $random_user_name . '@example.com'; // Append the user name to a dummy email domain - $random_user_pass = um_test_generate_random_string( 12 ); // Generate a random user password - $random_first_name = um_test_generate_random_string( 5 ); // Generate a random first name - $random_last_name = um_test_generate_random_string( 8 ); // Generate a random last name + $random_user_name = $users[ $i ]['username'] ?? um_test_generate_random_string( 8 ); + $random_user_email = $users[ $i ]['email'] ?? $random_user_name . '@example.com'; + $random_first_name = $users[ $i ]['first'] ?? um_test_generate_random_string( 5 ); + $random_last_name = $users[ $i ]['last'] ?? um_test_generate_random_string( 8 ); $userdata = array( 'user_login' => $random_user_name, diff --git a/ultimate-member.php b/ultimate-member.php index 66b8d5dd..8de11987 100644 --- a/ultimate-member.php +++ b/ultimate-member.php @@ -3,7 +3,7 @@ * Plugin Name: Ultimate Member * Plugin URI: http://ultimatemember.com/ * Description: The easiest way to create powerful online communities and beautiful user profiles with WordPress - * Version: 2.10.3 + * Version: 2.10.4-alpha * Author: Ultimate Member * Author URI: http://ultimatemember.com/ * Text Domain: ultimate-member