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