PluginProbe
Teydea Password Reset – Force Password Reset & Expiration / trunk
Teydea Password Reset – Force Password Reset & Expiration vtrunk
trunk 1.0.0 1.1.0 1.1.1 1.10.0 1.10.1 1.10.2 1.11.0 1.11.1 1.12.0 1.12.1 1.13.0 1.2.0 1.3.0 1.4.0 1.5.0 1.6.0 1.7.0 1.7.1 1.7.2 1.8.0 1.9.0
password-reset-enforcement / src / modules / reset-indicator / class-module-reset-indicator.php

class-module-reset-indicator.php in Teydea Password Reset – Force Password Reset & Expiration trunk, at src/modules/reset-indicator/class-module-reset-indicator.php

185 lines 5.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Add indicator to show that a password reset has been
4 * enforced for the user
5 *
6 * @package Teydea_Studio\Password_Reset
7 */
8
9 namespace Teydea_Studio\Password_Reset\Modules\Reset_Indicator;
10
11 use Teydea_Studio\Password_Reset\Dependencies\Utils;
12 use Teydea_Studio\Password_Reset\User;
13 use WP_User;
14
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit; // @codeCoverageIgnore
17 }
18
19 /**
20 * The "Module_Reset_Indicator" class
21 */
22 final class Module_Reset_Indicator extends Utils\Module {
23 /**
24 * Column slug
25 *
26 * @var string
27 */
28 const COLUMN_SLUG = 'password_reset_enforcement__status';
29
30 /**
31 * Register hooks
32 *
33 * @return void
34 */
35 public function register(): void {
36 // Add custom column to the multisite users list table.
37 add_filter( 'wpmu_users_columns', [ $this, 'add_custom_column' ] );
38
39 // Add custom column to the single-site users list table.
40 add_filter( 'manage_users_columns', [ $this, 'add_custom_column' ] );
41
42 // Render the content of the custom column.
43 add_filter( 'manage_users_custom_column', [ $this, 'render_custom_column' ], 10, 3 );
44
45 // Enqueue the column's stylesheet on the users list table.
46 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
47
48 // Register the admin notice on network admin user profile.
49 add_action( 'network_admin_notices', [ $this, 'maybe_register_admin_notice' ] );
50
51 // Register the admin notice on single-site user profile.
52 add_action( 'admin_notices', [ $this, 'maybe_register_admin_notice' ] );
53 }
54
55 /**
56 * Enqueue the column stylesheet on the users list table
57 *
58 * @return void
59 */
60 public function enqueue_assets(): void {
61 $screen = new Utils\Screen( $this->container );
62
63 if ( $screen->is( 'users' ) || $screen->is( 'users-network' ) ) {
64 $asset = new Utils\Asset( $this->container, 'reset-indicator' );
65 $asset->enqueue_style();
66 }
67 }
68
69 /**
70 * Add custom column to the users list table
71 *
72 * @param array<string,string> $columns Existing columns.
73 *
74 * @return array<string,string> Modified columns.
75 */
76 public function add_custom_column( array $columns ): array {
77 // Get the current user.
78 $current_user = new User( $this->container );
79
80 // Ensure current user has the managing permissions.
81 if ( $current_user->has_managing_permissions() ) {
82 $columns[ self::COLUMN_SLUG ] = __( 'Password Reset Enforced?', 'password-reset-enforcement' );
83 }
84
85 return $columns;
86 }
87
88 /**
89 * Render the content of the custom column
90 *
91 * @param string $value The column value.
92 * @param string $column_name The column name.
93 * @param int $user_id The user ID.
94 *
95 * @return string The modified column value.
96 */
97 public function render_custom_column( string $value, string $column_name, int $user_id ): string {
98 if ( self::COLUMN_SLUG === $column_name ) {
99 $wp_user = get_user_by( 'ID', $user_id );
100
101 if ( $wp_user instanceof WP_User ) {
102 $user = new User( $this->container, $wp_user );
103
104 if ( false === $user->is_password_reset_required() ) {
105 $value = sprintf( '<p class="password-reset-enforcement-reset-indicator__status">%s</p>', esc_html__( 'No', 'password-reset-enforcement' ) );
106 } else {
107 $value = sprintf( '<p class="password-reset-enforcement-reset-indicator__status password-reset-enforcement-reset-indicator__status--enforced">%s</p>', esc_html__( 'Yes', 'password-reset-enforcement' ) );
108 $data = $user->get_password_reset_request_data();
109
110 if ( null !== $data ) {
111 $items = [
112 __( 'Requested at:', 'password-reset-enforcement' ) => sprintf(
113 // Translators: %1$s - timestamp, %2$s - human-readable time difference.
114 __( '%1$s (%2$s ago)', 'password-reset-enforcement' ),
115 Utils\Date_Time::get_i18n_datetime_string( $data['requested_at'] ),
116 human_time_diff( $data['requested_at'] ),
117 ),
118 __( 'Requestor:', 'password-reset-enforcement' ) => $user->get_requestor_display_name( $data['requested_by'] ),
119 ];
120
121 $value .= '<ul class="password-reset-enforcement-reset-indicator__details">';
122
123 foreach ( $items as $label => $item ) {
124 $value .= sprintf( '<li><strong class="password-reset-enforcement-reset-indicator__detail-label">%s</strong> %s</li>', esc_html( $label ), esc_html( $item ) );
125 }
126
127 $value .= '</ul>';
128 }
129 }
130 }
131 }
132
133 return $value;
134 }
135
136 /**
137 * Maybe register the admin notice
138 *
139 * @return void
140 */
141 public function maybe_register_admin_notice(): void {
142 $screen = new Utils\Screen( $this->container );
143
144 if ( ! $screen->is( 'user-edit' ) ) {
145 return;
146 }
147
148 $user_id = isset( $_GET['user_id'] ) ? Utils\Type::ensure_int( wp_unslash( $_GET['user_id'] ) ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
149
150 if ( 0 === $user_id ) {
151 return;
152 }
153
154 $wp_user = get_user_by( 'ID', $user_id );
155
156 if ( $wp_user instanceof WP_User ) {
157 $user = new User( $this->container, $wp_user );
158
159 if ( $user->is_password_reset_required() ) {
160 $data = $user->get_password_reset_request_data();
161
162 if ( null === $data ) {
163 return;
164 }
165
166 $requestor = $user->get_requestor_display_name( $data['requested_by'] );
167
168 // Register the admin notice.
169 wp_admin_notice(
170 wp_kses(
171 sprintf(
172 // Translators: %1$s - user display name, %2$s - human-readable time difference.
173 __( 'A password reset was enforced for this user by <strong>%1$s %2$s ago</strong>, but they have not completed it yet. Please make sure they are informed.', 'password-reset-enforcement' ),
174 $requestor,
175 human_time_diff( $data['requested_at'] ),
176 ),
177 [ 'strong' => [] ],
178 ),
179 [ 'type' => 'info' ],
180 );
181 }
182 }
183 }
184 }
185