* * @phpstan-import-type PresizedDivSlot from PresizedDiv */ final class Cron { /** * Schedule cron jobs * * @since 2.0.0 * @return void */ public function schedule() { if ( ACTIRISE_CRON === 'true' ) { add_filter( 'cron_schedules', function ( $schedules ) { $schedules['five_minutes'] = array( 'interval' => 300, 'display' => esc_html__( 'Every Five Minutes', 'actirise' ), ); return $schedules; } ); if ( ! wp_next_scheduled( 'actirise_cron_update_adstxt' ) ) { wp_schedule_event( time(), 'hourly', 'actirise_cron_update_adstxt' ); $this->update_adstxt(); } if ( ! wp_next_scheduled( 'actirise_cron_update_presized_div' ) ) { wp_schedule_event( time(), 'hourly', 'actirise_cron_update_presized_div' ); $this->check_presized_div(); } if ( ! wp_next_scheduled( 'actirise_cron_update_fast_cmp' ) ) { wp_schedule_event( time(), 'hourly', 'actirise_cron_update_fast_cmp' ); $this->get_fast_cmp(); } if ( ! wp_next_scheduled( 'actirise_cron_check_adstxt' ) ) { wp_schedule_event( time(), 'hourly', 'actirise_cron_check_adstxt' ); $this->check_adstxt(); } if ( ! wp_next_scheduled( 'actirise_cron_check_slots' ) ) { wp_schedule_event( time(), 'hourly', 'actirise_cron_check_slots' ); $this->check_slots(); } if ( ! wp_next_scheduled( 'actirise_cron_event_annotation' ) ) { wp_schedule_event( time(), 'five_minutes', 'actirise_cron_event_annotation' ); $this->upload_event_annotation(); } } } /** * Update ads.txt file * * @since 2.0.0 * @return void */ public function update_adstxt() { if ( Options::get( 'settings-uuid' ) ) { $ads_txt = AdsTxt::get_from_api(); if ( $ads_txt !== false ) { Options::update( 'adstxt-actirise', $ads_txt ); $this->check_adstxt(); if ( Options::get( 'adstxt-active', false ) === true ) { AdsTxt::update_file(); } Options::update( 'adstxt-lastupdate', time() ); } if ( $ads_txt === false ) { Logger::add_log( 'adstxt get_from_api is false', 'include/cron', 'error' ); } } } /** * Check lines in ads.txt file * * @since 3.0.0 * @return bool|array */ public function check_adstxt() { if ( ! Helpers::is_user_authenticated() ) { return false; } $adstxt_status = AdsTxt::check_from_api( 'true' ); while ( isset( $adstxt_status['state'] ) && $adstxt_status['state'] === 'pending' ) { $adstxt_status = AdsTxt::check_from_api( 'false' ); } if ( isset( $adstxt_status['state'] ) ) { if ( $adstxt_status['state'] === 'ok' ) { Options::update( 'adstxt-update', false ); } else { Options::update( 'adstxt-update', true ); } } return $adstxt_status; } /** * Check for presized div * * @since 2.0.0 * @return void */ public function check_presized_div() { if ( ! Helpers::is_user_authenticated() ) { return; } if ( Options::get( 'settings-uuid' ) ) { /** @var array | bool $presized_div */ $presized_div = PresizedDiv::get_from_api(); if ( $presized_div !== false ) { /** @var mixed $presized_div_active */ $presized_div_active = Options::get( 'presizeddiv-selected', array() ); /** @var mixed $presized_div_notif */ $presized_div_notif = Options::get( 'presizeddiv-notif', array() ); if ( ! is_array( $presized_div_active ) ) { $presized_div_active = array(); } /** @var array $presized_div_active */ if ( ! is_array( $presized_div_notif ) ) { $presized_div_notif = array(); } /** @var array $presized_div */ foreach ( $presized_div as $presized_div_item ) { /** @var string $slot_name */ $slot_name = $presized_div_item['slotName']; if ( ! in_array( $slot_name, array_column( $presized_div_active, 'slotName' ), true ) ) { $presized_div_active[] = array( 'slotName' => $slot_name, 'active' => false, ); /** @var array<\stdclass> $presized_div_notif */ $presized_div_notif[] = $slot_name; } } /** @var array{slotName: string, active: bool} $presized_div_active_item */ foreach ( $presized_div_active as $key => $presized_div_active_item ) { $slot_name = $presized_div_active_item['slotName']; if ( ! in_array( $slot_name, array_column( $presized_div, 'slotName' ), true ) ) { unset( $presized_div_active[ $key ] ); } } Options::update( 'presizeddiv-selected', $presized_div_active ); Options::update( 'presizeddiv-actirise', $presized_div ); Options::update( 'presizeddiv-notif', $presized_div_notif ); Options::update( 'presizeddiv-lastupdate', time() ); } else { Options::update( 'presizeddiv-actirise', array() ); } } } /** * Get FastCmp stub light * * @since 2.3.0 * @return void */ public function get_fast_cmp() { $this->get_fastcmp_stublight(); $this->get_fastcmp_vendors(); if ( Options::get( 'fastcmp-uuid', '' ) === '' ) { $this->get_fastcmp_uuid(); } Options::update( 'fastcmp-lastupdate', time() ); } /** * Set auto update * * @since 2.4.0 * @param bool $enabled * @return void */ public function set_auto_update( $enabled ) { if ( ACTIRISE_CRON !== 'true' ) { return; } if ( $enabled === Helpers::has_auto_update() ) { return; } /** @var string $plugin_file */ $plugin_file = plugin_basename( ACTIRISE_FILE ); /** @var array $auto_updates */ $auto_updates = get_site_option( 'auto_update_plugins', array() ); if ( $enabled ) { $plugins = array_unique( array_merge( $auto_updates, array( plugin_basename( ACTIRISE_FILE ) ) ) ); } else { $plugins = array_values( array_diff( $auto_updates, array( plugin_basename( ACTIRISE_FILE ) ) ) ); } update_site_option( 'auto_update_plugins', $plugins ); } /** * Check if the slots XPath are present and valid in website pages * * @since 3.2.0 * @return void */ public function check_slots() { if ( ! Helpers::is_user_authenticated() ) { return; } if ( Options::get( 'contract-type' ) !== 'essential' ) { return; } $ad_format = new AdFormat(); $ad_format->validate_xpath_and_notify(); } /** * Uploads event annotations via cron task. * * This method is called by the cron system to trigger the event * annotation upload process. It delegates the actual work to the * EventAnnotation class. * * @return void * * @since 3.2.0 */ public function upload_event_annotation() { EventAnnotation::send_events(); } /** * Get FastCmp stub light * * @since 2.2.0 * @return void */ private function get_fastcmp_stublight() { $stub_light_url = 'https://static.fastcmp.com/fast-cmp-stub-light.js'; $response = wp_remote_request( $stub_light_url, array( 'method' => 'GET', 'timeout' => 10, 'sslverify' => true, ) ); if ( is_wp_error( $response ) ) { Logger::add_log( 'get_fastcmp_stublight error ' . $response->get_error_code(), 'include/cron', 'error' ); return; } /** @var string|boolean $stub_light */ $stub_light = wp_remote_retrieve_body( $response ); if ( $stub_light === false ) { return; } Options::update( 'fastcmp-stub-light', $stub_light ); } /** * Get FastCmp vendors * * @since 2.2.0 * @return void */ private function get_fastcmp_vendors() { $vendors_api_url = 'https://eu.fastcmp.com/wp/vendor-list'; $response = wp_remote_request( $vendors_api_url, array( 'method' => 'GET', 'timeout' => 10, 'sslverify' => true, ) ); if ( is_wp_error( $response ) ) { return; } /** @var string|boolean $vendors */ $vendors = wp_remote_retrieve_body( $response ); if ( $vendors === false ) { return; } /** @var string $vendors */ $vendors_json = json_decode( $vendors, true ); if ( $vendors_json === null ) { return; } Options::update( 'fastcmp-vendors', $vendors_json ); } /** * Get FastCmp uuid * * @since 2.2.0 * @return void */ private function get_fastcmp_uuid() { $fast_cmp_url = 'https://eu.fastcmp.com/wp/domain-uid?domain='; $domain = rawurlencode( Helpers::get_server_details()['host'] ); $domain = str_replace( 'www.', '', $domain ); $response = wp_remote_request( $fast_cmp_url . $domain, array( 'method' => 'GET', 'timeout' => 10, 'sslverify' => true, ) ); if ( is_wp_error( $response ) ) { return; } /** @var string|boolean $uuid */ $uuid = wp_remote_retrieve_body( $response ); if ( $uuid === false ) { return; } /** @var string $uuid */ $uuid_json = json_decode( $uuid, true ); /** @var null|array{domain?: string, domainUid?: string, error?: string} $uuid_json */ if ( $uuid_json === null ) { return; } /** @var array{domain?: string, domainUid?: string, error?: string} $uuid_json */ if ( isset( $uuid_json['error'] ) || ! isset( $uuid_json['domainUid'] ) ) { return; } Options::update( 'fastcmp-uuid', $uuid_json['domainUid'] ); } /** * Checks if a scheduled task needs to be executed based on transient expiration. * * This method uses WordPress transients to determine if a task should run. * If the transient doesn't exist (expired or never set), it creates a new one * with the specified duration and executes the callback function. * * @param string $transient_name The name of the transient to check. * @param callable $callback The function to execute if transient has expired. * @param int $duration Duration in seconds for the transient (default: 3600). * * @return bool True if the task was executed, false if it was skipped. * * @since 3.2.0 */ public function check_scheduled_task_with_transient( $transient_name, callable $callback, $duration = 3600 ) { if ( false === get_transient( $transient_name ) ) { set_transient( $transient_name, true, $duration ); call_user_func( $callback ); return true; } return false; } }