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