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

class-mainwp-sync.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies 4.1, at class/class-mainwp-sync.php

509 lines 17.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * MainWP Sync Handler
4 *
5 * Handle all syncing between MainWP & Child Site Network.
6 *
7 * @package MainWP/Dashboard
8 */
9
10 namespace MainWP\Dashboard;
11
12 /**
13 * Class MainWP_Sync
14 *
15 * @package MainWP\Dashboard
16 */
17 class MainWP_Sync {
18
19 /**
20 * Method sync_site()
21 *
22 * @param mixed $pWebsite Null|userid.
23 * @param bool $pForceFetch Check if a fourced Sync.
24 * @param bool $pAllowDisconnect Check if allowed to disconect.
25 *
26 * @return array sync_information_array
27 */
28 public static function sync_site( &$pWebsite = null, $pForceFetch = false, $pAllowDisconnect = true ) {
29 if ( null == $pWebsite ) {
30 return false;
31 }
32 $userExtension = MainWP_DB_Common::instance()->get_user_extension_by_user_id( $pWebsite->userid );
33 if ( null == $userExtension ) {
34 return false;
35 }
36
37 MainWP_Utility::end_session();
38
39 try {
40
41 /**
42 * Filter: mainwp_clone_enabled
43 *
44 * Filters whether the Clone feature is enabled or disabled.
45 *
46 * @since Unknown
47 */
48 $cloneEnabled = apply_filters( 'mainwp_clone_enabled', false );
49 $cloneSites = array();
50 if ( $cloneEnabled ) {
51 $disallowedCloneSites = get_option( 'mainwp_clone_disallowedsites' );
52 if ( false === $disallowedCloneSites ) {
53 $disallowedCloneSites = array();
54 }
55 $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_for_current_user() );
56 if ( $websites ) {
57 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
58 if ( in_array( $website->id, $disallowedCloneSites ) ) {
59 continue;
60 }
61 if ( $website->id == $pWebsite->id ) {
62 continue;
63 }
64
65 $cloneSites[ $website->id ] = array(
66 'name' => $website->name,
67 'url' => $website->url,
68 'extauth' => $website->extauth,
69 'size' => $website->totalsize,
70 );
71 }
72 MainWP_DB::free_result( $websites );
73 }
74 }
75
76 $primaryBackup = MainWP_System_Utility::get_primary_backup();
77
78 $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.
79
80 /**
81 * Filter: mainwp_sync_others_data
82 *
83 * Filters additional data in the sync request. Allows extensions or 3rd party plugins to hook data to the sync request.
84 *
85 * @param object $pWebsite Object contaning child site data.
86 *
87 * @since Unknown
88 */
89 $othersData = apply_filters( 'mainwp_sync_others_data', $othersData, $pWebsite );
90
91 $information = MainWP_Connect::fetch_url_authed(
92 $pWebsite,
93 'stats',
94 array(
95 'optimize' => ( ( get_option( 'mainwp_optimize' ) == 1 ) ? 1 : 0 ),
96 'cloneSites' => ( ! $cloneEnabled ? 0 : rawurlencode( wp_json_encode( $cloneSites ) ) ),
97 'othersData' => wp_json_encode( $othersData ),
98 'server' => get_admin_url(),
99 'numberdaysOutdatePluginTheme' => get_option( 'mainwp_numberdays_Outdate_Plugin_Theme', 365 ),
100 'primaryBackup' => $primaryBackup,
101 'siteId' => $pWebsite->id,
102 ),
103 true,
104 $pForceFetch
105 );
106 MainWP_DB::instance()->update_website_option( $pWebsite, 'primary_lasttime_backup', isset( $information['primaryLasttimeBackup'] ) ? $information['primaryLasttimeBackup'] : 0 );
107 $return = self::sync_information_array( $pWebsite, $information, '', 1, false, $pAllowDisconnect );
108
109 return $return;
110 } catch ( MainWP_Exception $e ) {
111 $sync_errors = '';
112 $check_result = 1;
113
114 if ( $e->getMessage() == 'HTTPERROR' ) {
115 $sync_errors = __( 'HTTP error', 'mainwp' ) . ( $e->get_message_extra() != null ? ' - ' . $e->get_message_extra() : '' );
116 $check_result = - 1;
117 } elseif ( $e->getMessage() == 'NOMAINWP' ) {
118 $sync_errors = __( 'MainWP Child plugin not detected', 'mainwp' );
119 $check_result = 1;
120 }
121
122 return self::sync_information_array( $pWebsite, $information, $sync_errors, $check_result, true, $pAllowDisconnect );
123 }
124 }
125
126 /**
127 * Method sync_information_array()
128 *
129 * Grab all Child Site Information.
130 *
131 * @param object $pWebsite The website object.
132 * @param array $information Array contaning information returned from child site.
133 * @param string $sync_errors Check for Sync Errors.
134 * @param int $check_result Check if offline.
135 * @param bool $error True|False.
136 * @param bool $pAllowDisconnect True|False.
137 *
138 * @return bool true|false True on success, false on failure.
139 */
140 public static function sync_information_array( &$pWebsite, &$information, $sync_errors = '', $check_result = 1, $error = false, $pAllowDisconnect = true ) { // phpcs:ignore -- Current complexity is the only way to achieve desired results, pull request solutions appreciated.
141 $emptyArray = wp_json_encode( array() );
142 $websiteValues = array(
143 'directories' => $emptyArray,
144 'plugin_upgrades' => $emptyArray,
145 'theme_upgrades' => $emptyArray,
146 'translation_upgrades' => $emptyArray,
147 'securityIssues' => $emptyArray,
148 'themes' => $emptyArray,
149 'plugins' => $emptyArray,
150 'users' => $emptyArray,
151 'categories' => $emptyArray,
152 'offline_check_result' => $check_result,
153 );
154 $websiteSyncValues = array(
155 'sync_errors' => $sync_errors,
156 'version' => 0,
157 );
158
159 $done = false;
160
161 /**
162 * Filter: mainwp_before_save_sync_result
163 *
164 * Filters data returned from child site before sasving to the database.
165 *
166 * @param object $pWebsite Object contaning child site data.
167 *
168 * @since 3.4
169 */
170 $information = apply_filters( 'mainwp_before_save_sync_result', $information, $pWebsite );
171
172 if ( isset( $information['siteurl'] ) ) {
173 $websiteValues['siteurl'] = $information['siteurl'];
174 $done = true;
175 }
176
177 if ( isset( $information['version'] ) ) {
178 $websiteSyncValues['version'] = $information['version'];
179 $done = true;
180 }
181
182 $phpversion = '';
183 if ( isset( $information['site_info'] ) && null != $information['site_info'] ) {
184 if ( is_array( $information['site_info'] ) && isset( $information['site_info']['phpversion'] ) ) {
185 $phpversion = $information['site_info']['phpversion'];
186 }
187 MainWP_DB::instance()->update_website_option( $pWebsite, 'site_info', wp_json_encode( $information['site_info'] ) );
188 $done = true;
189 } else {
190 MainWP_DB::instance()->update_website_option( $pWebsite, 'site_info', $emptyArray );
191 }
192 MainWP_DB::instance()->update_website_option( $pWebsite, 'phpversion', $phpversion );
193
194 if ( isset( $information['directories'] ) && is_array( $information['directories'] ) ) {
195 $websiteValues['directories'] = wp_json_encode( $information['directories'] );
196 $done = true;
197 } elseif ( isset( $information['directories'] ) ) {
198 $websiteValues['directories'] = $information['directories'];
199 $done = true;
200 }
201
202 if ( isset( $information['wp_updates'] ) && null != $information['wp_updates'] ) {
203 MainWP_DB::instance()->update_website_option(
204 $pWebsite,
205 'wp_upgrades',
206 wp_json_encode(
207 array(
208 'current' => $information['wpversion'],
209 'new' => $information['wp_updates'],
210 )
211 )
212 );
213 $done = true;
214 } else {
215 MainWP_DB::instance()->update_website_option( $pWebsite, 'wp_upgrades', $emptyArray );
216 }
217
218 if ( isset( $information['plugin_updates'] ) ) {
219 $websiteValues['plugin_upgrades'] = wp_json_encode( $information['plugin_updates'] );
220 $done = true;
221 }
222
223 if ( isset( $information['theme_updates'] ) ) {
224 $websiteValues['theme_upgrades'] = wp_json_encode( $information['theme_updates'] );
225 $done = true;
226 }
227
228 if ( isset( $information['translation_updates'] ) ) {
229 $websiteValues['translation_upgrades'] = wp_json_encode( $information['translation_updates'] );
230 $done = true;
231 }
232
233 if ( isset( $information['premium_updates'] ) ) {
234 MainWP_DB::instance()->update_website_option( $pWebsite, 'premium_upgrades', wp_json_encode( $information['premium_updates'] ) );
235 $done = true;
236 } else {
237 MainWP_DB::instance()->update_website_option( $pWebsite, 'premium_upgrades', $emptyArray );
238 }
239
240 if ( isset( $information['securityStats'] ) ) {
241 $total_securityIssues = 0;
242 $securityStats = $information['securityStats'];
243 if ( is_array( $securityStats ) ) {
244 /** This filter is documented in ../pages/page-mainwp-security-issues.php */
245 $filterStats = apply_filters( 'mainwp_security_issues_stats', false, $securityStats, $pWebsite );
246 if ( false !== $filterStats && is_array( $filterStats ) ) {
247 $securityStats = array_merge( $securityStats, $filterStats );
248 }
249
250 $tmp_issues = array_filter(
251 $securityStats,
252 function( $v, $k ) {
253 return 'N' == $v;
254 },
255 ARRAY_FILTER_USE_BOTH
256 );
257 $total_securityIssues = count( $tmp_issues );
258 $securityStats = wp_json_encode( $securityStats );
259 } else {
260 $securityStats = $emptyArray;
261 }
262 $websiteValues['securityIssues'] = $total_securityIssues;
263 $done = true;
264 } elseif ( isset( $information['securityIssues'] ) && MainWP_Utility::ctype_digit( $information['securityIssues'] ) && $information['securityIssues'] >= 0 ) {
265 $websiteValues['securityIssues'] = $information['securityIssues'];
266 $done = true;
267 }
268
269 if ( isset( $information['recent_comments'] ) ) {
270 MainWP_DB::instance()->update_website_option( $pWebsite, 'recent_comments', wp_json_encode( $information['recent_comments'] ) );
271 $done = true;
272 } else {
273 MainWP_DB::instance()->update_website_option( $pWebsite, 'recent_comments', $emptyArray );
274 }
275
276 if ( isset( $information['recent_posts'] ) ) {
277 MainWP_DB::instance()->update_website_option( $pWebsite, 'recent_posts', wp_json_encode( $information['recent_posts'] ) );
278 $done = true;
279 } else {
280 MainWP_DB::instance()->update_website_option( $pWebsite, 'recent_posts', $emptyArray );
281 }
282
283 if ( isset( $information['recent_pages'] ) ) {
284 MainWP_DB::instance()->update_website_option( $pWebsite, 'recent_pages', wp_json_encode( $information['recent_pages'] ) );
285 $done = true;
286 } else {
287 MainWP_DB::instance()->update_website_option( $pWebsite, 'recent_pages', $emptyArray );
288 }
289
290 if ( isset( $information['themes'] ) ) {
291 $websiteValues['themes'] = wp_json_encode( $information['themes'] );
292 $done = true;
293 }
294
295 if ( isset( $information['plugins'] ) ) {
296 $websiteValues['plugins'] = wp_json_encode( $information['plugins'] );
297 $done = true;
298 }
299
300 if ( isset( $information['users'] ) ) {
301 $websiteValues['users'] = wp_json_encode( $information['users'] );
302 $done = true;
303 }
304
305 if ( isset( $information['categories'] ) ) {
306 $websiteValues['categories'] = wp_json_encode( $information['categories'] );
307 $done = true;
308 }
309
310 if ( isset( $information['totalsize'] ) ) {
311 $websiteSyncValues['totalsize'] = $information['totalsize'];
312 $done = true;
313 }
314
315 if ( isset( $information['dbsize'] ) ) {
316 $websiteSyncValues['dbsize'] = $information['dbsize'];
317 $done = true;
318 }
319
320 if ( isset( $information['extauth'] ) ) {
321 $websiteSyncValues['extauth'] = $information['extauth'];
322 $done = true;
323 }
324
325 if ( isset( $information['nossl'] ) ) {
326 $websiteValues['nossl'] = $information['nossl'];
327 $done = true;
328 }
329
330 if ( isset( $information['wpe'] ) ) {
331 $websiteValues['wpe'] = $information['wpe'];
332 $done = true;
333 }
334
335 if ( isset( $information['last_post_gmt'] ) ) {
336 $websiteSyncValues['last_post_gmt'] = $information['last_post_gmt'];
337 $done = true;
338 }
339
340 if ( isset( $information['health_site_status'] ) ) {
341 $health_status = $information['health_site_status'];
342 $hstatus = MainWP_Utility::get_site_health( $health_status );
343 $new_health_value = $hstatus['val'] - $hstatus['critical'] * 100; // computes custom health value to support sorting by sites health and sites health threshold.
344 $websiteSyncValues['health_value'] = $new_health_value;
345 $done = true;
346 MainWP_DB::instance()->update_website_option( $pWebsite, 'health_site_status', wp_json_encode( $health_status ) );
347 $new_noticed = MainWP_Monitoring_Handler::get_health_noticed_status_value( $pWebsite, $new_health_value );
348 if ( null !== $new_noticed ) {
349 MainWP_DB::instance()->update_website_sync_values(
350 $pWebsite->id,
351 array(
352 'health_site_noticed' => $new_noticed,
353 )
354 );
355 }
356 } else {
357 MainWP_DB::instance()->update_website_option( $pWebsite, 'health_site_status', $emptyArray );
358 }
359
360 if ( isset( $information['mainwpdir'] ) ) {
361 $websiteValues['mainwpdir'] = $information['mainwpdir'];
362 $done = true;
363 }
364
365 if ( isset( $information['uniqueId'] ) ) {
366 $websiteValues['uniqueId'] = $information['uniqueId'];
367 $done = true;
368 }
369
370 if ( isset( $information['admin_nicename'] ) ) {
371 MainWP_DB::instance()->update_website_option( $pWebsite, 'admin_nicename', trim( $information['admin_nicename'] ) );
372 $done = true;
373 }
374
375 if ( isset( $information['admin_useremail'] ) ) {
376 MainWP_DB::instance()->update_website_option( $pWebsite, 'admin_useremail', trim( $information['admin_useremail'] ) );
377 $done = true;
378 }
379
380 if ( isset( $information['plugins_outdate_info'] ) ) {
381 MainWP_DB::instance()->update_website_option( $pWebsite, 'plugins_outdate_info', wp_json_encode( $information['plugins_outdate_info'] ) );
382 $done = true;
383 } else {
384 MainWP_DB::instance()->update_website_option( $pWebsite, 'plugins_outdate_info', $emptyArray );
385 }
386
387 if ( isset( $information['themes_outdate_info'] ) ) {
388 MainWP_DB::instance()->update_website_option( $pWebsite, 'themes_outdate_info', wp_json_encode( $information['themes_outdate_info'] ) );
389 $done = true;
390 } else {
391 MainWP_DB::instance()->update_website_option( $pWebsite, 'themes_outdate_info', $emptyArray );
392 }
393
394 if ( ! $done ) {
395 if ( isset( $information['wpversion'] ) ) {
396 $done = true;
397 } elseif ( isset( $information['error'] ) ) {
398 MainWP_Logger::instance()->warning_for_website( $pWebsite, 'SYNC ERROR', '[' . $information['error'] . ']' );
399 $error = true;
400 $done = true;
401 $websiteSyncValues['sync_errors'] = __( 'ERROR: ', 'mainwp' ) . $information['error'];
402 } elseif ( ! empty( $sync_errors ) ) {
403 MainWP_Logger::instance()->warning_for_website( $pWebsite, 'SYNC ERROR', '[' . $sync_errors . ']' );
404
405 $error = true;
406 if ( ! $pAllowDisconnect ) {
407 $sync_errors = '';
408 }
409
410 $websiteSyncValues['sync_errors'] = $sync_errors;
411 } else {
412 MainWP_Logger::instance()->warning_for_website( $pWebsite, 'SYNC ERROR', '[Undefined error]' );
413 $error = true;
414 if ( $pAllowDisconnect ) {
415 $websiteSyncValues['sync_errors'] = __( 'Undefined error! Please, reinstall the MainWP Child plugin on the child site.', 'mainwp' );
416 }
417 }
418 }
419
420 if ( $done ) {
421 $websiteSyncValues['dtsSync'] = time();
422 }
423 MainWP_DB::instance()->update_website_sync_values( $pWebsite->id, $websiteSyncValues );
424 MainWP_DB::instance()->update_website_values( $pWebsite->id, $websiteValues );
425
426 // Sync action.
427 if ( ! $error ) {
428 do_action_deprecated( 'mainwp-site-synced', array( $pWebsite, $information ), '4.0.7.2', 'mainwp_site_synced' ); // @deprecated Use 'mainwp_site_synced' instead.
429
430 /**
431 * Action: mainwp_site_synced
432 *
433 * Fires upon successfull site sinchronization.
434 *
435 * @param object $pWebsite Object contaning child site info.
436 * @param array $information Array contaning information returned from child site.
437 *
438 * @since 3.4
439 */
440 do_action( 'mainwp_site_synced', $pWebsite, $information );
441 }
442
443 return ( ! $error );
444 }
445
446 /**
447 * Method sync_site_icon()
448 *
449 * Get site's icon.
450 *
451 * @param mixed $siteId site's id.
452 * @return array result error or success
453 */
454 public static function sync_site_icon( $siteId = null ) {
455 if ( MainWP_Utility::ctype_digit( $siteId ) ) {
456 $website = MainWP_DB::instance()->get_website_by_id( $siteId );
457 if ( MainWP_System_Utility::can_edit_website( $website ) ) {
458 $error = '';
459 try {
460 $information = MainWP_Connect::fetch_url_authed( $website, 'get_site_icon' );
461 } catch ( MainWP_Exception $e ) {
462 $error = $e->getMessage();
463 }
464
465 if ( '' != $error ) {
466 return array( 'error' => $error );
467 } elseif ( isset( $information['faviIconUrl'] ) && ! empty( $information['faviIconUrl'] ) ) {
468 MainWP_Logger::instance()->debug( 'Downloading icon :: ' . $information['faviIconUrl'] );
469 $content = MainWP_Connect::get_file_content( $information['faviIconUrl'] );
470 if ( ! empty( $content ) ) {
471
472 $hasWPFileSystem = MainWP_System_Utility::get_wp_file_system();
473
474 /**
475 * WordPress files system object.
476 *
477 * @global object
478 */
479 global $wp_filesystem;
480
481 $dirs = MainWP_System_Utility::get_mainwp_dir( 'icons', true );
482 $iconsDir = $dirs[0];
483 $filename = basename( $information['faviIconUrl'] );
484 $filename = strtok( $filename, '?' );
485 if ( $filename ) {
486 $filename = 'favi-' . $siteId . '-' . $filename;
487 $size = $wp_filesystem->put_contents( $iconsDir . $filename, $content ); // phpcs:ignore --
488 if ( $size ) {
489 MainWP_Logger::instance()->debug( 'Icon size :: ' . $size );
490 MainWP_DB::instance()->update_website_option( $website, 'favi_icon', $filename );
491 return array( 'result' => 'success' );
492 } else {
493 return array( 'error' => 'Save icon file failed.' );
494 }
495 }
496 return array( 'undefined_error' => true );
497 } else {
498 return array( 'error' => esc_html__( 'Download icon file failed', 'mainwp' ) );
499 }
500 } else {
501 return array( 'undefined_error' => true );
502 }
503 }
504 }
505 return array( 'result' => 'NOSITE' );
506 }
507
508 }
509