PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 5.3
MainWP Dashboard: Self-hosted WordPress Management for Agencies v5.3
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 5.2.2 5.3 All 153 releases
mainwp / pages / page-mainwp-user.php

page-mainwp-user.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies 5.3, at pages/page-mainwp-user.php

2,377 lines 113.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * MainWP Users Page
4 *
5 * This page is used to Manage Users on child sites.
6 *
7 * @package MainWP/User
8 */
9
10 namespace MainWP\Dashboard;
11
12 /**
13 * Class MainWP_User
14 *
15 * @uses page-mainwp-bulk-add::MainWP_Bulk_Add()
16 */
17 class MainWP_User { // 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 * Public static varable to hold Subpages information.
30 *
31 * @var array $subPages
32 */
33 public static $subPages;
34
35 /**
36 * Method init()
37 *
38 * Initiate hooks for the users page.
39 */
40 public static function init() {
41 /**
42 * This hook allows you to render the User page header via the 'mainwp-pageheader-user' action.
43 *
44 * @link http://codex.mainwp.com/#mainwp-pageheader-user
45 *
46 * This hook is normally used in the same context of 'mainwp-getsubpages-user'
47 * @link http://codex.mainwp.com/#mainwp-getsubpages-user
48 *
49 * @see \MainWP_User::render_header
50 */
51 add_action( 'mainwp-pageheader-user', array( static::get_class_name(), 'render_header' ) );
52
53 /**
54 * This hook allows you to render the User page footer via the 'mainwp-pagefooter-user' action.
55 *
56 * @link http://codex.mainwp.com/#mainwp-pagefooter-user
57 *
58 * This hook is normally used in the same context of 'mainwp-getsubpages-user'
59 * @link http://codex.mainwp.com/#mainwp-getsubpages-user
60 *
61 * @see \MainWP_User::render_footer
62 */
63 add_action( 'mainwp-pagefooter-user', array( static::get_class_name(), 'render_footer' ) );
64
65 add_action( 'mainwp_help_sidebar_content', array( static::get_class_name(), 'mainwp_help_content' ) );
66 }
67
68 /**
69 * Method init_menu()
70 *
71 * Initiate menu.
72 *
73 * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
74 */
75 public static function init_menu() {
76 $_page = add_submenu_page(
77 'mainwp_tab',
78 __( 'Users', 'mainwp' ),
79 '<span id="mainwp-Users">' . esc_html__( 'Users', 'mainwp' ) . '</span>',
80 'read',
81 'UserBulkManage',
82 array(
83 static::get_class_name(),
84 'render',
85 )
86 );
87
88 add_action( 'load-' . $_page, array( static::get_class_name(), 'on_load_page' ) );
89
90 add_submenu_page(
91 'mainwp_tab',
92 __( 'Users', 'mainwp' ),
93 '<div class="mainwp-hidden">' . esc_html__( 'Add New', 'mainwp' ) . '</div>',
94 'read',
95 'UserBulkAdd',
96 array(
97 static::get_class_name(),
98 'render_bulk_add',
99 )
100 );
101
102 add_submenu_page(
103 'mainwp_tab',
104 __( 'Import Users', 'mainwp' ),
105 '<div class="mainwp-hidden">' . esc_html__( 'Import Users', 'mainwp' ) . '</div>',
106 'read',
107 'BulkImportUsers',
108 array(
109 static::get_class_name(),
110 'render_bulk_import_users',
111 )
112 );
113
114 /**
115 * This hook allows you to add extra sub pages to the User page via the 'mainwp-getsubpages-user' filter.
116 *
117 * @link http://codex.mainwp.com/#mainwp-getsubpages-user
118 */
119 $sub_pages = apply_filters_deprecated( 'mainwp-getsubpages-user', array( array() ), '4.0.7.2', 'mainwp_getsubpages_user' ); // @deprecated Use 'mainwp_getsubpages_user' instead. NOSONAR - not IP.
120 static::$subPages = apply_filters( 'mainwp_getsubpages_user', $sub_pages );
121
122 if ( isset( static::$subPages ) && is_array( static::$subPages ) ) {
123 foreach ( static::$subPages as $subPage ) {
124 if ( MainWP_Menu::is_disable_menu_item( 3, 'UserBulk' . $subPage['slug'] ) ) {
125 continue;
126 }
127 add_submenu_page( 'mainwp_tab', $subPage['title'], '<div class="mainwp-hidden">' . esc_html( $subPage['title'] ) . '</div>', 'read', 'UserBulk' . $subPage['slug'], $subPage['callback'] );
128 }
129 }
130
131 static::init_left_menu( static::$subPages );
132 }
133
134 /**
135 * Initiates sub pages menu.
136 *
137 * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
138 */
139 public static function init_subpages_menu() {
140 ?>
141 <div id="menu-mainwp-Users" class="mainwp-submenu-wrapper">
142 <div class="wp-submenu sub-open" style="">
143 <div class="mainwp_boxout">
144 <div class="mainwp_boxoutin"></div>
145 <?php if ( \mainwp_current_user_can( 'dashboard', 'manage_users' ) ) { ?>
146 <a href="<?php echo esc_url( admin_url( 'admin.php?page=UserBulkManage' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'Manage Users', 'mainwp' ); ?></a>
147 <?php } ?>
148 <?php if ( ! MainWP_Menu::is_disable_menu_item( 3, 'UserBulkAdd' ) ) { ?>
149 <a href="<?php echo esc_url( admin_url( 'admin.php?page=UserBulkAdd' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'Add New', 'mainwp' ); ?></a>
150 <?php } ?>
151 <?php if ( ! MainWP_Menu::is_disable_menu_item( 3, 'BulkImportUsers' ) ) { ?>
152 <a href="<?php echo esc_url( admin_url( 'admin.php?page=BulkImportUsers' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'Import Users', 'mainwp' ); ?></a>
153 <?php } ?>
154 <?php if ( ! MainWP_Menu::is_disable_menu_item( 3, 'UpdateAdminPasswords' ) ) { ?>
155 <a href="<?php echo esc_url( admin_url( 'admin.php?page=UpdateAdminPasswords' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'Admin Passwords', 'mainwp' ); ?></a>
156 <?php } ?>
157 <?php
158 if ( isset( static::$subPages ) && is_array( static::$subPages ) ) {
159 foreach ( static::$subPages as $subPage ) {
160 if ( MainWP_Menu::is_disable_menu_item( 3, 'UserBulk' . $subPage['slug'] ) ) {
161 continue;
162 }
163 ?>
164 <a href="<?php echo esc_url( admin_url( 'admin.php?page=UserBulk' . $subPage['slug'] ) ); ?>" class="mainwp-submenu"><?php echo esc_html( $subPage['title'] ); ?></a>
165 <?php
166 }
167 }
168 ?>
169 </div>
170 </div>
171 </div>
172 <?php
173 }
174
175 /**
176 * Method get_manage_columns()
177 *
178 * Get columns to display.
179 *
180 * @return array $colums Array of columns to display on the page.
181 *
182 * @uses \MainWP\Dashboard\MainWP_Utility::enabled_wp_seo()
183 */
184 public static function get_manage_columns() {
185 return array(
186 'name' => esc_html__( 'Name', 'mainwp' ),
187 'username' => esc_html__( 'Username', 'mainwp' ),
188 'email' => esc_html__( 'E-mail', 'mainwp' ),
189 'role' => esc_html__( 'Role', 'mainwp' ),
190 'posts' => esc_html__( 'Posts', 'mainwp' ),
191 'website' => esc_html__( 'Website', 'mainwp' ),
192 );
193 }
194
195 /**
196 * Method on_load_page()
197 *
198 * Used during init_menu() to get the class names of,
199 * admin_head and get_hidden_columns.
200 *
201 * @return void
202 */
203 public static function on_load_page() {
204 add_action( 'mainwp_screen_options_modal_bottom', array( static::get_class_name(), 'hook_screen_options_modal_bottom' ), 10, 2 );
205 }
206
207 /**
208 * Method hook_screen_options_modal_bottom()
209 *
210 * Render screen options modal bottom.
211 */
212 public static function hook_screen_options_modal_bottom() {
213 $page = isset( $_GET['page'] ) ? wp_unslash( $_GET['page'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
214 if ( 'UserBulkManage' === $page ) {
215
216 $show_columns = get_user_option( 'mainwp_manageusers_show_columns' );
217
218 if ( ! is_array( $show_columns ) ) {
219 $show_columns = array();
220 }
221
222 $cols = static::get_manage_columns();
223 MainWP_UI::render_showhide_columns_settings( $cols, $show_columns, 'user' );
224 }
225 }
226
227 /**
228 * Initiates Users menu.
229 *
230 * @param array $subPages Sub pages array.
231 *
232 * @uses \MainWP\Dashboard\MainWP_Menu::add_left_menu()
233 * @uses \MainWP\Dashboard\MainWP_Menu::init_subpages_left_menu()
234 * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
235 */
236 public static function init_left_menu( $subPages = array() ) {
237 MainWP_Menu::add_left_menu(
238 array(
239 'title' => esc_html__( 'Users', 'mainwp' ),
240 'parent_key' => 'managesites',
241 'slug' => 'UserBulkManage',
242 'href' => 'admin.php?page=UserBulkManage',
243 'icon' => '<i class="user icon"></i>',
244 'desc' => 'Manage users on your child sites',
245 'leftsub_order' => 7,
246 ),
247 1
248 );
249
250 $init_sub_subleftmenu = array(
251 array(
252 'title' => esc_html__( 'Manage Users', 'mainwp' ),
253 'parent_key' => 'UserBulkManage',
254 'href' => 'admin.php?page=UserBulkManage',
255 'slug' => 'UserBulkManage',
256 'right' => 'manage_users',
257 ),
258 array(
259 'title' => esc_html__( 'Add New', 'mainwp' ),
260 'parent_key' => 'UserBulkManage',
261 'href' => 'admin.php?page=UserBulkAdd',
262 'slug' => 'UserBulkAdd',
263 'right' => '',
264 ),
265 array(
266 'title' => esc_html__( 'Import Users', 'mainwp' ),
267 'parent_key' => 'UserBulkManage',
268 'href' => 'admin.php?page=BulkImportUsers',
269 'slug' => 'BulkImportUsers',
270 'right' => '',
271 ),
272 array(
273 'title' => esc_html__( 'Admin Passwords', 'mainwp' ),
274 'parent_key' => 'UserBulkManage',
275 'href' => 'admin.php?page=UpdateAdminPasswords',
276 'slug' => 'UpdateAdminPasswords',
277 'right' => '',
278 ),
279 );
280
281 MainWP_Menu::init_subpages_left_menu( $subPages, $init_sub_subleftmenu, 'UserBulkManage', 'UserBulk' );
282
283 foreach ( $init_sub_subleftmenu as $item ) {
284 if ( MainWP_Menu::is_disable_menu_item( 3, $item['slug'] ) ) {
285 continue;
286 }
287 MainWP_Menu::add_left_menu( $item, 2 );
288 }
289 }
290
291 /**
292 * Method render_header()
293 *
294 * Render Users page header.
295 *
296 * @param string $shownPage The page slug shown at this moment.
297 *
298 * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
299 * @uses \MainWP\Dashboard\MainWP_UI::render_top_header()
300 * @uses \MainWP\Dashboard\MainWP_UI::render_page_navigation()
301 */
302 public static function render_header( $shownPage = '' ) { //phpcs:ignore -- NOSONAR - complex.
303 $params = array(
304 'title' => esc_html__( 'Users', 'mainwp' ),
305 );
306 MainWP_UI::render_top_header( $params );
307
308 $renderItems = array();
309
310 if ( \mainwp_current_user_can( 'dashboard', 'manage_users' ) ) {
311 $renderItems[] = array(
312 'title' => esc_html__( 'Manage Users', 'mainwp' ),
313 'href' => 'admin.php?page=UserBulkManage',
314 'active' => ( '' === $shownPage ) ? true : false,
315 );
316 }
317
318 if ( ! MainWP_Menu::is_disable_menu_item( 3, 'UserBulkAdd' ) ) {
319 $renderItems[] = array(
320 'title' => esc_html__( 'Add New', 'mainwp' ),
321 'href' => 'admin.php?page=UserBulkAdd',
322 'active' => ( 'Add' === $shownPage ) ? true : false,
323 );
324 }
325
326 if ( ! MainWP_Menu::is_disable_menu_item( 3, 'BulkImportUsers' ) ) {
327 $renderItems[] = array(
328 'title' => esc_html__( 'Import Users', 'mainwp' ),
329 'href' => 'admin.php?page=BulkImportUsers',
330 'active' => ( 'Import' === $shownPage ) ? true : false,
331 );
332 }
333
334 if ( ! MainWP_Menu::is_disable_menu_item( 3, 'UpdateAdminPasswords' ) ) {
335 $renderItems[] = array(
336 'title' => esc_html__( 'Admin Passwords', 'mainwp' ),
337 'href' => 'admin.php?page=UpdateAdminPasswords',
338 'active' => ( 'UpdateAdminPasswords' === $shownPage ) ? true : false,
339 );
340 }
341
342 if ( isset( static::$subPages ) && is_array( static::$subPages ) ) {
343 foreach ( static::$subPages as $subPage ) {
344 if ( MainWP_Menu::is_disable_menu_item( 3, 'UserBulk' . $subPage['slug'] ) ) {
345 continue;
346 }
347
348 $item = array();
349 $item['title'] = $subPage['title'];
350 $item['href'] = 'admin.php?page=UserBulk' . $subPage['slug'];
351 $item['active'] = ( $subPage['slug'] === $shownPage ) ? true : false;
352 $renderItems[] = $item;
353 }
354 }
355
356 MainWP_UI::render_page_navigation( $renderItems );
357 }
358
359 /**
360 * Method render_footer()
361 *
362 * Render Users page footer. Closes the page container.
363 */
364 public static function render_footer() {
365 echo '</div>';
366 }
367
368 /**
369 * Renders manage users dashboard.
370 *
371 * @return void
372 *
373 * @uses \MainWP\Dashboard\MainWP_Cache::get_cached_context()
374 */
375 public static function render() {
376 if ( ! \mainwp_current_user_can( 'dashboard', 'manage_users' ) ) {
377 \mainwp_do_not_have_permissions( esc_html__( 'manage users', 'mainwp' ) );
378
379 return;
380 }
381
382 $cachedSearch = MainWP_Cache::get_cached_context( 'Users' );
383
384 $selected_sites = array();
385 $selected_groups = array();
386 $selected_clients = array();
387
388 if ( null !== $cachedSearch ) {
389 if ( is_array( $cachedSearch['sites'] ) ) {
390 $selected_sites = $cachedSearch['sites'];
391 } elseif ( is_array( $cachedSearch['groups'] ) ) {
392 $selected_groups = $cachedSearch['groups'];
393 } elseif ( is_array( $cachedSearch['clients'] ) ) {
394 $selected_clients = $cachedSearch['clients'];
395 }
396 }
397
398 static::render_header( '' );
399 ?>
400 <div id="mainwp-manage-users" class="ui alt segment">
401 <div class="mainwp-main-content">
402 <div class="mainwp-actions-bar ui mini form">
403 <div class="ui grid">
404 <div class="ui two column row">
405 <div class="column">
406 <select class="ui mini dropdown" id="mainwp-bulk-actions">
407 <option value=""><?php esc_html_e( 'Bulk Actions', 'mainwp' ); ?></option>
408 <option value="edit"><?php esc_html_e( 'Edit', 'mainwp' ); ?></option>
409 <option value="delete"><?php esc_html_e( 'Delete', 'mainwp' ); ?></option>
410 <?php
411 /**
412 * Action: mainwp_users_bulk_action
413 *
414 * Adds new Bulk Actions option under on Manage Users.
415 *
416 * Suggested HTML Markup:
417 * <option value="Your custom value">Your custom label</option>
418 *
419 * @since 4.1
420 */
421 do_action( 'mainwp_users_bulk_action' );
422 ?>
423 </select>
424 <button class="ui mini button" id="mainwp-do-users-bulk-actions"><?php esc_html_e( 'Apply', 'mainwp' ); ?></button>
425 <?php
426 /**
427 * Users actions bar (left)
428 *
429 * Fires at the left side of the actions bar on the Users screen, after the Bulk Actions menu.
430 *
431 * @since 4.0
432 */
433 do_action( 'mainwp_users_actions_bar_left' );
434 ?>
435 </div>
436 <div class="right aligned column">
437 <?php
438 /**
439 * Users actions bar (right)
440 *
441 * Fires at the right side of the actions bar on the Users screen.
442 *
443 * @since 4.0
444 */
445 do_action( 'mainwp_users_actions_bar_right' );
446 ?>
447 </div>
448 </div>
449 </div>
450 </div>
451 <div id="mainwp-loading-users-row" style="display: none;">
452 <div class="ui active inverted dimmer">
453 <div class="ui indeterminate large text loader"><?php esc_html_e( 'Loading Users...', 'mainwp' ); ?>
454 <span id="mainwp_users_loading_info" class="mainwp-grabbing-info-note"><br /><?php esc_html_e( 'Automatically refreshing to get up to date information.', 'mainwp' ); ?></span>
455 </div>
456 </div>
457 </div>
458 <div class="ui segment" id="mainwp_users_wrap_table">
459 <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-manage-users-info-message' ) ) : ?>
460 <div class="ui info message">
461 <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-manage-users-info-message"></i>
462 <?php printf( esc_html__( 'Manage existing users on your child sites. Here you can Delete, Edit or Change Role for existing users. For additional help, please check this %1$shelp documentation%2$s.', 'mainwp' ), '<a href="https://kb.mainwp.com/docs/manage-users/" target="_blank">', '</a>' ); ?>
463 </div>
464 <?php endif; ?>
465 <div class="ui message" id="mainwp-message-zone" style="display:none"></div>
466 <?php static::render_table( true ); ?>
467 </div>
468 <div id="mainwp-update-users-box" class="ui segment">
469 <?php static::render_update_users(); ?>
470 </div>
471 </div>
472 <div class="mainwp-side-content mainwp-no-padding">
473 <?php
474 /**
475 * Action: mainwp_manage_users_sidebar_top
476 *
477 * Fires on top of the sidebar on Manage Users page.
478 *
479 * @since 4.1
480 */
481 do_action( 'mainwp_manage_users_sidebar_top' );
482 ?>
483 <div class="mainwp-select-sites ui accordion mainwp-sidebar-accordion">
484 <?php
485 /**
486 * Action: mainwp_manage_users_before_select_sites
487 *
488 * Fires before the Select Sites section on Manage Users page.
489 *
490 * @since 4.1
491 */
492 do_action( 'mainwp_manage_users_before_select_sites' );
493 ?>
494 <div class="title active"><i class="dropdown icon"></i> <?php esc_html_e( 'Select Sites', 'mainwp' ); ?></div>
495 <div class="content active">
496 <?php
497 $sel_params = array(
498 'selected_sites' => $selected_sites,
499 'selected_groups' => $selected_groups,
500 'selected_clients' => $selected_clients,
501 'class' => 'mainwp_select_sites_box_left',
502 'show_client' => true,
503 );
504 MainWP_UI_Select_Sites::select_sites_box( $sel_params );
505 ?>
506 </div>
507 <?php
508 /**
509 * Action: mainwp_manage_users_after_select_sites
510 *
511 * Fires after the Select Sites section on Manage Users page.
512 *
513 * @since 4.1
514 */
515 do_action( 'mainwp_manage_users_after_select_sites' );
516 ?>
517 </div>
518
519 <?php
520 $user_roles = array(
521 'subscriber' => esc_html__( 'Subscriber', 'mainwp' ),
522 'administrator' => esc_html__( 'Administrator', 'mainwp' ),
523 'editor' => esc_html__( 'Editor', 'mainwp' ),
524 'author' => esc_html__( 'Author', 'mainwp' ),
525 'contributor' => esc_html__( 'Contributor', 'mainwp' ),
526 );
527
528 $user_roles = apply_filters_deprecated( 'mainwp-users-manage-roles', array( $user_roles ), '4.0.7.2', 'mainwp_users_manage_roles' ); // @deprecated Use 'mainwp_users_manage_roles' instead. NOSONAR - not IP.
529 $user_roles = apply_filters( 'mainwp_users_manage_roles', $user_roles );
530
531 ?>
532
533 <div class="ui fitted divider"></div>
534 <div class="mainwp-search-options ui accordion mainwp-sidebar-accordion">
535 <div class="title active"><i class="dropdown icon"></i> <?php esc_html_e( 'Select Roles', 'mainwp' ); ?></div>
536 <div class="content active">
537 <?php
538 /**
539 * Action: mainwp_manage_users_before_search_options
540 *
541 * Fires before the Search Options section on Manage Users page.
542 *
543 * @since 4.1
544 */
545 do_action( 'mainwp_manage_users_before_search_options' );
546 ?>
547 <div class="ui mini form">
548 <div class="field" data-tooltip="<?php esc_attr_e( 'Select specific roles that you want to search for.', 'mainwp' ); ?>" data-inverted="" data-position="top right">
549 <select multiple="" class="ui fluid mini dropdown" id="mainwp_user_roles">
550 <option value=""><?php esc_html_e( 'Select wanted role(s)', 'mainwp' ); ?></option>
551 <?php
552 foreach ( $user_roles as $r => $n ) {
553 if ( empty( $r ) ) {
554 continue;
555 }
556 ?>
557 <option value="<?php echo esc_html( $r ); ?>"><?php echo esc_html( $n ); ?></option>
558 <?php
559 }
560 ?>
561 </select>
562 </div>
563 </div>
564 <?php
565 /**
566 * Action: mainwp_manage_users_after_search_options
567 *
568 * Fires after the Search Options section on Manage Users page.
569 *
570 * @since 4.1
571 */
572 do_action( 'mainwp_manage_users_after_search_options' );
573 ?>
574 </div>
575 </div>
576 <div class="ui fitted divider"></div>
577 <div class="mainwp-search-options ui accordion mainwp-sidebar-accordion">
578 <div class="title active"><i class="dropdown icon"></i> <?php esc_html_e( 'Search Options', 'mainwp' ); ?></div>
579 <div class="content active"><?php static::render_search_options(); ?></div>
580 </div>
581 <div class="ui fitted divider"></div>
582 <div class="mainwp-search-submit">
583 <?php
584 /**
585 * Action: mainwp_manage_users_before_submit_button
586 *
587 * Fires before the Submit Button on Manage Users page.
588 *
589 * @since 4.1
590 */
591 do_action( 'mainwp_manage_users_before_submit_button' );
592 ?>
593 <input type="button" name="mainwp_show_users" id="mainwp_show_users" class="ui green big fluid button" value="<?php esc_attr_e( 'Show Users', 'mainwp' ); ?>"/>
594 <?php
595 /**
596 * Action: mainwp_manage_users_after_submit_button
597 *
598 * Fires after the Submit Button on Manage Users page.
599 *
600 * @since 4.1
601 */
602 do_action( 'mainwp_manage_users_after_submit_button' );
603 ?>
604 </div>
605 <?php
606 /**
607 * Action: mainwp_manage_users_sidebar_bottom
608 *
609 * Fires at the bottom of the sidebar on Manage Users page.
610 *
611 * @since 4.1
612 */
613 do_action( 'mainwp_manage_users_sidebar_bottom' );
614 ?>
615 </div>
616 <div class="ui hidden clearing divider"></div>
617 </div>
618 <?php
619 static::render_footer( '' );
620 }
621
622 /**
623 * Method render_search_options()
624 *
625 * Render User page search.
626 *
627 * @uses \MainWP\Dashboard\MainWP_Cache::get_cached_context()
628 */
629 public static function render_search_options() {
630 $cachedSearch = MainWP_Cache::get_cached_context( 'Users' );
631 $statuses = isset( $cachedSearch['status'] ) ? $cachedSearch['status'] : array();
632 if ( $cachedSearch && isset( $cachedSearch['keyword'] ) ) {
633 $cachedSearch['keyword'] = trim( $cachedSearch['keyword'] );
634 }
635 ?>
636
637 <div class="ui mini form">
638 <div class="field" data-tooltip="<?php esc_attr_e( 'Enter specific username that you want to search for.', 'mainwp' ); ?>" data-inverted="" data-position="top right">
639 <div class="ui input fluid">
640 <input type="text" placeholder="<?php esc_attr_e( 'Username', 'mainwp' ); ?>" id="mainwp_search_users" class="text" value="<?php echo ( null !== $cachedSearch ) ? esc_attr( $cachedSearch['keyword'] ) : ''; ?>" />
641 </div>
642 </div>
643 </div>
644 <?php
645 if ( is_array( $statuses ) && ! empty( $statuses ) ) {
646 $status = '';
647 foreach ( $statuses as $st ) {
648 $status .= "'" . esc_html( $st ) . "',";
649 }
650 $status = rtrim( $status, ',' );
651 ?>
652 <script type="text/javascript">
653 jQuery( document ).ready( function () {
654 jQuery( '#mainwp_user_roles' ).dropdown( 'set selected', [<?php echo $status; //phpcs:ignore -- safe output. ?>] );
655 } );
656 </script>
657 <?php
658 }
659 }
660
661 /**
662 * Renders Edit Users Modal window.
663 */
664 public static function render_update_users() {
665
666 $editable_roles = array(
667 'donotupdate' => esc_html__( 'Do not update', 'mainwp' ),
668 'administrator' => esc_html__( 'Administrator', 'mainwp' ),
669 'subscriber' => esc_html__( 'Subscriber', 'mainwp' ),
670 'contributor' => esc_html__( 'Contributor', 'mainwp' ),
671 'author' => esc_html__( 'Author', 'mainwp' ),
672 'editor' => esc_html__( 'Editor', 'mainwp' ),
673 );
674
675 $editable_roles = apply_filters_deprecated( 'mainwp-users-manage-roles', array( $editable_roles ), '4.0.7.2', 'mainwp_users_manage_roles' ); // @deprecated Use 'mainwp_users_manage_roles' instead. NOSONAR - not IP.
676 $editable_roles = apply_filters( 'mainwp_users_manage_roles', $editable_roles );
677
678 $editable_roles[''] = esc_html__( '&mdash; No role for this site &mdash;', 'mainwp' );
679
680 ?>
681 <div id="mainwp-edit-users-modal" class="ui modal">
682 <i class="close icon"></i>
683 <div class="header"><?php esc_html_e( 'Edit User', 'mainwp' ); ?></div>
684 <div class="ui message"><?php esc_html_e( 'Empty fields will not be passed to child sites.', 'mainwp' ); ?></div>
685 <form id="update_user_profile">
686 <?php wp_nonce_field( 'mainwp-admin-nonce' ); ?>
687 <div class="ui segment">
688 <div class="ui form">
689 <h3><?php esc_html_e( 'Name', 'mainwp' ); ?></h3>
690 <div class="ui grid field">
691 <label class="six wide column middle aligned"><?php esc_html_e( 'Role', 'mainwp' ); ?></label>
692 <div class="ui six wide column">
693 <div class="ui left labeled input">
694 <select name="role" id="role">
695 <?php
696 foreach ( $editable_roles as $role_id => $role_name ) {
697 echo '<option value="' . esc_attr( $role_id ) . '" ' . ( 'donotupdate' === $role_id ? 'selected="selected"' : '' ) . '>' . esc_html( $role_name ) . '</option>';
698 }
699 ?>
700 </select>
701 </div>
702 </div>
703 </div>
704
705 <div class="ui grid field">
706 <label class="six wide column middle aligned"><?php esc_html_e( 'First Name', 'mainwp' ); ?></label>
707 <div class="ui six wide column">
708 <div class="ui left labeled input">
709 <input type="text" name="first_name" id="first_name" value="" class="regular-text" />
710 </div>
711 </div>
712 </div>
713
714 <div class="ui grid field">
715 <label class="six wide column middle aligned"><?php esc_html_e( 'Last Name', 'mainwp' ); ?></label>
716 <div class="ui six wide column">
717 <div class="ui left labeled input">
718 <input type="text" name="last_name" id="last_name" value="" class="regular-text" />
719 </div>
720 </div>
721 </div>
722
723 <div class="ui grid field">
724 <label class="six wide column middle aligned"><?php esc_html_e( 'Nickname', 'mainwp' ); ?></label>
725 <div class="ui six wide column">
726 <div class="ui left labeled input">
727 <input type="text" name="nickname" id="nickname" value="" class="regular-text" />
728 </div>
729 </div>
730 </div>
731
732 <div class="ui grid field">
733 <label class="six wide column middle aligned"><?php esc_html_e( 'Display name publicly as', 'mainwp' ); ?></label>
734 <div class="ui six wide column">
735 <div class="ui left labeled input">
736 <select name="display_name" id="display_name"></select>
737 </div>
738 </div>
739 </div>
740
741 <h3><?php esc_html_e( 'Contact Info', 'mainwp' ); ?></h3>
742
743 <div class="ui grid field">
744 <label class="six wide column middle aligned"><?php esc_html_e( 'Email', 'mainwp' ); ?></label>
745 <div class="ui six wide column">
746 <div class="ui left labeled input">
747 <input type="email" name="email" id="email" value="" class="regular-text ltr" />
748 </div>
749 </div>
750 </div>
751
752 <div class="ui grid field">
753 <label class="six wide column middle aligned"><?php esc_html_e( 'Website', 'mainwp' ); ?></label>
754 <div class="ui six wide column">
755 <div class="ui left labeled input">
756 <input type="url" name="url" id="url" value="" class="regular-text code" />
757 </div>
758 </div>
759 </div>
760
761 <h3><?php esc_html_e( 'About the user', 'mainwp' ); ?></h3>
762
763 <div class="ui grid field">
764 <label class="six wide column middle aligned"><?php esc_html_e( 'Biographical Info', 'mainwp' ); ?></label>
765 <div class="ui six wide column">
766 <div class="ui left labeled input">
767 <textarea name="description" id="description" rows="5" cols="30"></textarea>
768 <p class="description"><?php esc_html_e( 'Share a little biographical information to fill out your profile. This may be shown publicly.', 'mainwp' ); ?></p>
769 </div>
770 </div>
771 </div>
772
773 <h3><?php esc_html_e( 'Account Management', 'mainwp' ); ?></h3>
774
775 <div class="ui grid field">
776 <label class="six wide column middle aligned"><?php esc_html_e( 'Password', 'mainwp' ); ?></label>
777 <div class="ui six wide column">
778 <div class="ui left labeled action input">
779 <input class="hidden" value=" "/>
780 <input type="text" id="password" name="password" autocomplete="off" value="">
781 </div>
782 </div>
783 </div>
784 </div>
785 </div>
786 </form>
787 <?php
788 $is_demo = MainWP_Demo_Handle::is_demo_mode();
789 ?>
790 <div class="actions">
791 <div id="mainwp_update_password_error" style="display: none"></div>
792 <span id="mainwp_users_updating"><i class="ui active inline loader tiny"></i></span>
793 <?php
794 if ( $is_demo ) {
795 MainWP_Demo_Handle::get_instance()->render_demo_disable_button( '<input type="button" class="ui green button disabled" disabled="disabled" value="' . esc_attr__( 'Update', 'mainwp' ) . '">' );
796 } else {
797 ?>
798 <input type="button" class="ui green button" id="mainwp_btn_update_user" value="<?php esc_attr_e( 'Update', 'mainwp' ); ?>">
799 <?php } ?>
800 </div>
801 </div>
802 <?php
803 }
804
805 /**
806 * Renders Users Table.
807 *
808 * @param bool $cached true|false Cached or not.
809 * @param string $role Current user role.
810 * @param string $groups Current user groups.
811 * @param string $sites Current Child Sites the user is on.
812 * @param null $search Search field.
813 * @param mixed $clients Current Clients's Sites the user is on.
814 *
815 * @uses \MainWP\Dashboard\MainWP_Cache::echo_body()
816 */
817 public static function render_table( $cached = true, $role = '', $groups = '', $sites = '', $search = null, $clients = '' ) {
818
819 /**
820 * Action: mainwp_before_users_table
821 *
822 * Fires before the User table.
823 *
824 * @since 4.1
825 */
826 do_action( 'mainwp_before_users_table' );
827 ?>
828 <table id="mainwp-users-table" class="ui unstackable single line table" style="width:100%">
829 <thead>
830 <tr>
831 <th class="no-sort collapsing check-column"><span class="ui checkbox"><input id="cb-select-all-top" type="checkbox" /></span></th>
832 <?php do_action( 'mainwp_users_table_header' ); ?>
833 <th id="name"><?php esc_html_e( 'Name', 'mainwp' ); ?></th>
834 <th id="username"><?php esc_html_e( 'Username', 'mainwp' ); ?></th>
835 <th id="email"><?php esc_html_e( 'E-mail', 'mainwp' ); ?></th>
836 <th id="role"><?php esc_html_e( 'Role', 'mainwp' ); ?></th>
837 <th id="posts"><?php esc_html_e( 'Posts', 'mainwp' ); ?></th>
838 <th id="website"><?php esc_html_e( 'Website', 'mainwp' ); ?></th>
839 <th id="mainwp-users-actions" class="no-sort collapsing"></th>
840 </tr>
841 </thead>
842 <tbody id="mainwp-users-list">
843 <?php
844 if ( $cached ) {
845 MainWP_Cache::echo_body( 'Users' );
846 } else {
847 static::render_table_body( $role, $groups, $sites, $search, $clients );
848 }
849 ?>
850 </tbody>
851 </table>
852 <?php
853 /**
854 * Action: mainwp_after_users_table
855 *
856 * Fires after the User table.
857 *
858 * @since 4.1
859 */
860 do_action( 'mainwp_after_users_table' );
861
862 /**
863 * Filter: mainwp_users_table_fatures
864 *
865 * Filters the Manage Users table features.
866 *
867 * @since 4.1
868 */
869 $table_features = array(
870 'searching' => 'true',
871 'paging' => 'true',
872 'info' => 'true',
873 'stateSave' => 'true',
874 'scrollX' => 'true',
875 'responsive' => 'true',
876 'colReorder' => '{columns:":not(.check-column):not(:last-child)"}',
877 'order' => '[]',
878 );
879 $table_features = apply_filters( 'mainwp_users_table_fatures', $table_features );
880 ?>
881 <script type="text/javascript">
882 if (typeof responsive === 'undefined') {
883 let responsive = false; // to fix redeclaration for ajax request.
884 }
885 responsive = <?php echo esc_html( $table_features['responsive'] ); ?>;
886 if( jQuery( window ).width() > 1140 ) {
887 responsive = false;
888 }
889 jQuery( document ).ready( function () {
890 try {
891 jQuery( "#mainwp-users-table" ).DataTable().destroy(); // to fix re-init database issue.
892 $manage_users_table = jQuery( "#mainwp-users-table" ).DataTable( {
893 "responsive" : responsive,
894 "searching" : <?php echo esc_html( $table_features['searching'] ); ?>,
895 "colReorder" : <?php echo $table_features['colReorder']; // phpcs:ignore -- specical chars. ?>,
896 "stateSave": <?php echo esc_html( $table_features['stateSave'] ); ?>,
897 "paging": <?php echo esc_html( $table_features['paging'] ); ?>,
898 "info": <?php echo esc_html( $table_features['info'] ); ?>,
899 "order": <?php echo esc_html( $table_features['order'] ); ?>,
900 "scrollX" : <?php echo esc_html( $table_features['scrollX'] ); ?>,
901 "lengthMenu": [ [10, 25, 50, 100, -1], [10, 25, 50, 100, "All"] ],
902 "language" : { "emptyTable": "<?php esc_html_e( 'Please use the search options to find wanted users.', 'mainwp' ); ?>" },
903 "columnDefs": [ {
904 "targets": 'no-sort',
905 "orderable": false
906 } ],
907 "preDrawCallback": function() {
908 console.log('preDrawCallback mainwp-users-table');
909 setTimeout(() => {
910 jQuery('#mainwp-users-table .ui.dropdown').dropdown();
911 jQuery('#mainwp-users-table .ui.checkbox').checkbox();
912 mainwp_datatable_fix_menu_overflow();
913 mainwp_table_check_columns_init(); // ajax: to fix checkbox all.
914 }, 1000);
915 },
916 select: {
917 items: 'row',
918 style: 'multi+shift',
919 selector: 'tr>td:not(.not-selectable)'
920 }
921 } ).on('select', function (e, dt, type, indexes) {
922 if( 'row' == type ){
923 dt.rows(indexes)
924 .nodes()
925 .to$().find('td.check-column .ui.checkbox' ).checkbox('set checked');
926 }
927 }).on('deselect', function (e, dt, type, indexes) {
928 if( 'row' == type ){
929 dt.rows(indexes)
930 .nodes()
931 .to$().find('td.check-column .ui.checkbox' ).checkbox('set unchecked');
932 }
933 }).on( 'columns-reordered', function () {
934 console.log('columns-reordered');
935 setTimeout(() => {
936 jQuery( '#mainwp-users-table .ui.dropdown' ).dropdown();
937 jQuery( '#mainwp-users-table .ui.checkbox' ).checkbox();
938 mainwp_datatable_fix_menu_overflow();
939 mainwp_table_check_columns_init(); // ajax: to fix checkbox all.
940 }, 1000);
941 });
942 } catch ( err ) {
943 // to fix js error.
944 }
945
946 _init_manage_sites_screen = function() {
947 jQuery( '#mainwp-overview-screen-options-modal input[type=checkbox][id^="mainwp_show_column_"]' ).each( function() {
948 let col_id = jQuery( this ).attr( 'id' );
949 col_id = col_id.replace( "mainwp_show_column_", "" );
950 try {
951 $manage_users_table.column( '#' + col_id ).visible( jQuery(this).is( ':checked' ) );
952 } catch(err) {
953 // to fix js error.
954 }
955 } );
956 };
957 _init_manage_sites_screen();
958
959 } );
960 </script>
961 <?php
962 }
963
964 /**
965 * Renders the table body.
966 *
967 * @param string $role User Role.
968 * @param string $groups Usr Group.
969 * @param string $sites Users Sites.
970 * @param string $search Search field.
971 * @param mixed $clients Current Clients's Sites the user is on.
972 *
973 * @uses \MainWP\Dashboard\MainWP_Cache::init_cache()
974 * @uses \MainWP\Dashboard\MainWP_Cache::add_context()
975 * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
976 * @uses \MainWP\Dashboard\MainWP_DB::query()
977 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
978 * @uses \MainWP\Dashboard\MainWP_DB::get_sql_websites_by_group_id()
979 * @uses \MainWP\Dashboard\MainWP_DB::fetch_object()
980 * @uses \MainWP\Dashboard\MainWP_DB::free_result()
981 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
982 * @uses \MainWP\Dashboard\MainWP_Utility::map_site()
983 */
984 public static function render_table_body( $role = '', $groups = '', $sites = '', $search = '', $clients = '' ) { // phpcs:ignore -- NOSONAR - current complexity required to achieve desired results. Pull request solutions appreciated.
985 MainWP_Cache::init_cache( 'Users' );
986
987 $output = new \stdClass();
988 $output->errors = array();
989 $output->users = 0;
990
991 $data_fields = MainWP_System_Utility::get_default_map_site_fields();
992 $data_fields[] = 'users';
993
994 if ( 1 === (int) get_option( 'mainwp_optimize', 1 ) || MainWP_Demo_Handle::is_demo_mode() ) {
995
996 $check_users_role = false;
997
998 if ( ! empty( $role ) ) {
999 $roles = explode( ',', $role );
1000 if ( is_array( $roles ) ) {
1001 $check_users_role = true;
1002 }
1003 }
1004
1005 $dbwebsites = array();
1006 if ( ! empty( $sites ) ) {
1007 foreach ( $sites as $v ) {
1008 if ( MainWP_Utility::ctype_digit( $v ) ) {
1009 $website = MainWP_DB::instance()->get_website_by_id( $v );
1010 if ( empty( $website->sync_errors ) && ! MainWP_System_Utility::is_suspended_site( $website ) ) {
1011 $dbwebsites[ $website->id ] = $website;
1012 }
1013 }
1014 }
1015 }
1016 if ( ! empty( $groups ) ) {
1017 foreach ( $groups as $v ) {
1018 if ( MainWP_Utility::ctype_digit( $v ) ) {
1019 $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_by_group_id( $v ) );
1020 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
1021 if ( ! empty( $website->sync_errors ) || MainWP_System_Utility::is_suspended_site( $website ) ) {
1022 continue;
1023 }
1024 $dbwebsites[ $website->id ] = $website;
1025 }
1026 MainWP_DB::free_result( $websites );
1027 }
1028 }
1029 }
1030
1031 if ( ! empty( $clients ) && is_array( $clients ) ) {
1032 $websites = MainWP_DB_Client::instance()->get_websites_by_client_ids(
1033 $clients,
1034 array(
1035 'select_data' => $data_fields,
1036 )
1037 );
1038
1039 foreach ( $websites as $website ) {
1040 if ( ! empty( $website->sync_errors ) || MainWP_System_Utility::is_suspended_site( $website ) ) {
1041 continue;
1042 }
1043 $dbwebsites[ $website->id ] = $website;
1044 }
1045 }
1046
1047 if ( $dbwebsites ) {
1048 foreach ( $dbwebsites as $website ) {
1049 $allUsers = json_decode( $website->users, true );
1050 $allUsersCount = count( $allUsers );
1051 $search_user_role = array();
1052 if ( $check_users_role ) {
1053 for ( $i = 0; $i < $allUsersCount; $i++ ) {
1054 $user = $allUsers[ $i ];
1055 foreach ( $roles as $_role ) {
1056 if ( stristr( $user['role'], $_role ) ) {
1057 if ( ! in_array( $user['id'], $search_user_role ) ) {
1058 $search_user_role[] = $user['id'];
1059 }
1060 break;
1061 }
1062 }
1063 }
1064 }
1065 for ( $i = 0; $i < $allUsersCount; $i++ ) {
1066 $user = $allUsers[ $i ];
1067 if ( ! empty( $search ) && ! stristr( $user['login'], trim( $search ) ) && ! stristr( $user['display_name'], trim( $search ) ) && ! stristr( $user['email'], trim( $search ) ) ) {
1068 continue;
1069 }
1070
1071 if ( $check_users_role && ! in_array( $user['id'], $search_user_role ) ) {
1072 continue;
1073 }
1074
1075 $tmpUsers = array( $user );
1076 $output->users += static::users_search_handler_renderer( $tmpUsers, $website );
1077 }
1078 }
1079 }
1080 } else {
1081 $dbwebsites = array();
1082 if ( '' !== $sites ) {
1083 foreach ( $sites as $v ) {
1084 if ( MainWP_Utility::ctype_digit( $v ) ) {
1085 $website = MainWP_DB::instance()->get_website_by_id( $v );
1086 if ( empty( $website->sync_errors ) && ! MainWP_System_Utility::is_suspended_site( $website ) ) {
1087 $dbwebsites[ $website->id ] = MainWP_Utility::map_site(
1088 $website,
1089 $data_fields
1090 );
1091 }
1092 }
1093 }
1094 }
1095 if ( '' !== $groups ) {
1096 foreach ( $groups as $v ) {
1097 if ( MainWP_Utility::ctype_digit( $v ) ) {
1098 $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_by_group_id( $v ) );
1099 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
1100 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
1101 continue;
1102 }
1103 $dbwebsites[ $website->id ] = MainWP_Utility::map_site(
1104 $website,
1105 $data_fields
1106 );
1107 }
1108 MainWP_DB::free_result( $websites );
1109 }
1110 }
1111 }
1112
1113 if ( '' !== $clients && is_array( $clients ) ) {
1114 $websites = MainWP_DB_Client::instance()->get_websites_by_client_ids(
1115 $clients,
1116 array(
1117 'select_data' => $data_fields,
1118 )
1119 );
1120 if ( $websites ) {
1121 foreach ( $websites as $website ) {
1122 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
1123 continue;
1124 }
1125 $dbwebsites[ $website->id ] = MainWP_Utility::map_site(
1126 $website,
1127 $data_fields
1128 );
1129 }
1130 }
1131 }
1132
1133 $post_data = array(
1134 'role' => $role,
1135 'search' => '*' . trim( $search ) . '*',
1136 'search_columns' => 'user_login,display_name,user_email',
1137 );
1138
1139 MainWP_Connect::fetch_urls_authed(
1140 $dbwebsites,
1141 'search_users',
1142 $post_data,
1143 array(
1144 static::get_class_name(),
1145 'users_search_handler',
1146 ),
1147 $output
1148 );
1149 }
1150
1151 MainWP_Cache::add_context(
1152 'Users',
1153 array(
1154 'count' => $output->users,
1155 'keyword' => $search,
1156 'status' => ( isset( $_POST['role'] ) ? sanitize_text_field( wp_unslash( $_POST['role'] ) ) : 'administrator' ), // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1157 'sites' => '' !== $sites ? $sites : '',
1158 'groups' => '' !== $groups ? $groups : '',
1159 'clients' => ( '' !== $clients ) ? $clients : '',
1160 )
1161 );
1162
1163 // Sort if required.
1164
1165 if ( empty( $output->users ) ) {
1166 static::render_cache_not_found();
1167 }
1168 }
1169
1170 /**
1171 * Renders when cache is not found.
1172 *
1173 * @uses \MainWP\Dashboard\MainWP_Cache::add_body()
1174 */
1175 public static function render_cache_not_found() {
1176 ob_start();
1177 $newOutput = ob_get_clean();
1178 echo $newOutput; // phpcs:ignore WordPress.Security.EscapeOutput
1179 MainWP_Cache::add_body( 'Users', $newOutput );
1180 }
1181
1182 /**
1183 * Gets the selected users current role.
1184 *
1185 * @param string $role Selected Users Role.
1186 */
1187 private static function get_role( $role ) {
1188 if ( is_array( $role ) ) {
1189 $allowed_roles = array( 'subscriber', 'administrator', 'editor', 'author', 'contributor' );
1190 $ret = '';
1191 foreach ( $role as $ro ) {
1192 if ( in_array( $ro, $allowed_roles ) ) {
1193 $ret .= ucfirst( $ro ) . ', ';
1194 }
1195 }
1196 $ret = rtrim( $ret, ', ' );
1197 if ( '' === $ret ) {
1198 $ret = 'None';
1199 }
1200
1201 return $ret;
1202 }
1203
1204 return ucfirst( $role );
1205 }
1206
1207 /**
1208 * Renders Search results.
1209 *
1210 * @param array $users Users array.
1211 * @param object $website Object containing the child site info.
1212 *
1213 * @return mixed Search results table.
1214 *
1215 * @uses \MainWP\Dashboard\MainWP_Cache::add_body()
1216 */
1217 protected static function users_search_handler_renderer( $users, $website ) {
1218 $return = 0;
1219 $is_demo = MainWP_Demo_Handle::is_demo_mode();
1220
1221 foreach ( $users as $user ) {
1222 if ( ! is_array( $user ) ) {
1223 continue;
1224 }
1225 ob_start();
1226 ?>
1227 <tr>
1228 <td class="check-column"><span class="ui checkbox"><input type="checkbox" name="user[]" value="1"></span></td>
1229 <?php do_action( 'mainwp_users_table_column', $user, $website ); ?>
1230 <td class="name column-name">
1231 <?php echo ! empty( $user['display_name'] ) ? esc_html( $user['display_name'] ) : '&nbsp;'; ?>
1232 </td>
1233 <td class="username column-username"><strong><abbr title="<?php echo esc_attr( $user['login'] ); ?>"><?php echo esc_html( $user['login'] ); ?></abbr></strong></td>
1234 <td class="email column-email"><a href="mailto:<?php echo esc_attr( $user['email'] ); ?>"><?php echo esc_html( $user['email'] ); ?></a></td>
1235 <td class="role column-role"><?php echo static::get_role( $user['role'] ); // phpcs:ignore WordPress.Security.EscapeOutput ?></td>
1236 <td class="posts column-posts"><a href="<?php echo esc_url( admin_url( 'admin.php?page=PostBulkManage&siteid=' . intval( $website->id ) ) . '&userid=' . $user['id'] ); ?>"><?php echo esc_html( $user['post_count'] ); ?></a></td>
1237 <td class="website column-website"><a href="<?php echo esc_url( $website->url ); ?>" target="_blank"><?php echo esc_html( $website->url ); ?></a></td>
1238 <td class="right aligned not-selectable">
1239 <input class="userId" type="hidden" name="id" value="<?php echo esc_attr( $user['id'] ); ?>" />
1240 <input class="userName" type="hidden" name="name" value="<?php echo esc_attr( $user['login'] ); ?>" />
1241 <input class="websiteId" type="hidden" name="id" value="<?php echo intval( $website->id ); ?>" />
1242 <div class="ui left pointing dropdown icon mini basic green button" style="z-index: 999">
1243 <a href="javascript:void(0)"><i class="ellipsis horizontal icon"></i></a>
1244 <div class="menu">
1245 <a class="item user_getedit" href="#"><?php esc_html_e( 'Edit', 'mainwp' ); ?></a>
1246 <?php if ( ( 1 !== (int) $user['id'] ) && ( $user['login'] !== $website->adminname ) ) { ?>
1247 <a class="item user_submitdelete" href="#"><?php esc_html_e( 'Delete', 'mainwp' ); ?></a>
1248 <?php } elseif ( ( 1 === (int) $user['id'] ) || ( $user['login'] === $website->adminname ) ) { ?>
1249 <a href="javascript:void(0)" class="item" data-tooltip="This user is used for our secure link, it can not be deleted." data-inverted="" data-position="left center"><?php esc_html_e( 'Delete', 'mainwp' ); ?></a>
1250 <?php } ?>
1251 <?php if ( ! $is_demo ) : ?>
1252 <a class="item" href="<?php echo 'admin.php?page=SiteOpen&newWindow=yes&websiteid=' . intval( $website->id ); ?>&_opennonce=<?php echo esc_html( wp_create_nonce( 'mainwp-admin-nonce' ) ); ?>" data-tooltip="<?php esc_attr_e( 'Jump to the site WP Admin', 'mainwp' ); ?>" data-position="bottom right" data-inverted="" class="open_newwindow_wpadmin ui green basic icon button" target="_blank"><?php esc_html_e( 'Go to WP Admin', 'mainwp' ); ?></a>
1253 <?php else : ?>
1254 <a class="item" href="<?php echo esc_url( $website->url ) . 'wp-admin.html'; ?>" data-tooltip="<?php esc_attr_e( 'Jump to the site WP Admin', 'mainwp' ); ?>" data-position="bottom right" data-inverted="" class="open_newwindow_wpadmin ui green basic icon button" target="_blank"><?php esc_html_e( 'Go to WP Admin', 'mainwp' ); ?></a>
1255 <?php endif; ?>
1256 <?php
1257 /**
1258 * Action: mainwp_users_table_action
1259 *
1260 * Adds a new item in the Actions menu in Manage Users table.
1261 *
1262 * Suggested HTML markup:
1263 * <a class="item" href="Your custom URL">Your custom label</a>
1264 *
1265 * @param array $user Array containing the user data.
1266 * @param array $website Object containing the website data.
1267 *
1268 * @since 4.1
1269 */
1270 do_action( 'mainwp_users_table_action', $user, $website );
1271 ?>
1272 </div>
1273 </div>
1274 </td>
1275 </tr>
1276 <?php
1277 $newOutput = ob_get_clean();
1278 echo $newOutput; // phpcs:ignore WordPress.Security.EscapeOutput
1279 MainWP_Cache::add_body( 'Users', $newOutput );
1280 ++$return;
1281 }
1282
1283 return $return;
1284 }
1285
1286 /**
1287 * Handles user search.
1288 *
1289 * @param mixed $data Search data.
1290 * @param mixed $website Child Site.
1291 * @param mixed $output Output to pass to static::users_search_handler_renderer().
1292 *
1293 * @uses \MainWP\Dashboard\MainWP_Error_Helper::get_error_message()
1294 * @uses \MainWP\Dashboard\MainWP_Exception
1295 * @uses \MainWP\Dashboard\MainWP_System_Utility::get_child_response()
1296 */
1297 public static function users_search_handler( $data, $website, &$output ) {
1298 if ( MainWP_Demo_Handle::get_instance()->is_demo_website( $website ) ) {
1299 return;
1300 }
1301 if ( 0 < preg_match( '/<mainwp>(.*)<\/mainwp>/', $data, $results ) ) {
1302 $result = $results[1];
1303 $users = MainWP_System_Utility::get_child_response( base64_decode( $result ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
1304 unset( $results );
1305 $output->users += static::users_search_handler_renderer( $users, $website );
1306 unset( $users );
1307 } else {
1308 $output->errors[ $website->id ] = MainWP_Error_Helper::get_error_message( new MainWP_Exception( 'NOMAINWP', $website->url ) );
1309 }
1310 }
1311
1312 /**
1313 * Deletes user.
1314 */
1315 public static function delete() {
1316 static::action( 'delete' );
1317 die( wp_json_encode( array( 'result' => esc_html__( 'User has been deleted', 'mainwp' ) ) ) );
1318 }
1319
1320 /**
1321 * Edits user.
1322 */
1323 public static function edit() {
1324 $information = static::action( 'edit' );
1325 wp_send_json( $information );
1326 }
1327
1328 /**
1329 * Updates user.
1330 */
1331 public static function update_user() {
1332 static::action( 'update_user' );
1333 die( wp_json_encode( array( 'result' => esc_html__( 'User has been updated', 'mainwp' ) ) ) );
1334 }
1335
1336 /**
1337 * Updates users password.
1338 */
1339 public static function update_password() {
1340 static::action( 'update_password' );
1341 die( wp_json_encode( array( 'result' => esc_html__( 'User password has been updated', 'mainwp' ) ) ) );
1342 }
1343
1344 /**
1345 * Users actions.
1346 *
1347 * @param mixed $pAction Action to perform delete|update_user|update_password.
1348 * @param string $extra Additional Roles to add if any.
1349 *
1350 * @return mixed $information User update info that is returned.
1351 * @throws \MainWP_Exception Error message.
1352 *
1353 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
1354 * @uses \MainWP\Dashboard\MainWP_DB::update_website_values()
1355 * @uses \MainWP\Dashboard\MainWP_Error_Helper::get_error_message()
1356 * @uses \MainWP\Dashboard\MainWP_Exception
1357 * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
1358 * @uses \MainWP\Dashboard\MainWP_System_Utility::can_edit_website()
1359 */
1360 public static function action( $pAction, $extra = '' ) { // phpcs:ignore -- NOSONAR - current complexity required to achieve desired results. Pull request solutions appreciated.
1361
1362 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1363 $userId = isset( $_POST['userId'] ) ? sanitize_text_field( wp_unslash( $_POST['userId'] ) ) : false;
1364 $userName = isset( $_POST['userName'] ) ? sanitize_text_field( wp_unslash( $_POST['userName'] ) ) : '';
1365 $websiteId = isset( $_POST['websiteId'] ) ? sanitize_text_field( wp_unslash( $_POST['websiteId'] ) ) : false;
1366 $pass = isset( $_POST['update_password'] ) ? rawurldecode( wp_unslash( $_POST['update_password'] ) ) : '';
1367
1368 if ( function_exists( '\mb_convert_encoding' ) ) {
1369 $pass = \mb_convert_encoding( $pass, 'ISO-8859-1', 'UTF-8' );
1370 } else {
1371 $pass = utf8_decode( $pass ); // to compatible.
1372 }
1373
1374 if ( empty( $userId ) || empty( $websiteId ) ) {
1375 die( wp_json_encode( array( 'error' => esc_html__( 'Site ID or user ID not found. Please reload the page and try again.', 'mainwp' ) ) ) );
1376 }
1377
1378 $website = MainWP_DB::instance()->get_website_by_id( $websiteId );
1379
1380 if ( MainWP_System_Utility::is_suspended_site( $website ) ) {
1381 die(
1382 wp_json_encode(
1383 array(
1384 'error' => esc_html__( 'Suspended site.', 'mainwp' ),
1385 'errorCode' => 'SUSPENDED_SITE',
1386 )
1387 )
1388 );
1389 }
1390
1391 if ( ! MainWP_System_Utility::can_edit_website( $website ) ) {
1392 die( wp_json_encode( array( 'error' => esc_html__( 'You can not edit this website!', 'mainwp' ) ) ) );
1393 }
1394
1395 if ( ( 'delete' === $pAction ) && ( $website->adminname === $userName ) ) {
1396 die( wp_json_encode( array( 'error' => esc_html__( 'This user is used for our secure link, it can not be deleted.', 'mainwp' ) ) ) );
1397 }
1398
1399 if ( 'update_user' === $pAction ) {
1400 $user_data = isset( $_POST['user_data'] ) ? wp_unslash( $_POST['user_data'] ) : '';
1401 parse_str( $user_data, $extra );
1402 if ( $website->adminname === $userName && is_array( $extra ) && isset( $extra['role'] ) ) {
1403 unset( $extra['role'] );
1404 }
1405
1406 if ( ! empty( $pass ) ) {
1407 $extra['pass1'] = $pass;
1408 $extra['pass2'] = $pass;
1409 }
1410 }
1411 // phpcs:enable
1412
1413 $optimize = ( 1 === (int) get_option( 'mainwp_optimize', 1 ) ) ? 1 : 0;
1414
1415 /**
1416 * Action: mainwp_before_user_action
1417 *
1418 * Fires before user edit/delete/update_user/update_password actions.
1419 *
1420 * @since 4.1
1421 */
1422 do_action( 'mainwp_before_user_action', $pAction, $userId, $extra, $pass, $optimize, $website );
1423
1424 try {
1425 $information = MainWP_Connect::fetch_url_authed(
1426 $website,
1427 'user_action',
1428 array(
1429 'action' => $pAction,
1430 'id' => $userId,
1431 'extra' => $extra,
1432 'user_pass' => $pass,
1433 'optimize' => $optimize,
1434 )
1435 );
1436
1437 if ( is_array( $information ) && isset( $information['status'] ) && ( 'SUCCESS' === $information['status'] ) ) {
1438 $data = isset( $information['other_data']['users_data'] ) ? $information['other_data']['users_data'] : array(); // user actions data.
1439
1440 /**
1441 * Fires immediately after user action.
1442 *
1443 * @since 4.5.1.1
1444 */
1445 do_action( 'mainwp_user_action', $website, $pAction, $data, $extra, $optimize );
1446 }
1447 } catch ( MainWP_Exception $e ) {
1448 die( wp_json_encode( array( 'error' => MainWP_Error_Helper::get_error_message( $e ) ) ) );
1449 }
1450
1451 /**
1452 * Action: mainwp_after_user_action
1453 *
1454 * Fires after user edit/delete/update_user/update_password actions.
1455 *
1456 * @since 4.1
1457 */
1458 do_action( 'mainwp_after_user_action', $information, $pAction, $userId, $extra, $pass, $optimize, $website );
1459
1460 if ( is_array( $information ) && isset( $information['error'] ) ) {
1461 wp_send_json( array( 'error' => esc_html( $information['error'] ) ) );
1462 }
1463
1464 if ( ! isset( $information['status'] ) || ( 'SUCCESS' !== $information['status'] ) ) {
1465 die( wp_json_encode( array( 'error' => esc_html__( 'Unexpected error.', 'mainwp' ) ) ) );
1466 } elseif ( 'update_user' === $pAction ) {
1467 if ( $optimize && isset( $information['users'] ) ) {
1468 $websiteValues['users'] = wp_json_encode( $information['users'] );
1469 MainWP_DB::instance()->update_website_values( $websiteId, $websiteValues );
1470 }
1471 }
1472
1473 // This user is used for our secure link, you can not change the role.
1474 if ( 'edit' === $pAction && $website->adminname === $userName && is_array( $information ) && isset( $information['user_data'] ) ) {
1475 $information['is_secure_admin'] = 1;
1476 }
1477
1478 return $information;
1479 }
1480
1481 /**
1482 * Renders the Add New user form.
1483 */
1484 public static function render_bulk_add() {
1485
1486 /**
1487 * Filter: mainwp_new_user_password_complexity
1488 *
1489 * Filters the Password lenght for the Add New user, Password field.
1490 *
1491 * Since 4.1
1492 */
1493 $pass_complexity = apply_filters( 'mainwp_new_user_password_complexity', '24' );
1494 static::render_header( 'Add' );
1495 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1496 ?>
1497 <div class="ui alt segment" id="mainwp-add-users">
1498 <?php
1499 /**
1500 * Action: mainwp_before_new_user_form
1501 *
1502 * Fires before the Add New user form.
1503 *
1504 * @since 4.1
1505 */
1506 do_action( 'mainwp_before_new_user_form' );
1507 ?>
1508 <form action="" method="post" name="createuser" id="createuser" class="add:users: validate">
1509 <?php wp_nonce_field( 'mainwp-admin-nonce' ); ?>
1510 <div class="mainwp-main-content">
1511 <div class="ui hidden divider"></div>
1512 <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-add-user-info-message' ) ) : ?>
1513 <div class="ui info message">
1514 <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-add-user-info-message"></i>
1515 <?php printf( esc_html__( 'Use the provided form to create a new user on your child site. For additional help, please check this %1$shelp documentation%2$s.', 'mainwp' ), '<a href="https://kb.mainwp.com/docs/create-a-new-user/" target="_blank">', '</a>' ); ?>
1516 </div>
1517 <?php endif; ?>
1518 <div class="ui message" id="mainwp-message-zone" style="display:none;"></div>
1519 <div id="mainwp-add-new-user-form" >
1520 <?php
1521 /**
1522 * Action: mainwp_before_new_user_form_fields
1523 *
1524 * Fires before the Add New user form fields.
1525 *
1526 * @since 4.1
1527 */
1528 do_action( 'mainwp_before_new_user_form_fields' );
1529 ?>
1530 <div class="ui form">
1531 <div class="ui grid field">
1532 <label class="six wide column middle aligned"><?php esc_html_e( 'Username', 'mainwp' ); ?></label>
1533 <div class="ui six wide column">
1534 <div class="ui left labeled input">
1535 <input type="text" id="user_login" name="user_login" value="<?php echo ( isset( $_POST['user_login'] ) ) ? esc_html( sanitize_text_field( wp_unslash( $_POST['user_login'] ) ) ) : ''; ?>">
1536 </div>
1537 </div>
1538 </div>
1539 <div class="ui grid field">
1540 <label class="six wide column middle aligned"><?php esc_html_e( 'E-mail', 'mainwp' ); ?></label>
1541 <div class="ui six wide column">
1542 <div class="ui left labeled input">
1543 <input type="text" id="email" name="email" value="<?php echo ( isset( $_POST['email'] ) ) ? esc_html( sanitize_text_field( wp_unslash( $_POST['email'] ) ) ) : ''; ?>">
1544 </div>
1545 </div>
1546 </div>
1547 <div class="ui grid field">
1548 <label class="six wide column middle aligned"><?php esc_html_e( 'First Name', 'mainwp' ); ?></label>
1549 <div class="ui six wide column">
1550 <div class="ui left labeled input">
1551 <input type="text" id="first_name" name="first_name" value="<?php echo ( isset( $_POST['first_name'] ) ) ? esc_html( sanitize_text_field( wp_unslash( $_POST['first_name'] ) ) ) : ''; ?>">
1552 </div>
1553 </div>
1554 </div>
1555 <div class="ui grid field">
1556 <label class="six wide column middle aligned"><?php esc_html_e( 'Last Name', 'mainwp' ); ?></label>
1557 <div class="ui six wide column">
1558 <div class="ui left labeled input">
1559 <input type="text" id="last_name" name="last_name" value="<?php echo ( isset( $_POST['last_name'] ) ) ? esc_html( sanitize_text_field( wp_unslash( $_POST['last_name'] ) ) ) : ''; ?>">
1560 </div>
1561 </div>
1562 </div>
1563 <div class="ui grid field">
1564 <label class="six wide column middle aligned"><?php esc_html_e( 'Website', 'mainwp' ); ?></label>
1565 <div class="ui six wide column">
1566 <div class="ui left labeled input">
1567 <input type="text" id="url" name="url" value="<?php echo ( isset( $_POST['url'] ) ) ? esc_url_raw( wp_unslash( $_POST['url'] ) ) : ''; ?>">
1568 </div>
1569 </div>
1570 </div>
1571 <div class="ui grid field">
1572 <label class="six wide column middle aligned"><?php esc_html_e( 'Password', 'mainwp' ); ?></label>
1573 <div class="ui six wide column">
1574 <div class="ui left labeled action input">
1575 <input class="hidden" value=" "/>
1576 <input type="text" id="password" name="password" autocomplete="off" value="<?php echo esc_attr( wp_generate_password( $pass_complexity ) ); ?>">
1577 <button class="ui green right button wp-generate-pw"><?php esc_html_e( 'Generate Password', 'mainwp' ); ?></button>
1578 </div>
1579 </div>
1580 </div>
1581
1582 <div class="ui grid field">
1583 <label class="six wide column middle aligned"><?php esc_html_e( 'Send Password?', 'mainwp' ); ?></label>
1584 <div class="six wide column ui toggle checkbox">
1585 <input type="checkbox" name="send_password" id="send_password" <?php echo ( isset( $_POST['send_password'] ) ) ? esc_html( 'checked' ) : ''; ?> >
1586 </div>
1587 </div>
1588
1589 <?php
1590 $user_roles = array(
1591 'subscriber' => esc_html__( 'Subscriber', 'mainwp' ),
1592 'administrator' => esc_html__( 'Administrator', 'mainwp' ),
1593 'editor' => esc_html__( 'Editor', 'mainwp' ),
1594 'author' => esc_html__( 'Author', 'mainwp' ),
1595 'contributor' => esc_html__( 'Contributor', 'mainwp' ),
1596 );
1597 $user_roles = apply_filters_deprecated( 'mainwp-users-manage-roles', array( $user_roles ), '4.0.7.2', 'mainwp_users_manage_roles' ); // @deprecated Use 'mainwp_users_manage_roles' instead. NOSONAR - not IP.
1598 $user_roles = apply_filters( 'mainwp_users_manage_roles', $user_roles );
1599 ?>
1600
1601 <div class="ui grid field">
1602 <label class="six wide column middle aligned"><?php esc_html_e( 'Role', 'mainwp' ); ?></label>
1603 <div class="six wide column">
1604 <select class="ui dropdown" name="role" id="role">
1605 <?php
1606 foreach ( $user_roles as $r => $n ) {
1607 if ( empty( $r ) ) {
1608 continue;
1609 }
1610 ?>
1611 <option value="<?php echo esc_html( $r ); ?>" <?php echo ( isset( $_POST['role'] ) && $_POST['role'] === $r ) ? esc_html( 'selected' ) : ''; ?>><?php echo esc_html( $n ); ?></option>
1612 <?php
1613 }
1614 ?>
1615 </select>
1616 </div>
1617 </div>
1618
1619 </div>
1620 <?php
1621 /**
1622 * Action: mainwp_after_new_user_form_fields
1623 *
1624 * Fires after the Add New user form fields.
1625 *
1626 * @since 4.1
1627 */
1628 do_action( 'mainwp_after_new_user_form_fields' );
1629 ?>
1630 </div>
1631 </div>
1632 <div class="mainwp-side-content mainwp-no-padding">
1633 <?php
1634 /**
1635 * Action: mainwp_add_new_user_sidebar_top
1636 *
1637 * Fires at the top of the sidebar on Add New user page.
1638 *
1639 * @since 4.1
1640 */
1641 do_action( 'mainwp_add_new_user_sidebar_top' );
1642 ?>
1643 <div class="mainwp-select-sites ui accordion mainwp-sidebar-accordion">
1644 <?php
1645 /**
1646 * Action: mainwp_add_new_user_before_select_sites
1647 *
1648 * Fires before the Select Sites section on the Add New user page.
1649 *
1650 * @since 4.1
1651 */
1652 do_action( 'mainwp_add_new_user_before_select_sites' );
1653 ?>
1654 <div class="title active"><i class="dropdown icon"></i> <?php esc_html_e( 'Select Sites', 'mainwp' ); ?></div>
1655 <div class="content active">
1656 <?php
1657 $sel_params = array(
1658 'show_client' => true,
1659 );
1660 MainWP_UI_Select_Sites::select_sites_box( $sel_params );
1661 ?>
1662 </div>
1663 <?php
1664 /**
1665 * Action: mainwp_add_new_user_after_select_sites
1666 *
1667 * Fires after the Select Sites section on the Add New user page.
1668 *
1669 * @since 4.1
1670 */
1671 do_action( 'mainwp_add_new_user_after_select_sites' );
1672 ?>
1673 </div>
1674 <div class="ui fitted divider"></div>
1675 <div class="mainwp-search-submit">
1676 <?php
1677 /**
1678 * Action: mainwp_add_new_user_before_submit_button
1679 *
1680 * Fires before the Submit button on the Add New user page.
1681 *
1682 * @since 4.1
1683 */
1684 do_action( 'mainwp_add_new_user_before_submit_button' );
1685
1686 $is_demo = MainWP_Demo_Handle::is_demo_mode();
1687 if ( $is_demo ) {
1688 MainWP_Demo_Handle::get_instance()->render_demo_disable_button( '<input type="button" class="ui green big button disabled" disabled="disabled" value="' . esc_attr__( 'Add New User', 'mainwp' ) . '"/>' );
1689 } else {
1690 ?>
1691 <input type="button" name="createuser" id="bulk_add_createuser" class="ui big green fluid button" value="<?php esc_attr_e( 'Add New User', 'mainwp' ); ?> "/>
1692 <?php
1693 }
1694 /**
1695 * Action: mainwp_add_new_user_after_submit_button
1696 *
1697 * Fires after the Submit button on the Add New user page.
1698 *
1699 * @since 4.1
1700 */
1701 do_action( 'mainwp_add_new_user_after_submit_button' );
1702 ?>
1703 </div>
1704 <?php
1705 /**
1706 * Action: mainwp_add_new_user_sidebar_bottom
1707 *
1708 * Fires at the bottom of the sidebar on Add New user page.
1709 *
1710 * @since 4.1
1711 */
1712 do_action( 'mainwp_add_new_user_sidebar_bottom' );
1713 ?>
1714 </div>
1715 <div style="clear:both"></div>
1716 </form>
1717 <?php
1718 /**
1719 * Action: mainwp_after_new_user_form
1720 *
1721 * Fires after the Add New user form.
1722 *
1723 * @since 4.1
1724 */
1725 do_action( 'mainwp_after_new_user_form' );
1726 ?>
1727 </div>
1728 <?php
1729 // phpcs:enable
1730
1731 static::render_footer( 'Add' );
1732 }
1733
1734 /**
1735 * Renders bulk Import Users form.
1736 *
1737 * @return void
1738 */
1739 public static function render_bulk_import_users() {
1740 if ( isset( $_FILES['import_user_file_bulkupload'] ) && isset( $_FILES['import_user_file_bulkupload']['error'] ) && UPLOAD_ERR_OK === $_FILES['import_user_file_bulkupload']['error'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing
1741 static::render_bulk_upload();
1742 return;
1743 }
1744 ?>
1745 <?php static::render_header( 'Import' ); ?>
1746 <div id="MainWP_Bulk_AddUser">
1747 <form action="" method="post" name="createuser" id="createuser" class="add:users: validate" enctype="multipart/form-data">
1748 <?php wp_nonce_field( 'mainwp-admin-nonce' ); ?>
1749 <?php static::render_import_users(); ?>
1750 </form>
1751 </div>
1752 <?php
1753 static::render_footer( 'Import' );
1754 }
1755
1756 /**
1757 * Method render_import_users()
1758 *
1759 * Render Import Users page.
1760 */
1761 public static function render_import_users() {
1762 ?>
1763 <div class="ui segment" id="mainwp-import-sites">
1764 <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-import-users-info-message' ) ) : ?>
1765 <div class="ui info message">
1766 <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-import-users-info-message"></i>
1767 <?php printf( esc_html__( 'Use the form to bulk import users. You can download the sample CSV file to see how to fomat the import file properly. For additional help, please check this %1$shelp documentation%2$s.', 'mainwp' ), '<a href="https://kb.mainwp.com/docs/import-users/" target="_blank">', '</a>' ); ?>
1768 </div>
1769 <?php endif; ?>
1770
1771 <div id="mainwp-message-zone" class="ui message" style="display:none"></div>
1772 <?php
1773 /**
1774 * Action: mainwp_before_import_users
1775 *
1776 * Fires above the Import Users section.
1777 *
1778 * @since 4.1
1779 */
1780 do_action( 'mainwp_before_import_users' );
1781 $is_demo = MainWP_Demo_Handle::is_demo_mode();
1782 ?>
1783 <div id="mainwp-message-zone" class="ui message" style="display:none"></div>
1784 <div class="ui form">
1785 <form method="POST" action="" enctype="multipart/form-data" id="mainwp_managesites_bulkadd_form">
1786 <?php wp_nonce_field( 'mainwp-admin-nonce' ); ?>
1787 <div class="ui grid field">
1788 <label class="six wide column middle aligned"><?php esc_html_e( 'Upload the CSV file', 'mainwp' ); ?></label>
1789 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'Click to upload the import file.', 'mainwp' ); ?>" data-inverted="" data-position="left center">
1790 <div class="ui file input">
1791 <input type="file" name="import_user_file_bulkupload" id="import_user_file_bulkupload" accept="text/comma-separated-values" />
1792 </div>
1793 </div>
1794 </div>
1795 <div class="ui grid field">
1796 <label class="six wide column middle aligned"><?php esc_html_e( 'CSV file contains a header', 'mainwp' ); ?></label>
1797 <div class="ui toggle checkbox" data-tooltip="<?php esc_attr_e( 'Enable if the import file contains a header.', 'mainwp' ); ?>" data-inverted="" data-position="left center">
1798 <input type="checkbox" name="import_user_chk_header_first" checked="checked" id="import_user_chk_header_first" value="1" />
1799 </div>
1800 </div>
1801 <div class="ui divider"></div>
1802 <?php
1803 if ( $is_demo ) {
1804 MainWP_Demo_Handle::get_instance()->render_demo_disable_button( '<input type="button" class="ui big green button disabled" disabled="disabled" value="' . esc_attr__( 'Import Users', 'mainwp' ) . '"/>' );
1805 } else {
1806 ?>
1807 <input type="button" name="createuser" id="bulk_import_createuser" class="ui big green button" value="<?php esc_attr_e( 'Import Users', 'mainwp' ); ?>" />
1808 <?php } ?>
1809 <a href="<?php echo esc_url( MAINWP_PLUGIN_URL . 'assets/csv/sample_users.csv' ); ?>" class="ui big green basic right floated button"><?php esc_html_e( 'Download Sample CSV file', 'mainwp' ); ?></a>
1810 </form>
1811 </div>
1812 <?php
1813 /**
1814 * Action: mainwp_after_import_users
1815 *
1816 * Fires under the Import Users section.
1817 *
1818 * @since 4.1
1819 */
1820 do_action( 'mainwp_after_import_users' );
1821 ?>
1822 </div>
1823 <?php
1824 }
1825
1826 /**
1827 * Method do_bulk_add()
1828 *
1829 * Bulk User addition $_POST Handler.
1830 *
1831 * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
1832 * @uses \MainWP\Dashboard\MainWP_DB::query()
1833 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
1834 * @uses \MainWP\Dashboard\MainWP_DB::fetch_object()
1835 * @uses \MainWP\Dashboard\MainWP_DB::free_result()
1836 * @uses \MainWP\Dashboard\MainWP_Bulk_Add::get_class_name()
1837 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
1838 * @uses \MainWP\Dashboard\MainWP_Utility::map_site()
1839 */
1840 public static function do_bulk_add() { // phpcs:ignore -- NOSONAR -Current complexity is required to achieve desired results. Pull request solutions appreciated.
1841 $errors = array();
1842 $errorFields = array();
1843
1844 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1845 if ( isset( $_POST['select_by'] ) ) {
1846 $selected_sites = ( isset( $_POST['selected_sites'] ) && is_array( $_POST['selected_sites'] ) ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['selected_sites'] ) ) : array();
1847 $selected_groups = ( isset( $_POST['selected_groups'] ) && is_array( $_POST['selected_groups'] ) ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['selected_groups'] ) ) : array();
1848 $selected_clients = ( isset( $_POST['selected_clients'] ) && is_array( $_POST['selected_clients'] ) ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['selected_clients'] ) ) : array();
1849
1850 if ( ( 'group' === $_POST['select_by'] && empty( $selected_groups ) ) || ( 'site' === $_POST['select_by'] && empty( $selected_sites ) ) || ( 'client' === $_POST['select_by'] && empty( $selected_clients ) ) ) {
1851 $errors[] = esc_html__( 'Please select at least one website or group or client.', 'mainwp' );
1852 }
1853 } else {
1854 $errors[] = esc_html__( 'Please select at least one website or group or client.', 'mainwp' );
1855 }
1856
1857 if ( ! isset( $_POST['user_login'] ) || '' === $_POST['user_login'] ) {
1858 $errorFields[] = 'user_login';
1859 }
1860
1861 if ( ! isset( $_POST['email'] ) || '' === $_POST['email'] ) {
1862 $errorFields[] = 'email';
1863 }
1864
1865 $allowed_roles = array( 'subscriber', 'administrator', 'editor', 'author', 'contributor' );
1866 $cus_roles = array();
1867 $cus_roles = apply_filters_deprecated( 'mainwp-users-manage-roles', array( $cus_roles ), '4.0.7.2', 'mainwp_users_manage_roles' ); // @deprecated Use 'mainwp_users_manage_roles' instead. NOSONAR - not IP.
1868 $cus_roles = apply_filters( 'mainwp_users_manage_roles', $cus_roles );
1869
1870 if ( is_array( $cus_roles ) && ! empty( $cus_roles ) ) {
1871 $cus_roles = array_keys( $cus_roles );
1872 $allowed_roles = array_merge( $allowed_roles, $cus_roles );
1873 }
1874
1875 if ( ! isset( $_POST['role'] ) || ! in_array( $_POST['role'], $allowed_roles ) ) {
1876 $errorFields[] = 'role';
1877 }
1878
1879 $data_fields = MainWP_System_Utility::get_default_map_site_fields();
1880
1881 if ( empty( $errors ) && empty( $errorFields ) ) {
1882 $user_to_add = array(
1883 'user_pass' => isset( $_POST['pass1'] ) ? wp_unslash( $_POST['pass1'] ) : '',
1884 'user_login' => isset( $_POST['user_login'] ) ? sanitize_text_field( wp_unslash( $_POST['user_login'] ) ) : '',
1885 'user_url' => isset( $_POST['url'] ) ? esc_url_raw( wp_unslash( $_POST['url'] ) ) : '',
1886 'user_email' => isset( $_POST['email'] ) ? sanitize_text_field( wp_unslash( $_POST['email'] ) ) : '',
1887 'first_name' => isset( $_POST['first_name'] ) ? sanitize_text_field( wp_unslash( $_POST['first_name'] ) ) : '',
1888 'last_name' => isset( $_POST['last_name'] ) ? sanitize_text_field( wp_unslash( $_POST['last_name'] ) ) : '',
1889 'role' => isset( $_POST['role'] ) ? sanitize_text_field( wp_unslash( $_POST['role'] ) ) : '',
1890 );
1891
1892 $dbwebsites = array();
1893
1894 if ( isset( $_POST['select_by'] ) && 'site' === $_POST['select_by'] ) {
1895 foreach ( $selected_sites as $k ) {
1896 if ( MainWP_Utility::ctype_digit( $k ) ) {
1897 $website = MainWP_DB::instance()->get_website_by_id( $k );
1898 if ( empty( $website->sync_errors ) && ! MainWP_System_Utility::is_suspended_site( $website ) ) {
1899 $dbwebsites[ $website->id ] = MainWP_Utility::map_site(
1900 $website,
1901 $data_fields
1902 );
1903 }
1904 }
1905 }
1906 } elseif ( isset( $_POST['select_by'] ) && 'client' === $_POST['select_by'] ) {
1907 $websites = MainWP_DB_Client::instance()->get_websites_by_client_ids(
1908 $selected_clients,
1909 array(
1910 'select_data' => $data_fields,
1911 )
1912 );
1913
1914 if ( $websites ) {
1915 foreach ( $websites as $website ) {
1916 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
1917 continue;
1918 }
1919 $dbwebsites[ $website->id ] = MainWP_Utility::map_site(
1920 $website,
1921 $data_fields
1922 );
1923 }
1924 }
1925 } else {
1926 foreach ( $selected_groups as $k ) {
1927 if ( MainWP_Utility::ctype_digit( $k ) ) {
1928 $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_by_group_id( $k ) );
1929 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
1930 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
1931 continue;
1932 }
1933 $dbwebsites[ $website->id ] = MainWP_Utility::map_site(
1934 $website,
1935 $data_fields
1936 );
1937 }
1938 MainWP_DB::free_result( $websites );
1939 }
1940 }
1941 }
1942
1943 if ( ! empty( $dbwebsites ) ) {
1944 $post_data = array(
1945 'new_user' => base64_encode( wp_json_encode( $user_to_add ) ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
1946 'send_password' => ( isset( $_POST['send_password'] ) ? intval( $_POST['send_password'] ) : '' ),
1947 );
1948 $output = new \stdClass();
1949 $output->ok = array();
1950 $output->errors = array();
1951
1952 /**
1953 * Action: mainwp_before_user_create
1954 *
1955 * Fires before user create.
1956 *
1957 * @since 4.1
1958 */
1959 do_action( 'mainwp_before_user_create', $post_data, $dbwebsites );
1960
1961 MainWP_Connect::fetch_urls_authed(
1962 $dbwebsites,
1963 'newuser',
1964 $post_data,
1965 array(
1966 MainWP_Bulk_Add::get_class_name(),
1967 'posting_bulk_handler',
1968 ),
1969 $output
1970 );
1971
1972 /**
1973 * Action: mainwp_after_user_create
1974 *
1975 * Fires after user create.
1976 *
1977 * @since 4.1
1978 */
1979 do_action( 'mainwp_after_user_create', $output, $post_data, $dbwebsites );
1980 }
1981
1982 $countSites = 0;
1983 $countRealItems = 0;
1984 foreach ( $dbwebsites as $website ) {
1985 if ( isset( $output->ok[ $website->id ] ) && 1 === (int) $output->ok[ $website->id ] ) {
1986 ++$countSites;
1987 ++$countRealItems;
1988 }
1989 }
1990 static::render_bulk_add_modal( $dbwebsites, $output );
1991 } else {
1992 echo wp_json_encode( array( $errorFields, $errors ) );
1993 }
1994 // phpcs:enable
1995 }
1996
1997 /**
1998 * Renders Bulk User addition Modal window.
1999 *
2000 * @param mixed $dbwebsites Child sites list.
2001 * @param mixed $output Modal window content.
2002 */
2003 public static function render_bulk_add_modal( $dbwebsites, $output ) {
2004 // phpcs:disable WordPress.Security.EscapeOutput
2005 ?>
2006 <div id="mainwp-creating-new-user-modal" class="ui modal">
2007 <i class="close icon"></i>
2008 <div class="header"><?php esc_html_e( 'New User', 'mainwp' ); ?></div>
2009 <div class="content">
2010 <div class="ui middle aligned divided selection list">
2011 <?php foreach ( $dbwebsites as $website ) : ?>
2012 <div class="item ui grid">
2013 <span class="content"><a href="<?php echo esc_url( admin_url( 'admin.php?page=managesites&dashboard=' . $website->id ) ); ?>"><?php echo esc_html( stripslashes( $website->name ) ); ?></a></span>
2014 <span class="right floated content"><?php echo isset( $output->ok[ $website->id ] ) && 1 === (int) $output->ok[ $website->id ] ? '<i class="check green icon"></i> ' : '<i class="times red icon"></i> ' . $output->errors[ $website->id ]; ?></span>
2015 </div>
2016 <?php endforeach; ?>
2017 </div>
2018 </div>
2019 <div class="actions">
2020 </div>
2021 </div>
2022 <?php
2023 // phpcs:enable
2024 }
2025
2026 /**
2027 * Renders Import Users Modal window.
2028 *
2029 * @uses \MainWP\Dashboard\MainWP_System_Utility::get_wp_file_system()
2030 * @uses \MainWP\Dashboard\MainWP_Utility::starts_with()
2031 */
2032 public static function render_bulk_upload() { //phpcs:ignore -- NOSONAR - complex.
2033 static::render_header( 'Import' );
2034 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
2035 $errors = array();
2036 if ( isset( $_FILES['import_user_file_bulkupload']['error'] ) && UPLOAD_ERR_OK === $_FILES['import_user_file_bulkupload']['error'] ) {
2037 if ( isset( $_FILES['import_user_file_bulkupload']['tmp_name'] ) && is_uploaded_file( $_FILES['import_user_file_bulkupload']['tmp_name'] ) ) {
2038 $tmp_path = isset( $_FILES['import_user_file_bulkupload']['tmp_name'] ) ? sanitize_text_field( wp_unslash( $_FILES['import_user_file_bulkupload']['tmp_name'] ) ) : '';
2039 MainWP_System_Utility::get_wp_file_system();
2040 // phpcs:enable
2041 /**
2042 * WordPress files system object.
2043 *
2044 * @global object
2045 */
2046 global $wp_filesystem;
2047
2048 $content = $wp_filesystem->get_contents( $tmp_path );
2049 $lines = explode( "\r\n", $content );
2050
2051 if ( is_array( $lines ) && ! empty( $lines ) ) {
2052 $i = 0;
2053 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
2054 if ( ! empty( $_POST['import_user_chk_header_first'] ) ) {
2055 $header_line = trim( $lines[0] ) . "\n";
2056 unset( $lines[0] );
2057 }
2058 // phpcs:enable
2059
2060 foreach ( $lines as $originalLine ) {
2061
2062 $line = trim( $originalLine );
2063
2064 if ( MainWP_Utility::starts_with( $line, '#' ) ) {
2065 continue;
2066 }
2067
2068 $items = str_getcsv( $line, ',' );
2069
2070 if ( 3 > count( $items ) ) {
2071 continue;
2072 }
2073
2074 $import_data = array(
2075 'user_login' => trim( $items[0] ),
2076 'email' => trim( $items[1] ),
2077 'first_name' => trim( $items[2] ),
2078 'last_name' => trim( $items[3] ),
2079 'url' => trim( $items[4] ),
2080 'pass1' => trim( $items[5] ),
2081 'send_password' => intval( $items[6] ),
2082 'role' => trim( strtolower( $items[7] ) ),
2083 'select_sites' => trim( $items[8] ),
2084 'select_groups' => trim( $items[9] ),
2085 );
2086 $encoded = wp_json_encode( $import_data );
2087 ?>
2088 <input type="hidden" id="user_import_csv_line_<?php echo intval( $i + 1 ); ?>" original-line="<?php echo esc_html( $line ); ?>" encoded-data="<?php echo esc_html( $encoded ); ?>" />
2089 <?php
2090 ++$i;
2091 }
2092 $header_line = trim( $header_line );
2093 ?>
2094 <div class="ui modal" id="mainwp-import-users-modal">
2095 <i class="close icon"></i>
2096 <div class="header"><?php esc_html_e( 'Importing new users and add them to your sites.', 'mainwp' ); ?></div>
2097 <div class="scrolling content">
2098 <?php
2099 /**
2100 * Action: mainwp_import_users_modal_top
2101 *
2102 * Fires on the top of the Import Users modal.
2103 *
2104 * @since 4.1
2105 */
2106 do_action( 'mainwp_import_users_modal_top' );
2107 ?>
2108 <div id="MainWPBulkUploadUserLoading" style="display: none;"><i class="ui active inline loader tiny"></i> <?php esc_html_e( 'Importing Users', 'mainwp' ); ?></div>
2109 <input type="hidden" id="import_user_do_import" value="1"/>
2110 <input type="hidden" id="import_user_total_import" value="<?php echo esc_attr( $i ); ?>"/>
2111 <p>
2112 <div class="import_user_import_listing" id="import_user_import_logging">
2113 <pre class="log"><?php echo esc_html( $header_line ) . "\n"; ?></pre>
2114 </div>
2115 </p>
2116 <div id="import_user_import_failed_rows" style="display: none;">
2117 <span><?php echo esc_html( $header_line ); ?></span>
2118 </div>
2119 <?php
2120 /**
2121 * Action: mainwp_import_users_modal_bottom
2122 *
2123 * Fires on the bottom of the Import Users modal.
2124 *
2125 * @since 4.1
2126 */
2127 do_action( 'mainwp_import_users_modal_bottom' );
2128 ?>
2129 </div>
2130 <div class="actions">
2131 <input type="button" name="import_user_btn_import" id="import_user_btn_import" class="ui basic button" value="<?php esc_attr_e( 'Pause', 'mainwp' ); ?>"/>
2132 <input type="button" name="import_user_btn_save_csv" id="import_user_btn_save_csv" style="display:none;" class="ui basic green button" value="<?php esc_attr_e( 'Save failed', 'mainwp' ); ?>"/>
2133 </div>
2134 </div>
2135 <script type="text/javascript">
2136 jQuery( document ).ready( function () {
2137 jQuery( "#mainwp-import-users-modal" ).modal( {
2138 closable: false,
2139 onHide: function() {
2140 location.href = 'admin.php?page=BulkImportUsers';
2141 }
2142 } ).modal( 'show' );
2143 } );
2144 </script>
2145
2146 <?php
2147
2148 } else {
2149 $errors[] = esc_html__( 'Invalid data. Please make sure that the Import file has been formated properly.', 'mainwp' );
2150 }
2151 } else {
2152 $errors[] = esc_html__( 'File could not be uploaded. Temporary file cold not be created. Please make sure that the tmpfile() PHP function is enabled on your server.', 'mainwp' );
2153 }
2154 } else {
2155 $errors[] = esc_html__( 'File could not be uploaded. Please try again. If process keeps failing, please review MainWP Knowledgebase, and if you still have issues, please let us know in the MainWP Community.', 'mainwp' );
2156 }
2157
2158 if ( ! empty( $errors ) ) {
2159 ?>
2160 <?php foreach ( $errors as $error ) { ?>
2161 <div class="ui error message"><?php echo esc_html( $error ); ?></div>
2162 <?php } ?>
2163
2164 <a href="<?php echo esc_url( get_admin_url() ); ?>admin.php?page=UserBulkAdd" class="ui button"><?php esc_html_e( 'Add New', 'mainwp' ); ?></a>
2165 <a href="<?php echo esc_url( get_admin_url() ); ?>admin.php?page=mainwp_tab" class="ui button"><?php esc_html_e( 'Return to Overview', 'mainwp' ); ?></a>
2166 <?php
2167 }
2168
2169 static::render_footer( 'Import' );
2170 }
2171
2172 /**
2173 * User Import $_POST handler.
2174 *
2175 * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
2176 * @uses \MainWP\Dashboard\MainWP_DB_Common::get_group_by_name()
2177 * @uses \MainWP\Dashboard\MainWP_DB::query()
2178 * @uses \MainWP\Dashboard\MainWP_DB::get_websites_by_url()
2179 * @uses \MainWP\Dashboard\MainWP_DB::get_sql_websites_by_group_id()
2180 * @uses \MainWP\Dashboard\MainWP_DB::fetch_object()
2181 * @uses \MainWP\Dashboard\MainWP_DB::free_result()
2182 * @uses \MainWP\Dashboard\MainWP_Bulk_Add::get_class_name()
2183 * @uses \MainWP\Dashboard\MainWP_Utility::map_site()
2184 */
2185 public static function do_import() { // phpcs:ignore -- NOSONAR -Current complexity is required to achieve desired results. Pull request solutions appreciated.
2186
2187 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
2188 $selected_sites = ( isset( $_POST['select_sites'] ) && is_array( $_POST['select_sites'] ) ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['select_sites'] ) ) : array();
2189 $selected_groups = ( isset( $_POST['select_groups'] ) && is_array( $_POST['select_groups'] ) ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['select_groups'] ) ) : array();
2190
2191 $data_fields = MainWP_System_Utility::get_default_map_site_fields();
2192 $data_fields[] = 'users';
2193
2194 $user_to_add = array(
2195 'user_pass' => isset( $_POST['pass1'] ) ? wp_unslash( $_POST['pass1'] ) : '',
2196 'user_login' => isset( $_POST['user_login'] ) ? sanitize_text_field( wp_unslash( $_POST['user_login'] ) ) : '',
2197 'user_url' => isset( $_POST['url'] ) ? wp_unslash( $_POST['url'] ) : '',
2198 'user_email' => isset( $_POST['email'] ) ? sanitize_text_field( wp_unslash( $_POST['email'] ) ) : '',
2199 'first_name' => isset( $_POST['first_name'] ) ? sanitize_text_field( wp_unslash( $_POST['first_name'] ) ) : '',
2200 'last_name' => isset( $_POST['last_name'] ) ? sanitize_text_field( wp_unslash( $_POST['last_name'] ) ) : '',
2201 'role' => isset( $_POST['role'] ) ? sanitize_text_field( wp_unslash( $_POST['role'] ) ) : '',
2202 );
2203
2204 $ret = array();
2205 $dbwebsites = array();
2206 $not_valid = array();
2207 $error_sites = '';
2208 if ( isset( $_POST['select_by'] ) && 'site' === $_POST['select_by'] ) {
2209 foreach ( $selected_sites as $url ) {
2210 if ( ! empty( $url ) ) {
2211 $website = MainWP_DB::instance()->get_websites_by_url( $url );
2212 if ( ! empty( $website ) ) {
2213 $website = current( $website );
2214 }
2215 if ( $website ) {
2216 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
2217 if ( '' !== $website->sync_errors ) {
2218 $err_imp = esc_html__( 'Site disconnected:', 'mainwp' );
2219 } else {
2220 $err_imp = esc_html__( 'Site suspended:', 'mainwp' );
2221 }
2222 $not_valid[] = $err_imp . ' ' . $website->url;
2223 $error_sites .= $website->url . ';';
2224 continue;
2225 }
2226 $dbwebsites[ $website->id ] = MainWP_Utility::map_site(
2227 $website,
2228 $data_fields
2229 );
2230 } else {
2231 $not_valid[] = esc_html__( 'Unexisting website. Please try again.', 'mainwp' ) . ' ' . $url;
2232 $error_sites .= $url . ';';
2233 }
2234 }
2235 }
2236 } else {
2237 foreach ( $selected_groups as $group ) {
2238 if ( MainWP_DB_Common::instance()->get_group_by_name( $group ) ) {
2239 $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_by_group_name( $group ) );
2240 if ( $websites ) {
2241 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
2242 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
2243 if ( '' !== $website->sync_errors ) {
2244 $err_imp = esc_html__( 'Site disconnected:', 'mainwp' );
2245 } else {
2246 $err_imp = esc_html__( 'Site suspended:', 'mainwp' );
2247 }
2248 $not_valid[] = $err_imp . ' ' . $website->url;
2249 $error_sites .= $website->url . ';';
2250 continue;
2251 }
2252 $dbwebsites[ $website->id ] = MainWP_Utility::map_site(
2253 $website,
2254 $data_fields
2255 );
2256 }
2257 MainWP_DB::free_result( $websites );
2258 } else {
2259 $not_valid[] = esc_html__( 'No websites assigned to the selected group.', 'mainwp' ) . ' ' . $group;
2260 $error_sites .= $group . ';';
2261 }
2262 } else {
2263 $not_valid[] = esc_html__( 'Unexisting group selected. Please try again.', 'mainwp' ) . ' ' . $group;
2264 $error_sites .= $group . ';';
2265 }
2266 }
2267 }
2268
2269 if ( ! empty( $dbwebsites ) ) {
2270 $post_data = array(
2271 'new_user' => base64_encode( wp_json_encode( $user_to_add ) ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
2272 'send_password' => ( isset( $_POST['send_password'] ) ? intval( $_POST['send_password'] ) : '' ),
2273 );
2274 $output = new \stdClass();
2275 $output->ok = array();
2276 $output->errors = array();
2277
2278 /**
2279 * Action: mainwp_before_user_create
2280 *
2281 * Fires before user create.
2282 *
2283 * @since 4.1
2284 */
2285 do_action( 'mainwp_before_user_create', $post_data, $dbwebsites );
2286
2287 MainWP_Connect::fetch_urls_authed(
2288 $dbwebsites,
2289 'newuser',
2290 $post_data,
2291 array(
2292 MainWP_Bulk_Add::get_class_name(),
2293 'posting_bulk_handler',
2294 ),
2295 $output
2296 );
2297
2298 /**
2299 * Action: mainwp_after_user_create
2300 *
2301 * Fires after user create.
2302 *
2303 * @since 4.1
2304 */
2305 do_action( 'mainwp_after_user_create', $output, $post_data, $dbwebsites );
2306 }
2307
2308 $ret['ok_list'] = array();
2309 $ret['error_list'] = array();
2310 foreach ( $dbwebsites as $website ) {
2311 if ( isset( $output->ok[ $website->id ] ) && 1 === (int) $output->ok[ $website->id ] ) {
2312 $ret['ok_list'][] = 'New user(s) created: ' . esc_html( stripslashes( $website->name ) );
2313 } else {
2314 $ret['error_list'][] = esc_html( $output->errors[ $website->id ] . ' ' . stripslashes( $website->name ) );
2315 $error_sites .= $website->url . ';';
2316 }
2317 }
2318
2319 foreach ( $not_valid as $val ) {
2320 $ret['error_list'][] = $val;
2321 }
2322
2323 $ret['failed_logging'] = '';
2324 if ( ! empty( $error_sites ) ) {
2325 $error_sites = rtrim( $error_sites, ';' );
2326
2327 $user_login = isset( $_POST['user_login'] ) ? sanitize_text_field( wp_unslash( $_POST['user_login'] ) ) : '';
2328 $email = isset( $_POST['email'] ) ? sanitize_text_field( wp_unslash( $_POST['email'] ) ) : '';
2329 $first_name = isset( $_POST['first_name'] ) ? sanitize_text_field( wp_unslash( $_POST['first_name'] ) ) : '';
2330 $last_name = isset( $_POST['last_name'] ) ? sanitize_text_field( wp_unslash( $_POST['last_name'] ) ) : '';
2331 $url = isset( $_POST['url'] ) ? sanitize_text_field( wp_unslash( $_POST['url'] ) ) : '';
2332 $pass1 = isset( $_POST['pass1'] ) ? wp_unslash( $_POST['pass1'] ) : '';
2333 $send_password = isset( $_POST['send_password'] ) ? intval( $_POST['send_password'] ) : 0;
2334 $role = isset( $_POST['role'] ) ? sanitize_text_field( wp_unslash( $_POST['role'] ) ) : '';
2335
2336 $ret['failed_logging'] = esc_html( $user_login . ',' . $email . ',' . $first_name . ',' . $last_name . ',' . $url . ',' . $pass1 . ',' . $send_password . ',' . $role . ',' . $error_sites . ',' );
2337 }
2338 $ret['line_number'] = isset( $_POST['line_number'] ) ? intval( $_POST['line_number'] ) : 0;
2339 // phpcs:enable
2340 die( wp_json_encode( $ret ) );
2341 }
2342
2343 /**
2344 * Method mainwp_help_content()
2345 *
2346 * Creates the MainWP Help Documentation List for the help component in the sidebar.
2347 */
2348 public static function mainwp_help_content() {
2349 if ( isset( $_GET['page'] ) && ( 'UserBulkManage' === $_GET['page'] || 'UserBulkAdd' === $_GET['page'] || 'UpdateAdminPasswords' === $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
2350 ?>
2351 <p><?php esc_html_e( 'If you need help with managing users, please review following help documents', 'mainwp' ); ?></p>
2352 <div class="ui list">
2353 <div class="item"><i class="external alternate icon"></i> <a href="https://kb.mainwp.com/docs/manage-users/" target="_blank">Manage Users</a></div>
2354 <div class="item"><i class="external alternate icon"></i> <a href="https://kb.mainwp.com/docs/manage-users/#create-a-new-user" target="_blank">Create a New User</a></div>
2355 <div class="item"><i class="external alternate icon"></i> <a href="https://kb.mainwp.com/docs/manage-users/#edit-existing-users" target="_blank">Edit an Existing User</a></div>
2356 <div class="item"><i class="external alternate icon"></i> <a href="https://kb.mainwp.com/docs/manage-users/#bulk-update-admin-passwords" target="_blank">Bulk Update Administrator Passwords</a></div>
2357 <div class="item"><i class="external alternate icon"></i> <a href="https://kb.mainwp.com/docs/manage-users/#delete-users" target="_blank">Delete User(s)</a></div>
2358 <?php
2359 /**
2360 * Action: mainwp_users_help_item
2361 *
2362 * Fires at the bottom of the help articles list in the Help sidebar on the Users page.
2363 *
2364 * Suggested HTML markup:
2365 *
2366 * <div class="item"><a href="Your custom URL">Your custom text</a></div>
2367 *
2368 * @since 4.1
2369 */
2370 do_action( 'mainwp_users_help_item' );
2371 ?>
2372 </div>
2373 <?php
2374 }
2375 }
2376 }
2377