PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.2.2
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.2.2
6.2.2 6.2.1 6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 All 155 releases
mainwp / class / class-mainwp-system-cron-jobs.php

class-mainwp-system-cron-jobs.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies 6.2.2, at class/class-mainwp-system-cron-jobs.php

1,836 lines 82.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * MainWP System Cron Jobs.
4 *
5 * @package MainWP/Dashboard
6 */
7
8 namespace MainWP\Dashboard;
9
10 // Exit if accessed directly.
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit;
13 }
14
15 //phpcs:disable WordPress.WP.AlternativeFunctions -- for custom read/write file.
16
17 /**
18 * Class MainWP_System_Cron_Jobs
19 *
20 * @package MainWP\Dashboard
21 */
22 class MainWP_System_Cron_Jobs { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
23
24 /**
25 * Singleton.
26 *
27 * @var null $instance
28 */
29 private static $instance = null;
30
31 /**
32 * Last auto logging.
33 *
34 * @var int Last time auto logs.
35 */
36 public $last_auto_logging = null;
37
38 /**
39 * MainWP Cron Instance.
40 *
41 * @return self $instance
42 */
43 public static function instance() {
44 if ( null === static::$instance ) {
45 static::$instance = new self();
46 }
47
48 return static::$instance;
49 }
50
51 /**
52 * MainWP_System_Cron_Jobs constructor.
53 *
54 * Run each time the class is called.
55 */
56 public function __construct() {
57 }
58
59 /**
60 * Method init_cron_jobs()
61 *
62 * Instantiate Cron Jobs.
63 */
64 public function init_cron_jobs() {
65
66 /**
67 * Action: mainwp_cronload_action
68 *
69 * Hooks MainWP cron jobs actions.
70 *
71 * @since Unknown
72 */
73 do_action( 'mainwp_cronload_action' );
74
75 add_action( 'mainwp_cronreconnect_action', array( $this, 'cron_reconnect' ) );
76 add_action( 'mainwp_cronbackups_action', array( $this, 'cron_backups' ) );
77 add_action( 'mainwp_cronbackups_continue_action', array( $this, 'cron_backups_continue' ) );
78 add_action( 'mainwp_cronupdatescheck_action', array( $this, 'cron_updates_check' ) );
79 add_action( 'mainwp_cronpingchilds_action', array( $this, 'cron_ping_childs' ) );
80 add_action( 'mainwp_cronsitehealthcheck_action', array( $this, 'cron_check_websites_health' ) );
81 add_action( 'mainwp_crondeactivatedlicensesalert_action', array( $this, 'cron_deactivated_licenses_alert' ) );
82 add_action( 'mainwp_cronuptimemonitoringcheck_action', array( MainWP_Uptime_Monitoring_Schedule::instance(), 'cron_uptime_check' ) );
83 add_action( 'mainwp_cron_perform_general_process', array( $this, 'cron_perform_general_process' ) );
84 // Site URL correction runs inside the regular-sequence dispatcher so it
85 // works under both WP cron and server cron ( cron/generalschedules.php ).
86 add_filter( 'mainwp_register_regular_sequence_process', array( MainWP_Site_Url_Corrector::class, 'hook_regular_sequence_process' ) );
87
88 // API Setting tools.
89 add_action( 'mainwp_cron_disconnect_batch', array( \MainWP_Rest_Settings_Controller::instance(), 'process_disconnect_batch' ) );
90 add_action( 'mainwp_cron_renew_connection_batch', array( \MainWP_Rest_Settings_Controller::instance(), 'process_renew_connection_batch' ) );
91 add_action( 'mainwp_cron_destroy_session_batch', array( \MainWP_Rest_Settings_Controller::instance(), 'process_destroy_session_batch' ) );
92
93 // phpcs:ignore -- required for dashboard's minutely scheduled jobs.
94 add_filter( 'cron_schedules', array( $this, 'get_cron_schedules' ), 9 );
95
96 $this->init_cron();
97 }
98
99 /**
100 * Method get_cron_jobs()
101 *
102 * @return array Cron jobs list.
103 */
104 public function get_cron_jobs() {
105
106 // Check wether or not to use MainWP Cron false|1.
107 $useWPCron = ( get_option( 'mainwp_wp_cron' ) === false ) || ( (int) get_option( 'mainwp_wp_cron' ) === 1 );
108
109 // Default Cron Jobs.
110 $jobs = array(
111 'mainwp_cronreconnect_action' => 'hourly',
112 'mainwp_cronpingchilds_action' => 'daily',
113 'mainwp_cronupdatescheck_action' => 'minutely',
114 'mainwp_crondeactivatedlicensesalert_action' => 'daily',
115 'mainwp_cronuptimemonitoringcheck_action' => 'minutely',
116 'mainwp_cron_perform_general_process' => 'minutely',
117 );
118
119 if ( ! $useWPCron && ! get_option( 'mainwp_individual_uptime_monitoring_schedule_enabled' ) ) {
120 unset( $jobs['mainwp_cronuptimemonitoringcheck_action'] );
121 }
122
123 $disableHealthChecking = get_option( 'mainwp_disableSitesHealthMonitoring', 1 ); // disabled by default.
124 if ( ! $disableHealthChecking ) {
125 $jobs['mainwp_cronsitehealthcheck_action'] = 'hourly';
126 }
127
128 // Legacy Backup Cron jobs.
129 if ( get_option( 'mainwp_enableLegacyBackupFeature' ) ) {
130 $jobs = array_merge(
131 $jobs,
132 array(
133 'mainwp_cronbackups_action' => 'hourly',
134 'mainwp_cronbackups_continue_action' => '5minutely',
135 )
136 );
137 }
138
139 return $jobs;
140 }
141
142 /**
143 * Method init_cron()
144 *
145 * Build Cron Jobs Array & initiate via init_mainwp_cron()
146 */
147 public function init_cron() { //phpcs:ignore -- NOSONAR - complex.
148
149 // Check wether or not to use MainWP Cron false|1.
150 $useWPCron = ( get_option( 'mainwp_wp_cron' ) === false ) || ( (int) get_option( 'mainwp_wp_cron' ) === 1 );
151
152 $disableHealthChecking = get_option( 'mainwp_disableSitesHealthMonitoring', 1 ); // disabled by default.
153 if ( $disableHealthChecking ) {
154 // disable check sites health cron.
155 $sched = wp_next_scheduled( 'mainwp_cronsitehealthcheck_action' );
156 if ( false !== $sched ) {
157 wp_unschedule_event( $sched, 'mainwp_cronsitehealthcheck_action' );
158 }
159 }
160
161 // Legacy Backup Cron jobs.
162 if ( ! get_option( 'mainwp_enableLegacyBackupFeature' ) ) {
163 // Unset Cron Schedules.
164 $sched = wp_next_scheduled( 'mainwp_cronbackups_action' );
165 if ( $sched ) {
166 wp_unschedule_event( $sched, 'mainwp_cronbackups_action' );
167 }
168 $sched = wp_next_scheduled( 'mainwp_cronbackups_continue_action' );
169 if ( $sched ) {
170 wp_unschedule_event( $sched, 'mainwp_cronbackups_continue_action' );
171 }
172 }
173
174 $jobs = $this->get_cron_jobs();
175
176 /**
177 * Hook mainwp_get_cron_jobs_init.
178 *
179 * @since 5.5.
180 */
181 $jobs = apply_filters( 'mainwp_get_cron_jobs_init', $jobs, $useWPCron );
182
183 foreach ( $jobs as $hook => $recur ) {
184 $this->init_mainwp_cron( $useWPCron, $hook, $recur );
185 }
186 }
187
188 /**
189 * Method init_mainwp_cron()
190 *
191 * Schedual Cron Jobs.
192 *
193 * @param mixed $useWPCron Wether or not to use WP_Cron.
194 * @param mixed $cron_hook When cron is going to reoccur.
195 * @param mixed $recurrence Cron job hook.
196 */
197 public function init_mainwp_cron( $useWPCron, $cron_hook, $recurrence ) {
198 $sched = wp_next_scheduled( $cron_hook );
199 $enabled_job = apply_filters( 'mainwp_is_enable_schedule_job', $useWPCron, $cron_hook, $recurrence );
200 if ( false === $sched ) {
201 if ( $useWPCron && $enabled_job ) {
202 wp_schedule_event( time(), $recurrence, $cron_hook );
203 }
204 } elseif ( ! $useWPCron || ! $enabled_job ) {
205 wp_unschedule_event( $sched, $cron_hook );
206 }
207 }
208
209 /**
210 * Method cron_active()
211 *
212 * Check if WP_Cron is active.
213 *
214 * @return void
215 *
216 * @uses \MainWP\Dashboard\MainWP_System::$version
217 */
218 public function cron_active() {
219 session_write_close();
220 if ( ! headers_sent() ) {
221 header( 'Content-Type: text/html; charset=' . get_bloginfo( 'charset' ), true );
222 header( 'X-Robots-Tag: noindex, nofollow', true );
223 header( 'X-MainWP-Version: ' . MainWP_System::$version, true );
224 nocache_headers();
225 }
226 wp_die( 'MainWP Test' );
227 }
228
229
230 /**
231 * Method get_cron_schedules()
232 *
233 * Get current Cron Schedual.
234 *
235 * @param array $schedules Array of currently set scheduals.
236 *
237 * @return array $scheduales.
238 */
239 public function get_cron_schedules( $schedules ) {
240 $schedules['5minutely'] = array(
241 'interval' => 5 * 60,
242 'display' => esc_html__( 'Once every 5 minutes', 'mainwp' ),
243 );
244 $schedules['minutely'] = array(
245 'interval' => 1 * 60,
246 'display' => esc_html__( 'Once every minute', 'mainwp' ),
247 );
248
249 return $schedules;
250 }
251
252 /**
253 * Method get_timestamp_from_hh_mm()
254 *
255 * Get Time Stamp from $hh_mm.
256 *
257 * @param mixed $hh_mm Global time stamp variable.
258 * @param int $time Time of day.
259 *
260 * @return time Y-m-d 00:00:59.
261 */
262 public static function get_timestamp_from_hh_mm( $hh_mm, $time = false ) {
263 $hh_mm = explode( ':', $hh_mm );
264 $_hour = isset( $hh_mm[0] ) ? intval( $hh_mm[0] ) : 0;
265 $_mins = isset( $hh_mm[1] ) ? intval( $hh_mm[1] ) : 0;
266 if ( $_hour < 0 || $_hour > 23 ) {
267 $_hour = 0;
268 }
269 if ( $_mins < 0 || $_mins > 59 ) {
270 $_mins = 0;
271 }
272 if ( ! empty( $time ) ) {
273 $str_date = date( 'Y-m-d', $time ); // phpcs:ignore -- check update at given time.
274 } else {
275 $lctime = MainWP_Utility::get_timestamp();
276 $str_date = date( 'Y-m-d', $lctime ); // phpcs:ignore -- check update at local server time.
277 }
278 return strtotime( $str_date . ' ' . $_hour . ':' . $_mins . ':59' ); // phpcs:ignore -- check update at given time.
279 }
280
281 /**
282 * Method get_next_time_automatic_update_to_show()
283 *
284 * Get websites automatic update next time.
285 *
286 * @return mixed array
287 */
288 public static function get_next_time_automatic_update_to_show() {
289 // to calculate next_time.
290 static::instance()->check_conds_to_run_auto_update( $next_time, $run_timestamp, $frequence_period_in_seconds );
291 return $next_time;
292 }
293
294 /**
295 * Method check_conds_to_run_auto_update()
296 *
297 * To check conditionals to run auto update checking.
298 *
299 * @param int $next_time Next time to run.
300 * @param int $run_timestamp Runtime daily.
301 * @param int $frequence_in_seconds frequence running in seconds.
302 *
303 * @return bool Valid or not to run.
304 */
305 public function check_conds_to_run_auto_update( &$next_time, &$run_timestamp = false, &$frequence_in_seconds = false ) { //phpcs:ignore -- NOSONAR - complexity.
306 $local_timestamp = MainWP_Utility::get_timestamp();
307 $today_0h = strtotime( date("Y-m-d 00:00:00", $local_timestamp) ); // phpcs:ignore -- to localtime.
308
309 $timeDailyUpdate = get_option( 'mainwp_timeDailyUpdate' );
310
311 if ( ! empty( $timeDailyUpdate ) ) {
312 $run_timestamp = static::get_timestamp_from_hh_mm( $timeDailyUpdate );
313 } else {
314 $run_timestamp = $today_0h; // midnight.
315 }
316
317 $lasttimeScheStartAutoUpdate = (int) get_option( 'mainwp_updatescheck_start_last_timestamp', 0 );
318 $frequency_daily = (int) get_option( 'mainwp_frequencyDailyUpdate', 2 );
319
320 if ( $frequency_daily <= 0 ) {
321 $frequency_daily = 1;
322 }
323
324 if ( $frequency_daily > 1 ) {
325 $frequence_in_seconds = intval( DAY_IN_SECONDS / $frequency_daily );
326 if ( $frequence_in_seconds < 2 * HOUR_IN_SECONDS ) {
327 $frequence_in_seconds = 2 * HOUR_IN_SECONDS;
328 }
329 } else {
330 $frequence_in_seconds = DAY_IN_SECONDS - 1;
331 }
332
333 if ( $next_time < $run_timestamp ) {
334 $next_time = $run_timestamp;
335 }
336
337 // Adjust the runtime according to the runtime settings, in certain sudden cases.
338 // Apply at intervals of more than 2 hours.
339 if ( $frequence_in_seconds >= 2 * HOUR_IN_SECONDS && $local_timestamp < $next_time && $lasttimeScheStartAutoUpdate + $frequence_in_seconds > $next_time + HOUR_IN_SECONDS ) {
340 // Process it within the next scheduled run timeframe.
341 // make sure of this.
342 // The difference is more than 1 hour.
343 MainWP_Utility::update_option( 'mainwp_adjust_auto_sync_run_time', $next_time );
344 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 ) );
345 }
346
347 $adjust_run_time = get_option( 'mainwp_adjust_auto_sync_run_time' );
348 if ( ! empty( $adjust_run_time ) ) {
349 $next_time = $adjust_run_time;
350 } elseif ( $next_time < $lasttimeScheStartAutoUpdate + $frequence_in_seconds ) {
351 $next_time = $lasttimeScheStartAutoUpdate + $frequence_in_seconds;
352 }
353
354 if ( $next_time < $local_timestamp ) {
355 $next_time = $local_timestamp; // will run now.
356 if ( ! empty( $adjust_run_time ) ) {
357 delete_option( 'mainwp_adjust_auto_sync_run_time' ); // Adjusted the runtime.
358 }
359 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 ) );
360 } elseif ( $this->is_log_time() ) {
361 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 ) );
362 }
363
364 $check_to_run = false;
365
366 if ( $local_timestamp >= $next_time ) {
367 $check_to_run = true;
368 $next_time = $local_timestamp + $frequence_in_seconds; // to show next time.
369 }
370
371 return $check_to_run;
372 }
373
374 /**
375 * Method is_log_time().
376 */
377 public function is_log_time() {
378 if ( null === $this->last_auto_logging ) {
379 $this->last_auto_logging = get_option( 'mainwp_log_wait_lasttime', 0 ); // load last time logging.
380 }
381 $time = time();
382 // do not logging much in short time.
383 if ( $this->last_auto_logging + 5 * MINUTE_IN_SECONDS < $time ) {
384 MainWP_Utility::update_option( 'mainwp_log_wait_lasttime', $time ); //phpcs:ignore -- local time.
385 return true;
386 }
387 return false;
388 }
389
390 /**
391 * Method init_environment()
392 */
393 public function init_environment() {
394 ignore_user_abort( true );
395 MainWP_System_Utility::set_time_limit( 0 );
396 add_filter(
397 'admin_memory_limit',
398 function () {
399 return '512M';
400 }
401 );
402 }
403
404 /**
405 * Method update_auto_sync_time
406 *
407 * @param int $site_id site id.
408 * @return void
409 */
410 public function update_auto_sync_time( $site_id ) {
411 $websiteValues = array(
412 'dtsAutomaticSync' => MainWP_Utility::get_timestamp(),
413 );
414 MainWP_DB::instance()->update_website_sync_values( $site_id, $websiteValues );
415 }
416
417 /**
418 * Method cron_updates_check()
419 *
420 * MainWP Cron Check Update
421 *
422 * This Cron Checks to see if Automatic Daily Updates need to be performed.
423 *
424 * @uses \MainWP\Dashboard\MainWP_Backup_Handler::is_archive()
425 * @uses \MainWP\Dashboard\MainWP_Backup_Handler::backup()
426 * @uses \MainWP\Dashboard\MainWP_Backup_Handler::backup_download_file()
427 * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
428 * @uses \MainWP\Dashboard\MainWP_DB_Backup::backup_full_task_running()
429 * @uses \MainWP\Dashboard\MainWP_DB_Common::get_user_extension_by_user_id()
430 * @uses \MainWP\Dashboard\MainWP_DB::update_website_sync_values()
431 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
432 * @uses \MainWP\Dashboard\MainWP_DB::get_website_option()
433 * @uses \MainWP\Dashboard\MainWP_DB::update_website_option()
434 * @uses \MainWP\Dashboard\MainWP_Logger::info()
435 * @uses \MainWP\Dashboard\MainWP_Logger::debug()
436 * @uses \MainWP\Dashboard\MainWP_Notification_Settings::get_general_email_settings()
437 * @uses \MainWP\Dashboard\MainWP_Notification_Settings::get_site_email_settings()
438 * @uses \MainWP\Dashboard\MainWP_Notification_Settings::get_default_emails_fields()
439 * @uses \MainWP\Dashboard\MainWP_Sync::sync_site()
440 * @uses \MainWP\Dashboard\MainWP_Sync::get_wp_icon()
441 * @uses \MainWP\Dashboard\MainWP_System_Utility::get_wp_file_system()
442 * @uses \MainWP\Dashboard\MainWP_System_Utility::get_mainwp_specific_dir()
443 * @uses \MainWP\Dashboard\MainWP_Utility::get_timestamp()
444 * @uses \MainWP\Dashboard\MainWP_Utility::update_option()
445 */
446 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.
447
448 $this->init_environment();
449
450 // send http check notification.
451 if ( 1 === (int) get_option( 'mainwp_check_http_response', 0 ) ) {
452 $plain_text = get_option( 'mainwp_daily_digest_plain_text', false );
453 $this->start_notification_http_check( $plain_text );
454 }
455
456 $batch_updates_running = MainWP_Cron_Jobs_Batch::instance()->check_to_run_batch_updates();
457 if ( $batch_updates_running ) {
458 MainWP_Logger::instance()->log_events( 'debug-updates-crons', 'Start run - batch updates' );
459 MainWP_Cron_Jobs_Batch::instance()->handle_cron_batch_updates();
460 return;
461 } else {
462 $auto_updates_running = MainWP_Cron_Jobs_Auto_Updates::instance()->check_to_run_auto_updates();
463 if ( $auto_updates_running ) {
464 MainWP_Cron_Jobs_Auto_Updates::instance()->handle_cron_auto_updates();
465 return;
466 }
467 }
468
469 $updatecheck_running = ( 'Y' === get_option( 'mainwp_updatescheck_is_running' ) ? true : false );
470
471 $local_timestamp = MainWP_Utility::get_timestamp();
472
473 $frequencyDailyUpdate = (int) get_option( 'mainwp_frequencyDailyUpdate', 2 );
474 if ( $frequencyDailyUpdate <= 0 ) {
475 $frequencyDailyUpdate = 1;
476 }
477
478 $today_m_y = date( 'd/m/Y', $local_timestamp ); //phpcs:ignore -- local time.
479
480 $lasttimeAutomaticUpdate = get_option( 'mainwp_updatescheck_last_timestamp' );
481 $lasttimeDailyDigest = get_option( 'mainwp_updatescheck_dailydigest_last_timestamp' );
482 $mainwpLastDailydigest = get_option( 'mainwp_dailydigest_last' );
483
484 /**
485 * Filter: mainwp_updatescheck_sendmail_at_time
486 *
487 * Filters the the time when the Daily Digest email will be sent.
488 *
489 * @since 3.4
490 */
491 $send_noti_at = apply_filters( 'mainwp_updatescheck_sendmail_at_time', false );
492 $time_to_noti = false;
493 $time_notice_at = false;
494 if ( ! empty( $send_noti_at ) ) {
495 $send_timestamp = static::get_timestamp_from_hh_mm( $send_noti_at, $lasttimeDailyDigest );
496 $time_notice_at = $local_timestamp > $send_timestamp ? true : false;
497 } elseif ( 1 < $frequencyDailyUpdate ) {
498 $time_to_noti = ( $today_m_y !== $mainwpLastDailydigest ) ? true : false;
499 }
500 $sendmail_for_each_auto_sync = apply_filters( 'mainwp_updatescheck_sendmail_for_each_auto_sync_finished', false );
501
502 $check_ready_sendmail = false;
503 if ( $sendmail_for_each_auto_sync || 1 === (int) $frequencyDailyUpdate || $time_notice_at || $time_to_noti ) {
504 $check_ready_sendmail = true;
505 }
506
507 if ( $check_ready_sendmail && 'Y' === get_option( 'mainwp_updatescheck_ready_sendmail' ) ) {
508
509 $plain_text = get_option( 'mainwp_daily_digest_plain_text', false );
510
511 MainWP_Utility::update_option( 'mainwp_dailydigest_last', $today_m_y );
512
513 MainWP_Utility::update_option( 'mainwp_updatescheck_dailydigest_last_timestamp', $local_timestamp );
514
515 // send daily digest email one time per day.
516 $individual_digestWebsites = get_option( 'mainwp_updatescheck_individual_digest_websites' );
517
518 MainWP_Utility::update_option( 'mainwp_updatescheck_ready_sendmail', '' ); // here to fix.
519
520 MainWP_Logger::instance()->log_update_check( 'got to the daily digest mail part' );
521
522 $gen_email_settings = MainWP_Notification_Settings::get_general_email_settings( 'daily_digest' );
523 if ( empty( $gen_email_settings['disable'] ) ) {
524 // send general daily digests.
525 $this->start_notification_daily_digest( $gen_email_settings, $plain_text ); // general email.
526 }
527
528 $to_admin_digestWebsites = array();
529
530 if ( is_array( $individual_digestWebsites ) && ! empty( $individual_digestWebsites ) ) {
531 // send individual site daily digests, one email for one site.
532 foreach ( $individual_digestWebsites as $siteid ) {
533 $website = MainWP_DB::instance()->get_website_by_id( $siteid, false, array( 'settings_notification_emails' ) );
534 $email_settings = MainWP_Notification_Settings::get_site_email_settings( 'daily_digest', $website ); // get site email settings.
535 if ( ! $email_settings['disable'] ) {
536 $to_admin_digestWebsites[] = $siteid;
537 $sent = $this->start_notification_daily_digest( $email_settings, $plain_text, array( $siteid ), $website );
538 if ( $sent ) {
539 usleep( 100000 );
540 }
541 }
542 }
543 }
544
545 if ( ! empty( $to_admin_digestWebsites ) ) {
546 $admin_email_settings = MainWP_Notification_Settings::get_default_emails_fields( 'daily_digest', '', true ); // get default subject and heading only.
547 $admin_email_settings['disable'] = 0;
548 $admin_email_settings['recipients'] = MainWP_Notification_Settings::get_general_email(); // sent to general notification email only.
549 // send all individual daily digest to admin in one email.
550 $this->start_notification_daily_digest( $admin_email_settings, $plain_text, $to_admin_digestWebsites ); // will send email to general notification email.
551 }
552 $this->refresh_saved_fields();
553 }
554
555 $valid_to_run = $this->check_conds_to_run_auto_update( $next_time, $run_timestamp, $frequence_period_in_seconds );
556
557 /**
558 * Filter: mainwp_updatescheck_hours_interval
559 *
560 * Filters the status check interval.
561 *
562 * @since 3.4
563 */
564 $hoursIntervalAutomaticUpdate = apply_filters( 'mainwp_updatescheck_hours_interval', false );
565
566 $manual_trigger_last_timestamp = 0;
567
568 $manual_trigger_start = get_option( 'mainwp_auto_sync_manual_trigger_start_last_timestamp' );
569
570 if ( ! empty( $manual_trigger_start ) ) {
571 if ( is_numeric( $manual_trigger_start ) ) {
572 $manual_trigger_last_timestamp = intval( $manual_trigger_start ); // timestamp value.
573 } elseif ( is_string( $manual_trigger_start ) ) {
574 $manual_trigger_last_timestamp = strtotime( $manual_trigger_start ); // Y-m-d H:i:S format.
575 }
576 }
577
578 if ( ! $updatecheck_running ) {
579 $run_auto_checks = false;
580 $run_hours_interval = null;
581 if ( $hoursIntervalAutomaticUpdate > 0 ) {
582 $run_hours_interval = false;
583 if ( $lasttimeAutomaticUpdate && ( $lasttimeAutomaticUpdate + $hoursIntervalAutomaticUpdate * 3600 > $local_timestamp ) ) {
584 MainWP_Logger::instance()->log_update_check( 'updates check :: already updated hours interval' );
585 } else {
586 $run_hours_interval = true;
587 }
588 }
589
590 if ( $run_hours_interval || ( null === $run_hours_interval && $valid_to_run ) ) { // if not set sync time, and run frequency.
591 $run_auto_checks = true;
592 }
593
594 if ( $manual_trigger_last_timestamp ) {
595 $run_auto_checks = true;
596 }
597
598 if ( ! $run_auto_checks ) {
599 if ( $this->is_log_time() ) {
600 MainWP_Logger::instance()->log_update_check( 'updates check :: wait frequency today :: [frequencyDailyUpdate=' . $frequencyDailyUpdate . '] :: [frequence=' . gmdate( 'H:i:s', $frequence_period_in_seconds ) . ']' );
601 }
602 return;
603 }
604 }
605
606 $lasttimeStartAutomaticUpdate = get_option( 'mainwp_updatescheck_start_last_timestamp' );
607
608 // not batch updates run at the moment.
609 if ( ! $updatecheck_running ) {
610
611 if ( ! $manual_trigger_last_timestamp ) {
612 // do not update if manual trigger.
613 MainWP_Utility::update_option( 'mainwp_updatescheck_start_last_timestamp', $local_timestamp ); // start new update checking.
614 $lasttimeStartAutomaticUpdate = $local_timestamp;
615 } else {
616 $lasttimeStartAutomaticUpdate = $manual_trigger_last_timestamp;
617 }
618
619 MainWP_Utility::update_option( 'mainwp_updatescheck_is_running', 'Y' );
620
621 // log last run.
622 $last_run = get_option( 'mainwp_updatescheck_last_run' );
623 if ( $last_run ) {
624 $last_run = json_decode( $last_run );
625 }
626 if ( ! is_array( $last_run ) ) {
627 $last_run = array();
628 }
629
630 if ( count( $last_run ) > 20 ) {
631 array_shift( $last_run );
632 }
633
634 $last_run[] = date( 'Y-m-d H:i:s', $local_timestamp ); //phpcs:ignore -- local time.
635
636 MainWP_Utility::update_option( 'mainwp_updatescheck_last_run', wp_json_encode( $last_run ) );
637
638 if ( $local_timestamp > $run_timestamp && $local_timestamp < $run_timestamp + $frequence_period_in_seconds && $frequencyDailyUpdate > 1 ) {
639 $last_run_timestamp_today = $run_timestamp + $frequence_period_in_seconds * ( $frequencyDailyUpdate - 1 );
640 MainWP_Utility::update_option( 'mainwp_updatescheck_last_run_timestamp_today', $last_run_timestamp_today );
641 }
642 $this->refresh_saved_fields();
643
644 $log_lastsstart = ! empty( $lasttimeStartAutomaticUpdate ) ? '[lasttimeStartAutomaticUpdate=' . MainWP_Utility::format_timestamp( $lasttimeStartAutomaticUpdate ) . ']' : '';
645 MainWP_Logger::instance()->log_update_check( 'Start automatic check updates :: ' . $log_lastsstart );
646 }
647
648 $websites = array();
649 $checkupdate_websites = MainWP_Auto_Updates_DB::instance()->get_websites_check_updates( 4, $lasttimeStartAutomaticUpdate ); // to sync sites data.
650
651 foreach ( $checkupdate_websites as $website ) {
652 if ( ! MainWP_DB_Backup::instance()->backup_full_task_running( $website->id ) ) {
653 $websites[] = $website;
654 }
655 }
656 MainWP_Logger::instance()->info( 'updates check found ' . count( $checkupdate_websites ) . ' websites' );
657 MainWP_Logger::instance()->log_update_check( 'updates check found [' . count( $checkupdate_websites ) . ' websites] :: going to check [' . count( $websites ) . ' websites]' );
658
659 $userid = null;
660 foreach ( $websites as $website ) {
661 $websiteValues = array(
662 'dtsAutomaticSyncStart' => $local_timestamp,
663 );
664 if ( null === $userid ) {
665 $userid = $website->userid;
666 }
667
668 MainWP_DB::instance()->update_website_sync_values( $website->id, $websiteValues );
669 }
670
671 $plain_text = get_option( 'mainwp_daily_digest_plain_text', false );
672
673 /**
674 * Filter: mainwp_text_format_email
675 *
676 * Filters whether the email shuld bein plain text format.
677 *
678 * @since 3.5
679 */
680 $filter_plain_text = apply_filters( 'mainwp_text_format_email', $plain_text );
681
682 if ( $plain_text !== $filter_plain_text ) {
683 $plain_text = $filter_plain_text;
684 MainWP_Utility::update_option( 'mainwp_daily_digest_plain_text', $plain_text );
685 }
686
687 if ( empty( $checkupdate_websites ) ) {
688 $busyCounter = MainWP_Auto_Updates_DB::instance()->get_websites_count_where_dts_automatic_sync_smaller_then_start( $lasttimeStartAutomaticUpdate );
689 if ( ! empty( $busyCounter ) ) {
690 MainWP_Logger::instance()->log_update_check( 'busy counter :: found ' . $busyCounter . ' websites' );
691 $lastAutomaticUpdate = MainWP_Auto_Updates_DB::instance()->get_websites_last_automatic_sync();
692 if ( ( time() - $lastAutomaticUpdate ) < HOUR_IN_SECONDS ) {
693 MainWP_Logger::instance()->log_update_check( 'Automatic check updates last time :: ' . MainWP_Utility::format_timestamp( $lastAutomaticUpdate ) );
694 }
695 }
696
697 if ( $manual_trigger_last_timestamp ) {
698 // finished manual trigger auto sync.
699 delete_option( 'mainwp_auto_sync_manual_trigger_start_last_timestamp' );
700 MainWP_Logger::instance()->log_update_check( 'Manual trigger for automatic synchronization of all sites completed.' );
701 } else {
702 MainWP_Logger::instance()->log_update_check( 'Automatic sync of all sites completed.' );
703 }
704
705 if ( $updatecheck_running ) {
706 MainWP_Utility::update_option( 'mainwp_updatescheck_is_running', '' );
707 $updatecheck_running = false;
708 do_action( 'mainwp_synced_all_sites' );
709 }
710
711 update_option( 'mainwp_last_synced_all_sites', time() );
712 MainWP_Utility::update_option( 'mainwp_updatescheck_last_timestamp', $local_timestamp );
713
714 MainWP_Utility::update_option( 'mainwp_updatescheck_last', $today_m_y );
715
716 if ( 'Y' !== get_option( 'mainwp_updatescheck_ready_sendmail' ) ) {
717 MainWP_Utility::update_option( 'mainwp_updatescheck_ready_sendmail', 'Y' );
718 }
719 } else {
720
721 $userExtension = MainWP_DB_Common::instance()->get_user_extension_by_user_id( $userid );
722
723 $decodedIgnoredCores = ! empty( $userExtension->ignored_wp_upgrades ) ? json_decode( $userExtension->ignored_wp_upgrades, true ) : array();
724 $decodedIgnoredPlugins = json_decode( $userExtension->ignored_plugins, true );
725 $trustedPlugins = json_decode( $userExtension->trusted_plugins, true );
726 $decodedIgnoredThemes = json_decode( $userExtension->ignored_themes, true );
727 $trustedThemes = json_decode( $userExtension->trusted_themes, true );
728
729 if ( ! is_array( $decodedIgnoredCores ) ) {
730 $decodedIgnoredCores = array();
731 }
732
733 if ( ! is_array( $decodedIgnoredPlugins ) ) {
734 $decodedIgnoredPlugins = array();
735 }
736
737 if ( ! is_array( $trustedPlugins ) ) {
738 $trustedPlugins = array();
739 }
740
741 if ( ! is_array( $decodedIgnoredThemes ) ) {
742 $decodedIgnoredThemes = array();
743 }
744
745 if ( ! is_array( $trustedThemes ) ) {
746 $trustedThemes = array();
747 }
748
749 $coreToUpdate = array();
750 $coreNewUpdate = array();
751 $ignoredCoreToUpdate = array();
752 $ignoredCoreNewUpdate = array();
753
754 $pluginsToUpdate = array();
755 $pluginsNewUpdate = array();
756 $notTrustedPluginsToUpdate = array();
757 $notTrustedPluginsNewUpdate = array();
758
759 $themesToUpdate = array();
760 $themesNewUpdate = array();
761 $notTrustedThemesToUpdate = array();
762 $notTrustedThemesNewUpdate = array();
763
764 $transToUpdate = array();
765 $transNewUpdate = array();
766 $notTrustedTransToUpdate = array();
767 $notTrustedTransNewUpdate = array();
768
769 $individualDailyDigestWebsites = array();
770
771 $updatescheckSitesIcon = get_option( 'mainwp_updatescheck_sites_icon' );
772 if ( ! is_array( $updatescheckSitesIcon ) ) {
773 $updatescheckSitesIcon = array();
774 }
775
776 $delay_autoupdate = get_option( 'mainwp_delay_autoupdate', 1 );
777
778 foreach ( $websites as $website ) {
779 $websiteDecodedIgnoredPlugins = json_decode( $website->ignored_plugins, true );
780 if ( ! is_array( $websiteDecodedIgnoredPlugins ) ) {
781 $websiteDecodedIgnoredPlugins = array();
782 }
783
784 $websiteDecodedIgnoredThemes = json_decode( $website->ignored_themes, true );
785 if ( ! is_array( $websiteDecodedIgnoredThemes ) ) {
786 $websiteDecodedIgnoredThemes = array();
787 }
788
789 $synced = MainWP_Sync::sync_site( $website, false, true );
790
791 $this->update_auto_sync_time( $website->id );
792
793 if ( ! $synced ) {
794 MainWP_Logger::instance()->log_update_check( 'auto sync failed :: [siteid=' . $website->id . ']' );
795 continue;
796 }
797
798 MainWP_Logger::instance()->log_update_check( 'auto sync success :: [siteid=' . $website->id . ']' );
799
800 $website = MainWP_DB::instance()->get_website_by_id( $website->id, false, array( 'wp_upgrades', 'ignored_wp_upgrades', 'last_wp_upgrades' ) );
801
802 $check_individual_digest = false;
803
804 /** Check core updates * */
805 $websiteLastCoreUpgrades = ! empty( $website->last_wp_upgrades ) ? json_decode( $website->last_wp_upgrades, true ) : array();
806 $websiteCoreUpgrades = ! empty( $website->wp_upgrades ) ? json_decode( $website->wp_upgrades, true ) : array();
807 $website_decodedIgnoredCores = ! empty( $website->ignored_wp_upgrades ) ? json_decode( $website->ignored_wp_upgrades, true ) : array();
808
809 $websiteCoreUpdateCheck = 0;
810 $websitePluginsUpdateCheck = array();
811 $websiteThemesUpdateCheck = array();
812 $websiteTransUpdateCheck = array();
813
814 if ( ! empty( $delay_autoupdate ) ) {
815 $websiteCoreUpdateCheck = MainWP_DB::instance()->get_website_option( $website, 'core_update_check' );
816 $websitePluginsUpdateCheck = MainWP_DB::instance()->get_website_option( $website, 'plugins_update_check' );
817 $websiteThemesUpdateCheck = MainWP_DB::instance()->get_website_option( $website, 'themes_update_check' );
818 $websiteTransUpdateCheck = MainWP_DB::instance()->get_website_option( $website, 'trans_update_check' );
819
820 $websiteCoreUpdateCheck = intval( $websiteCoreUpdateCheck );
821 $websitePluginsUpdateCheck = ! empty( $websitePluginsUpdateCheck ) ? json_decode( $websitePluginsUpdateCheck, true ) : array();
822 $websiteThemesUpdateCheck = ! empty( $websiteThemesUpdateCheck ) ? json_decode( $websiteThemesUpdateCheck, true ) : array();
823 $websiteTransUpdateCheck = ! empty( $websiteTransUpdateCheck ) ? json_decode( $websiteTransUpdateCheck, true ) : array();
824
825 if ( ! is_array( $websitePluginsUpdateCheck ) ) {
826 $websitePluginsUpdateCheck = array();
827 }
828
829 if ( ! is_array( $websiteThemesUpdateCheck ) ) {
830 $websiteThemesUpdateCheck = array();
831 }
832
833 if ( ! is_array( $websiteTransUpdateCheck ) ) {
834 $websiteTransUpdateCheck = array();
835 }
836 }
837
838 if ( isset( $websiteCoreUpgrades['current'] ) ) {
839 $newUpdate = ! ( isset( $websiteLastCoreUpgrades['current'] ) && ( $websiteLastCoreUpgrades['current'] === $websiteCoreUpgrades['current'] ) && ( $websiteLastCoreUpgrades['new'] === $websiteCoreUpgrades['new'] ) );
840 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' ) ) {
841 $check_individual_digest = true;
842 $item = array(
843 'id' => $website->id,
844 'name' => $website->name,
845 'url' => $website->url,
846 'current' => $websiteCoreUpgrades['current'],
847 'new_version' => $websiteCoreUpgrades['new'],
848 );
849 if ( ! empty( $website->automatic_update ) && 1 === (int) $website->automatic_update ) {
850 $item['trusted'] = 1;
851 if ( $newUpdate ) {
852 $item['new'] = 1;
853 $coreNewUpdate[] = $item;
854 $websiteCoreUpdateCheck = time();
855 } else {
856 $item['new'] = 0;
857 $coreToUpdate[] = $item;
858 if ( empty( $websiteCoreUpdateCheck ) && ! empty( $delay_autoupdate ) ) {
859 $websiteCoreUpdateCheck = time();
860 }
861 }
862 } else {
863 $item['trusted'] = 0;
864 if ( $newUpdate ) {
865 $item['new'] = 1;
866 $ignoredCoreNewUpdate[] = $item;
867 } else {
868 $item['new'] = 0;
869 $ignoredCoreToUpdate[] = $item;
870 }
871 $websiteCoreUpdateCheck = 0;
872 }
873 }
874 }
875
876 /** Check plugins * */
877 $websiteLastPlugins = MainWP_DB::instance()->get_website_option( $website, 'last_plugin_upgrades' );
878 $websiteLastPlugins = ! empty( $websiteLastPlugins ) ? json_decode( $websiteLastPlugins, true ) : array();
879
880 $websitePlugins = json_decode( $website->plugin_upgrades, true );
881
882 /** Check themes * */
883 $websiteLastThemes = MainWP_DB::instance()->get_website_option( $website, 'last_theme_upgrades' );
884 $websiteLastThemes = ! empty( $websiteLastThemes ) ? json_decode( $websiteLastThemes, true ) : array();
885
886 $websiteThemes = json_decode( $website->theme_upgrades, true );
887
888 /** Check translations * */
889 $websiteLastTrans = MainWP_DB::instance()->get_website_option( $website, 'last_trans_upgrades' );
890 $websiteLastTrans = ! empty( $websiteLastTrans ) ? json_decode( $websiteLastTrans, true ) : array();
891
892 $websiteTrans = json_decode( $website->translation_upgrades, true );
893
894 $decodedPremiumUpgrades = MainWP_DB::instance()->get_website_option( $website, 'premium_upgrades' );
895 $decodedPremiumUpgrades = ! empty( $decodedPremiumUpgrades ) ? json_decode( $decodedPremiumUpgrades, true ) : array();
896
897 if ( is_array( $decodedPremiumUpgrades ) ) {
898 foreach ( $decodedPremiumUpgrades as $slug => $premiumUpgrade ) {
899 if ( 'plugin' === $premiumUpgrade['type'] ) {
900 if ( ! is_array( $websitePlugins ) ) {
901 $websitePlugins = array();
902 }
903 $websitePlugins[ $slug ] = $premiumUpgrade;
904 } elseif ( 'theme' === $premiumUpgrade['type'] ) {
905 if ( ! is_array( $websiteThemes ) ) {
906 $websiteThemes = array();
907 }
908 $websiteThemes[ $slug ] = $premiumUpgrade;
909 }
910 }
911 }
912
913 foreach ( $websitePlugins as $pluginSlug => $pluginInfo ) {
914 if ( $website->is_ignorePluginUpdates ) {
915 continue;
916 }
917
918 if ( MainWP_Common_Functions::instance()->is_ignored_updates( $pluginInfo, $decodedIgnoredPlugins, 'plugin' ) || MainWP_Common_Functions::instance()->is_ignored_updates( $pluginInfo, $websiteDecodedIgnoredPlugins, 'plugin' ) ) {
919 continue;
920 }
921
922 $check_individual_digest = true;
923
924 $change_log = '';
925 if ( isset( $pluginInfo['update']['url'] ) && ( false !== strpos( $pluginInfo['update']['url'], 'wordpress.org/plugins' ) ) ) {
926 $change_log = $pluginInfo['update']['url'];
927 if ( substr( $change_log, - 1 ) !== '/' ) {
928 $change_log .= '/';
929 }
930 $change_log .= '#developers';
931 }
932
933 $item = array(
934 'id' => $website->id,
935 'name' => $website->name,
936 'url' => $website->url,
937 'plugin' => $pluginInfo['Name'],
938 'current' => $pluginInfo['Version'],
939 'new_version' => $pluginInfo['update']['new_version'],
940 'change_log' => $change_log,
941 'slug' => $pluginSlug,
942 );
943
944 $newUpdate = ! ( isset( $websiteLastPlugins[ $pluginSlug ] ) && ( $pluginInfo['Version'] === $websiteLastPlugins[ $pluginSlug ]['Version'] ) && ( $pluginInfo['update']['new_version'] === $websiteLastPlugins[ $pluginSlug ]['update']['new_version'] ) );
945 if ( in_array( $pluginSlug, $trustedPlugins ) ) {
946 $item['trusted'] = 1;
947 if ( $newUpdate ) {
948 $item['new'] = 1;
949 $pluginsNewUpdate[] = $item;
950 if ( ! empty( $delay_autoupdate ) ) {
951 $websitePluginsUpdateCheck[ $pluginSlug ] = time();
952 }
953 } else {
954 $item['new'] = 0;
955 $pluginsToUpdate[] = $item;
956 $check_timestamp = isset( $websitePluginsUpdateCheck[ $pluginSlug ] ) ? $websitePluginsUpdateCheck[ $pluginSlug ] : 0;
957 if ( ! empty( $delay_autoupdate ) && empty( $check_timestamp ) ) {
958 $websitePluginsUpdateCheck[ $pluginSlug ] = time();
959 }
960 }
961 } else {
962 $item['trusted'] = 0;
963 if ( $newUpdate ) {
964 $item['new'] = 1;
965 $notTrustedPluginsNewUpdate[] = $item;
966 } else {
967 $item['new'] = 0;
968 $notTrustedPluginsToUpdate[] = $item;
969 }
970 if ( isset( $websitePluginsUpdateCheck[ $pluginSlug ] ) ) {
971 unset( $websitePluginsUpdateCheck[ $pluginSlug ] );
972 }
973 }
974 }
975
976 foreach ( $websiteThemes as $themeSlug => $themeInfo ) {
977
978 if ( $website->is_ignoreThemeUpdates ) {
979 continue;
980 }
981
982 if ( MainWP_Common_Functions::instance()->is_ignored_updates( $themeInfo, $decodedIgnoredThemes, 'theme' ) || MainWP_Common_Functions::instance()->is_ignored_updates( $themeInfo, $websiteDecodedIgnoredThemes, 'theme' ) ) {
983 continue;
984 }
985
986 $check_individual_digest = true;
987
988 $newUpdate = ! ( isset( $websiteLastThemes[ $themeSlug ] ) && ( $themeInfo['Version'] === $websiteLastThemes[ $themeSlug ]['Version'] ) && ( $themeInfo['update']['new_version'] === $websiteLastThemes[ $themeSlug ]['update']['new_version'] ) );
989
990 $item = array(
991 'id' => $website->id,
992 'name' => $website->name,
993 'url' => $website->url,
994 'theme' => $themeInfo['Name'],
995 'current' => $themeInfo['Version'],
996 'new_version' => $themeInfo['update']['new_version'],
997 'slug' => $themeSlug,
998 );
999
1000 if ( in_array( $themeSlug, $trustedThemes ) ) {
1001 $item['trusted'] = 1;
1002 if ( $newUpdate ) {
1003 $item['new'] = 1;
1004 $themesNewUpdate[] = $item;
1005 if ( ! empty( $delay_autoupdate ) ) {
1006 $websiteThemesUpdateCheck[ $themeSlug ] = time();
1007 }
1008 } else {
1009 $item['new'] = 0;
1010 $check_timestamp = isset( $websiteThemesUpdateCheck[ $themeSlug ] ) ? $websiteThemesUpdateCheck[ $themeSlug ] : 0;
1011 if ( empty( $check_timestamp ) && ! empty( $delay_autoupdate ) ) {
1012 $websiteThemesUpdateCheck[ $themeSlug ] = time();
1013 }
1014 $themesToUpdate[] = $item;
1015 }
1016 } else {
1017 $item['trusted'] = 0;
1018 if ( $newUpdate ) {
1019 $item['new'] = 1;
1020 $notTrustedThemesNewUpdate[] = $item;
1021 } else {
1022 $item['new'] = 0;
1023 $notTrustedThemesToUpdate[] = $item;
1024 }
1025 if ( isset( $websiteThemesUpdateCheck[ $themeSlug ] ) ) {
1026 unset( $websiteThemesUpdateCheck[ $themeSlug ] );
1027 }
1028 }
1029 }
1030
1031 foreach ( $websiteTrans as $transSlug => $transInfo ) {
1032
1033 $check_individual_digest = true;
1034
1035 $newUpdate = ! isset( $websiteLastTrans[ $transSlug ] );
1036
1037 $item = array(
1038 'id' => $website->id,
1039 'name' => $website->name,
1040 'url' => $website->url,
1041 'translation' => $transInfo['name'],
1042 'version' => $transInfo['version'],
1043 'slug' => $transInfo['slug'],
1044 );
1045
1046 if ( MainWP_Manage_Sites_Update_View::is_trans_trusted_update( $transInfo, $trustedPlugins, $trustedThemes ) ) {
1047 $item['trusted'] = 1;
1048 if ( $newUpdate ) {
1049 $item['new'] = 1;
1050 $transNewUpdate[] = $item;
1051 if ( ! empty( $delay_autoupdate ) ) {
1052 $websiteTransUpdateCheck[ $transSlug ] = time();
1053 }
1054 } else {
1055 $item['new'] = 0;
1056 $check_timestamp = isset( $websiteTransUpdateCheck[ $transSlug ] ) ? $websiteTransUpdateCheck[ $transSlug ] : 0;
1057 if ( empty( $check_timestamp ) && ! empty( $delay_autoupdate ) ) {
1058 $websiteTransUpdateCheck[ $transSlug ] = time();
1059 }
1060 $transToUpdate[] = $item;
1061 }
1062 } else {
1063 $item['trusted'] = 0;
1064 if ( $newUpdate ) {
1065 $item['new'] = 1;
1066 $notTrustedTransNewUpdate[] = $item;
1067 } else {
1068 $item['new'] = 0;
1069 $notTrustedTransToUpdate[] = $item;
1070 }
1071 if ( isset( $websiteTransUpdateCheck[ $transSlug ] ) ) {
1072 unset( $websiteTransUpdateCheck[ $transSlug ] );
1073 }
1074 }
1075 }
1076
1077 /**
1078 * Action: mainwp_daily_digest_action
1079 *
1080 * Hooks the daily digest email notification send process.
1081 *
1082 * @param object $website Object conaining child site info.
1083 * @param bool $plain_text Whether plain text email should be sent.
1084 *
1085 * @since 4.1
1086 */
1087 do_action( 'mainwp_daily_digest_action', $website, $plain_text );
1088 MainWP_DB::instance()->update_website_sync_values( $website->id, array( 'dtsAutomaticSync' => $local_timestamp ) );
1089 MainWP_DB::instance()->update_website_option( $website, 'last_wp_upgrades', wp_json_encode( $websiteCoreUpgrades ) );
1090 MainWP_DB::instance()->update_website_option( $website, 'last_plugin_upgrades', $website->plugin_upgrades );
1091 MainWP_DB::instance()->update_website_option( $website, 'last_theme_upgrades', $website->theme_upgrades );
1092 MainWP_DB::instance()->update_website_option( $website, 'last_trans_upgrades', $website->translation_upgrades );
1093
1094 if ( ! empty( $delay_autoupdate ) ) {
1095 foreach ( $websitePluginsUpdateCheck as $slug => $check_time ) {
1096 if ( ( time() > $check_time + 30 * DAY_IN_SECONDS ) && is_array( $websitePlugins ) && ! empty( $websitePlugins ) && ! isset( $websitePlugins[ $slug ] ) ) {
1097 unset( $websitePluginsUpdateCheck[ $slug ] );
1098 }
1099 }
1100
1101 foreach ( $websiteThemesUpdateCheck as $slug => $check_time ) {
1102 if ( ( time() > $check_time + 30 * DAY_IN_SECONDS ) && is_array( $websiteThemes ) && ! empty( $websiteThemes ) && ! isset( $websiteThemes[ $slug ] ) ) {
1103 unset( $websiteThemesUpdateCheck[ $slug ] );
1104 }
1105 }
1106
1107 foreach ( $websiteTransUpdateCheck as $slug => $check_time ) {
1108 if ( ( time() > $check_time + 30 * DAY_IN_SECONDS ) && is_array( $websiteTrans ) && ! empty( $websiteTrans ) && ! isset( $websiteTrans[ $slug ] ) ) {
1109 unset( $websiteTransUpdateCheck[ $slug ] );
1110 }
1111 }
1112
1113 MainWP_DB::instance()->update_website_option( $website, 'core_update_check', $websiteCoreUpdateCheck );
1114 MainWP_DB::instance()->update_website_option( $website, 'plugins_update_check', ( ! empty( $websitePluginsUpdateCheck ) ? wp_json_encode( $websitePluginsUpdateCheck ) : '' ) );
1115 MainWP_DB::instance()->update_website_option( $website, 'themes_update_check', ( ! empty( $websiteThemesUpdateCheck ) ? wp_json_encode( $websiteThemesUpdateCheck ) : '' ) );
1116 MainWP_DB::instance()->update_website_option( $website, 'trans_update_check', ( ! empty( $websiteTransUpdateCheck ) ? wp_json_encode( $websiteTransUpdateCheck ) : '' ) );
1117
1118 } elseif ( ! empty( $websitePluginsUpdateCheck ) || ! empty( $websiteThemesUpdateCheck ) ) {
1119 MainWP_DB::instance()->update_website_option( $website, 'core_update_check', 0 );
1120 MainWP_DB::instance()->update_website_option( $website, 'plugins_update_check', '' );
1121 MainWP_DB::instance()->update_website_option( $website, 'themes_update_check', '' );
1122 MainWP_DB::instance()->update_website_option( $website, 'trans_update_check', '' );
1123 }
1124
1125 if ( ! in_array( $website->id, $updatescheckSitesIcon ) ) {
1126 MainWP_Sync::get_wp_icon( $website->id );
1127 $updatescheckSitesIcon[] = $website->id;
1128 }
1129
1130 if ( $check_individual_digest ) {
1131 $individualDailyDigestWebsites[] = $website->id;
1132 }
1133 }
1134
1135 MainWP_Utility::update_option( 'mainwp_updatescheck_sites_icon', $updatescheckSitesIcon );
1136
1137 if ( ! empty( $individualDailyDigestWebsites ) ) {
1138 $individualDailyDigestWebsitesSaved = get_option( 'mainwp_updatescheck_individual_digest_websites' );
1139 if ( ! is_array( $individualDailyDigestWebsitesSaved ) ) {
1140 $individualDailyDigestWebsitesSaved = array();
1141 }
1142 foreach ( $individualDailyDigestWebsites as $sid ) {
1143 if ( ! in_array( $sid, $individualDailyDigestWebsitesSaved ) ) {
1144 $individualDailyDigestWebsitesSaved[] = $sid;
1145 }
1146 }
1147 MainWP_Utility::update_option( 'mainwp_updatescheck_individual_digest_websites', $individualDailyDigestWebsitesSaved );
1148 }
1149
1150 if ( ! empty( $coreNewUpdate ) ) {
1151 $coreNewUpdateSaved = get_option( 'mainwp_updatescheck_mail_update_core_new' );
1152 MainWP_Utility::update_option( 'mainwp_updatescheck_mail_update_core_new', MainWP_Utility::array_merge( $coreNewUpdateSaved, $coreNewUpdate ) );
1153 }
1154
1155 if ( ! empty( $pluginsNewUpdate ) ) {
1156 $pluginsNewUpdateSaved = get_option( 'mainwp_updatescheck_mail_update_plugins_new' );
1157 MainWP_Utility::update_option( 'mainwp_updatescheck_mail_update_plugins_new', MainWP_Utility::array_merge( $pluginsNewUpdateSaved, $pluginsNewUpdate ) );
1158 }
1159
1160 if ( ! empty( $themesNewUpdate ) ) {
1161 $themesNewUpdateSaved = get_option( 'mainwp_updatescheck_mail_update_themes_new' );
1162 MainWP_Utility::update_option( 'mainwp_updatescheck_mail_update_themes_new', MainWP_Utility::array_merge( $themesNewUpdateSaved, $themesNewUpdate ) );
1163 }
1164
1165 if ( ! empty( $coreToUpdate ) ) {
1166 $coreToUpdateSaved = get_option( 'mainwp_updatescheck_mail_update_core' );
1167 MainWP_Utility::update_option( 'mainwp_updatescheck_mail_update_core', MainWP_Utility::array_merge( $coreToUpdateSaved, $coreToUpdate ) );
1168 }
1169
1170 if ( ! empty( $pluginsToUpdate ) ) {
1171 $pluginsToUpdateSaved = get_option( 'mainwp_updatescheck_mail_update_plugins' );
1172 MainWP_Utility::update_option( 'mainwp_updatescheck_mail_update_plugins', MainWP_Utility::array_merge( $pluginsToUpdateSaved, $pluginsToUpdate ) );
1173 }
1174
1175 if ( ! empty( $themesToUpdate ) ) {
1176 $themesToUpdateSaved = get_option( 'mainwp_updatescheck_mail_update_themes' );
1177 MainWP_Utility::update_option( 'mainwp_updatescheck_mail_update_themes', MainWP_Utility::array_merge( $themesToUpdateSaved, $themesToUpdate ) );
1178 }
1179
1180 if ( ! empty( $ignoredCoreToUpdate ) ) {
1181 $ignoredCoreToUpdateSaved = get_option( 'mainwp_updatescheck_mail_ignore_core' );
1182 MainWP_Utility::update_option( 'mainwp_updatescheck_mail_ignore_core', MainWP_Utility::array_merge( $ignoredCoreToUpdateSaved, $ignoredCoreToUpdate ) );
1183 }
1184
1185 if ( ! empty( $ignoredCoreNewUpdate ) ) {
1186 $ignoredCoreNewUpdateSaved = get_option( 'mainwp_updatescheck_mail_ignore_core_new' );
1187 MainWP_Utility::update_option( 'mainwp_updatescheck_mail_ignore_core_new', MainWP_Utility::array_merge( $ignoredCoreNewUpdateSaved, $ignoredCoreNewUpdate ) );
1188 }
1189
1190 if ( ! empty( $notTrustedPluginsToUpdate ) ) {
1191 $notTrustedPluginsToUpdateSaved = get_option( 'mainwp_updatescheck_mail_ignore_plugins' );
1192 MainWP_Utility::update_option( 'mainwp_updatescheck_mail_ignore_plugins', MainWP_Utility::array_merge( $notTrustedPluginsToUpdateSaved, $notTrustedPluginsToUpdate ) );
1193 }
1194
1195 if ( ! empty( $notTrustedPluginsNewUpdate ) ) {
1196 $notTrustedPluginsNewUpdateSaved = get_option( 'mainwp_updatescheck_mail_ignore_plugins_new' );
1197 MainWP_Utility::update_option( 'mainwp_updatescheck_mail_ignore_plugins_new', MainWP_Utility::array_merge( $notTrustedPluginsNewUpdateSaved, $notTrustedPluginsNewUpdate ) );
1198 }
1199
1200 if ( ! empty( $notTrustedThemesToUpdate ) ) {
1201 $notTrustedThemesToUpdateSaved = get_option( 'mainwp_updatescheck_mail_ignore_themes' );
1202 MainWP_Utility::update_option( 'mainwp_updatescheck_mail_ignore_themes', MainWP_Utility::array_merge( $notTrustedThemesToUpdateSaved, $notTrustedThemesToUpdate ) );
1203 }
1204
1205 if ( ! empty( $notTrustedThemesNewUpdate ) ) {
1206 $notTrustedThemesNewUpdateSaved = get_option( 'mainwp_updatescheck_mail_ignore_themes_new' );
1207 MainWP_Utility::update_option( 'mainwp_updatescheck_mail_ignore_themes_new', MainWP_Utility::array_merge( $notTrustedThemesNewUpdateSaved, $notTrustedThemesNewUpdate ) );
1208 }
1209 }
1210 }
1211
1212 /**
1213 * Method start_notification_daily_digest().
1214 *
1215 * Send email notification.
1216 *
1217 * @param array $email_settings Email settings.
1218 * @param bool $plain_text Text format value.
1219 * @param array $sites_ids Array of websites ids (option).
1220 * @param object $email_site current report site.
1221 *
1222 * @return bool True|False
1223 *
1224 * @uses \MainWP\Dashboard\MainWP_Format::get_site_updates_items()
1225 * @uses \MainWP\Dashboard\MainWP_DB::get_disconnected_websites()
1226 * @uses \MainWP\Dashboard\MainWP_Logger::debug()
1227 * @uses \MainWP\Dashboard\MainWP_Notification
1228 */
1229 public function start_notification_daily_digest( $email_settings, $plain_text, $sites_ids = false, $email_site = false ) {
1230
1231 $sendMail = false;
1232 $updateAvaiable = false;
1233 $plugin_updates = array();
1234 $theme_updates = array();
1235
1236 $plugin_updates = MainWP_Format::get_site_updates_items( 'plugin', $sites_ids );
1237 if ( ! empty( $plugin_updates ) ) {
1238 $sendMail = true;
1239 $updateAvaiable = true;
1240 }
1241
1242 $theme_updates = MainWP_Format::get_site_updates_items( 'theme', $sites_ids );
1243 if ( ! empty( $theme_updates ) ) {
1244 $sendMail = true;
1245 $updateAvaiable = true;
1246 }
1247
1248 $wp_updates = MainWP_Format::get_site_updates_items( 'wpcore', $sites_ids );
1249 if ( ! empty( $wp_updates ) ) {
1250 $sendMail = true;
1251 $updateAvaiable = true;
1252 }
1253
1254 $sites_disconnected = MainWP_DB::instance()->get_disconnected_websites( $sites_ids );
1255
1256 if ( ! empty( $sites_disconnected ) ) {
1257 $sendMail = true;
1258 }
1259
1260 if ( ! $sendMail ) {
1261 MainWP_Logger::instance()->log_update_check( 'updates check :: sendMail is false' );
1262 return false;
1263 }
1264
1265 $params = array(
1266 'plain_text' => $plain_text,
1267 'sites_ids' => $sites_ids,
1268 'email_site' => $email_site,
1269 );
1270
1271 return MainWP_Notification::send_daily_digest_notification( $email_settings, $updateAvaiable, $wp_updates, $plugin_updates, $theme_updates, $sites_disconnected, $params );
1272 }
1273
1274 /**
1275 * Method refresh_saved_fields().
1276 *
1277 * Clear settings field values.
1278 *
1279 * @uses \MainWP\Dashboard\MainWP_Utility::update_option()
1280 */
1281 public function refresh_saved_fields() {
1282
1283 MainWP_Logger::instance()->log_update_check( 'updates check :: clear saved info' );
1284
1285 $empty_fields = array(
1286 'mainwp_automaticUpdate_backupChecks',
1287 'mainwp_updatescheck_mail_update_core_new',
1288 'mainwp_updatescheck_mail_update_plugins_new',
1289 'mainwp_updatescheck_mail_update_themes_new',
1290 'mainwp_updatescheck_mail_update_core',
1291 'mainwp_updatescheck_mail_update_plugins',
1292 'mainwp_updatescheck_mail_update_themes',
1293 'mainwp_updatescheck_mail_ignore_core',
1294 'mainwp_updatescheck_mail_ignore_plugins',
1295 'mainwp_updatescheck_mail_ignore_themes',
1296 'mainwp_updatescheck_mail_ignore_core_new',
1297 'mainwp_updatescheck_mail_ignore_plugins_new',
1298 'mainwp_updatescheck_mail_ignore_themes_new',
1299 'mainwp_updatescheck_individual_digest_websites',
1300 'mainwp_updatescheck_sites_icon',
1301 );
1302
1303 foreach ( $empty_fields as $field ) {
1304 MainWP_Utility::update_option( $field, '' );
1305 }
1306 }
1307
1308 /**
1309 * Method start_notification_http_check().
1310 *
1311 * Prepare to send http check notification.
1312 *
1313 * @param bool $plain_text Text format value.
1314 *
1315 * @return bool True|False
1316 *
1317 * @uses \MainWP\Dashboard\MainWP_Notification::send_http_check_notification()
1318 * @uses \MainWP\Dashboard\MainWP_Notification_Settings::get_general_email_settings()
1319 * @uses \MainWP\Dashboard\MainWP_Notification_Settings::get_site_email_settings()
1320 * @uses \MainWP\Dashboard\MainWP_Notification_Settings::get_default_emails_fields()
1321 * @uses \MainWP\Dashboard\MainWP_Utility::get_http_codes()
1322 */
1323 public function start_notification_http_check( $plain_text ) { // phpcs:ignore -- NOSONAR - complex.
1324
1325 $sitesHttpCheck = array();
1326 $email_settings_sites = array();
1327
1328 $sites_offline = MainWP_DB::instance()->get_websites_http_check_status();
1329 if ( is_array( $sites_offline ) && ! empty( $sites_offline ) ) {
1330 foreach ( $sites_offline as $site ) {
1331 if ( empty( $site->http_response_code ) ) { // to fix: ignored 200 http code.
1332 continue;
1333 }
1334 $email_settings_sites[ $site->id ] = $site->settings_notification_emails; // ok.
1335 $code = $site->http_response_code;
1336 $code_string = MainWP_Utility::get_http_codes( $code );
1337 if ( ! empty( $code_string ) ) {
1338 $code .= ' - ' . $code_string;
1339 }
1340
1341 $sitesHttpCheck[] = array(
1342 'id' => $site->id,
1343 'name' => $site->name,
1344 'url' => $site->url,
1345 'code' => $code,
1346 );
1347 MainWP_DB::instance()->update_website_option( $site->id, 'http_status_notice_check_time', time() );
1348 }
1349 }
1350
1351 if ( empty( $sitesHttpCheck ) ) {
1352 return false;
1353 }
1354
1355 $gen_settings = MainWP_Notification_Settings::get_general_email_settings( 'http_check' );
1356 // general http check notificaion, to administrator.
1357 if ( ! $gen_settings['disable'] ) {
1358 MainWP_Notification::send_http_check_notification( $gen_settings, $sitesHttpCheck, $plain_text );
1359 usleep( 100000 );
1360 }
1361
1362 $to_admin_HttpCheckWebsites = array();
1363 // individual http check notification.
1364 foreach ( $sitesHttpCheck as $site ) {
1365
1366 $website = new \stdClass();
1367 $website->id = $site['id'];
1368 $website->url = $site['url'];
1369 $website->name = $site['name'];
1370
1371 $website->settings_notification_emails = $email_settings_sites[ $site['id'] ]; // ok.
1372
1373 $settings = MainWP_Notification_Settings::get_site_email_settings( 'http_check', $website ); // get site email settings.
1374
1375 MainWP_DB::instance()->set_website_noticed_http_check( $website->id );
1376
1377 if ( ! $settings['disable'] ) {
1378 $to_admin_HttpCheckWebsites[] = $site;
1379
1380 $sent = MainWP_Notification::send_http_check_notification( $settings, array( $site ), $plain_text, false );
1381 if ( $sent ) {
1382 usleep( 100000 );
1383 }
1384 }
1385 }
1386
1387 // send all individual notice to admin in one email.
1388 if ( ! empty( $to_admin_HttpCheckWebsites ) ) {
1389 $admin_email_settings = MainWP_Notification_Settings::get_default_emails_fields( 'http_check', '', true ); // get default subject and heading only.
1390 $admin_email_settings['disable'] = 0;
1391 $admin_email_settings['recipients'] = ''; // sent to admin only.
1392 MainWP_Notification::send_http_check_notification( $admin_email_settings, $sitesHttpCheck, $plain_text );
1393 }
1394
1395 return true;
1396 }
1397
1398 /**
1399 * Method cron_deactivated_licenses_alert()
1400 */
1401 public function cron_deactivated_licenses_alert() { // phpcs:ignore -- NOSONAR - complex.
1402 $admin_email_settings = MainWP_Notification_Settings::get_default_emails_fields( 'deactivated_license_alert' );
1403 if ( empty( $admin_email_settings['disable'] ) && ! empty( $admin_email_settings['recipients'] ) ) {
1404 $deactivated_licenses = MainWP_Extensions_Handler::get_indexed_extensions_infor( false, true );
1405 if ( ! empty( $deactivated_licenses ) ) {
1406 $alerts_now = array();
1407 foreach ( $deactivated_licenses as $slug => $info ) {
1408 if ( ! empty( $info['mainwp_version'] ) ) { // alert for versions 5 only.
1409 $alerted = MainWP_Utility::instance()->get_set_deactivated_licenses_alerted( $slug );
1410 if ( empty( $alerted ) ) {
1411 $alerts_now[ $slug ] = $info;
1412 MainWP_Utility::instance()->get_set_deactivated_licenses_alerted( $slug, time(), 'set' );
1413 }
1414 }
1415 }
1416
1417 if ( ! empty( $alerts_now ) ) {
1418 $plain_text = get_option( 'mainwp_license_deactivated_alert_plain_text', false );
1419 $filtered = apply_filters( 'mainwp_license_deactivated_alert_plain_text', $plain_text );
1420 if ( $plain_text !== $filtered ) {
1421 $plain_text = $filtered;
1422 MainWP_Utility::update_option( 'mainwp_license_deactivated_alert_plain_text', $plain_text );
1423 }
1424 MainWP_Notification::send_license_deactivated_alert( $admin_email_settings, $alerts_now, $plain_text );
1425 MainWP_Utility::update_option( 'mainwp_cron_license_deactivated_alert_lasttime', time() );
1426 }
1427 }
1428 }
1429 }
1430
1431 /**
1432 * Method cron_ping_childs()
1433 *
1434 * Cron job to ping child sites.
1435 *
1436 * @uses \MainWP\Dashboard\MainWP_DB::query()
1437 * @uses \MainWP\Dashboard\MainWP_DB::get_sql_websites()
1438 * @uses \MainWP\Dashboard\MainWP_DB::fetch_object()
1439 * @uses \MainWP\Dashboard\MainWP_DB::free_result()
1440 * @uses \MainWP\Dashboard\MainWP_Logger::info()
1441 * @uses \MainWP\Dashboard\MainWP_Utility::update_option()
1442 * @uses \MainWP\Dashboard\MainWP_Utility::ends_with()
1443 */
1444 public function cron_ping_childs() {
1445 MainWP_Logger::instance()->info( 'ping childs' );
1446
1447 $lastPing = get_option( 'mainwp_cron_last_ping' );
1448 if ( false !== $lastPing && ( time() - $lastPing ) < ( 60 * 60 * 23 ) ) {
1449 return;
1450 }
1451 MainWP_Utility::update_option( 'mainwp_cron_last_ping', time() );
1452
1453 $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites() );
1454 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
1455 try {
1456 $url = $website->siteurl;
1457 if ( ! MainWP_Utility::ends_with( $url, '/' ) ) {
1458 $url .= '/';
1459 }
1460
1461 wp_remote_get( $url . 'wp-cron.php' );
1462 } catch ( \Exception $e ) {
1463 // ok.
1464 }
1465 }
1466 MainWP_DB::free_result( $websites );
1467 }
1468
1469 /**
1470 * Method cron_backups_continue()
1471 *
1472 * Execute remaining backup tasks.
1473 *
1474 * @uses \MainWP\Dashboard\MainWP_DB_Backup::get_backup_tasks_to_complete()
1475 * @uses \MainWP\Dashboard\MainWP_DB_Backup::get_backup_task_by_id()
1476 * @uses \MainWP\Dashboard\MainWP_Logger::info()
1477 * @uses \MainWP\Dashboard\MainWP_Logger::debug()
1478 * @uses \MainWP\Dashboard\MainWP_Manage_Backups_Handler::execute_backup_task()
1479 * @uses \MainWP\Dashboard\MainWP_Utility::update_option()
1480 */
1481 public function cron_backups_continue() {
1482
1483 if ( ! get_option( 'mainwp_enableLegacyBackupFeature' ) ) {
1484 return;
1485 }
1486
1487 MainWP_Logger::instance()->info( 'backups continue' );
1488
1489 ignore_user_abort( true );
1490 MainWP_System_Utility::set_time_limit( 0 );
1491 add_filter(
1492 'admin_memory_limit',
1493 function () {
1494 return '512M';
1495 }
1496 );
1497
1498 MainWP_Utility::update_option( 'mainwp_cron_last_backups_continue', time() );
1499
1500 $tasks = MainWP_DB_Backup::instance()->get_backup_tasks_to_complete();
1501
1502 MainWP_Logger::instance()->debug( 'backups continue :: Found ' . count( $tasks ) . ' to continue.' );
1503
1504 if ( empty( $tasks ) ) {
1505 return;
1506 }
1507
1508 foreach ( $tasks as $task ) {
1509 MainWP_Logger::instance()->debug( 'backups continue :: Task: ' . $task->name );
1510 }
1511
1512 foreach ( $tasks as $task ) {
1513 $task = MainWP_DB_Backup::instance()->get_backup_task_by_id( $task->id );
1514 if ( $task->completed < $task->last_run ) {
1515 MainWP_Manage_Backups_Handler::execute_backup_task( $task, 5, false );
1516 break;
1517 }
1518 }
1519 }
1520
1521 /**
1522 * Method cron_backups()
1523 *
1524 * Execute Backup Tasks.
1525 *
1526 * @uses \MainWP\Dashboard\MainWP_DB_Backup::get_backup_tasks_todo_daily() - NOSONAR todo name.
1527 * @uses \MainWP\Dashboard\MainWP_DB_Backup::get_backup_tasks_todo_weekly() - NOSONAR todo name.
1528 * @uses \MainWP\Dashboard\MainWP_DB_Backup::get_backup_tasks_todo_monthly() - NOSONAR todo name.
1529 * @uses \MainWP\Dashboard\MainWP_DB_Backup::get_backup_task_by_id()
1530 * @uses \MainWP\Dashboard\MainWP_Logger::info()
1531 * @uses \MainWP\Dashboard\MainWP_Logger::debug()
1532 * @uses \MainWP\Dashboard\MainWP_Manage_Backups::validate_backup_tasks()
1533 * @uses \MainWP\Dashboard\MainWP_Manage_Backups_Handler::execute_backup_task()
1534 * @uses \MainWP\Dashboard\MainWP_Utility::update_option()
1535 */
1536 public function cron_backups() { // phpcs:ignore -- NOSONAR - complex.
1537 if ( ! get_option( 'mainwp_enableLegacyBackupFeature' ) ) {
1538 return;
1539 }
1540
1541 MainWP_Logger::instance()->info( 'backups' );
1542
1543 ignore_user_abort( true );
1544 MainWP_System_Utility::set_time_limit( 0 );
1545 add_filter(
1546 'admin_memory_limit',
1547 function () {
1548 return '512M';
1549 }
1550 );
1551
1552 MainWP_Utility::update_option( 'mainwp_cron_last_backups', time() );
1553
1554 $allTasks = array();
1555 $dailyTasks = MainWP_DB_Backup::instance()->get_backup_tasks_todo_daily();
1556 if ( ! empty( $dailyTasks ) ) {
1557 $allTasks = $dailyTasks;
1558 }
1559 $weeklyTasks = MainWP_DB_Backup::instance()->get_backup_tasks_todo_weekly();
1560 if ( ! empty( $weeklyTasks ) ) {
1561 $allTasks = array_merge( $allTasks, $weeklyTasks );
1562 }
1563 $monthlyTasks = MainWP_DB_Backup::instance()->get_backup_tasks_todo_monthly();
1564 if ( ! empty( $monthlyTasks ) ) {
1565 $allTasks = array_merge( $allTasks, $monthlyTasks );
1566 }
1567
1568 MainWP_Logger::instance()->debug( 'backups :: Found ' . count( $allTasks ) . ' to start.' );
1569
1570 foreach ( $allTasks as $task ) {
1571 MainWP_Logger::instance()->debug( 'backups :: Task: ' . $task->name );
1572 }
1573
1574 foreach ( $allTasks as $task ) {
1575 $threshold = 0;
1576 if ( 'daily' === $task->schedule ) {
1577 $threshold = ( 60 * 60 * 24 );
1578 } elseif ( 'weekly' === $task->schedule ) {
1579 $threshold = ( 60 * 60 * 24 * 7 );
1580 } elseif ( 'monthly' === $task->schedule ) {
1581 $threshold = ( 60 * 60 * 24 * 30 );
1582 }
1583 $task = MainWP_DB_Backup::instance()->get_backup_task_by_id( $task->id );
1584 if ( ( time() - $task->last_run ) < $threshold ) {
1585 continue;
1586 }
1587
1588 if ( ! MainWP_Manage_Backups_Handler::validate_backup_tasks( array( $task ) ) ) {
1589 $task = MainWP_DB_Backup::instance()->get_backup_task_by_id( $task->id );
1590 }
1591
1592 $chunkedBackupTasks = get_option( 'mainwp_chunkedBackupTasks' );
1593 MainWP_Manage_Backups_Handler::execute_backup_task( $task, ( 0 !== $chunkedBackupTasks ? 5 : 0 ) );
1594 }
1595 }
1596
1597 /**
1598 * Method cron_reconnect()
1599 *
1600 * Grab MainWP Cron Job Statistics.
1601 *
1602 * @uses \MainWP\Dashboard\MainWP_DB::query()
1603 * @uses \MainWP\Dashboard\MainWP_DB::get_websites_stats_update_sql()
1604 * @uses \MainWP\Dashboard\MainWP_DB::update_website_stats()
1605 * @uses \MainWP\Dashboard\MainWP_DB::fetch_object()
1606 * @uses \MainWP\Dashboard\MainWP_DB::free_result()
1607 * @uses \MainWP\Dashboard\MainWP_Logger::info()
1608 * @uses \MainWP\Dashboard\MainWP_Logger::info_for_website()
1609 * @uses \MainWP\Dashboard\MainWP_Logger::warning_for_website()
1610 * @uses \MainWP\Dashboard\MainWP_Manage_Sites_View::m_reconnect_site()
1611 * @uses \MainWP\Dashboard\MainWP_Utility::update_option()
1612 */
1613 public function cron_reconnect() {
1614 MainWP_Logger::instance()->info( 'stats' );
1615
1616 MainWP_Utility::update_option( 'mainwp_cron_last_stats', time() );
1617
1618 $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_websites_stats_update_sql() );
1619
1620 $start = time();
1621 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
1622 if ( ( time() - $start ) > ( 60 * 60 * 2 ) ) {
1623 break;
1624 }
1625
1626 MainWP_DB::instance()->update_website_stats( $website->id, time() );
1627
1628 if ( property_exists( $website, 'sync_errors' ) && '' !== $website->sync_errors ) {
1629 MainWP_Logger::instance()->info_for_website( $website, 'reconnect', 'Trying to reconnect' );
1630 try {
1631 if ( MainWP_Manage_Sites_View::m_reconnect_site( $website ) ) {
1632 MainWP_Logger::instance()->info_for_website( $website, 'reconnect', 'Reconnected successfully' );
1633 }
1634 } catch ( \Exception $e ) {
1635 MainWP_Logger::instance()->warning_for_website( $website, 'reconnect', $e->getMessage() );
1636 }
1637 }
1638 sleep( 3 );
1639 }
1640 MainWP_DB::free_result( $websites );
1641 }
1642
1643 /**
1644 * Method cron_check_websites_health()
1645 *
1646 * Cron job to check site health.
1647 *
1648 * @uses \MainWP\Dashboard\MainWP_Logger::info()
1649 * @uses \MainWP\Dashboard\MainWP_Utility::update_option()
1650 */
1651 public function cron_check_websites_health() {
1652
1653 // to disable if run custom cron.
1654 $disableChecking = get_option( 'mainwp_disableSitesHealthMonitoring', 1 ); // disabled by default.
1655 if ( $disableChecking ) {
1656 return;
1657 }
1658
1659 MainWP_Logger::instance()->info( 'check sites health :: starting.' );
1660 $plain_text = get_option( 'mainwp_daily_digest_plain_text', false );
1661 $this->start_notification_sites_health( $plain_text );
1662 MainWP_Logger::instance()->info( 'check sites health :: finished.' );
1663 MainWP_Utility::update_option( 'mainwp_cron_checksiteshealth_last_timestamp', time() );
1664 }
1665
1666 /**
1667 * Method start_notification_sites_health().
1668 *
1669 * Prepare sites health notification.
1670 *
1671 * @param bool $plain_text Text format value.
1672 *
1673 * @return bool True|False
1674 *
1675 * @uses \MainWP\Dashboard\MainWP_DB::get_websites_to_notice_health_threshold()
1676 * @uses \MainWP\Dashboard\MainWP_Logger::info()
1677 * @uses \MainWP\Dashboard\MainWP_Monitoring_Handler::notice_site_health_threshold()
1678 * @uses \MainWP\Dashboard\MainWP_Notification_Settings::get_general_email_settings()
1679 * @uses \MainWP\Dashboard\MainWP_Notification_Settings::get_site_email_settings()
1680 * @uses \MainWP\Dashboard\MainWP_Notification_Settings::get_default_emails_fields()
1681 */
1682 public function start_notification_sites_health( $plain_text ) {
1683
1684 $globalThreshold = get_option( 'mainwp_sitehealthThreshold', 80 );
1685 $healthSites = MainWP_DB::instance()->get_websites_to_notice_health_threshold( $globalThreshold );
1686 MainWP_Logger::instance()->info( 'check sites health :: notice site health :: found ' . ( $healthSites ? count( $healthSites ) : 0 ) );
1687
1688 if ( empty( $healthSites ) ) {
1689 return false;
1690 }
1691
1692 $email = MainWP_Notification_Settings::get_general_email();
1693
1694 // general site health notifcation.
1695 $email_settings = MainWP_Notification_Settings::get_general_email_settings( 'site_health' );
1696 if ( ! $email_settings['disable'] ) {
1697 // send to general email settings, one site in one email.
1698 MainWP_Monitoring_Handler::notice_site_health_threshold( $email_settings, $healthSites, $email, $plain_text );
1699 }
1700
1701 $to_admin_siteHealthWebsites = array();
1702 // individual uptime notification.
1703 foreach ( $healthSites as $site ) {
1704 $email_settings = MainWP_Notification_Settings::get_site_email_settings( 'site_health', $site );
1705 if ( $email_settings['disable'] ) {
1706 continue; // disabled notification for this site.
1707 }
1708 $to_admin_siteHealthWebsites[] = $site;
1709 // send to individual email settings, one site in one email.
1710 MainWP_Monitoring_Handler::notice_site_health_threshold( $email_settings, array( $site ), '', $plain_text, false ); // do not send to admin for individual sending.
1711 }
1712
1713 if ( ! empty( $to_admin_siteHealthWebsites ) ) {
1714 $admin_email_settings = MainWP_Notification_Settings::get_default_emails_fields( 'site_health', '', true ); // get default subject and heading only.
1715 $admin_email_settings['disable'] = 0;
1716 $admin_email_settings['recipients'] = ''; // sent to admin only.
1717 // send to admin, all individual sites in one email.
1718 MainWP_Monitoring_Handler::notice_site_health_threshold( $admin_email_settings, $to_admin_siteHealthWebsites, $email, $plain_text, true, true );
1719 }
1720
1721 return true;
1722 }
1723
1724
1725 /**
1726 * Method cron_perform_general_process
1727 *
1728 * @return void
1729 */
1730 public function cron_perform_general_process() {
1731 $this->perform_sequence_process();
1732 }
1733
1734 /**
1735 * Method perform_sequence_process
1736 *
1737 * @return void
1738 */
1739 public function perform_sequence_process() { //phpcs:ignore -- NOSONAR - complexity.
1740 $register_process = apply_filters( 'mainwp_register_regular_sequence_process', array() );
1741 $register_process = is_array( $register_process ) ? $register_process : array();
1742 $valid_processes = array();
1743
1744 foreach ( $register_process as $name => $reg_process ) {
1745
1746 if ( ! is_array( $reg_process ) || empty( $reg_process ) || ! is_string( $name ) || empty( $name ) ) {
1747 continue;
1748 }
1749
1750 if ( $this->is_process_callable( $reg_process ) ) {
1751 $valid_processes[ $name ] = $reg_process;
1752 }
1753 }
1754
1755 MainWP_Utility::array_sort( $valid_processes, 'priority', SORT_NUMERIC );
1756
1757 $managed_processes = array_values( $valid_processes );
1758
1759 // to fix.
1760 if ( empty( $managed_processes ) ) {
1761 return;
1762 }
1763
1764 $count = count( $managed_processes );
1765
1766 $current_pid = (int) get_option( 'mainwp_regular_sequence_current_process_pid', 0 );
1767
1768 if ( $current_pid > $count ) {
1769 $current_pid = 0;
1770 }
1771
1772 $process = isset( $managed_processes[ $current_pid ] ) ? $managed_processes[ $current_pid ] : array();
1773
1774 MainWP_Logger::instance()->log_events( 'regular-schedule', '[current_pid=' . $current_pid . ' :: [total=' . $count . '] :: [process=' . ( is_array($process) ? print_r($process, true ): '' ) . ']' ); //phpcs:ignore -- ok.
1775
1776 $performed = false;
1777 while ( $current_pid <= $count ) {
1778 $callable = $this->is_process_callable( $process );
1779
1780 if ( ! empty( $callable ) && is_callable( $callable ) ) {
1781 $this->set_process_counter( ++$current_pid );
1782 call_user_func( $callable );
1783 $performed = true;
1784 MainWP_Logger::instance()->log_events( 'regular-schedule', 'Run process: [process=' . ( is_array($process) ? print_r($process, true ): '' ) . ']' ); //phpcs:ignore -- ok.
1785 } else {
1786 $this->set_process_counter( ++$current_pid );
1787 }
1788
1789 if ( $performed ) {
1790 break; // to run next schedule.
1791 } else {
1792 $process = isset( $managed_processes[ $current_pid ] ) ? $managed_processes[ $current_pid ] : false;
1793 if ( empty( $process ) ) {
1794 break; // to run next schedule.
1795 }
1796 }
1797 }
1798 }
1799
1800
1801 /**
1802 * Method set_process_counter().
1803 *
1804 * @param int $counter_index Counter.
1805 * @return void
1806 */
1807 public function set_process_counter( $counter_index ) {
1808 update_option( 'mainwp_regular_sequence_current_process_pid', $counter_index );
1809 }
1810
1811 /**
1812 * Method is_process_callable().
1813 *
1814 * @param array $process The process.
1815 * @return mixed false|string|array callable.
1816 */
1817 public function is_process_callable( $process ) { //phpcs:ignore -- NOSONAR - complex.
1818 if ( is_array( $process ) && ! empty( $process['callback'] ) && is_array( $process['callback'] ) ) {
1819 $class_name = ! empty( $process['callback'][0] ) ? $process['callback'][0] : '';
1820 $method_name = ! empty( $process['callback'][1] ) ? $process['callback'][1] : '';
1821 if ( ! empty( $class_name ) && ! empty( $method_name ) ) {
1822 if ( class_exists( $class_name ) ) {
1823 $call_inst = new $class_name();
1824 $callback = array( $call_inst, $method_name );
1825 if ( is_callable( $callback ) ) {
1826 return $callback;
1827 }
1828 }
1829 } elseif ( ! empty( $method_name ) && is_callable( $method_name ) ) {
1830 return $method_name;
1831 }
1832 }
1833 return false;
1834 }
1835 }
1836