diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml
index 087ee59e..57c9ab73 100644
--- a/.github/workflows/code-quality.yml
+++ b/.github/workflows/code-quality.yml
@@ -1,4 +1,4 @@
-name: JobBoardWP GitHub Actions
+name: Ultimate Member - Checking Code quality through PHPCS + WPCS
on:
push:
diff --git a/assets/js/um-gdpr.js b/assets/js/um-gdpr.js
index 31c0fde9..f06d5907 100644
--- a/assets/js/um-gdpr.js
+++ b/assets/js/um-gdpr.js
@@ -1,22 +1,22 @@
-(function( $ ) {
+(function ( $ ) {
'use strict';
- $(document).on('click', "a.um-toggle-gdpr" ,function() {
-
- var me = jQuery(this);
+ $( document ).on( 'click', 'a.um-toggle-gdpr', function ( e ) {
+ let $a = jQuery( e.currentTarget );
+ let $area = $a.closest( '.um-field-area' );
+ let $content = $area.find( '.um-gdpr-content' );
- $( ".um-gdpr-content" ).toggle( "fast", function() {
- if( $( ".um-gdpr-content" ).is(':visible') ){
- me.text( me.data('toggle-hide') );
- }
-
- if( $( ".um-gdpr-content" ).is(':hidden') ){
- me.text( me.data('toggle-show') );
- }
-
- });
-
- });
+ if ( $content.is( ':visible' ) ) {
+ $area.find( 'a.um-toggle-gdpr' ).text( $a.data( 'toggle-show' ) );
+ $content.hide().find( 'a.um-toggle-gdpr' ).remove();
+ if ( $a.length ) {
+ $a.get( 0 ).scrollIntoView();
+ }
+ } else {
+ $area.find( 'a.um-toggle-gdpr' ).text( $a.data( 'toggle-hide' ) );
+ $content.show().prepend( $a.clone() );
+ }
+ } );
})( jQuery );
diff --git a/assets/js/um-gdpr.min.js b/assets/js/um-gdpr.min.js
index f3e35c42..d862d028 100644
--- a/assets/js/um-gdpr.min.js
+++ b/assets/js/um-gdpr.min.js
@@ -1 +1 @@
-!function(e){"use strict";e(document).on("click","a.um-toggle-gdpr",function(){var t=jQuery(this);e(".um-gdpr-content").toggle("fast",function(){e(".um-gdpr-content").is(":visible")&&t.text(t.data("toggle-hide")),e(".um-gdpr-content").is(":hidden")&&t.text(t.data("toggle-show"))})})}(jQuery);
\ No newline at end of file
+!function(){"use strict";jQuery(document).on("click","a.um-toggle-gdpr",function(e){let t=jQuery(e.currentTarget),g=t.closest(".um-field-area"),o=g.find(".um-gdpr-content");o.is(":visible")?(g.find("a.um-toggle-gdpr").text(t.data("toggle-show")),o.hide().find("a.um-toggle-gdpr").remove(),t.length&&t.get(0).scrollIntoView()):(g.find("a.um-toggle-gdpr").text(t.data("toggle-hide")),o.show().prepend(t.clone()))})}();
\ No newline at end of file
diff --git a/includes/admin/class-admin.php b/includes/admin/class-admin.php
index d503b5cf..c6cf0c80 100644
--- a/includes/admin/class-admin.php
+++ b/includes/admin/class-admin.php
@@ -72,6 +72,7 @@ if ( ! class_exists( 'um\admin\Admin' ) ) {
add_filter( "{$prefix}plugin_action_links_" . um_plugin, array( &$this, 'plugin_links' ) );
add_action( 'um_admin_do_action__user_cache', array( &$this, 'user_cache' ) );
+ add_action( 'um_admin_do_action__user_status_cache', array( &$this, 'user_status_cache' ) );
add_action( 'um_admin_do_action__purge_temp', array( &$this, 'purge_temp' ) );
add_action( 'um_admin_do_action__manual_upgrades_request', array( &$this, 'manual_upgrades_request' ) );
add_action( 'um_admin_do_action__duplicate_form', array( &$this, 'duplicate_form' ) );
@@ -1673,8 +1674,53 @@ if ( ! class_exists( 'um\admin\Admin' ) ) {
$wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE 'um_cache_userdata_%'" );
- $url = add_query_arg( array( 'page' => 'ultimatemember', 'update' => 'cleared_cache' ), admin_url( 'admin.php' ) );
- exit( wp_redirect( $url ) );
+ $url = add_query_arg(
+ array(
+ 'page' => 'ultimatemember',
+ 'update' => 'cleared_cache',
+ ),
+ admin_url( 'admin.php' )
+ );
+ wp_redirect( $url );
+ exit;
+ }
+
+
+ /**
+ * Clear all users statuses count cache
+ *
+ * @param $action
+ */
+ function user_status_cache( $action ) {
+ if ( ! is_admin() || ! current_user_can( 'manage_options' ) ) {
+ die();
+ }
+
+ $statuses = array(
+ 'approved',
+ 'awaiting_admin_review',
+ 'awaiting_email_confirmation',
+ 'inactive',
+ 'rejected',
+ 'pending_dot', // not real status key, just for the transient
+ 'unassigned', // not real status key, just for the transient
+ );
+
+ foreach ( $statuses as $status ) {
+ delete_transient( "um_count_users_{$status}" );
+ }
+
+ do_action( 'um_flush_user_status_cache' );
+
+ $url = add_query_arg(
+ array(
+ 'page' => 'ultimatemember',
+ 'update' => 'cleared_status_cache',
+ ),
+ admin_url( 'admin.php' )
+ );
+ wp_redirect( $url );
+ exit;
}
diff --git a/includes/admin/core/class-admin-menu.php b/includes/admin/core/class-admin-menu.php
index 26c07eb3..7ec8b88c 100644
--- a/includes/admin/core/class-admin-menu.php
+++ b/includes/admin/core/class-admin-menu.php
@@ -121,7 +121,7 @@ if ( ! class_exists( 'um\admin\core\Admin_Menu' ) ) {
return;
}
- $count = UM()->user()->get_pending_users_count();
+ $count = UM()->query()->get_pending_users_count();
if ( is_array( $menu ) ) {
foreach ( $menu as $key => $menu_item ) {
if ( 0 === strpos( $menu_item[0], _x( 'Users', 'Admin menu name' ) ) ) {
diff --git a/includes/admin/core/class-admin-notices.php b/includes/admin/core/class-admin-notices.php
index 7b6e98ee..5bdc533e 100644
--- a/includes/admin/core/class-admin-notices.php
+++ b/includes/admin/core/class-admin-notices.php
@@ -440,6 +440,10 @@ if ( ! class_exists( 'um\admin\core\Admin_Notices' ) ) {
$messages[0]['content'] = __( 'Your user cache is now removed.', 'ultimate-member' );
break;
+ case 'cleared_status_cache':
+ $messages[0]['content'] = __( 'Your user statuses cache is now removed.', 'ultimate-member' );
+ break;
+
case 'got_updates':
$messages[0]['content'] = __( 'You have the latest updates.', 'ultimate-member' );
break;
@@ -528,13 +532,13 @@ if ( ! class_exists( 'um\admin\core\Admin_Notices' ) ) {
continue;
if ( ( is_object( $license ) && 'inactive' == $license->license ) || 'inactive' == $license ) {
- $arr_inactive_license_keys[ ] = $license->item_name;
+ $arr_inactive_license_keys[] = $license->item_name;
}
$invalid_license++;
}
- if ( ! empty( $arr_inactive_license_keys ) ) {
+ if ( ! empty( $arr_inactive_license_keys ) ) {
$this->add_notice( 'license_key', array(
'class' => 'error',
'message' => '
' . sprintf( __( 'There are %d inactive %s license keys for this site. This site is not authorized to get plugin updates. You can active this site on www.ultimatemember.com .', 'ultimate-member' ), count( $arr_inactive_license_keys ) , ultimatemember_plugin_name, UM()->store_url ) . '
',
diff --git a/includes/admin/core/class-admin-users.php b/includes/admin/core/class-admin-users.php
index b7a0d2a1..ee9eff56 100644
--- a/includes/admin/core/class-admin-users.php
+++ b/includes/admin/core/class-admin-users.php
@@ -411,7 +411,8 @@ if ( ! class_exists( 'um\admin\core\Admin_Users' ) ) {
'rejected' => __( 'Rejected', 'ultimate-member' ),
);
- UM()->query()->count_users_by_status( 'unassigned' );
+ // set default statuses if not already done
+ UM()->setup()->set_default_user_status();
foreach ( $status as $k => $v ) {
if ( isset( $_REQUEST['um_status'] ) && sanitize_key( $_REQUEST['um_status'] ) === $k ) {
diff --git a/includes/admin/core/packages/2.5.0/functions.php b/includes/admin/core/packages/2.5.0/functions.php
new file mode 100644
index 00000000..2eece725
--- /dev/null
+++ b/includes/admin/core/packages/2.5.0/functions.php
@@ -0,0 +1,44 @@
+admin()->check_ajax_nonce();
+
+ um_maybe_unset_time_limit();
+
+ $forms_query = new \WP_Query;
+ $forms = $forms_query->query( array(
+ 'post_type' => 'um_form',
+ 'posts_per_page' => -1,
+ 'fields' => 'ids',
+ ) );
+
+ foreach ( $forms as $form_id ) {
+ $forms_fields = get_post_meta( $form_id, '_um_custom_fields', true );
+ if ( ! is_array( $forms_fields ) ) {
+ continue;
+ }
+
+ $need_update = false;
+ foreach ( $forms_fields as $key => &$field ) {
+ if ( in_array( $key, array( 'phone_number', 'mobile_number' ), true ) ) {
+ $field['type'] = 'tel';
+ $need_update = true;
+ }
+ }
+
+ if ( $need_update ) {
+ update_post_meta( $form_id, '_um_custom_fields', $forms_fields );
+ }
+ }
+
+ // remove cached option with users count, don't create separate AJAX upgrade for that
+ delete_option( 'um_cached_users_queue' );
+
+ // delete temporarily option for fields upgrade
+ update_option( 'um_last_version_upgrade', '2.5.0' );
+
+ wp_send_json_success( array( 'message' => __( 'Phone Number and Mobile Number fields have been successfully updated.', 'ultimate-member' ) ) );
+}
diff --git a/includes/admin/core/packages/2.5.0/hooks.php b/includes/admin/core/packages/2.5.0/hooks.php
new file mode 100644
index 00000000..341848e3
--- /dev/null
+++ b/includes/admin/core/packages/2.5.0/hooks.php
@@ -0,0 +1,5 @@
+ 'phone_fields250',
+);
diff --git a/includes/admin/core/packages/2.5.0/init.php b/includes/admin/core/packages/2.5.0/init.php
new file mode 100644
index 00000000..b729b357
--- /dev/null
+++ b/includes/admin/core/packages/2.5.0/init.php
@@ -0,0 +1,30 @@
+
+
+
+
diff --git a/includes/admin/templates/dashboard/cache.php b/includes/admin/templates/dashboard/cache.php
index cd2e44f1..364417ac 100644
--- a/includes/admin/templates/dashboard/cache.php
+++ b/includes/admin/templates/dashboard/cache.php
@@ -1,5 +1,6 @@
-get_var(
"SELECT COUNT( option_id )
FROM {$wpdb->options}
WHERE option_name LIKE 'um_cache_userdata_%'"
-); ?>
+);
+?>
+
-
+
-
\ No newline at end of file
+
+
+
+
diff --git a/includes/core/class-builtin.php b/includes/core/class-builtin.php
index c3bc14fe..8a507fe0 100644
--- a/includes/core/class-builtin.php
+++ b/includes/core/class-builtin.php
@@ -245,6 +245,22 @@ if ( ! class_exists( 'um\core\Builtin' ) ) {
)
),
+ 'tel' => array(
+ 'name' => __( 'Telephone Box', 'ultimate-member' ),
+ 'col1' => array('_title','_metakey','_help','_default','_min_chars','_visibility'),
+ 'col2' => array('_label','_placeholder','_public','_roles','_validate','_custom_validate','_max_chars'),
+ 'col3' => array('_required','_editable','_icon'),
+ 'validate' => array(
+ '_title' => array(
+ 'mode' => 'required',
+ 'error' => __('You must provide a title','ultimate-member'),
+ ),
+ '_metakey' => array(
+ 'mode' => 'unique',
+ ),
+ )
+ ),
+
'number' => array(
'name' => __('Number','ultimate-member'),
'col1' => array('_title','_metakey','_help','_default','_min','_visibility'),
@@ -1133,7 +1149,7 @@ if ( ! class_exists( 'um\core\Builtin' ) ) {
'phone_number' => array(
'title' => __('Phone Number','ultimate-member'),
'metakey' => 'phone_number',
- 'type' => 'text',
+ 'type' => 'tel',
'label' => __('Phone Number','ultimate-member'),
'required' => 0,
'public' => 1,
@@ -1145,7 +1161,7 @@ if ( ! class_exists( 'um\core\Builtin' ) ) {
'mobile_number' => array(
'title' => __('Mobile Number','ultimate-member'),
'metakey' => 'mobile_number',
- 'type' => 'text',
+ 'type' => 'tel',
'label' => __('Mobile Number','ultimate-member'),
'required' => 0,
'public' => 1,
diff --git a/includes/core/class-fields.php b/includes/core/class-fields.php
index 7d9b1ffe..f31a17f8 100644
--- a/includes/core/class-fields.php
+++ b/includes/core/class-fields.php
@@ -1579,6 +1579,12 @@ if ( ! class_exists( 'um\core\Fields' ) ) {
break;
+ case 'tel':
+
+ $array['input'] = 'tel';
+
+ break;
+
case 'password':
$array['input'] = 'password';
@@ -2324,6 +2330,43 @@ if ( ! class_exists( 'um\core\Fields' ) ) {
$output .= '';
break;
+ /* Tel */
+ case 'tel':
+
+ $output .= 'get_atts( $key, $classes, $conditional, $data ) . '>';
+
+ if ( isset( $data['label'] ) ) {
+ $output .= $this->field_label( $label, $key, $data );
+ }
+
+ $output .= '
';
+
+ if ( ! empty( $icon ) && isset( $this->field_icons ) && $this->field_icons == 'field' ) {
+
+ $output .= '
';
+
+ }
+
+ $field_name = $key . UM()->form()->form_suffix;
+ $field_value = htmlspecialchars( $this->field_value( $key, $default, $data ) );
+
+ $output .= '
+
+
';
+
+ if ( ! empty( $disabled ) ) {
+ $output .= $this->disabled_hidden_field( $field_name, $field_value );
+ }
+
+ if ( $this->is_error( $key ) ) {
+ $output .= $this->field_error( $this->show_error( $key ) );
+ }else if ( $this->is_notice( $key ) ) {
+ $output .= $this->field_notice( $this->show_notice( $key ) );
+ }
+
+ $output .= '
';
+ break;
+
/* Number */
case 'number':
diff --git a/includes/core/class-member-directory.php b/includes/core/class-member-directory.php
index 752018f5..664f9d15 100644
--- a/includes/core/class-member-directory.php
+++ b/includes/core/class-member-directory.php
@@ -684,7 +684,13 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
$attrs['options'] = apply_filters( 'um_member_directory_filter_select_options_sorted', $attrs['options'], $attrs );
- $label = isset( $attrs['label'] ) ? $attrs['label'] : ''; ?>
+ $label = '';
+ if ( isset( $attrs['label'] ) ) {
+ $label = $attrs['label'];
+ } elseif ( ! isset( $attrs['label'] ) && isset( $attrs['title'] ) ) {
+ $label = $attrs['title'];
+ }
+ ?>
user()->maybe_generate_password_reset_key( $user_data );
+ $key = UM()->user()->maybe_generate_password_reset_key( $user_data );
- $url = add_query_arg( array( 'act' => 'reset_password', 'hash' => $key, 'user_id' => $user_id ), um_get_core_page( 'password-reset' ) );
+ // this link looks like WordPress native link e.g. wp-login.php?action=rp&key={hash}&login={user_login}
+ $url = add_query_arg(
+ array(
+ 'act' => 'reset_password',
+ 'hash' => $key,
+ 'login' => $user_data->user_login,
+ ),
+ um_get_core_page( 'password-reset' )
+ );
return $url;
}
@@ -149,14 +157,14 @@ if ( ! class_exists( 'um\core\Password' ) ) {
$args = apply_filters( 'um_reset_password_shortcode_args_filter', $args );
if ( isset( $this->change_password ) ) {
+ // then COOKIE are valid then get data from them and populate hidden fields for the password reset form
$args['template'] = 'password-change';
- $args['rp_key'] = '';
+ $args['rp_key'] = '';
$rp_cookie = 'wp-resetpass-' . COOKIEHASH;
if ( isset( $_COOKIE[ $rp_cookie ] ) && 0 < strpos( $_COOKIE[ $rp_cookie ], ':' ) ) {
list( $rp_login, $rp_key ) = explode( ':', wp_unslash( $_COOKIE[ $rp_cookie ] ), 2 );
- $user = get_user_by( 'login', $rp_login );
- $args['user_id'] = $user->ID;
+ $args['login'] = $rp_login;
$args['rp_key'] = $rp_key;
}
}
@@ -258,6 +266,7 @@ if ( ! class_exists( 'um\core\Password' ) ) {
/**
* Check if a legitimate password change request is in action
*
+ * works both for the Account > Password form and the Reset Password shortcode form
*
* @return bool
*/
@@ -280,56 +289,47 @@ if ( ! class_exists( 'um\core\Password' ) ) {
UM()->fields()->set_mode = 'password';
}
+ // validate $rp_cookie and hash via check_password_reset_key
if ( um_is_core_page( 'password-reset' ) && isset( $_REQUEST['act'] ) && 'reset_password' === sanitize_key( $_REQUEST['act'] ) ) {
wp_fix_server_vars();
$rp_cookie = 'wp-resetpass-' . COOKIEHASH;
- if ( isset( $_GET['hash'] ) ) {
- $userdata = get_userdata( wp_unslash( absint( $_GET['user_id'] ) ) );
- if ( ! $userdata || is_wp_error( $userdata ) ) {
- wp_redirect( add_query_arg( array( 'act' => 'reset_password', 'error' => 'invalidkey' ), get_permalink() ) );
- exit;
- }
- $rp_login = $userdata->user_login;
- $rp_key = wp_unslash( sanitize_text_field( $_GET['hash'] ) );
-
- $user = check_password_reset_key( $rp_key, $rp_login );
-
- if ( is_wp_error( $user ) ) {
- $this->setcookie( $rp_cookie, false );
- wp_redirect( add_query_arg( array( 'updated' => 'invalidkey' ), get_permalink() ) );
- } else {
- $value = sprintf( '%s:%s', $rp_login, wp_unslash( sanitize_text_field( $_GET['hash'] ) ) );
- $this->setcookie( $rp_cookie, $value );
- wp_safe_redirect( remove_query_arg( array( 'hash', 'user_id' ) ) );
- }
+ if ( isset( $_GET['hash'] ) && isset( $_GET['login'] ) ) {
+ $value = sprintf( '%s:%s', wp_unslash( $_GET['login'] ), wp_unslash( $_GET['hash'] ) );
+ $this->setcookie( $rp_cookie, $value );
+ wp_safe_redirect( remove_query_arg( array( 'hash', 'login' ) ) );
exit;
}
if ( isset( $_COOKIE[ $rp_cookie ] ) && 0 < strpos( $_COOKIE[ $rp_cookie ], ':' ) ) {
list( $rp_login, $rp_key ) = explode( ':', wp_unslash( $_COOKIE[ $rp_cookie ] ), 2 );
+
$user = check_password_reset_key( $rp_key, $rp_login );
+
+ if ( isset( $_POST['user_password'] ) && ! hash_equals( $rp_key, $_POST['rp_key'] ) ) {
+ $user = false;
+ }
} else {
$user = false;
}
- if ( ( ! $user || is_wp_error( $user ) ) && ! isset( $_GET['updated'] ) ) {
+ if ( ! $user || is_wp_error( $user ) ) {
$this->setcookie( $rp_cookie, false );
- if ( $user && $user->get_error_code() === 'expired_key' ) {
- wp_redirect( add_query_arg( array( 'updated' => 'expiredkey' ), get_permalink() ) );
+ if ( $user && 'expired_key' === $user->get_error_code() ) {
+ wp_redirect( add_query_arg( array( 'updated' => 'expiredkey' ), um_get_core_page( 'password-reset' ) ) );
} else {
- wp_redirect( add_query_arg( array( 'updated' => 'invalidkey' ), get_permalink() ) );
+ wp_redirect( add_query_arg( array( 'updated' => 'invalidkey' ), um_get_core_page( 'password-reset' ) ) );
}
exit;
}
+ // this variable is used for populating the reset password form via the hash and login
$this->change_password = true;
}
if ( $this->is_reset_request() ) {
-
UM()->form()->post_form = $_POST;
if ( empty( UM()->form()->post_form['mode'] ) ) {
@@ -358,7 +358,6 @@ if ( ! class_exists( 'um\core\Password' ) ) {
do_action( 'um_reset_password_errors_hook', UM()->form()->post_form );
if ( ! isset( UM()->form()->errors ) ) {
-
/**
* UM hook
*
@@ -379,7 +378,6 @@ if ( ! class_exists( 'um\core\Password' ) ) {
* ?>
*/
do_action( 'um_reset_password_process_hook', UM()->form()->post_form );
-
}
}
@@ -408,7 +406,6 @@ if ( ! class_exists( 'um\core\Password' ) ) {
do_action( 'um_change_password_errors_hook', UM()->form()->post_form );
if ( ! isset( UM()->form()->errors ) ) {
-
/**
* UM hook
*
@@ -429,7 +426,6 @@ if ( ! class_exists( 'um\core\Password' ) ) {
* ?>
*/
do_action( 'um_change_password_process_hook', UM()->form()->post_form );
-
}
}
}
@@ -446,7 +442,6 @@ if ( ! class_exists( 'um\core\Password' ) ) {
}
$user = '';
-
foreach ( $args as $key => $val ) {
if ( strstr( $key, 'username_b' ) ) {
$user = trim( sanitize_text_field( $val ) );
@@ -468,7 +463,6 @@ if ( ! class_exists( 'um\core\Password' ) ) {
$is_admin = user_can( absint( $user_id ), 'manage_options' );
if ( UM()->options()->get( 'enable_reset_password_limit' ) ) { // if reset password limit is set
-
if ( ! ( UM()->options()->get( 'disable_admin_reset_password_limit' ) && $is_admin ) ) {
// Doesn't trigger this when a user has admin capabilities and when reset password limit is disabled for admins
$limit = UM()->options()->get( 'reset_password_limit_number' );
@@ -480,7 +474,6 @@ if ( ! class_exists( 'um\core\Password' ) ) {
}
}
}
-
}
@@ -509,13 +502,16 @@ if ( ! class_exists( 'um\core\Password' ) ) {
UM()->user()->password_reset();
}
- exit( wp_redirect( um_get_core_page('password-reset', 'checkemail' ) ) );
+ wp_redirect( um_get_core_page('password-reset', 'checkemail' ) );
+ exit;
}
/**
* Error handler: changing password
*
+ * It works both for the Reset Password Shortcode and Account > Change password form
+ *
* @param $args
*/
public function um_change_password_errors_hook( $args ) {
@@ -523,9 +519,11 @@ if ( ! class_exists( 'um\core\Password' ) ) {
wp_die( esc_html__( 'Hello, spam bot!', 'ultimate-member' ) );
}
- if ( ! is_user_logged_in() && isset( $args ) && ! um_is_core_page( 'password-reset' ) ||
- is_user_logged_in() && isset( $args['user_id'] ) && absint( $args['user_id'] ) !== get_current_user_id() ) {
- wp_die( esc_html__( 'This is not possible for security reasons.', 'ultimate-member' ) );
+ if ( isset( $args['_um_account'] ) == 1 && isset( $args['_um_account_tab'] ) && 'password' === sanitize_key( $args['_um_account_tab'] ) ) {
+ // validate for security on the account change password page
+ if ( ! is_user_logged_in() ) {
+ wp_die( esc_html__( 'This is not possible for security reasons.', 'ultimate-member' ) );
+ }
}
if ( isset( $args['user_password'] ) && empty( $args['user_password'] ) ) {
@@ -535,6 +533,7 @@ if ( ! class_exists( 'um\core\Password' ) ) {
if ( isset( $args['user_password'] ) ) {
$args['user_password'] = trim( $args['user_password'] );
}
+
if ( isset( $args['confirm_user_password'] ) ) {
$args['confirm_user_password'] = trim( $args['confirm_user_password'] );
}
@@ -545,7 +544,6 @@ if ( ! class_exists( 'um\core\Password' ) ) {
}
if ( UM()->options()->get( 'require_strongpass' ) ) {
-
$min_length = UM()->options()->get( 'password_min_chars' );
$min_length = ! empty( $min_length ) ? $min_length : 8;
$max_length = UM()->options()->get( 'password_max_chars' );
@@ -571,7 +569,6 @@ if ( ! class_exists( 'um\core\Password' ) ) {
if ( isset( $args['user_password'] ) && isset( $args['confirm_user_password'] ) && $args['user_password'] !== $args['confirm_user_password'] ) {
UM()->form()->add_error( 'confirm_user_password', __( 'Your passwords do not match', 'ultimate-member' ) );
}
-
}
@@ -582,20 +579,16 @@ if ( ! class_exists( 'um\core\Password' ) ) {
*/
public function um_change_password_process_hook( $args ) {
if ( isset( $args['_um_password_change'] ) && $args['_um_password_change'] == 1 ) {
-
+ // it only works on the Password Reset Shortcode form
$rp_cookie = 'wp-resetpass-' . COOKIEHASH;
- $user = get_userdata( absint( $args['user_id'] ) );
if ( isset( $_COOKIE[ $rp_cookie ] ) && 0 < strpos( $_COOKIE[ $rp_cookie ], ':' ) ) {
list( $rp_login, $rp_key ) = explode( ':', wp_unslash( $_COOKIE[ $rp_cookie ] ), 2 );
- if ( $user->user_login != $rp_login ) {
+ $user = check_password_reset_key( $rp_key, $rp_login );
+
+ if ( isset( $args['user_password'] ) && ! hash_equals( $rp_key, $args['rp_key'] ) ) {
$user = false;
- } else {
- $user = check_password_reset_key( $rp_key, $rp_login );
- if ( isset( $args['user_password'] ) && ! hash_equals( $rp_key, $args['rp_key'] ) ) {
- $user = false;
- }
}
} else {
$user = false;
@@ -603,31 +596,24 @@ if ( ! class_exists( 'um\core\Password' ) ) {
if ( ! $user || is_wp_error( $user ) ) {
$this->setcookie( $rp_cookie, false );
- if ( $user && $user->get_error_code() === 'expired_key' ) {
- wp_redirect( add_query_arg( array( 'updated' => 'expiredkey' ), get_permalink() ) );
+ if ( $user && 'expired_key' === $user->get_error_code() ) {
+ wp_redirect( add_query_arg( array( 'updated' => 'expiredkey' ), um_get_core_page( 'password-reset' ) ) );
} else {
- wp_redirect( add_query_arg( array( 'updated' => 'invalidkey' ), get_permalink() ) );
+ wp_redirect( add_query_arg( array( 'updated' => 'invalidkey' ), um_get_core_page( 'password-reset' ) ) );
}
exit;
}
-
$errors = new \WP_Error();
- /**
- * Fires before the password reset procedure is validated.
- *
- * @since 3.5.0
- *
- * @param object $errors WP Error object.
- * @param \WP_User|\WP_Error $user WP_User object if the login and reset key match. WP_Error object otherwise.
- */
+
+ /** This action is documented in wp-login.php */
do_action( 'validate_password_reset', $errors, $user );
if ( ( ! $errors->get_error_code() ) ) {
reset_password( $user, trim( $args['user_password'] ) );
// send the Password Changed Email
- UM()->user()->password_changed();
+ UM()->user()->password_changed( $user->ID );
// clear temporary data
$attempts = (int) get_user_meta( $user->ID, 'password_rst_attempts', true );
@@ -636,11 +622,6 @@ if ( ! class_exists( 'um\core\Password' ) ) {
}
$this->setcookie( $rp_cookie, false );
- // logout
- if ( is_user_logged_in() ) {
- wp_logout();
- }
-
/**
* UM hook
*
@@ -660,9 +641,15 @@ if ( ! class_exists( 'um\core\Password' ) ) {
* }
* ?>
*/
- do_action( 'um_after_changing_user_password', absint( $args['user_id'] ) );
+ do_action( 'um_after_changing_user_password', $user->ID );
- exit( wp_redirect( um_get_core_page( 'login', 'password_changed' ) ) );
+ if ( ! is_user_logged_in() ) {
+ $url = um_get_core_page( 'login', 'password_changed' );
+ } else {
+ $url = um_get_core_page( 'password-reset', 'password_changed' );
+ }
+ wp_redirect( $url );
+ exit;
}
}
}
diff --git a/includes/core/class-query.php b/includes/core/class-query.php
index 7061be61..ef19440a 100644
--- a/includes/core/class-query.php
+++ b/includes/core/class-query.php
@@ -217,48 +217,114 @@ if ( ! class_exists( 'um\core\Query' ) ) {
/**
* Count users by status
*
+ * @since 2.4.2 $status = 'unassigned' is unused. Please use `UM()->setup()->set_default_user_status()` instead. Will be deprecated since 3.0
+ *
* @param $status
*
* @return int
*/
function count_users_by_status( $status ) {
- $args = array( 'fields' => 'ID', 'number' => 0, 'um_custom_user_query' => true );
- if ( $status == 'unassigned' ) {
- $args['meta_query'][] = array(array('key' => 'account_status','compare' => 'NOT EXISTS'));
- $users = new \WP_User_Query( $args );
- foreach ( $users->results as $user ) {
- update_user_meta( $user, 'account_status', 'approved' );
- }
+ if ( 'unassigned' === $status ) {
+ _deprecated_argument(
+ __FUNCTION__,
+ '2.4.2',
+ __( 'The "unassigned" $status has been removed. Use `UM()->setup()->set_default_user_status()` for setting up default user account status.', 'ultimate-member' )
+ );
+
+ UM()->setup()->set_default_user_status();
return 0;
- } else {
- $args['meta_query'][] = array(array('key' => 'account_status','value' => $status,'compare' => '='));
}
- $users = new \WP_User_Query( $args );
- return count( $users->results );
+
+ $users_count = get_transient( "um_count_users_{$status}" );
+ if ( false === $users_count ) {
+ $args = array(
+ 'fields' => 'ids',
+ 'number' => 1,
+ 'meta_query' => array(
+ array(
+ 'key' => 'account_status',
+ 'value' => $status,
+ 'compare' => '=',
+ ),
+ ),
+ 'um_custom_user_query' => true,
+ );
+
+ $users = new \WP_User_Query( $args );
+ if ( empty( $users ) || is_wp_error( $users ) ) {
+ $users_count = 0;
+ } else {
+ $users_count = $users->get_total();
+ }
+
+ set_transient( "um_count_users_{$status}", $users_count );
+ }
+
+ return $users_count;
}
/**
- * Get users by status
+ * Get pending users (in queue)
*
- * @param $status
- * @param int $number
- *
- * @return array
+ * @return int
*/
- function get_users_by_status($status, $number = 5){
- $args = array( 'fields' => 'ID', 'number' => $number, 'orderby' => 'user_registered', 'order' => 'desc' );
+ function get_pending_users_count() {
+ $users_count = get_transient( 'um_count_users_pending_dot' );
+ if ( false === $users_count ) {
+ $args = array(
+ 'fields' => 'ids',
+ 'number' => 1,
+ 'meta_query' => array(
+ 'relation' => 'OR',
+ array(
+ 'key' => 'account_status',
+ 'value' => 'awaiting_email_confirmation',
+ 'compare' => '=',
+ ),
+ array(
+ 'key' => 'account_status',
+ 'value' => 'awaiting_admin_review',
+ 'compare' => '=',
+ ),
+ ),
+ 'um_custom_user_query' => true,
+ );
- $args['meta_query'][] = array(
- array(
- 'key' => 'account_status',
- 'value' => $status,
- 'compare' => '='
- )
- );
+ /**
+ * UM hook
+ *
+ * @type filter
+ * @title um_admin_pending_queue_filter
+ * @description Change user query arguments when get pending users
+ * @input_vars
+ * [{"var":"$args","type":"array","desc":"WP_Users query arguments"}]
+ * @change_log
+ * ["Since: 2.0"]
+ * @usage
+ *
+ * @example
+ *
+ */
+ $args = apply_filters( 'um_admin_pending_queue_filter', $args );
- $users = new \WP_User_Query( $args );
- return $users->results;
+ $users = new \WP_User_Query( $args );
+ if ( empty( $users ) || is_wp_error( $users ) ) {
+ $users_count = 0;
+ } else {
+ $users_count = $users->get_total();
+ }
+
+ set_transient( 'um_count_users_pending_dot', $users_count );
+ }
+
+ return $users_count;
}
@@ -456,5 +522,32 @@ if ( ! class_exists( 'um\core\Query' ) ) {
}
}
+
+ /**
+ * Get users by status
+ *
+ * @param $status
+ * @param int $number
+ *
+ * @deprecated 2.4.2
+ *
+ * @return array
+ */
+ function get_users_by_status( $status, $number = 5 ) {
+ _deprecated_function( __METHOD__, '2.4.2' );
+
+ $args = array( 'fields' => 'ID', 'number' => $number, 'orderby' => 'user_registered', 'order' => 'desc' );
+
+ $args['meta_query'][] = array(
+ array(
+ 'key' => 'account_status',
+ 'value' => $status,
+ 'compare' => '='
+ )
+ );
+
+ $users = new \WP_User_Query( $args );
+ return $users->results;
+ }
}
}
diff --git a/includes/core/class-setup.php b/includes/core/class-setup.php
index d788f7fe..3981cff6 100644
--- a/includes/core/class-setup.php
+++ b/includes/core/class-setup.php
@@ -32,6 +32,7 @@ if ( ! class_exists( 'um\core\Setup' ) ) {
$this->install_default_forms();
$this->set_default_settings();
$this->set_default_role_meta();
+ $this->set_default_user_status();
}
@@ -262,12 +263,49 @@ KEY meta_value_indx (um_value(191))
* Set UM roles meta to Default WP roles
*/
function set_default_role_meta() {
- //for set accounts without account status approved status
- UM()->query()->count_users_by_status( 'unassigned' );
-
foreach ( UM()->config()->default_roles_metadata as $role => $meta ) {
add_option( "um_role_{$role}_meta", $meta );
}
}
+
+
+ /**
+ * Set accounts without account_status meta to 'approved' status
+ *
+ * @since 2.4.2
+ */
+ function set_default_user_status() {
+ $result = get_transient( 'um_count_users_unassigned' );
+ if ( false === $result ) {
+ $args = array(
+ 'fields' => 'ids',
+ 'number' => 0,
+ 'meta_query' => array(
+ array(
+ 'key' => 'account_status',
+ 'compare' => 'NOT EXISTS',
+ ),
+ ),
+ 'um_custom_user_query' => true,
+ );
+
+ $users = new \WP_User_Query( $args );
+ if ( empty( $users ) || is_wp_error( $users ) ) {
+ $result = array();
+ } else {
+ $result = $users->get_results();
+ }
+
+ set_transient( 'um_count_users_unassigned', $result, DAY_IN_SECONDS );
+ }
+
+ if ( empty( $result ) ) {
+ return;
+ }
+
+ foreach ( $result as $user_id ) {
+ update_user_meta( $user_id, 'account_status', 'approved' );
+ }
+ }
}
-}
\ No newline at end of file
+}
diff --git a/includes/core/class-user.php b/includes/core/class-user.php
index 069be147..42830346 100644
--- a/includes/core/class-user.php
+++ b/includes/core/class-user.php
@@ -65,11 +65,8 @@ if ( ! class_exists( 'um\core\User' ) ) {
$this->target_id = null;
// When the cache should be cleared
- add_action( 'um_delete_user_hook', array( &$this, 'remove_cached_queue' ) );
add_action( 'um_delete_user', array( &$this, 'remove_cache' ), 10, 1 );
- add_action( 'um_after_user_status_is_changed_hook', array( &$this, 'remove_cached_queue' ) );
-
// When user cache should be cleared
add_action( 'um_after_user_updated', array( &$this, 'remove_cache' ) );
add_action( 'um_after_user_account_updated', array( &$this, 'remove_cache' ) );
@@ -111,6 +108,211 @@ if ( ! class_exists( 'um\core\User' ) ) {
add_action( 'added_user_meta', array( &$this, 'on_update_usermeta' ), 10, 4 );
add_action( 'deleted_user_meta', array( &$this, 'on_delete_usermeta' ), 10, 4 );
+
+
+ add_action( 'update_user_meta', array( &$this, 'flush_um_count_users_transient_update' ), 10, 4 );
+ add_action( 'added_user_meta', array( &$this, 'flush_um_count_users_transient_add' ), 10, 4 );
+ add_action( 'delete_user_meta', array( &$this, 'flush_um_count_users_transient_delete' ), 10, 4 );
+ }
+
+
+ /**
+ * @param $meta_ids
+ * @param $object_id
+ * @param $meta_key
+ * @param $_meta_value
+ */
+ public function flush_um_count_users_transient_update( $meta_ids, $object_id, $meta_key, $_meta_value ) {
+ if ( 'account_status' !== $meta_key ) {
+ return;
+ }
+
+ // related to the User role > Registration Options Metabox > Registration status 2nd and 3rd option
+ if ( in_array( $_meta_value, array( 'checkmail', 'pending' ), true ) ) {
+ return;
+ }
+
+ $pending_statuses = array(
+ 'awaiting_email_confirmation',
+ 'awaiting_admin_review',
+ );
+
+ $old = get_user_meta( $object_id, $meta_key, true );
+
+ if ( $old === $_meta_value ) {
+ return;
+ }
+
+ // related to the User role > Registration Options Metabox > Registration status 2nd and 3rd option
+ if ( ! in_array( $old, array( 'checkmail', 'pending' ), true ) ) {
+ // deduct old transient count
+ $count = get_transient( "um_count_users_{$old}" );
+ if ( false !== $count ) {
+ if ( ! is_numeric( $count ) ) {
+ delete_transient( "um_count_users_{$old}" );
+ } else {
+ if ( 0 < $count ) {
+ $count--;
+ } else {
+ $count = 0;
+ }
+ set_transient( "um_count_users_{$old}", $count );
+ }
+ }
+
+ if ( in_array( $old, $pending_statuses, true ) && ! in_array( $_meta_value, $pending_statuses, true ) ) {
+ // deduct old transient count
+ $count = get_transient( 'um_count_users_pending_dot' );
+ if ( false !== $count ) {
+ if ( ! is_numeric( $count ) ) {
+ delete_transient( 'um_count_users_pending_dot' );
+ } else {
+ if ( 0 < $count ) {
+ $count--;
+ } else {
+ $count = 0;
+ }
+ set_transient( 'um_count_users_pending_dot', $count );
+ }
+ }
+ }
+ }
+
+ // add new transient count
+ $count = get_transient( "um_count_users_{$_meta_value}" );
+ if ( false !== $count ) {
+ if ( is_numeric( $count ) ) {
+ $count++;
+ } else {
+ $count = 1;
+ }
+ } else {
+ $count = 1;
+ }
+ set_transient( "um_count_users_{$_meta_value}", $count );
+
+ if ( in_array( $_meta_value, $pending_statuses, true ) && ! in_array( $old, $pending_statuses, true ) ) {
+ // add new transient count
+ $count = get_transient( 'um_count_users_pending_dot' );
+ if ( false !== $count ) {
+ if ( is_numeric( $count ) ) {
+ $count++;
+ } else {
+ $count = 1;
+ }
+ } else {
+ $count = 1;
+ }
+ set_transient( 'um_count_users_pending_dot', $count );
+ }
+ }
+
+
+ /**
+ * @param $meta_ids
+ * @param $object_id
+ * @param $meta_key
+ * @param $_meta_value
+ */
+ public function flush_um_count_users_transient_add( $meta_ids, $object_id, $meta_key, $_meta_value ) {
+ if ( 'account_status' !== $meta_key ) {
+ return;
+ }
+
+ // related to the User role > Registration Options Metabox > Registration status 2nd and 3rd option
+ if ( in_array( $_meta_value, array( 'checkmail', 'pending' ), true ) ) {
+ return;
+ }
+
+ $pending_statuses = array(
+ 'awaiting_email_confirmation',
+ 'awaiting_admin_review',
+ );
+
+ // add new transient count
+ $count = get_transient( "um_count_users_{$_meta_value}" );
+ if ( false !== $count ) {
+ if ( is_numeric( $count ) ) {
+ $count++;
+ } else {
+ $count = 1;
+ }
+ } else {
+ $count = 1;
+ }
+ set_transient( "um_count_users_{$_meta_value}", $count );
+
+ if ( in_array( $_meta_value, $pending_statuses, true ) ) {
+ // add new transient count
+ $pending_count = get_transient( 'um_count_users_pending_dot' );
+ if ( false !== $pending_count ) {
+ if ( is_numeric( $pending_count ) ) {
+ $pending_count++;
+ } else {
+ $pending_count = 1;
+ }
+ } else {
+ $pending_count = 1;
+ }
+ set_transient( 'um_count_users_pending_dot', $pending_count );
+ }
+ }
+
+
+ /**
+ * @param $meta_ids
+ * @param $object_id
+ * @param $meta_key
+ * @param $_meta_value
+ */
+ public function flush_um_count_users_transient_delete( $meta_ids, $object_id, $meta_key, $_meta_value ) {
+ if ( 'account_status' !== $meta_key ) {
+ return;
+ }
+
+ $value = ( '' !== $_meta_value ) ? $_meta_value : get_user_meta( $object_id, $meta_key, true );
+
+ // related to the User role > Registration Options Metabox > Registration status 2nd and 3rd option
+ if ( in_array( $value, array( 'checkmail', 'pending' ), true ) ) {
+ return;
+ }
+
+ $pending_statuses = array(
+ 'awaiting_email_confirmation',
+ 'awaiting_admin_review',
+ );
+
+ // deduct old transient count
+ $count = get_transient( "um_count_users_{$value}" );
+ if ( false !== $count ) {
+ if ( ! is_numeric( $count ) ) {
+ delete_transient( "um_count_users_{$value}" );
+ } else {
+ if ( 0 < $count ) {
+ $count--;
+ } else {
+ $count = 0;
+ }
+ set_transient( "um_count_users_{$value}", $count );
+ }
+ }
+
+ if ( in_array( $value, $pending_statuses, true ) ) {
+ // deduct old transient count
+ $count = get_transient( 'um_count_users_pending_dot' );
+ if ( false !== $count ) {
+ if ( ! is_numeric( $count ) ) {
+ delete_transient( 'um_count_users_pending_dot' );
+ } else {
+ if ( 0 < $count ) {
+ $count--;
+ } else {
+ $count = 0;
+ }
+ set_transient( 'um_count_users_pending_dot', $count );
+ }
+ }
+ }
}
@@ -226,7 +428,7 @@ if ( ! class_exists( 'um\core\User' ) ) {
$hide_in_members = UM()->member_directory()->get_hide_in_members_default();
if ( ! empty( $_meta_value ) ) {
if ( $_meta_value == 'Yes' || $_meta_value == __( 'Yes', 'ultimate-member' ) ||
- array_intersect( array( 'Yes', __( 'Yes', 'ultimate-member' ) ), $_meta_value ) ) {
+ array_intersect( array( 'Yes', __( 'Yes', 'ultimate-member' ) ), $_meta_value ) ) {
$hide_in_members = true;
} else {
$hide_in_members = false;
@@ -324,6 +526,9 @@ if ( ! class_exists( 'um\core\User' ) ) {
// remove uploads
UM()->files()->remove_dir( UM()->files()->upload_temp );
UM()->files()->remove_dir( UM()->uploader()->get_upload_base_dir() . um_user( 'ID' ) . DIRECTORY_SEPARATOR );
+
+ delete_transient( 'um_count_users_unassigned' );
+ delete_transient( 'um_count_users_pending_dot' );
}
@@ -391,60 +596,6 @@ if ( ! class_exists( 'um\core\User' ) ) {
}
- /**
- * Get pending users (in queue)
- */
- function get_pending_users_count() {
-
- $cached_users_queue = get_option( 'um_cached_users_queue' );
- if ( $cached_users_queue > 0 && ! isset( $_REQUEST['delete_count'] ) ) {
- return $cached_users_queue;
- }
-
- $args = array( 'fields' => 'ID', 'number' => 1 );
- $args['meta_query']['relation'] = 'OR';
- $args['meta_query'][] = array(
- 'key' => 'account_status',
- 'value' => 'awaiting_email_confirmation',
- 'compare' => '='
- );
- $args['meta_query'][] = array(
- 'key' => 'account_status',
- 'value' => 'awaiting_admin_review',
- 'compare' => '='
- );
-
- /**
- * UM hook
- *
- * @type filter
- * @title um_admin_pending_queue_filter
- * @description Change user query arguments when get pending users
- * @input_vars
- * [{"var":"$args","type":"array","desc":"WP_Users query arguments"}]
- * @change_log
- * ["Since: 2.0"]
- * @usage
- *
- * @example
- *
- */
- $args = apply_filters( 'um_admin_pending_queue_filter', $args );
- $users = new \WP_User_Query( $args );
-
- delete_option( 'um_cached_users_queue' );
- add_option( 'um_cached_users_queue', $users->get_total(), '', 'no' );
-
- return $users->get_total();
- }
-
-
/**
* @param $user_id
*
@@ -597,7 +748,6 @@ if ( ! class_exists( 'um\core\User' ) ) {
* @param $user_id
*/
function user_register_via_admin( $user_id ) {
-
if ( empty( $user_id ) ) {
return;
}
@@ -634,6 +784,7 @@ if ( ! class_exists( 'um\core\User' ) ) {
do_action( 'um_user_register', $user_id, $_POST );
}
+ delete_transient( 'um_count_users_unassigned' );
}
@@ -807,14 +958,6 @@ if ( ! class_exists( 'um\core\User' ) ) {
}
- /**
- * Remove cached queue from Users backend
- */
- function remove_cached_queue() {
- delete_option( 'um_cached_users_queue' );
- }
-
-
/**
* Converts object to array
*
@@ -1053,11 +1196,11 @@ if ( ! class_exists( 'um\core\User' ) ) {
$role_meta = apply_filters( 'um_user_permissions_filter', $role_meta, $this->id );
/*$role_meta = array_map( function( $key, $item ) {
- if ( strpos( $key, '_um_' ) === 0 )
- $key = str_replace( '_um_', '', $key );
+ if ( strpos( $key, '_um_' ) === 0 )
+ $key = str_replace( '_um_', '', $key );
- return array( $key => $item );
- }, array_keys( $role_meta ), $role_meta );*/
+ return array( $key => $item );
+ }, array_keys( $role_meta ), $role_meta );*/
$this->profile = array_merge( $this->profile, (array)$role_meta );
@@ -1409,9 +1552,19 @@ if ( ! class_exists( 'um\core\User' ) ) {
/**
* Password changed email
+ *
+ * @param null|int $user_id
*/
- function password_changed() {
+ function password_changed( $user_id = null ) {
+ if ( ! empty( $user_id ) ) {
+ um_fetch_user( $user_id );
+ }
+
UM()->mail()->send( um_user( 'user_email' ), 'changedpw_email' );
+
+ if ( ! empty( $user_id ) ) {
+ um_reset_user();
+ }
}
@@ -2187,5 +2340,27 @@ if ( ! class_exists( 'um\core\User' ) ) {
$replace_placeholders[] = um_user( 'account_activation_link' );
return $replace_placeholders;
}
+
+
+ /**
+ * Get pending users (in queue)
+ *
+ * @deprecated 2.4.2
+ */
+ function get_pending_users_count() {
+ _deprecated_function( __METHOD__, '2.4.2', 'UM()->query()->get_pending_users_count()' );
+ return UM()->query()->get_pending_users_count();
+ }
+
+
+ /**
+ * Remove cached queue from Users backend
+ *
+ * @deprecated 2.4.2
+ */
+ function remove_cached_queue() {
+ _deprecated_function( __METHOD__, '2.4.2', '' );
+ delete_option( 'um_cached_users_queue' );
+ }
}
}
diff --git a/includes/core/rest/class-api.php b/includes/core/rest/class-api.php
index ef8c3fb3..ba12fb9c 100644
--- a/includes/core/rest/class-api.php
+++ b/includes/core/rest/class-api.php
@@ -296,7 +296,7 @@ if ( ! class_exists( 'um\core\rest\API' ) ) {
$count = absint( $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}users" ) );
$response['stats']['total_users'] = $count;
- $pending = UM()->user()->get_pending_users_count();
+ $pending = UM()->query()->get_pending_users_count();
$response['stats']['pending_users'] = absint( $pending );
/**
@@ -612,4 +612,4 @@ if ( ! class_exists( 'um\core\rest\API' ) ) {
}
}
-}
\ No newline at end of file
+}
diff --git a/includes/core/um-actions-account.php b/includes/core/um-actions-account.php
index c4324e74..723663a5 100644
--- a/includes/core/um-actions-account.php
+++ b/includes/core/um-actions-account.php
@@ -209,20 +209,18 @@ function um_submit_account_details( $args ) {
//change password account's tab
if ( 'password' === $current_tab && $args['user_password'] && $args['confirm_user_password'] ) {
-
$changes['user_pass'] = trim( $args['user_password'] );
-
- $args['user_id'] = $user_id;
+ $args['user_id'] = get_current_user_id();
UM()->user()->password_changed();
add_filter( 'send_password_change_email', '__return_false' );
//clear all sessions with old passwords
- $user = WP_Session_Tokens::get_instance( $user_id );
+ $user = WP_Session_Tokens::get_instance( $args['user_id'] );
$user->destroy_all();
- wp_set_password( $changes['user_pass'], $user_id );
+ wp_set_password( $changes['user_pass'], $args['user_id'] );
do_action( 'um_before_signon_after_account_changes', $args );
diff --git a/includes/core/um-actions-register.php b/includes/core/um-actions-register.php
index b170a89e..604f3177 100644
--- a/includes/core/um-actions-register.php
+++ b/includes/core/um-actions-register.php
@@ -51,14 +51,10 @@ add_action('um_post_registration_pending_hook', 'um_post_registration_pending_ho
* @param $args
*/
function um_after_insert_user( $user_id, $args ) {
-
if ( empty( $user_id ) || ( is_object( $user_id ) && is_a( $user_id, 'WP_Error' ) ) ) {
return;
}
- //clear Users cached queue
- UM()->user()->remove_cached_queue();
-
um_fetch_user( $user_id );
if ( ! empty( $args['submitted'] ) ) {
UM()->user()->set_registration_details( $args['submitted'], $args );
diff --git a/includes/core/um-filters-fields.php b/includes/core/um-filters-fields.php
index 3ad00b43..7bde5b92 100644
--- a/includes/core/um-filters-fields.php
+++ b/includes/core/um-filters-fields.php
@@ -99,6 +99,22 @@ function um_profile_field_filter_hook__vimeo_video( $value, $data ) {
add_filter( 'um_profile_field_filter_hook__vimeo_video', 'um_profile_field_filter_hook__vimeo_video', 99, 2 );
+/**
+ * Outputs a phone link
+ *
+ * @param $value
+ * @param $data
+ *
+ * @return int|string
+ */
+function um_profile_field_filter_hook__phone( $value, $data ) {
+ $value = '' . esc_html( $value ) . ' ';
+ return $value;
+}
+add_filter( 'um_profile_field_filter_hook__phone_number', 'um_profile_field_filter_hook__phone', 99, 2 );
+add_filter( 'um_profile_field_filter_hook__mobile_number', 'um_profile_field_filter_hook__phone', 99, 2 );
+
+
/**
* Outputs a viber link
*
diff --git a/readme.txt b/readme.txt
index 7a98a3ed..edca5c33 100644
--- a/readme.txt
+++ b/readme.txt
@@ -7,7 +7,7 @@ Tags: community, member, membership, user-profile, user-registration
Requires PHP: 5.6
Requires at least: 5.0
Tested up to: 6.0
-Stable tag: 2.4.2
+Stable tag: 2.5.0
License: GNU Version 2 or Any Later Version
License URI: http://www.gnu.org/licenses/gpl-3.0.txt
@@ -163,6 +163,32 @@ No, you do not need to use our plugin’s login or registration pages and can us
* To learn more about version 2.1 please see this [docs](https://docs.ultimatemember.com/article/1512-upgrade-2-1-0)
* UM2.1+ is a significant update to the Member Directories' code base from 2.0.x. Please make sure you take a full-site backup with restore point before updating the plugin
+= 2.5.0: August 17, 2022 =
+
+* Enhancements:
+
+ - Added: Input type "tel" using for the "Mobile Number" and "Phone Number" fields
+
+* Bugfixes:
+
+ - Fixed: Performance issue on wp-admin Users screen. Queries were replaced to the cache transient values
+ - Fixed: Privacy policy displaying when there are 2 registration forms on the same page
+ - Fixed: Password Reset process via Ultimate Member - Password Reset form. Reset password links' arguments changed to the same view as WordPress native has. Password Reset available for the same cases as native WordPress Password Reset has
+ - Fixed: Sanitizing for the Info Text field-type in wp-admin forms. Needed for the proper 3rd-party integrations
+ - Fixed: Displaying the filters' titles on the Member Directory pages
+
+* Deprecated:
+
+ - `UM()->query()->get_users_by_status()` without alternativities. It's unused since 2.5.0. Will be removed since 2.7.0
+ - `UM()->user()->get_pending_users_count()`. Use `UM()->query()->get_pending_users_count()` instead. It's unused since 2.5.0. Will be removed since 2.7.0
+ - `UM()->user()->remove_cached_queue()` without alternativities. It's unused since 2.5.0. Will be removed since 2.7.0
+
+* Templates required update:
+ - password-change.php
+ - password-reset.php
+
+* Cached and optimized/minified assets(JS/CSS) must be flushed/re-generated after upgrade
+
= 2.4.2: July 14, 2022 =
* Bugfixes:
diff --git a/templates/password-change.php b/templates/password-change.php
index 7b9101e2..414cb6e0 100644
--- a/templates/password-change.php
+++ b/templates/password-change.php
@@ -6,7 +6,7 @@
-
\ No newline at end of file
+
diff --git a/templates/password-reset.php b/templates/password-reset.php
index 384da0be..9b706317 100644
--- a/templates/password-reset.php
+++ b/templates/password-reset.php
@@ -13,6 +13,14 @@
+
+
@@ -93,7 +101,7 @@