From c9f90c54dde8876c54a2dbab304d7a0e7b7c50aa Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Mon, 20 Jun 2022 17:29:31 +0300 Subject: [PATCH 1/8] - User queries performance fix; --- includes/admin/core/class-admin-menu.php | 2 +- includes/admin/core/class-admin-users.php | 3 +- includes/core/class-query.php | 147 +++++++++++++++---- includes/core/class-setup.php | 46 +++++- includes/core/class-user.php | 168 +++++++++++++--------- includes/core/rest/class-api.php | 4 +- includes/core/um-actions-register.php | 4 - uninstall.php | 14 ++ 8 files changed, 279 insertions(+), 109 deletions(-) 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-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/core/class-query.php b/includes/core/class-query.php index 7061be61..2320ecd0 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' ); + 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', $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..d99f26a8 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 ); + } + + 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..33fbaaa4 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,74 @@ 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; + } + + $old = get_user_meta( $object_id, $meta_key, true ); + + $values = array( $old, $_meta_value ); + foreach ( $values as $value ) { + delete_transient( "um_count_users_{$value}" ); + } + + $maybe_flush_pending = array_intersect( $values, array( 'awaiting_email_confirmation', 'awaiting_admin_review' ) ); + if ( ! empty( $maybe_flush_pending ) ) { + delete_transient( 'um_count_users_pending' ); + } + } + + + /** + * @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; + } + + delete_transient( "um_count_users_{$_meta_value}" ); + if ( in_array( $_meta_value, array( 'awaiting_email_confirmation', 'awaiting_admin_review' ), true ) ) { + delete_transient( 'um_count_users_pending' ); + } + } + + + /** + * @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 ); + delete_transient( "um_count_users_{$value}" ); + + if ( in_array( $value, array( 'awaiting_email_confirmation', 'awaiting_admin_review' ), true ) ) { + delete_transient( 'um_count_users_pending' ); + } } @@ -226,7 +291,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 +389,8 @@ 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' ); } @@ -391,60 +458,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 * @@ -634,6 +647,7 @@ if ( ! class_exists( 'um\core\User' ) ) { do_action( 'um_user_register', $user_id, $_POST ); } + delete_transient( 'um_count_users_unassigned' ); } @@ -807,14 +821,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 +1059,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 ); @@ -2187,5 +2193,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-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/uninstall.php b/uninstall.php index c1d6626a..70ad4733 100644 --- a/uninstall.php +++ b/uninstall.php @@ -115,6 +115,20 @@ if ( ! empty( $delete_options ) ) { delete_option( '__ultimatemember_sitekey' ); delete_option( 'um_flush_rewrite_rules' ); + $statuses = array( + 'approved', + 'awaiting_admin_review', + 'awaiting_email_confirmation', + 'inactive', + 'rejected', + ); + + foreach ( $statuses as $status ) { + delete_transient( "um_count_users_{$status}" ); + } + delete_transient( 'um_count_users_pending' ); + delete_transient( 'um_count_users_unassigned' ); + //remove all users cache UM()->user()->remove_cache_all_users(); From d1b4b08af0d2ee1ba4839cfdde3e106ab7f9e7d1 Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Mon, 20 Jun 2022 20:24:31 +0300 Subject: [PATCH 2/8] - added flushing the users query transients; --- includes/admin/class-admin.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/includes/admin/class-admin.php b/includes/admin/class-admin.php index d503b5cf..509b56e0 100644 --- a/includes/admin/class-admin.php +++ b/includes/admin/class-admin.php @@ -1673,6 +1673,20 @@ if ( ! class_exists( 'um\admin\Admin' ) ) { $wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE 'um_cache_userdata_%'" ); + $statuses = array( + 'approved', + 'awaiting_admin_review', + 'awaiting_email_confirmation', + 'inactive', + 'rejected', + 'pending', // 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}" ); + } + $url = add_query_arg( array( 'page' => 'ultimatemember', 'update' => 'cleared_cache' ), admin_url( 'admin.php' ) ); exit( wp_redirect( $url ) ); } From 9b74beab8be91d87c07546ab7024aaae01443237 Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Fri, 12 Aug 2022 02:53:25 +0300 Subject: [PATCH 3/8] - fixed performance issue by using add or deduct count instead of the WP_Users_Query; --- .github/workflows/code-quality.yml | 2 +- includes/core/class-user.php | 141 ++++++++++++++++++++++++++--- 2 files changed, 130 insertions(+), 13 deletions(-) diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml index 5265fed1..2acf9bfc 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/includes/core/class-user.php b/includes/core/class-user.php index 33fbaaa4..0d7892f6 100644 --- a/includes/core/class-user.php +++ b/includes/core/class-user.php @@ -127,16 +127,71 @@ if ( ! class_exists( 'um\core\User' ) ) { return; } + $pending_statuses = array( + 'awaiting_email_confirmation', + 'awaiting_admin_review', + ); + $old = get_user_meta( $object_id, $meta_key, true ); - $values = array( $old, $_meta_value ); - foreach ( $values as $value ) { - delete_transient( "um_count_users_{$value}" ); + // 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 ); + } } - $maybe_flush_pending = array_intersect( $values, array( 'awaiting_email_confirmation', 'awaiting_admin_review' ) ); - if ( ! empty( $maybe_flush_pending ) ) { - delete_transient( 'um_count_users_pending' ); + 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' ); + if ( false !== $count ) { + if ( ! is_numeric( $count ) ) { + delete_transient( 'um_count_users_pending' ); + } else { + if ( 0 < $count ) { + $count--; + } else { + $count = 0; + } + set_transient( 'um_count_users_pending', $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' ); + if ( false !== $count ) { + if ( is_numeric( $count ) ) { + $count++; + } else { + $count = 1; + } + } else { + $count = 1; + } + set_transient( 'um_count_users_pending', $count ); } } @@ -152,9 +207,37 @@ if ( ! class_exists( 'um\core\User' ) ) { return; } - delete_transient( "um_count_users_{$_meta_value}" ); - if ( in_array( $_meta_value, array( 'awaiting_email_confirmation', 'awaiting_admin_review' ), true ) ) { - delete_transient( 'um_count_users_pending' ); + $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 + $count = get_transient( 'um_count_users_pending' ); + if ( false !== $count ) { + if ( is_numeric( $count ) ) { + $count++; + } else { + $count = 1; + } + } else { + $count = 1; + } + set_transient( 'um_count_users_pending', $count ); } } @@ -171,10 +254,42 @@ if ( ! class_exists( 'um\core\User' ) ) { } $value = ( '' !== $_meta_value ) ? $_meta_value : get_user_meta( $object_id, $meta_key, true ); - delete_transient( "um_count_users_{$value}" ); - if ( in_array( $value, array( 'awaiting_email_confirmation', 'awaiting_admin_review' ), true ) ) { - delete_transient( 'um_count_users_pending' ); + $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' ); + if ( false !== $count ) { + if ( ! is_numeric( $count ) ) { + delete_transient( 'um_count_users_pending' ); + } else { + if ( 0 < $count ) { + $count--; + } else { + $count = 0; + } + set_transient( 'um_count_users_pending', $count ); + } + } } } @@ -391,6 +506,7 @@ if ( ! class_exists( 'um\core\User' ) ) { 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' ); } @@ -648,6 +764,7 @@ if ( ! class_exists( 'um\core\User' ) ) { } delete_transient( 'um_count_users_unassigned' ); + delete_transient( 'um_count_users_pending' ); } From 69321f0cb1bc2927e7b10939800685153a0ffb41 Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Fri, 12 Aug 2022 16:20:14 +0300 Subject: [PATCH 4/8] - return from the function update_usermeta when old value the same as new; --- includes/core/class-user.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/includes/core/class-user.php b/includes/core/class-user.php index 0d7892f6..870025fe 100644 --- a/includes/core/class-user.php +++ b/includes/core/class-user.php @@ -134,6 +134,10 @@ if ( ! class_exists( 'um\core\User' ) ) { $old = get_user_meta( $object_id, $meta_key, true ); + if ( $old === $_meta_value ) { + return; + } + // deduct old transient count $count = get_transient( "um_count_users_{$old}" ); if ( false !== $count ) { From f4f84bbd7eff44052a86cc0329888e75298b8315 Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Fri, 12 Aug 2022 16:33:23 +0300 Subject: [PATCH 5/8] - added expiration for the `um_count_users_unassigned` transient for the checking everyday the users who don't have the account_status meta (registered 3rd-party way); --- includes/core/class-setup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/core/class-setup.php b/includes/core/class-setup.php index d99f26a8..3981cff6 100644 --- a/includes/core/class-setup.php +++ b/includes/core/class-setup.php @@ -296,7 +296,7 @@ KEY meta_value_indx (um_value(191)) $result = $users->get_results(); } - set_transient( 'um_count_users_unassigned', $result ); + set_transient( 'um_count_users_unassigned', $result, DAY_IN_SECONDS ); } if ( empty( $result ) ) { From 221e54f6ce38e32524212728ae32c4842cad0594 Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Fri, 12 Aug 2022 20:14:39 +0300 Subject: [PATCH 6/8] - added separate button for the user statuses count cache clearing; --- includes/admin/class-admin.php | 34 ++++++++++++++++++-- includes/admin/core/class-admin-notices.php | 8 +++-- includes/admin/templates/dashboard/cache.php | 16 ++++++--- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/includes/admin/class-admin.php b/includes/admin/class-admin.php index 509b56e0..bb6431fd 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,6 +1674,28 @@ 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' ) + ); + 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', @@ -1687,8 +1710,15 @@ if ( ! class_exists( 'um\admin\Admin' ) ) { delete_transient( "um_count_users_{$status}" ); } - $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_status_cache', + ), + admin_url( 'admin.php' ) + ); + wp_redirect( $url ); + exit; } 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/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 + + + +

From c1b3b0d3c470d263d35378959e42e1c4235352a1 Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Fri, 12 Aug 2022 23:07:16 +0300 Subject: [PATCH 7/8] - fixed issues related to the registration users with awaiting admin review or email confirmation; --- includes/admin/class-admin.php | 2 + includes/core/class-query.php | 4 +- includes/core/class-user.php | 84 ++++++++++++++++++++-------------- uninstall.php | 2 +- 4 files changed, 55 insertions(+), 37 deletions(-) diff --git a/includes/admin/class-admin.php b/includes/admin/class-admin.php index bb6431fd..2d3879ad 100644 --- a/includes/admin/class-admin.php +++ b/includes/admin/class-admin.php @@ -1710,6 +1710,8 @@ if ( ! class_exists( 'um\admin\Admin' ) ) { delete_transient( "um_count_users_{$status}" ); } + do_action( 'um_flush_user_status_cache' ); + $url = add_query_arg( array( 'page' => 'ultimatemember', diff --git a/includes/core/class-query.php b/includes/core/class-query.php index 2320ecd0..ef19440a 100644 --- a/includes/core/class-query.php +++ b/includes/core/class-query.php @@ -270,7 +270,7 @@ if ( ! class_exists( 'um\core\Query' ) ) { * @return int */ function get_pending_users_count() { - $users_count = get_transient( 'um_count_users_pending' ); + $users_count = get_transient( 'um_count_users_pending_dot' ); if ( false === $users_count ) { $args = array( 'fields' => 'ids', @@ -321,7 +321,7 @@ if ( ! class_exists( 'um\core\Query' ) ) { $users_count = $users->get_total(); } - set_transient( 'um_count_users_pending', $users_count ); + set_transient( 'um_count_users_pending_dot', $users_count ); } return $users_count; diff --git a/includes/core/class-user.php b/includes/core/class-user.php index 870025fe..864787a4 100644 --- a/includes/core/class-user.php +++ b/includes/core/class-user.php @@ -127,6 +127,11 @@ if ( ! class_exists( 'um\core\User' ) ) { 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', @@ -138,34 +143,37 @@ if ( ! class_exists( 'um\core\User' ) ) { return; } - // 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 ) ) { + // 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_pending' ); + $count = get_transient( "um_count_users_{$old}" ); if ( false !== $count ) { if ( ! is_numeric( $count ) ) { - delete_transient( 'um_count_users_pending' ); + delete_transient( "um_count_users_{$old}" ); } else { if ( 0 < $count ) { $count--; } else { $count = 0; } - set_transient( 'um_count_users_pending', $count ); + 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 ); + } } } } @@ -185,7 +193,7 @@ if ( ! class_exists( 'um\core\User' ) ) { 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' ); + $count = get_transient( 'um_count_users_pending_dot' ); if ( false !== $count ) { if ( is_numeric( $count ) ) { $count++; @@ -195,7 +203,7 @@ if ( ! class_exists( 'um\core\User' ) ) { } else { $count = 1; } - set_transient( 'um_count_users_pending', $count ); + set_transient( 'um_count_users_pending_dot', $count ); } } @@ -211,6 +219,11 @@ if ( ! class_exists( 'um\core\User' ) ) { 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', @@ -231,17 +244,17 @@ if ( ! class_exists( 'um\core\User' ) ) { if ( in_array( $_meta_value, $pending_statuses, true ) ) { // add new transient count - $count = get_transient( 'um_count_users_pending' ); - if ( false !== $count ) { - if ( is_numeric( $count ) ) { - $count++; + $pending_count = get_transient( 'um_count_users_pending_dot' ); + if ( false !== $pending_count ) { + if ( is_numeric( $pending_count ) ) { + $pending_count++; } else { - $count = 1; + $pending_count = 1; } } else { - $count = 1; + $pending_count = 1; } - set_transient( 'um_count_users_pending', $count ); + set_transient( 'um_count_users_pending_dot', $pending_count ); } } @@ -259,6 +272,11 @@ if ( ! class_exists( 'um\core\User' ) ) { $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', @@ -281,17 +299,17 @@ if ( ! class_exists( 'um\core\User' ) ) { if ( in_array( $value, $pending_statuses, true ) ) { // deduct old transient count - $count = get_transient( 'um_count_users_pending' ); + $count = get_transient( 'um_count_users_pending_dot' ); if ( false !== $count ) { if ( ! is_numeric( $count ) ) { - delete_transient( 'um_count_users_pending' ); + delete_transient( 'um_count_users_pending_dot' ); } else { if ( 0 < $count ) { $count--; } else { $count = 0; } - set_transient( 'um_count_users_pending', $count ); + set_transient( 'um_count_users_pending_dot', $count ); } } } @@ -510,7 +528,7 @@ if ( ! class_exists( 'um\core\User' ) ) { 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' ); + delete_transient( 'um_count_users_pending_dot' ); } @@ -730,7 +748,6 @@ if ( ! class_exists( 'um\core\User' ) ) { * @param $user_id */ function user_register_via_admin( $user_id ) { - if ( empty( $user_id ) ) { return; } @@ -768,7 +785,6 @@ if ( ! class_exists( 'um\core\User' ) ) { } delete_transient( 'um_count_users_unassigned' ); - delete_transient( 'um_count_users_pending' ); } diff --git a/uninstall.php b/uninstall.php index 70ad4733..63e24f8b 100644 --- a/uninstall.php +++ b/uninstall.php @@ -126,7 +126,7 @@ if ( ! empty( $delete_options ) ) { foreach ( $statuses as $status ) { delete_transient( "um_count_users_{$status}" ); } - delete_transient( 'um_count_users_pending' ); + delete_transient( 'um_count_users_pending_dot' ); delete_transient( 'um_count_users_unassigned' ); //remove all users cache From 1da32184df78ff00ec0b41bfd3708830fe2cbd9a Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Sat, 13 Aug 2022 00:31:23 +0300 Subject: [PATCH 8/8] - the fix for the flushing cache; --- includes/admin/class-admin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/admin/class-admin.php b/includes/admin/class-admin.php index 2d3879ad..c6cf0c80 100644 --- a/includes/admin/class-admin.php +++ b/includes/admin/class-admin.php @@ -1702,7 +1702,7 @@ if ( ! class_exists( 'um\admin\Admin' ) ) { 'awaiting_email_confirmation', 'inactive', 'rejected', - 'pending', // not real status key, just for the transient + 'pending_dot', // not real status key, just for the transient 'unassigned', // not real status key, just for the transient );