PluginProbe ʕ •ᴥ•ʔ
WP 2FA – Two-factor authentication for WordPress / 4.0.0
WP 2FA – Two-factor authentication for WordPress v4.0.0
4.0.0 1.7.1 2.0.0 2.0.1 2.1.0 2.2.0 2.2.1 2.3.0 2.4.0 2.4.1 2.4.2 2.5.0 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.8.0 2.9.0 2.9.1 2.9.2 2.9.3 3.0.0 3.0.1 3.1.0 3.1.1 3.1.1.2 trunk 1.2.0 1.3.0 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.6.0 1.6.1 1.6.2 1.7.0
wp-2fa / includes / classes / Admin / class-user-listing.php
wp-2fa / includes / classes / Admin Last commit date
AdminSettings 2 days ago Controllers 2 days ago Fly-Out 2 days ago Helpers 2 days ago Methods 2 days ago Settings 2 days ago SettingsPages 2 days ago Views 2 days ago class-about-us.php 2 days ago class-docs-and-support.php 2 days ago class-free-support-notice.php 2 days ago class-help-contact-us.php 2 days ago class-license-page.php 2 days ago class-new-interface-notice.php 2 days ago class-plugin-updated-notice.php 2 days ago class-premium-features.php 2 days ago class-profile-section-renderer.php 2 days ago class-settings-page.php 2 days ago class-setup-wizard.php 2 days ago class-top-bar-banner.php 2 days ago class-user-listing.php 2 days ago class-user-notices.php 2 days ago class-user-profile.php 2 days ago class-user-registered.php 2 days ago class-wizard-integration.php 2 days ago index.php 2 days ago
class-user-listing.php
240 lines
1 <?php
2 /**
3 * Responsible for user listing in admin manipulation.
4 *
5 * @package wp2fa
6 * @subpackage user-utils
7 * @copyright 2026 Melapress
8 * @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
9 * @link https://wordpress.org/plugins/wp-2fa/
10 */
11
12 declare(strict_types=1);
13
14 namespace WP2FA\Admin;
15
16 use WP2FA\Utils\User_Utils;
17 use WP2FA\Admin\Helpers\User_Helper;
18 use WP2FA\Extensions\TrustedDevices\Core;
19
20 defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
21
22 /**
23 * User_Listing class with user listing filters
24 */
25 if ( ! class_exists( '\WP2FA\Admin\User_Listing' ) ) {
26
27 /**
28 * User_Listing - Shows extra column in user table with WP2FA status for every user
29 */
30 class User_Listing {
31
32 /**
33 * The users table column name
34 *
35 * @var string
36 *
37 * @since 3.0.0
38 */
39 private static $column_name = 'wp-2fa-status';
40
41 /**
42 * Inits all the hooks used for showing the extra user data in the users column
43 *
44 * @return void
45 *
46 * @since 3.0.0
47 */
48 public static function init() {
49 \add_filter( 'manage_users_columns', array( __CLASS__, 'add_wp_2fa_column' ) );
50 \add_filter( 'wpmu_users_columns', array( __CLASS__, 'add_wp_2fa_column' ) );
51 \add_filter( 'manage_users_custom_column', array( __CLASS__, 'show_column_data' ), 10, 3 );
52 \add_filter( 'bulk_actions-users', array( __CLASS__, 'add_bulk_action' ), 10, 1 );
53 \add_filter( 'handle_bulk_actions-users', array( __CLASS__, 'handle_bulk_actions' ), 10, 3 );
54 \add_action( 'admin_notices', array( __CLASS__, 'show_admin_notice' ) );
55 \add_filter( 'user_row_actions', array( __CLASS__, 'add_users_hover' ), 10, 2 );
56 }
57
58 /**
59 * Sets the column in the admin users table
60 *
61 * @param array $columns - Array with all the columns.
62 *
63 * @return array
64 *
65 * @since 3.0.0
66 */
67 public static function add_wp_2fa_column( array $columns ): array {
68 $columns[ self::$column_name ] = esc_html__( '2FA Status', 'wp-2fa' );
69 return $columns;
70 }
71
72 /**
73 * Shows the user WP 2FA status data in the users table
74 *
75 * @param mixed $value - The value of the column.
76 * @param string $column_name - The name of the column.
77 * @param int $user_id - the ID of the user.
78 *
79 * @return mixed
80 *
81 * @since 3.0.0
82 */
83 public static function show_column_data( $value, string $column_name, $user_id ) {
84 if ( self::$column_name === $column_name ) {
85 return esc_html( self::get_user2fa_status( $user_id ) );
86 }
87 return $value;
88 }
89
90 /**
91 * Retrieves the translated 2FA status label for given user.
92 *
93 * @param int $user_id - The id of the user for which the info should be extracted.
94 *
95 * @return string
96 *
97 * @since 3.0.0
98 */
99 private static function get_user2fa_status( $user_id ): string {
100 $status_meta_value = User_Helper::get_2fa_status( $user_id );
101 if ( ! empty( $status_meta_value ) ) {
102 $status_data = User_Utils::extract_statuses( array( $status_meta_value ) );
103 if ( ! empty( $status_data ) ) {
104 return $status_data['label'];
105 }
106 }
107 return User_Helper::set_user_status( new \WP_User( $user_id ) );
108 }
109
110 /**
111 * Returns the users table column name
112 *
113 * @return string
114 *
115 * @since 3.0.0
116 */
117 public static function get_column_name(): string {
118 return self::$column_name;
119 }
120
121 /**
122 * Adds bulk action to the WP users menu
123 *
124 * @param array $bulk_actions - Array of bulk actions.
125 *
126 * @return array
127 *
128 * @since 2.2.2
129 */
130 public static function add_bulk_action( $bulk_actions ): array {
131 $bulk_actions['remove-2fa'] = \esc_html__( 'Remove 2FA', 'wp-2fa' );
132 $bulk_actions['remove-2fa-trusted'] = \esc_html__( 'Reset list of 2FA trusted devices', 'wp-2fa' );
133
134 return $bulk_actions;
135 }
136
137 /**
138 * Removes the 2fa from the list of the selected users.
139 *
140 * @param string $redirect_url - The redirect URL to redirect to when action is performed.
141 * @param string $action - The action to perform.
142 * @param array $user_ids - The user IDs to remove from.
143 *
144 * @return string
145 *
146 * @since 2.2.2
147 */
148 public static function handle_bulk_actions( $redirect_url, $action, $user_ids ): string {
149 if ( ! current_user_can( 'manage_options' ) ) {
150 return esc_url_raw( \network_admin_url() );
151 }
152
153 if ( 'remove-2fa' === $action ) {
154
155 foreach ( (array) $user_ids as $user_id ) {
156 User_Helper::remove_2fa_for_user( (int) $user_id );
157 }
158 \set_site_transient(
159 'wp_2fa_bulk_notice_' . \get_current_user_id(),
160 array(
161 'type' => 'removed',
162 'count' => count( (array) $user_ids ),
163 ),
164 30
165 );
166 }
167
168 if ( class_exists( '\WP2FA\Extensions\TrustedDevices\Core' ) && 'remove-2fa-trusted' === $action ) {
169
170 Core::remove_trusted_devices_for_users( (array) $user_ids );
171 \set_site_transient(
172 'wp_2fa_bulk_notice_' . \get_current_user_id(),
173 array(
174 'type' => 'trusted-removed',
175 'count' => count( (array) $user_ids ),
176 ),
177 30
178 );
179 }
180
181 return esc_url_raw( $redirect_url );
182 }
183
184 /**
185 * Adds links to the on hover state of the users table row
186 *
187 * @param array $actions - Array with all the actions for the current row.
188 * @param \WP_User $user_object - The user object from the current row.
189 *
190 * @return array
191 *
192 * @since 2.4.0
193 */
194 public static function add_users_hover( $actions, $user_object ): array {
195 if ( class_exists( '\WP2FA\Extensions\TrustedDevices\Core' ) ) {
196 $actions['remove-2fa-trusted'] = "<a class='resetpassword' href='" . \esc_url( \wp_nonce_url( "users.php?action=remove-2fa-trusted&amp;users=$user_object->ID", 'bulk-users' ) ) . "'>" . \esc_html__( 'Reset list of 2FA trusted devices', 'wp-2fa' ) . '</a>';
197 }
198 return $actions;
199 }
200
201 /**
202 * Handles the Admin notice for the users removed 2FA.
203 *
204 * @return void
205 *
206 * @since 2.2.2
207 */
208 public static function show_admin_notice() {
209 $transient_key = 'wp_2fa_bulk_notice_' . \get_current_user_id();
210 $notice = \get_site_transient( $transient_key );
211
212 if ( ! $notice || ! is_array( $notice ) || ! isset( $notice['type'] ) ) {
213 return;
214 }
215
216 \delete_site_transient( $transient_key );
217
218 $num_changed = (int) ( $notice['count'] ?? 0 );
219
220 if ( 'removed' === $notice['type'] ) {
221 printf(
222 '<div id="message" class="updated notice is-dismissable"><p>' .
223 // translators: The number of the affected users.
224 \esc_html__( 'Removed 2FA from %d users.', 'wp-2fa' ) .
225 '</p></div>',
226 $num_changed
227 );
228 } elseif ( 'trusted-removed' === $notice['type'] ) {
229 printf(
230 '<div id="message" class="updated notice is-dismissable"><p>' .
231 // translators: The number of the affected users.
232 \esc_html__( 'Removed 2FA trusted devices from %d users.', 'wp-2fa' ) .
233 '</p></div>',
234 $num_changed
235 );
236 }
237 }
238 }
239 }
240