Merge pull request #1753 from ultimatemember/development/2.9.x

Version 2.10.7
This commit is contained in:
Mykyta Synelnikov
2025-11-18 14:40:03 +02:00
committed by GitHub
15 changed files with 217 additions and 66 deletions
+1 -1
View File
@@ -15,7 +15,7 @@
"step": "installPlugin",
"pluginZipFile": {
"resource": "url",
"url": "https:\/\/downloads.wordpress.org\/plugin\/ultimate-member.2.10.6.zip"
"url": "https:\/\/downloads.wordpress.org\/plugin\/ultimate-member.2.10.7.zip"
},
"options": {
"activate": true
+1 -1
View File
@@ -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.6](https://github.com/ultimatemember/ultimatemember/releases/tag/2.10.6).
[Official Release Version: 2.10.7](https://github.com/ultimatemember/ultimatemember/releases/tag/2.10.7).
## Changelog
+1
View File
@@ -348,6 +348,7 @@ function initImageUpload_UM( trigger ) {
var cache_ts = new Date();
img_id.removeAttr("loading");
img_id.attr("src", d.url + "?"+cache_ts.getTime() );
img_id.data("file", d.file );
+1 -1
View File
File diff suppressed because one or more lines are too long
+16
View File
@@ -1,5 +1,21 @@
== Changelog ==
= 2.10.7 November 20, 2025 =
* Enhancements:
- Added: Extra condition for checking the license activation requests.
- Added: 2nd `$args` attribute to the action hook 'um_cover_area_content'.
- Tweak: Updated `Extensions_Updater` class to use Action Scheduler in the upgrade process of the UM extensions.
* Bugfixes:
- Fixed: User profile links in the comments section on the frontend when the `$comment->user_id` is empty.
- Fixed: The `emotize` function regexp for better emoji converting.
- Fixed: The conflict between the image uploader and lazy-loading attribute added by 3rd-party plugins.
- Fixed: PHP warnings for roles without meta data.
- Fixed: Typo in labels.
= 2.10.6 October 02, 2025 =
* Enhancements:
+105 -8
View File
@@ -10,6 +10,10 @@ if ( ! defined( 'ABSPATH' ) ) {
*/
class Extensions_Updater {
const EXTRA_TIME = 30;
const PAGINATION = 50;
/**
* @var array
*/
@@ -33,20 +37,90 @@ class Extensions_Updater {
);
add_action( 'admin_init', array( $this, 'maybe_run_updater' ) );
add_action( 'um_' . $this->updater_data['slug'] . '_package_start', array( $this, 'package_start' ), 10, 4 );
add_action( 'um_' . $this->updater_data['slug'] . '_package_complete', array( $this, 'package_complete' ) );
}
public function package_start( $version, $file_path, $delay, $per_page ) {
$hooks = array(
'start' => 'um_' . $this->updater_data['slug'] . '_package_start',
'complete' => 'um_' . $this->updater_data['slug'] . '_package_complete',
);
$debug = defined( 'UM_UPDATER_DEBUG' ) && UM_UPDATER_DEBUG;
include_once $file_path;
/**
* IMPORTANT!!!: Last action that we need to do after package is complete.
* `UM()->maybe_action_scheduler()->schedule_single_action(
* time() + 1,
* $hook,
* array(
* 'version' => $version,
* )
* );`
*/
}
public function package_complete( $version ) {
$this->set_last_version_upgrade( $version );
$this->reset_in_process_package_version();
}
/**
* Maybe run upgrade if needed.
*/
public function maybe_run_updater() {
$last_version_upgrade = $this->get_last_version_upgrade();
if ( ! empty( $last_version_upgrade ) && version_compare( $last_version_upgrade, $this->updater_data['version'], '>=' ) ) {
// Don't need update.
// Cold start to avoid scheduled actions duplicates. Don't remove it.
$init = get_transient( 'um_' . $this->updater_data['slug'] . '_updater_init' );
if ( ! empty( $init ) ) {
return;
}
set_transient( 'um_' . $this->updater_data['slug'] . '_updater_init', true, 10 );
$next_package = $this->get_next_package();
if ( empty( $next_package ) ) {
$this->set_last_version_upgrade( $this->updater_data['version'] );
$this->reset_in_process_package_version();
return;
}
list( $package_version, $file_path ) = $next_package;
$in_process_package = $this->get_in_process_package_version();
if ( ! empty( $in_process_package ) && version_compare( $in_process_package, $package_version, '=' ) ) {
return;
}
// Initialize start package action.
$action_id = UM()->maybe_action_scheduler()->schedule_single_action(
time() + self::EXTRA_TIME,
'um_' . $this->updater_data['slug'] . '_package_start',
array(
'version' => $package_version,
'path' => $file_path,
'delay' => self::EXTRA_TIME,
'per_page' => self::PAGINATION,
)
);
// As soon as scheduler single action is created - then set in progress package version to avoid duplicates of the package start action.
if ( ! empty( $action_id ) ) {
$this->set_in_process_package_version( $package_version );
}
}
private function get_next_package() {
$last_version_upgrade = $this->get_last_version_upgrade();
if ( ! empty( $last_version_upgrade ) && version_compare( $last_version_upgrade, $this->updater_data['version'], '>=' ) ) {
return null;
}
$packages = $this->get_packages();
if ( ! empty( $packages ) ) {
if ( empty( $packages ) ) {
return null;
}
$packages_dir = $this->get_packages_dir();
foreach ( $packages as $package_version ) {
if ( version_compare( $package_version, $last_version_upgrade, '<=' ) ) {
@@ -62,12 +136,10 @@ class Extensions_Updater {
continue;
}
include_once $file_path;
$this->set_last_version_upgrade( $package_version );
}
return array( $package_version, $file_path );
}
$this->set_last_version_upgrade( $this->updater_data['version'] );
return null;
}
/**
@@ -121,4 +193,29 @@ class Extensions_Updater {
private function set_last_version_upgrade( $version ) {
update_option( 'um_' . $this->updater_data['slug'] . '_last_version_upgrade', $version );
}
/**
* Gets the last version upgrade from options.
*
* @return string The last version upgrade.
*/
private function get_in_process_package_version() {
return get_option( 'um_' . $this->updater_data['slug'] . '_in_process_package_upgrade', '' );
}
/**
* Set the last version upgrade for the updater.
*
* @param string $version The version to set as the last upgrade version.
*/
private function set_in_process_package_version( $version ) {
update_option( 'um_' . $this->updater_data['slug'] . '_in_process_package_upgrade', $version );
}
/**
* Set the last version upgrade for the updater.
*/
private function reset_in_process_package_version() {
update_option( 'um_' . $this->updater_data['slug'] . '_in_process_package_upgrade', '' );
}
}
+16 -2
View File
@@ -325,7 +325,7 @@ if ( ! class_exists( 'um\admin\core\Admin_Settings' ) ) {
break;
case 'members':
if ( ! has_shortcode( $content, 'ultimatemember' ) ) {
$page_setting_description = __( '<strong>Warning:</strong> Members page must contain a profile form shortcode. You can get existing shortcode or create a new one <a href="edit.php?post_type=um_directory" target="_blank">here</a>.', 'ultimate-member' );
$page_setting_description = __( '<strong>Warning:</strong> Members page must contain a member directory shortcode. You can get existing shortcode or create a new one <a href="edit.php?post_type=um_directory" target="_blank">here</a>.', 'ultimate-member' );
}
break;
default:
@@ -2968,12 +2968,23 @@ if ( ! class_exists( 'um\admin\core\Admin_Settings' ) ) {
error_log( maybe_serialize( $post_attr ) );
}
$request = wp_remote_post( UM()::$store_url, $post_attr );
if ( empty( $request ) || is_wp_error( $request ) ) {
if ( self::is_license_debug_enabled() ) {
error_log( '> Got `wp_error` or empty request body, try again with `sslverify=true`' );
}
$post_attr['sslverify'] = true;
$request = wp_remote_post( UM()::$store_url, $post_attr );
if ( ! is_wp_error( $request ) ) {
$request = json_decode( wp_remote_retrieve_body( $request ) );
}
} else {
$request = json_decode( wp_remote_retrieve_body( $request ) );
if ( empty( $request ) ) {
if ( self::is_license_debug_enabled() ) {
error_log( '> Got `wp_error`, try again with `sslverify=true`' );
error_log( '> Got empty request body, try again with `sslverify=true`' );
}
$post_attr['sslverify'] = true;
@@ -2983,12 +2994,15 @@ if ( ! class_exists( 'um\admin\core\Admin_Settings' ) ) {
$request = json_decode( wp_remote_retrieve_body( $request ) );
}
}
}
if ( self::is_license_debug_enabled() ) {
if ( is_wp_error( $request ) ) {
error_log( '> Finally got `wp_error`. Details below.' );
error_log( '>> Error code: ' . $request->get_error_code() );
error_log( '>> Error message: ' . $request->get_error_message() );
} elseif ( empty( $request ) ) {
error_log( '> Finally got empty UM website response.' );
} else {
error_log( '### Response from UM website:' );
error_log( '>' . maybe_serialize( $request ) );
+1 -1
View File
@@ -55,7 +55,7 @@ if ( ! empty( $_GET['id'] ) ) {
// roles e.g. "潜水艦subs" with both latin + not-UTB-8 symbols had invalid role ID
$role_id = sanitize_title( $_GET['id'] );
$data = get_option( "um_role_{$role_id}_meta" );
$data = get_option( "um_role_{$role_id}_meta", array() );
if ( empty( $data['_um_is_custom'] ) ) {
$data['name'] = $wp_roles->roles[ $role_id ]['name'];
+5 -5
View File
@@ -31,23 +31,23 @@ if ( ! class_exists( 'um\Dependencies' ) ) {
*/
public $ext_required_version = array(
'bbpress' => '2.0.7',
'followers' => '2.1.6',
'followers' => '2.3.5',
'forumwp' => '2.1.5',
'friends' => '2.1.4',
'friends' => '2.3.4',
'groups' => '2.4.2',
'jobboardwp' => '1.0.7',
'mailchimp' => '2.2.0',
'mailchimp' => '2.6.2',
'messaging' => '2.2.5',
'mycred' => '2.2.4',
'notices' => '2.0.5',
'notifications' => '2.1.3',
'notifications' => '2.3.8',
'online' => '2.1.1',
'private-content' => '2.0.5',
'profile-completeness' => '2.2.7',
'profile-tabs' => '1.0.0',
'recaptcha' => '2.3.4',
'reviews' => '2.1.5',
'social-activity' => '2.2.0',
'social-activity' => '2.4.0',
'social-login' => '2.2.0',
'stripe' => '1.0.0',
'zapier' => '1.0.0',
+11 -6
View File
@@ -217,24 +217,29 @@ if ( ! class_exists( 'um\core\Shortcodes' ) ) {
return $args;
}
/**
* Emoji support
*
* @param $content
* @param string $content
* @param bool $stripslashes
*
* @return mixed|string
*/
function emotize( $content ) {
public function emotize( $content, $stripslashes = true ) {
if ( $stripslashes ) {
$content = stripslashes( $content );
}
foreach ( $this->emoji as $code => $val ) {
$regex = str_replace(array('(', ')'), array("\\" . '(', "\\" . ')'), $code);
$content = preg_replace('/(' . $regex . ')(\s|$)/', '<img src="' . $val . '" alt="' . $code . '" title="' . $code . '" class="emoji" />$2', $content);
$regex = str_replace( array( '(', ')' ), array( '\\' . '(', '\\' . ')' ), $code );
$content = preg_replace(
'/(' . $regex . ')(?=\s|$|<)/',
'<img src="' . $val . '" alt="' . $code . '" title="' . $code . '" class="emoji" />',
$content
);
}
return $content;
}
/**
* Remove wpautop filter for post content if it's UM core page
*/
+12 -15
View File
@@ -863,25 +863,22 @@ function um_profile_header_cover_area( $args ) {
data-user_id="<?php echo esc_attr( um_profile_id() ); ?>" data-ratio="<?php echo esc_attr( $args['cover_ratio'] ); ?>">
<?php
/**
* UM hook
* Fires in the User Profile cover wrapper.
*
* @type action
* @title um_cover_area_content
* @description Cover area content change
* @input_vars
* [{"var":"$user_id","type":"int","desc":"User ID"}]
* @change_log
* ["Since: 2.0"]
* @usage add_action( 'um_cover_area_content', 'function_name', 10, 1 );
* @example
* <?php
* add_action( 'um_cover_area_content', 'my_cover_area_content', 10, 1 );
* function my_cover_area_content( $user_id ) {
* @since 1.3.x
* @since 2.10.7 Added $args attribute.
* @hook um_cover_area_content
*
* @param {int} $user_id User Profile ID.
* @param {array} $args User Profile data.
*
* @example <caption>Make any custom action in the User Profile cover wrapper.</caption>
* function my_cover_area_content( $user_id, $args ) {
* // your code here
* }
* ?>
* add_action( 'um_cover_area_content', 'my_cover_area_content', 10, 2 );
*/
do_action( 'um_cover_area_content', um_profile_id() );
do_action( 'um_cover_area_content', um_profile_id(), $args );
if ( true === UM()->fields()->editing ) {
$hide_remove = ' style="display:none;"';
+5 -1
View File
@@ -89,12 +89,16 @@ if ( ! class_exists( 'um\frontend\User_Profile' ) ) {
*
* @param string $comment_author_url The URL of the comment author.
* @param int $comment_id The ID of the comment.
* @param WP_Comment $comment The comment object.
* @param WP_Comment|null $comment The comment object.
*
* @return string The user profile URL for the comment author.
*/
public function change_comment_author_url( $comment_author_url, $comment_id, $comment ) {
if ( ! is_null( $comment ) && ! empty( $comment->user_id ) ) {
return um_user_profile_url( $comment->user_id );
}
return $comment_author_url;
}
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "ultimate-member",
"version": "2.10.6",
"version": "2.10.7",
"author": {
"name": "Ultimate Member",
"email": "team@ultimatemember.com",
+17 -1
View File
@@ -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.6
Stable tag: 2.10.7
License: GPLv3
License URI: http://www.gnu.org/licenses/gpl-3.0.txt
@@ -167,6 +167,22 @@ 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.7 2025-11-20 =
**Enhancements**
* Added: Extra condition for checking the license activation requests.
* Added: 2nd `$args` attribute to the action hook 'um_cover_area_content'.
* Tweak: Updated `Extensions_Updater` class to use Action Scheduler in the upgrade process of the UM extensions.
**Bugfixes**
* Fixed: User profile links in the comments section on the frontend when the `$comment->user_id` is empty.
* Fixed: The `emotize` function regexp for better emoji converting.
* Fixed: The conflict between the image uploader and lazy-loading attribute added by 3rd-party plugins.
* Fixed: PHP warnings for roles without meta data.
* Fixed: Typo in labels.
= 2.10.6 2025-10-02 =
**Enhancements**
+2 -1
View File
@@ -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.6
* Version: 2.10.7
* Author: Ultimate Member
* Author URI: http://ultimatemember.com/
* License: GPLv3
@@ -36,6 +36,7 @@ define( 'UM_VERSION', $plugin_data['Version'] );
define( 'UM_PLUGIN_NAME', $plugin_data['Name'] );
define( 'UM_WP_FUNCTIONS_VERSION', '6.8.0' ); // Updates every major WordPress release.
define( 'UM_LICENSE_REQUEST_DEBUG', false ); // Set true then need to debug the license request.
define( 'UM_UPDATER_DEBUG', false ); // Set true then need to debug the upgrade packages.
// define( 'UM_DEV_MODE', true );
require_once 'includes/class-functions.php';