PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 5.2.1
MainWP Dashboard: Self-hosted WordPress Management for Agencies v5.2.1
6.2.2 6.2.1 6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 All 155 releases
mainwp / pages / page-mainwp-bulk-update-admin-passwords.php

page-mainwp-bulk-update-admin-passwords.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies 5.2.1, at pages/page-mainwp-bulk-update-admin-passwords.php

481 lines 24.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Bulk Update Admin Passwords.
4 *
5 * Handles bulk updating of Administrator Passwords.
6 *
7 * @package MainWP/Dashboard
8 */
9
10 namespace MainWP\Dashboard;
11
12 /**
13 * Class MainWP_Bulk_Update_Admin_Passwords
14 *
15 * @uses MainWP_Bulk_Add
16 */
17 class MainWP_Bulk_Update_Admin_Passwords { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
18
19 /**
20 * Get Class Name
21 *
22 * @return string __CLASS__
23 */
24 public static function get_class_name() {
25 return __CLASS__;
26 }
27
28 /**
29 * Method init_menu()
30 *
31 * Add Users sub menu "Admin Passwords".
32 */
33 public static function init_menu() {
34 add_submenu_page(
35 'mainwp_tab',
36 __( 'Admin Passwords', 'mainwp' ),
37 '<div class="mainwp-hidden">' . esc_html__( 'Admin Passwords', 'mainwp' ) . '</div>',
38 'read',
39 'UpdateAdminPasswords',
40 array(
41 static::get_class_name(),
42 'render',
43 )
44 );
45 }
46
47 /**
48 * Renders the Admin Passwords page footer.
49 */
50 public static function render_footer() {
51 echo '</div>';
52 }
53
54 /**
55 * Renders the Admin Passwords page.
56 *
57 * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
58 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
59 * @uses \MainWP\Dashboard\MainWP_DB::query()
60 * @uses \MainWP\Dashboard\MainWP_DB::get_sql_websites_by_group_id()
61 * @uses \MainWP\Dashboard\MainWP_DB::get_sql_websites_for_current_user()
62 * @uses \MainWP\Dashboard\MainWP_DB::fetch_object()
63 * @uses \MainWP\Dashboard\MainWP_DB::free_result()
64 * @uses \MainWP\Dashboard\MainWP_Bulk_Add::get_class_name()
65 * @uses \MainWP\Dashboard\MainWP_User::render_header()
66 * @uses \MainWP\Dashboard\MainWP_User::render_footer()
67 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
68 * @uses \MainWP\Dashboard\MainWP_Utility::map_site()
69 */
70 public static function render() { // phpcs:ignore -- NOSONAR -Current complexity is the only way to achieve desired results, pull request solutions appreciated.
71 $show_form = true;
72 $errors = array();
73
74 if ( isset( $_POST['bulk_updateadminpassword'] ) ) {
75 check_admin_referer( 'mainwp_updateadminpassword', 'security' );
76
77 if ( isset( $_POST['select_by'] ) ) {
78 $selected_sites = ( isset( $_POST['selected_sites'] ) && is_array( $_POST['selected_sites'] ) ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['selected_sites'] ) ) : array();
79 $selected_groups = ( isset( $_POST['selected_groups'] ) && is_array( $_POST['selected_groups'] ) ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['selected_groups'] ) ) : array();
80 $selected_clients = ( isset( $_POST['selected_clients'] ) && is_array( $_POST['selected_clients'] ) ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['selected_clients'] ) ) : array();
81
82 if ( ( 'group' === $_POST['select_by'] && empty( $selected_groups ) ) || ( 'site' === $_POST['select_by'] && empty( $selected_sites ) ) || ( 'client' === $_POST['select_by'] && empty( $selected_clients ) ) ) {
83 $errors[] = esc_html__( 'Please select the sites or groups or clients where you want to change the administrator password.', 'mainwp' );
84 }
85 } else {
86 $errors[] = esc_html__( 'Please select whether you want to change the administrator password for specific sites or groups or clients.', 'mainwp' );
87 }
88
89 if ( ! isset( $_POST['password'] ) || '' === trim( wp_unslash( $_POST['password'] ) ) ) { //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- ok.
90 $errors[] = esc_html__( 'Please enter the password.', 'mainwp' );
91 }
92
93 $data_fields = MainWP_System_Utility::get_default_map_site_fields();
94
95 if ( empty( $errors ) ) {
96 $show_form = false;
97
98 $new_password = wp_unslash( $_POST['password'] ); //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- ok.
99
100 $dbwebsites = array();
101 if ( 'site' === $_POST['select_by'] ) { // Get all selected websites.
102 foreach ( $selected_sites as $k ) {
103 if ( MainWP_Utility::ctype_digit( $k ) ) {
104 $website = MainWP_DB::instance()->get_website_by_id( $k );
105 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
106 continue;
107 }
108 $dbwebsites[ $website->id ] = MainWP_Utility::map_site(
109 $website,
110 $data_fields
111 );
112 }
113 }
114 } elseif ( 'client' === $_POST['select_by'] ) { // Get all selected websites.
115 $websites = MainWP_DB_Client::instance()->get_websites_by_client_ids(
116 $selected_clients,
117 array(
118 'select_data' => $data_fields,
119 )
120 );
121 if ( $websites ) {
122 foreach ( $websites as $website ) {
123 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
124 continue;
125 }
126 $dbwebsites[ $website->id ] = MainWP_Utility::map_site(
127 $website,
128 $data_fields
129 );
130 }
131 }
132 } else { // Get all websites from the selected groups.
133 foreach ( $selected_groups as $k ) {
134 if ( MainWP_Utility::ctype_digit( $k ) ) {
135 $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_by_group_id( $k ) );
136 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
137 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
138 continue;
139 }
140 $dbwebsites[ $website->id ] = MainWP_Utility::map_site(
141 $website,
142 $data_fields
143 );
144 }
145 MainWP_DB::free_result( $websites );
146 }
147 }
148 }
149
150 if ( ! empty( $dbwebsites ) ) {
151 $post_data = array( 'new_password' => base64_encode( $new_password ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
152 $output = new \stdClass();
153 $output->ok = array();
154 $output->errors = array();
155
156 MainWP_Connect::fetch_urls_authed(
157 $dbwebsites,
158 'newadminpassword',
159 $post_data,
160 array(
161 MainWP_Bulk_Add::get_class_name(),
162 'posting_bulk_handler',
163 ),
164 $output
165 );
166 }
167 }
168 }
169
170 $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_for_current_user( false, null, 'wp.url', false, false, null, false, array( 'admin_nicename', 'admin_useremail' ) ) );
171
172 MainWP_User::render_header( 'UpdateAdminPasswords' );
173 if ( ! $show_form ) {
174 static::render_modal( $dbwebsites, $output );
175 }
176 static::render_bulk_form( $websites );
177 MainWP_User::render_footer( 'UpdateAdminPasswords' );
178 }
179
180 /**
181 * Renders update password results.
182 *
183 * @param object $dbwebsites The websites object.
184 * @param object $output Result of update password.
185 */
186 public static function render_modal( $dbwebsites, $output ) {
187 ?>
188 <div class="ui modal" id="mainwp-reset-admin-passwords-modal">
189 <i class="close icon"></i>
190 <div class="header"><?php esc_html_e( 'Update Admin Password', 'mainwp' ); ?></div>
191 <div class="scrolling content">
192 <?php
193 /**
194 * Action: mainwp_reset_admin_pass_modal_top
195 *
196 * Fires at the top of the Update Admin Passwords modal.
197 *
198 * @since 4.1
199 */
200 do_action( 'mainwp_reset_admin_pass_modal_top' );
201 ?>
202 <div class="ui relaxed divided list">
203 <?php foreach ( $dbwebsites as $website ) : ?>
204 <div class="item">
205 <a href="<?php echo esc_url( admin_url( 'admin.php?page=managesites&dashboard=' . $website->id ) ); ?>"><?php echo esc_html( stripslashes( $website->name ) ); ?></a>
206 <span class="right floated content">
207 <?php echo isset( $output->ok[ $website->id ] ) && 1 === (int) $output->ok[ $website->id ] ? '<i class="green check icon"></i>' : '<i class="red times icon"></i> ' . $output->errors[ $website->id ]; // phpcs:ignore WordPress.Security.EscapeOutput ?>
208 </span>
209 </div>
210 <?php endforeach; ?>
211 </div>
212 <?php
213 /**
214 * Action: mainwp_reset_admin_pass_modal_bottom
215 *
216 * Fires at the bottom of the Update Admin Passwords modal.
217 *
218 * @since 4.1
219 */
220 do_action( 'mainwp_reset_admin_pass_modal_bottom' );
221 ?>
222 </div>
223 <div class="actions">
224 </div>
225 </div>
226 <script type="text/javascript">
227 jQuery( '#mainwp-reset-admin-passwords-modal' ).modal( 'show' );
228 </script>
229 <?php
230 }
231
232 /**
233 * Renders bulk update administrator password form.
234 *
235 * @param object $websites Object containing child sites info.
236 *
237 * @uses \MainWP\Dashboard\MainWP_DB::fetch_object()
238 * @uses \MainWP\Dashboard\MainWP_DB::free_result()
239 */
240 public static function render_bulk_form( $websites ) {
241 $is_demo = MainWP_Demo_Handle::is_demo_mode();
242 /**
243 * Filter: mainwp_update_admin_password_complexity
244 *
245 * Filters the Password lenght for the Update Admin Password, Password field.
246 *
247 * Since 4.1
248 */
249 $pass_complexity = apply_filters( 'mainwp_update_admin_password_complexity', '24' );
250 ?>
251 <div class="ui alt segment" id="mainwp-bulk-update-admin-passwords">
252 <form action="" method="post" name="createuser" id="createuser">
253 <?php wp_nonce_field( 'mainwp-admin-nonce' ); ?>
254 <input type="hidden" name="security" value="<?php echo esc_attr( wp_create_nonce( 'mainwp_updateadminpassword' ) ); ?>"/>
255 <div class="mainwp-main-content" >
256 <div class="ui em hidden divider"></div>
257 <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-admin-pass-info-message' ) ) : ?>
258 <div class="ui info message">
259 <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-admin-pass-info-message"></i>
260 <?php printf( esc_html__( 'See the list of Admininstrator users used to establish secure connection between your MainWP Dashboard and child sites. If needed, use the provided form to set a new password for these accounts. For additional help, please check this %1$shelp documentation%2$s.', 'mainwp' ), '<a href="https://kb.mainwp.com/docs/bulk-update-administrator-passwords/" target="_blank">', '</a> <i class="external alternate icon"></i>' ); // NOSONAR - noopener - open safe. ?>
261 </div>
262 <?php endif; ?>
263 <?php
264 /**
265 * Action: mainwp_admin_pass_before_users_table
266 *
267 * Fires before the Connected Admin Users mysql_list_tables
268 *
269 * @since 4.1
270 */
271 do_action( 'mainwp_admin_pass_before_users_table' );
272 ?>
273 <table id="mainwp-admin-users-table" class="ui single line unstackable table">
274 <thead>
275 <tr>
276 <th scope="col" ><?php esc_html_e( 'Site', 'mainwp' ); ?></th>
277 <th scope="col" class="no-sort collapsing"><i class="sign in icon"></i></th>
278 <th scope="col" ><?php esc_html_e( 'Admin Username', 'mainwp' ); ?></th>
279 <th scope="col" ><?php esc_html_e( 'Admin Name', 'mainwp' ); ?></th>
280 <th scope="col" ><?php esc_html_e( 'Admin Email', 'mainwp' ); ?></th>
281 </tr>
282 </thead>
283 <tbody>
284 <?php
285 while ( $websites && $website = MainWP_DB::fetch_object( $websites ) ) :
286 $adminname = $website->adminname;
287 ?>
288 <tr>
289 <td><a href="<?php echo esc_url( admin_url( 'admin.php?page=managesites&dashboard=' . $website->id ) ); ?>"><?php echo esc_html( stripslashes( $website->name ) ); ?></a></td>
290 <td><a target="_blank" href="admin.php?page=SiteOpen&newWindow=yes&websiteid=<?php echo intval( $website->id ); ?>&_opennonce=<?php echo esc_html( wp_create_nonce( 'mainwp-admin-nonce' ) ); ?>"><i class="sign in icon"></i></a></td>
291 <td><?php echo esc_html( $adminname ); ?></td>
292 <td><?php echo esc_html( $website->admin_nicename ); ?></td>
293 <td><?php echo esc_html( $website->admin_useremail ); ?></td>
294 </tr>
295 <?php endwhile; ?>
296 <?php MainWP_DB::free_result( $websites ); ?>
297 </tbody>
298 <tfoot>
299 <tr>
300 <th scope="col" ><?php esc_html_e( 'Site', 'mainwp' ); ?></th>
301 <th scope="col" ><i class="sign in icon"></i></th>
302 <th scope="col" ><?php esc_html_e( 'Admin Username', 'mainwp' ); ?></th>
303 <th scope="col" ><?php esc_html_e( 'Admin Name', 'mainwp' ); ?></th>
304 <th scope="col" ><?php esc_html_e( 'Admin Email', 'mainwp' ); ?></th>
305 </tr>
306 </tfoot>
307 </table>
308 <?php
309 /**
310 * Action: mainwp_admin_pass_after_users_table
311 *
312 * Fires after the Connected Admin Users mysql_list_tables
313 *
314 * @since 4.1
315 */
316 do_action( 'mainwp_admin_pass_after_users_table' );
317
318 $table_features = array(
319 'searching' => 'true',
320 'paging' => 'true',
321 'info' => 'true',
322 'colReorder' => 'true',
323 'stateSave' => 'true',
324 'responsive' => 'true',
325 );
326 /**
327 * Filter: mainwp_admin_users_table_fatures
328 *
329 * Filters Admin Users table features.
330 *
331 * @since 4.1
332 */
333 $table_features = apply_filters( 'mainwp_admin_users_table_fatures', $table_features );
334 ?>
335 <script type="text/javascript">
336
337 jQuery( document ).ready( function () {
338 let responsive = <?php echo esc_html( $table_features['responsive'] ); ?>;
339 if( jQuery( window ).width() > 1140 ) {
340 responsive = false;
341 }
342 jQuery( '#mainwp-admin-users-table' ).DataTable( {
343 "searching" : <?php echo esc_html( $table_features['searching'] ); ?>,
344 "paging" : <?php echo esc_html( $table_features['paging'] ); ?>,
345 "info" : <?php echo esc_html( $table_features['info'] ); ?>,
346 "colReorder" : <?php echo $table_features['colReorder']; // phpcs:ignore -- specical chars. ?>,
347 "stateSave": <?php echo esc_html( $table_features['stateSave'] ); ?>,
348 "order": [],
349 "columnDefs": [ { "targets": 'no-sort', "orderable": false } ],
350 "responsive": responsive
351 } );
352 } );
353 </script>
354 </div>
355 <div class="mainwp-side-content mainwp-no-padding">
356 <?php
357 /**
358 * Action: mainwp_admin_pass_sidebar_top
359 *
360 * Fires at the top of the sidebar on Admin Passwords page.
361 *
362 * @since 4.1
363 */
364 do_action( 'mainwp_admin_pass_sidebar_top' );
365 ?>
366 <div class="mainwp-select-sites ui accordion mainwp-sidebar-accordion">
367 <?php
368 /**
369 * Action: mainwp_admin_pass_before_select_sites
370 *
371 * Fires before the Select Sites section on the Admin Passwords page.
372 *
373 * @since 4.1
374 */
375 do_action( 'mainwp_admin_pass_before_select_sites' );
376 ?>
377 <div class="title active"><i class="dropdown icon"></i> <?php esc_html_e( 'Select Sites', 'mainwp' ); ?></div>
378 <div class="content active">
379 <?php
380 $sel_params = array(
381 'show_client' => true,
382 );
383 MainWP_UI_Select_Sites::select_sites_box( $sel_params );
384 ?>
385 </div>
386 <?php
387 /**
388 * Action: mainwp_admin_pass_after_select_sites
389 *
390 * Fires after the Select Sites section on the Admin Passwords page.
391 *
392 * @since 4.1
393 */
394 do_action( 'mainwp_admin_pass_after_select_sites' );
395 ?>
396 </div>
397 <div class="ui fitted divider"></div>
398 <div class="mainwp-search-options ui accordion mainwp-sidebar-accordion">
399 <div class="title active"><i class="dropdown icon"></i> <?php esc_html_e( 'Update Admin Password', 'mainwp' ); ?></div>
400 <div class="content active">
401 <?php
402 /**
403 * Action: mainwp_admin_pass_before_pass_form
404 *
405 * Fires before the New password form on the Admin Passwords page.
406 *
407 * @since 4.1
408 */
409 do_action( 'mainwp_admin_pass_before_pass_form' );
410 ?>
411 <div class="ui mini form">
412 <div class="field">
413 <label><?php esc_html_e( 'New Password', 'mainwp' ); ?></label>
414 <div class="ui fluid input" data-tooltip="<?php esc_attr_e( 'Enter a new password or use the Generate Password button.', 'mainwp' ); ?>" data-inverted="" data-position="top right">
415 <input class="hidden" value=" "/>
416 <input type="text" id="password" name="password" autocomplete="off" value="<?php echo esc_attr( wp_generate_password( $pass_complexity ) ); ?>">
417 </div>
418 <br />
419 <button class="ui basic green fluid button wp-generate-pw"><?php esc_html_e( 'Generate New Password', 'mainwp' ); ?></button>
420 </div>
421 </div>
422 <?php
423 /**
424 * Action: mainwp_admin_pass_after_pass_form
425 *
426 * Fires after the New password form on the Admin Passwords page.
427 *
428 * @since 4.1
429 */
430 do_action( 'mainwp_admin_pass_after_pass_form' );
431 ?>
432 </div>
433 </div>
434 <div class="ui fitted divider"></div>
435 <div class="mainwp-search-submit">
436 <?php
437 /**
438 * Action: mainwp_admin_pass_before_submit_button
439 *
440 * Fires before the Submit button on the Admin Passwords page.
441 *
442 * @since 4.1
443 */
444 do_action( 'mainwp_admin_pass_before_submit_button' );
445 if ( $is_demo ) {
446 MainWP_Demo_Handle::get_instance()->render_demo_disable_button( '<input type="submit" disabled="disabled" class="ui big green fluid button" value="' . esc_attr__( 'Update Password', 'mainwp' ) . '"/>' );
447 } else {
448 ?>
449 <input type="submit" name="bulk_updateadminpassword" id="bulk_updateadminpassword" class="ui big green fluid button" value="<?php esc_attr_e( 'Update Password', 'mainwp' ); ?> "/>
450 <?php
451 }
452 /**
453 * Action: mainwp_admin_pass_after_submit_button
454 *
455 * Fires after the Submit button on the Admin Passwords page.
456 *
457 * @since 4.1
458 */
459 do_action( 'mainwp_admin_pass_after_submit_button' );
460 ?>
461 </div>
462 <?php
463 /**
464 * Action: mainwp_admin_pass_sidebar_bottom
465 *
466 * Fires at the bottom of the sidebar on Admin Passwords page.
467 *
468 * @since 4.1
469 */
470 do_action( 'mainwp_admin_pass_sidebar_bottom' );
471 ?>
472 </div>
473 <div style="clear:both"></div>
474 </form>
475 </div>
476 <?php
477 }
478 }
479
480 ?>
481