=e.number&&(t=e.number-1,a=10);e=r._getSize.call(this)/10,t=i(this.stars[t]),e=t.offset().left+e*parseInt(a,10),a=i.Event("mousemove",{pageX:e});t.trigger(a)})},readOnly:function(e){return this.each(function(){var t=i(this);t.data("readonly")!==e&&((e?(t.off(".um_raty").children("img").off(".um_raty"),r._lock):(r._binds.call(this),r._unlock)).call(this),t.data("readonly",e))})},reload:function(){return r.set.call(this,{})},score:function(){var t=i(this);return arguments.length?r.setScore.apply(t,arguments):r.getScore.call(t)},set:function(a){return this.each(function(){var t=i(this),e=t.data("options"),e=i.extend({},e,a);t.um_raty(e)})},setScore:function(t){return this.each(function(){!0!==i(this).data("readonly")&&(r._apply.call(this,t),r._target.call(this,t))})}};i.fn.um_raty=function(t){return r[t]?r[t].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof t&&t?void i.error("Method "+t+" does not exist!"):r.init.apply(this,arguments)},i.fn.um_raty.defaults={cancel:!1,cancelClass:"raty-cancel",cancelHint:wp.i18n.__("Cancel this rating!","ultimate-member"),cancelOff:"cancel-off.png",cancelOn:"cancel-on.png",cancelPlace:"left",click:void 0,half:!1,halfShow:!0,hints:["bad","poor","regular","good","gorgeous"],iconRange:void 0,mouseout:void 0,mouseover:void 0,noRatedMsg:wp.i18n.__("Not rated yet!","ultimate-member"),number:5,numberMax:20,path:void 0,precision:!1,readOnly:!1,round:{down:.25,full:.6,up:.76},score:void 0,scoreName:"score",single:!1,space:!0,starHalf:"star-half.png",starOff:"star-off.png",starOn:"star-on.png",starType:"img",target:void 0,targetFormat:"{score}",targetKeep:!1,targetScore:void 0,targetText:"",targetType:"hint"}}(jQuery);
\ No newline at end of file
diff --git a/includes/admin/class-actions-listener.php b/includes/admin/class-actions-listener.php
new file mode 100644
index 00000000..81442364
--- /dev/null
+++ b/includes/admin/class-actions-listener.php
@@ -0,0 +1,160 @@
+common()->users()->can_current_user_edit_user( $user_id ) ) {
+ $result = UM()->common()->users()->approve( $user_id );
+ if ( $result ) {
+ $redirect = add_query_arg( array( 'update' => 'um_approved', 'approved_count' => 1 ), $redirect );
+ }
+ }
+
+ wp_safe_redirect( $redirect );
+ exit;
+ case 'reactivate_user':
+ if ( empty( $_REQUEST['uid'] ) || ! is_numeric( $_REQUEST['uid'] ) ) {
+ die( esc_html__( 'Invalid user ID', 'ultimate-member' ) );
+ }
+
+ $user_id = absint( $_REQUEST['uid'] );
+
+ check_admin_referer( "reactivate_user{$user_id}" );
+
+ $redirect = wp_get_referer();
+ if ( UM()->common()->users()->can_current_user_edit_user( $user_id ) ) {
+ $result = UM()->common()->users()->reactivate( $user_id );
+ if ( $result ) {
+ $redirect = add_query_arg( array( 'update' => 'um_reactivated', 'reactivated_count' => 1 ), $redirect );
+ }
+ }
+ wp_safe_redirect( $redirect );
+ exit;
+ case 'put_user_as_pending':
+ if ( empty( $_REQUEST['uid'] ) || ! is_numeric( $_REQUEST['uid'] ) ) {
+ die( esc_html__( 'Invalid user ID', 'ultimate-member' ) );
+ }
+
+ $user_id = absint( $_REQUEST['uid'] );
+
+ check_admin_referer( "put_user_as_pending{$user_id}" );
+
+ $redirect = wp_get_referer();
+ if ( UM()->common()->users()->can_current_user_edit_user( $user_id ) ) {
+ $result = UM()->common()->users()->set_as_pending( $user_id );
+ if ( $result ) {
+ $redirect = add_query_arg( array( 'update' => 'um_pending', 'pending_count' => 1 ), $redirect );
+ }
+ }
+ wp_safe_redirect( $redirect );
+ exit;
+ case 'resend_user_activation':
+ if ( empty( $_REQUEST['uid'] ) || ! is_numeric( $_REQUEST['uid'] ) ) {
+ die( esc_html__( 'Invalid user ID', 'ultimate-member' ) );
+ }
+
+ $user_id = absint( $_REQUEST['uid'] );
+
+ check_admin_referer( "resend_user_activation{$user_id}" );
+
+ $redirect = wp_get_referer();
+ if ( UM()->common()->users()->can_current_user_edit_user( $user_id ) ) {
+ $result = UM()->common()->users()->send_activation( $user_id );
+ if ( $result ) {
+ $redirect = add_query_arg( array( 'update' => 'um_resend_activation', 'resend_activation_count' => 1 ), $redirect );
+ }
+ }
+ wp_safe_redirect( $redirect );
+ exit;
+ case 'reject_user':
+ if ( empty( $_REQUEST['uid'] ) || ! is_numeric( $_REQUEST['uid'] ) ) {
+ die( esc_html__( 'Invalid user ID', 'ultimate-member' ) );
+ }
+
+ $user_id = absint( $_REQUEST['uid'] );
+
+ check_admin_referer( "reject_user{$user_id}" );
+
+ $redirect = wp_get_referer();
+ if ( UM()->common()->users()->can_current_user_edit_user( $user_id ) ) {
+ $result = UM()->common()->users()->reject( $user_id );
+ if ( $result ) {
+ $redirect = add_query_arg( array( 'update' => 'um_rejected', 'rejected_count' => 1 ), $redirect );
+ }
+ }
+ wp_safe_redirect( $redirect );
+ exit;
+ case 'deactivate_user':
+ if ( empty( $_REQUEST['uid'] ) || ! is_numeric( $_REQUEST['uid'] ) ) {
+ die( esc_html__( 'Invalid user ID', 'ultimate-member' ) );
+ }
+
+ $user_id = absint( $_REQUEST['uid'] );
+
+ check_admin_referer( "deactivate_user{$user_id}" );
+
+ $redirect = wp_get_referer();
+ if ( UM()->common()->users()->can_current_user_edit_user( $user_id ) ) {
+ $result = UM()->common()->users()->deactivate( $user_id );
+ if ( $result ) {
+ $redirect = add_query_arg( array( 'update' => 'um_deactivate', 'deactivated_count' => 1 ), $redirect );
+ }
+ }
+ wp_safe_redirect( $redirect );
+ exit;
+ }
+ }
+ }
+
+ public function extends_individual_nonce_actions( $actions ) {
+ $actions[] = 'approve_user';
+ $actions[] = 'reactivate_user';
+ $actions[] = 'put_user_as_pending';
+ $actions[] = 'resend_user_activation';
+ $actions[] = 'reject_user';
+ $actions[] = 'deactivate_user';
+ return $actions;
+ }
+ }
+}
diff --git a/includes/admin/class-admin.php b/includes/admin/class-admin.php
index 0afb0a04..c34d913c 100644
--- a/includes/admin/class-admin.php
+++ b/includes/admin/class-admin.php
@@ -67,7 +67,6 @@ if ( ! class_exists( 'um\admin\Admin' ) ) {
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' ) );
- add_action( 'um_admin_do_action__user_action', array( &$this, 'user_action' ) );
add_action( 'um_admin_do_action__check_templates_version', array( &$this, 'check_templates_version' ) );
add_action( 'um_admin_do_action__install_core_pages', array( &$this, 'install_core_pages' ) );
@@ -79,10 +78,12 @@ if ( ! class_exists( 'um\admin\Admin' ) ) {
}
public function includes() {
+ $this->actions_listener();
$this->enqueue();
$this->notices();
$this->secure();
$this->site_health();
+ $this->users_columns();
}
public function init_variables() {
@@ -1840,69 +1841,6 @@ if ( ! class_exists( 'um\admin\Admin' ) ) {
exit;
}
- /**
- * Various user actions.
- */
- public function user_action() {
- if ( ! current_user_can( 'edit_users' ) ) {
- die();
- }
- if ( ! isset( $_REQUEST['sub'] ) ) {
- die();
- }
- if ( ! isset( $_REQUEST['user_id'] ) ) {
- die();
- }
-
- um_fetch_user( absint( $_REQUEST['user_id'] ) );
-
- $subaction = sanitize_key( $_REQUEST['sub'] );
-
- /**
- * UM hook
- *
- * @type action
- * @title um_admin_user_action_hook
- * @description Action on bulk user subaction
- * @input_vars
- * [{"var":"$subaction","type":"string","desc":"Bulk Subaction"}]
- * @change_log
- * ["Since: 2.0"]
- * @usage add_action( 'um_admin_user_action_hook', 'function_name', 10, 1 );
- * @example
- *
- */
- do_action( 'um_admin_user_action_hook', $subaction );
- /**
- * UM hook
- *
- * @type action
- * @title um_admin_user_action_{$subaction}_hook
- * @description Action on bulk user subaction
- * @change_log
- * ["Since: 2.0"]
- * @usage add_action( 'um_admin_user_action_{$subaction}_hook', 'function_name', 10 );
- * @example
- *
- */
- do_action( "um_admin_user_action_{$subaction}_hook" );
-
- um_reset_user();
-
- wp_safe_redirect( add_query_arg( 'update', 'um_user_updated', admin_url( '?page=ultimatemember' ) ) );
- exit;
- }
-
/**
* Manual check templates versions.
*/
@@ -1946,7 +1884,6 @@ if ( ! class_exists( 'um\admin\Admin' ) ) {
$action = sanitize_key( $_REQUEST['um_adm_action'] );
$individual_nonce_actions = array(
- 'user_action',
'duplicate_form',
);
$individual_nonce_actions = apply_filters( 'um_adm_action_individual_nonce_actions', $individual_nonce_actions );
@@ -2071,6 +2008,18 @@ if ( ! class_exists( 'um\admin\Admin' ) ) {
return $parent_file;
}
+ /**
+ * @since 2.8.7
+ *
+ * @return Actions_Listener
+ */
+ public function actions_listener() {
+ if ( empty( UM()->classes['um\admin\actions_listener'] ) ) {
+ UM()->classes['um\admin\actions_listener'] = new Actions_Listener();
+ }
+ return UM()->classes['um\admin\actions_listener'];
+ }
+
/**
* @since 2.7.0
*
@@ -2130,5 +2079,17 @@ if ( ! class_exists( 'um\admin\Admin' ) ) {
}
return UM()->classes['um\admin\site_health'];
}
+
+ /**
+ * @since 2.8.7
+ *
+ * @return Users_Columns
+ */
+ public function users_columns() {
+ if ( empty( UM()->classes['um\admin\users_columns'] ) ) {
+ UM()->classes['um\admin\users_columns'] = new Users_Columns();
+ }
+ return UM()->classes['um\admin\users_columns'];
+ }
}
}
diff --git a/includes/admin/class-secure.php b/includes/admin/class-secure.php
index 30bb4ff2..772891ec 100644
--- a/includes/admin/class-secure.php
+++ b/includes/admin/class-secure.php
@@ -150,7 +150,8 @@ if ( ! class_exists( 'um\admin\Secure' ) ) {
}
// Restore Account Status.
if ( isset( $metadata['account_status'] ) ) {
- UM()->user()->set_status( $metadata['account_status'] );
+ // UM()->user()->set_status( $metadata['account_status'] );
+ UM()->common()->users()->set_status( $user_id, $metadata['account_status'] );
}
// Delete blocked meta.
diff --git a/includes/admin/class-users-columns.php b/includes/admin/class-users-columns.php
new file mode 100644
index 00000000..76989262
--- /dev/null
+++ b/includes/admin/class-users-columns.php
@@ -0,0 +1,633 @@
+common()->users()->get_status( $user_id, 'formatted' );
+
+ $status = apply_filters( 'um_users_column_account_status', $status, $user_id );
+
+ $value = '' . esc_html( $status ) . '';
+
+ if ( get_current_user_id() === $user_id ) {
+ return $value;
+ }
+
+ $row_actions = array();
+ if ( UM()->common()->users()->can_be_approved( $user_id ) ) {
+ $url = add_query_arg(
+ array(
+ 'um_adm_action' => 'approve_user',
+ 'uid' => $user_id,
+ '_wpnonce' => wp_create_nonce( 'approve_user' . $user_id ),
+ ),
+ admin_url( 'users.php' )
+ );
+ $row_actions[] = '' . esc_html__( 'Approve', 'ultimate-member' ) . '';
+ }
+ if ( UM()->common()->users()->can_be_reactivated( $user_id ) ) {
+ $url = add_query_arg(
+ array(
+ 'um_adm_action' => 'reactivate_user',
+ 'uid' => $user_id,
+ '_wpnonce' => wp_create_nonce( 'reactivate_user' . $user_id ),
+ ),
+ admin_url( 'users.php' )
+ );
+ $row_actions[] = '' . esc_html__( 'Reactivate', 'ultimate-member' ) . '';
+ }
+ if ( UM()->common()->users()->can_be_set_as_pending( $user_id ) ) {
+ $url = add_query_arg(
+ array(
+ 'um_adm_action' => 'put_user_as_pending',
+ 'uid' => $user_id,
+ '_wpnonce' => wp_create_nonce( 'put_user_as_pending' . $user_id ),
+ ),
+ admin_url( 'users.php' )
+ );
+ $row_actions[] = '' . esc_html__( 'Put as pending', 'ultimate-member' ) . '';
+ }
+ if ( UM()->common()->users()->can_activation_send( $user_id ) ) {
+ $url = add_query_arg(
+ array(
+ 'um_adm_action' => 'resend_user_activation',
+ 'uid' => $user_id,
+ '_wpnonce' => wp_create_nonce( 'resend_user_activation' . $user_id ),
+ ),
+ admin_url( 'users.php' )
+ );
+ $row_actions[] = '' . esc_html__( 'Resend activation email', 'ultimate-member' ) . '';
+ }
+ if ( UM()->common()->users()->can_be_rejected( $user_id ) ) {
+ $url = add_query_arg(
+ array(
+ 'um_adm_action' => 'reject_user',
+ 'uid' => $user_id,
+ '_wpnonce' => wp_create_nonce( 'reject_user' . $user_id ),
+ ),
+ admin_url( 'users.php' )
+ );
+ $row_actions[] = '' . esc_html__( 'Reject', 'ultimate-member' ) . '';
+ }
+ if ( UM()->common()->users()->can_be_deactivated( $user_id ) ) {
+ $url = add_query_arg(
+ array(
+ 'um_adm_action' => 'deactivate_user',
+ 'uid' => $user_id,
+ '_wpnonce' => wp_create_nonce( 'deactivate_user' . $user_id ),
+ ),
+ admin_url( 'users.php' )
+ );
+ $row_actions[] = '' . esc_html__( 'Deactivate', 'ultimate-member' ) . '';
+ }
+
+ $row_actions = apply_filters( 'um_users_column_account_status_row_actions', $row_actions, $user_id );
+ if ( ! empty( $row_actions ) ) {
+ $value .= '- ' . implode( '
- |
- ', $row_actions ) . '
';
+ }
+ return $value;
+ }
+
+ /**
+ * Change default sorting at WP Users list table
+ *
+ * @param WP_User_Query $query Current instance of WP_User_Query (passed by reference).
+ */
+ public function sort_by_newest( $query ) {
+ global $pagenow;
+
+ // phpcs:ignore WordPress.Security.NonceVerification -- situated in WP native query and just checking sorting
+ if ( 'users.php' === $pagenow && ! isset( $_REQUEST['orderby'] ) && is_admin() ) {
+ $query->query_vars['order'] = 'desc';
+ $query->query_orderby = ' ORDER BY user_registered DESC';
+ }
+ }
+
+ /**
+ * Hide users who are hidden by role access for not Administrator user
+ *
+ * @param array $args Arguments passed to WP_User_Query to retrieve items for the current
+ * users list table
+ *
+ * @return array
+ */
+ public function hide_by_caps( $args ) {
+ if ( current_user_can( 'manage_options' ) ) {
+ return $args;
+ }
+
+ // @todo avoid um_user() function using
+ // @todo check another restrictions not only the role settings. We need to exclude users per user ID.
+ $can_view_roles = um_user( 'can_view_roles' );
+ if ( ! empty( $can_view_roles ) && um_user( 'can_view_all' ) ) {
+ $args['role__in'] = $can_view_roles;
+ }
+
+ return $args;
+ }
+
+ /**
+ * Hide role filters with not accessible roles
+ *
+ * @param array $views
+ * @return array
+ */
+ public function restrict_role_links( $views ) {
+ if ( current_user_can( 'manage_options' ) ) {
+ return $views;
+ }
+
+ $can_view_roles = um_user( 'can_view_roles' );
+ if ( ! empty( $can_view_roles ) && um_user( 'can_view_all' ) ) {
+ $wp_roles = wp_roles();
+ foreach ( $wp_roles->get_names() as $this_role => $name ) {
+ if ( ! in_array( $this_role, $can_view_roles, true ) ) {
+ unset( $views[ $this_role ] );
+ }
+ }
+ }
+
+ return $views;
+ }
+
+ /**
+ * Custom row actions for users page
+ *
+ * @param array $actions
+ * @param WP_User $user_object
+ *
+ * @return array
+ */
+ public function user_row_actions( $actions, $user_object ) {
+ $user_id = $user_object->ID;
+
+ // Link to Ultimate Member Profile.
+ $actions['frontend_profile'] = '' . esc_html__( 'View profile', 'ultimate-member' ) . '';
+
+ // The link for open popup with the registration data submitted through Ultimate Member Registration form.
+ $submitted = get_user_meta( $user_id, 'submitted', true );
+ if ( ! empty( $submitted ) ) {
+ $actions['view_info'] = '' . esc_html__( 'Info', 'ultimate-member' ) . '';
+ // For new modal below.
+ // $actions['view_info'] = '' . esc_html__( 'Info', 'ultimate-member' ) . '';
+ }
+
+ // Remove row actions for now Administrator role and who cannot view profiles of row's user.
+ if ( ! current_user_can( 'manage_options' ) && ! um_can_view_profile( $user_id ) ) {
+ unset( $actions['frontend_profile'], $actions['view_info'], $actions['view'] );
+ }
+
+ /**
+ * Filters the rows actions for the user in wp-admin > Users List Table screen.
+ *
+ * Note: Row actions format is 'key' => 'action_link_html'
+ *
+ * @since 1.3.x
+ * @hook um_admin_user_row_actions
+ *
+ * @param {array} $actions User's row actions.
+ * @param {int} $user_id Row's user ID.
+ *
+ * @return {array} User's row actions.
+ */
+ return apply_filters( 'um_admin_user_row_actions', $actions, $user_id );
+ }
+
+ /**
+ * Get the list with the bulk actions.
+ *
+ * @return array
+ */
+ private function get_user_bulk_actions() {
+ $um_actions = array(
+ 'um_approve_membership' => __( 'Approve Membership', 'ultimate-member' ),
+ 'um_reject_membership' => __( 'Reject Membership', 'ultimate-member' ),
+ 'um_put_as_pending' => __( 'Put as Pending Review', 'ultimate-member' ),
+ 'um_resend_activation' => __( 'Resend Activation E-mail', 'ultimate-member' ),
+ 'um_deactivate' => __( 'Deactivate', 'ultimate-member' ),
+ 'um_reactivate' => __( 'Reactivate', 'ultimate-member' ), // um_reenable
+ );
+ /**
+ * Filters wp-admin > Users List Table bulk actions.
+ *
+ * @since 1.3.x
+ * @since 2.8.7 changed format from `$action_slug => array( 'label' => $action_title )` to `$action_slug => $action_title`
+ * @hook um_admin_bulk_user_actions_hook
+ *
+ * @param {array} $um_actions Users admin actions.
+ *
+ * @return {array} Users admin actions.
+ *
+ * @example Add `$action_title` to Users List Table bulk actions.
+ * function um_custom_admin_bulk_user_actions_hook( $um_actions ) {
+ * $um_actions[ $action_slug ] = $action_title;
+ * return $um_actions;
+ * }
+ * add_filter( 'um_admin_bulk_user_actions_hook', 'um_custom_admin_bulk_user_actions_hook' );
+ */
+ return apply_filters( 'um_admin_bulk_user_actions_hook', $um_actions );
+ }
+
+ /**
+ * @param array $actions
+ *
+ * @return array
+ */
+ public function add_bulk_actions( $actions ) {
+ $rolename = UM()->roles()->get_priority_user_role( get_current_user_id() );
+ $role = get_role( $rolename );
+
+ if ( null === $role ) {
+ return $actions;
+ }
+
+ // Add Ultimate Member bulk actions only when the current user has 'edit_users' capability.
+ if ( ! current_user_can( 'edit_users' ) && ! $role->has_cap( 'edit_users' ) ) {
+ return $actions;
+ }
+
+ $actions[ esc_html__( 'Ultimate Member', 'ultimate-member' ) ] = $this->get_user_bulk_actions();
+ return $actions;
+ }
+
+ private function get_statuses_filter_options() {
+ $statuses = UM()->common()->users()->statuses_list();
+ /**
+ * Filters the user statuses added via Ultimate Member plugin.
+ *
+ * Note: Statuses format is 'key' => 'title'
+ *
+ * @since 2.8.7
+ * @hook um_user_statuses_admin_filter_options
+ *
+ * @param {array} $statuses User statuses in Ultimate Member environment.
+ *
+ * @return {array} User statuses.
+ */
+ return apply_filters( 'um_user_statuses_admin_filter_options', $statuses );
+ }
+
+ /**
+ * Adds HTML with the filter by the Ultimate Member status.
+ *
+ * @param string $which Where the callback's hook fired.
+ */
+ public function add_status_filter( $which ) {
+ if ( 'top' !== $which ) {
+ return;
+ }
+
+ // Set default statuses if not already done.
+ UM()->setup()->set_default_user_status();
+
+ $id = 'um_user_status';
+
+ // need to add there additional nonce field because WordPress native _wpnonce field isn't visible on the users.php screen then custom actions
+ wp_nonce_field( 'um-bulk-users', '_um_wpnonce', false );
+
+ $statuses = $this->get_statuses_filter_options();
+ ?>
+
+
+
+
+
+ get_user_bulk_actions();
+
+ if ( ! array_key_exists( $current_action, $um_actions ) ) {
+ return $sendback;
+ }
+
+ // need to handle there additional nonce field because WordPress native _wpnonce field isn't visible on the users.php screen then custom actions
+ check_admin_referer( 'um-bulk-users', '_um_wpnonce' );
+
+ $rolename = UM()->roles()->get_priority_user_role( get_current_user_id() );
+ $role = get_role( $rolename );
+
+ if ( null === $role ) {
+ return $sendback;
+ }
+
+ // Make Ultimate Member bulk actions only when the current user has 'edit_users' capability.
+ if ( ! current_user_can( 'edit_users' ) && ! $role->has_cap( 'edit_users' ) ) {
+ wp_die( esc_html__( 'You do not have enough permissions to do that.', 'ultimate-member' ) );
+ }
+
+ $users = array_map( 'absint', $userids );
+ $users = array_diff( $users, array( get_current_user_id() ) ); // cannot make any action related to himself.
+
+ switch ( $current_action ) {
+ case 'um_approve_membership':
+ $approved_count = 0;
+ foreach ( $users as $user_id ) {
+ $res = UM()->common()->users()->approve( $user_id );
+ if ( $res ) {
+ ++$approved_count;
+ }
+ }
+
+ $sendback = add_query_arg(
+ array(
+ 'approved_count' => $approved_count,
+ 'update' => 'um_approved',
+ ),
+ $this->set_redirect_uri( $sendback )
+ );
+ break;
+
+ case 'um_reactivate':
+ $reactivated_count = 0;
+ foreach ( $users as $user_id ) {
+ $res = UM()->common()->users()->reactivate( $user_id );
+ if ( $res ) {
+ ++$reactivated_count;
+ }
+ }
+
+ $sendback = add_query_arg(
+ array(
+ 'reactivated_count' => $reactivated_count,
+ 'update' => 'um_reactivated',
+ ),
+ $this->set_redirect_uri( $sendback )
+ );
+ break;
+
+ case 'um_reject_membership':
+ $rejected_count = 0;
+ foreach ( $users as $user_id ) {
+ $res = UM()->common()->users()->reject( $user_id );
+ if ( $res ) {
+ ++$rejected_count;
+ }
+ }
+
+ $sendback = add_query_arg(
+ array(
+ 'rejected_count' => $rejected_count,
+ 'update' => 'um_rejected',
+ ),
+ $this->set_redirect_uri( $sendback )
+ );
+ break;
+
+ case 'um_deactivate':
+ $deactivated_count = 0;
+ foreach ( $users as $user_id ) {
+ $res = UM()->common()->users()->deactivate( $user_id );
+ if ( $res ) {
+ ++$deactivated_count;
+ }
+ }
+
+ $sendback = add_query_arg(
+ array(
+ 'deactivated_count' => $deactivated_count,
+ 'update' => 'um_deactivate',
+ ),
+ $this->set_redirect_uri( $sendback )
+ );
+ break;
+
+ case 'um_put_as_pending':
+ $pending_count = 0;
+ foreach ( $users as $user_id ) {
+ $res = UM()->common()->users()->set_as_pending( $user_id );
+ if ( $res ) {
+ ++$pending_count;
+ }
+ }
+
+ $sendback = add_query_arg(
+ array(
+ 'pending_count' => $pending_count,
+ 'update' => 'um_pending',
+ ),
+ $this->set_redirect_uri( $sendback )
+ );
+ break;
+
+ case 'um_resend_activation':
+ $email_pending_count = 0;
+ foreach ( $users as $user_id ) {
+ $res = UM()->common()->users()->send_activation( $user_id );
+ if ( $res ) {
+ ++$email_pending_count;
+ }
+ }
+
+ $sendback = add_query_arg(
+ array(
+ 'resend_activation_count' => $email_pending_count,
+ 'update' => 'um_resend_activation',
+ ),
+ $this->set_redirect_uri( $sendback )
+ );
+ break;
+
+ default:
+ /**
+ * Fires when a custom Ultimate Member bulk action for wp-admin > Users list table should be handled.
+ *
+ * The redirect link should be modified with success or failure feedback
+ * from the action to be used to display feedback to the user.
+ *
+ * The dynamic portion of the hook name, `$current_action`, refers to the current bulk action.
+ * Use together with custom actions added via `um_admin_bulk_user_actions_hook` hook.
+ *
+ * @param {string} $sendback The redirect URL.
+ * @param {array} $userids Selected users in bulk action.
+ *
+ * @return {string} The redirect URL.
+ *
+ * @since 2.8.7
+ * @hook um_handle_bulk_actions-users-{$current_action}
+ *
+ * @example Handle custom-action and set redirect after it.
+ * function um_custom_bulk_actions_users( $sendback, $userids ) {
+ * foreach ( $userids as $user_id ) {
+ * // make some action here
+ * }
+ * return add_query_arg( 'action_counter', 'completed action count', $sendback );
+ * }
+ * add_filter( 'um_handle_bulk_actions-users-custom-action', 'um_custom_bulk_actions_users' );
+ */
+ $sendback = apply_filters( "um_handle_bulk_actions-users-{$current_action}", $sendback, $userids ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
+ break;
+ }
+
+ return $sendback;
+ }
+
+ /**
+ * Filter WP users by UM Status
+ *
+ * WP_User_Query $query Current instance of WP_User_Query (passed by reference).
+ */
+ public function filter_users_by_status( $query ) {
+ global $wpdb, $pagenow;
+
+ if ( 'users.php' !== $pagenow || ! is_admin() ) {
+ return;
+ }
+
+ if ( empty( $_REQUEST['um_user_status'] ) ) {
+ return;
+ }
+
+ $status = sanitize_key( $_REQUEST['um_user_status'] );
+
+ /**
+ * Filters the marker to disable Ultimate Member default filter by user status.
+ *
+ * @since 2.8.7
+ * @hook um_skip_filter_users_by_status
+ *
+ * @param {bool} $skip Marker to skip Ultimate Member core user filter handler.
+ * @param {string} $status User Status
+ *
+ * @return {array} User's row actions.
+ */
+ $skip_status_filter = apply_filters( 'um_skip_filter_users_by_status', false, $status );
+ if ( false !== $skip_status_filter ) {
+ return;
+ }
+
+ $query->query_where = str_replace(
+ 'WHERE 1=1',
+ $wpdb->prepare(
+ "WHERE 1=1 AND
+ {$wpdb->users}.ID IN (
+ SELECT {$wpdb->usermeta}.user_id
+ FROM $wpdb->usermeta
+ WHERE {$wpdb->usermeta}.meta_key = 'account_status' AND
+ {$wpdb->usermeta}.meta_value = %s
+ )",
+ $status
+ ),
+ $query->query_where
+ );
+ }
+
+ /**
+ * Sets redirect URI after bulk action
+ *
+ * @param string $uri
+ * @return string
+ */
+ public function set_redirect_uri( $uri ) {
+ if ( ! empty( $_REQUEST['s'] ) ) {
+ $uri = add_query_arg( 's', sanitize_text_field( $_REQUEST['s'] ), $uri );
+ }
+
+ if ( ! empty( $_REQUEST['um_user_status'] ) ) {
+ $uri = add_query_arg( 'um_user_status', sanitize_key( $_REQUEST['um_user_status'] ), $uri );
+ }
+
+ return $uri;
+ }
+
+ /**
+ * Add query args to list of query variable names to remove.
+ *
+ * @param array $removable_query_args An array of query variable names to remove from a URL
+ *
+ * @return array
+ */
+ public function add_removable_query_args( $removable_query_args ) {
+ $removable_query_args[] = '_um_wpnonce'; // need to add there additional nonce field because WordPress native _wpnonce field isn't visible on the users.php screen then custom actions
+ $removable_query_args[] = 'approved_count';
+ $removable_query_args[] = 'rejected_count';
+ $removable_query_args[] = 'reactivated_count';
+ $removable_query_args[] = 'deactivated_count';
+ $removable_query_args[] = 'pending_count';
+ $removable_query_args[] = 'resend_activation_count';
+ return $removable_query_args;
+ }
+ }
+}
diff --git a/includes/admin/core/class-admin-ajax-hooks.php b/includes/admin/core/class-admin-ajax-hooks.php
index 23e27f06..2342a2cd 100644
--- a/includes/admin/core/class-admin-ajax-hooks.php
+++ b/includes/admin/core/class-admin-ajax-hooks.php
@@ -30,8 +30,6 @@ if ( ! class_exists( 'um\admin\core\Admin_Ajax_Hooks' ) ) {
add_action( 'wp_ajax_um_member_directory_default_filter_settings', array( UM()->member_directory(), 'default_filter_settings' ) );
add_action( 'wp_ajax_um_same_page_update', array( UM()->admin_settings(), 'same_page_update_ajax' ) );
-
- add_action( 'wp_ajax_um_get_users', array( UM()->users(), 'get_users' ) );
}
}
diff --git a/includes/admin/core/class-admin-columns.php b/includes/admin/core/class-admin-columns.php
index 9baa4527..2b689bec 100644
--- a/includes/admin/core/class-admin-columns.php
+++ b/includes/admin/core/class-admin-columns.php
@@ -33,42 +33,6 @@ if ( ! class_exists( 'um\admin\core\Admin_Columns' ) ) {
add_filter( 'display_post_states', array( &$this, 'add_display_post_states' ), 10, 2 );
add_filter( 'post_row_actions', array( &$this, 'remove_bulk_actions_um_form_inline' ), 10, 2 );
-
- add_filter( 'manage_users_columns', array( &$this, 'manage_users_columns' ) );
-
- add_filter( 'manage_users_custom_column', array( &$this, 'manage_users_custom_column' ), 10, 3 );
- }
-
- /**
- * Filter: Add column 'Status'
- *
- * @param array $columns
- *
- * @return array
- */
- public function manage_users_columns( $columns ) {
- $columns['account_status'] = __( 'Status', 'ultimate-member' );
- return $columns;
- }
-
-
- /**
- * Filter: Show column 'Status'
- *
- * @param string $val
- * @param string $column_name
- * @param int $user_id
- *
- * @return string
- */
- public function manage_users_custom_column( $val, $column_name, $user_id ) {
- if ( $column_name == 'account_status' ) {
- um_fetch_user( $user_id );
- $value = um_user( 'account_status_name' );
- um_reset_user();
- return $value;
- }
- return $val;
}
/**
diff --git a/includes/admin/core/class-admin-notices.php b/includes/admin/core/class-admin-notices.php
index 8ea72173..94641895 100644
--- a/includes/admin/core/class-admin-notices.php
+++ b/includes/admin/core/class-admin-notices.php
@@ -490,9 +490,6 @@ if ( ! class_exists( 'um\admin\core\Admin_Notices' ) ) {
case 'um_settings_updated':
$messages[0]['content'] = __( 'Settings have been saved successfully.', 'ultimate-member' );
break;
- case 'um_user_updated':
- $messages[0]['content'] = __( 'User has been updated.', 'ultimate-member' );
- break;
case 'um_users_updated':
$messages[0]['content'] = __( 'Users have been updated.', 'ultimate-member' );
break;
@@ -502,6 +499,36 @@ if ( ! class_exists( 'um\admin\core\Admin_Notices' ) ) {
case 'um_secure_restore':
$messages[0]['content'] = __( 'Account has been successfully restored.', 'ultimate-member' );
break;
+ case 'um_approved':
+ $approved_count = isset( $_REQUEST['approved_count'] ) ? absint( $_REQUEST['approved_count'] ) : 0;
+
+ $messages[0]['content'] = sprintf( _n( '%s user has been approved.', '%s users have been approved.', $approved_count, 'ultimate-member' ), $approved_count );
+ break;
+ case 'um_reactivated':
+ $reactivated_count = isset( $_REQUEST['reactivated_count'] ) ? absint( $_REQUEST['reactivated_count'] ) : 0;
+
+ $messages[0]['content'] = sprintf( _n( '%s user has been reactivated.', '%s users have been reactivated.', $reactivated_count, 'ultimate-member' ), $reactivated_count );
+ break;
+ case 'um_rejected':
+ $rejected_count = isset( $_REQUEST['rejected_count'] ) ? absint( $_REQUEST['rejected_count'] ) : 0;
+
+ $messages[0]['content'] = sprintf( _n( '%s user has been rejected.', '%s users have been rejected.', $rejected_count, 'ultimate-member' ), $rejected_count );
+ break;
+ case 'um_deactivate':
+ $deactivated_count = isset( $_REQUEST['deactivated_count'] ) ? absint( $_REQUEST['deactivated_count'] ) : 0;
+
+ $messages[0]['content'] = sprintf( _n( '%s user has been deactivated.', '%s users have been deactivated.', $deactivated_count, 'ultimate-member' ), $deactivated_count );
+ break;
+ case 'um_pending':
+ $pending_count = isset( $_REQUEST['pending_count'] ) ? absint( $_REQUEST['pending_count'] ) : 0;
+
+ $messages[0]['content'] = sprintf( _n( '%s user has been set as pending admin review.', '%s users have been set as pending admin review.', $pending_count, 'ultimate-member' ), $pending_count );
+ break;
+ case 'um_resend_activation':
+ $resend_activation_count = isset( $_REQUEST['resend_activation_count'] ) ? absint( $_REQUEST['resend_activation_count'] ) : 0;
+
+ $messages[0]['content'] = sprintf( _n( 'Activation email for %s user has been sent.', 'Activation emails for %s users have been sent.', $resend_activation_count, 'ultimate-member' ), $resend_activation_count );
+ break;
default:
/**
* Filters the custom admin notice after um_adm_action.
diff --git a/includes/admin/core/class-admin-users.php b/includes/admin/core/class-admin-users.php
deleted file mode 100644
index 6db6d889..00000000
--- a/includes/admin/core/class-admin-users.php
+++ /dev/null
@@ -1,576 +0,0 @@
-admin()->check_ajax_nonce();
-
- $search_request = ! empty( $_REQUEST['search'] ) ? sanitize_text_field( $_REQUEST['search'] ) : '';
- $page = ! empty( $_REQUEST['page'] ) ? absint( $_REQUEST['page'] ) : 1;
- $per_page = 20;
-
- $args = array(
- 'fields' => array( 'ID', 'user_login' ),
- 'paged' => $page,
- 'number' => $per_page,
- );
-
- if ( ! empty( $search_request ) ) {
- $args['search'] = '*' . $search_request . '*';
- }
-
- $args = apply_filters( 'um_get_users_list_ajax_args', $args );
-
- $users_query = new \WP_User_Query( $args );
- $users = $users_query->get_results();
- $total_count = $users_query->get_total();
-
- if ( ! empty( $_REQUEST['avatar'] ) ) {
- foreach ( $users as $key => $user ) {
- $url = get_avatar_url( $user->ID );
- $users[ $key ]->img = $url;
- }
- }
-
- wp_send_json_success(
- array(
- 'users' => $users,
- 'total_count' => $total_count,
- )
- );
- }
-
- /**
- * Restrict the edit/delete users via wp-admin screen by the UM role capabilities
- *
- * @param $allcaps
- * @param $cap
- * @param $args
- * @param $user
- *
- * @return mixed
- */
- public function map_caps_by_role( $allcaps, $cap, $args, $user ) {
- if ( isset( $cap[0] ) && $cap[0] == 'edit_users' ) {
- if ( isset( $args[0] ) && isset( $args[1] ) && ! user_can( $args[1], 'administrator' ) && $args[0] == 'edit_user' ) {
- if ( isset( $args[2] ) && ! UM()->roles()->um_current_user_can( 'edit', $args[2] ) ) {
- $allcaps[ $cap[0] ] = false;
- }
- }
- } elseif ( isset( $cap[0] ) && $cap[0] == 'delete_users' ) {
- if ( isset( $args[0] ) && isset( $args[1] ) && ! user_can( $args[1], 'administrator' ) && $args[0] == 'delete_user' ) {
- if ( isset( $args[2] ) && ! UM()->roles()->um_current_user_can( 'delete', $args[2] ) ) {
- $allcaps[ $cap[0] ] = false;
- }
- }
- } elseif ( isset( $cap[0] ) && $cap[0] == 'list_users' ) {
- if ( isset( $args[0] ) && isset( $args[1] ) && ! user_can( $args[1], 'administrator' ) && $args[0] == 'list_users' ) {
- if ( ! um_user( 'can_view_all' ) ) {
- $allcaps[ $cap[0] ] = false;
- }
- }
- }
-
- return $allcaps;
- }
-
- /**
- * Does an action to user asap
- *
- * @param string $action
- */
- public function user_action_hook( $action ) {
- switch ( $action ) {
- default:
- /**
- * UM hook
- *
- * @type action
- * @title um_admin_custom_hook_{$action}
- * @description Integration hook on user action
- * @input_vars
- * [{"var":"$user_id","type":"int","desc":"User ID"}]
- * @change_log
- * ["Since: 2.0"]
- * @usage add_action( 'um_admin_custom_hook_{$action}', 'function_name', 10, 1 );
- * @example
- *
- */
- do_action( "um_admin_custom_hook_{$action}", UM()->user()->id );
- break;
-
- case 'um_put_as_pending':
- UM()->user()->pending();
- break;
-
- case 'um_approve_membership':
- case 'um_reenable':
- add_filter( 'um_template_tags_patterns_hook', array( UM()->password(), 'add_placeholder' ), 10, 1 );
- add_filter( 'um_template_tags_replaces_hook', array( UM()->password(), 'add_replace_placeholder' ), 10, 1 );
-
- UM()->user()->approve();
- break;
-
- case 'um_reject_membership':
- UM()->user()->reject();
- break;
-
- case 'um_resend_activation':
- add_filter( 'um_template_tags_patterns_hook', array( UM()->user(), 'add_activation_placeholder' ), 10, 1 );
- add_filter( 'um_template_tags_replaces_hook', array( UM()->user(), 'add_activation_replace_placeholder' ), 10, 1 );
-
- UM()->user()->email_pending();
- break;
-
- case 'um_deactivate':
- UM()->user()->deactivate();
- break;
-
- case 'um_delete':
- if ( is_admin() ) {
- wp_die( esc_html__( 'This action is not allowed in backend.', 'ultimate-member' ) );
- }
- UM()->user()->delete();
- break;
- }
- }
-
- /**
- * Add UM Bulk actions to Users List Table
- *
- */
- public function restrict_manage_users() {
- ?>
-
-
-
-
-
-
-
-
-
-
-
-
- 'My Custom Bulk Action'
- * );
- * return $actions;
- * }
- * ?>
- */
- $actions = apply_filters( 'um_admin_bulk_user_actions_hook', array(
- 'um_approve_membership' => array(
- 'label' => __( 'Approve Membership', 'ultimate-member' )
- ),
- 'um_reject_membership' => array(
- 'label' => __( 'Reject Membership', 'ultimate-member' )
- ),
- 'um_put_as_pending' => array(
- 'label' => __( 'Put as Pending Review', 'ultimate-member' )
- ),
- 'um_resend_activation' => array(
- 'label' => __( 'Resend Activation Email', 'ultimate-member' )
- ),
- 'um_deactivate' => array(
- 'label' => __( 'Deactivate', 'ultimate-member' )
- ),
- 'um_reenable' => array(
- 'label' => __( 'Reactivate', 'ultimate-member' )
- )
- ) );
-
- $output = '';
- foreach ( $actions as $id => $action_data ) {
- $output .= '';
- }
- return $output;
- }
-
- /**
- * Custom row actions for users page
- *
- * @param array $actions
- * @param $user_object \WP_User
- * @return array
- */
- public function user_row_actions( $actions, $user_object ) {
- $user_id = $user_object->ID;
-
- $actions['frontend_profile'] = '' . __( 'View profile', 'ultimate-member' ) . '';
-
- $submitted = get_user_meta( $user_id, 'submitted', true );
- if ( ! empty( $submitted ) ) {
- $actions['view_info'] = '' . __( 'Info', 'ultimate-member' ) . '';
- }
-
- if ( ! current_user_can( 'administrator' ) ) {
- if ( ! um_can_view_profile( $user_id ) ) {
- unset( $actions['frontend_profile'] );
- unset( $actions['view_info'] );
- unset( $actions['view'] );
- }
- }
-
- /**
- * UM hook
- *
- * @type filter
- * @title um_admin_user_row_actions
- * @description Admin views array
- * @input_vars
- * [{"var":"$actions","type":"array","desc":"User List Table actions"},
- * {"var":"$user_id","type":"int","desc":"User ID"}]
- * @change_log
- * ["Since: 2.0"]
- * @usage add_filter( 'um_admin_user_row_actions', 'function_name', 10, 2 );
- * @example
- *
- */
- $actions = apply_filters( 'um_admin_user_row_actions', $actions, $user_id );
-
- return $actions;
- }
-
- /**
- * Change default sorting at WP Users list table
- *
- * @param array $args
- * @return array
- */
- public function hide_by_caps( $args ) {
- if ( ! current_user_can( 'administrator' ) ) {
- $can_view_roles = um_user( 'can_view_roles' );
- if ( um_user( 'can_view_all' ) && ! empty( $can_view_roles ) ) {
- $args['role__in'] = $can_view_roles;
- }
- }
-
- return $args;
- }
-
- /**
- * Change default sorting at WP Users list table
- *
- * @param $query
- * @return mixed
- */
- public function sort_by_newest( $query ) {
- global $pagenow;
-
- if ( is_admin() && 'users.php' === $pagenow ) {
- if ( ! isset( $_REQUEST['orderby'] ) ) {
- $query->query_vars['order'] = 'desc';
- $query->query_orderby = ' ORDER BY user_registered ' . ( 'desc' === $query->query_vars['order'] ? 'desc ' : 'asc ' ); //set sort order
- }
- }
-
- return $query;
- }
-
- /**
- * Filter WP users by UM Status
- *
- * @param $query
- * @return mixed
- */
- public function filter_users_by_status( $query ) {
- global $wpdb, $pagenow;
- if ( is_admin() && 'users.php' === $pagenow && ! empty( $_REQUEST['um_status'] ) ) {
-
- $status = sanitize_key( $_REQUEST['um_status'] );
-
- if ( 'needs-verification' === $status ) {
- $query->query_where = str_replace('WHERE 1=1',
- "WHERE 1=1 AND {$wpdb->users}.ID IN (
- SELECT {$wpdb->usermeta}.user_id FROM $wpdb->usermeta
- WHERE {$wpdb->usermeta}.meta_key = '_um_verified'
- AND {$wpdb->usermeta}.meta_value = 'pending')",
- $query->query_where
- );
- } else {
- $query->query_where = str_replace('WHERE 1=1',
- "WHERE 1=1 AND {$wpdb->users}.ID IN (
- SELECT {$wpdb->usermeta}.user_id FROM $wpdb->usermeta
- WHERE {$wpdb->usermeta}.meta_key = 'account_status'
- AND {$wpdb->usermeta}.meta_value = '{$status}')",
- $query->query_where
- );
- }
- }
-
- return $query;
- }
-
- /**
- * Add status links to WP Users List Table
- *
- * @param $views
- * @return array
- */
- public function add_status_links( $views ) {
- remove_filter( 'pre_user_query', array( &$this, 'filter_users_by_status' ) );
-
- $old_views = $views;
- $views = array();
-
- if ( ! isset( $_REQUEST['role'] ) && ! isset( $_REQUEST['um_status'] ) ) {
- $views['all'] = '' . __( 'All', 'ultimate-member' ) . ' (' . UM()->query()->count_users() . ')';
- } else {
- $views['all'] = '' . __( 'All', 'ultimate-member' ) . ' (' . UM()->query()->count_users() . ')';
- }
-
- $status = array(
- 'approved' => __( 'Approved', 'ultimate-member' ),
- 'awaiting_admin_review' => __( 'Pending review', 'ultimate-member' ),
- 'awaiting_email_confirmation' => __( 'Waiting email confirmation', 'ultimate-member' ),
- 'inactive' => __( 'Inactive', 'ultimate-member' ),
- 'rejected' => __( 'Rejected', 'ultimate-member' ),
- );
-
- // 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 ) {
- $current = 'class="current"';
- } else {
- $current = '';
- }
-
- $views[ $k ] = '' . $v . ' (' . UM()->query()->count_users_by_status( $k ) . ')';
- }
-
- /**
- * UM hook
- *
- * @type filter
- * @title um_admin_views_users
- * @description Admin views array
- * @input_vars
- * [{"var":"$views","type":"array","desc":"User Views"}]
- * @change_log
- * ["Since: 2.0"]
- * @usage add_filter( 'um_admin_views_users', 'function_name', 10, 1 );
- * @example
- *
- */
- $views = apply_filters( 'um_admin_views_users', $views );
-
- // remove all filters
- unset( $old_views['all'] );
-
- // add separator
- $views['subsep'] = '';
-
- // merge views
- foreach ( $old_views as $key => $view ) {
- $views[ $key ] = $view;
- }
-
- // hide filters with not accessible roles
- if ( ! current_user_can( 'administrator' ) ) {
- $wp_roles = wp_roles();
- $can_view_roles = um_user( 'can_view_roles' );
- if ( ! empty( $can_view_roles ) ) {
- foreach ( $wp_roles->get_names() as $this_role => $name ) {
- if ( ! in_array( $this_role, $can_view_roles, true ) ) {
- unset( $views[ $this_role ] );
- }
- }
- }
- }
-
- return $views;
- }
-
- /**
- * Bulk user editing actions
- */
- public function um_bulk_users_edit() {
- // bulk edit users
- if ( ! empty( $_REQUEST['users'] ) && ! empty( $_REQUEST['um_bulkedit'] ) && ! empty( $_REQUEST['um_bulk_action'] ) ) {
-
- $rolename = UM()->roles()->get_priority_user_role( get_current_user_id() );
- $role = get_role( $rolename );
-
- if ( empty( $role ) ) {
- wp_die( esc_html__( 'You do not have enough permissions to do that.', 'ultimate-member' ) );
- }
-
- if ( ! current_user_can( 'edit_users' ) && ! $role->has_cap( 'edit_users' ) ) {
- wp_die( esc_html__( 'You do not have enough permissions to do that.', 'ultimate-member' ) );
- }
-
- check_admin_referer( 'bulk-users' );
-
- $users = array_map( 'absint', (array) $_REQUEST['users'] );
- $bulk_action = current( array_filter( $_REQUEST['um_bulk_action'] ) );
-
- foreach ( $users as $user_id ) {
- UM()->user()->set( $user_id );
-
- /**
- * UM hook
- *
- * @type action
- * @title um_admin_user_action_hook
- * @description Action on bulk user action
- * @input_vars
- * [{"var":"$bulk_action","type":"string","desc":"Bulk Action"}]
- * @change_log
- * ["Since: 2.0"]
- * @usage add_action( 'um_admin_user_action_hook{$action}', 'function_name', 10, 1 );
- * @example
- *
- */
- do_action( 'um_admin_user_action_hook', $bulk_action );
-
- /**
- * UM hook
- *
- * @type action
- * @title um_admin_user_action_{$bulk_action}_hook
- * @description Action on bulk user action
- * @change_log
- * ["Since: 2.0"]
- * @usage add_action( 'um_admin_user_action_{$bulk_action}_hook', 'function_name', 10 );
- * @example
- *
- */
- do_action( "um_admin_user_action_{$bulk_action}_hook" );
- }
-
- $uri = $this->set_redirect_uri( admin_url( 'users.php' ) );
- $uri = add_query_arg( 'update', 'um_users_updated', $uri );
-
- wp_safe_redirect( $uri );
- exit;
- }
-
- if ( ! empty( $_REQUEST['um_bulkedit'] ) ) {
- $uri = $this->set_redirect_uri( admin_url( 'users.php' ) );
- wp_safe_redirect( $uri );
- exit;
- }
- }
-
- /**
- * Sets redirect URI after bulk action
- *
- * @param string $uri
- * @return string
- */
- public function set_redirect_uri( $uri ) {
-
- if ( ! empty( $_REQUEST['s'] ) ) {
- $uri = add_query_arg( 's', sanitize_text_field( $_REQUEST['s'] ), $uri );
- }
-
- if ( ! empty( $_REQUEST['um_status'] ) ) {
- $uri = add_query_arg( 'um_status', sanitize_key( $_REQUEST['um_status'] ), $uri );
- }
-
- return $uri;
-
- }
- }
-}
diff --git a/includes/ajax/class-init.php b/includes/ajax/class-init.php
index 50645233..eeb2e7fc 100644
--- a/includes/ajax/class-init.php
+++ b/includes/ajax/class-init.php
@@ -23,6 +23,7 @@ if ( ! class_exists( 'um\ajax\Init' ) ) {
$this->forms();
$this->pages();
$this->secure();
+ $this->users();
}
/**
@@ -60,5 +61,17 @@ if ( ! class_exists( 'um\ajax\Init' ) ) {
}
return UM()->classes['um\ajax\secure'];
}
+
+ /**
+ * @since 2.8.7
+ *
+ * @return Users
+ */
+ public function users() {
+ if ( empty( UM()->classes['um\ajax\users'] ) ) {
+ UM()->classes['um\ajax\users'] = new Users();
+ }
+ return UM()->classes['um\ajax\users'];
+ }
}
}
diff --git a/includes/ajax/class-users.php b/includes/ajax/class-users.php
new file mode 100644
index 00000000..bd44eaa5
--- /dev/null
+++ b/includes/ajax/class-users.php
@@ -0,0 +1,56 @@
+admin()->check_ajax_nonce();
+
+ $search_request = ! empty( $_REQUEST['search'] ) ? sanitize_text_field( $_REQUEST['search'] ) : '';
+ $page = ! empty( $_REQUEST['page'] ) ? absint( $_REQUEST['page'] ) : 1;
+ $per_page = 20;
+
+ $args = array(
+ 'fields' => array( 'ID', 'user_login' ),
+ 'paged' => $page,
+ 'number' => $per_page,
+ );
+
+ if ( ! empty( $search_request ) ) {
+ $args['search'] = '*' . $search_request . '*';
+ }
+
+ $args = apply_filters( 'um_get_users_list_ajax_args', $args );
+
+ $users_query = new \WP_User_Query( $args );
+ $users = $users_query->get_results();
+ $total_count = $users_query->get_total();
+
+ if ( ! empty( $_REQUEST['avatar'] ) ) {
+ foreach ( $users as $key => $user ) {
+ $url = get_avatar_url( $user->ID );
+ $users[ $key ]->img = $url;
+ }
+ }
+
+ wp_send_json_success(
+ array(
+ 'users' => $users,
+ 'total_count' => $total_count,
+ )
+ );
+ }
+}
diff --git a/includes/class-init.php b/includes/class-init.php
index efa6cf07..9c8f811b 100644
--- a/includes/class-init.php
+++ b/includes/class-init.php
@@ -526,7 +526,6 @@ if ( ! class_exists( 'UM' ) ) {
$this->admin_settings();
$this->columns();
$this->metabox();
- $this->users();
$this->dragdrop();
$this->admin_gdpr();
$this->admin_navmenu();
@@ -902,20 +901,6 @@ if ( ! class_exists( 'UM' ) ) {
return $this->classes['admin_metabox'];
}
-
- /**
- * @since 2.0
- *
- * @return um\admin\core\Admin_Users()
- */
- function users() {
- if ( empty( $this->classes['admin_users'] ) ) {
- $this->classes['admin_users'] = new um\admin\core\Admin_Users();
- }
- return $this->classes['admin_users'];
- }
-
-
/**
* @since 2.0
*
@@ -1466,7 +1451,7 @@ if ( ! class_exists( 'UM' ) ) {
require_once 'core/um-actions-form.php';
require_once 'core/um-actions-access.php';
require_once 'core/um-actions-wpadmin.php';
- require_once 'core/um-actions-core.php';
+// require_once 'core/um-actions-core.php';
require_once 'core/um-actions-ajax.php';
require_once 'core/um-actions-login.php';
require_once 'core/um-actions-register.php';
diff --git a/includes/common/class-init.php b/includes/common/class-init.php
index 1e9e74cd..41ad1b2a 100644
--- a/includes/common/class-init.php
+++ b/includes/common/class-init.php
@@ -25,6 +25,7 @@ if ( ! class_exists( 'um\common\Init' ) ) {
$this->secure()->hooks();
$this->site_health();
$this->theme()->hooks();
+ $this->users()->hooks();
}
/**
@@ -86,5 +87,17 @@ if ( ! class_exists( 'um\common\Init' ) ) {
}
return UM()->classes['um\common\theme'];
}
+
+ /**
+ * @since 2.8.7
+ *
+ * @return Users
+ */
+ public function users() {
+ if ( empty( UM()->classes['um\common\users'] ) ) {
+ UM()->classes['um\common\users'] = new Users();
+ }
+ return UM()->classes['um\common\users'];
+ }
}
}
diff --git a/includes/common/class-secure.php b/includes/common/class-secure.php
index a0d01571..6fd084fa 100644
--- a/includes/common/class-secure.php
+++ b/includes/common/class-secure.php
@@ -229,9 +229,11 @@ if ( ! class_exists( 'um\common\Secure' ) ) {
$user->update_user_level_from_caps();
if ( is_user_logged_in() ) {
- UM()->user()->set_status( 'inactive' );
+ //UM()->user()->set_status( 'inactive' );
+ UM()->common()->users()->set_status( $user->ID, 'inactive' );
} else {
- UM()->user()->set_status( 'rejected' );
+ //UM()->user()->set_status( 'rejected' );
+ UM()->common()->users()->set_status( $user->ID, 'rejected' );
}
um_reset_user();
update_user_meta( $user->ID, 'um_user_blocked', 'suspicious_activity' );
diff --git a/includes/common/class-users.php b/includes/common/class-users.php
new file mode 100644
index 00000000..f8a8b512
--- /dev/null
+++ b/includes/common/class-users.php
@@ -0,0 +1,811 @@
+roles()->um_current_user_can( 'edit', $args[2] ) ) {
+ $allcaps[ $caps[0] ] = false;
+ }
+ } elseif ( 'delete_users' === $caps[0] && 'delete_user' === $args[0] ) {
+ if ( isset( $args[2] ) && ! UM()->roles()->um_current_user_can( 'delete', $args[2] ) ) {
+ $allcaps[ $caps[0] ] = false;
+ }
+ } elseif ( 'list_users' === $caps[0] ) {
+ if ( 'list_users' === $args[0] && ! um_user( 'can_view_all' ) ) {
+ $allcaps[ $caps[0] ] = false;
+ }
+ }
+
+ return $allcaps;
+ }
+
+ /**
+ * Hide role filters with not accessible roles
+ *
+ * @param array $roles
+ * @return array
+ */
+ public function restrict_roles( $roles ) {
+ if ( current_user_can( 'manage_options' ) ) {
+ return $roles;
+ }
+
+ $can_view_roles = UM()->roles()->um_user_can( 'can_view_roles' );
+ if ( UM()->roles()->um_user_can( 'can_view_all' ) && empty( $can_view_roles ) ) {
+ return $roles;
+ }
+
+ if ( ! empty( $can_view_roles ) ) {
+ $wp_roles = wp_roles();
+ foreach ( $wp_roles->get_names() as $this_role => $name ) {
+ if ( ! in_array( $this_role, $can_view_roles, true ) ) {
+ unset( $roles[ $this_role ] );
+ }
+ }
+ }
+
+ return $roles;
+ }
+
+ /**
+ * Get the user statuses list.
+ *
+ * @return array
+ */
+ public function statuses_list() {
+ $statuses = array(
+ 'approved' => __( 'Approved', 'ultimate-member' ),
+ 'awaiting_admin_review' => __( 'Pending administrator review', 'ultimate-member' ),
+ 'awaiting_email_confirmation' => __( 'Waiting email confirmation', 'ultimate-member' ),
+ 'inactive' => __( 'Membership inactive', 'ultimate-member' ),
+ 'rejected' => __( 'Membership rejected', 'ultimate-member' ),
+ );
+ /**
+ * Filters the user statuses added via Ultimate Member plugin.
+ *
+ * Note: Statuses format is 'key' => 'title'
+ *
+ * @since 2.8.7
+ * @hook um_user_statuses
+ *
+ * @param {array} $statuses User statuses in Ultimate Member environment.
+ *
+ * @return {array} User statuses.
+ */
+ return apply_filters( 'um_user_statuses', $statuses );
+ }
+
+ /**
+ * Set user's account status.
+ *
+ * @param int $user_id User ID.
+ * @param string $status Status key.
+ *
+ * @return bool
+ */
+ public function set_status( $user_id, $status ) {
+ $old_status = $this->get_status( $user_id );
+
+ /**
+ * Fires before User status is set.
+ *
+ * @since 2.8.7
+ * @hook um_before_user_status_is_set
+ *
+ * @param {string} $status New status key.
+ * @param {int} $user_id User ID.
+ * @param {string} $old_status Old status key.
+ */
+ do_action( 'um_before_user_status_is_set', $status, $user_id, $old_status );
+
+ $result = update_user_meta( $user_id, 'account_status', $status );
+
+ // false on failure or if the value passed to the function is the same as the one that is already in the database.
+ if ( false !== $result ) {
+ // backward compatibility. @todo maybe uncomment it after some testing.
+ // UM()->user()->profile['account_status'] = $status;
+
+ // Reset cache.
+ $this->remove_cache( $user_id );
+
+ /**
+ * Fires just after User status is changed.
+ *
+ * @since 1.3.x
+ * @since 2.0 Added $user_id
+ * @since 2.8.7 Added $old_status
+ *
+ * @hook um_after_user_status_is_changed
+ *
+ * @param {string} $status Status key.
+ * @param {int} $user_id User ID. Since 2.0
+ * @param {string} $old_status Old status key. Since 2.8.7
+ */
+ do_action( 'um_after_user_status_is_changed', $status, $user_id, $old_status );
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Get user account status.
+ *
+ * @param int $user_id User ID
+ *
+ * @return string
+ */
+ public function get_status( $user_id, $format = 'raw' ) {
+ $status = get_user_meta( $user_id, 'account_status', true );
+ if ( 'raw' === $format ) {
+ return $status;
+ }
+
+ $all_statuses = $this->statuses_list();
+ if ( array_key_exists( $status, $all_statuses ) ) {
+ return $all_statuses[ $status ];
+ }
+
+ return __( 'Undefined', 'ultimate-member' );
+ }
+
+ /**
+ * Check if user has selected account status.
+ *
+ * @since 2.8.7
+ *
+ * @param int $user_id User ID.
+ * @param string $status_control Status key.
+ *
+ * @return bool
+ */
+ public function has_status( $user_id, $status_control ) {
+ $status = $this->get_status( $user_id );
+ return $status === $status_control;
+ }
+
+ /**
+ * Reset User cache
+ *
+ * @param int $user_id User ID.
+ */
+ public function remove_cache( $user_id ) {
+ delete_option( "um_cache_userdata_{$user_id}" );
+ }
+
+ /**
+ * Reset Activation link hash.
+ *
+ * @param int $user_id User ID.
+ */
+ public function reset_activation_link( $user_id ) {
+ delete_user_meta( $user_id, 'account_secret_hash' );
+ delete_user_meta( $user_id, 'account_secret_hash_expiry' );
+ }
+
+ /**
+ * Set user's activation link hash
+ *
+ * @param int $user_id User ID.
+ */
+ public function assign_secretkey( $user_id ) {
+ if ( ! $this->has_status( $user_id, 'awaiting_email_confirmation' ) ) {
+ return;
+ }
+
+ /**
+ * Fires before user activation link hash is generated.
+ *
+ * @since 1.3.x
+ * @since 2.8.7 Added $user_id
+ * @hook um_before_user_hash_is_changed
+ *
+ * @param {int} $user_id User ID. Since 2.8.7
+ */
+ do_action( 'um_before_user_hash_is_changed', $user_id );
+
+ $hash = UM()->validation()->generate();
+ update_user_meta( $user_id, 'account_secret_hash', $hash );
+ // backward compatibility. @todo maybe uncomment it after some testing.
+ // UM()->user()->profile['account_secret_hash'] = $hash;
+
+ $expiration = '';
+ $expiry_time = UM()->options()->get( 'activation_link_expiry_time' );
+ if ( ! empty( $expiry_time ) && is_numeric( $expiry_time ) ) {
+ $expiration = time() + $expiry_time * DAY_IN_SECONDS;
+ update_user_meta( $user_id, 'account_secret_hash_expiry', $expiration );
+ // backward compatibility. @todo maybe uncomment it after some testing.
+ // UM()->user()->profile['account_secret_hash_expiry'] = $expiration;
+ }
+
+ /**
+ * Fires after user activation link hash is changed.
+ *
+ * @since 1.3.x
+ * @since 2.8.7 Added $user_id, $hash, $expiration
+ * @hook um_before_user_hash_is_changed
+ *
+ * @param {int} $user_id User ID. Since 2.8.7.
+ * @param {string} $hash Activation link hash. Since 2.8.7.
+ * @param {int} $expiration Expiration timestamp. Since 2.8.7.
+ */
+ do_action( 'um_after_user_hash_is_changed', $user_id, $hash, $expiration );
+ }
+
+ /**
+ * @param WP_User $userdata
+ *
+ * @return string|WP_Error
+ */
+ public function maybe_generate_password_reset_key( $userdata ) {
+ return get_password_reset_key( $userdata );
+ }
+
+ public function can_current_user_edit_user( $user_id ) {
+ $current_user_id = get_current_user_id();
+ if ( $current_user_id === $user_id ) {
+ return true;
+ }
+
+ if ( ! self::user_exists( $user_id ) ) {
+ return false;
+ }
+
+ $rolename = UM()->roles()->get_priority_user_role( $current_user_id );
+ $role = get_role( $rolename );
+
+ if ( null === $role ) {
+ return false;
+ }
+
+ // Make Ultimate Member bulk actions only when the current user has 'edit_users' capability.
+ if ( ! current_user_can( 'edit_users' ) && ! $role->has_cap( 'edit_users' ) ) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public function can_activation_send( $user_id ) {
+ $current_user_id = get_current_user_id();
+ if ( $current_user_id === $user_id || ! self::user_exists( $user_id ) ) {
+ return false;
+ }
+
+// $rolename = UM()->roles()->get_priority_user_role( $current_user_id );
+// $role = get_role( $rolename );
+//
+// if ( null === $role ) {
+// return false;
+// }
+//
+// // Make Ultimate Member bulk actions only when the current user has 'edit_users' capability.
+// if ( ! current_user_can( 'edit_users' ) && ! $role->has_cap( 'edit_users' ) ) {
+// return false;
+// }
+
+ $status = $this->get_status( $user_id );
+ return 'awaiting_admin_review' !== $status;
+ }
+
+ public function send_activation( $user_id ) {
+ if ( ! $this->can_activation_send( $user_id ) ) {
+ return false;
+ }
+
+ /**
+ * Fires before User has been set as pending email confirmation.
+ *
+ * @since 2.8.7
+ * @hook um_before_user_is_set_as_awaiting_email_confirmation
+ *
+ * @param {int} $user_id User ID.
+ */
+ do_action( 'um_before_user_is_set_as_awaiting_email_confirmation', $user_id );
+
+ $result = $this->set_status( $user_id, 'awaiting_email_confirmation' );
+
+ // It's `false` on failure or if the user already has rejected status.
+ if ( false !== $result ) {
+ //clear all sessions for email confirmation pending users
+ $user = WP_Session_Tokens::get_instance( $user_id );
+ $user->destroy_all();
+
+ // Set activation link hash.
+ $this->assign_secretkey( $user_id );
+
+ $userdata = get_userdata( $user_id );
+
+ add_filter( 'um_template_tags_patterns_hook', array( UM()->user(), 'add_activation_placeholder' ) );
+ add_filter( 'um_template_tags_replaces_hook', array( UM()->user(), 'add_activation_replace_placeholder' ) );
+
+ UM()->mail()->send( $userdata->user_email, 'checkmail_email' );
+
+ /**
+ * Fires after User has been set as pending email confirmation.
+ *
+ * @since 2.8.7
+ * @hook um_after_user_is_set_as_awaiting_email_confirmation
+ *
+ * @param {int} $user_id User ID.
+ */
+ do_action( 'um_after_user_is_set_as_awaiting_email_confirmation', $user_id );
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * @param $user_id
+ *
+ * @return bool
+ */
+ public function can_be_deactivated( $user_id ) {
+ $current_user_id = get_current_user_id();
+ if ( $current_user_id === $user_id || ! self::user_exists( $user_id ) ) {
+ return false;
+ }
+
+// $rolename = UM()->roles()->get_priority_user_role( $current_user_id );
+// $role = get_role( $rolename );
+//
+// if ( null === $role ) {
+// return false;
+// }
+//
+// // Make Ultimate Member bulk actions only when the current user has 'edit_users' capability.
+// if ( ! current_user_can( 'edit_users' ) && ! $role->has_cap( 'edit_users' ) ) {
+// return false;
+// }
+
+ $status = $this->get_status( $user_id );
+ if ( 'inactive' === $status ) {
+ // Break if the user already approved
+ return false;
+ }
+
+ if ( 'approved' !== $status ) {
+ // Break if the user already doesn't approved yet
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * @param $user_id
+ *
+ * @return bool
+ */
+ public function deactivate( $user_id ) {
+ if ( ! $this->can_be_deactivated( $user_id ) ) {
+ return false;
+ }
+
+ /**
+ * Fires before User has been deactivated.
+ *
+ * @since 2.8.7
+ * @hook um_before_user_is_deactivated
+ *
+ * @param {int} $user_id User ID.
+ */
+ do_action( 'um_before_user_is_deactivated', $user_id );
+
+ $result = $this->set_status( $user_id, 'inactive' );
+
+ // It's `false` on failure or if the user already has approved status.
+ if ( false !== $result ) {
+ // Clear all sessions for inactive users
+ $user = WP_Session_Tokens::get_instance( $user_id );
+ $user->destroy_all();
+
+ $userdata = get_userdata( $user_id );
+ UM()->mail()->send( $userdata->user_email, 'inactive_email' );
+
+ /**
+ * Fires after User has been deactivated.
+ *
+ * @since 1.3.x
+ * @hook um_after_user_is_inactive
+ *
+ * @param {int} $user_id User ID.
+ */
+ do_action( 'um_after_user_is_inactive', $user_id );
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * @param $user_id
+ *
+ * @return bool
+ */
+ public function can_be_rejected( $user_id ) {
+ $current_user_id = get_current_user_id();
+ if ( $current_user_id === $user_id || ! self::user_exists( $user_id ) ) {
+ return false;
+ }
+
+// $rolename = UM()->roles()->get_priority_user_role( $current_user_id );
+// $role = get_role( $rolename );
+//
+// if ( null === $role ) {
+// return false;
+// }
+//
+// // Make Ultimate Member bulk actions only when the current user has 'edit_users' capability.
+// if ( ! current_user_can( 'edit_users' ) && ! $role->has_cap( 'edit_users' ) ) {
+// return false;
+// }
+
+ $status = $this->get_status( $user_id );
+ if ( 'rejected' === $status ) {
+ // Break if the user already rejected
+ return false;
+ }
+
+ if ( 'approved' !== $status ) {
+ // Break if the user already doesn't approved yet
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * @param $user_id
+ *
+ * @return bool
+ */
+ public function reject( $user_id ) {
+ if ( ! $this->can_be_rejected( $user_id ) ) {
+ return false;
+ }
+
+ /**
+ * Fires before User has been rejected.
+ *
+ * @since 2.8.7
+ * @hook um_before_user_is_rejected
+ *
+ * @param {int} $user_id User ID.
+ */
+ do_action( 'um_before_user_is_rejected', $user_id );
+
+ $result = $this->set_status( $user_id, 'rejected' );
+
+ // It's `false` on failure or if the user already has rejected status.
+ if ( false !== $result ) {
+ // Clear all sessions for rejected users
+ $user = WP_Session_Tokens::get_instance( $user_id );
+ $user->destroy_all();
+
+ $userdata = get_userdata( $user_id );
+ UM()->mail()->send( $userdata->user_email, 'rejected_email' );
+
+ /**
+ * Fires after User has been rejected.
+ *
+ * @since 2.8.7
+ * @hook um_after_user_is_rejected
+ *
+ * @param {int} $user_id User ID.
+ */
+ do_action( 'um_after_user_is_rejected', $user_id );
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * @param int $user_id
+ *
+ * @return bool
+ */
+ public function can_be_set_as_pending( $user_id ) {
+ $current_user_id = get_current_user_id();
+ if ( $current_user_id === $user_id || ! self::user_exists( $user_id ) ) {
+ return false;
+ }
+
+// $rolename = UM()->roles()->get_priority_user_role( $current_user_id );
+// $role = get_role( $rolename );
+//
+// if ( null === $role ) {
+// return false;
+// }
+//
+// // Make Ultimate Member bulk actions only when the current user has 'edit_users' capability.
+// if ( ! current_user_can( 'edit_users' ) && ! $role->has_cap( 'edit_users' ) ) {
+// return false;
+// }
+
+ $status = $this->get_status( $user_id );
+ return 'awaiting_admin_review' !== $status;
+ }
+
+ /**
+ * @param int $user_id
+ *
+ * @return bool
+ */
+ public function set_as_pending( $user_id ) {
+ if ( ! $this->can_be_set_as_pending( $user_id ) ) {
+ return false;
+ }
+
+ /**
+ * Fires before User has been set as pending admin review.
+ *
+ * @since 2.8.7
+ * @hook um_before_user_is_set_as_pending
+ *
+ * @param {int} $user_id User ID.
+ */
+ do_action( 'um_before_user_is_set_as_pending', $user_id );
+
+ $result = $this->set_status( $user_id, 'awaiting_admin_review' );
+
+ // It's `false` on failure or if the user already has rejected status.
+ if ( false !== $result ) {
+ // Clear all sessions for awaiting admin confirmation users
+ $user = WP_Session_Tokens::get_instance( $user_id );
+ $user->destroy_all();
+
+ $userdata = get_userdata( $user_id );
+ UM()->mail()->send( $userdata->user_email, 'pending_email' );
+
+ /**
+ * Fires after User has been set as pending admin review.
+ *
+ * @since 2.8.7
+ * @hook um_after_user_is_set_as_pending
+ *
+ * @param {int} $user_id User ID.
+ */
+ do_action( 'um_after_user_is_set_as_pending', $user_id );
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Check if the user can be approved.
+ *
+ * @param int $user_id User ID
+ *
+ * @return bool
+ */
+ public function can_be_approved( $user_id ) {
+ $current_user_id = get_current_user_id();
+ if ( $current_user_id === $user_id || ! self::user_exists( $user_id ) ) {
+ return false;
+ }
+
+// $rolename = UM()->roles()->get_priority_user_role( $current_user_id );
+// $role = get_role( $rolename );
+//
+// if ( null === $role ) {
+// return false;
+// }
+//
+// // Make Ultimate Member bulk actions only when the current user has 'edit_users' capability.
+// if ( ! current_user_can( 'edit_users' ) && ! $role->has_cap( 'edit_users' ) ) {
+// return false;
+// }
+
+ $status = $this->get_status( $user_id );
+ return 'approved' !== $status;
+ }
+
+ /**
+ * @param int $user_id
+ *
+ * @return bool
+ */
+ public static function user_exists( $user_id ) {
+ /**
+ * @var bool[] $search_results
+ */
+ static $search_results = array();
+
+ if ( array_key_exists( $user_id, $search_results ) ) {
+ return $search_results[ $user_id ];
+ }
+
+ $user = get_userdata( $user_id );
+
+ $search_results[ $user_id ] = false !== $user;
+ return $search_results[ $user_id ];
+ }
+
+ /**
+ * Approve user.
+ *
+ * @param int $user_id User ID.
+ *
+ * @return bool `true` if the user has been approved
+ * `false` on failure or if the user already has approved status.
+ */
+ public function approve( $user_id ) {
+ if ( ! $this->can_be_approved( $user_id ) ) {
+ return false;
+ }
+
+ /**
+ * Fires before User has been approved.
+ *
+ * @since 2.8.7
+ * @hook um_before_user_is_approved
+ *
+ * @param {int} $user_id User ID.
+ */
+ do_action( 'um_before_user_is_approved', $user_id );
+
+ $old_status = $this->get_status( $user_id );
+
+ $result = $this->set_status( $user_id, 'approved' );
+
+ // It's `false` on failure or if the user already has approved status.
+ if ( false !== $result ) {
+ $userdata = get_userdata( $user_id );
+
+ $this->reset_activation_link( $user_id );
+
+ $email_slug = 'welcome_email';
+ if ( 'awaiting_admin_review' === $old_status ) {
+ $email_slug = 'approved_email';
+ $this->maybe_generate_password_reset_key( $userdata );
+ }
+
+ add_filter( 'um_template_tags_patterns_hook', array( UM()->password(), 'add_placeholder' ) );
+ add_filter( 'um_template_tags_replaces_hook', array( UM()->password(), 'add_replace_placeholder' ) );
+
+ UM()->mail()->send( $userdata->user_email, $email_slug );
+
+ /**
+ * Fires after User has been approved.
+ *
+ * @since 1.3.x
+ * @hook um_after_user_is_approved
+ *
+ * @param {int} $user_id User ID.
+ */
+ do_action( 'um_after_user_is_approved', $user_id );
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * @param int $user_id
+ *
+ * @return bool
+ */
+ public function can_be_reactivated( $user_id ) {
+ $current_user_id = get_current_user_id();
+ if ( $current_user_id === $user_id || ! self::user_exists( $user_id ) ) {
+ return false;
+ }
+
+// $rolename = UM()->roles()->get_priority_user_role( $current_user_id );
+// $role = get_role( $rolename );
+//
+// if ( null === $role ) {
+// return false;
+// }
+//
+// // Make Ultimate Member bulk actions only when the current user has 'edit_users' capability.
+// if ( ! current_user_can( 'edit_users' ) && ! $role->has_cap( 'edit_users' ) ) {
+// return false;
+// }
+
+ $status = $this->get_status( $user_id );
+ return 'inactive' === $status;
+ }
+
+ /**
+ * @param int $user_id
+ *
+ * @return bool
+ */
+ public function reactivate( $user_id ) {
+ if ( ! $this->can_be_reactivated( $user_id ) ) {
+ return false;
+ }
+
+ /**
+ * Fires before User has been reactivated.
+ *
+ * @since 2.8.7
+ * @hook um_before_user_is_reactivated
+ *
+ * @param {int} $user_id User ID.
+ */
+ do_action( 'um_before_user_is_reactivated', $user_id );
+
+ $result = $this->set_status( $user_id, 'approved' );
+
+ // It's `false` on failure or if the user already has approved status.
+ if ( false !== $result ) {
+ // Reset activation link hash.
+ $this->reset_activation_link( $user_id );
+
+ $userdata = get_userdata( $user_id );
+
+ add_filter( 'um_template_tags_patterns_hook', array( UM()->password(), 'add_placeholder' ) );
+ add_filter( 'um_template_tags_replaces_hook', array( UM()->password(), 'add_replace_placeholder' ) );
+
+ UM()->mail()->send( $userdata->user_email, 'welcome_email' );
+
+ /**
+ * Fires after User has been reactivated.
+ *
+ * @since 2.8.7
+ * @hook um_after_user_is_reactivated
+ *
+ * @param {int} $user_id User ID.
+ */
+ do_action( 'um_after_user_is_reactivated', $user_id );
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/includes/core/class-member-directory.php b/includes/core/class-member-directory.php
index d9cdea0e..ea83dffa 100644
--- a/includes/core/class-member-directory.php
+++ b/includes/core/class-member-directory.php
@@ -2589,21 +2589,18 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
return $pagination_data;
}
-
/**
* @param int $user_id
*
* @return array
*/
- function build_user_actions_list( $user_id ) {
-
+ private function build_user_actions_list( $user_id ) {
$actions = array();
if ( ! is_user_logged_in() ) {
return $actions;
}
- if ( get_current_user_id() != $user_id ) {
-
+ if ( get_current_user_id() !== $user_id ) {
if ( UM()->roles()->um_current_user_can( 'edit', $user_id ) ) {
$actions['um-editprofile'] = array(
'title' => esc_html__( 'Edit Profile', 'ultimate-member' ),
@@ -2611,31 +2608,17 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
);
}
- /**
- * UM hook
- *
- * @type filter
- * @title um_admin_user_actions_hook
- * @description Extend admin actions for each user
- * @input_vars
- * [{"var":"$actions","type":"array","desc":"Actions for user"}]
- * @change_log
- * ["Since: 2.0"]
- * @usage
- *
- * @example
- *
- */
- $admin_actions = apply_filters( 'um_admin_user_actions_hook', array(), $user_id );
+ $admin_actions = UM()->frontend()->users()->get_actions_list( $user_id );
if ( ! empty( $admin_actions ) ) {
foreach ( $admin_actions as $id => $arr ) {
- $url = add_query_arg( array( 'um_action' => $id, 'uid' => $user_id ), um_get_core_page( 'user' ) );
+ $url = add_query_arg(
+ array(
+ 'um_action' => $id,
+ 'uid' => $user_id,
+ 'nonce' => wp_create_nonce( $id . $user_id ),
+ ),
+ um_user_profile_url( $user_id )
+ );
$actions[ $id ] = array(
'title' => esc_html( $arr['label'] ),
@@ -2645,9 +2628,7 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
}
$actions = apply_filters( 'um_member_directory_users_card_actions', $actions, $user_id );
-
} else {
-
if ( empty( UM()->user()->cannot_edit ) ) {
$actions['um-editprofile'] = array(
'title' => esc_html__( 'Edit Profile', 'ultimate-member' ),
@@ -2671,15 +2652,13 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
return $actions;
}
-
/**
* @param int $user_id
* @param array $directory_data
*
* @return array
*/
- function build_user_card_data( $user_id, $directory_data ) {
-
+ public function build_user_card_data( $user_id, $directory_data ) {
um_fetch_user( $user_id );
$dropdown_actions = $this->build_user_actions_list( $user_id );
diff --git a/includes/core/class-permalinks.php b/includes/core/class-permalinks.php
index b2714d45..3f04ffac 100644
--- a/includes/core/class-permalinks.php
+++ b/includes/core/class-permalinks.php
@@ -129,7 +129,7 @@ if ( ! class_exists( 'um\core\Permalinks' ) ) {
$set_password_required = get_user_meta( $user_id, 'um_set_password_required', true );
um_fetch_user( $user_id );
- UM()->user()->approve();
+ UM()->common()->users()->approve( $user_id );
if ( ! empty( $set_password_required ) ) {
$redirect = um_user( 'password_reset_link' );
}
diff --git a/includes/core/class-rewrite.php b/includes/core/class-rewrite.php
index 13578add..7d238716 100644
--- a/includes/core/class-rewrite.php
+++ b/includes/core/class-rewrite.php
@@ -234,8 +234,8 @@ if ( ! class_exists( 'um\core\Rewrite' ) ) {
$user_id = $this->get_user_id_by_user_login_slug();
}
- if ( 'user_id' === $permalink_base ) {
- $user_id = UM()->user()->user_exists_by_id( um_queried_user() );
+ if ( 'user_id' === $permalink_base && UM()->common()->users()::user_exists( um_queried_user() ) ) {
+ $user_id = um_queried_user();
}
if ( 'hash' === $permalink_base ) {
diff --git a/includes/core/class-user.php b/includes/core/class-user.php
index 914a82b2..68f53dd9 100644
--- a/includes/core/class-user.php
+++ b/includes/core/class-user.php
@@ -130,7 +130,6 @@ if ( ! class_exists( 'um\core\User' ) ) {
add_action( 'personal_options_update', array( &$this, 'remove_cache' ) );
//add_action('edit_user_profile_update', array(&$this, 'remove_cache') );
add_action( 'um_when_role_is_set', array( &$this, 'remove_cache' ) );
- add_action( 'um_when_status_is_set', array( &$this, 'remove_cache' ) );
add_action( 'show_user_profile', array( $this, 'profile_form_additional_section' ), 10 );
add_action( 'user_new_form', array( $this, 'profile_form_additional_section' ), 10 );
@@ -1504,134 +1503,23 @@ if ( ! class_exists( 'um\core\User' ) ) {
/**
* Set user's account status
*
- * @param $status
+ * @deprecated 2.8.7
+ *
+ * @param string $status
*/
- function set_status( $status ) {
-
- /**
- * UM hook
- *
- * @type action
- * @title um_when_status_is_set
- * @description Action on user status changed
- * @input_vars
- * [{"var":"$user_id","type":"int","desc":"User ID"}]
- * @change_log
- * ["Since: 2.0"]
- * @usage add_action( 'um_when_status_is_set', 'function_name', 10, 1 );
- * @example
- *
- */
- do_action( 'um_when_status_is_set', um_user( 'ID' ) );
-
- $this->profile['account_status'] = $status;
-
- $this->update_usermeta_info( 'account_status' );
-
- /**
- * UM hook
- *
- * @type action
- * @title um_after_user_status_is_changed_hook
- * @description Action after user status changed
- * @input_vars
- * [{"var":"$user_id","type":"int","desc":"User ID"}]
- * @change_log
- * ["Since: 2.0"]
- * @usage add_action( 'um_after_user_status_is_changed_hook', 'function_name', 10 );
- * @example
- *
- */
- do_action( 'um_after_user_status_is_changed_hook', um_user( 'ID' ) );
-
- /**
- * UM hook
- *
- * @type action
- * @title um_after_user_status_is_changed
- * @description Action after user status changed
- * @input_vars
- * [{"var":"$status","type":"string","desc":"User Status"},
- * {"var":"$user_id","type":"integer","desc":"User ID"}]
- * @change_log
- * ["Since: 2.0"]
- * @usage add_action( 'um_after_user_status_is_changed', 'function_name', 10, 1 );
- * @example
- *
- */
- do_action( 'um_after_user_status_is_changed', $status, um_user( 'ID' ) );
-
+ public function set_status( $status ) {
+ _deprecated_function( __METHOD__, '2.8.7', 'UM()->common()->users()->set_status()' );
+ UM()->common()->users()->set_status( $status, um_user( 'ID' ) );
}
-
/**
* Set user's hash
*/
- function assign_secretkey() {
- /**
- * UM hook
- *
- * @type action
- * @title um_before_user_hash_is_changed
- * @description Action before user hash is changed
- * @change_log
- * ["Since: 2.0"]
- * @usage add_action( 'um_before_user_hash_is_changed', 'function_name', 10 );
- * @example
- *
- */
- do_action( 'um_before_user_hash_is_changed' );
-
- $this->profile['account_secret_hash'] = UM()->validation()->generate();
- $this->update_usermeta_info( 'account_secret_hash' );
-
- $expiry_time = UM()->options()->get( 'activation_link_expiry_time' );
- if ( ! empty( $expiry_time ) && is_numeric( $expiry_time ) ) {
- $this->profile['account_secret_hash_expiry'] = time() + $expiry_time * DAY_IN_SECONDS;
- $this->update_usermeta_info( 'account_secret_hash_expiry' );
- }
-
- /**
- * UM hook
- *
- * @type action
- * @title um_after_user_hash_is_changed
- * @description Action after user hash is changed
- * @change_log
- * ["Since: 2.0"]
- * @usage add_action( 'um_after_user_hash_is_changed', 'function_name', 10 );
- * @example
- *
- */
- do_action( 'um_after_user_hash_is_changed' );
+ public function assign_secretkey() {
+ _deprecated_function( __METHOD__, '2.8.7', 'UM()->common()->users()->assign_secretkey()' );
+ UM()->common()->users()->assign_secretkey( um_user( 'ID' ) );
}
-
/**
* @param \WP_User $userdata
*
@@ -1677,186 +1565,53 @@ if ( ! class_exists( 'um\core\User' ) ) {
/**
* This method approves a user membership and sends them an optional welcome/approval email.
- *
- * @usage user()->approve(); ?>
- *
- * @example Approve a pending user and allow him to sign-in to your site.
-
- user()->approve();
-
- ?>
- *
+ * @param bool $repeat @deprecated
+ * @deprecated 2.8.7
*/
- public function approve( $repeat = true ) {
- $user_id = um_user( 'ID' );
-
- if ( ! $repeat ) {
- $status = get_user_meta( $user_id, 'account_status', true );
- if ( 'approved' === $status ) {
- return;
- }
- }
-
- delete_option( "um_cache_userdata_{$user_id}" );
-
- if ( 'awaiting_admin_review' === um_user( 'account_status' ) ) {
- $userdata = get_userdata( $user_id );
-
- $this->maybe_generate_password_reset_key( $userdata );
-
- UM()->mail()->send( um_user( 'user_email' ), 'approved_email' );
-
- } else {
- //$userdata = get_userdata( $user_id );
- //get_password_reset_key( $userdata );
- UM()->mail()->send( um_user( 'user_email' ), 'welcome_email' );
- }
-
- $this->set_status( 'approved' );
- $this->delete_meta( 'account_secret_hash' );
- $this->delete_meta( 'account_secret_hash_expiry' );
-
- /**
- * UM hook
- *
- * @type action
- * @title um_after_user_is_approved
- * @description Action after user was approved
- * @input_vars
- * [{"var":"$user_id","type":"int","desc":"User ID"}]
- * @change_log
- * ["Since: 2.0"]
- * @usage add_action( 'um_after_user_is_approved', 'function_name', 10, 1 );
- * @example
- *
- */
- do_action( 'um_after_user_is_approved', um_user( 'ID' ) );
+ public function approve( $repeat = true ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found -- deprecated function
+ _deprecated_function( __METHOD__, '2.8.7', 'UM()->common()->users()->approve()' );
+ UM()->common()->users()->approve( um_user( 'ID' ) );
}
-
/**
* Pending email
+ * @deprecated 2.8.7
*/
- function email_pending() {
- $this->assign_secretkey();
- $this->set_status( 'awaiting_email_confirmation' );
-
- //clear all sessions for email confirmation pending users
- $user = \WP_Session_Tokens::get_instance( um_user( 'ID' ) );
- $user->destroy_all();
-
- UM()->mail()->send( um_user( 'user_email' ), 'checkmail_email' );
+ public function email_pending() {
+ _deprecated_function( __METHOD__, '2.8.7', 'UM()->common()->users()->send_activation()' );
+ UM()->common()->users()->send_activation( um_user( 'ID' ) );
}
-
/**
* This method puts a user under manual review by administrator and sends them an optional email.
- *
- * @usage user()->pending(); ?>
- *
- * @example An example of putting a user pending manual review
-
- user()->pending();
-
- ?>
- *
+ * @deprecated 2.8.7
+ * @return void
*/
- function pending() {
- $this->set_status( 'awaiting_admin_review' );
-
- //clear all sessions for awaiting admin confirmation users
- $user = \WP_Session_Tokens::get_instance( um_user( 'ID' ) );
- $user->destroy_all();
-
- UM()->mail()->send( um_user( 'user_email' ), 'pending_email' );
+ public function pending() {
+ _deprecated_function( __METHOD__, '2.8.7', 'UM()->common()->users()->set_as_pending()' );
+ UM()->common()->users()->set_as_pending( um_user( 'ID' ) );
}
-
/**
* This method rejects a user membership and sends them an optional email.
- *
- * @usage user()->reject(); ?>
- *
- * @example Reject a user membership example
-
- user()->reject();
-
- ?>
-
- *
+ * @deprecated 2.8.7
+ * @return void
*/
- function reject() {
- $this->set_status( 'rejected' );
-
- //clear all sessions for rejected users
- $user = \WP_Session_Tokens::get_instance( um_user( 'ID' ) );
- $user->destroy_all();
-
- UM()->mail()->send( um_user( 'user_email' ), 'rejected_email' );
+ public function reject() {
+ _deprecated_function( __METHOD__, '2.8.7', 'UM()->common()->users()->reject()' );
+ UM()->common()->users()->reject( um_user( 'ID' ) );
}
-
/**
* This method deactivates a user membership and sends them an optional email.
- *
- * @usage user()->deactivate(); ?>
- *
- * @example Deactivate a user membership with the following example
-
- user->deactivate();
-
- ?>
- *
+ * @deprecated 2.8.7
+ * @return void
*/
- function deactivate() {
- $this->set_status( 'inactive' );
-
- //clear all sessions for inactive users
- $user = \WP_Session_Tokens::get_instance( um_user( 'ID' ) );
- $user->destroy_all();
-
- /**
- * UM hook
- *
- * @type action
- * @title um_after_user_is_inactive
- * @description Action after user was inactive
- * @input_vars
- * [{"var":"$user_id","type":"int","desc":"User ID"}]
- * @change_log
- * ["Since: 2.0"]
- * @usage add_action( 'um_after_user_is_inactive', 'function_name', 10, 1 );
- * @example
- *
- */
- do_action( 'um_after_user_is_inactive', um_user( 'ID' ) );
-
- UM()->mail()->send( um_user( 'user_email' ), 'inactive_email' );
+ public function deactivate() {
+ _deprecated_function( __METHOD__, '2.8.7', 'UM()->common()->users()->deactivate()' );
+ UM()->common()->users()->deactivate( um_user( 'ID' ) );
}
-
/**
* Delete user
*
@@ -1970,28 +1725,7 @@ if ( ! class_exists( 'um\core\User' ) ) {
function get_admin_actions() {
$items = array();
- /**
- * UM hook
- *
- * @type filter
- * @title um_admin_user_actions_hook
- * @description Extend admin actions for each user
- * @input_vars
- * [{"var":"$actions","type":"array","desc":"Actions for user"}]
- * @change_log
- * ["Since: 2.0"]
- * @usage
- *
- * @example
- *
- */
- $actions = apply_filters( 'um_admin_user_actions_hook', array(), um_profile_id() );
+ $actions = UM()->frontend()->users()->get_actions_list( um_profile_id() );
if ( empty( $actions ) ) {
return $items;
}
@@ -2001,10 +1735,9 @@ if ( ! class_exists( 'um\core\User' ) ) {
array(
'um_action' => $id,
'uid' => um_profile_id(),
+ 'nonce' => wp_create_nonce( $id . um_profile_id() ),
)
);
- /*$url = add_query_arg( 'um_action', $id );
- $url = add_query_arg( 'uid', um_profile_id(), $url );*/
$items[] = '' . esc_html( $arr['label'] ) . '';
}
return $items;
@@ -2356,32 +2089,15 @@ if ( ! class_exists( 'um\core\User' ) ) {
/**
* This method checks if a user exists or not in your site based on the user ID.
*
- * @usage user()->user_exists_by_id( $user_id ); ?>
+ * @deprecated 2.8.7
*
* @param int $user_id A user ID must be passed to check if the user exists
*
* @return bool|int
- *
- * @example Basic Usage
-
- user()->user_exists_by_id( 15 );
- if ( $boolean ) {
- // That user exists
- }
-
- ?>
-
- *
*/
public function user_exists_by_id( $user_id ) {
- $aux = get_userdata( absint( $user_id ) );
- if ( $aux == false ) {
- return false;
- } else {
- return $user_id;
- }
+ _deprecated_function( __METHOD__, '2.8.7', 'UM()->common()->users()::user_exists' );
+ return UM()->common()->users()::user_exists( $user_id ) ? $user_id : false;
}
/**
@@ -2522,7 +2238,6 @@ if ( ! class_exists( 'um\core\User' ) ) {
return $hash_email_address;
}
-
/**
* UM Placeholders for activation link in email
*
@@ -2530,12 +2245,11 @@ if ( ! class_exists( 'um\core\User' ) ) {
*
* @return array
*/
- function add_activation_placeholder( $placeholders ) {
+ public function add_activation_placeholder( $placeholders ) {
$placeholders[] = '{account_activation_link}';
return $placeholders;
}
-
/**
* UM Replace Placeholders for activation link in email
*
@@ -2543,31 +2257,9 @@ if ( ! class_exists( 'um\core\User' ) ) {
*
* @return array
*/
- function add_activation_replace_placeholder( $replace_placeholders ) {
+ public function add_activation_replace_placeholder( $replace_placeholders ) {
$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-v1.php b/includes/core/rest/class-api-v1.php
index a3aee5c2..40a0df97 100644
--- a/includes/core/rest/class-api-v1.php
+++ b/includes/core/rest/class-api-v1.php
@@ -239,7 +239,8 @@ if ( ! class_exists( 'um\core\rest\API_v1' ) ) {
switch ( $data ) {
case 'status':
- UM()->user()->set_status( $value );
+ //UM()->user()->set_status( $value );
+ UM()->common()->users()->set_status( $id, $value );
$response['success'] = __( 'User status has been changed.', 'ultimate-member' );
break;
case 'role':
diff --git a/includes/core/rest/class-api-v2.php b/includes/core/rest/class-api-v2.php
index 3874b827..68cc382c 100644
--- a/includes/core/rest/class-api-v2.php
+++ b/includes/core/rest/class-api-v2.php
@@ -221,7 +221,8 @@ if ( ! class_exists( 'um\core\rest\API_v2' ) ) {
switch ( $data ) {
case 'status':
- UM()->user()->set_status( $value );
+ // UM()->user()->set_status( $value );
+ UM()->common()->users()->set_status( $id, $value );
$response['success'] = __( 'User status has been changed.', 'ultimate-member' );
break;
case 'role':
diff --git a/includes/core/um-actions-core.php b/includes/core/um-actions-core.php
deleted file mode 100644
index 8779fafc..00000000
--- a/includes/core/um-actions-core.php
+++ /dev/null
@@ -1,157 +0,0 @@
-user()->user_exists_by_id( $uid ) ) {
- return;
- }
-
- if ( ! empty( $uid ) && is_super_admin( $uid ) ) {
- wp_die( esc_html__( 'Super administrators can not be modified.', 'ultimate-member' ) );
- }
-
- $role = get_role( UM()->roles()->get_priority_user_role( get_current_user_id() ) );
- $can_edit_users = current_user_can( 'edit_users' ) && $role->has_cap( 'edit_users' );
-
- switch ( $action ) {
- default:
- /**
- * UM hook
- *
- * @type action
- * @title um_action_user_request_hook
- * @description Integration for user actions
- * @input_vars
- * [{"var":"$action","type":"string","desc":"Action for user"},
- * {"var":"$user_id","type":"int","desc":"User ID"}]
- * @change_log
- * ["Since: 2.0"]
- * @usage add_action( 'um_action_user_request_hook', 'function_name', 10, 2 );
- * @example
- *
- */
- do_action( 'um_action_user_request_hook', $action, $uid );
- break;
-
- case 'edit':
- UM()->fields()->editing = true;
- if ( ! um_is_myprofile() ) {
- if ( ! UM()->roles()->um_current_user_can( 'edit', um_profile_id() ) ) {
- exit( wp_redirect( UM()->permalinks()->get_current_url( true ) ) );
- }
- } else {
- if ( ! um_can_edit_my_profile() ) {
- $url = um_edit_my_profile_cancel_uri();
- exit( wp_redirect( $url ) );
- }
- }
- break;
-
- case 'um_switch_user':
- if ( ! current_user_can( 'manage_options' ) ) {
- return;
- }
- UM()->user()->auto_login( $uid );
- exit( wp_redirect( UM()->permalinks()->get_current_url( true ) ) );
- break;
-
- case 'um_reject_membership':
- if ( ! $can_edit_users ) {
- wp_die( esc_html__( 'You do not have permission to make this action.', 'ultimate-member' ) );
- }
-
- um_fetch_user( $uid );
- UM()->user()->reject();
- exit( wp_redirect( UM()->permalinks()->get_current_url( true ) ) );
- break;
-
- case 'um_approve_membership':
- case 'um_reenable':
- if ( ! $can_edit_users ) {
- wp_die( esc_html__( 'You do not have permission to make this action.', 'ultimate-member' ) );
- }
-
- um_fetch_user( $uid );
-
- add_filter( 'um_template_tags_patterns_hook', array( UM()->password(), 'add_placeholder' ), 10, 1 );
- add_filter( 'um_template_tags_replaces_hook', array( UM()->password(), 'add_replace_placeholder' ), 10, 1 );
-
- UM()->user()->approve();
- exit( wp_redirect( UM()->permalinks()->get_current_url( true ) ) );
- break;
-
- case 'um_put_as_pending':
- if ( ! $can_edit_users ) {
- wp_die( esc_html__( 'You do not have permission to make this action.', 'ultimate-member' ) );
- }
-
- um_fetch_user( $uid );
- UM()->user()->pending();
- exit( wp_redirect( UM()->permalinks()->get_current_url( true ) ) );
- break;
-
- case 'um_resend_activation':
- if ( ! $can_edit_users ) {
- wp_die( esc_html__( 'You do not have permission to make this action.', 'ultimate-member' ) );
- }
-
- add_filter( 'um_template_tags_patterns_hook', array( UM()->user(), 'add_activation_placeholder' ), 10, 1 );
- add_filter( 'um_template_tags_replaces_hook', array( UM()->user(), 'add_activation_replace_placeholder' ), 10, 1 );
-
- um_fetch_user( $uid );
- UM()->user()->email_pending();
- exit( wp_redirect( UM()->permalinks()->get_current_url( true ) ) );
- break;
-
- case 'um_deactivate':
- if ( ! $can_edit_users ) {
- wp_die( esc_html__( 'You do not have permission to make this action.', 'ultimate-member' ) );
- }
-
- um_fetch_user( $uid );
- UM()->user()->deactivate();
- exit( wp_redirect( UM()->permalinks()->get_current_url( true ) ) );
- break;
-
- case 'um_delete':
- if ( ! UM()->roles()->um_current_user_can( 'delete', $uid ) ) {
- wp_die( esc_html__( 'You do not have permission to delete this user.', 'ultimate-member' ) );
- }
-
- um_fetch_user( $uid );
- UM()->user()->delete();
- exit( wp_redirect( UM()->permalinks()->get_current_url( true ) ) );
- break;
-
- }
-}
-add_action( 'template_redirect', 'um_action_request_process', 10000 );
diff --git a/includes/core/um-actions-register.php b/includes/core/um-actions-register.php
index d79718c4..f2c65e92 100644
--- a/includes/core/um-actions-register.php
+++ b/includes/core/um-actions-register.php
@@ -11,7 +11,7 @@ if ( ! defined( 'ABSPATH' ) ) {
function um_post_registration_approved_hook( $user_id ) {
um_fetch_user( $user_id );
- UM()->user()->approve();
+ UM()->common()->users()->approve( $user_id );
}
add_action( 'um_post_registration_approved_hook', 'um_post_registration_approved_hook' );
@@ -23,7 +23,7 @@ add_action( 'um_post_registration_approved_hook', 'um_post_registration_approved
function um_post_registration_checkmail_hook( $user_id ) {
um_fetch_user( $user_id );
- UM()->user()->email_pending();
+ UM()->common()->users()->send_activation( $user_id );
}
add_action( 'um_post_registration_checkmail_hook', 'um_post_registration_checkmail_hook' );
@@ -35,7 +35,7 @@ add_action( 'um_post_registration_checkmail_hook', 'um_post_registration_checkma
function um_post_registration_pending_hook( $user_id ) {
um_fetch_user( $user_id );
- UM()->user()->pending();
+ UM()->common()->users()->set_as_pending( $user_id );
}
add_action( 'um_post_registration_pending_hook', 'um_post_registration_pending_hook' );
@@ -64,7 +64,8 @@ function um_after_insert_user( $user_id, $args, $form_data = null ) {
um_fetch_user( $user_id );
$status = um_user( 'status' );
}
- UM()->user()->set_status( $status );
+ // UM()->user()->set_status( $status );
+ UM()->common()->users()->set_status( $user_id, $status );
// Create user uploads directory.
UM()->uploader()->get_upload_user_base_dir( $user_id, true );
diff --git a/includes/core/um-filters-user.php b/includes/core/um-filters-user.php
index 2ff9e293..4d0eb375 100644
--- a/includes/core/um-filters-user.php
+++ b/includes/core/um-filters-user.php
@@ -3,61 +3,6 @@ if ( ! defined( 'ABSPATH' ) ) {
exit;
}
-/**
- * Main admin user actions.
- *
- * @param array $actions
- * @param int $user_id
- *
- * @return array
- */
-function um_admin_user_actions_hook( $actions, $user_id ) {
- um_fetch_user( $user_id );
-
- $role = get_role( UM()->roles()->get_priority_user_role( get_current_user_id() ) );
-
- $can_edit_users = null !== $role && current_user_can( 'edit_users' ) && $role->has_cap( 'edit_users' );
- if ( $can_edit_users ) {
- $account_status = um_user( 'account_status' );
-
- if ( 'awaiting_admin_review' === $account_status ) {
- $actions['um_approve_membership'] = array( 'label' => __( 'Approve Membership', 'ultimate-member' ) );
- $actions['um_reject_membership'] = array( 'label' => __( 'Reject Membership', 'ultimate-member' ) );
- }
-
- if ( 'rejected' === $account_status ) {
- $actions['um_approve_membership'] = array( 'label' => __( 'Approve Membership', 'ultimate-member' ) );
- }
-
- if ( 'approved' === $account_status ) {
- $actions['um_put_as_pending'] = array( 'label' => __( 'Put as Pending Review', 'ultimate-member' ) );
- }
-
- if ( 'awaiting_email_confirmation' === $account_status ) {
- $actions['um_resend_activation'] = array( 'label' => __( 'Resend Activation Email', 'ultimate-member' ) );
- }
-
- if ( 'inactive' !== $account_status ) {
- $actions['um_deactivate'] = array( 'label' => __( 'Deactivate this account', 'ultimate-member' ) );
- }
-
- if ( 'inactive' === $account_status ) {
- $actions['um_reenable'] = array( 'label' => __( 'Reactivate this account', 'ultimate-member' ) );
- }
- }
-
- if ( UM()->roles()->um_current_user_can( 'delete', $user_id ) ) {
- $actions['um_delete'] = array( 'label' => __( 'Delete this user', 'ultimate-member' ) );
- }
-
- if ( current_user_can( 'manage_options' ) && ! is_super_admin( $user_id ) ) {
- $actions['um_switch_user'] = array( 'label' => __( 'Login as this user', 'ultimate-member' ) );
- }
-
- return $actions;
-}
-add_filter( 'um_admin_user_actions_hook', 'um_admin_user_actions_hook', 10, 2 );
-
/**
* Filter user basename.
*
diff --git a/includes/frontend/class-actions-listener.php b/includes/frontend/class-actions-listener.php
new file mode 100644
index 00000000..389f7a21
--- /dev/null
+++ b/includes/frontend/class-actions-listener.php
@@ -0,0 +1,206 @@
+common()->users()::user_exists( $user_id ) ) {
+ return;
+ }
+
+ if ( get_current_user_id() === $user_id ) {
+ return;
+ }
+
+ if ( ! empty( $user_id ) && is_super_admin( $user_id ) ) {
+ wp_die( esc_html__( 'Super administrators can not be modified.', 'ultimate-member' ) );
+ }
+
+ $action = sanitize_key( $_REQUEST['um_action'] );
+ // phpcs:enable WordPress.Security.NonceVerification -- there is nonce verification below for each case
+ switch ( $action ) {
+ case 'approve_user':
+ if ( ! wp_verify_nonce( $_REQUEST['nonce'], "approve_user{$user_id}" ) ) {
+ wp_die( esc_html__( 'The link you followed has expired.', 'ultimate-member' ) );
+ }
+
+ if ( ! UM()->common()->users()->can_current_user_edit_user( $user_id ) ) {
+ wp_die( esc_html__( 'You do not have permission to edit this user.', 'ultimate-member' ) );
+ }
+
+ $result = UM()->common()->users()->approve( $user_id );
+ if ( ! $result ) {
+ wp_die( esc_html__( 'Something went wrong.', 'ultimate-member' ) );
+ }
+
+ um_safe_redirect( UM()->permalinks()->get_current_url( true ) );
+ exit;
+ case 'reactivate_user':
+ if ( ! wp_verify_nonce( $_REQUEST['nonce'], "reactivate_user{$user_id}" ) ) {
+ wp_die( esc_html__( 'The link you followed has expired.', 'ultimate-member' ) );
+ }
+
+ if ( ! UM()->common()->users()->can_current_user_edit_user( $user_id ) ) {
+ wp_die( esc_html__( 'You do not have permission to edit this user.', 'ultimate-member' ) );
+ }
+
+ $result = UM()->common()->users()->reactivate( $user_id );
+ if ( ! $result ) {
+ wp_die( esc_html__( 'Something went wrong.', 'ultimate-member' ) );
+ }
+
+ um_safe_redirect( UM()->permalinks()->get_current_url( true ) );
+ exit;
+ case 'put_user_as_pending':
+ if ( ! wp_verify_nonce( $_REQUEST['nonce'], "put_user_as_pending{$user_id}" ) ) {
+ wp_die( esc_html__( 'The link you followed has expired.', 'ultimate-member' ) );
+ }
+
+ if ( ! UM()->common()->users()->can_current_user_edit_user( $user_id ) ) {
+ wp_die( esc_html__( 'You do not have permission to edit this user.', 'ultimate-member' ) );
+ }
+
+ $result = UM()->common()->users()->set_as_pending( $user_id );
+ if ( ! $result ) {
+ wp_die( esc_html__( 'Something went wrong.', 'ultimate-member' ) );
+ }
+
+ um_safe_redirect( UM()->permalinks()->get_current_url( true ) );
+ exit;
+ case 'resend_user_activation':
+ if ( ! wp_verify_nonce( $_REQUEST['nonce'], "resend_user_activation{$user_id}" ) ) {
+ wp_die( esc_html__( 'The link you followed has expired.', 'ultimate-member' ) );
+ }
+
+ if ( ! UM()->common()->users()->can_current_user_edit_user( $user_id ) ) {
+ wp_die( esc_html__( 'You do not have permission to edit this user.', 'ultimate-member' ) );
+ }
+
+ $result = UM()->common()->users()->send_activation( $user_id );
+ if ( ! $result ) {
+ wp_die( esc_html__( 'Something went wrong.', 'ultimate-member' ) );
+ }
+
+ um_safe_redirect( UM()->permalinks()->get_current_url( true ) );
+ exit;
+ case 'reject_user':
+ if ( ! wp_verify_nonce( $_REQUEST['nonce'], "reject_user{$user_id}" ) ) {
+ wp_die( esc_html__( 'The link you followed has expired.', 'ultimate-member' ) );
+ }
+
+ if ( ! UM()->common()->users()->can_current_user_edit_user( $user_id ) ) {
+ wp_die( esc_html__( 'You do not have permission to edit this user.', 'ultimate-member' ) );
+ }
+
+ $result = UM()->common()->users()->reject( $user_id );
+ if ( ! $result ) {
+ wp_die( esc_html__( 'Something went wrong.', 'ultimate-member' ) );
+ }
+
+ um_safe_redirect( UM()->permalinks()->get_current_url( true ) );
+ exit;
+ case 'deactivate_user':
+ if ( ! wp_verify_nonce( $_REQUEST['nonce'], "deactivate_user{$user_id}" ) ) {
+ wp_die( esc_html__( 'The link you followed has expired.', 'ultimate-member' ) );
+ }
+
+ if ( ! UM()->common()->users()->can_current_user_edit_user( $user_id ) ) {
+ wp_die( esc_html__( 'You do not have permission to edit this user.', 'ultimate-member' ) );
+ }
+
+ $result = UM()->common()->users()->deactivate( $user_id );
+ if ( ! $result ) {
+ wp_die( esc_html__( 'Something went wrong.', 'ultimate-member' ) );
+ }
+
+ um_safe_redirect( UM()->permalinks()->get_current_url( true ) );
+ exit;
+ case 'switch_user':
+ if ( ! current_user_can( 'manage_options' ) ) {
+ return;
+ }
+
+ if ( ! wp_verify_nonce( $_REQUEST['nonce'], "switch_user{$user_id}" ) ) {
+ wp_die( esc_html__( 'The link you followed has expired.', 'ultimate-member' ) );
+ }
+
+ UM()->user()->auto_login( $user_id );
+
+ um_safe_redirect( UM()->permalinks()->get_current_url( true ) );
+ exit;
+ case 'delete':
+ if ( ! wp_verify_nonce( $_REQUEST['nonce'], "delete{$user_id}" ) ) {
+ wp_die( esc_html__( 'The link you followed has expired.', 'ultimate-member' ) );
+ }
+
+ if ( ! UM()->roles()->um_current_user_can( 'delete', $user_id ) ) {
+ wp_die( esc_html__( 'You do not have permission to delete this user.', 'ultimate-member' ) );
+ }
+
+ um_fetch_user( $user_id );
+ UM()->user()->delete();
+
+ um_safe_redirect( UM()->permalinks()->get_current_url( true ) );
+ exit;
+ default:
+ /**
+ * Fires to handle 3rd-party user actions from User Profile.
+ *
+ * Note: Please verify nonce and redirect after action individually in 3rd-party handler.
+ *
+ * @since 1.3.x
+ * @hook um_action_user_request_hook
+ *
+ * @param {string} $action User action key.
+ * @param {int} $user_id User ID.
+ *
+ * @example Update `some_custom_meta` user meta on `my_custom_action`.
+ * function um_action_user_request_hook( $action, $user_id ) {
+ * if ( 'my_custom_action' === $action ) {
+ * update_user_meta( $user_id, 'some_custom_meta', true );
+ * }
+ * }
+ * add_action( 'um_action_user_request_hook', 'um_action_user_request_hook', 10, 2 );
+ */
+ do_action( 'um_action_user_request_hook', $action, $user_id );
+ break;
+ }
+ }
+ }
+}
diff --git a/includes/frontend/class-init.php b/includes/frontend/class-init.php
index b34cd983..1d3d460f 100644
--- a/includes/frontend/class-init.php
+++ b/includes/frontend/class-init.php
@@ -20,9 +20,25 @@ if ( ! class_exists( 'um\frontend\Init' ) ) {
* @used-by \UM::includes()
*/
public function includes() {
+ $this->actions_listener();
$this->enqueue();
$this->modal();
$this->secure();
+ $this->user_profile();
+ $this->users();
+ }
+
+ /**
+ * @since 2.8.7
+ *
+ * @return Actions_Listener
+ */
+ public function actions_listener() {
+ if ( empty( UM()->classes['um\frontend\actions_listener'] ) ) {
+ UM()->classes['um\frontend\actions_listener'] = new Actions_Listener();
+ }
+
+ return UM()->classes['um\frontend\actions_listener'];
}
/**
@@ -62,5 +78,29 @@ if ( ! class_exists( 'um\frontend\Init' ) ) {
}
return UM()->classes['um\frontend\secure'];
}
+
+ /**
+ * @since 2.8.7
+ *
+ * @return User_Profile
+ */
+ public function user_profile() {
+ if ( empty( UM()->classes['um\frontend\user_profile'] ) ) {
+ UM()->classes['um\frontend\user_profile'] = new User_Profile();
+ }
+ return UM()->classes['um\frontend\user_profile'];
+ }
+
+ /**
+ * @since 2.8.7
+ *
+ * @return Users
+ */
+ public function users() {
+ if ( empty( UM()->classes['um\frontend\users'] ) ) {
+ UM()->classes['um\frontend\users'] = new Users();
+ }
+ return UM()->classes['um\frontend\users'];
+ }
}
}
diff --git a/includes/frontend/class-user-profile.php b/includes/frontend/class-user-profile.php
new file mode 100644
index 00000000..f77cd3cc
--- /dev/null
+++ b/includes/frontend/class-user-profile.php
@@ -0,0 +1,69 @@
+common()->users()::user_exists( $uid ) ) {
+ return;
+ }
+
+ if ( ! empty( $uid ) && is_super_admin( $uid ) ) {
+ wp_die( esc_html__( 'Super administrators can not be modified.', 'ultimate-member' ) );
+ }
+
+ UM()->fields()->editing = true;
+
+ if ( ! um_is_myprofile() && ! UM()->roles()->um_current_user_can( 'edit', um_profile_id() ) ) {
+ um_safe_redirect( UM()->permalinks()->get_current_url( true ) );
+ exit;
+ }
+
+ if ( ! um_can_edit_my_profile() ) {
+ um_safe_redirect( um_edit_my_profile_cancel_uri() );
+ exit;
+ }
+ }
+ }
+}
diff --git a/includes/frontend/class-users.php b/includes/frontend/class-users.php
new file mode 100644
index 00000000..585cbcd9
--- /dev/null
+++ b/includes/frontend/class-users.php
@@ -0,0 +1,81 @@
+roles()->get_priority_user_role( get_current_user_id() );
+ $role = get_role( $priority_role );
+
+ $can_edit_users = null !== $role && current_user_can( 'edit_users' ) && $role->has_cap( 'edit_users' );
+ if ( $can_edit_users ) {
+ if ( UM()->common()->users()->can_be_approved( $user_id ) ) {
+ $actions['approve_user'] = array( 'label' => __( 'Approve Membership', 'ultimate-member' ) );
+ }
+ if ( UM()->common()->users()->can_be_reactivated( $user_id ) ) {
+ $actions['reactivate_user'] = array( 'label' => __( 'Reactivate this account', 'ultimate-member' ) );
+ }
+ if ( UM()->common()->users()->can_be_set_as_pending( $user_id ) ) {
+ $actions['put_user_as_pending'] = array( 'label' => __( 'Put as Pending Review', 'ultimate-member' ) );
+ }
+ if ( UM()->common()->users()->can_activation_send( $user_id ) ) {
+ $actions['resend_user_activation'] = array( 'label' => __( 'Resend Activation Email', 'ultimate-member' ) );
+ }
+ if ( UM()->common()->users()->can_be_rejected( $user_id ) ) {
+ $actions['reject_user'] = array( 'label' => __( 'Reject Membership', 'ultimate-member' ) );
+ }
+ if ( UM()->common()->users()->can_be_deactivated( $user_id ) ) {
+ $actions['deactivate_user'] = array( 'label' => __( 'Deactivate this account', 'ultimate-member' ) );
+ }
+ }
+
+ if ( UM()->roles()->um_current_user_can( 'delete', $user_id ) ) {
+ $actions['delete'] = array( 'label' => __( 'Delete this user', 'ultimate-member' ) );
+ }
+
+ if ( current_user_can( 'manage_options' ) && ! is_super_admin( $user_id ) ) {
+ $actions['switch_user'] = array( 'label' => __( 'Login as this user', 'ultimate-member' ) );
+ }
+
+ /**
+ * Filters users actions list in Ultimate Member frontend.
+ *
+ * @since 1.3.x
+ * @hook um_admin_user_actions_hook
+ *
+ * @param {array} $actions CPT keys.
+ * @param {int} $user_id User ID.
+ *
+ * @return {array} CPT keys.
+ *
+ * @example Add `um_custom_action` action to the users actions list on frontend.
+ * function um_custom_admin_user_actions_hook( $actions, $user_id ) {
+ * $actions['um_custom_action'] = array( 'label' => 'um_custom_action_label' );
+ * return $actions;
+ * }
+ * add_filter( 'um_admin_user_actions_hook', 'um_custom_admin_user_actions_hook', 10, 2 );
+ */
+ return apply_filters( 'um_admin_user_actions_hook', $actions, $user_id );
+ }
+}
diff --git a/includes/um-deprecated-hooks.php b/includes/um-deprecated-hooks.php
index 86a01327..3231ab27 100644
--- a/includes/um-deprecated-hooks.php
+++ b/includes/um-deprecated-hooks.php
@@ -45,3 +45,53 @@ if ( ! defined( 'ABSPATH' ) ) {
* }
* add_filter( 'um_language_file', 'my_um_language_file' );
*/
+
+/**
+ * Fires after user status changed.
+ *
+ * @param {int} $user_id User ID.
+ *
+ * @since 1.3.x
+ * @depecated 2.8.7 use action hook `um_after_user_status_is_changed` instead.
+ * @hook um_after_user_status_is_changed_hook
+ */
+
+/**
+ * Fires just before User status is changed.
+ *
+ * @since 1.3.x
+ * @depecated 2.8.7 use action hook `um_before_user_status_is_set` instead.
+ * @hook um_when_status_is_set
+ *
+ * @param {int} $user_id User ID. Since 2.0
+ */
+
+/**
+ * Fires for handle admin user_action scripts.
+ *
+ * @since 1.3.x
+ * @depecated 2.8.7 WordPress native `handle_bulk_actions-users` hook is used. Use action hook `um_handle_bulk_actions-users-{$current_action}` for custom user bulk actions instead.
+ * @hook um_admin_user_action_hook
+ *
+ * @param {string} $bulk_action Bulk action key
+ */
+
+/**
+ * Fires for handle admin user_action scripts.
+ * Where $bulk_action is a bulk action key
+ *
+ * @since 1.3.x
+ * @depecated 2.8.7 WordPress native `handle_bulk_actions-users` hook is used. Use action hook `um_handle_bulk_actions-users-{$current_action}` for custom user bulk actions instead.
+ * @hook um_admin_user_action_{$bulk_action}_hook
+ */
+
+/**
+ * Fires for handle custom admin user_action scripts.
+ * Where $action is a bulk action key
+ *
+ * @since 1.3.x
+ * @depecated 2.8.7 WordPress native `handle_bulk_actions-users` hook is used. Use action hook `um_handle_bulk_actions-users-{$current_action}` for custom user bulk actions instead.
+ * @hook um_admin_custom_hook_{$action}
+ *
+ * @param {int} $user_id User ID.
+ */
diff --git a/includes/um-short-functions.php b/includes/um-short-functions.php
index b4179d30..280b3714 100644
--- a/includes/um-short-functions.php
+++ b/includes/um-short-functions.php
@@ -1579,7 +1579,7 @@ function um_can_view_field( $data ) {
/**
* Checks if user can view profile
- *
+ * @todo make the function review. Maybe rewrite it.
* @param int $user_id
*
* @return bool
diff --git a/ultimate-member.php b/ultimate-member.php
index ea2c7aa5..c24ef586 100644
--- a/ultimate-member.php
+++ b/ultimate-member.php
@@ -3,7 +3,7 @@
* Plugin Name: Ultimate Member
* Plugin URI: http://ultimatemember.com/
* Description: The easiest way to create powerful online communities and beautiful user profiles with WordPress
- * Version: 2.8.7-alpha
+ * Version: 2.8.7
* Author: Ultimate Member
* Author URI: http://ultimatemember.com/
* Text Domain: ultimate-member