init_cron(); } /** * Method get_cron_jobs() * * @return array Cron jobs list. */ public function get_cron_jobs() { // Check wether or not to use MainWP Cron false|1. $useWPCron = ( get_option( 'mainwp_wp_cron' ) === false ) || ( (int) get_option( 'mainwp_wp_cron' ) === 1 ); // Default Cron Jobs. $jobs = array( 'mainwp_cronreconnect_action' => 'hourly', 'mainwp_cronpingchilds_action' => 'daily', 'mainwp_cronupdatescheck_action' => 'minutely', 'mainwp_crondeactivatedlicensesalert_action' => 'daily', 'mainwp_cronuptimemonitoringcheck_action' => 'minutely', 'mainwp_cron_perform_general_process' => 'minutely', ); if ( ! $useWPCron && ! get_option( 'mainwp_individual_uptime_monitoring_schedule_enabled' ) ) { unset( $jobs['mainwp_cronuptimemonitoringcheck_action'] ); } $disableHealthChecking = get_option( 'mainwp_disableSitesHealthMonitoring', 1 ); // disabled by default. if ( ! $disableHealthChecking ) { $jobs['mainwp_cronsitehealthcheck_action'] = 'hourly'; } // Legacy Backup Cron jobs. if ( get_option( 'mainwp_enableLegacyBackupFeature' ) ) { $jobs = array_merge( $jobs, array( 'mainwp_cronbackups_action' => 'hourly', 'mainwp_cronbackups_continue_action' => '5minutely', ) ); } return $jobs; } /** * Method init_cron() * * Build Cron Jobs Array & initiate via init_mainwp_cron() */ public function init_cron() { //phpcs:ignore -- NOSONAR - complex. // Check wether or not to use MainWP Cron false|1. $useWPCron = ( get_option( 'mainwp_wp_cron' ) === false ) || ( (int) get_option( 'mainwp_wp_cron' ) === 1 ); $disableHealthChecking = get_option( 'mainwp_disableSitesHealthMonitoring', 1 ); // disabled by default. if ( $disableHealthChecking ) { // disable check sites health cron. $sched = wp_next_scheduled( 'mainwp_cronsitehealthcheck_action' ); if ( false !== $sched ) { wp_unschedule_event( $sched, 'mainwp_cronsitehealthcheck_action' ); } } // Legacy Backup Cron jobs. if ( ! get_option( 'mainwp_enableLegacyBackupFeature' ) ) { // Unset Cron Schedules. $sched = wp_next_scheduled( 'mainwp_cronbackups_action' ); if ( $sched ) { wp_unschedule_event( $sched, 'mainwp_cronbackups_action' ); } $sched = wp_next_scheduled( 'mainwp_cronbackups_continue_action' ); if ( $sched ) { wp_unschedule_event( $sched, 'mainwp_cronbackups_continue_action' ); } } $jobs = $this->get_cron_jobs(); foreach ( $jobs as $hook => $recur ) { $this->init_mainwp_cron( $useWPCron, $hook, $recur ); } } /** * Method init_mainwp_cron() * * Schedual Cron Jobs. * * @param mixed $useWPCron Wether or not to use WP_Cron. * @param mixed $cron_hook When cron is going to reoccur. * @param mixed $recurrence Cron job hook. */ public function init_mainwp_cron( $useWPCron, $cron_hook, $recurrence ) { $sched = wp_next_scheduled( $cron_hook ); $enabled_job = apply_filters( 'mainwp_is_enable_schedule_job', $useWPCron, $cron_hook, $recurrence ); if ( false === $sched ) { if ( $useWPCron && $enabled_job ) { wp_schedule_event( time(), $recurrence, $cron_hook ); } } elseif ( ! $useWPCron || ! $enabled_job ) { wp_unschedule_event( $sched, $cron_hook ); } } /** * Method cron_active() * * Check if WP_Cron is active. * * @return void * * @uses \MainWP\Dashboard\MainWP_System::$version */ public function cron_active() { session_write_close(); if ( ! headers_sent() ) { header( 'Content-Type: text/html; charset=' . get_bloginfo( 'charset' ), true ); header( 'X-Robots-Tag: noindex, nofollow', true ); header( 'X-MainWP-Version: ' . MainWP_System::$version, true ); nocache_headers(); } wp_die( 'MainWP Test' ); } /** * Method get_cron_schedules() * * Get current Cron Schedual. * * @param array $schedules Array of currently set scheduals. * * @return array $scheduales. */ public function get_cron_schedules( $schedules ) { $schedules['5minutely'] = array( 'interval' => 5 * 60, 'display' => esc_html__( 'Once every 5 minutes', 'mainwp' ), ); $schedules['minutely'] = array( 'interval' => 1 * 60, 'display' => esc_html__( 'Once every minute', 'mainwp' ), ); return $schedules; } /** * Method get_timestamp_from_hh_mm() * * Get Time Stamp from $hh_mm. * * @param mixed $hh_mm Global time stamp variable. * @param int $time Time of day. * * @return time Y-m-d 00:00:59. */ public static function get_timestamp_from_hh_mm( $hh_mm, $time = false ) { $hh_mm = explode( ':', $hh_mm ); $_hour = isset( $hh_mm[0] ) ? intval( $hh_mm[0] ) : 0; $_mins = isset( $hh_mm[1] ) ? intval( $hh_mm[1] ) : 0; if ( $_hour < 0 || $_hour > 23 ) { $_hour = 0; } if ( $_mins < 0 || $_mins > 59 ) { $_mins = 0; } if ( ! empty( $time ) ) { $str_date = date( 'Y-m-d', $time ); // phpcs:ignore -- check update at given time. } else { $lctime = MainWP_Utility::get_timestamp(); $str_date = date( 'Y-m-d', $lctime ); // phpcs:ignore -- check update at local server time. } return strtotime( $str_date . ' ' . $_hour . ':' . $_mins . ':59' ); // phpcs:ignore -- check update at given time. } /** * Method get_next_time_automatic_update_to_show() * * Get websites automatic update next time. * * @return mixed array */ public static function get_next_time_automatic_update_to_show() { // to calculate next_time. static::instance()->check_conds_to_run_auto_update( $next_time, $run_timestamp, $frequence_period_in_seconds ); return $next_time; } /** * Method check_conds_to_run_auto_update() * * To check conditionals to run auto update checking. * * @param int $next_time Next time to run. * @param int $run_timestamp Runtime daily. * @param int $frequence_in_seconds frequence running in seconds. * * @return bool Valid or not to run. */ public function check_conds_to_run_auto_update( &$next_time, &$run_timestamp = false, &$frequence_in_seconds = false ) { //phpcs:ignore -- NOSONAR - complexity. $local_timestamp = MainWP_Utility::get_timestamp(); $today_0h = strtotime( date("Y-m-d 00:00:00", $local_timestamp) ); // phpcs:ignore -- to localtime. $timeDailyUpdate = get_option( 'mainwp_timeDailyUpdate' ); if ( ! empty( $timeDailyUpdate ) ) { $run_timestamp = static::get_timestamp_from_hh_mm( $timeDailyUpdate ); } else { $run_timestamp = $today_0h; // midnight. } $lasttimeScheStartAutoUpdate = (int) get_option( 'mainwp_updatescheck_start_last_timestamp', 0 ); $frequency_daily = (int) get_option( 'mainwp_frequencyDailyUpdate', 2 ); if ( $frequency_daily <= 0 ) { $frequency_daily = 1; } if ( $frequency_daily > 1 ) { $frequence_in_seconds = intval( DAY_IN_SECONDS / $frequency_daily ); if ( $frequence_in_seconds < 2 * HOUR_IN_SECONDS ) { $frequence_in_seconds = 2 * HOUR_IN_SECONDS; } } else { $frequence_in_seconds = DAY_IN_SECONDS - 1; } if ( $next_time < $run_timestamp ) { $next_time = $run_timestamp; } // Adjust the runtime according to the runtime settings, in certain sudden cases. // Apply at intervals of more than 2 hours. if ( $frequence_in_seconds >= 2 * HOUR_IN_SECONDS && $local_timestamp < $next_time && $lasttimeScheStartAutoUpdate + $frequence_in_seconds > $next_time + HOUR_IN_SECONDS ) { // Process it within the next scheduled run timeframe. // make sure of this. // The difference is more than 1 hour. MainWP_Utility::update_option( 'mainwp_adjust_auto_sync_run_time', $next_time ); MainWP_Logger::instance()->log_update_check( 'updates check :: adjust next run time :: next_time :: ' . gmdate( 'Y-m-d H:i:s', $next_time ) . ' :: local_timestamp :: ' . gmdate( 'Y-m-d H:i:s', $local_timestamp ) ); } $adjust_run_time = get_option( 'mainwp_adjust_auto_sync_run_time' ); if ( ! empty( $adjust_run_time ) ) { $next_time = $adjust_run_time; } elseif ( $next_time < $lasttimeScheStartAutoUpdate + $frequence_in_seconds ) { $next_time = $lasttimeScheStartAutoUpdate + $frequence_in_seconds; } if ( $next_time < $local_timestamp ) { $next_time = $local_timestamp; // will run now. if ( ! empty( $adjust_run_time ) ) { delete_option( 'mainwp_adjust_auto_sync_run_time' ); // Adjusted the runtime. } MainWP_Logger::instance()->log_update_check( 'updates check :: time to frequency run today :: next_time :: ' . gmdate( 'Y-m-d H:i:s', $next_time ) . ' :: local_timestamp :: ' . gmdate( 'Y-m-d H:i:s', $local_timestamp ) ); } elseif ( $this->is_log_time() ) { MainWP_Logger::instance()->log_update_check( 'updates check :: wait frequency today :: daily sync time :: ' . gmdate( 'Y-m-d H:i:s', $run_timestamp ) . ' :: next_time :: ' . gmdate( 'Y-m-d H:i:s', $next_time ) . ' :: local_timestamp :: ' . gmdate( 'Y-m-d H:i:s', $local_timestamp ) ); } $check_to_run = false; if ( $local_timestamp >= $next_time ) { $check_to_run = true; $next_time = $local_timestamp + $frequence_in_seconds; // to show next time. } return $check_to_run; } /** * Method is_log_time(). */ public function is_log_time() { if ( null === $this->last_auto_logging ) { $this->last_auto_logging = get_option( 'mainwp_log_wait_lasttime', 0 ); // load last time logging. } $time = time(); // do not logging much in short time. if ( $this->last_auto_logging + 15 * MINUTE_IN_SECONDS < $time ) { MainWP_Utility::update_option( 'mainwp_log_wait_lasttime', $time ); //phpcs:ignore -- local time. return true; } return false; } /** * Method init_environment() */ public function init_environment() { ignore_user_abort( true ); MainWP_System_Utility::set_time_limit( 0 ); add_filter( 'admin_memory_limit', function () { return '512M'; } ); } /** * Method update_auto_sync_time * * @param int $site_id site id. * @return void */ public function update_auto_sync_time( $site_id ) { $websiteValues = array( 'dtsAutomaticSync' => MainWP_Utility::get_timestamp(), ); MainWP_DB::instance()->update_website_sync_values( $site_id, $websiteValues ); } /** * Method cron_updates_check() * * MainWP Cron Check Update * * This Cron Checks to see if Automatic Daily Updates need to be performed. * * @uses \MainWP\Dashboard\MainWP_Backup_Handler::is_archive() * @uses \MainWP\Dashboard\MainWP_Backup_Handler::backup() * @uses \MainWP\Dashboard\MainWP_Backup_Handler::backup_download_file() * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed() * @uses \MainWP\Dashboard\MainWP_DB_Backup::backup_full_task_running() * @uses \MainWP\Dashboard\MainWP_DB_Common::get_user_extension_by_user_id() * @uses \MainWP\Dashboard\MainWP_DB::update_website_sync_values() * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id() * @uses \MainWP\Dashboard\MainWP_DB::get_website_option() * @uses \MainWP\Dashboard\MainWP_DB::update_website_option() * @uses \MainWP\Dashboard\MainWP_Logger::info() * @uses \MainWP\Dashboard\MainWP_Logger::debug() * @uses \MainWP\Dashboard\MainWP_Notification_Settings::get_general_email_settings() * @uses \MainWP\Dashboard\MainWP_Notification_Settings::get_site_email_settings() * @uses \MainWP\Dashboard\MainWP_Notification_Settings::get_default_emails_fields() * @uses \MainWP\Dashboard\MainWP_Sync::sync_site() * @uses \MainWP\Dashboard\MainWP_Sync::get_wp_icon() * @uses \MainWP\Dashboard\MainWP_Sync::sync_information_array() * @uses \MainWP\Dashboard\MainWP_System_Utility::get_wp_file_system() * @uses \MainWP\Dashboard\MainWP_System_Utility::get_mainwp_specific_dir() * @uses \MainWP\Dashboard\MainWP_Utility::get_timestamp() * @uses \MainWP\Dashboard\MainWP_Utility::update_option() */ public function cron_updates_check() { // phpcs:ignore Generic.Metrics.CyclomaticComplexity -- NOSONAR Current complexity is the only way to achieve desired results, pull request solutions appreciated. $this->init_environment(); $batch_updates_running = MainWP_Cron_Jobs_Batch::instance()->check_to_run_batch_updates(); if ( $batch_updates_running ) { MainWP_Logger::instance()->log_events( 'debug-updates-crons', 'Start run - batch updates' ); MainWP_Cron_Jobs_Batch::instance()->handle_cron_batch_updates(); return; } else { $auto_updates_running = MainWP_Cron_Jobs_Auto_Updates::instance()->check_to_run_auto_updates(); if ( $auto_updates_running ) { MainWP_Logger::instance()->log_events( 'debug-updates-crons', 'Start run - auto updates' ); MainWP_Cron_Jobs_Auto_Updates::instance()->handle_cron_auto_updates(); return; } } MainWP_Logger::instance()->log_events( 'debug-updates-crons', 'Start run - updates check' ); $updatecheck_running = ( 'Y' === get_option( 'mainwp_updatescheck_is_running' ) ? true : false ); $local_timestamp = MainWP_Utility::get_timestamp(); $frequencyDailyUpdate = (int) get_option( 'mainwp_frequencyDailyUpdate', 2 ); if ( $frequencyDailyUpdate <= 0 ) { $frequencyDailyUpdate = 1; } $today_m_y = date( 'd/m/Y', $local_timestamp ); //phpcs:ignore -- local time. $lasttimeAutomaticUpdate = get_option( 'mainwp_updatescheck_last_timestamp' ); $lasttimeDailyDigest = get_option( 'mainwp_updatescheck_dailydigest_last_timestamp' ); $mainwpLastDailydigest = get_option( 'mainwp_dailydigest_last' ); /** * Filter: mainwp_updatescheck_sendmail_at_time * * Filters the the time when the Daily Digest email will be sent. * * @since 3.4 */ $send_noti_at = apply_filters( 'mainwp_updatescheck_sendmail_at_time', false ); $time_to_noti = false; $time_notice_at = false; if ( ! empty( $send_noti_at ) ) { $send_timestamp = static::get_timestamp_from_hh_mm( $send_noti_at, $lasttimeDailyDigest ); $time_notice_at = $local_timestamp > $send_timestamp ? true : false; } elseif ( 1 < $frequencyDailyUpdate ) { $time_to_noti = ( $today_m_y !== $mainwpLastDailydigest ) ? true : false; } $sendmail_for_each_auto_sync = apply_filters( 'mainwp_updatescheck_sendmail_for_each_auto_sync_finished', false ); $check_ready_sendmail = false; if ( $sendmail_for_each_auto_sync || 1 === (int) $frequencyDailyUpdate || $time_notice_at || $time_to_noti ) { $check_ready_sendmail = true; } if ( $check_ready_sendmail && 'Y' === get_option( 'mainwp_updatescheck_ready_sendmail' ) ) { $plain_text = get_option( 'mainwp_daily_digest_plain_text', false ); MainWP_Utility::update_option( 'mainwp_dailydigest_last', $today_m_y ); MainWP_Utility::update_option( 'mainwp_updatescheck_dailydigest_last_timestamp', $local_timestamp ); // send daily digest email one time per day. $individual_digestWebsites = get_option( 'mainwp_updatescheck_individual_digest_websites' ); MainWP_Utility::update_option( 'mainwp_updatescheck_ready_sendmail', '' ); // here to fix. MainWP_Logger::instance()->log_update_check( 'got to the daily digest mail part' ); $gen_email_settings = MainWP_Notification_Settings::get_general_email_settings( 'daily_digest' ); if ( empty( $gen_email_settings['disable'] ) ) { // send general daily digests. $this->start_notification_daily_digest( $gen_email_settings, $plain_text ); // general email. } $to_admin_digestWebsites = array(); if ( is_array( $individual_digestWebsites ) && ! empty( $individual_digestWebsites ) ) { // send individual site daily digests, one email for one site. foreach ( $individual_digestWebsites as $siteid ) { $website = MainWP_DB::instance()->get_website_by_id( $siteid, false, array( 'settings_notification_emails' ) ); $email_settings = MainWP_Notification_Settings::get_site_email_settings( 'daily_digest', $website ); // get site email settings. if ( ! $email_settings['disable'] ) { $to_admin_digestWebsites[] = $siteid; $sent = $this->start_notification_daily_digest( $email_settings, $plain_text, array( $siteid ), $website ); if ( $sent ) { usleep( 100000 ); } } } } if ( ! empty( $to_admin_digestWebsites ) ) { $admin_email_settings = MainWP_Notification_Settings::get_default_emails_fields( 'daily_digest', '', true ); // get default subject and heading only. $admin_email_settings['disable'] = 0; $admin_email_settings['recipients'] = MainWP_Notification_Settings::get_general_email(); // sent to general notification email only. // send all individual daily digest to admin in one email. $this->start_notification_daily_digest( $admin_email_settings, $plain_text, $to_admin_digestWebsites ); // will send email to general notification email. } $this->refresh_saved_fields(); } $valid_to_run = $this->check_conds_to_run_auto_update( $next_time, $run_timestamp, $frequence_period_in_seconds ); /** * Filter: mainwp_updatescheck_hours_interval * * Filters the status check interval. * * @since 3.4 */ $hoursIntervalAutomaticUpdate = apply_filters( 'mainwp_updatescheck_hours_interval', false ); $manual_trigger_last_timestamp = 0; $manual_trigger_start = get_option( 'mainwp_auto_sync_manual_trigger_start_last_timestamp' ); if ( ! empty( $manual_trigger_start ) ) { if ( is_numeric( $manual_trigger_start ) ) { $manual_trigger_last_timestamp = intval( $manual_trigger_start ); // timestamp value. } elseif ( is_string( $manual_trigger_start ) ) { $manual_trigger_last_timestamp = strtotime( $manual_trigger_start ); // Y-m-d H:i:S format. } } if ( ! $updatecheck_running ) { $run_auto_checks = false; $run_hours_interval = null; if ( $hoursIntervalAutomaticUpdate > 0 ) { $run_hours_interval = false; if ( $lasttimeAutomaticUpdate && ( $lasttimeAutomaticUpdate + $hoursIntervalAutomaticUpdate * 3600 > $local_timestamp ) ) { MainWP_Logger::instance()->log_update_check( 'updates check :: already updated hours interval' ); } else { $run_hours_interval = true; } } if ( $run_hours_interval || ( null === $run_hours_interval && $valid_to_run ) ) { // if not set sync time, and run frequency. $run_auto_checks = true; } if ( $manual_trigger_last_timestamp ) { $run_auto_checks = true; } if ( ! $run_auto_checks ) { if ( $this->is_log_time() ) { MainWP_Logger::instance()->log_update_check( 'updates check :: wait frequency today :: [frequencyDailyUpdate=' . $frequencyDailyUpdate . '] :: [frequence=' . gmdate( 'H:i:s', $frequence_period_in_seconds ) . ']' ); } return; } } $lasttimeStartAutomaticUpdate = get_option( 'mainwp_updatescheck_start_last_timestamp' ); // not batch updates run at the moment. if ( ! $updatecheck_running ) { if ( ! $manual_trigger_last_timestamp ) { // do not update if manual trigger. MainWP_Utility::update_option( 'mainwp_updatescheck_start_last_timestamp', $local_timestamp ); // start new update checking. $lasttimeStartAutomaticUpdate = $local_timestamp; } else { $lasttimeStartAutomaticUpdate = $manual_trigger_last_timestamp; } MainWP_Utility::update_option( 'mainwp_updatescheck_is_running', 'Y' ); // log last run. $last_run = get_option( 'mainwp_updatescheck_last_run' ); if ( $last_run ) { $last_run = json_decode( $last_run ); } if ( ! is_array( $last_run ) ) { $last_run = array(); } if ( count( $last_run ) > 20 ) { array_shift( $last_run ); } $last_run[] = date( 'Y-m-d H:i:s', $local_timestamp ); //phpcs:ignore -- local time. MainWP_Utility::update_option( 'mainwp_updatescheck_last_run', wp_json_encode( $last_run ) ); if ( $local_timestamp > $run_timestamp && $local_timestamp < $run_timestamp + $frequence_period_in_seconds && $frequencyDailyUpdate > 1 ) { $last_run_timestamp_today = $run_timestamp + $frequence_period_in_seconds * ( $frequencyDailyUpdate - 1 ); MainWP_Utility::update_option( 'mainwp_updatescheck_last_run_timestamp_today', $last_run_timestamp_today ); } $this->refresh_saved_fields(); $log_lastsstart = ! empty( $lasttimeStartAutomaticUpdate ) ? '[lasttimeStartAutomaticUpdate=' . MainWP_Utility::format_timestamp( $lasttimeStartAutomaticUpdate ) . ']' : ''; MainWP_Logger::instance()->log_update_check( 'Start automatic check updates :: ' . $log_lastsstart ); } $websites = array(); $checkupdate_websites = MainWP_Auto_Updates_DB::instance()->get_websites_check_updates( 4, $lasttimeStartAutomaticUpdate ); // to sync sites data. foreach ( $checkupdate_websites as $website ) { if ( ! MainWP_DB_Backup::instance()->backup_full_task_running( $website->id ) ) { $websites[] = $website; } } MainWP_Logger::instance()->info( 'updates check found ' . count( $checkupdate_websites ) . ' websites' ); MainWP_Logger::instance()->log_update_check( 'updates check found [' . count( $checkupdate_websites ) . ' websites] :: going to check [' . count( $websites ) . ' websites]' ); $userid = null; foreach ( $websites as $website ) { $websiteValues = array( 'dtsAutomaticSyncStart' => $local_timestamp, ); if ( null === $userid ) { $userid = $website->userid; } MainWP_DB::instance()->update_website_sync_values( $website->id, $websiteValues ); } $plain_text = get_option( 'mainwp_daily_digest_plain_text', false ); /** * Filter: mainwp_text_format_email * * Filters whether the email shuld bein plain text format. * * @since 3.5 */ $filter_plain_text = apply_filters( 'mainwp_text_format_email', $plain_text ); if ( $plain_text !== $filter_plain_text ) { $plain_text = $filter_plain_text; MainWP_Utility::update_option( 'mainwp_daily_digest_plain_text', $plain_text ); } if ( empty( $checkupdate_websites ) ) { $busyCounter = MainWP_Auto_Updates_DB::instance()->get_websites_count_where_dts_automatic_sync_smaller_then_start( $lasttimeStartAutomaticUpdate ); if ( ! empty( $busyCounter ) ) { MainWP_Logger::instance()->log_update_check( 'busy counter :: found ' . $busyCounter . ' websites' ); $lastAutomaticUpdate = MainWP_Auto_Updates_DB::instance()->get_websites_last_automatic_sync(); if ( ( time() - $lastAutomaticUpdate ) < HOUR_IN_SECONDS ) { MainWP_Logger::instance()->log_update_check( 'Automatic check updates last time :: ' . MainWP_Utility::format_timestamp( $lastAutomaticUpdate ) ); } } if ( $manual_trigger_last_timestamp ) { // finished manual trigger auto sync. delete_option( 'mainwp_auto_sync_manual_trigger_start_last_timestamp' ); MainWP_Logger::instance()->log_update_check( 'Manual trigger for automatic synchronization of all sites completed.' ); } else { MainWP_Logger::instance()->log_update_check( 'Automatic sync of all sites completed.' ); } if ( $updatecheck_running ) { MainWP_Utility::update_option( 'mainwp_updatescheck_is_running', '' ); $updatecheck_running = false; do_action( 'mainwp_synced_all_sites' ); } update_option( 'mainwp_last_synced_all_sites', time() ); MainWP_Utility::update_option( 'mainwp_updatescheck_last_timestamp', $local_timestamp ); MainWP_Utility::update_option( 'mainwp_updatescheck_last', $today_m_y ); if ( 'Y' !== get_option( 'mainwp_updatescheck_ready_sendmail' ) ) { MainWP_Utility::update_option( 'mainwp_updatescheck_ready_sendmail', 'Y' ); } } else { $userExtension = MainWP_DB_Common::instance()->get_user_extension_by_user_id( $userid ); $decodedIgnoredCores = ! empty( $userExtension->ignored_wp_upgrades ) ? json_decode( $userExtension->ignored_wp_upgrades, true ) : array(); $decodedIgnoredPlugins = json_decode( $userExtension->ignored_plugins, true ); $trustedPlugins = json_decode( $userExtension->trusted_plugins, true ); $decodedIgnoredThemes = json_decode( $userExtension->ignored_themes, true ); $trustedThemes = json_decode( $userExtension->trusted_themes, true ); if ( ! is_array( $decodedIgnoredCores ) ) { $decodedIgnoredCores = array(); } if ( ! is_array( $decodedIgnoredPlugins ) ) { $decodedIgnoredPlugins = array(); } if ( ! is_array( $trustedPlugins ) ) { $trustedPlugins = array(); } if ( ! is_array( $decodedIgnoredThemes ) ) { $decodedIgnoredThemes = array(); } if ( ! is_array( $trustedThemes ) ) { $trustedThemes = array(); } $coreToUpdate = array(); $coreNewUpdate = array(); $ignoredCoreToUpdate = array(); $ignoredCoreNewUpdate = array(); $pluginsToUpdate = array(); $pluginsNewUpdate = array(); $notTrustedPluginsToUpdate = array(); $notTrustedPluginsNewUpdate = array(); $themesToUpdate = array(); $themesNewUpdate = array(); $notTrustedThemesToUpdate = array(); $notTrustedThemesNewUpdate = array(); $transToUpdate = array(); $transNewUpdate = array(); $notTrustedTransToUpdate = array(); $notTrustedTransNewUpdate = array(); $individualDailyDigestWebsites = array(); $updatescheckSitesIcon = get_option( 'mainwp_updatescheck_sites_icon' ); if ( ! is_array( $updatescheckSitesIcon ) ) { $updatescheckSitesIcon = array(); } $delay_autoupdate = get_option( 'mainwp_delay_autoupdate', 1 ); foreach ( $websites as $website ) { $websiteDecodedIgnoredPlugins = json_decode( $website->ignored_plugins, true ); if ( ! is_array( $websiteDecodedIgnoredPlugins ) ) { $websiteDecodedIgnoredPlugins = array(); } $websiteDecodedIgnoredThemes = json_decode( $website->ignored_themes, true ); if ( ! is_array( $websiteDecodedIgnoredThemes ) ) { $websiteDecodedIgnoredThemes = array(); } $synced = MainWP_Sync::sync_site( $website, false, true ); $this->update_auto_sync_time( $website->id ); if ( ! $synced ) { MainWP_Logger::instance()->log_update_check( 'auto sync failed :: [siteid=' . $website->id . ']' ); continue; } MainWP_Logger::instance()->log_update_check( 'auto sync success :: [siteid=' . $website->id . ']' ); $website = MainWP_DB::instance()->get_website_by_id( $website->id, false, array( 'wp_upgrades', 'ignored_wp_upgrades', 'last_wp_upgrades' ) ); $check_individual_digest = false; /** Check core updates * */ $websiteLastCoreUpgrades = ! empty( $website->last_wp_upgrades ) ? json_decode( $website->last_wp_upgrades, true ) : array(); $websiteCoreUpgrades = ! empty( $website->wp_upgrades ) ? json_decode( $website->wp_upgrades, true ) : array(); $website_decodedIgnoredCores = ! empty( $website->ignored_wp_upgrades ) ? json_decode( $website->ignored_wp_upgrades, true ) : array(); $websiteCoreUpdateCheck = 0; $websitePluginsUpdateCheck = array(); $websiteThemesUpdateCheck = array(); $websiteTransUpdateCheck = array(); if ( ! empty( $delay_autoupdate ) ) { $websiteCoreUpdateCheck = MainWP_DB::instance()->get_website_option( $website, 'core_update_check' ); $websitePluginsUpdateCheck = MainWP_DB::instance()->get_website_option( $website, 'plugins_update_check' ); $websiteThemesUpdateCheck = MainWP_DB::instance()->get_website_option( $website, 'themes_update_check' ); $websiteTransUpdateCheck = MainWP_DB::instance()->get_website_option( $website, 'trans_update_check' ); $websiteCoreUpdateCheck = intval( $websiteCoreUpdateCheck ); $websitePluginsUpdateCheck = ! empty( $websitePluginsUpdateCheck ) ? json_decode( $websitePluginsUpdateCheck, true ) : array(); $websiteThemesUpdateCheck = ! empty( $websiteThemesUpdateCheck ) ? json_decode( $websiteThemesUpdateCheck, true ) : array(); $websiteTransUpdateCheck = ! empty( $websiteTransUpdateCheck ) ? json_decode( $websiteTransUpdateCheck, true ) : array(); if ( ! is_array( $websitePluginsUpdateCheck ) ) { $websitePluginsUpdateCheck = array(); } if ( ! is_array( $websiteThemesUpdateCheck ) ) { $websiteThemesUpdateCheck = array(); } if ( ! is_array( $websiteTransUpdateCheck ) ) { $websiteTransUpdateCheck = array(); } } if ( isset( $websiteCoreUpgrades['current'] ) ) { $newUpdate = ! ( isset( $websiteLastCoreUpgrades['current'] ) && ( $websiteLastCoreUpgrades['current'] === $websiteCoreUpgrades['current'] ) && ( $websiteLastCoreUpgrades['new'] === $websiteCoreUpgrades['new'] ) ); if ( ! $website->is_ignoreCoreUpdates && ! MainWP_Common_Functions::instance()->is_ignored_updates( $websiteCoreUpgrades, $website_decodedIgnoredCores, 'core' ) && ! MainWP_Common_Functions::instance()->is_ignored_updates( $websiteCoreUpgrades, $decodedIgnoredCores, 'core' ) ) { $check_individual_digest = true; $item = array( 'id' => $website->id, 'name' => $website->name, 'url' => $website->url, 'current' => $websiteCoreUpgrades['current'], 'new_version' => $websiteCoreUpgrades['new'], ); if ( ! empty( $website->automatic_update ) && 1 === (int) $website->automatic_update ) { $item['trusted'] = 1; if ( $newUpdate ) { $item['new'] = 1; $coreNewUpdate[] = $item; $websiteCoreUpdateCheck = time(); } else { $item['new'] = 0; $coreToUpdate[] = $item; if ( empty( $websiteCoreUpdateCheck ) && ! empty( $delay_autoupdate ) ) { $websiteCoreUpdateCheck = time(); } } } else { $item['trusted'] = 0; if ( $newUpdate ) { $item['new'] = 1; $ignoredCoreNewUpdate[] = $item; } else { $item['new'] = 0; $ignoredCoreToUpdate[] = $item; } $websiteCoreUpdateCheck = 0; } } } /** Check plugins * */ $websiteLastPlugins = MainWP_DB::instance()->get_website_option( $website, 'last_plugin_upgrades' ); $websiteLastPlugins = ! empty( $websiteLastPlugins ) ? json_decode( $websiteLastPlugins, true ) : array(); $websitePlugins = json_decode( $website->plugin_upgrades, true ); /** Check themes * */ $websiteLastThemes = MainWP_DB::instance()->get_website_option( $website, 'last_theme_upgrades' ); $websiteLastThemes = ! empty( $websiteLastThemes ) ? json_decode( $websiteLastThemes, true ) : array(); $websiteThemes = json_decode( $website->theme_upgrades, true ); /** Check translations * */ $websiteLastTrans = MainWP_DB::instance()->get_website_option( $website, 'last_trans_upgrades' ); $websiteLastTrans = ! empty( $websiteLastTrans ) ? json_decode( $websiteLastTrans, true ) : array(); $websiteTrans = json_decode( $website->translation_upgrades, true ); $decodedPremiumUpgrades = MainWP_DB::instance()->get_website_option( $website, 'premium_upgrades' ); $decodedPremiumUpgrades = ! empty( $decodedPremiumUpgrades ) ? json_decode( $decodedPremiumUpgrades, true ) : array(); if ( is_array( $decodedPremiumUpgrades ) ) { foreach ( $decodedPremiumUpgrades as $slug => $premiumUpgrade ) { if ( 'plugin' === $premiumUpgrade['type'] ) { if ( ! is_array( $websitePlugins ) ) { $websitePlugins = array(); } $websitePlugins[ $slug ] = $premiumUpgrade; } elseif ( 'theme' === $premiumUpgrade['type'] ) { if ( ! is_array( $websiteThemes ) ) { $websiteThemes = array(); } $websiteThemes[ $slug ] = $premiumUpgrade; } } } foreach ( $websitePlugins as $pluginSlug => $pluginInfo ) { if ( $website->is_ignorePluginUpdates ) { continue; } if ( MainWP_Common_Functions::instance()->is_ignored_updates( $pluginInfo, $decodedIgnoredPlugins, 'plugin' ) || MainWP_Common_Functions::instance()->is_ignored_updates( $pluginInfo, $websiteDecodedIgnoredPlugins, 'plugin' ) ) { continue; } $check_individual_digest = true; $change_log = ''; if ( isset( $pluginInfo['update']['url'] ) && ( false !== strpos( $pluginInfo['update']['url'], 'wordpress.org/plugins' ) ) ) { $change_log = $pluginInfo['update']['url']; if ( substr( $change_log, - 1 ) !== '/' ) { $change_log .= '/'; } $change_log .= '#developers'; } $item = array( 'id' => $website->id, 'name' => $website->name, 'url' => $website->url, 'plugin' => $pluginInfo['Name'], 'current' => $pluginInfo['Version'], 'new_version' => $pluginInfo['update']['new_version'], 'change_log' => $change_log, 'slug' => $pluginSlug, ); $newUpdate = ! ( isset( $websiteLastPlugins[ $pluginSlug ] ) && ( $pluginInfo['Version'] === $websiteLastPlugins[ $pluginSlug ]['Version'] ) && ( $pluginInfo['update']['new_version'] === $websiteLastPlugins[ $pluginSlug ]['update']['new_version'] ) ); if ( in_array( $pluginSlug, $trustedPlugins ) ) { $item['trusted'] = 1; if ( $newUpdate ) { $item['new'] = 1; $pluginsNewUpdate[] = $item; if ( ! empty( $delay_autoupdate ) ) { $websitePluginsUpdateCheck[ $pluginSlug ] = time(); } } else { $item['new'] = 0; $pluginsToUpdate[] = $item; $check_timestamp = isset( $websitePluginsUpdateCheck[ $pluginSlug ] ) ? $websitePluginsUpdateCheck[ $pluginSlug ] : 0; if ( ! empty( $delay_autoupdate ) && empty( $check_timestamp ) ) { $websitePluginsUpdateCheck[ $pluginSlug ] = time(); } } } else { $item['trusted'] = 0; if ( $newUpdate ) { $item['new'] = 1; $notTrustedPluginsNewUpdate[] = $item; } else { $item['new'] = 0; $notTrustedPluginsToUpdate[] = $item; } if ( isset( $websitePluginsUpdateCheck[ $pluginSlug ] ) ) { unset( $websitePluginsUpdateCheck[ $pluginSlug ] ); } } } foreach ( $websiteThemes as $themeSlug => $themeInfo ) { if ( $website->is_ignoreThemeUpdates ) { continue; } if ( MainWP_Common_Functions::instance()->is_ignored_updates( $themeInfo, $decodedIgnoredThemes, 'theme' ) || MainWP_Common_Functions::instance()->is_ignored_updates( $themeInfo, $websiteDecodedIgnoredThemes, 'theme' ) ) { continue; } $check_individual_digest = true; $newUpdate = ! ( isset( $websiteLastThemes[ $themeSlug ] ) && ( $themeInfo['Version'] === $websiteLastThemes[ $themeSlug ]['Version'] ) && ( $themeInfo['update']['new_version'] === $websiteLastThemes[ $themeSlug ]['update']['new_version'] ) ); $item = array( 'id' => $website->id, 'name' => $website->name, 'url' => $website->url, 'theme' => $themeInfo['Name'], 'current' => $themeInfo['Version'], 'new_version' => $themeInfo['update']['new_version'], 'slug' => $themeSlug, ); if ( in_array( $themeSlug, $trustedThemes ) ) { $item['trusted'] = 1; if ( $newUpdate ) { $item['new'] = 1; $themesNewUpdate[] = $item; if ( ! empty( $delay_autoupdate ) ) { $websiteThemesUpdateCheck[ $themeSlug ] = time(); } } else { $item['new'] = 0; $check_timestamp = isset( $websiteThemesUpdateCheck[ $themeSlug ] ) ? $websiteThemesUpdateCheck[ $themeSlug ] : 0; if ( empty( $check_timestamp ) && ! empty( $delay_autoupdate ) ) { $websiteThemesUpdateCheck[ $themeSlug ] = time(); } $themesToUpdate[] = $item; } } else { $item['trusted'] = 0; if ( $newUpdate ) { $item['new'] = 1; $notTrustedThemesNewUpdate[] = $item; } else { $item['new'] = 0; $notTrustedThemesToUpdate[] = $item; } if ( isset( $websiteThemesUpdateCheck[ $themeSlug ] ) ) { unset( $websiteThemesUpdateCheck[ $themeSlug ] ); } } } foreach ( $websiteTrans as $transSlug => $transInfo ) { $check_individual_digest = true; $newUpdate = ! isset( $websiteLastTrans[ $transSlug ] ); $item = array( 'id' => $website->id, 'name' => $website->name, 'url' => $website->url, 'translation' => $transInfo['name'], 'version' => $transInfo['version'], 'slug' => $transInfo['slug'], ); if ( MainWP_Manage_Sites_Update_View::is_trans_trusted_update( $transInfo, $trustedPlugins, $trustedThemes ) ) { $item['trusted'] = 1; if ( $newUpdate ) { $item['new'] = 1; $transNewUpdate[] = $item; if ( ! empty( $delay_autoupdate ) ) { $websiteTransUpdateCheck[ $transSlug ] = time(); } } else { $item['new'] = 0; $check_timestamp = isset( $websiteTransUpdateCheck[ $transSlug ] ) ? $websiteTransUpdateCheck[ $transSlug ] : 0; if ( empty( $check_timestamp ) && ! empty( $delay_autoupdate ) ) { $websiteTransUpdateCheck[ $transSlug ] = time(); } $transToUpdate[] = $item; } } else { $item['trusted'] = 0; if ( $newUpdate ) { $item['new'] = 1; $notTrustedTransNewUpdate[] = $item; } else { $item['new'] = 0; $notTrustedTransToUpdate[] = $item; } if ( isset( $websiteTransUpdateCheck[ $transSlug ] ) ) { unset( $websiteTransUpdateCheck[ $transSlug ] ); } } } /** * Action: mainwp_daily_digest_action * * Hooks the daily digest email notification send process. * * @param object $website Object conaining child site info. * @param bool $plain_text Whether plain text email should be sent. * * @since 4.1 */ do_action( 'mainwp_daily_digest_action', $website, $plain_text ); MainWP_DB::instance()->update_website_sync_values( $website->id, array( 'dtsAutomaticSync' => $local_timestamp ) ); MainWP_DB::instance()->update_website_option( $website, 'last_wp_upgrades', wp_json_encode( $websiteCoreUpgrades ) ); MainWP_DB::instance()->update_website_option( $website, 'last_plugin_upgrades', $website->plugin_upgrades ); MainWP_DB::instance()->update_website_option( $website, 'last_theme_upgrades', $website->theme_upgrades ); MainWP_DB::instance()->update_website_option( $website, 'last_trans_upgrades', $website->translation_upgrades ); if ( ! empty( $delay_autoupdate ) ) { foreach ( $websitePluginsUpdateCheck as $slug => $check_time ) { if ( ( time() > $check_time + 30 * DAY_IN_SECONDS ) && is_array( $websitePlugins ) && ! empty( $websitePlugins ) && ! isset( $websitePlugins[ $slug ] ) ) { unset( $websitePluginsUpdateCheck[ $slug ] ); } } foreach ( $websiteThemesUpdateCheck as $slug => $check_time ) { if ( ( time() > $check_time + 30 * DAY_IN_SECONDS ) && is_array( $websiteThemes ) && ! empty( $websiteThemes ) && ! isset( $websiteThemes[ $slug ] ) ) { unset( $websiteThemesUpdateCheck[ $slug ] ); } } foreach ( $websiteTransUpdateCheck as $slug => $check_time ) { if ( ( time() > $check_time + 30 * DAY_IN_SECONDS ) && is_array( $websiteTrans ) && ! empty( $websiteTrans ) && ! isset( $websiteTrans[ $slug ] ) ) { unset( $websiteTransUpdateCheck[ $slug ] ); } } MainWP_DB::instance()->update_website_option( $website, 'core_update_check', $websiteCoreUpdateCheck ); MainWP_DB::instance()->update_website_option( $website, 'plugins_update_check', ( ! empty( $websitePluginsUpdateCheck ) ? wp_json_encode( $websitePluginsUpdateCheck ) : '' ) ); MainWP_DB::instance()->update_website_option( $website, 'themes_update_check', ( ! empty( $websiteThemesUpdateCheck ) ? wp_json_encode( $websiteThemesUpdateCheck ) : '' ) ); MainWP_DB::instance()->update_website_option( $website, 'trans_update_check', ( ! empty( $websiteTransUpdateCheck ) ? wp_json_encode( $websiteTransUpdateCheck ) : '' ) ); } elseif ( ! empty( $websitePluginsUpdateCheck ) || ! empty( $websiteThemesUpdateCheck ) ) { MainWP_DB::instance()->update_website_option( $website, 'core_update_check', 0 ); MainWP_DB::instance()->update_website_option( $website, 'plugins_update_check', '' ); MainWP_DB::instance()->update_website_option( $website, 'themes_update_check', '' ); MainWP_DB::instance()->update_website_option( $website, 'trans_update_check', '' ); } if ( ! in_array( $website->id, $updatescheckSitesIcon ) ) { MainWP_Sync::get_wp_icon( $website->id ); $updatescheckSitesIcon[] = $website->id; } if ( $check_individual_digest ) { $individualDailyDigestWebsites[] = $website->id; } } MainWP_Utility::update_option( 'mainwp_updatescheck_sites_icon', $updatescheckSitesIcon ); if ( ! empty( $individualDailyDigestWebsites ) ) { $individualDailyDigestWebsitesSaved = get_option( 'mainwp_updatescheck_individual_digest_websites' ); if ( ! is_array( $individualDailyDigestWebsitesSaved ) ) { $individualDailyDigestWebsitesSaved = array(); } foreach ( $individualDailyDigestWebsites as $sid ) { if ( ! in_array( $sid, $individualDailyDigestWebsitesSaved ) ) { $individualDailyDigestWebsitesSaved[] = $sid; } } MainWP_Utility::update_option( 'mainwp_updatescheck_individual_digest_websites', $individualDailyDigestWebsitesSaved ); } if ( ! empty( $coreNewUpdate ) ) { $coreNewUpdateSaved = get_option( 'mainwp_updatescheck_mail_update_core_new' ); MainWP_Utility::update_option( 'mainwp_updatescheck_mail_update_core_new', MainWP_Utility::array_merge( $coreNewUpdateSaved, $coreNewUpdate ) ); } if ( ! empty( $pluginsNewUpdate ) ) { $pluginsNewUpdateSaved = get_option( 'mainwp_updatescheck_mail_update_plugins_new' ); MainWP_Utility::update_option( 'mainwp_updatescheck_mail_update_plugins_new', MainWP_Utility::array_merge( $pluginsNewUpdateSaved, $pluginsNewUpdate ) ); } if ( ! empty( $themesNewUpdate ) ) { $themesNewUpdateSaved = get_option( 'mainwp_updatescheck_mail_update_themes_new' ); MainWP_Utility::update_option( 'mainwp_updatescheck_mail_update_themes_new', MainWP_Utility::array_merge( $themesNewUpdateSaved, $themesNewUpdate ) ); } if ( ! empty( $coreToUpdate ) ) { $coreToUpdateSaved = get_option( 'mainwp_updatescheck_mail_update_core' ); MainWP_Utility::update_option( 'mainwp_updatescheck_mail_update_core', MainWP_Utility::array_merge( $coreToUpdateSaved, $coreToUpdate ) ); } if ( ! empty( $pluginsToUpdate ) ) { $pluginsToUpdateSaved = get_option( 'mainwp_updatescheck_mail_update_plugins' ); MainWP_Utility::update_option( 'mainwp_updatescheck_mail_update_plugins', MainWP_Utility::array_merge( $pluginsToUpdateSaved, $pluginsToUpdate ) ); } if ( ! empty( $themesToUpdate ) ) { $themesToUpdateSaved = get_option( 'mainwp_updatescheck_mail_update_themes' ); MainWP_Utility::update_option( 'mainwp_updatescheck_mail_update_themes', MainWP_Utility::array_merge( $themesToUpdateSaved, $themesToUpdate ) ); } if ( ! empty( $ignoredCoreToUpdate ) ) { $ignoredCoreToUpdateSaved = get_option( 'mainwp_updatescheck_mail_ignore_core' ); MainWP_Utility::update_option( 'mainwp_updatescheck_mail_ignore_core', MainWP_Utility::array_merge( $ignoredCoreToUpdateSaved, $ignoredCoreToUpdate ) ); } if ( ! empty( $ignoredCoreNewUpdate ) ) { $ignoredCoreNewUpdateSaved = get_option( 'mainwp_updatescheck_mail_ignore_core_new' ); MainWP_Utility::update_option( 'mainwp_updatescheck_mail_ignore_core_new', MainWP_Utility::array_merge( $ignoredCoreNewUpdateSaved, $ignoredCoreNewUpdate ) ); } if ( ! empty( $notTrustedPluginsToUpdate ) ) { $notTrustedPluginsToUpdateSaved = get_option( 'mainwp_updatescheck_mail_ignore_plugins' ); MainWP_Utility::update_option( 'mainwp_updatescheck_mail_ignore_plugins', MainWP_Utility::array_merge( $notTrustedPluginsToUpdateSaved, $notTrustedPluginsToUpdate ) ); } if ( ! empty( $notTrustedPluginsNewUpdate ) ) { $notTrustedPluginsNewUpdateSaved = get_option( 'mainwp_updatescheck_mail_ignore_plugins_new' ); MainWP_Utility::update_option( 'mainwp_updatescheck_mail_ignore_plugins_new', MainWP_Utility::array_merge( $notTrustedPluginsNewUpdateSaved, $notTrustedPluginsNewUpdate ) ); } if ( ! empty( $notTrustedThemesToUpdate ) ) { $notTrustedThemesToUpdateSaved = get_option( 'mainwp_updatescheck_mail_ignore_themes' ); MainWP_Utility::update_option( 'mainwp_updatescheck_mail_ignore_themes', MainWP_Utility::array_merge( $notTrustedThemesToUpdateSaved, $notTrustedThemesToUpdate ) ); } if ( ! empty( $notTrustedThemesNewUpdate ) ) { $notTrustedThemesNewUpdateSaved = get_option( 'mainwp_updatescheck_mail_ignore_themes_new' ); MainWP_Utility::update_option( 'mainwp_updatescheck_mail_ignore_themes_new', MainWP_Utility::array_merge( $notTrustedThemesNewUpdateSaved, $notTrustedThemesNewUpdate ) ); } } } /** * Method start_notification_daily_digest(). * * Send email notification. * * @param array $email_settings Email settings. * @param bool $plain_text Text format value. * @param array $sites_ids Array of websites ids (option). * @param object $email_site current report site. * * @return bool True|False * * @uses \MainWP\Dashboard\MainWP_Format::get_site_updates_items() * @uses \MainWP\Dashboard\MainWP_DB::get_disconnected_websites() * @uses \MainWP\Dashboard\MainWP_Logger::debug() * @uses \MainWP\Dashboard\MainWP_Notification */ public function start_notification_daily_digest( $email_settings, $plain_text, $sites_ids = false, $email_site = false ) { $sendMail = false; $updateAvaiable = false; $plugin_updates = array(); $theme_updates = array(); $plugin_updates = MainWP_Format::get_site_updates_items( 'plugin', $sites_ids ); if ( ! empty( $plugin_updates ) ) { $sendMail = true; $updateAvaiable = true; } $theme_updates = MainWP_Format::get_site_updates_items( 'theme', $sites_ids ); if ( ! empty( $theme_updates ) ) { $sendMail = true; $updateAvaiable = true; } $wp_updates = MainWP_Format::get_site_updates_items( 'wpcore', $sites_ids ); if ( ! empty( $wp_updates ) ) { $sendMail = true; $updateAvaiable = true; } $sites_disconnected = MainWP_DB::instance()->get_disconnected_websites( $sites_ids ); if ( ! empty( $sites_disconnected ) ) { $sendMail = true; } if ( ! $sendMail ) { MainWP_Logger::instance()->log_update_check( 'updates check :: sendMail is false' ); return false; } $params = array( 'plain_text' => $plain_text, 'sites_ids' => $sites_ids, 'email_site' => $email_site, ); return MainWP_Notification::send_daily_digest_notification( $email_settings, $updateAvaiable, $wp_updates, $plugin_updates, $theme_updates, $sites_disconnected, $params ); } /** * Method refresh_saved_fields(). * * Clear settings field values. * * @uses \MainWP\Dashboard\MainWP_Utility::update_option() */ public function refresh_saved_fields() { MainWP_Logger::instance()->log_update_check( 'updates check :: clear saved info' ); $empty_fields = array( 'mainwp_automaticUpdate_backupChecks', 'mainwp_updatescheck_mail_update_core_new', 'mainwp_updatescheck_mail_update_plugins_new', 'mainwp_updatescheck_mail_update_themes_new', 'mainwp_updatescheck_mail_update_core', 'mainwp_updatescheck_mail_update_plugins', 'mainwp_updatescheck_mail_update_themes', 'mainwp_updatescheck_mail_ignore_core', 'mainwp_updatescheck_mail_ignore_plugins', 'mainwp_updatescheck_mail_ignore_themes', 'mainwp_updatescheck_mail_ignore_core_new', 'mainwp_updatescheck_mail_ignore_plugins_new', 'mainwp_updatescheck_mail_ignore_themes_new', 'mainwp_updatescheck_individual_digest_websites', 'mainwp_updatescheck_sites_icon', ); foreach ( $empty_fields as $field ) { MainWP_Utility::update_option( $field, '' ); } } /** * Method start_notification_http_check(). * * Prepare to send http check notification. * * @param bool $plain_text Text format value. * * @return bool True|False * * @uses \MainWP\Dashboard\MainWP_Notification::send_http_check_notification() * @uses \MainWP\Dashboard\MainWP_Notification_Settings::get_general_email_settings() * @uses \MainWP\Dashboard\MainWP_Notification_Settings::get_site_email_settings() * @uses \MainWP\Dashboard\MainWP_Notification_Settings::get_default_emails_fields() * @uses \MainWP\Dashboard\MainWP_Utility::get_http_codes() */ public function start_notification_http_check( $plain_text ) { // phpcs:ignore -- NOSONAR - complex. $sitesHttpCheck = array(); $email_settings_sites = array(); $sites_offline = MainWP_DB::instance()->get_websites_http_check_status(); if ( is_array( $sites_offline ) && ! empty( $sites_offline ) ) { foreach ( $sites_offline as $site ) { if ( 200 === (int) $site->http_response_code || empty( $site->http_response_code ) ) { // to fix: ignored 200 http code. continue; } $email_settings_sites[ $site->id ] = $site->settings_notification_emails; // ok. $code = $site->http_response_code; $code_string = MainWP_Utility::get_http_codes( $code ); if ( ! empty( $code_string ) ) { $code .= ' - ' . $code_string; } $sitesHttpCheck[] = array( 'id' => $site->id, 'name' => $site->name, 'url' => $site->url, 'code' => $code, ); } } if ( empty( $sitesHttpCheck ) ) { return false; } $gen_settings = MainWP_Notification_Settings::get_general_email_settings( 'http_check' ); // general http check notificaion, to administrator. if ( ! $gen_settings['disable'] ) { MainWP_Notification::send_http_check_notification( $gen_settings, $sitesHttpCheck, $plain_text ); usleep( 100000 ); } $to_admin_HttpCheckWebsites = array(); // individual http check notification. foreach ( $sitesHttpCheck as $site ) { $website = new \stdClass(); $website->id = $site['id']; $website->url = $site['url']; $website->name = $site['name']; $website->settings_notification_emails = $email_settings_sites[ $site['id'] ]; // ok. $settings = MainWP_Notification_Settings::get_site_email_settings( 'http_check', $website ); // get site email settings. if ( ! $settings['disable'] ) { $to_admin_HttpCheckWebsites[] = $site; $sent = MainWP_Notification::send_http_check_notification( $settings, array( $site ), $plain_text, false ); if ( $sent ) { usleep( 100000 ); } } } // send all individual notice to admin in one email. if ( ! empty( $to_admin_HttpCheckWebsites ) ) { $admin_email_settings = MainWP_Notification_Settings::get_default_emails_fields( 'http_check', '', true ); // get default subject and heading only. $admin_email_settings['disable'] = 0; $admin_email_settings['recipients'] = ''; // sent to admin only. MainWP_Notification::send_http_check_notification( $admin_email_settings, $sitesHttpCheck, $plain_text ); } return true; } /** * Method cron_deactivated_licenses_alert() */ public function cron_deactivated_licenses_alert() { // phpcs:ignore -- NOSONAR - complex. $admin_email_settings = MainWP_Notification_Settings::get_default_emails_fields( 'deactivated_license_alert' ); if ( empty( $admin_email_settings['disable'] ) && ! empty( $admin_email_settings['recipients'] ) ) { $deactivated_licenses = MainWP_Extensions_Handler::get_indexed_extensions_infor( false, true ); if ( ! empty( $deactivated_licenses ) ) { $alerts_now = array(); foreach ( $deactivated_licenses as $slug => $info ) { if ( ! empty( $info['mainwp_version'] ) ) { // alert for versions 5 only. $alerted = MainWP_Utility::instance()->get_set_deactivated_licenses_alerted( $slug ); if ( empty( $alerted ) ) { $alerts_now[ $slug ] = $info; MainWP_Utility::instance()->get_set_deactivated_licenses_alerted( $slug, time(), 'set' ); } } } if ( ! empty( $alerts_now ) ) { $plain_text = get_option( 'mainwp_license_deactivated_alert_plain_text', false ); $filtered = apply_filters( 'mainwp_license_deactivated_alert_plain_text', $plain_text ); if ( $plain_text !== $filtered ) { $plain_text = $filtered; MainWP_Utility::update_option( 'mainwp_license_deactivated_alert_plain_text', $plain_text ); } MainWP_Notification::send_license_deactivated_alert( $admin_email_settings, $alerts_now, $plain_text ); MainWP_Utility::update_option( 'mainwp_cron_license_deactivated_alert_lasttime', time() ); } } } } /** * Method cron_ping_childs() * * Cron job to ping child sites. * * @uses \MainWP\Dashboard\MainWP_DB::query() * @uses \MainWP\Dashboard\MainWP_DB::get_sql_websites() * @uses \MainWP\Dashboard\MainWP_DB::fetch_object() * @uses \MainWP\Dashboard\MainWP_DB::free_result() * @uses \MainWP\Dashboard\MainWP_Logger::info() * @uses \MainWP\Dashboard\MainWP_Utility::update_option() * @uses \MainWP\Dashboard\MainWP_Utility::ends_with() */ public function cron_ping_childs() { MainWP_Logger::instance()->info( 'ping childs' ); $lastPing = get_option( 'mainwp_cron_last_ping' ); if ( false !== $lastPing && ( time() - $lastPing ) < ( 60 * 60 * 23 ) ) { return; } MainWP_Utility::update_option( 'mainwp_cron_last_ping', time() ); $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites() ); while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) { try { $url = $website->siteurl; if ( ! MainWP_Utility::ends_with( $url, '/' ) ) { $url .= '/'; } wp_remote_get( $url . 'wp-cron.php' ); } catch ( \Exception $e ) { // ok. } } MainWP_DB::free_result( $websites ); } /** * Method cron_backups_continue() * * Execute remaining backup tasks. * * @uses \MainWP\Dashboard\MainWP_DB_Backup::get_backup_tasks_to_complete() * @uses \MainWP\Dashboard\MainWP_DB_Backup::get_backup_task_by_id() * @uses \MainWP\Dashboard\MainWP_Logger::info() * @uses \MainWP\Dashboard\MainWP_Logger::debug() * @uses \MainWP\Dashboard\MainWP_Manage_Backups_Handler::execute_backup_task() * @uses \MainWP\Dashboard\MainWP_Utility::update_option() */ public function cron_backups_continue() { if ( ! get_option( 'mainwp_enableLegacyBackupFeature' ) ) { return; } MainWP_Logger::instance()->info( 'backups continue' ); ignore_user_abort( true ); MainWP_System_Utility::set_time_limit( 0 ); add_filter( 'admin_memory_limit', function () { return '512M'; } ); MainWP_Utility::update_option( 'mainwp_cron_last_backups_continue', time() ); $tasks = MainWP_DB_Backup::instance()->get_backup_tasks_to_complete(); MainWP_Logger::instance()->debug( 'backups continue :: Found ' . count( $tasks ) . ' to continue.' ); if ( empty( $tasks ) ) { return; } foreach ( $tasks as $task ) { MainWP_Logger::instance()->debug( 'backups continue :: Task: ' . $task->name ); } foreach ( $tasks as $task ) { $task = MainWP_DB_Backup::instance()->get_backup_task_by_id( $task->id ); if ( $task->completed < $task->last_run ) { MainWP_Manage_Backups_Handler::execute_backup_task( $task, 5, false ); break; } } } /** * Method cron_backups() * * Execute Backup Tasks. * * @uses \MainWP\Dashboard\MainWP_DB_Backup::get_backup_tasks_todo_daily() - NOSONAR todo name. * @uses \MainWP\Dashboard\MainWP_DB_Backup::get_backup_tasks_todo_weekly() - NOSONAR todo name. * @uses \MainWP\Dashboard\MainWP_DB_Backup::get_backup_tasks_todo_monthly() - NOSONAR todo name. * @uses \MainWP\Dashboard\MainWP_DB_Backup::get_backup_task_by_id() * @uses \MainWP\Dashboard\MainWP_Logger::info() * @uses \MainWP\Dashboard\MainWP_Logger::debug() * @uses \MainWP\Dashboard\MainWP_Manage_Backups::validate_backup_tasks() * @uses \MainWP\Dashboard\MainWP_Manage_Backups_Handler::execute_backup_task() * @uses \MainWP\Dashboard\MainWP_Utility::update_option() */ public function cron_backups() { // phpcs:ignore -- NOSONAR - complex. if ( ! get_option( 'mainwp_enableLegacyBackupFeature' ) ) { return; } MainWP_Logger::instance()->info( 'backups' ); ignore_user_abort( true ); MainWP_System_Utility::set_time_limit( 0 ); add_filter( 'admin_memory_limit', function () { return '512M'; } ); MainWP_Utility::update_option( 'mainwp_cron_last_backups', time() ); $allTasks = array(); $dailyTasks = MainWP_DB_Backup::instance()->get_backup_tasks_todo_daily(); if ( ! empty( $dailyTasks ) ) { $allTasks = $dailyTasks; } $weeklyTasks = MainWP_DB_Backup::instance()->get_backup_tasks_todo_weekly(); if ( ! empty( $weeklyTasks ) ) { $allTasks = array_merge( $allTasks, $weeklyTasks ); } $monthlyTasks = MainWP_DB_Backup::instance()->get_backup_tasks_todo_monthly(); if ( ! empty( $monthlyTasks ) ) { $allTasks = array_merge( $allTasks, $monthlyTasks ); } MainWP_Logger::instance()->debug( 'backups :: Found ' . count( $allTasks ) . ' to start.' ); foreach ( $allTasks as $task ) { MainWP_Logger::instance()->debug( 'backups :: Task: ' . $task->name ); } foreach ( $allTasks as $task ) { $threshold = 0; if ( 'daily' === $task->schedule ) { $threshold = ( 60 * 60 * 24 ); } elseif ( 'weekly' === $task->schedule ) { $threshold = ( 60 * 60 * 24 * 7 ); } elseif ( 'monthly' === $task->schedule ) { $threshold = ( 60 * 60 * 24 * 30 ); } $task = MainWP_DB_Backup::instance()->get_backup_task_by_id( $task->id ); if ( ( time() - $task->last_run ) < $threshold ) { continue; } if ( ! MainWP_Manage_Backups_Handler::validate_backup_tasks( array( $task ) ) ) { $task = MainWP_DB_Backup::instance()->get_backup_task_by_id( $task->id ); } $chunkedBackupTasks = get_option( 'mainwp_chunkedBackupTasks' ); MainWP_Manage_Backups_Handler::execute_backup_task( $task, ( 0 !== $chunkedBackupTasks ? 5 : 0 ) ); } } /** * Method cron_reconnect() * * Grab MainWP Cron Job Statistics. * * @uses \MainWP\Dashboard\MainWP_DB::query() * @uses \MainWP\Dashboard\MainWP_DB::get_websites_stats_update_sql() * @uses \MainWP\Dashboard\MainWP_DB::update_website_stats() * @uses \MainWP\Dashboard\MainWP_DB::fetch_object() * @uses \MainWP\Dashboard\MainWP_DB::free_result() * @uses \MainWP\Dashboard\MainWP_Logger::info() * @uses \MainWP\Dashboard\MainWP_Logger::info_for_website() * @uses \MainWP\Dashboard\MainWP_Logger::warning_for_website() * @uses \MainWP\Dashboard\MainWP_Manage_Sites_View::m_reconnect_site() * @uses \MainWP\Dashboard\MainWP_Utility::update_option() */ public function cron_reconnect() { MainWP_Logger::instance()->info( 'stats' ); MainWP_Utility::update_option( 'mainwp_cron_last_stats', time() ); $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_websites_stats_update_sql() ); $start = time(); while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) { if ( ( time() - $start ) > ( 60 * 60 * 2 ) ) { break; } MainWP_DB::instance()->update_website_stats( $website->id, time() ); if ( property_exists( $website, 'sync_errors' ) && '' !== $website->sync_errors ) { MainWP_Logger::instance()->info_for_website( $website, 'reconnect', 'Trying to reconnect' ); try { if ( MainWP_Manage_Sites_View::m_reconnect_site( $website ) ) { MainWP_Logger::instance()->info_for_website( $website, 'reconnect', 'Reconnected successfully' ); } } catch ( \Exception $e ) { MainWP_Logger::instance()->warning_for_website( $website, 'reconnect', $e->getMessage() ); } } sleep( 3 ); } MainWP_DB::free_result( $websites ); } /** * Method cron_check_websites_health() * * Cron job to check site health. * * @uses \MainWP\Dashboard\MainWP_Logger::info() * @uses \MainWP\Dashboard\MainWP_Utility::update_option() */ public function cron_check_websites_health() { // to disable if run custom cron. $disableChecking = get_option( 'mainwp_disableSitesHealthMonitoring', 1 ); // disabled by default. if ( $disableChecking ) { return; } MainWP_Logger::instance()->info( 'check sites health :: starting.' ); $plain_text = get_option( 'mainwp_daily_digest_plain_text', false ); $this->start_notification_sites_health( $plain_text ); MainWP_Logger::instance()->info( 'check sites health :: finished.' ); MainWP_Utility::update_option( 'mainwp_cron_checksiteshealth_last_timestamp', time() ); } /** * Method start_notification_sites_health(). * * Prepare sites health notification. * * @param bool $plain_text Text format value. * * @return bool True|False * * @uses \MainWP\Dashboard\MainWP_DB::get_websites_to_notice_health_threshold() * @uses \MainWP\Dashboard\MainWP_Logger::info() * @uses \MainWP\Dashboard\MainWP_Monitoring_Handler::notice_site_health_threshold() * @uses \MainWP\Dashboard\MainWP_Notification_Settings::get_general_email_settings() * @uses \MainWP\Dashboard\MainWP_Notification_Settings::get_site_email_settings() * @uses \MainWP\Dashboard\MainWP_Notification_Settings::get_default_emails_fields() */ public function start_notification_sites_health( $plain_text ) { $globalThreshold = get_option( 'mainwp_sitehealthThreshold', 80 ); $healthSites = MainWP_DB::instance()->get_websites_to_notice_health_threshold( $globalThreshold ); MainWP_Logger::instance()->info( 'check sites health :: notice site health :: found ' . ( $healthSites ? count( $healthSites ) : 0 ) ); if ( empty( $healthSites ) ) { return false; } $email = MainWP_Notification_Settings::get_general_email(); // general site health notifcation. $email_settings = MainWP_Notification_Settings::get_general_email_settings( 'site_health' ); if ( ! $email_settings['disable'] ) { // send to general email settings, one site in one email. MainWP_Monitoring_Handler::notice_site_health_threshold( $email_settings, $healthSites, $email, $plain_text ); } $to_admin_siteHealthWebsites = array(); // individual uptime notification. foreach ( $healthSites as $site ) { $email_settings = MainWP_Notification_Settings::get_site_email_settings( 'site_health', $site ); if ( $email_settings['disable'] ) { continue; // disabled notification for this site. } $to_admin_siteHealthWebsites[] = $site; // send to individual email settings, one site in one email. MainWP_Monitoring_Handler::notice_site_health_threshold( $email_settings, array( $site ), '', $plain_text, false ); // do not send to admin for individual sending. } if ( ! empty( $to_admin_siteHealthWebsites ) ) { $admin_email_settings = MainWP_Notification_Settings::get_default_emails_fields( 'site_health', '', true ); // get default subject and heading only. $admin_email_settings['disable'] = 0; $admin_email_settings['recipients'] = ''; // sent to admin only. // send to admin, all individual sites in one email. MainWP_Monitoring_Handler::notice_site_health_threshold( $admin_email_settings, $to_admin_siteHealthWebsites, $email, $plain_text, true, true ); } return true; } /** * Method cron_perform_general_process * * @return void */ public function cron_perform_general_process() { $this->perform_sequence_process(); } /** * Method perform_sequence_process * * @return void */ public function perform_sequence_process() { //phpcs:ignore -- NOSONAR - complexity. $register_process = apply_filters( 'mainwp_register_regular_sequence_process', array() ); $register_process = is_array( $register_process ) ? $register_process : array(); $valid_processes = array(); foreach ( $register_process as $name => $reg_process ) { if ( ! is_array( $reg_process ) || empty( $reg_process ) || ! is_string( $name ) || empty( $name ) ) { continue; } if ( $this->is_process_callable( $reg_process ) ) { $valid_processes[ $name ] = $reg_process; } } MainWP_Utility::array_sort( $valid_processes, 'priority', SORT_NUMERIC ); $managed_processes = array_values( $valid_processes ); // to fix. if ( empty( $managed_processes ) ) { return; } $count = count( $managed_processes ); $current_pid = (int) get_option( 'mainwp_regular_sequence_current_process_pid', 0 ); if ( $current_pid > $count ) { $current_pid = 0; } $process = isset( $managed_processes[ $current_pid ] ) ? $managed_processes[ $current_pid ] : array(); MainWP_Logger::instance()->log_events( 'regular-schedule', '[current_pid=' . $current_pid . ' :: [total=' . $count . '] :: [process=' . ( is_array($process) ? print_r($process, true ): '' ) . ']' ); //phpcs:ignore -- ok. $performed = false; while ( $current_pid <= $count ) { $callable = $this->is_process_callable( $process ); if ( ! empty( $callable ) && is_callable( $callable ) ) { $this->set_process_counter( ++$current_pid ); call_user_func( $callable ); $performed = true; MainWP_Logger::instance()->log_events( 'regular-schedule', 'Run process: [process=' . ( is_array($process) ? print_r($process, true ): '' ) . ']' ); //phpcs:ignore -- ok. } else { $this->set_process_counter( ++$current_pid ); } if ( $performed ) { break; // to run next schedule. } else { $process = isset( $managed_processes[ $current_pid ] ) ? $managed_processes[ $current_pid ] : false; if ( empty( $process ) ) { break; // to run next schedule. } } } } /** * Method set_process_counter(). * * @param int $counter_index Counter. * @return void */ public function set_process_counter( $counter_index ) { update_option( 'mainwp_regular_sequence_current_process_pid', $counter_index ); } /** * Method is_process_callable(). * * @param array $process The process. * @return mixed false|string|array callable. */ public function is_process_callable( $process ) { //phpcs:ignore -- NOSONAR - complex. if ( is_array( $process ) && ! empty( $process['callback'] ) && is_array( $process['callback'] ) ) { $class_name = ! empty( $process['callback'][0] ) ? $process['callback'][0] : ''; $method_name = ! empty( $process['callback'][1] ) ? $process['callback'][1] : ''; if ( ! empty( $class_name ) && ! empty( $method_name ) ) { if ( class_exists( $class_name ) ) { $call_inst = new $class_name(); $callback = array( $call_inst, $method_name ); if ( is_callable( $callback ) ) { return $callback; } } } elseif ( ! empty( $method_name ) && is_callable( $method_name ) ) { return $method_name; } } return false; } }