PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.1.6
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.1.6
6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 5.2.2 5.3 All 153 releases
mainwp / class / class-mainwp-post-handler.php

class-mainwp-post-handler.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies 6.1.6, at class/class-mainwp-post-handler.php

2,107 lines 88.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Post Handler.
4 *
5 * @package MainWP/Dashboard
6 */
7
8 namespace MainWP\Dashboard;
9
10 use MainWP\Dashboard\Module\Log\Log_DB_Helper;
11 use MainWP\Dashboard\Module\Log\Log_Changes_Logs_Helper;
12
13 // Exit if accessed directly.
14 if ( ! defined( 'ABSPATH' ) ) {
15 exit;
16 }
17
18 // phpcs:disable Generic.Metrics.CyclomaticComplexity -- complexity.
19
20 /**
21 * Class MainWP_Post_Handler
22 *
23 * @package MainWP\Dashboard
24 *
25 * @uses \MainWP\Dashboard\MainWP_Post_Base_Handler
26 */
27 class MainWP_Post_Handler extends MainWP_Post_Base_Handler { // phpcs:ignore -- NOSONAR - Complex.
28
29 /**
30 * Private static variable to hold the single instance of the class.
31 *
32 * @static
33 *
34 * @var mixed Default null
35 */
36 private static $instance = null;
37
38 /**
39 * Method instance()
40 *
41 * Create a public static instance.
42 *
43 * @static
44 * @return MainWP_Post_Handler
45 */
46 public static function instance() {
47 if ( null === static::$instance ) {
48 static::$instance = new self();
49 }
50 return static::$instance;
51 }
52
53 /**
54 * Initiate all actions.
55 *
56 * @uses \MainWP\Dashboard\MainWP_Post_Page_Handler::get_class_name()
57 */
58 public function init() {
59 // Page: ManageSites.
60 $this->add_action( 'mainwp_notes_save', array( &$this, 'mainwp_notes_save' ) );
61
62 // Page: BulkAddUser.
63 $this->add_action( 'mainwp_bulkadduser', array( &$this, 'mainwp_bulkadduser' ) );
64 $this->add_action( 'mainwp_importuser', array( &$this, 'mainwp_importuser' ) );
65
66 // Widget: RightNow.
67 $this->add_action( 'mainwp_syncerrors_dismiss', array( &$this, 'mainwp_syncerrors_dismiss' ) );
68
69 if ( \mainwp_current_user_can( 'dashboard', 'manage_security_issues' ) ) {
70 // Page: SecurityIssues.
71 $this->add_action( 'mainwp_security_issues_request', array( &$this, 'mainwp_security_issues_request' ) );
72 $this->add_action( 'mainwp_security_issues_fix', array( &$this, 'mainwp_security_issues_fix' ) );
73 $this->add_action( 'mainwp_security_issues_unfix', array( &$this, 'mainwp_security_issues_unfix' ) );
74 }
75
76 $this->add_action( 'mainwp_notice_status_update', array( &$this, 'mainwp_notice_status_update' ) );
77 $this->add_action( 'mainwp_dismiss_activate_notice', array( &$this, 'dismiss_activate_notice' ) );
78 $this->add_action( 'mainwp_status_saving', array( &$this, 'mainwp_status_saving' ) );
79 $this->add_action( 'mainwp_leftmenu_filter_group', array( &$this, 'mainwp_leftmenu_filter_group' ) );
80 $this->add_action( 'mainwp_widgets_order', array( &$this, 'ajax_widgets_order' ) );
81 $this->add_action( 'mainwp_save_settings', array( &$this, 'ajax_mainwp_save_settings' ) );
82 $this->add_action( 'mainwp_guided_tours_option_update', array( &$this, 'ajax_guided_tours_option_update' ) );
83 $this->add_action( 'mainwp_help_modal_content_update', array( &$this, 'ajax_mainwp_help_modal_content_update' ) );
84 $this->add_action( 'mainwp_widgets_connections_status_details_display_rows', array( MainWP_Connection_Status::instance(), 'ajax_display_rows' ) );
85
86
87 // Page: Recent Posts.
88 if ( \mainwp_current_user_can( 'dashboard', 'manage_posts' ) ) {
89 $this->add_action( 'mainwp_post_unpublish', array( &$this, 'mainwp_post_unpublish' ) );
90 $this->add_action( 'mainwp_post_publish', array( &$this, 'mainwp_post_publish' ) );
91 $this->add_action( 'mainwp_post_trash', array( &$this, 'mainwp_post_trash' ) );
92 $this->add_action( 'mainwp_post_delete', array( &$this, 'mainwp_post_delete' ) );
93 $this->add_action( 'mainwp_post_restore', array( &$this, 'mainwp_post_restore' ) );
94 $this->add_action( 'mainwp_post_approve', array( &$this, 'mainwp_post_approve' ) );
95 }
96 $this->add_action( 'mainwp_post_addmeta', array( MainWP_Post_Page_Handler::get_class_name(), 'ajax_add_meta' ) );
97 // Page: Pages.
98 if ( \mainwp_current_user_can( 'dashboard', 'manage_pages' ) ) {
99 $this->add_action( 'mainwp_page_unpublish', array( &$this, 'mainwp_page_unpublish' ) );
100 $this->add_action( 'mainwp_page_publish', array( &$this, 'mainwp_page_publish' ) );
101 $this->add_action( 'mainwp_page_trash', array( &$this, 'mainwp_page_trash' ) );
102 $this->add_action( 'mainwp_page_delete', array( &$this, 'mainwp_page_delete' ) );
103 $this->add_action( 'mainwp_page_restore', array( &$this, 'mainwp_page_restore' ) );
104 }
105 // Page: Users.
106 $this->add_action( 'mainwp_user_delete', array( &$this, 'mainwp_user_delete' ) );
107 $this->add_action( 'mainwp_user_edit', array( &$this, 'mainwp_user_edit' ) );
108 $this->add_action( 'mainwp_user_update_password', array( &$this, 'mainwp_user_update_password' ) );
109 $this->add_action( 'mainwp_user_update_user', array( &$this, 'mainwp_user_update_user' ) );
110
111 // Page: Posts.
112 $this->add_action( 'mainwp_posts_search', array( &$this, 'mainwp_posts_search' ) );
113 $this->add_action( 'mainwp_get_categories', array( &$this, 'mainwp_get_categories' ) );
114 $this->add_action( 'mainwp_post_get_edit', array( &$this, 'mainwp_post_get_edit' ) );
115 $this->add_action( 'mainwp_post_postingbulk', array( MainWP_Post_Page_Handler::get_class_name(), 'ajax_posting_posts' ) );
116 $this->add_action( 'mainwp_get_sites_of_groups', array( MainWP_Post_Page_Handler::get_class_name(), 'ajax_get_sites_of_groups' ) );
117
118 // Page: Pages.
119 $this->add_action( 'mainwp_pages_search', array( &$this, 'mainwp_pages_search' ) );
120 // Page: User.
121 $this->add_action( 'mainwp_users_search', array( &$this, 'mainwp_users_search' ) );
122
123 $this->add_action( 'mainwp_events_notice_hide', array( &$this, 'mainwp_events_notice_hide' ) );
124 $this->add_action( 'mainwp_showhide_sections', array( &$this, 'mainwp_showhide_sections' ) );
125 $this->add_action( 'mainwp_saving_status', array( &$this, 'mainwp_saving_status' ) );
126 $this->add_action( 'mainwp_autoupdate_and_trust_child', array( &$this, 'mainwp_autoupdate_and_trust_child' ) );
127 $this->add_action( 'mainwp_installation_warning_hide', array( &$this, 'mainwp_installation_warning_hide' ) );
128 $this->add_action( 'mainwp_force_destroy_sessions', array( &$this, 'mainwp_force_destroy_sessions' ) );
129 $this->add_action( 'mainwp_recheck_http', array( &$this, 'ajax_recheck_http' ) );
130 $this->add_action( 'mainwp_ignore_http_response', array( &$this, 'mainwp_ignore_http_response' ) );
131 $this->add_action( 'mainwp_disconnect_site', array( &$this, 'ajax_disconnect_site' ) );
132 $this->add_action( 'mainwp_manage_sites_display_rows', array( &$this, 'ajax_sites_display_rows' ) );
133 $this->add_action( 'mainwp_monitoring_sites_display_rows', array( &$this, 'ajax_monitoring_display_rows' ) );
134
135 $this->add_action_nonce( 'mainwp-common-nonce' );
136
137 // Page: Clients.
138 $this->add_action( 'mainwp_clients_add_client', array( &$this, 'mainwp_clients_add_client' ) );
139 $this->add_action( 'mainwp_clients_delete_client', array( &$this, 'mainwp_clients_delete_client' ) );
140
141 $this->add_action( 'mainwp_clients_save_field', array( &$this, 'mainwp_clients_save_field' ) );
142 $this->add_action( 'mainwp_clients_delete_general_field', array( &$this, 'mainwp_clients_delete_general_field' ) );
143 $this->add_action( 'mainwp_clients_bulk_delete_fields', array( &$this, 'mainwp_clients_bulk_delete_fields' ) );
144 $this->add_action( 'mainwp_clients_delete_field', array( &$this, 'mainwp_clients_delete_field' ) );
145 $this->add_action( 'mainwp_clients_notes_save', array( &$this, 'mainwp_clients_notes_save' ) );
146 $this->add_action( 'mainwp_clients_suspend_client', array( &$this, 'mainwp_clients_suspend_client' ) );
147 $this->add_action( 'mainwp_refresh_icon', array( &$this, 'ajax_refresh_icon' ) );
148 $this->add_action( 'mainwp_upload_custom_icon', array( &$this, 'ajax_upload_custom_icon' ) );
149 $this->add_action( 'mainwp_select_custom_theme', array( &$this, 'ajax_select_custom_theme' ) );
150 $this->add_action( 'mainwp_import_demo_data', array( &$this, 'ajax_import_demo_data' ) );
151 $this->add_action( 'mainwp_delete_demo_data', array( &$this, 'ajax_delete_demo_data' ) );
152 $this->add_action( 'mainwp_prepare_renew_connections', array( MainWP_Connect_Helper::instance(), 'ajax_prepare_renew_connections' ) );
153 $this->add_action( 'mainwp_renew_connections', array( MainWP_Connect_Helper::instance(), 'ajax_renew_connections' ) );
154
155 $this->add_action( 'mainwp_clients_check_client', array( &$this, 'mainwp_clients_check_client' ) );
156 $this->add_action( 'mainwp_clients_import_client', array( &$this, 'mainwp_clients_import_client' ) );
157
158 // Page: managesites.
159 $this->add_action( 'mainwp_save_temp_import_website', array( &$this, 'ajax_save_temp_import_website' ) );
160 $this->add_action( 'mainwp_delete_temp_import_website', array( &$this, 'ajax_delete_temp_import_website' ) );
161 $this->add_action( 'mainwp_import_website_add_client', array( &$this, 'ajax_import_website_add_client' ) );
162 $this->add_action( 'mainwp_import_website_add_client_no_site', array( &$this, 'ajax_import_website_add_client_no_site' ) );
163
164 // Page:: mainwp-setup.
165 $this->add_action( 'mainwp_clients_add_multi_client', array( &$this, 'ajax_clients_add_multi_client' ) );
166 $this->add_action( 'mainwp_increase_connection_security', array( &$this, 'ajax_increase_connection_security' ) );
167 $this->add_action( 'mainwp_qsw_ui_mode_detected', array( &$this, 'ajax_ui_mode_detected' ) );
168
169 $this->add_action( 'mainwp_changes_logs_get_item_changes', array( &$this, 'ajax_get_item_changes_logs' ) );
170 }
171
172 /**
173 * Method add_post_action()
174 *
175 * Add ajax action.
176 *
177 * @param string $action Action to perform.
178 * @param string $callback Callback to perform.
179 */
180 public function add_post_action( $action, $callback ) {
181 $this->add_action( $action, $callback );
182 }
183
184 /**
185 * Method mainwp_installation_warning_hide()
186 *
187 * Hide the installation warning.
188 */
189 public function mainwp_installation_warning_hide() {
190 $this->secure_request( 'mainwp_installation_warning_hide' );
191
192 update_option( 'mainwp_installation_warning_hide_the_notice', 'yes' );
193 die( 'ok' );
194 }
195
196 /**
197 * Method mainwp_users_search()
198 *
199 * Search Post handler,
200 * Page: User.
201 *
202 * @uses \MainWP\Dashboard\MainWP_Cache::init_session()
203 * @uses \MainWP\Dashboard\MainWP_User::render_table()
204 */
205 public function mainwp_users_search() {
206 $this->secure_request( 'mainwp_users_search' );
207 MainWP_Cache::init_session();
208
209 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
210 $role = isset( $_POST['urole'] ) ? sanitize_text_field( wp_unslash( $_POST['urole'] ) ) : '';
211 $groups = isset( $_POST['groups'] ) && is_array( $_POST['groups'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['groups'] ) ) : '';
212 $sites = isset( $_POST['sites'] ) && is_array( $_POST['sites'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['sites'] ) ) : '';
213 $clients = isset( $_POST['clients'] ) && is_array( $_POST['clients'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['clients'] ) ) : '';
214 $search = isset( $_POST['search'] ) ? sanitize_text_field( wp_unslash( $_POST['search'] ) ) : '';
215 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
216 MainWP_User::render_table( false, $role, $groups, $sites, $search, $clients );
217 session_write_close();
218 die();
219 }
220
221 /**
222 * Method mainwp_posts_search()
223 *
224 * Search Post handler,
225 * Page: Posts.
226 *
227 * @uses \MainWP\Dashboard\MainWP_Cache::init_session()
228 * @uses \MainWP\Dashboard\MainWP_Post::render_table()
229 * @uses \MainWP\Dashboard\MainWP_Utility::update_option()
230 */
231 public function mainwp_posts_search() { // phpcs:ignore -- NOSONAR - complex.
232 $this->secure_request( 'mainwp_posts_search' );
233 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
234 $post_type = ( isset( $_POST['post_type'] ) && 0 < strlen( sanitize_text_field( wp_unslash( $_POST['post_type'] ) ) ) ? sanitize_text_field( wp_unslash( $_POST['post_type'] ) ) : 'post' );
235 if ( isset( $_POST['maximum'] ) ) {
236 MainWP_Utility::update_option( 'mainwp_maximumPosts', isset( $_POST['maximum'] ) ? intval( $_POST['maximum'] ) : 50 );
237 }
238 $keyword = isset( $_POST['keyword'] ) ? sanitize_text_field( wp_unslash( $_POST['keyword'] ) ) : '';
239 $dtsstart = isset( $_POST['dtsstart'] ) ? sanitize_text_field( trim( wp_unslash( $_POST['dtsstart'] ) ) ) : '';
240 $dtsstop = isset( $_POST['dtsstop'] ) ? sanitize_text_field( trim( wp_unslash( $_POST['dtsstop'] ) ) ) : '';
241 $status = isset( $_POST['status'] ) ? sanitize_text_field( wp_unslash( $_POST['status'] ) ) : '';
242 $groups = isset( $_POST['groups'] ) && is_array( $_POST['groups'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['groups'] ) ) : '';
243 $sites = isset( $_POST['sites'] ) && is_array( $_POST['sites'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['sites'] ) ) : '';
244 $clients = isset( $_POST['clients'] ) && is_array( $_POST['clients'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['clients'] ) ) : '';
245 $postId = isset( $_POST['postId'] ) ? sanitize_text_field( wp_unslash( $_POST['postId'] ) ) : '';
246 $userId = isset( $_POST['userId'] ) ? sanitize_text_field( wp_unslash( $_POST['userId'] ) ) : '';
247 $search_on = isset( $_POST['search_on'] ) ? sanitize_text_field( wp_unslash( $_POST['search_on'] ) ) : '';
248 $table_content_only = isset( $_POST['table_content'] ) && wp_unslash( $_POST['table_content'] ) ? true : false;
249 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
250
251 MainWP_Cache::init_session();
252 if ( $table_content_only ) {
253 MainWP_Post::render_table_body( $keyword, $dtsstart, $dtsstop, $status, $groups, $sites, $postId, $userId, $post_type, $search_on, true, $clients );
254 } else {
255 $params = array(
256 'groups' => $groups,
257 'sites' => $sites,
258 'postId' => $postId,
259 'userId' => $userId,
260 'post_type' => $post_type,
261 'search_on' => $search_on,
262 'clients' => $clients,
263 );
264 MainWP_Post::render_table( false, $keyword, $dtsstart, $dtsstop, $status, $params );
265 }
266 die();
267 }
268 /**
269 * Method mainwp_pages_search()
270 *
271 * Search Post handler,
272 * Page: Pages.
273 *
274 * @uses \MainWP\Dashboard\MainWP_Cache::init_session()
275 * @uses \MainWP\Dashboard\MainWP_Page::render_table()
276 *
277 * @uses \MainWP\Dashboard\MainWP_Utility::update_option()
278 */
279 public function mainwp_pages_search() {
280 $this->secure_request( 'mainwp_pages_search' );
281 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
282 if ( isset( $_POST['maximum'] ) ) {
283 MainWP_Utility::update_option( 'mainwp_maximumPages', intval( $_POST['maximum'] ) ? intval( $_POST['maximum'] ) : 50 );
284 }
285 $keyword = isset( $_POST['keyword'] ) ? sanitize_text_field( wp_unslash( $_POST['keyword'] ) ) : '';
286 $dtsstart = isset( $_POST['dtsstart'] ) ? sanitize_text_field( wp_unslash( $_POST['dtsstart'] ) ) : '';
287 $dtsstop = isset( $_POST['dtsstop'] ) ? sanitize_text_field( wp_unslash( $_POST['dtsstop'] ) ) : '';
288 $status = isset( $_POST['status'] ) ? sanitize_text_field( wp_unslash( $_POST['status'] ) ) : '';
289 $groups = isset( $_POST['groups'] ) && is_array( $_POST['groups'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['groups'] ) ) : '';
290 $sites = isset( $_POST['sites'] ) && is_array( $_POST['sites'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['sites'] ) ) : '';
291 $clients = isset( $_POST['clients'] ) && is_array( $_POST['clients'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['clients'] ) ) : '';
292 $search_on = isset( $_POST['search_on'] ) ? sanitize_text_field( wp_unslash( $_POST['search_on'] ) ) : '';
293 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
294 MainWP_Cache::init_session();
295
296 $params = array(
297 'groups' => $groups,
298 'sites' => $sites,
299 'search_on' => $search_on,
300 'clients' => $clients,
301 );
302
303 MainWP_Page::render_table( false, $keyword, $dtsstart, $dtsstop, $status, $params );
304 die();
305 }
306
307 /**
308 * Method mainwp_get_categories()
309 *
310 * Get post/page categories.
311 *
312 * @uses \MainWP\Dashboard\MainWP_Post_Page_Handler::get_categories()
313 */
314 public function mainwp_get_categories() {
315 $this->secure_request( 'mainwp_get_categories' );
316 MainWP_Post_Page_Handler::ajax_handle_get_categories();
317 die();
318 }
319
320 /**
321 * Method mainwp_post_get_edit()
322 *
323 * Get post to edit.
324 *
325 * @uses \MainWP\Dashboard\MainWP_Post_Page_Handler::get_post()
326 */
327 public function mainwp_post_get_edit() {
328 $this->secure_request( 'mainwp_post_get_edit' );
329 MainWP_Post_Page_Handler::get_post();
330 die();
331 }
332
333 /**
334 * Method mainwp_user_delete()
335 *
336 * Delete User from Child Site,
337 * Page: Users.
338 *
339 * @uses \MainWP\Dashboard\MainWP_User::delete()
340 */
341 public function mainwp_user_delete() {
342 $this->secure_request( 'mainwp_user_delete' );
343 MainWP_User::delete();
344 }
345
346 /**
347 * Method mainwp_user_edit()
348 *
349 * Edit User from Child Site,
350 * Page: Users.
351 *
352 * @uses \MainWP\Dashboard\MainWP_User::edit()
353 */
354 public function mainwp_user_edit() {
355 $this->secure_request( 'mainwp_user_edit' );
356 MainWP_User::edit();
357 }
358
359 /**
360 * Method mainwp_user_update_password(
361 *
362 * Update User password from Child Site,
363 * Page: Users.
364 *
365 * @uses \MainWP\Dashboard\MainWP_User::update_password()
366 */
367 public function mainwp_user_update_password() {
368 $this->secure_request( 'mainwp_user_update_password' );
369 MainWP_User::update_password();
370 }
371
372 /**
373 * Method mainwp_user_update_user()
374 *
375 * Update User from Child Site,
376 * Page: Users.
377 *
378 * @uses \MainWP\Dashboard\MainWP_User::update_user()
379 */
380 public function mainwp_user_update_user() {
381 $this->secure_request( 'mainwp_user_update_user' );
382 MainWP_User::update_user();
383 }
384
385 /**
386 * Method mainwp_post_unpublish()
387 *
388 * Unpublish post from Child Site,
389 * Page: Recent Posts.
390 *
391 * @uses \MainWP\Dashboard\MainWP_Recent_Posts::unpublish()
392 */
393 public function mainwp_post_unpublish() {
394 $this->secure_request( 'mainwp_post_unpublish' );
395 MainWP_Recent_Posts::unpublish();
396 }
397
398 /**
399 * Method mainwp_post_publish()
400 *
401 * Publish post on Child Site,
402 * Page: Recent Posts.
403 *
404 * @uses \MainWP\Dashboard\MainWP_Recent_Posts::publish()
405 */
406 public function mainwp_post_publish() {
407 $this->secure_request( 'mainwp_post_publish' );
408 MainWP_Recent_Posts::publish();
409 }
410
411 /**
412 * Method mainwp_post_approve()
413 *
414 * Approve post on Child Site,
415 * Page: Recent Posts.
416 *
417 * @uses \MainWP\Dashboard\MainWP_Recent_Posts::approve()
418 */
419 public function mainwp_post_approve() {
420 $this->secure_request( 'mainwp_post_approve' );
421 MainWP_Recent_Posts::approve();
422 }
423
424 /**
425 * Method mainwp_post_trash()
426 *
427 * Trash post on Child Site,
428 * Page: Recent Posts.
429 *
430 * @uses \MainWP\Dashboard\MainWP_Recent_Posts::trash()
431 */
432 public function mainwp_post_trash() {
433 $this->secure_request( 'mainwp_post_trash' );
434
435 MainWP_Recent_Posts::trash();
436 }
437
438 /**
439 * Method mainwp_post_delete()
440 *
441 * Delete post on Child Site,
442 * Page: Recent Posts.
443 *
444 * @uses \MainWP\Dashboard\MainWP_Recent_Posts::delete()
445 */
446 public function mainwp_post_delete() {
447 $this->secure_request( 'mainwp_post_delete' );
448
449 MainWP_Recent_Posts::delete();
450 }
451
452 /**
453 * Method mainwp_post_restore()
454 *
455 * Restore post,
456 * Page: Recent Posts.
457 *
458 * @uses \MainWP\Dashboard\MainWP_Recent_Posts::restore()
459 */
460 public function mainwp_post_restore() {
461 $this->secure_request( 'mainwp_post_restore' );
462
463 MainWP_Recent_Posts::restore();
464 }
465
466 /**
467 * Method mainwp_page_unpublish()
468 *
469 * Unpublish page,
470 * Page: Recent Pages.
471 *
472 * @uses \MainWP\Dashboard\MainWP_Page::unpublish()
473 */
474 public function mainwp_page_unpublish() {
475 $this->secure_request( 'mainwp_page_unpublish' );
476 MainWP_Page::unpublish();
477 }
478
479 /**
480 * Method mainwp_page_publish()
481 *
482 * Publish page,
483 * Page: Recent Pages.
484 *
485 * @uses \MainWP\Dashboard\MainWP_Page::publish()
486 */
487 public function mainwp_page_publish() {
488 $this->secure_request( 'mainwp_page_publish' );
489 MainWP_Page::publish();
490 }
491
492 /**
493 * Method mainwp_page_trash()
494 *
495 * Trash page,
496 * Page: Recent Pages.
497 *
498 * @uses \MainWP\Dashboard\MainWP_Page::trash()
499 */
500 public function mainwp_page_trash() {
501 $this->secure_request( 'mainwp_page_trash' );
502 MainWP_Page::trash();
503 }
504
505 /**
506 * Method mainwp_page_delete()
507 *
508 * Delete page,
509 * Page: Recent Pages.
510 *
511 * @uses \MainWP\Dashboard\MainWP_Page::delete()
512 */
513 public function mainwp_page_delete() {
514 $this->secure_request( 'mainwp_page_delete' );
515 MainWP_Page::delete();
516 }
517
518 /**
519 * Method mainwp_page_restor()
520 *
521 * Restore page,
522 * Page: Recent Pages.
523 *
524 * @uses \MainWP\Dashboard\MainWP_Page::restore()
525 */
526 public function mainwp_page_restore() {
527 $this->secure_request( 'mainwp_page_restore' );
528 MainWP_Page::restore();
529 }
530
531 /**
532 * Method mainwp_notice_status_update()
533 *
534 * Hide after installation notices,
535 * (PHP version, Trust MainWP Child, Multisite Warning and OpenSSL warning).
536 *
537 * @uses \MainWP\Dashboard\MainWP_Utility::update_option()
538 */
539 public function mainwp_notice_status_update() {
540 $this->secure_request( 'mainwp_notice_status_update' );
541
542 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
543 $no_id = isset( $_POST['notice_id'] ) ? sanitize_text_field( wp_unslash( $_POST['notice_id'] ) ) : false;
544 if ( 'mail_failed' === $no_id ) {
545 MainWP_Utility::update_option( 'mainwp_notice_wp_mail_failed', 'hide' );
546 die( 'ok' );
547 }
548
549 if ( 'phpver_8_0' === $no_id ) {
550 MainWP_Utility::update_user_option( 'lasttime_hidden_phpver_8_0', time() );
551 }
552
553 $time_set = isset( $_POST['time_set'] ) && 1 === intval( $_POST['time_set'] ) ? true : false;
554 $this->hide_dashboard_notice_status( $no_id, $time_set );
555 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
556 die( 1 );
557 }
558
559 /**
560 * Method hide dashboard notice status.
561 *
562 * @param mixed $no_id notice id.
563 * @param mixed $time_set time.
564 * @param bool $hide_noti hide notice.
565 * @return void
566 */
567 public function hide_dashboard_notice_status( $no_id, $time_set = false, $hide_noti = true ) { //phpcs:ignore -- NOSONAR - complexity.
568 /**
569 * Current user global.
570 *
571 * @global string
572 */
573 global $current_user;
574 $user_id = $current_user->ID;
575 if ( $user_id ) {
576 $status = get_user_option( 'mainwp_notice_saved_status' );
577 if ( ! is_array( $status ) ) {
578 $status = array();
579 }
580 if ( ! empty( $no_id ) ) {
581 if ( 'mainwp_secure_priv_key_notice' === $no_id ) {
582 MainWP_Utility::update_option( 'mainwp_not_start_encrypt_keys', 1 ); // to show the button.
583 }
584 if ( $hide_noti ) {
585 if ( $time_set ) {
586 $status[ $no_id ] = time();
587 } else {
588 $status[ $no_id ] = 1;
589 }
590 } elseif ( ! empty( $status[ $no_id ] ) ) {
591 unset( $status[ $no_id ] );
592 }
593 update_user_option( $user_id, 'mainwp_notice_saved_status', $status );
594 }
595 }
596 }
597
598 /**
599 * Method mainwp_status_saving()
600 *
601 * Save last_sync_sites time().
602 */
603 public function mainwp_status_saving() { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR - complexity.
604 $this->secure_request( 'mainwp_status_saving' );
605 $values = get_option( 'mainwp_status_saved_values' );
606
607 if ( ! is_array( $values ) ) {
608 $values = array();
609 }
610
611 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
612 if ( ! isset( $_POST['status'] ) ) {
613 die( -1 );
614 }
615
616 if ( 'last_sync_sites' === $_POST['status'] ) {
617 if ( isset( $_POST['isGlobalSync'] ) && ! empty( $_POST['isGlobalSync'] ) ) {
618 update_option( 'mainwp_last_synced_all_sites', time() );
619
620 /**
621 * Action: mainwp_synced_all_sites
622 *
623 * Fires upon successfull synchronization process.
624 *
625 * @since 3.5.1
626 */
627 do_action( 'mainwp_synced_all_sites' );
628 }
629 die( 'ok' );
630 }
631
632 $status = isset( $_POST['status'] ) ? sanitize_text_field( wp_unslash( $_POST['status'] ) ) : '';
633 $value = isset( $_POST['value'] ) ? sanitize_text_field( wp_unslash( $_POST['value'] ) ) : '';
634 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
635
636 if ( ! empty( $status ) ) {
637 if ( empty( $value ) ) {
638 if ( isset( $values[ $status ] ) ) {
639 unset( $values[ $status ] );
640 }
641 } else {
642 $values[ $status ] = $value;
643 }
644 update_option( 'mainwp_status_saved_values', $values );
645 }
646
647 die( 'ok' );
648 }
649
650 /**
651 * Method ajax_widget_order()
652 *
653 * Update saved widget order.
654 */
655 public function ajax_widgets_order() { //phpcs:ignore -- NOSONAR - complex.
656
657 $this->secure_request( 'mainwp_widgets_order' );
658 $user = wp_get_current_user();
659 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
660 if ( $user && ! empty( $_POST['page'] ) ) {
661 $page = isset( $_POST['page'] ) ? sanitize_text_field( wp_unslash( $_POST['page'] ) ) : '';
662 $order = isset( $_POST['order'] ) ? sanitize_text_field( wp_unslash( $_POST['order'] ) ) : '';
663 $wgids = isset( $_POST['wgids'] ) ? sanitize_text_field( wp_unslash( $_POST['wgids'] ) ) : '';
664 $page_widget = isset( $_POST['page_widget'] ) ? sanitize_text_field( wp_unslash( $_POST['page_widget'] ) ) : '';
665
666 $wgs_orders = array();
667
668 if ( ! empty( $wgids ) ) {
669 $wgids = json_decode( $wgids, true );
670 $order = json_decode( $order, true );
671 if ( is_array( $wgids ) && is_array( $order ) ) {
672 foreach ( $wgids as $idx => $wgid ) {
673 if ( isset( $order[ $idx ] ) ) {
674 $pre = 'widget-'; // #compatible-widgetid.
675 if ( 0 === strpos( $wgid, $pre ) ) {
676 $wgid = substr( $wgid, strlen( $pre ) );
677 }
678 $wgs_orders[ $wgid ] = $order[ $idx ];
679 }
680 }
681 }
682 }
683
684 if ( 'mainwp_page_manageclients' === $page ) {
685 $item_id = isset( $_POST['item_id'] ) ? intval( $_POST['item_id'] ) : 0;
686 $sorted_array = get_user_option( 'mainwp_widgets_sorted_' . strtolower( $page ) );
687 if ( ! empty( $sorted_array ) ) {
688 $sorted_array = json_decode( $sorted_array, true );
689 }
690 if ( ! is_array( $sorted_array ) ) {
691 $sorted_array = array();
692 }
693 $sorted_array[ $item_id ] = $wgs_orders;
694 update_user_option( $user->ID, 'mainwp_widgets_sorted_' . $page, wp_json_encode( $sorted_array ), true );
695 } else {
696 update_user_option( $user->ID, 'mainwp_widgets_sorted_' . $page, wp_json_encode( $wgs_orders ), true );
697 }
698 MainWP_Cache_Warm_Helper::invalidate_manage_pages( array( $page_widget ) );
699 die( 'ok' );
700 }
701 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
702 die( -1 );
703 }
704
705 /**
706 * Method ajax_mainwp_save_settings()
707 *
708 * Update saved MainWP Settings.
709 *
710 * @uses \MainWP\Dashboard\MainWP_Utility::update_option()
711 */
712 public function ajax_mainwp_save_settings() {
713 $this->secure_request( 'mainwp_save_settings' );
714 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
715 $name = isset( $_POST['name'] ) ? sanitize_text_field( wp_unslash( $_POST['name'] ) ) : '';
716 if ( ! empty( $name ) ) {
717 $option_name = 'mainwp_' . $name;
718 $val = isset( $_POST['value'] ) ? sanitize_text_field( wp_unslash( $_POST['value'] ) ) : '';
719 MainWP_Utility::update_option( $option_name, $val );
720 }
721 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
722 die( 'ok' );
723 }
724
725 /**
726 * Method ajax_guided_tours_option_update()
727 *
728 * Update saved MainWP Settings.
729 *
730 * @uses \MainWP\Dashboard\MainWP_Utility::update_option()
731 */
732 public function ajax_guided_tours_option_update() {
733 $this->secure_request( 'mainwp_guided_tours_option_update' );
734 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
735 $enable = isset( $_POST['enable'] ) ? intval( $_POST['enable'] ) : 0;
736 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
737 MainWP_Utility::update_option( 'mainwp_enable_guided_tours', $enable );
738 die( 'ok ' . intval( $enable ) );
739 }
740
741 /**
742 * Method mainwp_help_modal_content_update()
743 *
744 * Update saved MainWP Settings.
745 *
746 * @uses \MainWP\Dashboard\MainWP_Utility::update_option()
747 */
748 public function ajax_mainwp_help_modal_content_update() {
749 $this->secure_request( 'mainwp_help_modal_content_update' );
750 MainWP_Utility::update_option( 'mainwp_enable_guided_tours', ( int)$_POST['enable_tour'] ); //phpcs:ignore -- NOSONAR verify.
751 MainWP_Utility::update_option( 'mainwp_enable_guided_video', (int)$_POST['enable_video'] ); //phpcs:ignore -- NOSONAR verify.
752 MainWP_Utility::update_option( 'mainwp_enable_guided_chatbase', (int)$_POST['enable_chatbase'] ); //phpcs:ignore -- NOSONAR verify.
753 die( 'ok' );
754 }
755
756 /**
757 * Method mainwp_leftmenu_filter_group()
758 *
759 * MainWP left menu filter by group.
760 *
761 * @uses \MainWP\Dashboard\MainWP_DB::query()
762 * @uses \MainWP\Dashboard\MainWP_DB::get_websites_by_group_id()
763 * @uses \MainWP\Dashboard\MainWP_DB::fetch_object()
764 * @uses \MainWP\Dashboard\MainWP_DB::free_result()
765 */
766 public function mainwp_leftmenu_filter_group() {
767 $this->secure_request( 'mainwp_leftmenu_filter_group' );
768
769 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
770 $gid = isset( $_POST['group_id'] ) ? intval( $_POST['group_id'] ) : false;
771 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
772
773 if ( ! empty( $gid ) ) {
774 $ids = '';
775 $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_by_group_id( $gid, true ) );
776 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
777 $ids .= $website->id . ',';
778 }
779 MainWP_DB::free_result( $websites );
780 $ids = rtrim( $ids, ',' );
781 die( $ids ); // phpcs:ignore WordPress.Security.EscapeOutput
782 }
783 die( '' );
784 }
785
786 /**
787 * Method dismiss_activate_notice()
788 *
789 * Dismiss activate notice.
790 */
791 public function dismiss_activate_notice() {
792 $this->secure_request( 'mainwp_dismiss_activate_notice' );
793
794 /**
795 * Current user global.
796 *
797 * @global string
798 */
799 global $current_user;
800 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
801 $user_id = $current_user->ID;
802 $slug = isset( $_POST['slug'] ) ? sanitize_text_field( wp_unslash( $_POST['slug'] ) ) : '';
803 if ( $user_id && ! empty( $slug ) ) {
804 $activate_notices = get_user_option( 'mainwp_hide_activate_notices' );
805 if ( ! is_array( $activate_notices ) ) {
806 $activate_notices = array();
807 }
808
809 $activate_notices[ $slug ] = time();
810 update_user_option( $user_id, 'mainwp_hide_activate_notices', $activate_notices );
811 }
812 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
813 die( 1 );
814 }
815
816
817
818 /**
819 * Method mainwp_security_issues_request()
820 *
821 * Post handler for,
822 * Page: SecurityIssues.
823 *
824 * @uses \MainWP\Dashboard\MainWP_Exception
825 * @uses \MainWP\Dashboard\MainWP_Security_Issues::fetch_security_issues()
826 */
827 public function mainwp_security_issues_request() {
828 $this->secure_request( 'mainwp_security_issues_request' );
829
830 try {
831 wp_send_json( array( 'result' => MainWP_Security_Issues::fetch_security_issues() ) );
832 } catch ( MainWP_Exception $e ) {
833 die(
834 wp_json_encode(
835 array(
836 'error' => array(
837 'message' => $e->getMessage(),
838 'extra' => $e->get_message_extra(),
839 ),
840 )
841 )
842 );
843 }
844 }
845
846 /**
847 * Method mainwp_security_issues_fix()
848 *
849 * Post handler for 'fix issues',
850 * Page: SecurityIssues.
851 *
852 * @uses \MainWP\Dashboard\MainWP_Exception
853 * @uses \MainWP\Dashboard\MainWP_Security_Issues::fix_security_issue()
854 */
855 public function mainwp_security_issues_fix() {
856 $this->secure_request( 'mainwp_security_issues_fix' );
857
858 try {
859 wp_send_json( array( 'result' => MainWP_Security_Issues::fix_security_issue() ) );
860 } catch ( MainWP_Exception $e ) {
861 die(
862 wp_json_encode(
863 array(
864 'error' => array(
865 'message' => $e->getMessage(),
866 'extra' => $e->get_message_extra(),
867 ),
868 )
869 )
870 );
871 }
872 }
873
874 /**
875 * Method mainwp_security_issues_unfix()
876 *
877 * Post handler for 'unfix issues',
878 * Page: SecurityIssues.
879 *
880 * @uses \MainWP\Dashboard\MainWP_Exception
881 * @uses \MainWP\Dashboard\MainWP_Security_Issues::unfix_security_issue()
882 */
883 public function mainwp_security_issues_unfix() {
884 $this->secure_request( 'mainwp_security_issues_unfix' );
885
886 try {
887 wp_send_json( array( 'result' => MainWP_Security_Issues::unfix_security_issue() ) );
888 } catch ( MainWP_Exception $e ) {
889 die(
890 wp_json_encode(
891 array(
892 'error' => array(
893 'message' => $e->getMessage(),
894 'extra' => $e->get_message_extra(),
895 ),
896 )
897 )
898 );
899 }
900 }
901
902 /**
903 * Method ajax_disconnect_site()
904 *
905 * Disconnect Child Site.
906 *
907 * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
908 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
909 */
910 public function ajax_disconnect_site() {
911 $this->secure_request( 'mainwp_disconnect_site' );
912 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
913 $siteid = isset( $_POST['wp_id'] ) ? intval( $_POST['wp_id'] ) : 0;
914 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
915
916 if ( empty( $siteid ) ) {
917 die( wp_json_encode( array( 'error' => 'Error: site id empty' ) ) );
918 }
919
920 $website = MainWP_DB::instance()->get_website_by_id( $siteid );
921
922 if ( ! $website ) {
923 die( wp_json_encode( array( 'error' => 'Not found site' ) ) );
924 }
925
926 try {
927 $information = MainWP_Connect::fetch_url_authed( $website, 'disconnect' );
928 } catch ( \Exception $e ) {
929 $information = array( 'error' => esc_html__( 'fetch_url_authed exception', 'mainwp' ) );
930 }
931
932 wp_send_json( $information );
933 }
934
935 /**
936 * Method ajax_sites_display_rows()
937 *
938 * Display rows via ajax,
939 * Page: Manage Sites.
940 *
941 * @uses \MainWP\Dashboard\MainWP_Manage_Sites::ajax_optimize_display_rows()
942 */
943 public function ajax_sites_display_rows() {
944 $this->secure_request( 'mainwp_manage_sites_display_rows' );
945 MainWP_Manage_Sites::ajax_optimize_display_rows();
946 }
947
948 /**
949 * Method ajax_monitoring_display_rows()
950 *
951 * Display rows via ajax,
952 * Page: Monitoring Sites.
953 *
954 * @uses \MainWP\Dashboard\MainWP_Monitoring::ajax_optimize_display_rows()
955 */
956 public function ajax_monitoring_display_rows() {
957 $this->secure_request( 'mainwp_monitoring_sites_display_rows' );
958 MainWP_Monitoring::ajax_optimize_display_rows();
959 }
960
961
962 /**
963 * Method mainwp_bulkadduser()
964 *
965 * Bulk Add User for,
966 * Page: BulkAddUser.
967 *
968 * @uses \MainWP\Dashboard\MainWP_User::do_bulk_add()
969 */
970 public function mainwp_bulkadduser() {
971 $this->check_security( 'mainwp_bulkadduser' );
972 MainWP_User::do_bulk_add();
973 die();
974 }
975
976 /**
977 * Method mainwp_importuser()
978 *
979 * Import user.
980 *
981 * @uses \MainWP\Dashboard\MainWP_User::do_import()
982 */
983 public function mainwp_importuser() {
984 $this->secure_request( 'mainwp_importuser' );
985 MainWP_User::do_import();
986 }
987
988 /**
989 * Method mainwp_clients_add_client()
990 *
991 * Add Client for,
992 * Page: BulkAddClient.
993 */
994 public function mainwp_clients_add_client() {
995 $this->check_security( 'mainwp_clients_add_client' );
996 MainWP_Client::add_client();
997 die();
998 }
999
1000 /**
1001 * Method mainwp_clients_delete_client()
1002 *
1003 * Add Client for,
1004 * Page: BulkAddClient.
1005 */
1006 public function mainwp_clients_delete_client() {
1007 $this->check_security( 'mainwp_clients_delete_client' );
1008 $ret = array( 'success' => false );
1009 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1010 $client_id = isset( $_POST['clientid'] ) ? intval( $_POST['clientid'] ) : 0;
1011 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1012 if ( $client_id ) {
1013 MainWP_DB_Client::instance()->delete_client( $client_id );
1014 $ret['success'] = 'SUCCESS';
1015 $ret['result'] = esc_html__( 'Client removed successfully.', 'mainwp' );
1016 MainWP_Client::invalidate_warm_cache();
1017 } else {
1018 $ret['result'] = esc_html__( 'Client ID empty.', 'mainwp' );
1019 }
1020
1021 echo wp_json_encode( $ret );
1022 exit;
1023 }
1024
1025 /**
1026 * Method mainwp_clients_save_field()
1027 *
1028 * Save client custom fields.
1029 */
1030 public function mainwp_clients_save_field() {
1031 $this->check_security( 'mainwp_clients_save_field' );
1032 MainWP_Client::invalidate_warm_cache();
1033 MainWP_Client::save_client_field();
1034 die();
1035 }
1036
1037
1038 /**
1039 * Method mainwp_clients_delete_general_field()
1040 *
1041 * Delete client general fields.
1042 */
1043 public function mainwp_clients_delete_general_field() {
1044 $this->check_security( 'mainwp_clients_delete_general_field' );
1045 $ret = array( 'success' => false );
1046 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1047 $field_id = isset( $_POST['field_id'] ) ? intval( $_POST['field_id'] ) : 0;
1048 $client_id = 0; // 0 general fields.
1049 if ( MainWP_DB_Client::instance()->delete_client_field_by( 'field_id', $field_id, $client_id ) ) {
1050 $ret['success'] = true;
1051 }
1052 MainWP_Client::invalidate_warm_cache();
1053 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1054 echo wp_json_encode( $ret );
1055 exit;
1056 }
1057
1058 /**
1059 * Method mainwp_clients_bulk_delete_fields()
1060 *
1061 * Bulk delete client general fields.
1062 */
1063 public function mainwp_clients_bulk_delete_fields() {
1064 $this->check_security( 'mainwp_clients_bulk_delete_fields' );
1065 $ret = array( 'success' => false );
1066 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1067 $field_ids = isset( $_POST['field_ids'] ) && is_array( $_POST['field_ids'] ) ? array_map( 'intval', $_POST['field_ids'] ) : array();
1068 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1069
1070 if ( empty( $field_ids ) ) {
1071 $ret['data'] = array( 'message' => __( 'No fields selected.', 'mainwp' ) );
1072 echo wp_json_encode( $ret );
1073 exit;
1074 }
1075
1076 $client_id = 0; // 0 general fields.
1077 $deleted_count = 0;
1078 foreach ( $field_ids as $field_id ) {
1079 if ( MainWP_DB_Client::instance()->delete_client_field_by( 'field_id', $field_id, $client_id ) ) {
1080 ++$deleted_count;
1081 }
1082 }
1083
1084 if ( $deleted_count > 0 ) {
1085 $ret['success'] = true;
1086 MainWP_Client::invalidate_warm_cache();
1087 } else {
1088 $ret['data'] = array( 'message' => __( 'Failed to delete fields.', 'mainwp' ) );
1089 }
1090
1091 echo wp_json_encode( $ret );
1092 exit;
1093 }
1094
1095 /**
1096 * Method mainwp_clients_delete_field()
1097 *
1098 * Delete client custom fields.
1099 */
1100 public function mainwp_clients_delete_field() {
1101 $this->check_security( 'mainwp_clients_delete_field' );
1102 $ret = array( 'success' => false );
1103 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1104 $field_id = isset( $_POST['field_id'] ) ? intval( $_POST['field_id'] ) : 0;
1105 $client_id = isset( $_POST['client_id'] ) ? intval( $_POST['client_id'] ) : 0; // $client_id > 0, individual token.
1106 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1107 if ( $client_id && MainWP_DB_Client::instance()->delete_client_field_by( 'field_id', $field_id, $client_id ) ) {
1108 $ret['success'] = true;
1109 }
1110 echo wp_json_encode( $ret );
1111 exit;
1112 }
1113
1114 /**
1115 * Method mainwp_notes_save()
1116 *
1117 * Post handler for save notes on,
1118 * Page: Manage Sites.
1119 *
1120 * @uses \MainWP\Dashboard\MainWP_Manage_Sites_Handler::save_note()
1121 */
1122 public function mainwp_notes_save() {
1123 $this->secure_request( 'mainwp_notes_save' );
1124 MainWP_Manage_Sites_Handler::save_note();
1125 }
1126
1127 /**
1128 * Method mainwp_clients_notes_save()
1129 *
1130 * Post handler for save notes on,
1131 * Page: Manage Sites.
1132 *
1133 * @uses \MainWP\Dashboard\MainWP_Manage_Sites_Handler::save_note()
1134 */
1135 public function mainwp_clients_notes_save() {
1136 $this->secure_request( 'mainwp_clients_notes_save' );
1137 MainWP_Client::save_note();
1138 }
1139
1140 /**
1141 * Method mainwp_clients_suspend_client()
1142 *
1143 * Post handler for suspend client,
1144 * Page: Manage Sites.
1145 *
1146 * @uses \MainWP\Dashboard\MainWP_Manage_Sites_Handler::save_note()
1147 */
1148 public function mainwp_clients_suspend_client() {
1149 $this->secure_request( 'mainwp_clients_suspend_client' );
1150 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1151 $clientid = isset( $_POST['clientid'] ) ? intval( $_POST['clientid'] ) : 0;
1152 $suspended = isset( $_POST['suspend_status'] ) && ! empty( $_POST['suspend_status'] ) ? 1 : 0;
1153 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1154
1155 if ( empty( $clientid ) ) {
1156 wp_die( 'Error - empty client id!' );
1157 }
1158
1159 $params = array(
1160 'client_id' => $clientid,
1161 'suspended' => $suspended,
1162 );
1163
1164 MainWP_DB_Client::instance()->update_client( $params );
1165
1166 $client = MainWP_DB_Client::instance()->get_wp_client_by( 'client_id', $clientid );
1167
1168 /**
1169 * Fires immediately after update client suspend/unsuspend.
1170 *
1171 * @since 4.5.1.1
1172 *
1173 * @param object $client client data.
1174 * @param bool $suspended true|false.
1175 */
1176 do_action( 'mainwp_client_suspend', $client, $suspended );
1177
1178 MainWP_DB_Client::instance()->suspend_unsuspend_websites_by_client_id( $clientid, $suspended );
1179
1180 wp_die( 'success' );
1181 }
1182
1183 /**
1184 * Method mainwp_clients_check_client()
1185 *
1186 * The client check has been created in the system yet.
1187 *
1188 * @uses \MainWP_DB_Client::instance()->get_wp_client_by()
1189 */
1190 public function mainwp_clients_check_client() {
1191 $this->secure_request( 'mainwp_clients_check_client' );
1192 // phpcs:disable WordPress.Security.NonceVerification
1193 $client_email = isset( $_POST['email'] ) ? sanitize_text_field( wp_unslash( $_POST['email'] ) ) : '';
1194 // phpcs:enable WordPress.Security.NonceVerification
1195 $client_existed = MainWP_DB_Client::instance()->get_wp_client_by( 'client_email', $client_email, ARRAY_A );
1196 if ( is_array( $client_existed ) && isset( $client_existed['client_id'] ) ) {
1197 return wp_send_json_error( array( 'error' => esc_html__( 'Client email exists. Please try again.', 'mainwp' ) ) );
1198 }
1199 return wp_send_json_success( array( 'result' => esc_html__( 'Client email not exists.', 'mainwp' ) ) );
1200 }
1201
1202 /**
1203 * Method mainwp_clients_import_client()
1204 *
1205 * Import new client
1206 *
1207 * @uses \MainWP_DB::instance()->get_websites_by_url()
1208 * @uses \MainWP_Client_Handler::get_default_client_fields()
1209 * @uses \MainWP_DB_Client::instance()->update_client()
1210 * @uses \MainWP_DB_Client::instance()->update_selected_sites_for_client()
1211 */
1212 public function mainwp_clients_import_client() { // phpcs:ignore -- NOSONAR
1213 $this->secure_request( 'mainwp_clients_import_client' );
1214 // phpcs:disable
1215 // Set value from POST data.
1216 $default_values = array(
1217 'client.name' => ! empty( $_POST['name'] ) ? sanitize_text_field( wp_unslash( $_POST['name'] ) ) : '',
1218 'client.email' => ! empty( $_POST['email'] ) ? sanitize_text_field( wp_unslash( $_POST['email'] ) ) : '',
1219 'client.contact.address.1' => ! empty( $_POST['address_1'] ) ? sanitize_text_field( wp_unslash( $_POST['address_1'] ) ) : '',
1220 'client.contact.address.2' => ! empty( $_POST['address_2'] ) ? sanitize_text_field( wp_unslash( $_POST['address_2'] ) ) : '',
1221 'client.city' => ! empty( $_POST['city'] ) ? sanitize_text_field( wp_unslash( $_POST['city'] ) ) : '',
1222 'client.state' => ! empty( $_POST['state'] ) ? sanitize_text_field( wp_unslash( $_POST['state'] ) ) : '',
1223 'client.zip' => ! empty( $_POST['zip'] ) ? sanitize_text_field( wp_unslash( $_POST['zip'] ) ) : '',
1224 'client.country' => ! empty( $_POST['country'] ) ? sanitize_text_field( wp_unslash( $_POST['country'] ) ) : '',
1225 'client.suspended' => ! empty( $_POST['suspended'] ) ? sanitize_text_field( wp_unslash( $_POST['suspended'] ) ) : 0,
1226 );
1227 // Get Site id.
1228 $selected_sites = array();
1229 if ( ! empty( $_POST['urls'] ) ) {
1230 $urls = array_map( 'sanitize_text_field', wp_unslash( $_POST['urls'] ) );
1231 $selected_sites = array_filter(
1232 array_map(
1233 function ( $v_url ) {
1234 $url = esc_url( $v_url );
1235 $website = MainWP_DB::instance()->get_websites_by_url( $url );
1236 return ! empty( $website ) ? current( $website )->id : null;
1237 },
1238 $urls
1239 )
1240 );
1241 }
1242 // phpcs:enable
1243 $client_to_add = array();
1244 $default_client_fields = MainWP_Client_Handler::get_default_client_fields(); // Get client field database.
1245 foreach ( $default_values as $key_client => $val_client ) {
1246 if ( isset( $default_client_fields[ $key_client ] ) && ! empty( $default_client_fields[ $key_client ]['db_field'] ) && ! empty( $val_client ) ) {
1247 $client_to_add[ $default_client_fields[ $key_client ]['db_field'] ] = $val_client; // Assign data to customers according to DB Field.
1248 }
1249 }
1250
1251 if ( ! empty( $client_to_add ) ) {
1252 // Set default values.
1253 $client_to_add['created'] = time();
1254 $client_to_add['primary_contact_id'] = 0;
1255 // Inset client.
1256 $inserted = MainWP_DB_Client::instance()->update_client( $client_to_add, true );
1257
1258 if ( ! empty( $inserted ) && is_object( $inserted ) ) {
1259 if ( ! empty( $selected_sites ) ) {
1260 MainWP_DB_Client::instance()->update_selected_sites_for_client( $inserted->client_id, $selected_sites ); // Set client to selected sites.
1261 }
1262 // Set default color and icon .
1263 $update = array(
1264 'client_id' => $inserted->client_id,
1265 'selected_icon_info' => 'selected:wordpress;color:#34424d',
1266 );
1267 MainWP_DB_Client::instance()->update_client( $update ); // Update Client.
1268
1269 return wp_send_json_success(
1270 array(
1271 'message' => esc_html__( 'successful client.', 'mainwp' ),
1272 'client' => $inserted,
1273 )
1274 );
1275 }
1276 return wp_send_json_error(
1277 array(
1278 'message' => esc_html__( 'unsuccessful client.', 'mainwp' ),
1279 )
1280 );
1281 }
1282 return wp_send_json_error(
1283 array(
1284 'message' => esc_html__( 'Error, please try again later.', 'mainwp' ),
1285 )
1286 );
1287 }
1288
1289 /**
1290 * Method mainwp_syncerrors_dismiss()
1291 *
1292 * Dismiss Sync errors for,
1293 * Widget: RightNow.
1294 *
1295 * @uses \MainWP\Dashboard\MainWP_Updates_Overview::dismiss_sync_errors()
1296 */
1297 public function mainwp_syncerrors_dismiss() {
1298
1299 $this->secure_request( 'mainwp_syncerrors_dismiss' );
1300
1301 try {
1302 die( wp_json_encode( array( 'result' => MainWP_Updates_Overview::dismiss_sync_errors() ) ) );
1303 } catch ( \Exception $e ) {
1304 die( wp_json_encode( array( 'error' => sanitize_text_field( $e->getMessage() ) ) ) );
1305 }
1306 }
1307
1308 /**
1309 * Method mainwp_events_notice_hide()
1310 *
1311 * Hide events notice.
1312 */
1313 public function mainwp_events_notice_hide() {
1314 $this->secure_request( 'mainwp_events_notice_hide' );
1315 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1316 if ( isset( $_POST['notice'] ) ) {
1317 $current_options = get_option( 'mainwp_showhide_events_notice' );
1318 if ( ! is_array( $current_options ) ) {
1319 $current_options = array();
1320 }
1321 if ( 'first_site' === $_POST['notice'] ) {
1322 update_option( 'mainwp_first_site_events_notice', '' );
1323 } elseif ( 'request_reviews1' === $_POST['notice'] ) {
1324 $current_options['request_reviews1'] = 15;
1325 $current_options['request_reviews1_starttime'] = time();
1326 } elseif ( 'request_reviews1_forever' === $_POST['notice'] || 'request_reviews2_forever' === $_POST['notice'] ) {
1327 $current_options['request_reviews1'] = 'forever';
1328 $current_options['request_reviews2'] = 'forever';
1329 } elseif ( 'request_reviews2' === $_POST['notice'] ) {
1330 $current_options['request_reviews2'] = 15;
1331 $current_options['request_reviews2_starttime'] = time();
1332 } elseif ( 'trust_child' === $_POST['notice'] ) {
1333 $current_options['trust_child'] = 1;
1334 } elseif ( 'multi_site' === $_POST['notice'] ) {
1335 $current_options['hide_multi_site_notice'] = 1;
1336 }
1337 update_option( 'mainwp_showhide_events_notice', $current_options );
1338 }
1339 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1340 die( 'ok' );
1341 }
1342
1343 /**
1344 * Method mainwp_showhide_sections()
1345 *
1346 * Show/Hide sections.
1347 */
1348 public function mainwp_showhide_sections() {
1349 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1350 if ( isset( $_POST['sec'] ) && isset( $_POST['status'] ) ) {
1351 $opts = get_option( 'mainwp_opts_showhide_sections' );
1352 if ( ! is_array( $opts ) ) {
1353 $opts = array();
1354 }
1355 $opts[ sanitize_text_field( wp_unslash( $_POST['sec'] ) ) ] = sanitize_text_field( wp_unslash( $_POST['status'] ) );
1356 update_option( 'mainwp_opts_showhide_sections', $opts );
1357 die( 'ok' );
1358 }
1359 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1360 die( 'failed' );
1361 }
1362
1363 /**
1364 * Method mainwp_saving_status()
1365 *
1366 * MainWP Saving Status.
1367 */
1368 public function mainwp_saving_status() {
1369 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1370 if ( ! isset( $_REQUEST['nonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['nonce'] ), 'mainwp_ajax' ) ) {
1371 die( esc_html__( 'WP nonce could not be verified. Please reload the page and try again.', 'mainwp' ) );
1372 }
1373 $saving_status = isset( $_POST['saving_status'] ) ? sanitize_text_field( wp_unslash( $_POST['saving_status'] ) ) : false;
1374 if ( ! empty( $saving_status ) ) {
1375 $current_options = get_option( 'mainwp_opts_saving_status' );
1376 if ( ! is_array( $current_options ) ) {
1377 $current_options = array();
1378 }
1379 if ( isset( $_POST['value'] ) ) {
1380 $current_options[ $saving_status ] = sanitize_text_field( wp_unslash( $_POST['value'] ) );
1381 }
1382 update_option( 'mainwp_opts_saving_status', $current_options );
1383 }
1384 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1385 die( 'ok' );
1386 }
1387
1388 /**
1389 * Method ajax_recheck_http()
1390 *
1391 * Recheck Child Site http status code & message.
1392 *
1393 * @uses \MainWP\Dashboard\MainWP_Connect::check_ignored_http_code()
1394 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
1395 * @uses \MainWP\Dashboard\MainWP_Monitoring_Handler::handle_check_website()
1396 */
1397 public function ajax_recheck_http() {
1398 $this->check_security( 'mainwp_recheck_http' );
1399 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1400 if ( ! isset( $_POST['websiteid'] ) || empty( $_POST['websiteid'] ) ) {
1401 die( -1 );
1402 }
1403
1404 $website = MainWP_DB::instance()->get_website_by_id( intval( $_POST['websiteid'] ) );
1405 if ( empty( $website ) ) {
1406 die( -1 );
1407 }
1408 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1409
1410 $result = MainWP_Monitoring_Handler::handle_check_website( $website );
1411 $http_code = ( is_array( $result ) && isset( $result['httpCode'] ) ) ? $result['httpCode'] : 0;
1412 $check_result = MainWP_Connect::check_ignored_http_code( $http_code, $website );
1413
1414 if ( is_array( $result ) && isset( $result['new_uptime_status'] ) ) {
1415 $check_result = $result['new_uptime_status'];
1416 }
1417
1418 die(
1419 wp_json_encode(
1420 array(
1421 'httpcode' => esc_html( $http_code ),
1422 'status' => $check_result ? 1 : 0,
1423 )
1424 )
1425 );
1426 }
1427
1428 /**
1429 * Method mainwp_ignore_http_response()
1430 *
1431 * Ignore Child Site https response.
1432 *
1433 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
1434 * @uses \MainWP\Dashboard\MainWP_DB::update_website_values()
1435 */
1436 public function mainwp_ignore_http_response() {
1437 $this->check_security( 'mainwp_ignore_http_response' );
1438 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1439 $siteid = isset( $_POST['websiteid'] ) ? intval( $_POST['websiteid'] ) : false;
1440 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1441 if ( empty( $siteid ) ) {
1442 die( -1 );
1443 }
1444
1445 $website = MainWP_DB::instance()->get_website_by_id( $siteid );
1446 if ( empty( $website ) ) {
1447 die( -1 );
1448 }
1449
1450 MainWP_DB::instance()->update_website_values( $website->id, array( 'http_response_code' => '-1' ) );
1451 die( wp_json_encode( array( 'ok' => 1 ) ) );
1452 }
1453
1454 /**
1455 * Method mainwp_autoupdate_and_trust_child()
1456 *
1457 * Set MainWP Child Plugin to Trusted & AutoUpdate.
1458 *
1459 * @uses \MainWP\Dashboard\MainWP_Plugins_Handler::trust_plugin()
1460 */
1461 public function mainwp_autoupdate_and_trust_child() {
1462 $this->secure_request( 'mainwp_autoupdate_and_trust_child' );
1463 if ( 1 !== (int) get_option( 'mainwp_pluginAutomaticDailyUpdate' ) ) {
1464 update_option( 'mainwp_pluginAutomaticDailyUpdate', 1 );
1465 }
1466 MainWP_Plugins_Handler::trust_plugin( 'mainwp-child/mainwp-child.php' );
1467 die( 'ok' );
1468 }
1469
1470 /**
1471 * Method mainwp_force_destroy_sessions()
1472 *
1473 * Force destroy sessions.
1474 *
1475 * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
1476 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
1477 *
1478 * @uses \MainWP\Dashboard\MainWP_System_Utility::can_edit_website()
1479 */
1480 public function mainwp_force_destroy_sessions() {
1481 $this->secure_request( 'mainwp_force_destroy_sessions' );
1482
1483 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1484 $website_id = ( isset( $_POST['website_id'] ) ? (int) $_POST['website_id'] : 0 );
1485 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1486 if ( ! MainWP_DB::instance()->get_website_by_id( $website_id ) ) {
1487 die( wp_json_encode( array( 'error' => array( 'message' => esc_html__( 'This website does not exist.', 'mainwp' ) ) ) ) );
1488 }
1489
1490 $website = MainWP_DB::instance()->get_website_by_id( $website_id );
1491 if ( ! MainWP_System_Utility::can_edit_website( $website ) ) {
1492 die( wp_json_encode( array( 'error' => array( 'message' => esc_html__( 'You cannot edit this website.', 'mainwp' ) ) ) ) );
1493 }
1494
1495 try {
1496 $information = MainWP_Connect::fetch_url_authed(
1497 $website,
1498 'settings_tools',
1499 array(
1500 'action' => 'force_destroy_sessions',
1501 )
1502 );
1503 } catch ( \Exception $e ) {
1504 $information = array( 'error' => esc_html__( 'fetch_url_authed exception', 'mainwp' ) );
1505 }
1506
1507 wp_send_json( $information );
1508 }
1509
1510 /**
1511 * Method ajax_refresh_icon()
1512 */
1513 public function ajax_refresh_icon() {
1514 $this->secure_request( 'mainwp_refresh_icon' );
1515 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1516 $slug = isset( $_POST['slug'] ) ? sanitize_text_field( wp_unslash( $_POST['slug'] ) ) : '';
1517 $type = isset( $_POST['type'] ) ? sanitize_text_field( wp_unslash( $_POST['type'] ) ) : '';
1518 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1519
1520 if ( empty( $slug ) ) {
1521 wp_die( 'failed' );
1522 }
1523
1524 $fet_icon = MainWP_System_Utility::handle_get_icon( $slug, $type );
1525
1526 if ( ! empty( $fet_icon ) ) {
1527 wp_die( 'success' );
1528 } else {
1529 wp_die( 'failed' );
1530 }
1531 }
1532
1533 /**
1534 * Method ajax_upload_custom_icon()
1535 */
1536 public function ajax_upload_custom_icon() { //phpcs:ignore -- NOSONAR -complex.
1537 $this->secure_request( 'mainwp_upload_custom_icon' );
1538 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1539 $slug = isset( $_POST['slug'] ) ? sanitize_text_field( wp_unslash( $_POST['slug'] ) ) : '';
1540 $type = isset( $_POST['type'] ) ? sanitize_text_field( wp_unslash( $_POST['type'] ) ) : '';
1541 $delete = isset( $_POST['delete'] ) ? intval( $_POST['delete'] ) : 0;
1542
1543 if ( empty( $slug ) || ( 'plugin' !== $type && 'theme' !== $type ) ) {
1544 wp_die( 'Invalid data! Type or empty slug' );
1545 }
1546
1547 $sub_folder = '';
1548
1549 if ( 'plugin' === $type ) {
1550 $sub_folder = 'plugin-icons';
1551 } elseif ( 'theme' === $type ) {
1552 $sub_folder = 'theme-icons';
1553 } else {
1554 wp_die( wp_json_encode( array( 'result' => 'invalid' ) ) );
1555 }
1556
1557 if ( $delete ) {
1558 MainWP_System_Utility::update_cached_icons( '', $slug, $type, true );
1559 wp_die( wp_json_encode( array( 'result' => 'success' ) ) );
1560 }
1561
1562 $output = isset( $_FILES['mainwp_upload_icon_uploader'] ) ? MainWP_System_Utility::handle_upload_image( $sub_folder, $_FILES['mainwp_upload_icon_uploader'], 0 ) : null;
1563 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1564
1565 $uploaded_icon = 'NOTCHANGE';
1566 if ( is_array( $output ) && isset( $output['filename'] ) && ! empty( $output['filename'] ) ) {
1567 $uploaded_icon = $output['filename'];
1568 }
1569
1570 if ( 'NOTCHANGE' !== $uploaded_icon ) {
1571 MainWP_System_Utility::update_cached_icons( $uploaded_icon, $slug, $type, true );
1572 wp_die( wp_json_encode( array( 'result' => 'success' ) ) );
1573 } else {
1574 $result = array(
1575 'result' => 'failed',
1576 );
1577 $error = static::get_upload_icon_error( $output );
1578 if ( ! empty( $error ) ) {
1579 $result['error'] = esc_html( $error );
1580 }
1581 wp_die( wp_json_encode( $result ) );
1582 }
1583 }
1584
1585 /**
1586 * Method get_upload_icon_error().
1587 *
1588 * @param mixed $results Upload results.
1589 *
1590 * @return string
1591 */
1592 public static function get_upload_icon_error( $results ) {
1593 $error = '';
1594 if ( is_array( $results ) && ! empty( $results['error'] ) && is_array( $results['error'] ) ) {
1595 $error_code = $results['error'][0];
1596 switch ( $error_code ) {
1597 case 3:
1598 $error = __( 'File size is too big. Please try a smaller file.', 'mainwp' );
1599 break;
1600 case 4:
1601 $error = __( 'File type is not allowed. Please use a different file type.', 'mainwp' );
1602 break;
1603 case 5:
1604 $error = __( 'File extension is not allowed. Please use a different file type.', 'mainwp' );
1605 break;
1606 case 6:
1607 $error = __( 'Cannot copy file. Please try again.', 'mainwp' );
1608 break;
1609 case 9:
1610 $error = __( 'Failed to crop file. Please try again.', 'mainwp' );
1611 break;
1612 default:
1613 $error = __( 'Undefined error. Please try again.', 'mainwp' );
1614 break;
1615 }
1616 }
1617 return $error;
1618 }
1619
1620 /**
1621 * Method ajax_select_custom_theme()
1622 */
1623 public function ajax_select_custom_theme() {
1624 $this->secure_request( 'mainwp_select_custom_theme' );
1625 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1626 $theme = isset( $_POST['theme'] ) ? sanitize_text_field( wp_unslash( $_POST['theme'] ) ) : '';
1627 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1628 if ( empty( $theme ) ) {
1629 wp_die( 'failed' );
1630 }
1631
1632 $user = wp_get_current_user();
1633 if ( empty( $user ) || empty( $user->ID ) ) {
1634 wp_die( 'failed' );
1635 }
1636
1637 update_user_option( $user->ID, 'mainwp_selected_theme', $theme );
1638 wp_die( 'success' );
1639 }
1640
1641 /**
1642 * Method ajax_import_demo_data().
1643 */
1644 public function ajax_import_demo_data() {
1645 $this->secure_request( 'mainwp_import_demo_data' );
1646 $data = MainWP_Demo_Handle::get_instance()->import_data_demo();
1647 MainWP_Utility::update_option( 'mainwp_enable_guided_tours', 1 );
1648 wp_die( wp_json_encode( $data ) );
1649 }
1650
1651 /**
1652 * Method ajax_delete_demo_data().
1653 */
1654 public function ajax_delete_demo_data() {
1655 $this->secure_request( 'mainwp_delete_demo_data' );
1656 $data = MainWP_Demo_Handle::get_instance()->delete_data_demo();
1657 MainWP_Utility::update_option( 'mainwp_enable_guided_tours', 0 );
1658 wp_die( wp_json_encode( $data ) );
1659 }
1660
1661 /**
1662 * Method ajax_save_temp_import_website()
1663 *
1664 * Save temp import website.
1665 *
1666 * @uses MainWP_DB::instance()->get_general_option()
1667 * @uses MainWP_DB::instance()->update_general_option(()
1668 */
1669 public function ajax_save_temp_import_website() {
1670 $this->secure_request( 'mainwp_save_temp_import_website' ); // Check secure.
1671 $error_msg = esc_html__( 'Undefined error. Please try again.', 'mainwp' );
1672 // Get previously saved temporary data (if any).
1673 $values = MainWP_DB::instance()->get_general_option( 'temp_import_sites', 'array' );
1674 $status = $this->mainwp_get_sanitized_post( 'status' );
1675 $index = $this->mainwp_get_sanitized_post( 'row_index', 'intval' ) ?? 1;
1676 if ( empty( $status ) || '' === $index ) {
1677 wp_die( wp_send_json_error( $error_msg ) ); //phpcs:ignore WordPress.Security.EscapeOutput
1678 }
1679
1680 $is_update = false;
1681 if ( 'delete_temp' === $status ) { // Handling remove temp data.
1682 $is_update = $this->mainwp_handle_delete_temp_import_website( $values, $index );
1683 } elseif ( 'save_temp' === $status ) { // Handling save row data.
1684 // Update row data into array.
1685 $row_item = array(
1686 'site_url' => $this->mainwp_get_sanitized_post( 'site_url' ),
1687 'admin_name' => $this->mainwp_get_sanitized_post( 'admin_name' ),
1688 'admin_password' => $this->mainwp_get_sanitized_post( 'admin_password' ),
1689 'site_name' => $this->mainwp_get_sanitized_post( 'site_name' ),
1690 'tag' => $this->mainwp_get_sanitized_post( 'tag' ),
1691 'security_id' => $this->mainwp_get_sanitized_post( 'security_id' ),
1692 'http_username' => $this->mainwp_get_sanitized_post( 'http_username' ),
1693 'http_password' => $this->mainwp_get_sanitized_post( 'http_password' ),
1694 'verify_certificate' => $this->mainwp_get_sanitized_post( 'verify_certificate', 'intval' ) ?? 1,
1695 'ssl_version' => $this->mainwp_get_sanitized_post( 'ssl_version' ) ?? 'auto',
1696 );
1697
1698 $is_update = $this->mainwp_handle_save_temp_import_website( $values, $index, $row_item );
1699 }
1700 // Save data to options table.
1701 if ( $is_update ) {
1702 MainWP_DB::instance()->update_general_option( 'temp_import_sites', $values, 'array' );
1703 wp_die( wp_send_json_success( esc_html( __( 'Row data saved successfully.', 'mainwp' ) ) ) ); //phpcs:ignore WordPress.Security.EscapeOutput
1704 }
1705
1706 // In case of no updates.
1707 wp_die( wp_send_json_error( esc_html( $error_msg ) ) ); //phpcs:ignore WordPress.Security.EscapeOutput
1708 }
1709
1710 /**
1711 * Method mainwp_handle_delete_temp_import_website()
1712 *
1713 * Handling remove temp data.
1714 *
1715 * @param mixed $values temp import sites.
1716 * @param int $index row key.
1717 *
1718 * @return bool true|false.
1719 */
1720 private function mainwp_handle_delete_temp_import_website( &$values, $index ) {
1721 // Check if row data stream exists.
1722 if ( ! empty( $values ) && is_array( $values ) && array_key_exists( $index, $values ) ) {
1723 unset( $values[ $index ] ); // Remove row data.
1724 return true;
1725 }
1726 return false;
1727 }
1728
1729 /**
1730 * Method mainwp_handle_save_temp_import_website()
1731 *
1732 * Create value if empty or array key exists.
1733 *
1734 * @param mixed $values temp import sites.
1735 * @param int $index row key.
1736 * @param array $row_item new row.
1737 *
1738 * @return bool true.
1739 */
1740 private function mainwp_handle_save_temp_import_website( &$values, $index, $row_item ) {
1741 if ( empty( $values ) || ! array_key_exists( $index, $values ) ) {
1742 $index = 0 !== $index ? $index : 0;
1743 $values[ $index ] = $row_item;
1744 } else {
1745 $values[ $index ] = $row_item;
1746 }
1747 return true;
1748 }
1749
1750 /**
1751 * Method ajax_delete_temp_import_website().
1752 *
1753 * Delete data temp if has been added website.
1754 *
1755 * @uses MainWP_DB::instance()->get_general_option().
1756 * @uses MainWP_DB::instance()->update_general_option().
1757 */
1758 public function ajax_delete_temp_import_website() {
1759 $this->secure_request( 'mainwp_delete_temp_import_website' ); // Check secure.
1760 $error_msg = esc_html__( 'Undefined error. Please try again.', 'mainwp' );
1761 // Get option temp import sites data.
1762 $temp_sites = MainWP_DB::instance()->get_general_option( 'temp_import_sites', 'array' );
1763 if ( empty( $temp_sites ) || ! is_array( $temp_sites ) ) { // Check if temp_sites data exists and is an array.
1764 wp_die( wp_send_json_error( esc_html( $error_msg ) ) ); //phpcs:ignore WordPress.Security.EscapeOutput
1765 }
1766
1767 // Get wpurl, wpadmin from POST.
1768 $wp_url = $this->mainwp_get_sanitized_post( 'managesites_add_wpurl' );
1769 $wp_admin = $this->mainwp_get_sanitized_post( 'managesites_add_wpadmin' );
1770 if ( empty( $wp_url ) || empty( $wp_admin ) ) { // Check wpurl, wpadmin has data or empty.
1771 wp_die( wp_send_json_error( esc_html( $error_msg ) ) ); //phpcs:ignore WordPress.Security.EscapeOutput
1772 }
1773 $is_delete = false;
1774
1775 if ( ! empty( $temp_sites ) && is_array( $temp_sites ) ) {
1776 foreach ( $temp_sites as $k_site => $val_site ) { // Loop through data to remove added website.
1777 // Check if row data stream exists.
1778 if ( rtrim( $wp_url, '/' ) === $val_site['site_url'] && $wp_admin === $val_site['admin_name'] ) {
1779 // Remove row data.
1780 unset( $temp_sites[ $k_site ] );
1781 $is_delete = true;
1782 break;
1783 }
1784 }
1785 }
1786
1787 // Save data to options table.
1788 if ( $is_delete ) {
1789 MainWP_DB::instance()->update_general_option( 'temp_import_sites', $temp_sites, 'array' );
1790 wp_die( wp_send_json_success( esc_html__( 'Delete import row successfully.', 'mainwp' ) ) ); //phpcs:ignore WordPress.Security.EscapeOutput
1791 }
1792
1793 // In case of no delete.
1794 wp_die( wp_send_json_error( $error_msg ) ); //phpcs:ignore WordPress.Security.EscapeOutput
1795 }
1796
1797 /**
1798 * Method ajax_import_website_add_client()
1799 *
1800 * Create client.
1801 */
1802 public function ajax_import_website_add_client() {
1803 $this->secure_request( 'mainwp_import_website_add_client' ); // Check secure.
1804 $error_msg = esc_html__( 'Undefined error. Please try again.', 'mainwp' );
1805 try {
1806 // Retrieve client data.
1807 $data = $this->mainwp_get_sanitized_post( 'client' );
1808 $site_id = $this->mainwp_get_sanitized_post( 'site_id' );
1809
1810 if ( empty( $data ) ) {
1811 wp_die( wp_send_json_error( esc_html( $error_msg ) ) ); //phpcs:ignore WordPress.Security.EscapeOutput
1812 }
1813
1814 $client_data = json_decode( $data, true );
1815 // Create client.
1816 $client = $this->mainwp_handle_create_client( $client_data );
1817 if ( $client ) {
1818 // Add groups website and client.
1819 if ( ! empty( $site_id ) ) {
1820 $this->mainwp_handle_selected_sites_for_client( $client, $site_id );
1821 }
1822
1823 wp_die( wp_send_json_success( esc_html__( 'Created client successfully.', 'mainwp' ) ) ); //phpcs:ignore WordPress.Security.EscapeOutput
1824 }
1825 } catch ( \Exception $e ) {
1826 wp_die( wp_send_json_error( sanitize_text_field( $e->getMessage() ) ) ); //phpcs:ignore WordPress.Security.EscapeOutput
1827 }
1828 // In case of no created.
1829 wp_die( wp_send_json_error( esc_html( $error_msg ) ) ); //phpcs:ignore WordPress.Security.EscapeOutput
1830 }
1831
1832 /**
1833 * Method ajax_import_website_add_client_no_site()
1834 *
1835 * Create client dont has a website.
1836 */
1837 public function ajax_import_website_add_client_no_site() {
1838 $this->secure_request( 'mainwp_import_website_add_client_no_site' ); // Check secure.
1839 $error_msg = esc_html__( 'Undefined error. Please try again.', 'mainwp' );
1840 try {
1841 $data = ! empty( $_POST['client'] ) ? rest_sanitize_array( $_POST['client'] ) : array(); //phpcs:ignore -- NonceVerification.
1842
1843 if ( empty( $data ) || ! is_array( $data ) ) {
1844 wp_die( wp_send_json_error( esc_html( $error_msg ) ) ); //phpcs:ignore WordPress.Security.EscapeOutput
1845 }
1846
1847 foreach ( $data as $val_data ) {
1848 $client_data = json_decode( stripslashes( $val_data ), true ); // Decode client data.
1849 $this->mainwp_handle_create_client( $client_data ); // Update or instert new client.
1850 }
1851 } catch ( \Exception $e ) {
1852 wp_die( wp_send_json_error( sanitize_text_field( $e->getMessage() ) ) ); //phpcs:ignore WordPress.Security.EscapeOutput
1853 }
1854 // In case of no created.
1855 wp_die( wp_send_json_error( esc_html( $error_msg ) ) ); //phpcs:ignore WordPress.Security.EscapeOutput
1856 }
1857
1858 /**
1859 * Method ajax_clients_add_multi_client
1860 *
1861 * Create Multi Client form QSW.
1862 */
1863 public function ajax_clients_add_multi_client() {
1864 $error_msg = esc_html__( 'Undefined error. Please try again.', 'mainwp' );
1865 $this->check_security( 'mainwp_clients_add_multi_client' );
1866 $dataes = isset( $_POST['data'] ) ? $_POST['data'] : array(); //phpcs:ignore -- NonceVerification.
1867 try {
1868 if ( ! empty( $dataes ) ) {
1869 foreach ( $dataes as $val_data ) {
1870 $client_data = array(
1871 'image' => '',
1872 'name' => $val_data['client_name'] ?? '',
1873 'address_1' => '',
1874 'address_2' => '',
1875 'city' => '',
1876 'zip' => '',
1877 'state' => '',
1878 'country' => '',
1879 'note' => '',
1880 'selected_icon_info' => 'selected:wordpress;color:#34424d',
1881 'client_email' => $val_data['client_email'] ?? '',
1882 'client_phone' => '',
1883 'client_facebook' => '',
1884 'client_twitter' => '',
1885 'client_instagram' => '',
1886 'client_linkedin' => '',
1887 'suspended' => 0,
1888 'primary_contact_id' => 0,
1889 );
1890
1891 // Create client.
1892 $client = $this->mainwp_handle_create_client( $client_data );
1893
1894 // Create client successfy.
1895 if ( ! empty( $client ) && ! empty( $val_data['website_id'] ) ) {
1896 // Add groups website and client.
1897 $this->mainwp_handle_selected_sites_for_client( $client, $val_data['website_id'] );
1898 }
1899 // Create client contact.
1900 if ( ! empty( $val_data['contacts_field'] ) ) {
1901 $this->mainwp_handle_create_contact_for_client( $client, $val_data['contacts_field'] );
1902 }
1903 }
1904 wp_die( wp_send_json_success( esc_html__( 'Created client successfully.', 'mainwp' ) ) ); //phpcs:ignore WordPress.Security.EscapeOutput
1905 }
1906 } catch ( \Exception $e ) {
1907 wp_die( wp_send_json_error( sanitize_text_field( $e->getMessage() ) ) ); //phpcs:ignore WordPress.Security.EscapeOutput
1908 }
1909
1910 wp_die( wp_send_json_error( esc_html( $error_msg ) ) ); //phpcs:ignore WordPress.Security.EscapeOutput
1911 }
1912
1913 /**
1914 * Method ajax_increase_connection_security
1915 */
1916 public function ajax_increase_connection_security() {
1917 $this->check_security( 'mainwp_increase_connection_security' );
1918 $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_for_current_user( false, null, 'wp.url', false, false, null, true ) );
1919 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
1920 // try to decrypt priv key.
1921 $de_privkey = MainWP_Encrypt_Data_Lib::instance()->decrypt_privkey( base64_decode( $website->privkey ), $website->id ); // phpcs:ignore -- NOSONAR - base64_encode trust.
1922 if ( empty( $de_privkey ) ) { // key is not encrypted.
1923 $en_privkey = MainWP_Encrypt_Data_Lib::instance()->encrypt_privkey( base64_decode( $website->privkey ), $website->id, true ); //phpcs:ignore -- NOSONAR - trust - create encrypt priv key for the site.
1924 if ( ! empty( $en_privkey['en_data'] ) ) {
1925 MainWP_DB::instance()->update_website_values(
1926 $website->id,
1927 array(
1928 'privkey' => base64_encode( $en_privkey['en_data'] ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- NOSONAR - base64_encode trust.
1929 )
1930 );
1931 }
1932 }
1933 }
1934 MainWP_DB::free_result( $websites );
1935 $this->hide_dashboard_notice_status( 'mainwp_secure_priv_key_notice' );
1936 delete_option( 'mainwp_not_start_encrypt_keys' );
1937 wp_die( wp_json_encode( array( 'success' => 1 ) ) );
1938 }
1939
1940 /**
1941 * Method ajax_ui_mode_detected
1942 */
1943 public function ajax_ui_mode_detected() {
1944 $this->check_security( 'mainwp_qsw_ui_mode_detected' );
1945
1946 $detected_ui = isset( $_POST['ui_mode'] ) ? sanitize_text_field( wp_unslash( $_POST['ui_mode'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1947
1948 $current_user_theme = get_user_option( 'mainwp_selected_theme' );
1949 if ( empty( $current_user_theme ) ) {
1950 if ( 'dark' === $detected_ui ) {
1951 MainWP_Utility::update_user_option( 'mainwp_selected_theme', 'default-dark' );
1952 } else {
1953 MainWP_Utility::update_user_option( 'mainwp_selected_theme', 'default' );
1954 }
1955 }
1956
1957 wp_die( wp_json_encode( array( 'success' => 1 ) ) );
1958 }
1959
1960
1961
1962 /**
1963 * Handle ajax get changes logs for plugins/themes.
1964 */
1965 public function ajax_get_item_changes_logs() { //phpcs:ignore -- NOSONAR -complex.
1966 $this->check_security( 'mainwp_changes_logs_get_item_changes' );
1967
1968 $siteId = isset( $_POST['siteId'] ) ? intval( $_POST['siteId'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1969 $type = isset( $_POST['type'] ) ? sanitize_text_field( wp_unslash( $_POST['type'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1970 $slug = isset( $_POST['slug'] ) ? sanitize_text_field( wp_unslash( $_POST['slug'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1971 $name = isset( $_POST['name'] ) ? sanitize_text_field( wp_unslash( urldecode( $_POST['name'] ) ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1972
1973 if ( 'plugin' === $type && ! empty( $slug ) ) {
1974 if ( false !== strpos( $slug, '/' ) ) {
1975 $parts = explode( '/', $slug );
1976 $slug = $parts[0];
1977 } else {
1978 $slug = basename( $slug, '.php' );
1979 }
1980 } elseif ( 'theme' === $type && ! empty( $slug ) ) {
1981 $slug = strtolower( $slug );
1982 }
1983
1984 // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1985 $target_dt = ! empty( $_POST['target_date'] ) ? sanitize_text_field( wp_unslash( $_POST['target_date'] ) ) : '';
1986
1987 if ( ! in_array( $type, array( 'plugin', 'theme' ) ) || ( empty( $target_dt ) && ( empty( $siteId ) || ( empty( $slug ) && empty( $name ) ) ) ) ) {
1988 wp_send_json( array( 'error' => esc_html__( 'Invalid request data. Please try again.', 'mainwp' ) ) );
1989 }
1990
1991 // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1992 $from_date = isset( $_POST['from_date'] ) ? sanitize_text_field( wp_unslash( $_POST['from_date'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1993
1994 $results = Log_Changes_Logs_Helper::instance()->get_history_changes(
1995 array(
1996 'wpid' => $siteId,
1997 'from_date' => $from_date,
1998 'days_number' => 10,
1999 'slug' => $slug,
2000 'type' => $type,
2001 'name' => $name,
2002 'target_date' => $target_dt,
2003 )
2004 );
2005
2006 if ( ! is_array( $results ) ) {
2007 $results = array();
2008 }
2009
2010 wp_send_json( $results );
2011 }
2012
2013
2014 /**
2015 * Method mainwp_get_sanitized_post()
2016 *
2017 * Sanitized post field.
2018 *
2019 * @param string $key key to get from POST.
2020 * @param string $callback cleaning method.
2021 *
2022 * @return mixed data value.
2023 */
2024 public function mainwp_get_sanitized_post( $key, $callback = 'sanitize_text_field' ) {
2025 return isset( $_POST[ $key ] ) ? $callback( wp_unslash( $_POST[ $key ] ) ) : ''; //phpcs:ignore -- NonceVerification.
2026 }
2027
2028 /**
2029 * Method mainwp_handle_create_client()
2030 *
2031 * Create new client or return client data.
2032 *
2033 * @uses MainWP_DB_Client::instance()->get_wp_client_by()
2034 * @uses MainWP_DB_Client::instance()->update_client()
2035 *
2036 * @param array $client_data new client creation data.
2037 *
2038 * @return object client data.
2039 */
2040 public function mainwp_handle_create_client( $client_data ) {
2041 // Check if client does not exist then create new one.
2042 $client = MainWP_DB_Client::instance()->get_wp_client_by( 'client_email', $client_data['client_email'], OBJECT );
2043 if ( empty( $client ) ) {
2044 $client = MainWP_DB_Client::instance()->update_client( $client_data ); // Create client.
2045 }
2046
2047 return $client;
2048 }
2049
2050 /**
2051 * Method mainwp_handle_selected_sites_for_client()
2052 *
2053 * Update selected sites for client.
2054 *
2055 * @uses MainWP_DB_Client::instance()->get_websites_by_client_ids()
2056 * @uses MainWP_DB_Client::instance()->update_selected_sites_for_client()
2057 *
2058 * @param object $client client data.
2059 * @param int $website_id id.
2060 */
2061 public function mainwp_handle_selected_sites_for_client( $client, $website_id ) {
2062 $sites_ids = MainWP_DB_Client::instance()->get_websites_by_client_ids( $client->client_id );
2063 $ids = isset( $sites_ids ) && ! empty( $sites_ids ) ? array_column( $sites_ids, 'id' ) : array();
2064 $ids[] = $website_id;
2065 MainWP_DB_Client::instance()->update_selected_sites_for_client( $client->client_id, $ids );
2066 }
2067
2068 /**
2069 * Method mainwp_handle_create_contact_for_client()
2070 *
2071 * Handle create contact for client.
2072 *
2073 * @uses MainWP_DB_Client::instance()->update_client_contact()
2074 * @uses MMainWP_DB_Client::instance()->update_client()
2075 *
2076 * @param object $client client data.
2077 * @param array $contacts_data contacts Data.
2078 */
2079 public function mainwp_handle_create_contact_for_client( $client, $contacts_data ) {
2080 $contacts = array_filter( $contacts_data );
2081 // Check required fields.
2082 if ( ( isset( $contacts['contact_name'] ) && '' !== $contacts['contact_name'] ) && ( isset( $contacts['contact_email'] ) && $contacts['contact_email'] ) ) {
2083 $contact_data = array(
2084 'contact_name' => $contacts['contact_name'] ?? '',
2085 'contact_email' => $contacts['contact_email'] ?? '',
2086 'contact_role' => $contacts['contact_role'] ?? '',
2087 'contact_client_id' => $client->client_id,
2088 'contact_phone' => '',
2089 'facebook' => '',
2090 'twitter' => '',
2091 'instagram' => '',
2092 'linkedin' => '',
2093 'contact_icon_info' => '',
2094 );
2095 $inserted = MainWP_DB_Client::instance()->update_client_contact( $contact_data ); // Create or update contact of client.
2096 // If the update is successful, the client will be updated again.
2097 if ( $inserted ) {
2098 $update = array(
2099 'client_id' => $client->client_id,
2100 'primary_contact_id' => $inserted->contact_id,
2101 );
2102 MainWP_DB_Client::instance()->update_client( $update );
2103 }
2104 }
2105 }
2106 }
2107