PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / trunk
MainWP Dashboard: Self-hosted WordPress Management for Agencies vtrunk
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
← All changes | class/class-mainwp-sync.php +408 -92 5.2trunk View file →
@@ -8,8 +8,13 @@
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_Sync
14 19 *
15 20 * @package MainWP\Dashboard
@@ -15,10 +20,56 @@
15 20 * @package MainWP\Dashboard
16 21 */
17 22 class MainWP_Sync { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
18 23
24 + /**
25 + * Clone websites setting.
26 + *
27 + * @var mixed Clone websites.
28 + */
29 + public static $clone_websites = null;
19 30
20 31 /**
32 + * Clone enabled setting.
33 + *
34 + * @var mixed Clone enabled.
35 + */
36 + public static $clone_enabled = null;
37 +
38 +
39 + /**
40 + * Disallowed Clone sites setting.
41 + *
42 + * @var mixed Disallowed clone.
43 + */
44 + public static $disallowed_clone_sites = null;
45 +
46 + /**
47 + * Get the current stack action if the helper is available.
48 + *
49 + * Some execution paths can reach sync handlers before the stack helper
50 + * has been loaded, so telemetry must degrade safely instead of fatalling.
51 + *
52 + * @return string|null
53 + */
54 + protected static function get_current_stack_action() {
55 + return class_exists( __NAMESPACE__ . '\MainWP_Stack_Helper' ) ? MainWP_Stack_Helper::stack_current() : null;
56 + }
57 +
58 + /**
59 + * Push a stack action if the helper is available.
60 + *
61 + * @param string $action Stack action.
62 + * @return void
63 + */
64 + protected static function push_stack_action( $action ) {
65 + if ( class_exists( __NAMESPACE__ . '\MainWP_Stack_Helper' ) ) {
66 + MainWP_Stack_Helper::stack_push( $action );
67 + }
68 + }
69 +
70 +
71 + /**
21 72 * Method sync_website()
22 73 *
23 74 * Sync Child Site.
24 75 *
@@ -72,50 +123,74 @@
72 123 if ( $clear_session ) {
73 124 MainWP_Utility::end_session();
74 125 }
75 126
127 + $cur_id = MainWP_System_Utility::get_current_wpid();
128 + if ( empty( $cur_id ) ) {
129 + MainWP_System_Utility::set_current_wpid( $pWebsite->id );
130 + }
131 +
132 + MainWP_Logger::instance()->log_execution_sync( 'init', '', $pWebsite );
133 + $stats_track_id = MainWP_Execution_Helper::execute_call_track( 'start_point', $pWebsite );
134 +
76 135 try {
77 136
78 - /**
79 - * Filter: mainwp_clone_enabled
80 - *
81 - * Filters whether the Clone feature is enabled or disabled.
82 - *
83 - * @since Unknown
84 - */
85 - $cloneEnabled = apply_filters( 'mainwp_clone_enabled', false );
86 - $cloneSites = array();
137 + if ( null === static::$clone_enabled ) {
87 138
88 - $disallowed_current_site = false;
139 + /**
140 + * Filter: mainwp_clone_enabled
141 + *
142 + * Filters whether the Clone feature is enabled or disabled.
143 + *
144 + * @since Unknown
145 + */
146 + static::$clone_enabled = apply_filters( 'mainwp_clone_enabled', false );
147 + static::$clone_websites = array();
89 148
90 - if ( $cloneEnabled ) {
91 - $disallowedCloneSites = get_option( 'mainwp_clone_disallowedsites' );
92 - if ( false === $disallowedCloneSites ) {
93 - $disallowedCloneSites = array();
94 - }
95 - $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_for_current_user() );
96 - if ( $websites ) {
97 - while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
98 - if ( in_array( $website->id, $disallowedCloneSites ) ) {
99 - continue;
149 + if ( static::$clone_enabled ) {
150 +
151 + static::$disallowed_clone_sites = get_option( 'mainwp_clone_disallowedsites' );
152 +
153 + if ( ! is_array( static::$disallowed_clone_sites ) ) {
154 + static::$disallowed_clone_sites = array();
155 + }
156 +
157 + $wpsite_fields = array( 'id', 'name', 'url', 'adminname' );
158 + $sync_fields = array( 'extauth', 'totalsize' );
159 + $websites = MainWP_DB::instance()->query(
160 + MainWP_DB::instance()->get_sql_websites_for_current_user_by_params(
161 + array(
162 + 'select_wp_fields' => $wpsite_fields,
163 + 'select_sync_fields' => $sync_fields,
164 + )
165 + )
166 + );
167 +
168 + if ( $websites ) {
169 + while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
170 + if ( in_array( $website->id, static::$disallowed_clone_sites ) ) {
171 + continue;
172 + }
173 + if ( (int) $website->id === (int) $pWebsite->id ) {
174 + continue;
175 + }
176 +
177 + static::$clone_websites[ $website->id ] = array(
178 + 'name' => $website->name,
179 + 'url' => $website->url,
180 + 'extauth' => $website->extauth,
181 + 'size' => $website->totalsize,
182 + 'connect_admin' => $website->adminname,
183 + );
100 184 }
101 - if ( (int) $website->id === (int) $pWebsite->id ) {
102 - continue;
103 - }
104 -
105 - $cloneSites[ $website->id ] = array(
106 - 'name' => $website->name,
107 - 'url' => $website->url,
108 - 'extauth' => $website->extauth,
109 - 'size' => $website->totalsize,
110 - 'connect_admin' => $website->adminname,
111 - );
185 + MainWP_DB::free_result( $websites );
112 186 }
113 - MainWP_DB::free_result( $websites );
187 + $disallowed_current_site = in_array( $pWebsite->id, static::$disallowed_clone_sites ) ? true : false;
114 188 }
115 - $disallowed_current_site = in_array( $pWebsite->id, $disallowedCloneSites ) ? true : false;
116 189 }
117 190
191 + $disallowed_current_site = static::$clone_enabled && is_array( static::$disallowed_clone_sites ) && in_array( $pWebsite->id, static::$disallowed_clone_sites ) ? true : false;
192 +
118 193 $primaryBackup = MainWP_System_Utility::get_primary_backup();
119 194
120 195 $othersData = apply_filters_deprecated( 'mainwp-sync-others-data', array( array(), $pWebsite ), '4.0.7.2', 'mainwp_sync_others_data' ); // @deprecated Use 'mainwp_sync_others_data' instead. NOSONAR - not IP.
121 196
@@ -133,20 +208,78 @@
133 208 $othersData = apply_filters( 'mainwp_sync_others_data', $othersData, $pWebsite );
134 209
135 210 $saved_days_number = apply_filters( 'mainwp_site_actions_saved_days_number', 30 );
136 211
212 + $backup_method = '';
213 + if ( property_exists( $pWebsite, 'primary_backup_method' ) ) {
214 + if ( '' === $pWebsite->primary_backup_method || 'global' === $pWebsite->primary_backup_method ) {
215 + $backup_method = $primaryBackup;
216 + } else {
217 + $backup_method = $pWebsite->primary_backup_method;
218 + }
219 + }
220 +
137 221 $postdata = array(
138 222 'optimize' => 1 === (int) get_option( 'mainwp_optimize', 1 ) ? 1 : 0,
139 - 'cloneSites' => ( ! $cloneEnabled || $disallowed_current_site ) ? 0 : rawurlencode( wp_json_encode( $cloneSites ) ),
223 + 'cloneSites' => ( ! static::$clone_enabled || $disallowed_current_site ) ? 0 : rawurlencode( wp_json_encode( static::$clone_websites ) ),
140 224 'othersData' => wp_json_encode( $othersData ),
141 225 'server' => get_admin_url(),
142 226 'numberdaysOutdatePluginTheme' => get_option( 'mainwp_numberdays_Outdate_Plugin_Theme', 365 ),
143 - 'primaryBackup' => $primaryBackup,
227 + 'primaryBackup' => $backup_method, // if empty site backup method will not sync the backup info from child site.
144 228 'siteId' => $pWebsite->id,
145 229 'child_actions_saved_days_number' => intval( $saved_days_number ),
146 230 'pingnonce' => MainWP_Utility::instance()->create_site_nonce( 'pingnonce', $pWebsite->id ),
147 231 );
148 232
233 + $individual_settings_json = MainWP_DB::instance()->get_website_option( $pWebsite, 'password_policy_individual_settings' );
234 + $individual_settings = array();
235 +
236 + if ( ! empty( $individual_settings_json ) ) {
237 + $individual_settings = json_decode( $individual_settings_json, true );
238 + if ( ! is_array( $individual_settings ) ) {
239 + $individual_settings = array();
240 + }
241 + }
242 +
243 + if ( ! empty( $individual_settings['overwrite_enabled'] ) ) {
244 + $password_policy_settings = wp_parse_args(
245 + $individual_settings,
246 + array(
247 + 'max_age_days' => 0,
248 + 'due_soon_message' => __( 'Your password is due to be changed soon. Please update it as soon as possible. This helps keep your account secure.', 'mainwp' ),
249 + 'overdue_message' => __( 'Your password change is overdue. Please update your password now. This is required by your site\'s password policy.', 'mainwp' ),
250 + 'show_notices_to' => 'edit_posts',
251 + )
252 + );
253 + } else {
254 + $password_policy_defaults = array(
255 + 'max_age_days' => 0,
256 + 'due_soon_message' => __( 'Your password is due to be changed soon. Please update it as soon as possible. This helps keep your account secure.', 'mainwp' ),
257 + 'overdue_message' => __( 'Your password change is overdue. Please update your password now. This is required by your site\'s password policy.', 'mainwp' ),
258 + 'show_notices_to' => 'edit_posts',
259 + );
260 + $password_policy_settings = wp_parse_args( get_option( 'mainwp_password_policy_settings', array() ), $password_policy_defaults );
261 + }
262 +
263 + $postdata['passwordPolicySettings'] = wp_json_encode( $password_policy_settings );
264 +
265 + $reg_verify = MainWP_DB::instance()->get_website_option( $pWebsite, 'register_verify_key', '' );
266 + if ( empty( $reg_verify ) ) {
267 + $postdata['sync_regverify'] = 1;
268 + }
269 +
270 + $postdata['params_logs'] = apply_filters( 'mainwp_module_logs_changes_logs_sync_params', '', $pWebsite->id, $postdata, $pWebsite );
271 +
272 + if ( class_exists( '\MainWP\Dashboard\Module\Log\Log_Manager' ) ) {
273 + $sync_last_created = \MainWP\Dashboard\Module\Log\Log_Manager::instance()->get_sync_actions_last_created( $pWebsite->id );
274 + $postdata['child_actions_last_created'] = (float) $sync_last_created;
275 + }
276 +
277 + $synclist = MainWP_Settings::get_instance()->get_data_list_to_sync();
278 + $postdata['syncdata'] = wp_json_encode( $synclist );
279 +
280 + static::push_stack_action( 'sync_stats' );
281 +
149 282 $information = MainWP_Connect::fetch_url_authed(
150 283 $pWebsite,
151 284 'stats',
152 285 $postdata,
@@ -152,25 +285,25 @@
152 285 $postdata,
153 286 true,
154 287 $pForceFetch
155 288 );
156 - $return = static::sync_information_array( $pWebsite, $information, '', 1, false, $pAllowDisconnect );
289 +
290 + $return = static::sync_information_array( $pWebsite, $information, '', false, false, $pAllowDisconnect );
157 291 MainWP_Logger::instance()->log_execution_time( 'sync :: [siteid=' . $pWebsite->id . ']' );
292 + MainWP_Execution_Helper::execute_call_track( 'end_point', $pWebsite, array(), $stats_track_id, 'stats site' );
158 293 return $return;
159 294 } catch ( MainWP_Exception $e ) {
160 - $sync_errors = '';
161 - $check_result = 1;
295 + MainWP_Execution_Helper::execute_call_track( 'end_point', $pWebsite, array(), $stats_track_id, 'stats site' );
296 + $sync_errors = '';
162 297
163 298 if ( $e->getMessage() === 'HTTPERROR' ) {
164 - $sync_errors = esc_html__( 'HTTP error', 'mainwp' ) . ( ! empty( $e->get_message_extra() ) ? ' - ' . $e->get_message_extra() : '' );
165 - $check_result = - 1;
299 + $sync_errors = esc_html__( 'HTTP error', 'mainwp' ) . ( ! empty( $e->get_message_extra() ) ? ' - ' . $e->get_message_extra() : '' );
166 300 } elseif ( $e->getMessage() === 'NOMAINWP' ) {
167 - $sync_errors = MainWP_Error_Helper::get_error_not_detected_connect();
168 - $check_result = 1;
301 + $sync_errors = MainWP_Error_Helper::get_error_not_detected_connect();
169 302 }
170 303
171 304 MainWP_Logger::instance()->log_execution_time( 'sync :: [siteid=' . $pWebsite->id . ']' );
172 - return static::sync_information_array( $pWebsite, $information, $sync_errors, $check_result, true, $pAllowDisconnect );
305 + return static::sync_information_array( $pWebsite, $information, $sync_errors, false, true, $pAllowDisconnect );
173 306 }
174 307 }
175 308
176 309 /**
@@ -183,8 +316,10 @@
183 316 * @param string $sync_errors Check for Sync Errors.
184 317 * @param int $check_result Check if offline.
185 318 * @param bool $error True|False.
186 319 * @param bool $pAllowDisconnect True|False.
320 + * @param array $other Additional parameters.
321 + * @param array $fetch_output Fetch output.
187 322 *
188 323 * @return bool true|false True on success, false on failure.
189 324 *
190 325 * @uses \MainWP\Dashboard\MainWP_DB::update_website_option()
@@ -194,22 +329,11 @@
194 329 * @uses \MainWP\Dashboard\MainWP_Monitoring_Handler::get_health_noticed_status_value()
195 330 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
196 331 * @uses \MainWP\Dashboard\MainWP_Utility::get_site_health()
197 332 */
198 - public static function sync_information_array( &$pWebsite, &$information, $sync_errors = '', $check_result = 1, $error = false, $pAllowDisconnect = true ) { // phpcs:ignore -- NOSONAR -Current complexity is the only way to achieve desired results, pull request solutions appreciated.
333 + public static function sync_information_array( &$pWebsite, &$information, $sync_errors = '', $check_result = false, $error = false, $pAllowDisconnect = true, $other = array(), $fetch_output = array() ) { // phpcs:ignore -- NOSONAR -Current complexity is the only way to achieve desired results, pull request solutions appreciated.
199 334 $emptyArray = wp_json_encode( array() );
200 - $websiteValues = array(
201 - 'directories' => $emptyArray,
202 - 'plugin_upgrades' => $emptyArray,
203 - 'theme_upgrades' => $emptyArray,
204 - 'translation_upgrades' => $emptyArray,
205 - 'securityIssues' => $emptyArray,
206 - 'themes' => $emptyArray,
207 - 'plugins' => $emptyArray,
208 - 'users' => $emptyArray,
209 - 'categories' => $emptyArray,
210 - 'offline_check_result' => $check_result,
211 - );
335 + $websiteValues = array();
212 336 $websiteSyncValues = array(
213 337 'sync_errors' => $sync_errors,
214 338 'version' => 0,
215 339 );
@@ -240,8 +364,13 @@
240 364 * @since 3.4
241 365 */
242 366 $information = apply_filters( 'mainwp_before_save_sync_result', $information, $pWebsite );
243 367
368 + if ( ! empty( $information['regverify_info'] ) ) {
369 + MainWP_DB::instance()->update_website_option( $pWebsite, 'register_verify_key', $information['regverify_info'] );
370 + $done = true;
371 + }
372 +
244 373 if ( isset( $information['siteurl'] ) ) {
245 374 $websiteValues['siteurl'] = $information['siteurl'];
246 375 $done = true;
247 376 }
@@ -251,8 +380,9 @@
251 380 $done = true;
252 381 }
253 382
254 383 $phpversion = '';
384 + $wpversion = '';
255 385 if ( isset( $information['site_info'] ) && ! empty( $information['site_info'] ) ) {
256 386 if ( is_array( $information['site_info'] ) && isset( $information['site_info']['phpversion'] ) ) {
257 387 $phpversion = $information['site_info']['phpversion'];
258 388 }
@@ -258,16 +388,25 @@
258 388 }
259 389 if ( is_array( $information['site_info'] ) && isset( $information['site_info']['ip'] ) ) {
260 390 $websiteValues['ip'] = sanitize_text_field( wp_unslash( $information['site_info']['ip'] ) );
261 391 }
392 +
393 + if ( is_array( $information['site_info'] ) && isset( $information['site_info']['wpversion'] ) ) {
394 + $wpversion = $information['site_info']['wpversion'];
395 + }
396 +
262 397 MainWP_DB::instance()->update_website_option( $pWebsite, 'site_info', wp_json_encode( $information['site_info'] ) );
263 398 $done = true;
264 - } else {
265 - MainWP_DB::instance()->update_website_option( $pWebsite, 'site_info', $emptyArray );
266 399 }
400 +
267 401 if ( ! empty( $phpversion ) ) {
268 402 MainWP_DB::instance()->update_website_option( $pWebsite, 'phpversion', $phpversion );
269 403 }
404 + if ( ! empty( $wpversion ) ) { // to support sorting by wpversion.
405 + $ver_num = MainWP_Utility::instance()->wp_versions_order_num( $wpversion );
406 + MainWP_DB::instance()->update_website_option( $pWebsite, 'wpversion_order_num', $ver_num );
407 + }
408 +
270 409 if ( isset( $information['directories'] ) && is_array( $information['directories'] ) ) {
271 410 $websiteValues['directories'] = wp_json_encode( $information['directories'] );
272 411 $done = true;
273 412 } elseif ( isset( $information['directories'] ) ) {
@@ -274,8 +413,11 @@
274 413 $websiteValues['directories'] = $information['directories'];
275 414 $done = true;
276 415 }
277 416
417 + $had_pending_updates = null;
418 +
419 + $wp_updates_empty = true;
278 420 if ( isset( $information['wp_updates'] ) && ! empty( $information['wp_updates'] ) ) {
279 421 MainWP_DB::instance()->update_website_option(
280 422 $pWebsite,
281 423 'wp_upgrades',
@@ -285,11 +427,11 @@
285 427 'new' => $information['wp_updates'],
286 428 )
287 429 )
288 430 );
289 - $done = true;
290 - } else {
291 - MainWP_DB::instance()->update_website_option( $pWebsite, 'wp_upgrades', $emptyArray );
431 + $done = true;
432 + $wp_updates_empty = false;
433 + $had_pending_updates = true;
292 434 }
293 435
294 436 if ( isset( $information['plugin_updates'] ) ) {
295 437 $update_values = array();
@@ -297,8 +439,11 @@
297 439 foreach ( $information['plugin_updates'] as $file => $update ) {
298 440 $update_values[ $file ] = $update;
299 441 }
300 442 }
443 +
444 + $had_pending_updates = ! empty( $update_values ) || (bool) $had_pending_updates;
445 +
301 446 $websiteValues['plugin_upgrades'] = wp_json_encode( $update_values );
302 447 $done = true;
303 448 }
304 449
@@ -308,22 +453,24 @@
308 453 foreach ( $information['theme_updates'] as $file => $update ) {
309 454 $update_values[ $file ] = $update;
310 455 }
311 456 }
457 + $had_pending_updates = ! empty( $update_values ) || (bool) $had_pending_updates;
312 458 $websiteValues['theme_upgrades'] = wp_json_encode( $update_values );
313 459 $done = true;
314 460 }
315 461
316 462 if ( isset( $information['translation_updates'] ) ) {
463 + $had_pending_updates = ! empty( $information['translation_updates'] ) || (bool) $had_pending_updates;
317 464 $websiteValues['translation_upgrades'] = wp_json_encode( $information['translation_updates'] );
318 465 $done = true;
319 466 }
320 467
321 468 if ( isset( $information['premium_updates'] ) ) {
469 + $had_pending_updates = ! empty( $information['premium_updates'] ) || (bool) $had_pending_updates;
470 +
322 471 MainWP_DB::instance()->update_website_option( $pWebsite, 'premium_upgrades', wp_json_encode( $information['premium_updates'] ) );
323 472 $done = true;
324 - } else {
325 - MainWP_DB::instance()->update_website_option( $pWebsite, 'premium_upgrades', $emptyArray );
326 473 }
327 474
328 475 if ( isset( $information['securityStats'] ) ) {
329 476 $total_securityIssues = 0;
@@ -334,18 +481,8 @@
334 481 if ( false !== $filterStats && is_array( $filterStats ) ) {
335 482 $securityStats = array_merge( $securityStats, $filterStats );
336 483 }
337 484
338 - $unset_scripts = apply_filters( 'mainwp_unset_security_scripts_stylesheets', true );
339 - if ( $unset_scripts ) {
340 - if ( isset( $securityStats['versions'] ) ) {
341 - unset( $securityStats['versions'] );
342 - }
343 - if ( isset( $securityStats['registered_versions'] ) ) {
344 - unset( $securityStats['registered_versions'] );
345 - }
346 - }
347 -
348 485 $tmp_issues = array_filter(
349 486 $securityStats,
350 487 function ( $v ) {
351 488 return 'N' === $v;
@@ -367,24 +504,18 @@
367 504
368 505 if ( isset( $information['recent_comments'] ) ) {
369 506 MainWP_DB::instance()->update_website_option( $pWebsite, 'recent_comments', wp_json_encode( $information['recent_comments'] ) );
370 507 $done = true;
371 - } else {
372 - MainWP_DB::instance()->update_website_option( $pWebsite, 'recent_comments', $emptyArray );
373 508 }
374 509
375 510 if ( isset( $information['recent_posts'] ) ) {
376 511 MainWP_DB::instance()->update_website_option( $pWebsite, 'recent_posts', wp_json_encode( $information['recent_posts'] ) );
377 512 $done = true;
378 - } else {
379 - MainWP_DB::instance()->update_website_option( $pWebsite, 'recent_posts', $emptyArray );
380 513 }
381 514
382 515 if ( isset( $information['recent_pages'] ) ) {
383 516 MainWP_DB::instance()->update_website_option( $pWebsite, 'recent_pages', wp_json_encode( $information['recent_pages'] ) );
384 517 $done = true;
385 - } else {
386 - MainWP_DB::instance()->update_website_option( $pWebsite, 'recent_pages', $emptyArray );
387 518 }
388 519
389 520 if ( isset( $information['themes'] ) ) {
390 521 $websiteValues['themes'] = wp_json_encode( $information['themes'] );
@@ -390,10 +521,13 @@
390 521 $websiteValues['themes'] = wp_json_encode( $information['themes'] );
391 522 $done = true;
392 523 }
393 524
525 + $plugins_info = array();
526 +
394 527 if ( isset( $information['plugins'] ) ) {
395 - $websiteValues['plugins'] = wp_json_encode( $information['plugins'] );
528 + $plugins_info = $information['plugins'];
529 + $websiteValues['plugins'] = wp_json_encode( $plugins_info );
396 530 $done = true;
397 531 }
398 532
399 533 if ( isset( $information['users'] ) ) {
@@ -418,8 +552,13 @@
418 552 $websiteSyncValues['dbsize'] = $information['dbsize'];
419 553 $done = true;
420 554 }
421 555
556 + if ( isset( $information['dbsize_activitylogs'] ) ) {
557 + MainWP_DB::instance()->update_website_option( $pWebsite, 'dbsize_activitylogs', $information['dbsize_activitylogs'] );
558 + $done = true;
559 + }
560 +
422 561 if ( isset( $information['extauth'] ) ) {
423 562 $websiteSyncValues['extauth'] = $information['extauth'];
424 563 $done = true;
425 564 }
@@ -463,10 +602,8 @@
463 602 } else {
464 603 $health_status = 1; // Should be improved'.
465 604 }
466 605 $websiteSyncValues['health_status'] = $health_status;
467 - } else {
468 - MainWP_DB::instance()->update_website_option( $pWebsite, 'health_site_status', $emptyArray );
469 606 }
470 607
471 608 if ( isset( $information['mainwpdir'] ) ) {
472 609 $websiteValues['mainwpdir'] = $information['mainwpdir'];
@@ -495,19 +632,36 @@
495 632
496 633 if ( isset( $information['plugins_outdate_info'] ) ) {
497 634 MainWP_DB::instance()->update_website_option( $pWebsite, 'plugins_outdate_info', wp_json_encode( $information['plugins_outdate_info'] ) );
498 635 $done = true;
499 - } else {
500 - MainWP_DB::instance()->update_website_option( $pWebsite, 'plugins_outdate_info', $emptyArray );
501 636 }
502 637
503 638 if ( isset( $information['themes_outdate_info'] ) ) {
504 639 MainWP_DB::instance()->update_website_option( $pWebsite, 'themes_outdate_info', wp_json_encode( $information['themes_outdate_info'] ) );
505 640 $done = true;
506 - } else {
507 - MainWP_DB::instance()->update_website_option( $pWebsite, 'themes_outdate_info', $emptyArray );
508 641 }
509 642
643 + if ( isset( $information['password_policy_options'] ) ) {
644 + MainWP_DB::instance()->update_website_option( $pWebsite, 'password_policy_options', wp_json_encode( $information['password_policy_options'] ) );
645 + $done = true;
646 + }
647 +
648 + if ( isset( $information['premium_updates_results'] ) && is_array( $information['premium_updates_results'] ) ) {
649 + foreach ( array( 'plugin', 'theme' ) as $type ) {
650 + if ( isset( $information['premium_updates_results'][ $type ] ) ) {
651 + $update_results = $information['premium_updates_results'][ $type ];
652 + if ( is_array( $update_results ) ) {
653 + foreach ( $update_results as $info ) {
654 + if ( is_array( $info ) && isset( $info['other_data'] ) ) {
655 + $output_array = $info['other_data'];
656 + mainwp_get_actions_handler_instance()->do_action_mainwp_install_actions( $pWebsite, 'updated', $output_array, $type );
657 + }
658 + }
659 + }
660 + }
661 + }
662 + }
663 +
510 664 if ( isset( $information['primaryLasttimeBackup'] ) ) {
511 665 MainWP_DB::instance()->update_website_option( $pWebsite, 'primary_lasttime_backup', $information['primaryLasttimeBackup'] );
512 666 $done = true;
513 667 }
@@ -515,12 +669,29 @@
515 669 if ( isset( $information['child_site_actions_data'] ) ) {
516 670 if ( is_array( $information['child_site_actions_data'] ) && isset( $information['child_site_actions_data']['connected_admin'] ) ) {
517 671 unset( $information['child_site_actions_data']['connected_admin'] );
518 672 }
519 - MainWP_DB_Site_Actions::instance()->sync_site_actions( $pWebsite->id, $information['child_site_actions_data'] );
673 + if ( class_exists( '\MainWP\Dashboard\Module\Log\Log_Manager' ) ) {
674 + \MainWP\Dashboard\Module\Log\Log_Manager::instance()->sync_log_site_actions( $pWebsite->id, $information['child_site_actions_data'], $pWebsite );
675 + }
520 676 $done = true;
521 677 }
522 678
679 + if ( ! empty( $information['changes_logs_data'] ) && class_exists( '\MainWP\Dashboard\Module\Log\Log_Changes_Logs_Helper' ) ) {
680 + \MainWP\Dashboard\Module\Log\Log_Changes_Logs_Helper::instance()->sync_changes_logs( $pWebsite->id, $information['changes_logs_data'], $pWebsite );
681 + $done = true;
682 + }
683 +
684 + $monitor_data = array();
685 + if ( isset( $information['child_monitor_data'] ) && is_array( $information['child_monitor_data'] ) ) {
686 + $monitor_data = $information['child_monitor_data'];
687 + $done = true;
688 + }
689 +
690 + if ( $done ) {
691 + MainWP_DB::instance()->update_website_option( $pWebsite, 'child_monitor_data', wp_json_encode( $monitor_data ) );
692 + }
693 +
523 694 if ( ! $done ) {
524 695 if ( isset( $information['wpversion'] ) ) {
525 696 $done = true;
526 697 } elseif ( isset( $information['error'] ) ) {
@@ -548,18 +719,45 @@
548 719 }
549 720 }
550 721 }
551 722
552 - $act_success = false;
723 + $sync_success = false;
553 724 if ( $done ) {
554 - $act_success = true;
725 + $sync_success = true;
555 726 $websiteSyncValues['dtsSync'] = time();
727 + if ( $wp_updates_empty ) {
728 + MainWP_DB::instance()->update_website_option(
729 + $pWebsite,
730 + 'wp_upgrades',
731 + $emptyArray
732 + );
733 + }
556 734 }
557 735 MainWP_DB::instance()->update_website_sync_values( $pWebsite->id, $websiteSyncValues );
558 - MainWP_DB::instance()->update_website_values( $pWebsite->id, $websiteValues );
736 + MainWP_Logger::instance()->log_events( 'db-queries', sprintf( '[Update sync values=%s]', MainWP_DB::instance()->get_last_query() ) );
559 737
738 + if ( ! empty( $websiteValues ) ) {
739 + MainWP_DB::instance()->update_website_values( $pWebsite->id, $websiteValues );
740 + MainWP_Logger::instance()->log_events( 'db-queries', sprintf( '[Update site sync data=%s]', MainWP_DB::instance()->get_last_query() ) );
741 + }
742 +
743 + $error_occurred = $error;
744 + $msg_errors = $_error;
745 +
746 + $error = apply_filters( 'mainwp_sync_site_after_sync_result', $error, $pWebsite, $information );
747 +
748 + if ( ! empty( $plugins_info ) && is_array( $plugins_info ) ) {
749 + foreach ( $plugins_info as $info ) {
750 + if ( ! empty( $info['icon'] ) ) {
751 + $icon_slug = MainWP_Utility::get_dir_slug( $info['slug'] );
752 + MainWP_System_Utility::save_cached_icons( $info['icon'], $icon_slug, 'plugin' );
753 + }
754 + }
755 + }
756 +
560 757 // Sync action.
561 758 if ( ! $error ) {
759 +
562 760 do_action_deprecated( 'mainwp-site-synced', array( $pWebsite, $information ), '4.0.7.2', 'mainwp_site_synced' ); // @deprecated Use 'mainwp_site_synced' instead. NOSONAR - not IP.
563 761
564 762 /**
565 763 * Action: mainwp_site_synced
@@ -573,8 +771,45 @@
573 771 */
574 772 do_action( 'mainwp_site_synced', $pWebsite, $information );
575 773 }
576 774
775 + $telem_info = static::get_telem_sync_info( $sync_success );
776 +
777 + if ( isset( $information['version'] ) ) {
778 + $telem_info['child_plugin_version'] = $information['version'];
779 + }
780 +
781 + if ( isset( $had_pending_updates ) ) {
782 + $telem_info['site_had_pending_updates'] = $had_pending_updates ? true : false;
783 + }
784 +
785 + if ( $error_occurred && ! empty( $information['fetch_url_output'] ) && is_array( $information['fetch_url_output'] ) ) {
786 + $output = $information['fetch_url_output'];
787 + $telem_info['error_message'] = $msg_errors;
788 + $telem_info['error_category'] = ! empty( $output['error_category'] ) ? $output['error_category'] : 'unknown';
789 + $telem_info['error_code'] = ! empty( $output['error_code'] ) ? $output['error_code'] : 'undefined_error';
790 + $telem_info['connection_step'] = ! empty( $output['connection_step'] ) ? $output['connection_step'] : 'handshake';
791 + if ( ! empty( $output['http_status'] ) ) {
792 + $telem_info['http_status'] = $output['http_status'];
793 + }
794 + }
795 +
796 + /**
797 + * Action: mainwp_after_site_synced
798 + *
799 + * Fires upon site synchronization.
800 + *
801 + * @param object $pWebsite Object containing child site info.
802 + * @param array $information Array containing information returned from child site.
803 + * @param mixed $error Sync error result.
804 + * @param mixed $sync_errors Sync error message if existed.
805 + * @param array $other Additional parameters.
806 + * @param array $telem_info Telemetry information.
807 + *
808 + * @since 6.0
809 + */
810 + do_action( 'mainwp_after_site_synced', $pWebsite, $information, $error, $sync_errors, $other, $telem_info );
811 +
577 812 $post_data = array();
578 813
579 814 /**
580 815 * Action: mainwp_site_sync
@@ -582,18 +817,99 @@
582 817 * Fires upon successful site synchronization.
583 818 *
584 819 * @param object $pWebsite Object containing child site info.
585 820 * @param array $information Array containing information returned from child site.
586 - * @param bool $act_success action success or failed.
821 + * @param bool $sync_success action success or failed.
587 822 * @param string $_error Sync error message if existed.
588 823 * @param array $post_data Addition post data.
589 824 *
590 825 * @since 3.4
591 826 */
592 - do_action( 'mainwp_site_sync', $pWebsite, $information, $act_success, $_error, $post_data );
827 + do_action( 'mainwp_site_sync', $pWebsite, $information, $sync_success, $_error, $post_data );
593 828
594 829 return ! $error;
595 830 }
831 +
832 +
833 + /**
834 + * Method get_telem_sync_info.
835 + *
836 + * @param mixed $sync_done
837 + * @return void
838 + */
839 + public static function get_telem_sync_info( $sync_done ) {
840 +
841 + $is_bulk_sync = ! empty( $_POST['bulkSync'] ) ? true : false; // phpcs:ignore -- NOSONAR - superglobal usage is acceptable.
842 +
843 + $tp = 'post_add_site';
844 +
845 + if ( $is_bulk_sync ) {
846 + $tp = 'manual_bulk';
847 + } elseif ( defined( 'DOING_CRON' ) && DOING_CRON ) {
848 + $tp = 'auto_cron';
849 + } elseif ( isset( $_POST['bulkSync'] ) && ! $is_bulk_sync ) { //phpcs:ignore -- NOSONAR - superglobal usage is acceptable.
850 + $tp = 'manual_single';
851 + }
852 +
853 + $trigger = 'system';
854 + if ( 'manual_single' === $tp || 'manual_bulk' === $tp ) {
855 + $trigger = 'user_click';
856 + } elseif ( defined( 'DOING_CRON' ) && DOING_CRON ) {
857 + $trigger = 'cron';
858 + }
859 +
860 + $curr_stack = static::get_current_stack_action();
861 + $prev_conn_status = in_array( $curr_stack, array( 'sync_before_reconnect', 'sync_reconnect' ) ) ? 'disconnected' : 'connected';
862 + $new_conn_status = $sync_done ? 'disconnected' : 'connected';
863 +
864 + return array(
865 + 'sync_type' => $tp,
866 + 'trigger' => $trigger,
867 + 'previous_connection_status' => $prev_conn_status,
868 + 'new_connection_status' => $new_conn_status,
869 + 'connection_status_changed' => $prev_conn_status === $new_conn_status ? false : true,
870 + 'sync_duration_ms' => MainWP_Execution_Helper::get_run_time( true ),
871 + );
872 + }
873 +
874 + /**
875 + * Method init empty sync values.
876 + *
877 + * @param object $pWebsite Object containing child site info.
878 + *
879 + * @return void
880 + */
881 + public static function sync_init_empty_values( $pWebsite ) {
882 +
883 + $emptyArray = wp_json_encode( array() );
884 +
885 + $opts = array(
886 + 'site_info',
887 + 'wp_upgrades',
888 + 'premium_upgrades',
889 + 'recent_comments',
890 + 'recent_posts',
891 + 'recent_pages',
892 + 'health_site_status',
893 + 'plugins_outdate_info',
894 + 'themes_outdate_info',
895 + 'directories',
896 + 'plugin_upgrades',
897 + 'theme_upgrades',
898 + 'translation_upgrades',
899 + 'securityIssues',
900 + 'themes',
901 + 'plugins',
902 + 'users',
903 + 'categories',
904 + 'password_policy_options',
905 + );
906 +
907 + foreach ( $opts as $opt ) {
908 + MainWP_DB::instance()->update_website_option( $pWebsite, $opt, $emptyArray );
909 + }
910 + }
911 +
596 912
597 913 /**
598 914 * Method get_wp_icon()
599 915 *