WARNING: Ensure that you\'ve created a full backup of your site as your restoration point before changing anything on your site with our recommendations.
';
+ if ( $suspicious_accounts_count > 0 ) {
+ $lock_register_forms_url = admin_url( 'admin.php?page=um_options&tab=secure&um_secure_lock_register_forms=1&_wpnonce=' . wp_create_nonce( 'um_secure_lock_register_forms' ) );
+ $content .= $br . '1. Please temporarily lock all your active Register forms. Click here to lock them now. You can unblock the Register forms later. Just go to Ultimate Member > Settings > Secure > uncheck the option "Lock All Register Forms".';
+ $content .= $br . $br;
+ $suspicious_accounts_url = admin_url( 'users.php?um_status=inactive' );
+
+ if ( $might_affected_users->get_total() > 0 ) {
+ $od = gmdate( 'F d, Y', $oldest_date );
+ $nd = gmdate( 'F d, Y', $newest_date );
+ if ( $od !== $nd ) {
+ $suspicious_accounts_url = admin_url( 'users.php?um_secure_date_from=' . $oldest_date . '&um_secure_date_to=' . $newest_date );
+ } else {
+ $suspicious_accounts_url = admin_url( 'users.php?um_secure_date_from=' . $oldest_date );
+ }
+ }
+
+ $content .= '2. Review all suspicious accounts and delete them completely. Click here to review accounts.';
+ $content .= $br . $br;
+
+ $nonce = wp_create_nonce( 'um-secure-expire-session-nonce' );
+ $destroy_all_sessions_url = admin_url( '?um_secure_expire_all_sessions=1&_wpnonce=' . esc_attr( $nonce ) . '&except_me=1' );
+ $content .= '4. If accounts are suspicious to you, please destroy all user sessions to logout active users on your site. Click here to Destroy Sessions now';
+
+ $content .= $br . $br;
+ $content .= '4. Run a complete scan on your site using third-party Security plugins such as WPScan/Jetpack Protect or WordFence Security.';
+
+ $content .= $br . $br;
+ $nonce = wp_create_nonce( 'um-secure-enable-reset-pass-nonce' );
+ $reset_pass_sessions_url = admin_url( '?um_secure_enable_reset_password=1&_wpnonce=' . esc_attr( $nonce ) . '&except_me=1' );
+
+ $content .= '5. Force users to Reset their Passwords. Click here to enable this option. When this option is enabled, users will be asked to reset their passwords(one-time) on the next login in the UM Login form.';
+ $content .= $br . $br;
+
+ $content .= '6. Once your site is secured, please create or enable Daily Backups of your server/site. You can contact your hosting provider to assist you on this matter.';
+ $content .= $br . $br;
+
+ $content .= '👇 MORE RECOMMENDATIONS BELOW.';
+ }
+
+ $content .= $br . $br . 'Review & Resolve Issues with Site Health Check tool';
+ $content .= $br . __( 'Site Health is a tool in WordPress that helps you monitor how your site is doing. It shows critical information about your WordPress configuration and items that require your attention.', 'ultimate-member' );
+ if ( $site_health_issues_total > 0 ) {
+ $content .= $br . $flag . sprintf( /* translators: %d issue in the Site Health status */ _n( 'There\s %d issue in the Site Health status', 'There are %d issues in the Site Health status', $site_health_issues_total ), $site_health_issues_total );
+ $content .= ': Review Site Health Status';
+ } else {
+ $content .= $br . $check . __( 'There are no issues found in the Site Health status', 'ultimate-member' );
+ }
+
+ $content .= $br . $br . 'Default WP Register Form';
+ if ( get_option( 'users_can_register' ) ) {
+ $content .= $br . $flag . 'The default WordPress Register form is enabled. If you\'re getting Spam User Registrations, we recommend that you enable a Challenge-Response plugin such as our Ultimate Member - ReCaptcha extension.';
+ $content .= $br;
+ } else {
+ $content .= $br . $check . 'The default WordPress Register form is disabled.' . $br;
+ }
+
+ $content .= $br . 'Block Disposable Email Addresses/Domains';
+ if ( empty( UM()->options()->get( 'blocked_emails' ) ) ) {
+ $content .= $br . $flag . 'You are not blocking email addresses or disposable email domains that are mostly used for Spam Account Registrations. You can get the list of disposable email domains from this repository and then add them to Blocked Email Addresses options.';
+ $content .= $br;
+ } else {
+ $content .= $br . $check . 'Blocked Emails option is already set.';
+ $content .= $br;
+ }
+
+ $content .= $br . 'Manage User Roles & Capabilities';
+ if ( absint( $scan_details['total_all_affected_users'] ) > 0 ) {
+ $count_flagged_caps = $scan_details['total_all_cap_flagged'];
+ $count_users = $scan_details['total_all_affected_users'];
+ $affected_caps = $option['affected_caps'];
+ $affected_roles = array();
+
+ $all_roles = $wp_roles->roles;
+ $editable_roles = apply_filters( 'editable_roles', $all_roles );
+ foreach ( $affected_caps as $cap ) {
+ foreach ( $editable_roles as $role_key => $role ) {
+ if ( in_array( $cap, array_keys( $role['capabilities'] ), true ) ) {
+ $affected_roles[ $role_key ] = $role['name'];
+ }
+ }
+ }
+ $content .= $br . $flag . 'We have found ' . sprintf( /* translators: */ _n( ' %d user account', ' %d user accounts ', $count_users, 'ultimate-member' ), $count_users );
+ $content .= sprintf( /* translators: */ _n( ' affected by %d capability selected in the Banned Administrative Capabilities.', ' affected by one of the %d capabilities selected in the Banned Administrative Capabilities.', $count_flagged_caps, 'ultimate-member' ), $count_flagged_caps );
+
+ $content .= $br . '- ' . implode( ' - ', $affected_caps );
+
+ $content .= $br . $br . 'The flagged capabilities are related to the following roles: ' . $br . ' - ' . implode( ' - ', array_values( $affected_roles ) );
+
+ $content .= $br . $br . 'The affected user accounts will be flagged as suspicious when they update their Profile/Account. If you are not using these capabilities, you may remove them from the roles in the User Role settings. If the roles are not created via Ultimate Member > User Roles, you can use a third-party plugin to modify the role capability.';
+ $content .= $br . $br . 'We strongly recommend that you never assign roles with the same capabilities as your administrators for your members/users and that may allow them to access the admin-side features and functionalities of your WordPress site.';
+ } else {
+ $content .= $br . $check . 'Roles & Capabilities are all secured. No users are using the same capabilities as your administrators.';
+ }
+
+ $content .= $br . $br . 'Require Strong Passwords';
+ if ( ! UM()->options()->get( 'require_strongpass' ) ) {
+ $content .= $br . $flag . 'We recommend that you enable and require "Strong Password" feature for all the Register, Reset Password & Account forms.';
+ $content .= $br . ' Click here to enable.';
+ } else {
+ $content .= $br . $check . 'Your forms are already configured to require of using strong passwords.';
+ }
+
+ $content .= $br . $br . 'Secure Site\'s Connection';
+ if ( ! isset( $_SERVER['HTTPS'] ) || 'on' !== $_SERVER['HTTPS'] ) {
+ $content .= $br . $flag . 'Your site cannot provide a secure connection. Please contact your hosting provider to enable SSL certifications on your server.';
+ } else {
+ $content .= $br . $check . 'Your site provides a secure connection with SSL.';
+ }
+
+ $content .= $br . $br . 'Install Challenge-Response plugin to Login & Register Forms';
+ if ( ! array_key_exists( 'um-recaptcha/um-recaptcha.php', $all_plugins ) ) {
+ $content .= $br . $flag . 'We recommend that you install and enable ReCaptcha to your Reset Password, Login & Register forms.';
+ } else {
+ if ( in_array( 'um-recaptcha/um-recaptcha.php', $active_plugins, true ) ) {
+ $content .= $br . $check . 'Ultimate Member ReCaptcha is actived.';
+ $um_forms = get_posts( 'post_type=um_form&numberposts=-1&fields=ids' );
+ foreach ( $um_forms as $fid ) {
+ switch ( get_post_meta( $fid, '_um_mode', true ) ) {
+ case 'register':
+ $has_captcha = absint( get_post_meta( $fid, '_um_register_g_recaptcha_status', true ) );
+ $content .= $br . ' - Register: ' . get_the_title( $fid ) . ' recaptcha ' . ( 1 === $has_captcha ? ' is enabled ' . $check : 'is disabled ' . $flag );
+ break;
+ case 'login':
+ $has_captcha = absint( get_post_meta( $fid, '_um_login_g_recaptcha_status', true ) );
+ $content .= $br . ' - Login: ' . get_the_title( $fid ) . ' recaptcha ' . ( 1 === $has_captcha ? ' is enabled ' . $check : 'is disabled ' . $flag );
+ break;
+ }
+ }
+ $reset_pass_form = absint( UM()->options()->get( 'g_recaptcha_password_reset' ) );
+ $content .= $br . ' - Reset Password Form\'s recaptcha ' . ( 1 === $reset_pass_form ? ' is enabled ' . $check : 'is disabled ' . $flag );
+
+ } elseif ( array_key_exists( 'um-recaptcha/um-recaptcha.php', $all_plugins ) ) {
+ $content .= $br . $flag . 'Ultimate Member ReCaptcha is installed but not activated.';
+ } else {
+ $content .= $br . $flag . 'We recommend that you install and enable ReCaptcha to Login & Register forms.';
+ }
+ }
+
+ $update_plugins = get_site_transient( 'update_plugins' );
+ $update_themes = get_site_transient( 'update_themes' );
+ $update_wp_core = get_site_transient( 'update_core' );
+ global $wp_version;
+ $content .= $br . $br . 'Keep Themes & Plugins up to date.';
+ $content .= $br . __( 'It is important that you update your themes/plugins if the theme/plugin creators update is aimed at fixing security, bug and vulnerability issues. It is not a good idea to ignore available updates as this may give hackers an advantage when trying to access your website.', 'ultimate-member' );
+
+ if ( isset( $update_plugins->response ) && ! empty( $update_plugins->response ) ) {
+ $content .= $br . $br . $flag . sprintf( /* translators: */ _n( 'There\'s %d plugin that requires an update.', 'There are %d plugins that require updates', count( $update_plugins->response ), 'ultimate-member' ), count( $update_plugins->response ) ) . ' Update Plugins Now';
+ foreach ( $update_plugins->response as $plugin_name => $data ) {
+ $content .= $br . ' - ' . $plugin_name;
+ }
+ } else {
+ $content .= $br . $br . $check . __( 'Plugins are up to date.', 'ultimate-member' );
+ }
+
+ if ( isset( $update_themes->response ) && ! empty( $update_themes->response ) ) {
+ $content .= $br . $br . $flag . sprintf( /* translators: */ _n( 'There\'s %d theme that requires an update.', 'There are %d themes that require updates', count( $update_plugins->response ), 'ultimate-member' ), count( $update_plugins->response ) ) . ' Update Themes Now';
+ foreach ( $update_themes->response as $theme_name => $data ) {
+ $content .= $br . ' - ' . $theme_name;
+ }
+ } else {
+ $content .= $br . $br . $check . __( 'Themes are up to date.', 'ultimate-member' );
+ }
+
+ if ( isset( $update_themes->current ) && $wp_version !== $update_themes->current ) {
+ $content .= $br . $br . $flag . __( 'There\'s a new version of WordPress.', 'ultimate-member' ) . 'Update WordPress Now';
+ } else {
+ $content .= $br . $br . $check . __( 'You\'re using the latest version of WordPress', 'ultimate-member' ) . '(' . esc_attr( $wp_version ) . ')';
+ }
+
+ $content .= $br . $br . __( 'That\'s all. If you have any recommendation on how to secure your site or have questions, please contact us on our feedback page. ', 'ultimate-member' );
+
+ update_option( 'um_secure_scan_result_content', $content );
+
+ return $content;
+ }
+}
diff --git a/includes/class-config.php b/includes/class-config.php
index 903b4515..26259166 100644
--- a/includes/class-config.php
+++ b/includes/class-config.php
@@ -195,7 +195,6 @@ if ( ! class_exists( 'um\Config' ) ) {
'_um_secondary_color',
);
-
/**
* UM hook
*
@@ -496,10 +495,18 @@ if ( ! class_exists( 'um\Config' ) ) {
'body' => '{display_name} has just deleted their {site_name} account.',
'description' => __('Whether to receive notification when an account is deleted','ultimate-member'),
'recipient' => 'admin'
- )
+ ),
+ 'suspicious-activity' => array(
+ 'key' => 'suspicious-activity',
+ 'title' => __( 'Secure: Suspicious Account Activity', 'ultimate-member' ),
+ 'subject' => __( '[{site_name}] Suspicious Account Activity', 'ultimate-member' ),
+ 'body' => 'This is to inform you that there are suspicious activities with the following accounts: {user_profile_link}',
+ 'description' => __( 'Whether to receive notification when suspicious account activity is detected.', 'ultimate-member' ),
+ 'recipient' => 'admin',
+ 'default_active' => true,
+ ),
) );
-
//settings defaults
$this->settings_defaults = array(
'restricted_access_post_metabox' => array( 'post' => 1, 'page' => 1 ),
@@ -559,9 +566,9 @@ if ( ! class_exists( 'um\Config' ) ) {
'form_asterisk' => 0,
'profile_title' => '{display_name} | {site_name}',
'profile_desc' => '{display_name} is on {site_name}. Join {site_name} to view {display_name}\'s profile',
- 'admin_email' => get_bloginfo('admin_email'),
- 'mail_from' => get_bloginfo('name'),
- 'mail_from_addr' => get_bloginfo('admin_email'),
+ 'admin_email' => get_bloginfo( 'admin_email' ),
+ 'mail_from' => get_bloginfo( 'name' ),
+ 'mail_from_addr' => get_bloginfo( 'admin_email' ),
'email_html' => 1,
'image_orientation_by_exif' => 0,
'image_compression' => 60,
@@ -576,6 +583,12 @@ if ( ! class_exists( 'um\Config' ) ) {
'profile_show_html_bio' => 0,
'profile_noindex' => 0,
'activation_link_expiry_time' => '',
+ 'lock_register_forms' => false,
+ 'display_login_form_notice' => false,
+ 'secure_ban_admins_accounts' => false,
+ 'banned_capabilities' => array( 'manage_options', 'promote_users', 'level_10' ),
+ 'secure_notify_admins_banned_accounts' => false,
+ 'secure_notify_admins_banned_accounts__interval' => 'instant',
);
add_filter( 'um_get_tabs_from_config', '__return_true' );
diff --git a/includes/class-functions.php b/includes/class-functions.php
index 0a1aed80..dabefd4e 100644
--- a/includes/class-functions.php
+++ b/includes/class-functions.php
@@ -568,6 +568,9 @@ if ( ! class_exists( 'UM_Functions' ) ) {
'charoff' => true,
'valign' => true,
),
+ 'a' => array(
+ 'onclick' => array(),
+ ),
);
break;
case 'templates':
diff --git a/includes/class-init.php b/includes/class-init.php
index 3c839c9a..2cf9fdf6 100644
--- a/includes/class-init.php
+++ b/includes/class-init.php
@@ -527,8 +527,10 @@ if ( ! class_exists( 'UM' ) ) {
}
//run setup
- $this->common()->create_post_types();
+ $this->common()->cpt()->create_post_types();
$this->setup()->run_setup();
+
+ $this->cron()->schedule_events();
}
@@ -549,10 +551,11 @@ if ( ! class_exists( 'UM' ) ) {
*/
public function includes() {
- $this->common();
+ $this->common()->includes();
$this->access();
if ( $this->is_request( 'ajax' ) ) {
+ $this->ajax()->includes();
$this->admin();
$this->ajax_init();
$this->admin_ajax_hooks();
@@ -565,6 +568,7 @@ if ( ! class_exists( 'UM' ) ) {
$this->plugin_updater();
$this->theme_updater();
} elseif ( $this->is_request( 'admin' ) ) {
+ $this->admin()->includes();
$this->admin();
$this->admin_menu();
$this->admin_upgrade();
@@ -572,7 +576,6 @@ if ( ! class_exists( 'UM' ) ) {
$this->columns();
$this->admin_enqueue();
$this->metabox();
- $this->admin()->notices();
$this->users();
$this->dragdrop();
$this->admin_gdpr();
@@ -580,6 +583,7 @@ if ( ! class_exists( 'UM' ) ) {
$this->plugin_updater();
$this->theme_updater();
} elseif ( $this->is_request( 'frontend' ) ) {
+ $this->frontend()->includes();
$this->enqueue();
$this->account();
$this->password();
@@ -607,6 +611,7 @@ if ( ! class_exists( 'UM' ) ) {
$this->gdpr();
$this->member_directory();
$this->blocks();
+ $this->secure();
//if multisite networks active
if ( is_multisite() ) {
@@ -649,7 +654,6 @@ if ( ! class_exists( 'UM' ) ) {
return $this->classes['blocks'];
}
-
/**
* Get extension API
*
@@ -688,19 +692,43 @@ if ( ! class_exists( 'UM' ) ) {
return $this->classes[ $key ];
}
+ /**
+ * @since 2.6.8
+ *
+ * @return um\ajax\Init
+ */
+ public function ajax() {
+ if ( empty( $this->classes['um\ajax\init'] ) ) {
+ $this->classes['um\ajax\init'] = new um\ajax\Init();
+ }
+
+ return $this->classes['um\ajax\init'];
+ }
/**
* @since 2.0
+ * @since 2.6.8 changed namespace and class content.
*
- * @return um\core\Common()
+ * @return um\common\Init
*/
- function common() {
- if ( empty( $this->classes['common'] ) ) {
- $this->classes['common'] = new um\core\Common();
+ public function common() {
+ if ( empty( $this->classes['um\common\init'] ) ) {
+ $this->classes['um\common\init'] = new um\common\Init();
}
- return $this->classes['common'];
+ return $this->classes['um\common\init'];
}
+ /**
+ * @since 2.6.8
+ *
+ * @return um\frontend\Init
+ */
+ public function frontend() {
+ if ( empty( $this->classes['um\frontend\init'] ) ) {
+ $this->classes['um\frontend\init'] = new um\frontend\Init();
+ }
+ return $this->classes['um\frontend\init'];
+ }
/**
* @since 2.0
@@ -760,7 +788,6 @@ if ( ! class_exists( 'UM' ) ) {
new um\core\AJAX_Common();
}
-
/**
* @since 2.0.30
*/
@@ -775,9 +802,9 @@ if ( ! class_exists( 'UM' ) ) {
/**
* @since 2.0
*
- * @return um\admin\Admin()
+ * @return um\admin\Admin
*/
- function admin() {
+ public function admin() {
if ( empty( $this->classes['admin'] ) ) {
$this->classes['admin'] = new um\admin\Admin();
}
diff --git a/includes/common/class-cpt.php b/includes/common/class-cpt.php
new file mode 100644
index 00000000..fe3828f1
--- /dev/null
+++ b/includes/common/class-cpt.php
@@ -0,0 +1,92 @@
+ array(
+ 'name' => __( 'Forms', 'ultimate-member' ),
+ 'singular_name' => __( 'Form', 'ultimate-member' ),
+ 'add_new' => __( 'Add New', 'ultimate-member' ),
+ 'add_new_item' => __( 'Add New Form', 'ultimate-member' ),
+ 'edit_item' => __( 'Edit Form', 'ultimate-member' ),
+ 'not_found' => __( 'You did not create any forms yet', 'ultimate-member' ),
+ 'not_found_in_trash' => __( 'Nothing found in Trash', 'ultimate-member' ),
+ 'search_items' => __( 'Search Forms', 'ultimate-member' ),
+ ),
+ 'capabilities' => array(
+ 'edit_post' => 'manage_options',
+ 'read_post' => 'manage_options',
+ 'delete_post' => 'manage_options',
+ 'edit_posts' => 'manage_options',
+ 'edit_others_posts' => 'manage_options',
+ 'delete_posts' => 'manage_options',
+ 'publish_posts' => 'manage_options',
+ 'read_private_posts' => 'manage_options',
+ ),
+ 'show_ui' => true,
+ 'show_in_menu' => false,
+ 'public' => false,
+ 'show_in_rest' => true,
+ 'supports' => array( 'title' ),
+ )
+ );
+
+ if ( UM()->options()->get( 'members_page' ) ) {
+ register_post_type(
+ 'um_directory',
+ array(
+ 'labels' => array(
+ 'name' => __( 'Member Directories', 'ultimate-member' ),
+ 'singular_name' => __( 'Member Directory', 'ultimate-member' ),
+ 'add_new' => __( 'Add New', 'ultimate-member' ),
+ 'add_new_item' => __( 'Add New Member Directory', 'ultimate-member' ),
+ 'edit_item' => __( 'Edit Member Directory', 'ultimate-member' ),
+ 'not_found' => __( 'You did not create any member directories yet', 'ultimate-member' ),
+ 'not_found_in_trash' => __( 'Nothing found in Trash', 'ultimate-member' ),
+ 'search_items' => __( 'Search Member Directories', 'ultimate-member' ),
+ ),
+ 'capabilities' => array(
+ 'edit_post' => 'manage_options',
+ 'read_post' => 'manage_options',
+ 'delete_post' => 'manage_options',
+ 'edit_posts' => 'manage_options',
+ 'edit_others_posts' => 'manage_options',
+ 'delete_posts' => 'manage_options',
+ 'publish_posts' => 'manage_options',
+ 'read_private_posts' => 'manage_options',
+ ),
+ 'show_ui' => true,
+ 'show_in_menu' => false,
+ 'public' => false,
+ 'show_in_rest' => true,
+ 'supports' => array( 'title' ),
+ )
+ );
+ }
+ }
+ }
+}
diff --git a/includes/common/class-init.php b/includes/common/class-init.php
new file mode 100644
index 00000000..b33146f1
--- /dev/null
+++ b/includes/common/class-init.php
@@ -0,0 +1,64 @@
+cpt()->hooks();
+ $this->screen();
+ $this->secure()->hooks();
+ }
+
+ /**
+ * @since 2.6.8
+ *
+ * @return CPT
+ */
+ public function cpt() {
+ if ( empty( UM()->classes['um\common\cpt'] ) ) {
+ UM()->classes['um\common\cpt'] = new CPT();
+ }
+ return UM()->classes['um\common\cpt'];
+ }
+
+ /**
+ * @since 2.6.8
+ *
+ * @return Screen
+ */
+ public function screen() {
+ if ( empty( UM()->classes['um\common\screen'] ) ) {
+ UM()->classes['um\common\screen'] = new Screen();
+ }
+ return UM()->classes['um\common\screen'];
+ }
+
+ /**
+ * @since 2.6.8
+ *
+ * @return Secure
+ */
+ public function secure() {
+ if ( empty( UM()->classes['um\common\secure'] ) ) {
+ UM()->classes['um\common\secure'] = new Secure();
+ }
+ return UM()->classes['um\common\secure'];
+ }
+ }
+}
diff --git a/includes/common/class-screen.php b/includes/common/class-screen.php
new file mode 100644
index 00000000..494cdae8
--- /dev/null
+++ b/includes/common/class-screen.php
@@ -0,0 +1,44 @@
+options()->get( 'secure_ban_admins_accounts' ) ) {
+ return;
+ }
+
+ if ( UM()->options()->get( 'secure_notify_admins_banned_accounts' ) ) {
+ $notification_interval = UM()->options()->get( 'secure_notify_admins_banned_accounts__interval' );
+ if ( 'instant' === $notification_interval ) {
+ return;
+ }
+
+ if ( 'hourly' === $notification_interval ) {
+ add_action( 'um_hourly_scheduled_events', array( $this, 'notify_administrators_hourly' ) );
+ } elseif ( 'daily' === $notification_interval ) {
+ add_action( 'um_daily_scheduled_events', array( $this, 'notify_administrators_daily' ) );
+ }
+ }
+ }
+
+ /**
+ * Notify Administrators hourly - Suspicious activities in an hour
+ *
+ * @since 2.6.8
+ */
+ public function notify_administrators_hourly() {
+ $user_ids = get_users(
+ array(
+ 'fields' => 'ids',
+ 'meta_query' => array(
+ 'relation' => 'AND',
+ array(
+ 'key' => 'um_user_blocked__timestamp',
+ 'value' => gmdate( 'Y-m-d H:i:s', strtotime( '-1 hour' ) ),
+ 'compare' => '>=',
+ 'type' => 'DATETIME',
+ ),
+ ),
+ )
+ );
+
+ $this->send_notification( $user_ids );
+ }
+
+ /**
+ * Notify Administrators daily - Today's suspicious activity
+ *
+ * @since 2.6.8
+ */
+ public function notify_administrators_daily() {
+ $user_ids = get_users(
+ array(
+ 'fields' => 'ids',
+ 'relation' => 'AND',
+ 'meta_query' => array(
+ 'relation' => 'AND',
+ array(
+ 'key' => 'um_user_blocked__timestamp',
+ 'value' => gmdate( 'Y-m-d H:i:s', strtotime( '-1 day' ) ),
+ 'compare' => '>=',
+ 'type' => 'DATE',
+ ),
+ array(
+ 'key' => 'um_user_blocked__timestamp',
+ 'value' => gmdate( 'Y-m-d H:i:s', strtotime( 'now' ) ),
+ 'compare' => '<=',
+ 'type' => 'DATE',
+ ),
+ ),
+ )
+ );
+
+ $this->send_notification( $user_ids );
+ }
+
+ public function send_notification( $user_ids ) {
+ $banned_profile_links = '';
+ foreach ( $user_ids as $uid ) {
+ um_fetch_user( $uid );
+ $banned_profile_links .= UM()->user()->get_profile_link( $uid ) . ' ' . um_user( 'account_status' ) . ' ';
+ }
+ um_reset_user();
+
+ $emails = um_multi_admin_email();
+ if ( ! empty( $emails ) ) {
+ foreach ( $emails as $email ) {
+ UM()->mail()->send(
+ $email,
+ 'suspicious-activity',
+ array(
+ 'admin' => true,
+ 'tags' => array(
+ '{banned_profile_links}',
+ ),
+ 'tags_replace' => array(
+ $banned_profile_links,
+ ),
+ )
+ );
+ }
+ }
+ }
+
+ /**
+ * Get the banned capabilities list.
+ *
+ * @return array
+ */
+ public function get_banned_capabilities_list() {
+ /**
+ * Filters the banned capabilities for UM Register forms.
+ *
+ * @param {array} $capabilities WordPress Administrative Capabilities.
+ *
+ * @return {array} Banned admin capabilities.
+ *
+ * @since 2.6.8
+ * @hook um_secure_register_form_banned_capabilities
+ *
+ * @example