PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 4.2
MainWP Dashboard: Self-hosted WordPress Management for Agencies v4.2
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 +501 -882 6.14.2 View file →
@@ -8,957 +8,576 @@
8 8 */
9 9
10 10 namespace MainWP\Dashboard;
11 11
12 -// Exit if accessed directly.
13 -if ( ! defined( 'ABSPATH' ) ) {
14 - exit;
15 -}
16 -
17 12 /**
18 13 * Class MainWP_Sync
19 14 *
20 15 * @package MainWP\Dashboard
21 16 */
22 -class MainWP_Sync { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
17 +class MainWP_Sync {
23 18
24 - /**
25 - * Clone websites setting.
26 - *
27 - * @var mixed Clone websites.
28 - */
29 - public static $clone_websites = null;
30 19
31 - /**
32 - * Clone enabled setting.
33 - *
34 - * @var mixed Clone enabled.
35 - */
36 - public static $clone_enabled = null;
20 + /**
21 + * Method sync_website()
22 + *
23 + * Sync Child Site.
24 + *
25 + * @param object $website object.
37 26
27 + * @return bool sync result.
28 + */
29 + public static function sync_website( $website ) {
30 + if ( ! is_object( $website ) ) {
31 + return false;
32 + }
33 + MainWP_DB::instance()->update_website_sync_values( $website->id, array( 'dtsSyncStart' => time() ) );
34 + return self::sync_site( $website );
35 + }
38 36
39 - /**
40 - * Disallowed Clone sites setting.
41 - *
42 - * @var mixed Disallowed clone.
43 - */
44 - public static $disallowed_clone_sites = null;
37 + /**
38 + * Method sync_site()
39 + *
40 + * @param mixed $pWebsite Null|userid.
41 + * @param bool $pForceFetch Check if a fourced Sync.
42 + * @param bool $pAllowDisconnect Check if allowed to disconect.
43 + *
44 + * @return bool sync_information_array
45 + *
46 + * @uses \MainWP\Dashboard\MainWP_DB_Common::get_user_extension_by_user_id()
47 + * @uses \MainWP\Dashboard\MainWP_DB::query()
48 + * @uses \MainWP\Dashboard\MainWP_DB::get_sql_search_websites_for_current_user()
49 + * @uses \MainWP\Dashboard\MainWP_DB::update_website_option()
50 + * @uses \MainWP\Dashboard\MainWP_DB::fetch_object()
51 + * @uses \MainWP\Dashboard\MainWP_DB::free_result()
52 + * @uses \MainWP\Dashboard\MainWP_Exception
53 + * @uses \MainWP\Dashboard\MainWP_System_Utility::get_primary_backup()
54 + * @uses \MainWP\Dashboard\MainWP_Utility::end_session()
55 + */
56 + public static function sync_site( &$pWebsite = null, $pForceFetch = false, $pAllowDisconnect = true ) {
57 + if ( null == $pWebsite ) {
58 + return false;
59 + }
60 + $userExtension = MainWP_DB_Common::instance()->get_user_extension_by_user_id( $pWebsite->userid );
61 + if ( null == $userExtension ) {
62 + return false;
63 + }
45 64
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 - }
65 + MainWP_Utility::end_session();
57 66
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 - }
67 + try {
69 68
69 + /**
70 + * Filter: mainwp_clone_enabled
71 + *
72 + * Filters whether the Clone feature is enabled or disabled.
73 + *
74 + * @since Unknown
75 + */
76 + $cloneEnabled = apply_filters( 'mainwp_clone_enabled', false );
77 + $cloneSites = array();
78 + if ( $cloneEnabled ) {
79 + $disallowedCloneSites = get_option( 'mainwp_clone_disallowedsites' );
80 + if ( false === $disallowedCloneSites ) {
81 + $disallowedCloneSites = array();
82 + }
83 + $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_for_current_user() );
84 + if ( $websites ) {
85 + while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
86 + if ( in_array( $website->id, $disallowedCloneSites ) ) {
87 + continue;
88 + }
89 + if ( $website->id == $pWebsite->id ) {
90 + continue;
91 + }
70 92
71 - /**
72 - * Method sync_website()
73 - *
74 - * Sync Child Site.
75 - *
76 - * @param object $website object.
77 - * @param bool $clear_session to run the ending session or not.
78 - *
79 - * @return bool sync result.
80 - */
81 - public static function sync_website( $website, $clear_session = true ) {
82 - if ( ! is_object( $website ) ) {
83 - return false;
84 - }
85 - MainWP_DB::instance()->update_website_sync_values( $website->id, array( 'dtsSyncStart' => time() ) );
86 - return static::sync_site( $website, false, true, $clear_session );
87 - }
93 + $cloneSites[ $website->id ] = array(
94 + 'name' => $website->name,
95 + 'url' => $website->url,
96 + 'extauth' => $website->extauth,
97 + 'size' => $website->totalsize,
98 + 'connect_admin' => $website->adminname,
99 + );
100 + }
101 + MainWP_DB::free_result( $websites );
102 + }
103 + }
88 104
89 - /**
90 - * Method sync_site()
91 - *
92 - * @param mixed $pWebsite Null|userid.
93 - * @param bool $pForceFetch Check if a fourced Sync.
94 - * @param bool $pAllowDisconnect Check if allowed to disconect.
95 - * @param bool $clear_session to run the ending session or not.
96 - *
97 - * @return bool sync_information_array
98 - *
99 - * @uses \MainWP\Dashboard\MainWP_DB_Common::get_user_extension_by_user_id()
100 - * @uses \MainWP\Dashboard\MainWP_DB::query()
101 - * @uses \MainWP\Dashboard\MainWP_DB::update_website_option()
102 - * @uses \MainWP\Dashboard\MainWP_DB::fetch_object()
103 - * @uses \MainWP\Dashboard\MainWP_DB::free_result()
104 - * @uses \MainWP\Dashboard\MainWP_Exception
105 - * @uses \MainWP\Dashboard\MainWP_System_Utility::get_primary_backup()
106 - * @uses \MainWP\Dashboard\MainWP_Utility::end_session()
107 - */
108 - public static function sync_site( &$pWebsite = null, $pForceFetch = false, $pAllowDisconnect = true, $clear_session = true ) { // phpcs:ignore -- NOSONAR - complexity method.
105 + $primaryBackup = MainWP_System_Utility::get_primary_backup();
109 106
110 - // to support demo data.
111 - if ( MainWP_Demo_Handle::get_instance()->is_demo_website( $pWebsite ) ) {
112 - return MainWP_Demo_Handle::get_instance()->handle_action_demo( $pWebsite, 'sync_site' );
113 - }
107 + $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.
114 108
115 - if ( null === $pWebsite ) {
116 - return false;
117 - }
118 - $userExtension = MainWP_DB_Common::instance()->get_user_extension_by_user_id( $pWebsite->userid );
119 - if ( null === $userExtension ) {
120 - return false;
121 - }
109 + /**
110 + * Filter: mainwp_sync_others_data
111 + *
112 + * Filters additional data in the sync request. Allows extensions or 3rd party plugins to hook data to the sync request.
113 + *
114 + * @param object $pWebsite Object contaning child site data.
115 + *
116 + * @since Unknown
117 + *
118 + * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
119 + */
120 + $othersData = apply_filters( 'mainwp_sync_others_data', $othersData, $pWebsite );
122 121
123 - if ( $clear_session ) {
124 - MainWP_Utility::end_session();
125 - }
122 + $information = MainWP_Connect::fetch_url_authed(
123 + $pWebsite,
124 + 'stats',
125 + array(
126 + 'optimize' => ( ( get_option( 'mainwp_optimize', 0 ) == 1 ) ? 1 : 0 ),
127 + 'cloneSites' => ( ! $cloneEnabled ? 0 : rawurlencode( wp_json_encode( $cloneSites ) ) ),
128 + 'othersData' => wp_json_encode( $othersData ),
129 + 'server' => get_admin_url(),
130 + 'numberdaysOutdatePluginTheme' => get_option( 'mainwp_numberdays_Outdate_Plugin_Theme', 365 ),
131 + 'primaryBackup' => $primaryBackup,
132 + 'siteId' => $pWebsite->id,
133 + ),
134 + true,
135 + $pForceFetch
136 + );
137 + $return = self::sync_information_array( $pWebsite, $information, '', 1, false, $pAllowDisconnect );
126 138
127 - $cur_id = MainWP_System_Utility::get_current_wpid();
128 - if ( empty( $cur_id ) ) {
129 - MainWP_System_Utility::set_current_wpid( $pWebsite->id );
130 - }
139 + return $return;
140 + } catch ( MainWP_Exception $e ) {
141 + $sync_errors = '';
142 + $check_result = 1;
131 143
132 - MainWP_Logger::instance()->log_execution_sync( 'init', '', $pWebsite );
133 - $stats_track_id = MainWP_Execution_Helper::execute_call_track( 'start_point', $pWebsite );
144 + if ( $e->getMessage() == 'HTTPERROR' ) {
145 + $sync_errors = __( 'HTTP error', 'mainwp' ) . ( $e->get_message_extra() != null ? ' - ' . $e->get_message_extra() : '' );
146 + $check_result = - 1;
147 + } elseif ( $e->getMessage() == 'NOMAINWP' ) {
148 + $sync_errors = __( 'MainWP Child plugin not detected or could not be reached! Ensure the MainWP Child plugin is installed and activated on the child site, and there are no security rules blocking requests. If you continue experiencing this issue, check the %sMainWP Community%s for help.', 'mainwp' );
149 + $check_result = 1;
150 + }
134 151
135 - try {
152 + return self::sync_information_array( $pWebsite, $information, $sync_errors, $check_result, true, $pAllowDisconnect );
153 + }
154 + }
136 155
137 - if ( null === static::$clone_enabled ) {
156 + /**
157 + * Method sync_information_array()
158 + *
159 + * Grab all Child Site Information.
160 + *
161 + * @param object $pWebsite The website object.
162 + * @param array $information Array contaning information returned from child site.
163 + * @param string $sync_errors Check for Sync Errors.
164 + * @param int $check_result Check if offline.
165 + * @param bool $error True|False.
166 + * @param bool $pAllowDisconnect True|False.
167 + *
168 + * @return bool true|false True on success, false on failure.
169 + *
170 + * @uses \MainWP\Dashboard\MainWP_DB::update_website_option()
171 + * @uses \MainWP\Dashboard\MainWP_DB::update_website_sync_values()
172 + * @uses \MainWP\Dashboard\MainWP_DB::update_website_values()
173 + * @uses \MainWP\Dashboard\MainWP_Logger::warning_for_website()
174 + * @uses \MainWP\Dashboard\MainWP_Monitoring_Handler::get_health_noticed_status_value()
175 + * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
176 + * @uses \MainWP\Dashboard\MainWP_Utility::get_site_health()
177 + */
178 + 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.
179 + $emptyArray = wp_json_encode( array() );
180 + $websiteValues = array(
181 + 'directories' => $emptyArray,
182 + 'plugin_upgrades' => $emptyArray,
183 + 'theme_upgrades' => $emptyArray,
184 + 'translation_upgrades' => $emptyArray,
185 + 'securityIssues' => $emptyArray,
186 + 'themes' => $emptyArray,
187 + 'plugins' => $emptyArray,
188 + 'users' => $emptyArray,
189 + 'categories' => $emptyArray,
190 + 'offline_check_result' => $check_result,
191 + );
192 + $websiteSyncValues = array(
193 + 'sync_errors' => $sync_errors,
194 + 'version' => 0,
195 + );
138 196
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();
197 + $done = false;
148 198
149 - if ( static::$clone_enabled ) {
199 + /**
200 + * Filter: mainwp_before_save_sync_result
201 + *
202 + * Filters data returned from child site before saving to the database.
203 + *
204 + * @param object $pWebsite Object containing child site data.
205 + *
206 + * @since 3.4
207 + */
208 + $information = apply_filters( 'mainwp_before_save_sync_result', $information, $pWebsite );
150 209
151 - static::$disallowed_clone_sites = get_option( 'mainwp_clone_disallowedsites' );
210 + if ( isset( $information['siteurl'] ) ) {
211 + $websiteValues['siteurl'] = $information['siteurl'];
212 + $done = true;
213 + }
152 214
153 - if ( ! is_array( static::$disallowed_clone_sites ) ) {
154 - static::$disallowed_clone_sites = array();
155 - }
215 + if ( isset( $information['version'] ) ) {
216 + $websiteSyncValues['version'] = $information['version'];
217 + $done = true;
218 + }
156 219
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 - );
220 + $phpversion = '';
221 + if ( isset( $information['site_info'] ) && null != $information['site_info'] ) {
222 + if ( is_array( $information['site_info'] ) && isset( $information['site_info']['phpversion'] ) ) {
223 + $phpversion = $information['site_info']['phpversion'];
224 + }
225 + MainWP_DB::instance()->update_website_option( $pWebsite, 'site_info', wp_json_encode( $information['site_info'] ) );
226 + $done = true;
227 + } else {
228 + MainWP_DB::instance()->update_website_option( $pWebsite, 'site_info', $emptyArray );
229 + }
230 + MainWP_DB::instance()->update_website_option( $pWebsite, 'phpversion', $phpversion );
167 231
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 - }
232 + if ( isset( $information['directories'] ) && is_array( $information['directories'] ) ) {
233 + $websiteValues['directories'] = wp_json_encode( $information['directories'] );
234 + $done = true;
235 + } elseif ( isset( $information['directories'] ) ) {
236 + $websiteValues['directories'] = $information['directories'];
237 + $done = true;
238 + }
176 239
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 - );
184 - }
185 - MainWP_DB::free_result( $websites );
186 - }
187 - $disallowed_current_site = in_array( $pWebsite->id, static::$disallowed_clone_sites ) ? true : false;
188 - }
189 - }
240 + if ( isset( $information['wp_updates'] ) && null != $information['wp_updates'] ) {
241 + MainWP_DB::instance()->update_website_option(
242 + $pWebsite,
243 + 'wp_upgrades',
244 + wp_json_encode(
245 + array(
246 + 'current' => $information['wpversion'],
247 + 'new' => $information['wp_updates'],
248 + )
249 + )
250 + );
251 + $done = true;
252 + } else {
253 + MainWP_DB::instance()->update_website_option( $pWebsite, 'wp_upgrades', $emptyArray );
254 + }
190 255
191 - $disallowed_current_site = static::$clone_enabled && is_array( static::$disallowed_clone_sites ) && in_array( $pWebsite->id, static::$disallowed_clone_sites ) ? true : false;
256 + if ( isset( $information['plugin_updates'] ) ) {
257 + $websiteValues['plugin_upgrades'] = wp_json_encode( $information['plugin_updates'] );
258 + $done = true;
259 + }
192 260
193 - $primaryBackup = MainWP_System_Utility::get_primary_backup();
261 + if ( isset( $information['theme_updates'] ) ) {
262 + $websiteValues['theme_upgrades'] = wp_json_encode( $information['theme_updates'] );
263 + $done = true;
264 + }
194 265
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.
266 + if ( isset( $information['translation_updates'] ) ) {
267 + $websiteValues['translation_upgrades'] = wp_json_encode( $information['translation_updates'] );
268 + $done = true;
269 + }
196 270
197 - /**
198 - * Filter: mainwp_sync_others_data
199 - *
200 - * Filters additional data in the sync request. Allows extensions or 3rd party plugins to hook data to the sync request.
201 - *
202 - * @param object $pWebsite Object contaning child site data.
203 - *
204 - * @since Unknown
205 - *
206 - * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
207 - */
208 - $othersData = apply_filters( 'mainwp_sync_others_data', $othersData, $pWebsite );
271 + if ( isset( $information['premium_updates'] ) ) {
272 + MainWP_DB::instance()->update_website_option( $pWebsite, 'premium_upgrades', wp_json_encode( $information['premium_updates'] ) );
273 + $done = true;
274 + } else {
275 + MainWP_DB::instance()->update_website_option( $pWebsite, 'premium_upgrades', $emptyArray );
276 + }
209 277
210 - $saved_days_number = apply_filters( 'mainwp_site_actions_saved_days_number', 30 );
278 + if ( isset( $information['securityStats'] ) ) {
279 + $total_securityIssues = 0;
280 + $securityStats = $information['securityStats'];
281 + if ( is_array( $securityStats ) ) {
282 + /** This filter is documented in ../pages/page-mainwp-security-issues.php */
283 + $filterStats = apply_filters( 'mainwp_security_issues_stats', false, $securityStats, $pWebsite );
284 + if ( false !== $filterStats && is_array( $filterStats ) ) {
285 + $securityStats = array_merge( $securityStats, $filterStats );
286 + }
211 287
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 - }
288 + $unset_scripts = apply_filters( 'mainwp_unset_security_scripts_stylesheets', true );
289 + if ( $unset_scripts ) {
290 + if ( isset( $securityStats['versions'] ) ) {
291 + unset( $securityStats['versions'] );
292 + }
293 + if ( isset( $securityStats['registered_versions'] ) ) {
294 + unset( $securityStats['registered_versions'] );
295 + }
296 + }
220 297
221 - $postdata = array(
222 - 'optimize' => 1 === (int) get_option( 'mainwp_optimize', 1 ) ? 1 : 0,
223 - 'cloneSites' => ( ! static::$clone_enabled || $disallowed_current_site ) ? 0 : rawurlencode( wp_json_encode( static::$clone_websites ) ),
224 - 'othersData' => wp_json_encode( $othersData ),
225 - 'server' => get_admin_url(),
226 - 'numberdaysOutdatePluginTheme' => get_option( 'mainwp_numberdays_Outdate_Plugin_Theme', 365 ),
227 - 'primaryBackup' => $backup_method, // if empty site backup method will not sync the backup info from child site.
228 - 'siteId' => $pWebsite->id,
229 - 'child_actions_saved_days_number' => intval( $saved_days_number ),
230 - 'pingnonce' => MainWP_Utility::instance()->create_site_nonce( 'pingnonce', $pWebsite->id ),
231 - );
298 + $tmp_issues = array_filter(
299 + $securityStats,
300 + function( $v, $k ) {
301 + return 'N' == $v;
302 + },
303 + ARRAY_FILTER_USE_BOTH
304 + );
305 + $total_securityIssues = count( $tmp_issues );
306 + $securityStats = wp_json_encode( $securityStats );
307 + } else {
308 + $securityStats = $emptyArray;
309 + }
310 + $websiteValues['securityIssues'] = $total_securityIssues;
311 + MainWP_DB::instance()->update_website_option( $pWebsite, 'security_stats', $securityStats );
312 + $done = true;
313 + } elseif ( isset( $information['securityIssues'] ) && MainWP_Utility::ctype_digit( $information['securityIssues'] ) && $information['securityIssues'] >= 0 ) {
314 + $websiteValues['securityIssues'] = $information['securityIssues'];
315 + $done = true;
316 + }
232 317
233 - $individual_settings_json = MainWP_DB::instance()->get_website_option( $pWebsite, 'password_policy_individual_settings' );
234 - $individual_settings = array();
318 + if ( isset( $information['recent_comments'] ) ) {
319 + MainWP_DB::instance()->update_website_option( $pWebsite, 'recent_comments', wp_json_encode( $information['recent_comments'] ) );
320 + $done = true;
321 + } else {
322 + MainWP_DB::instance()->update_website_option( $pWebsite, 'recent_comments', $emptyArray );
323 + }
235 324
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 - }
325 + if ( isset( $information['recent_posts'] ) ) {
326 + MainWP_DB::instance()->update_website_option( $pWebsite, 'recent_posts', wp_json_encode( $information['recent_posts'] ) );
327 + $done = true;
328 + } else {
329 + MainWP_DB::instance()->update_website_option( $pWebsite, 'recent_posts', $emptyArray );
330 + }
242 331
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 - }
332 + if ( isset( $information['recent_pages'] ) ) {
333 + MainWP_DB::instance()->update_website_option( $pWebsite, 'recent_pages', wp_json_encode( $information['recent_pages'] ) );
334 + $done = true;
335 + } else {
336 + MainWP_DB::instance()->update_website_option( $pWebsite, 'recent_pages', $emptyArray );
337 + }
262 338
263 - $postdata['passwordPolicySettings'] = wp_json_encode( $password_policy_settings );
339 + if ( isset( $information['themes'] ) ) {
340 + $websiteValues['themes'] = wp_json_encode( $information['themes'] );
341 + $done = true;
342 + }
264 343
265 - $reg_verify = MainWP_DB::instance()->get_website_option( $pWebsite, 'register_verify_key', '' );
266 - if ( empty( $reg_verify ) ) {
267 - $postdata['sync_regverify'] = 1;
268 - }
344 + if ( isset( $information['plugins'] ) ) {
345 + $websiteValues['plugins'] = wp_json_encode( $information['plugins'] );
346 + $done = true;
347 + }
269 348
270 - $postdata['params_logs'] = apply_filters( 'mainwp_module_logs_changes_logs_sync_params', '', $pWebsite->id, $postdata, $pWebsite );
349 + if ( isset( $information['users'] ) ) {
350 + $websiteValues['users'] = wp_json_encode( $information['users'] );
351 + $done = true;
352 + }
271 353
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 - }
354 + if ( isset( $information['categories'] ) ) {
355 + $websiteValues['categories'] = wp_json_encode( $information['categories'] );
356 + $done = true;
357 + }
276 358
277 - $synclist = MainWP_Settings::get_instance()->get_data_list_to_sync();
278 - $postdata['syncdata'] = wp_json_encode( $synclist );
359 + if ( isset( $information['totalsize'] ) ) {
360 + $websiteSyncValues['totalsize'] = $information['totalsize'];
361 + $done = true;
362 + }
279 363
280 - static::push_stack_action( 'sync_stats' );
364 + if ( isset( $information['dbsize'] ) ) {
365 + $websiteSyncValues['dbsize'] = $information['dbsize'];
366 + $done = true;
367 + }
281 368
282 - $information = MainWP_Connect::fetch_url_authed(
283 - $pWebsite,
284 - 'stats',
285 - $postdata,
286 - true,
287 - $pForceFetch
288 - );
369 + if ( isset( $information['extauth'] ) ) {
370 + $websiteSyncValues['extauth'] = $information['extauth'];
371 + $done = true;
372 + }
289 373
290 - $return = static::sync_information_array( $pWebsite, $information, '', false, false, $pAllowDisconnect );
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' );
293 - return $return;
294 - } catch ( MainWP_Exception $e ) {
295 - MainWP_Execution_Helper::execute_call_track( 'end_point', $pWebsite, array(), $stats_track_id, 'stats site' );
296 - $sync_errors = '';
374 + if ( isset( $information['nossl'] ) ) {
375 + $websiteValues['nossl'] = $information['nossl'];
376 + $done = true;
377 + }
297 378
298 - if ( $e->getMessage() === 'HTTPERROR' ) {
299 - $sync_errors = esc_html__( 'HTTP error', 'mainwp' ) . ( ! empty( $e->get_message_extra() ) ? ' - ' . $e->get_message_extra() : '' );
300 - } elseif ( $e->getMessage() === 'NOMAINWP' ) {
301 - $sync_errors = MainWP_Error_Helper::get_error_not_detected_connect();
302 - }
379 + if ( isset( $information['wpe'] ) ) {
380 + $websiteValues['wpe'] = $information['wpe'];
381 + $done = true;
382 + }
303 383
304 - MainWP_Logger::instance()->log_execution_time( 'sync :: [siteid=' . $pWebsite->id . ']' );
305 - return static::sync_information_array( $pWebsite, $information, $sync_errors, false, true, $pAllowDisconnect );
306 - }
307 - }
384 + if ( isset( $information['last_post_gmt'] ) ) {
385 + $websiteSyncValues['last_post_gmt'] = $information['last_post_gmt'];
386 + $done = true;
387 + }
308 388
309 - /**
310 - * Method sync_information_array()
311 - *
312 - * Grab all Child Site Information.
313 - *
314 - * @param object $pWebsite The website object.
315 - * @param array $information Array contaning information returned from child site.
316 - * @param string $sync_errors Check for Sync Errors.
317 - * @param int $check_result Check if offline.
318 - * @param bool $error True|False.
319 - * @param bool $pAllowDisconnect True|False.
320 - * @param array $other Additional parameters.
321 - * @param array $fetch_output Fetch output.
322 - *
323 - * @return bool true|false True on success, false on failure.
324 - *
325 - * @uses \MainWP\Dashboard\MainWP_DB::update_website_option()
326 - * @uses \MainWP\Dashboard\MainWP_DB::update_website_sync_values()
327 - * @uses \MainWP\Dashboard\MainWP_DB::update_website_values()
328 - * @uses \MainWP\Dashboard\MainWP_Logger::warning_for_website()
329 - * @uses \MainWP\Dashboard\MainWP_Monitoring_Handler::get_health_noticed_status_value()
330 - * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
331 - * @uses \MainWP\Dashboard\MainWP_Utility::get_site_health()
332 - */
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.
334 - $emptyArray = wp_json_encode( array() );
335 - $websiteValues = array();
336 - $websiteSyncValues = array(
337 - 'sync_errors' => $sync_errors,
338 - 'version' => 0,
339 - );
389 + if ( isset( $information['health_site_status'] ) ) {
390 + $health_status = $information['health_site_status'];
391 + $hstatus = MainWP_Utility::get_site_health( $health_status );
392 + $new_health_value = $hstatus['val'] - $hstatus['critical'] * 100; // computes custom health value to support sorting by sites health and sites health threshold.
393 + $websiteSyncValues['health_value'] = $new_health_value;
394 + $done = true;
395 + MainWP_DB::instance()->update_website_option( $pWebsite, 'health_site_status', wp_json_encode( $health_status ) );
396 + $new_noticed = MainWP_Monitoring_Handler::get_health_noticed_status_value( $pWebsite, $new_health_value );
397 + if ( null !== $new_noticed ) {
398 + MainWP_DB::instance()->update_website_sync_values(
399 + $pWebsite->id,
400 + array(
401 + 'health_site_noticed' => $new_noticed,
402 + )
403 + );
404 + }
405 + } else {
406 + MainWP_DB::instance()->update_website_option( $pWebsite, 'health_site_status', $emptyArray );
407 + }
340 408
341 - $_error = $sync_errors;
409 + if ( isset( $information['mainwpdir'] ) ) {
410 + $websiteValues['mainwpdir'] = $information['mainwpdir'];
411 + $done = true;
412 + }
342 413
343 - $done = false;
414 + if ( isset( $information['uniqueId'] ) ) {
415 + $websiteValues['uniqueId'] = $information['uniqueId'];
416 + $done = true;
417 + }
344 418
345 - $current_siteid = 0;
346 - if ( is_string( $pWebsite ) || is_int( $pWebsite ) ) {
347 - $current_siteid = intval( $pWebsite );
348 - } elseif ( is_object( $pWebsite ) && ( ! property_exists( $pWebsite, 'plugin_updates' ) || ! property_exists( $pWebsite, 'theme_updates' ) ) ) {
349 - $current_siteid = $pWebsite->id;
350 - }
419 + if ( isset( $information['clone_adminname'] ) ) {
420 + $websiteValues['adminname'] = $information['clone_adminname'];
421 + $done = true;
422 + }
351 423
352 - // to get full data.
353 - if ( $current_siteid ) {
354 - $pWebsite = MainWP_DB::instance()->get_website_by_id( $current_siteid );
355 - }
424 + if ( isset( $information['admin_nicename'] ) ) {
425 + MainWP_DB::instance()->update_website_option( $pWebsite, 'admin_nicename', trim( $information['admin_nicename'] ) );
426 + $done = true;
427 + }
356 428
357 - /**
358 - * Filter: mainwp_before_save_sync_result
359 - *
360 - * Filters data returned from child site before saving to the database.
361 - *
362 - * @param object $pWebsite Object containing child site data.
363 - *
364 - * @since 3.4
365 - */
366 - $information = apply_filters( 'mainwp_before_save_sync_result', $information, $pWebsite );
429 + if ( isset( $information['admin_useremail'] ) ) {
430 + MainWP_DB::instance()->update_website_option( $pWebsite, 'admin_useremail', trim( $information['admin_useremail'] ) );
431 + $done = true;
432 + }
367 433
368 - if ( ! empty( $information['regverify_info'] ) ) {
369 - MainWP_DB::instance()->update_website_option( $pWebsite, 'register_verify_key', $information['regverify_info'] );
370 - $done = true;
371 - }
434 + if ( isset( $information['plugins_outdate_info'] ) ) {
435 + MainWP_DB::instance()->update_website_option( $pWebsite, 'plugins_outdate_info', wp_json_encode( $information['plugins_outdate_info'] ) );
436 + $done = true;
437 + } else {
438 + MainWP_DB::instance()->update_website_option( $pWebsite, 'plugins_outdate_info', $emptyArray );
439 + }
372 440
373 - if ( isset( $information['siteurl'] ) ) {
374 - $websiteValues['siteurl'] = $information['siteurl'];
375 - $done = true;
376 - }
441 + if ( isset( $information['themes_outdate_info'] ) ) {
442 + MainWP_DB::instance()->update_website_option( $pWebsite, 'themes_outdate_info', wp_json_encode( $information['themes_outdate_info'] ) );
443 + $done = true;
444 + } else {
445 + MainWP_DB::instance()->update_website_option( $pWebsite, 'themes_outdate_info', $emptyArray );
446 + }
377 447
378 - if ( isset( $information['version'] ) ) {
379 - $websiteSyncValues['version'] = $information['version'];
380 - $done = true;
381 - }
448 + if ( isset( $information['primaryLasttimeBackup'] ) ) {
449 + MainWP_DB::instance()->update_website_option( $pWebsite, 'primary_lasttime_backup', $information['primaryLasttimeBackup'] );
450 + $done = true;
451 + }
382 452
383 - $phpversion = '';
384 - $wpversion = '';
385 - if ( isset( $information['site_info'] ) && ! empty( $information['site_info'] ) ) {
386 - if ( is_array( $information['site_info'] ) && isset( $information['site_info']['phpversion'] ) ) {
387 - $phpversion = $information['site_info']['phpversion'];
388 - }
389 - if ( is_array( $information['site_info'] ) && isset( $information['site_info']['ip'] ) ) {
390 - $websiteValues['ip'] = sanitize_text_field( wp_unslash( $information['site_info']['ip'] ) );
391 - }
453 + if ( ! $done ) {
454 + if ( isset( $information['wpversion'] ) ) {
455 + $done = true;
456 + } elseif ( isset( $information['error'] ) ) {
457 + MainWP_Logger::instance()->warning_for_website( $pWebsite, 'SYNC ERROR', '[' . esc_html( $information['error'] ) . ']' );
458 + $error = true;
459 + $done = true;
460 + $websiteSyncValues['sync_errors'] = __( 'ERROR: ', 'mainwp' ) . esc_html( $information['error'] );
461 + } elseif ( ! empty( $sync_errors ) ) {
462 + MainWP_Logger::instance()->warning_for_website( $pWebsite, 'SYNC ERROR', '[' . $sync_errors . ']' );
392 463
393 - if ( is_array( $information['site_info'] ) && isset( $information['site_info']['wpversion'] ) ) {
394 - $wpversion = $information['site_info']['wpversion'];
395 - }
464 + $error = true;
465 + if ( ! $pAllowDisconnect ) {
466 + $sync_errors = '';
467 + }
396 468
397 - MainWP_DB::instance()->update_website_option( $pWebsite, 'site_info', wp_json_encode( $information['site_info'] ) );
398 - $done = true;
399 - }
469 + $websiteSyncValues['sync_errors'] = $sync_errors;
470 + } else {
471 + MainWP_Logger::instance()->warning_for_website( $pWebsite, 'SYNC ERROR', '[Undefined error]' );
472 + $error = true;
473 + if ( $pAllowDisconnect ) {
474 + $websiteSyncValues['sync_errors'] = __( 'Undefined error! Please, reinstall the MainWP Child plugin on the child site.', 'mainwp' );
475 + }
476 + }
477 + }
400 478
401 - if ( ! empty( $phpversion ) ) {
402 - MainWP_DB::instance()->update_website_option( $pWebsite, 'phpversion', $phpversion );
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 - }
479 + if ( $done ) {
480 + $websiteSyncValues['dtsSync'] = time();
481 + }
482 + MainWP_DB::instance()->update_website_sync_values( $pWebsite->id, $websiteSyncValues );
483 + MainWP_DB::instance()->update_website_values( $pWebsite->id, $websiteValues );
408 484
409 - if ( isset( $information['directories'] ) && is_array( $information['directories'] ) ) {
410 - $websiteValues['directories'] = wp_json_encode( $information['directories'] );
411 - $done = true;
412 - } elseif ( isset( $information['directories'] ) ) {
413 - $websiteValues['directories'] = $information['directories'];
414 - $done = true;
415 - }
485 + // Sync action.
486 + if ( ! $error ) {
487 + do_action_deprecated( 'mainwp-site-synced', array( $pWebsite, $information ), '4.0.7.2', 'mainwp_site_synced' ); // @deprecated Use 'mainwp_site_synced' instead.
416 488
417 - $had_pending_updates = null;
489 + /**
490 + * Action: mainwp_site_synced
491 + *
492 + * Fires upon successful site synchronization.
493 + *
494 + * @param object $pWebsite Object containing child site info.
495 + * @param array $information Array containing information returned from child site.
496 + *
497 + * @since 3.4
498 + */
499 + do_action( 'mainwp_site_synced', $pWebsite, $information );
500 + }
418 501
419 - $wp_updates_empty = true;
420 - if ( isset( $information['wp_updates'] ) && ! empty( $information['wp_updates'] ) ) {
421 - MainWP_DB::instance()->update_website_option(
422 - $pWebsite,
423 - 'wp_upgrades',
424 - wp_json_encode(
425 - array(
426 - 'current' => $information['wpversion'],
427 - 'new' => $information['wp_updates'],
428 - )
429 - )
430 - );
431 - $done = true;
432 - $wp_updates_empty = false;
433 - $had_pending_updates = true;
434 - }
502 + return ( ! $error );
503 + }
435 504
436 - if ( isset( $information['plugin_updates'] ) ) {
437 - $update_values = array();
438 - if ( is_array( $information['plugin_updates'] ) ) {
439 - foreach ( $information['plugin_updates'] as $file => $update ) {
440 - $update_values[ $file ] = $update;
441 - }
442 - }
505 + /**
506 + * Method sync_site_icon()
507 + *
508 + * Get site's icon.
509 + *
510 + * @param mixed $siteId site's id.
511 + *
512 + * @return array result error or success
513 + * @throws \Exception Error message.
514 + *
515 + * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
516 + * @uses \MainWP\Dashboard\MainWP_Connect::get_file_content()
517 + * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
518 + * @uses \MainWP\Dashboard\MainWP_DB_Common::update_website_option()
519 + * @uses \MainWP\Dashboard\MainWP_Exception
520 + * @uses \MainWP\Dashboard\MainWP_Logger::debug()
521 + * @uses \MainWP\Dashboard\MainWP_System_Utility::can_edit_website()
522 + * @uses \MainWP\Dashboard\MainWP_System_Utility::get_wp_file_system()
523 + * @uses \MainWP\Dashboard\MainWP_System_Utility::get_mainwp_dir()
524 + * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
525 + */
526 + public static function sync_site_icon( $siteId = null ) {
527 + if ( MainWP_Utility::ctype_digit( $siteId ) ) {
528 + $website = MainWP_DB::instance()->get_website_by_id( $siteId );
529 + if ( MainWP_System_Utility::can_edit_website( $website ) ) {
530 + $error = '';
531 + try {
532 + $information = MainWP_Connect::fetch_url_authed( $website, 'get_site_icon' );
533 + } catch ( MainWP_Exception $e ) {
534 + $error = $e->getMessage();
535 + }
443 536
444 - $had_pending_updates = ! empty( $update_values ) || (bool) $had_pending_updates;
537 + if ( '' != $error ) {
538 + return array( 'error' => $error );
539 + } elseif ( isset( $information['faviIconUrl'] ) && ! empty( $information['faviIconUrl'] ) ) {
540 + MainWP_Logger::instance()->debug( 'Downloading icon :: ' . esc_html( $information['faviIconUrl'] ) );
541 + $content = MainWP_Connect::get_file_content( $information['faviIconUrl'] );
542 + if ( ! empty( $content ) ) {
445 543
446 - $websiteValues['plugin_upgrades'] = wp_json_encode( $update_values );
447 - $done = true;
448 - }
544 + $hasWPFileSystem = MainWP_System_Utility::get_wp_file_system();
449 545
450 - if ( isset( $information['theme_updates'] ) ) {
451 - $update_values = array();
452 - if ( is_array( $information['theme_updates'] ) ) {
453 - foreach ( $information['theme_updates'] as $file => $update ) {
454 - $update_values[ $file ] = $update;
455 - }
456 - }
457 - $had_pending_updates = ! empty( $update_values ) || (bool) $had_pending_updates;
458 - $websiteValues['theme_upgrades'] = wp_json_encode( $update_values );
459 - $done = true;
460 - }
546 + /**
547 + * WordPress files system object.
548 + *
549 + * @global object
550 + */
551 + global $wp_filesystem;
461 552
462 - if ( isset( $information['translation_updates'] ) ) {
463 - $had_pending_updates = ! empty( $information['translation_updates'] ) || (bool) $had_pending_updates;
464 - $websiteValues['translation_upgrades'] = wp_json_encode( $information['translation_updates'] );
465 - $done = true;
466 - }
553 + $dirs = MainWP_System_Utility::get_mainwp_dir( 'icons', true );
554 + $iconsDir = $dirs[0];
555 + $filename = basename( $information['faviIconUrl'] );
556 + $filename = strtok( $filename, '?' );
557 + if ( $filename ) {
558 + $filename = 'favi-' . $siteId . '-' . $filename;
559 + $size = false;
560 + if ( MainWP_Utility::check_image_file_name( $filename ) ) {
561 + $size = $wp_filesystem->put_contents( $iconsDir . $filename, $content ); // phpcs:ignore --
562 + }
563 + if ( $size ) {
564 + MainWP_Logger::instance()->debug( 'Icon size :: ' . $size );
565 + MainWP_DB::instance()->update_website_option( $website, 'favi_icon', $filename );
566 + return array( 'result' => 'success' );
567 + } else {
568 + return array( 'error' => 'Save icon file failed.' );
569 + }
570 + }
571 + return array( 'undefined_error' => true );
572 + } else {
573 + return array( 'error' => esc_html__( 'Download icon file failed', 'mainwp' ) );
574 + }
575 + } else {
576 + return array( 'undefined_error' => true );
577 + }
578 + }
579 + }
580 + return array( 'result' => 'NOSITE' );
581 + }
467 582
468 - if ( isset( $information['premium_updates'] ) ) {
469 - $had_pending_updates = ! empty( $information['premium_updates'] ) || (bool) $had_pending_updates;
470 -
471 - MainWP_DB::instance()->update_website_option( $pWebsite, 'premium_upgrades', wp_json_encode( $information['premium_updates'] ) );
472 - $done = true;
473 - }
474 -
475 - if ( isset( $information['securityStats'] ) ) {
476 - $total_securityIssues = 0;
477 - $securityStats = $information['securityStats'];
478 - if ( is_array( $securityStats ) ) {
479 - /** This filter is documented in ../pages/page-mainwp-security-issues.php */
480 - $filterStats = apply_filters( 'mainwp_security_issues_stats', false, $securityStats, $pWebsite );
481 - if ( false !== $filterStats && is_array( $filterStats ) ) {
482 - $securityStats = array_merge( $securityStats, $filterStats );
483 - }
484 -
485 - $tmp_issues = array_filter(
486 - $securityStats,
487 - function ( $v ) {
488 - return 'N' === $v;
489 - },
490 - ARRAY_FILTER_USE_BOTH
491 - );
492 - $total_securityIssues = count( $tmp_issues );
493 - $securityStats = wp_json_encode( $securityStats );
494 - } else {
495 - $securityStats = $emptyArray;
496 - }
497 - $websiteValues['securityIssues'] = $total_securityIssues;
498 - MainWP_DB::instance()->update_website_option( $pWebsite, 'security_stats', $securityStats );
499 - $done = true;
500 - } elseif ( isset( $information['securityIssues'] ) && MainWP_Utility::ctype_digit( $information['securityIssues'] ) && $information['securityIssues'] >= 0 ) {
501 - $websiteValues['securityIssues'] = $information['securityIssues'];
502 - $done = true;
503 - }
504 -
505 - if ( isset( $information['recent_comments'] ) ) {
506 - MainWP_DB::instance()->update_website_option( $pWebsite, 'recent_comments', wp_json_encode( $information['recent_comments'] ) );
507 - $done = true;
508 - }
509 -
510 - if ( isset( $information['recent_posts'] ) ) {
511 - MainWP_DB::instance()->update_website_option( $pWebsite, 'recent_posts', wp_json_encode( $information['recent_posts'] ) );
512 - $done = true;
513 - }
514 -
515 - if ( isset( $information['recent_pages'] ) ) {
516 - MainWP_DB::instance()->update_website_option( $pWebsite, 'recent_pages', wp_json_encode( $information['recent_pages'] ) );
517 - $done = true;
518 - }
519 -
520 - if ( isset( $information['themes'] ) ) {
521 - $websiteValues['themes'] = wp_json_encode( $information['themes'] );
522 - $done = true;
523 - }
524 -
525 - $plugins_info = array();
526 -
527 - if ( isset( $information['plugins'] ) ) {
528 - $plugins_info = $information['plugins'];
529 - $websiteValues['plugins'] = wp_json_encode( $plugins_info );
530 - $done = true;
531 - }
532 -
533 - if ( isset( $information['users'] ) ) {
534 - $websiteValues['users'] = wp_json_encode( $information['users'] );
535 - $done = true;
536 - }
537 -
538 - if ( isset( $information['categories_list'] ) ) {
539 - $websiteValues['categories'] = wp_json_encode( $information['categories_list'] );
540 - $done = true;
541 - } elseif ( isset( $information['categories'] ) ) { // support old child version.
542 - $websiteValues['categories'] = wp_json_encode( $information['categories'] );
543 - $done = true;
544 - }
545 -
546 - if ( isset( $information['totalsize'] ) ) {
547 - $websiteSyncValues['totalsize'] = $information['totalsize'];
548 - $done = true;
549 - }
550 -
551 - if ( isset( $information['dbsize'] ) ) {
552 - $websiteSyncValues['dbsize'] = $information['dbsize'];
553 - $done = true;
554 - }
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 -
561 - if ( isset( $information['extauth'] ) ) {
562 - $websiteSyncValues['extauth'] = $information['extauth'];
563 - $done = true;
564 - }
565 -
566 - if ( isset( $information['wpe'] ) ) {
567 - $websiteValues['wpe'] = $information['wpe'];
568 - $done = true;
569 - }
570 -
571 - if ( isset( $information['wphost'] ) ) {
572 - MainWP_DB::instance()->update_website_option( $pWebsite, 'wphost', $information['wphost'] );
573 - }
574 -
575 - if ( isset( $information['last_post_gmt'] ) ) {
576 - $websiteSyncValues['last_post_gmt'] = $information['last_post_gmt'];
577 - $done = true;
578 - }
579 -
580 - if ( isset( $information['health_site_status'] ) ) {
581 - $health_status = $information['health_site_status'];
582 - $hstatus = MainWP_Utility::get_site_health( $health_status );
583 - $custom_health_value = $hstatus['val'] - $hstatus['critical'] * 100; // computes custom health value to support sorting by sites health and sites health threshold.
584 - $websiteSyncValues['health_value'] = $custom_health_value;
585 - $done = true;
586 - MainWP_DB::instance()->update_website_option( $pWebsite, 'health_site_status', wp_json_encode( $health_status ) );
587 - $new_noticed = MainWP_Monitoring_Handler::get_health_noticed_status_value( $pWebsite, $custom_health_value );
588 - if ( null !== $new_noticed ) {
589 - MainWP_DB::instance()->update_website_sync_values(
590 - $pWebsite->id,
591 - array(
592 - 'health_site_noticed' => $new_noticed,
593 - )
594 - );
595 - }
596 -
597 - $hval = $hstatus['val'];
598 - $critical = $hstatus['critical'];
599 - $health_status = 0;
600 - if ( 80 <= $hval && empty( $critical ) ) {
601 - $health_status = 0; // Good.
602 - } else {
603 - $health_status = 1; // Should be improved'.
604 - }
605 - $websiteSyncValues['health_status'] = $health_status;
606 - }
607 -
608 - if ( isset( $information['mainwpdir'] ) ) {
609 - $websiteValues['mainwpdir'] = $information['mainwpdir'];
610 - $done = true;
611 - }
612 -
613 - if ( isset( $information['uniqueId'] ) ) {
614 - $websiteValues['uniqueId'] = $information['uniqueId'];
615 - $done = true;
616 - }
617 -
618 - if ( isset( $information['clone_adminname'] ) ) {
619 - $websiteValues['adminname'] = $information['clone_adminname'];
620 - $done = true;
621 - }
622 -
623 - if ( isset( $information['admin_nicename'] ) ) {
624 - MainWP_DB::instance()->update_website_option( $pWebsite, 'admin_nicename', trim( $information['admin_nicename'] ) );
625 - $done = true;
626 - }
627 -
628 - if ( isset( $information['admin_useremail'] ) ) {
629 - MainWP_DB::instance()->update_website_option( $pWebsite, 'admin_useremail', trim( $information['admin_useremail'] ) );
630 - $done = true;
631 - }
632 -
633 - if ( isset( $information['plugins_outdate_info'] ) ) {
634 - MainWP_DB::instance()->update_website_option( $pWebsite, 'plugins_outdate_info', wp_json_encode( $information['plugins_outdate_info'] ) );
635 - $done = true;
636 - }
637 -
638 - if ( isset( $information['themes_outdate_info'] ) ) {
639 - MainWP_DB::instance()->update_website_option( $pWebsite, 'themes_outdate_info', wp_json_encode( $information['themes_outdate_info'] ) );
640 - $done = true;
641 - }
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['primaryLasttimeBackup'] ) ) {
649 - MainWP_DB::instance()->update_website_option( $pWebsite, 'primary_lasttime_backup', $information['primaryLasttimeBackup'] );
650 - $done = true;
651 - }
652 -
653 - if ( isset( $information['child_site_actions_data'] ) ) {
654 - if ( is_array( $information['child_site_actions_data'] ) && isset( $information['child_site_actions_data']['connected_admin'] ) ) {
655 - unset( $information['child_site_actions_data']['connected_admin'] );
656 - }
657 - if ( class_exists( '\MainWP\Dashboard\Module\Log\Log_Manager' ) ) {
658 - \MainWP\Dashboard\Module\Log\Log_Manager::instance()->sync_log_site_actions( $pWebsite->id, $information['child_site_actions_data'], $pWebsite );
659 - }
660 - $done = true;
661 - }
662 -
663 - if ( ! empty( $information['changes_logs_data'] ) && class_exists( '\MainWP\Dashboard\Module\Log\Log_Changes_Logs_Helper' ) ) {
664 - \MainWP\Dashboard\Module\Log\Log_Changes_Logs_Helper::instance()->sync_changes_logs( $pWebsite->id, $information['changes_logs_data'], $pWebsite );
665 - $done = true;
666 - }
667 -
668 - if ( ! $done ) {
669 - if ( isset( $information['wpversion'] ) ) {
670 - $done = true;
671 - } elseif ( isset( $information['error'] ) ) {
672 - MainWP_Logger::instance()->warning_for_website( $pWebsite, 'SYNC ERROR', '[' . esc_html( $information['error'] ) . ']' );
673 - $error = true;
674 - $done = true;
675 - $_error = esc_html__( 'ERROR: ', 'mainwp' ) . esc_html( $information['error'] );
676 - $websiteSyncValues['sync_errors'] = $_error;
677 - } elseif ( ! empty( $sync_errors ) ) {
678 - MainWP_Logger::instance()->warning_for_website( $pWebsite, 'SYNC ERROR', '[' . $sync_errors . ']' );
679 - $_error = $sync_errors;
680 - $error = true;
681 - if ( ! $pAllowDisconnect ) {
682 - $sync_errors = '';
683 - }
684 -
685 - $websiteSyncValues['sync_errors'] = $sync_errors;
686 - } else {
687 - MainWP_Logger::instance()->warning_for_website( $pWebsite, 'SYNC ERROR', '[Undefined error]' );
688 - $error = true;
689 - if ( $pAllowDisconnect ) {
690 - $sync_errors = esc_html__( 'Undefined error! Please, reinstall the MainWP Child plugin on the child site.', 'mainwp' );
691 - $websiteSyncValues['sync_errors'] = $sync_errors;
692 - $_error = $sync_errors;
693 - }
694 - }
695 - }
696 -
697 - $sync_success = false;
698 - if ( $done ) {
699 - $sync_success = true;
700 - $websiteSyncValues['dtsSync'] = time();
701 - if ( $wp_updates_empty ) {
702 - MainWP_DB::instance()->update_website_option(
703 - $pWebsite,
704 - 'wp_upgrades',
705 - $emptyArray
706 - );
707 - }
708 - }
709 - MainWP_DB::instance()->update_website_sync_values( $pWebsite->id, $websiteSyncValues );
710 - MainWP_Logger::instance()->log_events( 'db-queries', sprintf( '[Update sync values=%s]', MainWP_DB::instance()->get_last_query() ) );
711 -
712 - if ( ! empty( $websiteValues ) ) {
713 - MainWP_DB::instance()->update_website_values( $pWebsite->id, $websiteValues );
714 - MainWP_Logger::instance()->log_events( 'db-queries', sprintf( '[Update site sync data=%s]', MainWP_DB::instance()->get_last_query() ) );
715 - }
716 -
717 - $error_occurred = $error;
718 - $msg_errors = $_error;
719 -
720 - $error = apply_filters( 'mainwp_sync_site_after_sync_result', $error, $pWebsite, $information );
721 -
722 - if ( ! empty( $plugins_info ) && is_array( $plugins_info ) ) {
723 - foreach ( $plugins_info as $info ) {
724 - if ( ! empty( $info['icon'] ) ) {
725 - $icon_slug = MainWP_Utility::get_dir_slug( $info['slug'] );
726 - MainWP_System_Utility::save_cached_icons( $info['icon'], $icon_slug, 'plugin' );
727 - }
728 - }
729 - }
730 -
731 - // Sync action.
732 - if ( ! $error ) {
733 -
734 - 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.
735 -
736 - /**
737 - * Action: mainwp_site_synced
738 - *
739 - * Fires upon successful site synchronization.
740 - *
741 - * @param object $pWebsite Object containing child site info.
742 - * @param array $information Array containing information returned from child site.
743 - *
744 - * @since 3.4
745 - */
746 - do_action( 'mainwp_site_synced', $pWebsite, $information );
747 - }
748 -
749 - $telem_info = static::get_telem_sync_info( $sync_success );
750 -
751 - if ( isset( $information['version'] ) ) {
752 - $telem_info['child_plugin_version'] = $information['version'];
753 - }
754 -
755 - if ( isset( $had_pending_updates ) ) {
756 - $telem_info['site_had_pending_updates'] = $had_pending_updates ? true : false;
757 - }
758 -
759 - if ( $error_occurred && ! empty( $information['fetch_url_output'] ) && is_array( $information['fetch_url_output'] ) ) {
760 - $output = $information['fetch_url_output'];
761 - $telem_info['error_message'] = $msg_errors;
762 - $telem_info['error_category'] = ! empty( $output['error_category'] ) ? $output['error_category'] : 'unknown';
763 - $telem_info['error_code'] = ! empty( $output['error_code'] ) ? $output['error_code'] : 'undefined_error';
764 - $telem_info['connection_step'] = ! empty( $output['connection_step'] ) ? $output['connection_step'] : 'handshake';
765 - if ( ! empty( $output['http_status'] ) ) {
766 - $telem_info['http_status'] = $output['http_status'];
767 - }
768 - }
769 -
770 - /**
771 - * Action: mainwp_after_site_synced
772 - *
773 - * Fires upon site synchronization.
774 - *
775 - * @param object $pWebsite Object containing child site info.
776 - * @param array $information Array containing information returned from child site.
777 - * @param mixed $error Sync error result.
778 - * @param mixed $sync_errors Sync error message if existed.
779 - * @param array $other Additional parameters.
780 - * @param array $telem_info Telemetry information.
781 - *
782 - * @since 6.0
783 - */
784 - do_action( 'mainwp_after_site_synced', $pWebsite, $information, $error, $sync_errors, $other, $telem_info );
785 -
786 - $post_data = array();
787 -
788 - /**
789 - * Action: mainwp_site_sync
790 - *
791 - * Fires upon successful site synchronization.
792 - *
793 - * @param object $pWebsite Object containing child site info.
794 - * @param array $information Array containing information returned from child site.
795 - * @param bool $sync_success action success or failed.
796 - * @param string $_error Sync error message if existed.
797 - * @param array $post_data Addition post data.
798 - *
799 - * @since 3.4
800 - */
801 - do_action( 'mainwp_site_sync', $pWebsite, $information, $sync_success, $_error, $post_data );
802 -
803 - return ! $error;
804 - }
805 -
806 -
807 - /**
808 - * Method get_telem_sync_info.
809 - *
810 - * @param mixed $sync_done
811 - * @return void
812 - */
813 - public static function get_telem_sync_info( $sync_done ) {
814 -
815 - $is_bulk_sync = ! empty( $_POST['bulkSync'] ) ? true : false; // phpcs:ignore -- NOSONAR - superglobal usage is acceptable.
816 -
817 - $tp = 'post_add_site';
818 -
819 - if ( $is_bulk_sync ) {
820 - $tp = 'manual_bulk';
821 - } elseif ( defined( 'DOING_CRON' ) && DOING_CRON ) {
822 - $tp = 'auto_cron';
823 - } elseif ( isset( $_POST['bulkSync'] ) && ! $is_bulk_sync ) { //phpcs:ignore -- NOSONAR - superglobal usage is acceptable.
824 - $tp = 'manual_single';
825 - }
826 -
827 - $trigger = 'system';
828 - if ( 'manual_single' === $tp || 'manual_bulk' === $tp ) {
829 - $trigger = 'user_click';
830 - } elseif ( defined( 'DOING_CRON' ) && DOING_CRON ) {
831 - $trigger = 'cron';
832 - }
833 -
834 - $curr_stack = static::get_current_stack_action();
835 - $prev_conn_status = in_array( $curr_stack, array( 'sync_before_reconnect', 'sync_reconnect' ) ) ? 'disconnected' : 'connected';
836 - $new_conn_status = $sync_done ? 'disconnected' : 'connected';
837 -
838 - return array(
839 - 'sync_type' => $tp,
840 - 'trigger' => $trigger,
841 - 'previous_connection_status' => $prev_conn_status,
842 - 'new_connection_status' => $new_conn_status,
843 - 'connection_status_changed' => $prev_conn_status === $new_conn_status ? false : true,
844 - 'sync_duration_ms' => MainWP_Execution_Helper::get_run_time( true ),
845 - );
846 - }
847 -
848 - /**
849 - * Method init empty sync values.
850 - *
851 - * @param object $pWebsite Object containing child site info.
852 - *
853 - * @return void
854 - */
855 - public static function sync_init_empty_values( $pWebsite ) {
856 -
857 - $emptyArray = wp_json_encode( array() );
858 -
859 - $opts = array(
860 - 'site_info',
861 - 'wp_upgrades',
862 - 'premium_upgrades',
863 - 'recent_comments',
864 - 'recent_posts',
865 - 'recent_pages',
866 - 'health_site_status',
867 - 'plugins_outdate_info',
868 - 'themes_outdate_info',
869 - 'directories',
870 - 'plugin_upgrades',
871 - 'theme_upgrades',
872 - 'translation_upgrades',
873 - 'securityIssues',
874 - 'themes',
875 - 'plugins',
876 - 'users',
877 - 'categories',
878 - 'password_policy_options',
879 - );
880 -
881 - foreach ( $opts as $opt ) {
882 - MainWP_DB::instance()->update_website_option( $pWebsite, $opt, $emptyArray );
883 - }
884 - }
885 -
886 -
887 - /**
888 - * Method get_wp_icon()
889 - *
890 - * Get site's icon.
891 - *
892 - * @param mixed $siteId site's id.
893 - *
894 - * @return array result error or success
895 - * @throws \MainWP_Exception Error message.
896 - *
897 - * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
898 - * @uses \MainWP\Dashboard\MainWP_Connect::get_file_content()
899 - * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
900 - * @uses \MainWP\Dashboard\MainWP_DB_Common::update_website_option()
901 - * @uses \MainWP\Dashboard\MainWP_Exception
902 - * @uses \MainWP\Dashboard\MainWP_Logger::debug()
903 - * @uses \MainWP\Dashboard\MainWP_System_Utility::can_edit_website()
904 - * @uses \MainWP\Dashboard\MainWP_System_Utility::get_wp_file_system()
905 - * @uses \MainWP\Dashboard\MainWP_System_Utility::get_mainwp_dir()
906 - * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
907 - */
908 - public static function get_wp_icon( $siteId = null ) { // phpcs:ignore -- NOSONAR - complex.
909 - if ( MainWP_Utility::ctype_digit( $siteId ) ) {
910 - $website = MainWP_DB::instance()->get_website_by_id( $siteId );
911 - if ( MainWP_System_Utility::can_edit_website( $website ) ) {
912 - $error = '';
913 - try {
914 - $information = MainWP_Connect::fetch_url_authed( $website, 'get_site_icon' );
915 - } catch ( MainWP_Exception $e ) {
916 - $error = $e->getMessage();
917 - }
918 -
919 - if ( ! empty( $error ) ) {
920 - return array( 'error' => $error );
921 - } elseif ( isset( $information['faviIconUrl'] ) && ! empty( $information['faviIconUrl'] ) ) {
922 - MainWP_Logger::instance()->debug( 'Downloading icon :: ' . esc_html( $information['faviIconUrl'] ) );
923 - $content = MainWP_Connect::get_file_content( $information['faviIconUrl'] );
924 - if ( ! empty( $content ) ) {
925 -
926 - MainWP_System_Utility::get_wp_file_system();
927 -
928 - /**
929 - * WordPress files system object.
930 - *
931 - * @global object
932 - */
933 - global $wp_filesystem;
934 -
935 - $dirs = MainWP_System_Utility::get_mainwp_dir( 'icons', true );
936 - $iconsDir = $dirs[0];
937 - $filename = basename( $information['faviIconUrl'] );
938 - $filename = strtok( $filename, '?' );
939 - if ( $filename ) {
940 - $filename = 'favi-' . $siteId . '-' . $filename;
941 - $size = false;
942 - if ( MainWP_Utility::check_image_file_name( $filename ) ) {
943 - $size = $wp_filesystem->put_contents( $iconsDir . $filename, $content ); // phpcs:ignore --
944 - }
945 - if ( $size ) {
946 - MainWP_Logger::instance()->debug( 'Icon size :: ' . $size );
947 - MainWP_DB::instance()->update_website_option( $website, 'favi_icon', $filename );
948 - return array( 'result' => 'success' );
949 - } else {
950 - return array( 'error' => 'Save icon file failed.' );
951 - }
952 - }
953 - return array( 'undefined_error' => true );
954 - } else {
955 - return array( 'error' => esc_html__( 'Download icon file failed', 'mainwp' ) );
956 - }
957 - } else {
958 - return array( 'undefined_error' => true );
959 - }
960 - }
961 - }
962 - return array( 'result' => 'NOSITE' );
963 - }
964 583 }