PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 5.0.2
MainWP Dashboard: Self-hosted WordPress Management for Agencies v5.0.2
6.2.3 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 All 156 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.0.2, at pages/page-mainwp-bulk-update-admin-passwords.php

479 lines 17.4 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 {
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 self::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 -- 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'] && 0 === count( $selected_groups ) ) || ( 'site' === $_POST['select_by'] && 0 === count( $selected_sites ) ) || ( 'client' === $_POST['select_by'] && 0 === count( $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 ( 0 === count( $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 ( count( $dbwebsites ) > 0 ) {
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 $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' ) ) );
170
171 MainWP_User::render_header( 'UpdateAdminPasswords' );
172 if ( ! $show_form ) {
173 self::render_modal( $dbwebsites, $output );
174 }
175 self::render_bulk_form( $websites );
176 MainWP_User::render_footer( 'UpdateAdminPasswords' );
177 }
178
179 /**
180 * Renders update password results.
181 *
182 * @param object $dbwebsites The websites object.
183 * @param object $output Result of update password.
184 */
185 public static function render_modal( $dbwebsites, $output ) {
186 ?>
187 <div class="ui modal" id="mainwp-reset-admin-passwords-modal">
188 <i class="close icon"></i>
189 <div class="header"><?php esc_html_e( 'Update Admin Password', 'mainwp' ); ?></div>
190 <div class="scrolling content">
191 <?php
192 /**
193 * Action: mainwp_reset_admin_pass_modal_top
194 *
195 * Fires at the top of the Update Admin Passwords modal.
196 *
197 * @since 4.1
198 */
199 do_action( 'mainwp_reset_admin_pass_modal_top' );
200 ?>
201 <div class="ui relaxed divided list">
202 <?php foreach ( $dbwebsites as $website ) : ?>
203 <div class="item">
204 <a href="<?php echo esc_url( admin_url( 'admin.php?page=managesites&dashboard=' . $website->id ) ); ?>"><?php echo esc_html( stripslashes( $website->name ) ); ?></a>
205 <span class="right floated content">
206 <?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 ?>
207 </span>
208 </div>
209 <?php endforeach; ?>
210 </div>
211 <?php
212 /**
213 * Action: mainwp_reset_admin_pass_modal_bottom
214 *
215 * Fires at the bottom of the Update Admin Passwords modal.
216 *
217 * @since 4.1
218 */
219 do_action( 'mainwp_reset_admin_pass_modal_bottom' );
220 ?>
221 </div>
222 <div class="actions">
223 </div>
224 </div>
225 <script type="text/javascript">
226 jQuery( '#mainwp-reset-admin-passwords-modal' ).modal( 'show' );
227 </script>
228 <?php
229 }
230
231 /**
232 * Renders bulk update administrator password form.
233 *
234 * @param object $websites Object containing child sites info.
235 *
236 * @uses \MainWP\Dashboard\MainWP_DB::fetch_object()
237 * @uses \MainWP\Dashboard\MainWP_DB::free_result()
238 */
239 public static function render_bulk_form( $websites ) {
240 $is_demo = MainWP_Demo_Handle::is_demo_mode();
241 /**
242 * Filter: mainwp_update_admin_password_complexity
243 *
244 * Filters the Password lenght for the Update Admin Password, Password field.
245 *
246 * Since 4.1
247 */
248 $pass_complexity = apply_filters( 'mainwp_update_admin_password_complexity', '24' );
249 ?>
250 <div class="ui alt segment" id="mainwp-bulk-update-admin-passwords">
251 <form action="" method="post" name="createuser" id="createuser">
252 <?php wp_nonce_field( 'mainwp-admin-nonce' ); ?>
253 <input type="hidden" name="security" value="<?php echo esc_attr( wp_create_nonce( 'mainwp_updateadminpassword' ) ); ?>"/>
254 <div class="mainwp-main-content" >
255 <div class="ui em hidden divider"></div>
256 <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-admin-pass-info-message' ) ) : ?>
257 <div class="ui info message">
258 <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-admin-pass-info-message"></i>
259 <?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>' ); ?>
260 </div>
261 <?php endif; ?>
262 <?php
263 /**
264 * Action: mainwp_admin_pass_before_users_table
265 *
266 * Fires before the Connected Admin Users mysql_list_tables
267 *
268 * @since 4.1
269 */
270 do_action( 'mainwp_admin_pass_before_users_table' );
271 ?>
272 <table id="mainwp-admin-users-table" class="ui single line unstackable table">
273 <thead>
274 <tr>
275 <th><?php esc_html_e( 'Site', 'mainwp' ); ?></th>
276 <th class="no-sort collapsing"><i class="sign in icon"></i></th>
277 <th><?php esc_html_e( 'Admin Username', 'mainwp' ); ?></th>
278 <th><?php esc_html_e( 'Admin Name', 'mainwp' ); ?></th>
279 <th><?php esc_html_e( 'Admin Email', 'mainwp' ); ?></th>
280 </tr>
281 </thead>
282 <tbody>
283 <?php
284 while ( $websites && $website = MainWP_DB::fetch_object( $websites ) ) :
285 $adminname = $website->adminname;
286 ?>
287 <tr>
288 <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>
289 <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>
290 <td><?php echo esc_html( $adminname ); ?></td>
291 <td><?php echo esc_html( $website->admin_nicename ); ?></td>
292 <td><?php echo esc_html( $website->admin_useremail ); ?></td>
293 </tr>
294 <?php endwhile; ?>
295 <?php MainWP_DB::free_result( $websites ); ?>
296 </tbody>
297 <tfoot>
298 <tr>
299 <th><?php esc_html_e( 'Site', 'mainwp' ); ?></th>
300 <th><i class="sign in icon"></i></th>
301 <th><?php esc_html_e( 'Admin Username', 'mainwp' ); ?></th>
302 <th><?php esc_html_e( 'Admin Name', 'mainwp' ); ?></th>
303 <th><?php esc_html_e( 'Admin Email', 'mainwp' ); ?></th>
304 </tr>
305 </tfoot>
306 </table>
307 <?php
308 /**
309 * Action: mainwp_admin_pass_after_users_table
310 *
311 * Fires after the Connected Admin Users mysql_list_tables
312 *
313 * @since 4.1
314 */
315 do_action( 'mainwp_admin_pass_after_users_table' );
316
317 $table_features = array(
318 'searching' => 'true',
319 'paging' => 'true',
320 'info' => 'true',
321 'colReorder' => 'true',
322 'stateSave' => 'true',
323 'responsive' => 'true',
324 );
325 /**
326 * Filter: mainwp_admin_users_table_fatures
327 *
328 * Filters Admin Users table features.
329 *
330 * @since 4.1
331 */
332 $table_features = apply_filters( 'mainwp_admin_users_table_fatures', $table_features );
333 ?>
334 <script type="text/javascript">
335 var responsive = <?php echo esc_html( $table_features['responsive'] ); ?>;
336 if( jQuery( window ).width() > 1140 ) {
337 responsive = false;
338 }
339 jQuery( document ).ready( function () {
340 jQuery( '#mainwp-admin-users-table' ).DataTable( {
341 "searching" : <?php echo esc_html( $table_features['searching'] ); ?>,
342 "paging" : <?php echo esc_html( $table_features['paging'] ); ?>,
343 "info" : <?php echo esc_html( $table_features['info'] ); ?>,
344 "colReorder" : <?php echo esc_html( $table_features['colReorder'] ); ?>,
345 "stateSave": <?php echo esc_html( $table_features['stateSave'] ); ?>,
346 "order": [],
347 "columnDefs": [ { "targets": 'no-sort', "orderable": false } ],
348 "responsive": responsive,
349 } );
350 } );
351 </script>
352 </div>
353 <div class="mainwp-side-content mainwp-no-padding">
354 <?php
355 /**
356 * Action: mainwp_admin_pass_sidebar_top
357 *
358 * Fires at the top of the sidebar on Admin Passwords page.
359 *
360 * @since 4.1
361 */
362 do_action( 'mainwp_admin_pass_sidebar_top' );
363 ?>
364 <div class="mainwp-select-sites ui accordion mainwp-sidebar-accordion">
365 <?php
366 /**
367 * Action: mainwp_admin_pass_before_select_sites
368 *
369 * Fires before the Select Sites section on the Admin Passwords page.
370 *
371 * @since 4.1
372 */
373 do_action( 'mainwp_admin_pass_before_select_sites' );
374 ?>
375 <div class="title active"><i class="dropdown icon"></i> <?php esc_html_e( 'Select Sites', 'mainwp' ); ?></div>
376 <div class="content active">
377 <?php
378 $sel_params = array(
379 'show_client' => true,
380 );
381 MainWP_UI_Select_Sites::select_sites_box( $sel_params );
382 ?>
383 </div>
384 <?php
385 /**
386 * Action: mainwp_admin_pass_after_select_sites
387 *
388 * Fires after the Select Sites section on the Admin Passwords page.
389 *
390 * @since 4.1
391 */
392 do_action( 'mainwp_admin_pass_after_select_sites' );
393 ?>
394 </div>
395 <div class="ui fitted divider"></div>
396 <div class="mainwp-search-options ui accordion mainwp-sidebar-accordion">
397 <div class="title active"><i class="dropdown icon"></i> <?php esc_html_e( 'Update Admin Password', 'mainwp' ); ?></div>
398 <div class="content active">
399 <?php
400 /**
401 * Action: mainwp_admin_pass_before_pass_form
402 *
403 * Fires before the New password form on the Admin Passwords page.
404 *
405 * @since 4.1
406 */
407 do_action( 'mainwp_admin_pass_before_pass_form' );
408 ?>
409 <div class="ui mini form">
410 <div class="field">
411 <label><?php esc_html_e( 'New Password', 'mainwp' ); ?></label>
412 <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">
413 <input class="hidden" value=" "/>
414 <input type="text" id="password" name="password" autocomplete="off" value="<?php echo esc_attr( wp_generate_password( $pass_complexity ) ); ?>">
415 </div>
416 <br />
417 <button class="ui basic green fluid button wp-generate-pw"><?php esc_html_e( 'Generate New Password', 'mainwp' ); ?></button>
418 </div>
419 </div>
420 <?php
421 /**
422 * Action: mainwp_admin_pass_after_pass_form
423 *
424 * Fires after the New password form on the Admin Passwords page.
425 *
426 * @since 4.1
427 */
428 do_action( 'mainwp_admin_pass_after_pass_form' );
429 ?>
430 </div>
431 </div>
432 <div class="ui fitted divider"></div>
433 <div class="mainwp-search-submit">
434 <?php
435 /**
436 * Action: mainwp_admin_pass_before_submit_button
437 *
438 * Fires before the Submit button on the Admin Passwords page.
439 *
440 * @since 4.1
441 */
442 do_action( 'mainwp_admin_pass_before_submit_button' );
443 if ( $is_demo ) {
444 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' ) . '"/>' );
445 } else {
446 ?>
447 <input type="submit" name="bulk_updateadminpassword" id="bulk_updateadminpassword" class="ui big green fluid button" value="<?php esc_attr_e( 'Update Password', 'mainwp' ); ?> "/>
448 <?php
449 }
450 /**
451 * Action: mainwp_admin_pass_after_submit_button
452 *
453 * Fires after the Submit button on the Admin Passwords page.
454 *
455 * @since 4.1
456 */
457 do_action( 'mainwp_admin_pass_after_submit_button' );
458 ?>
459 </div>
460 <?php
461 /**
462 * Action: mainwp_admin_pass_sidebar_bottom
463 *
464 * Fires at the bottom of the sidebar on Admin Passwords page.
465 *
466 * @since 4.1
467 */
468 do_action( 'mainwp_admin_pass_sidebar_bottom' );
469 ?>
470 </div>
471 <div style="clear:both"></div>
472 </form>
473 </div>
474 <?php
475 }
476 }
477
478 ?>
479