oont-contents/plugins/webappick-product-feed-for-woocommerce/V5/Helper/CronHelper.php
2025-03-31 21:42:48 +02:00

834 lines
27 KiB
PHP

<?php
/**
* Cron Helper
*
* @package CTXFeed\V5\Helper
*/
namespace CTXFeed\V5\Helper;
use CTXFeed\V5\Common\Helper;
use CTXFeed\V5\Feed\Feed;
use CTXFeed\V5\Product\AttributeValueByType;
use CTXFeed\V5\Query\QueryFactory;
use CTXFeed\V5\Utility\Cache;
use CTXFeed\V5\Utility\Config;
use CTXFeed\V5\Utility\Logs;
use CTXFeed\V5\Utility\Settings;
/**
* Developer written Documentation for Woo Feed Update Cron Job
*
* Write a developer doc comment for CTX Feed cron job which I build. So that, other developer can understand it. And can modify it if needed.
* Write the documentation as function doc comment. So that, it can be used as a documentation whole process.
*
* The functionality of this suppose, I have 100000 woo commerce products
* and with my ctx feed plugin I create an XML file for Google shop/Facebook catalog etc,
* after XML/CSV/txt feed generation I register a cron job named "woo_feed_update_${option_name}"
* as products are 100000 during cron job action it will not be able to generate feed because of
* memory limit and maximum execution time. So, I have created sub batches for the feed which is
* also basically a cron job. The sub-batch name will be
* wf_store_auto_feed_body_info_${option_name}_0,
* wf_store_auto_feed_body_info_${option_name}_1,
* wf_store_auto_feed_body_info_${option_name}_2
* .........
* during feed creation parent batch which is "woo_feed_update_${option_name}"
* time will be the default interval time only if products are less than $cron_job_per_batch (5000 products).
* if more than that then the interval will be 1 hour. Though our products are 100000 then interval will be 1 hour.
* Now sub-batch time interval will 1 year. So it can't be run by cron job automatically, actually be before parent cron job.
* The name of parent cron job "woo_feed_update_${option_name}" will be added to transient cache for 1 year. The cache name will be "woo_feed_cron_list".
* "woo_feed_cron_list" will an array of all the parent cron job names.
*
* And another cache will be "woo_feed_update_${option_name}" here all data will be stored for the parent cron job. Example
* array(
* 'product_ids' => [1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
* 'feed_name' => ${option_name},
* 'hook_name' => "woo_feed_update_${option_name}"
* )
*
* And another cache will be "woo_feed_sub_cron_list" which will be an array of all the sub-batch cron job names.
* Example array(
* "wf_store_auto_feed_body_info_${option_name}_0",
* "wf_store_auto_feed_body_info_${option_name}_1",
* "wf_store_auto_feed_body_info_${option_name}_2",
* "wf_store_auto_feed_body_info_${option_name}_3",
* "wf_store_auto_feed_body_info_${option_name}_4",
* )
*
* Sub bath cron job cache will be like this "wf_store_auto_feed_body_info_${option_name}_0" => array(
* 'feed_name' => "${option_name}",
* 'option' => "",
* 'total_offset' => 1,
* 'parent_hook_name' => "woo_feed_update_${option_name}",
* 'product_ids' => [1, 3, 4, 5, ... ],
* 'offset' => 0,
* 'hook_name' => "wf_store_auto_feed_body_info_${option_name}_0",
* );
*
* Now when the parent cron job will be executed it will get the product ids from the cache "woo_feed_update_${option_name}".
* Then it will create sub-batches for the product ids. And will create sub-batch cron jobs. Batch will be created depending on the product ids.
* If product ids are 100000 then 20 sub-batches will be created. Because the product batch safe limit is 5000. The execution time sub batches are
* 1rst sub-batch will be executed immediately. And the 2nd the sub-batches will be executed after 1 minute. And the 3rd sub-batches will be executed
* 2 minutes later. And so on. And the last sub-batch will be executed after 19 minutes. When finally the last sub-batch will be executed then all
* files will be merged with header and footer into 1 file named "${option_name}.${file_extentsion}". And all the sub-batch files will be deleted.
*
* Now all sub-batch cron jobs will be executed after 1 year. And the parent cron job will be executed after 1 hour.
*/
/**
* AI Generated Feed Cron Job Documentation for CTX Feed Plugin Feed Generation.
*
* WordPress Cron Job Documentation for CTX Feed Plugin Feed Generation.
*
* This cron job automates the generation of feed files (XML, CSV, TXT, etc.) for Google Shopping, Facebook Catalog, etc.,
* from a vast pool of 100,000 Woo Commerce products. The process is designed to overcome memory and execution time
* constraints by splitting it into a parent cron job and sub-batch cron jobs.
*
* @since 7.0.0
* @see woo_feed_update_${option_name}
* @see wf_store_auto_feed_body_info_${option_name}_0, wf_store_auto_feed_body_info_${option_name}_1, ...
*
* ## Parent Cron Job:
* - **Name:** `woo_feed_update_${option_name}`
* - **Interval:** Default if products < $cron_job_per_batch, else 1 hour.
* - **Cache:** Stored in `woo_feed_cron_list` for 1 year.
* - **Cache Content (Example):**
* ```
* array(
* 'product_ids' => [1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
* 'feed_name' => ${option_name},
* 'hook_name' => "woo_feed_update_${option_name}"
* )
* ```
*
* ## Sub-Batch Cron Jobs:
* - **Name Format:** `wf_store_auto_feed_body_info_${option_name}_0`, ...
* - **Interval:** 1 year (manually triggered before the parent cron job).
* - **Cache:** Stored in `woo_feed_sub_cron_list`.
* - **Cache Content (Example):**
* ```
* array(
* "wf_store_auto_feed_body_info_${option_name}_0",
* "wf_store_auto_feed_body_info_${option_name}_1",
* ...
* )
* ```
*
* ## Sub-Batch Cron Job Cache:
* - **Cache Format:** `wf_store_auto_feed_body_info_${option_name}_0`
* - **Content (Example):**
* ```
* array(
* 'feed_name' => "${option_name}",
* 'option' => "",
* 'total_offset' => 1,
* 'parent_hook_name' => "woo_feed_update_${option_name}",
* 'product_ids' => [1, 3, 4, 5, ... ],
* 'offset' => 0,
* 'hook_name' => "wf_store_auto_feed_body_info_${option_name}_0",
* )
* ```
*
* ## Execution Flow:
* - Parent cron job fetches product IDs from either `woo_feed_update_${option_name}` cache or QueryFactor class based on $config object.
* - Sub-batches are created with staggered execution times.
* - Sub-batch cron jobs are scheduled for immediate and 1-minute interval execution.
* - The last sub-batch executes after 19 minutes.
* - Files are merged into `${option_name}.${file_extension}`, and sub-batch files are deleted.
* - Sub-batch cron jobs run after 1 year, and the parent cron job runs after 1 hour.
*/
/**
* Class CronHelper
* @package CTXFeed\V5\Helper
*
* @since 7.3.0
*/
class CronHelper { // phpcs:ignore
/**
* Cron Settings.
*
* @var array
*/
private static $settings = array();
/**
* Product Batch Safe Limit.
*
* @var int
*/
private static $cron_job_per_batch = 5000;
/**
* Cache Expiration.
*
* @var int
*/
private static $cache_expiration = YEAR_IN_SECONDS;
/**
* Cache Prefix.
*
* @var string
*/
private static $cache_prefix = '__woo_feed_auto_update_cache_';
/**
* Constructor
*/
public function __construct() {
$cron_per_batch_setting = Settings::get( 'cron_job__per_batch__safe_limit' );
if($cron_per_batch_setting) {
self::$cron_job_per_batch = $cron_per_batch_setting;
}
if (!isset(self::$settings['sub_feed_body_prefix'])) {
self::set_cron_settings();
}
// Delete current feed cron jobs.
add_action( 'woo_feed_before_product_loop', array( $this, 'clear_cron_schedule_before_product_query' ), 10, 3 );
add_action( 'woo_feed_after_product_loop', array( $this, 'schedule_cron_job_after_product_query' ), 10, 3 );
// Add cron job for all feeds.
$feed_cron_list = self::get_cache( 'woo_feed_cron_list' );
if ( ! empty( $feed_cron_list ) ) {
foreach ( $feed_cron_list as $feed_cron_hook_name ) {
add_action( $feed_cron_hook_name, array( $this, 'woo_feed_cron_update_single_feed' ), 10, 1 );
}
}
// Add cron job for all feeds sub batches.
$feed_sub_cron_list = self::get_cache( 'woo_feed_sub_cron_list' );
if ( ! empty( $feed_sub_cron_list ) ) {
foreach ( $feed_sub_cron_list as $feed_sub_cron_hook_name ) {
add_action( $feed_sub_cron_hook_name, array( $this, 'woo_feed_cron_update_batched_feed' ), 10, 1 );
}
}
// Handle old feed.
add_action( 'woo_feed_update_single_feed', array( $this, 'handle_old_single_feed' ), 10, 1 );
// Delete old woo_feed_update cron job.
if ( ! self::get_cache( 'is_deleted__woo_feed_update__cron_job' ) || self::is_cron_exits( 'woo_feed_update' ) ) {
self::delete_cron_job( 'woo_feed_update' );
return;
}
self::set_cache( 'is_deleted__woo_feed_update__cron_job', true );
}
/**
* Get Cron Hook Name.
*
* @param string $feed_name Feed Name.
* @param bool $is_single_hook Is Single Hook.
*
* @return string
*/
public static function get_cron_hook_name( $feed_name, $is_single_hook = false ) {
$feed_name = str_replace( 'wf_feed_', '', $feed_name );
$feed_name = str_replace( 'wf_config', '', $feed_name );
if(!isset(self::$settings['single_feed_hook_prefix'])) {
self::set_cron_settings();
}
if ( $is_single_hook ) {
if ( strpos( $feed_name, self::$settings['single_feed_hook_prefix'] ) === false ) {
$hook_name = self::$settings['single_feed_hook_prefix'] . $feed_name;
} else {
$hook_name = $feed_name;
}
} elseif ( strpos( $feed_name, self::$settings['sub_feed_body_prefix'] ) === false ) {
$hook_name = self::$settings['sub_feed_body_prefix'] . $feed_name;
} else {
$hook_name = $feed_name;
}
return $hook_name;
}
/**
* Delete Cron Job.
*
* @param string $hook_name Cron Hook Name.
*
* @return void
*/
public static function delete_cron_job( $hook_name, $arg_value = false ) {
// !IMPORTANT:: delete also sub hooks.
$crons = _get_cron_array();
$updated = array_filter(
$crons,
function ( $v ) use ( $hook_name, $arg_value ) {
// If arg value is set then check with arg value.
if ( $arg_value && array_key_exists( $hook_name, $v ) ) {
$cron_job = $v[ $hook_name ];
$args = array_values( $cron_job );
foreach ( $args as $arg ) {
if ( isset( $arg['args'] ) && in_array( $arg_value, $arg['args'] ) ) {
return false;
}
}
return true;
} else {
return ! array_key_exists( $hook_name, $v );
}
}
);
_set_cron_array( $updated );
}
/**
* Delete Cron Job.
*
* @param string $hook_name Cron Hook Name.
*
* @return bool
*/
public static function is_cron_exits( $hook_name ) {
// !IMPORTANT:: delete also sub hooks.
$crons = _get_cron_array();
$is_cron_exists = array_filter(
$crons,
function ( $v ) use ( $hook_name ) {
return array_key_exists( $hook_name, $v );
}
);
return ! empty( $is_cron_exists );
}
/**
* Add Cron Job.
*
* @param string $hook_name Cron Hook Name.
* @param bool $is_single_hook Is Single Hook.
*
* @return void
*/
public static function add_cron_job( $hook_name, $is_single_hook ) {
$hook_name = self::get_cron_hook_name( $hook_name, $is_single_hook );
self::delete_cron_job( $hook_name );
if ( wp_next_scheduled( $hook_name, array( $hook_name ) ) ) {
return;
}
$interval = self::get_feed_cron_interval();
wp_schedule_event( time() + $interval, 'woo_feed_corn', $hook_name, array( $hook_name ) );
}
/**
* Schedule Cron Job For Sub Batches.
*
* @param string $feed_name Feed Name.
* @param array $cron_batched_ids Cron Batched Ids.
* @param array $batch_data Batch Data.
* @param array $option Feed Option.
* @param bool $execute_now Execute Now or Not.
*
* @return void
*/
private function schedule_cron_job_for_sub_batches( // phpcs:ignore
$feed_name,
$cron_batched_ids,
$batch_data,
$option,
$execute_now = false
) { // phpcs:ignore
$feed_name = str_replace( 'wf_config', 'wf_feed_', $feed_name );
$time = 0;
$current_batch_data = array(
'feed_name' => $feed_name,
'option' => $option,
'total_offset' => count( $cron_batched_ids ) - 1,
'parent_hook_name' => $batch_data['hook_name'],
);
if (!isset(self::$settings['sub_feed_body_prefix'])) {
self::set_cron_settings();
}
foreach ( $cron_batched_ids as $index => $batch_ids ) {
$current_batch_name = $feed_name . '_' . $index;
$current_batch_feed_cron_hook_name = self::$settings['sub_feed_body_prefix'] . $current_batch_name;
$current_batch_data['product_ids'] = $batch_ids;
$current_batch_data['offset'] = $index;
$current_batch_data['hook_name'] = $current_batch_feed_cron_hook_name;
// Delete sub batch cron job. And reschedule it.
self::delete_cron_job( $current_batch_feed_cron_hook_name );
if ( wp_next_scheduled( $current_batch_feed_cron_hook_name, array( $current_batch_feed_cron_hook_name ) ) ) {
continue;
}
// Delete sub batch data if exists. And set new data.
if ( self::get_cache( $current_batch_feed_cron_hook_name ) ) {
self::delete_cache( $current_batch_feed_cron_hook_name );
}
self::set_cache( $current_batch_feed_cron_hook_name, wp_json_encode( $current_batch_data ) );
if ( $execute_now ) {
if ( $index > 0 ) {
$time += self::$settings['sub_batch_update_interval'];
}
wp_schedule_event( time() + $time, 'woo_feed_corn', $current_batch_feed_cron_hook_name, array( $current_batch_feed_cron_hook_name ) );
} else {
wp_schedule_event( time() + YEAR_IN_SECONDS, 'woo_feed_corn', $current_batch_feed_cron_hook_name, array( $current_batch_feed_cron_hook_name ) );
}
}
}
/**
* Clear Cron Schedule Before Update Config.
*
* @param array $product_ids Product Ids.
* @param array $feed_rules Feed Rules.
* @param \CTXFeed\V5\Utility\Config $config Config.
*
* @return void
*/
public function clear_cron_schedule_before_product_query( $product_ids, $feed_rules, $config ) { // phpcs:ignore
$feed_name = $config->get_feed_option_name();
if ( ! $feed_name ) {
return;
}
if (!isset(self::$settings['single_feed_hook_prefix'])) {
self::set_cron_settings();
}
self::delete_cron_job( self::$settings['single_feed_hook_prefix'] . $feed_name );
}
/**
* Schedule Cron Job After Product Query.
*
* @param array $product_ids Product Ids.
* @param array $feed_rules Feed Rules.
* @param \CTXFeed\V5\Utility\Config $config Config.
*
* @return void
*/
public function schedule_cron_job_after_product_query( $product_ids, $feed_rules, $config ) { // phpcs:ignore
$cron_batched_ids = $this->get_cron_batches( $product_ids );
$interval = self::get_feed_cron_interval( $product_ids );
$feed_name = $config->get_feed_option_name();
if ( ! $feed_name ) {
return;
}
if (!isset(self::$settings['single_feed_hook_prefix'])) {
self::set_cron_settings();
}
$feed_cron_hook_name = self::$settings['single_feed_hook_prefix'] . $feed_name;
$batch_data = array(
'product_ids' => $product_ids,
'feed_name' => $feed_name,
'hook_name' => $feed_cron_hook_name,
);
if ( ! wp_next_scheduled( $feed_cron_hook_name, array( $feed_cron_hook_name ) ) ) {
if ( self::get_cache( $feed_cron_hook_name ) ) {
self::delete_cache( $feed_cron_hook_name );
}
self::set_cache( $feed_cron_hook_name, wp_json_encode( $batch_data ) );
if ( self::get_cache( 'woo_feed_cron_list' ) ) {
$feed_cron_list = self::get_cache( 'woo_feed_cron_list' );
if ( is_array( $feed_cron_list ) && ! in_array( $feed_cron_hook_name, $feed_cron_list ) ) { // phpcs:ignore
$feed_cron_list[] = $feed_cron_hook_name;
self::set_cache( 'woo_feed_cron_list', $feed_cron_list );
}
} else {
self::set_cache( 'woo_feed_cron_list', array( $feed_cron_hook_name ) );
}
wp_schedule_event( time() + $interval, 'woo_feed_corn', $feed_cron_hook_name, array( $feed_cron_hook_name ) );
}
if ( ! count( $cron_batched_ids ) ) {
return;
}
foreach ( $cron_batched_ids as $index => $batch_ids ) { // phpcs:ignore
$current_batch_name = $feed_name . '_' . $index;
$current_batch_feed_cron_hook_name = self::$settings['sub_feed_body_prefix'] . $current_batch_name;
self::delete_cron_job( $current_batch_feed_cron_hook_name );
if ( wp_next_scheduled( $current_batch_feed_cron_hook_name, array( $current_batch_feed_cron_hook_name ) ) ) {
continue;
}
if ( self::get_cache( 'woo_feed_sub_cron_list' ) ) {
$feed_sub_cron_list = self::get_cache( 'woo_feed_sub_cron_list' );
if (
is_array( $feed_sub_cron_list )
&& ! in_array( $current_batch_feed_cron_hook_name, $feed_sub_cron_list ) // phpcs:ignore
) { // phpcs:ignore
$feed_sub_cron_list[] = $current_batch_feed_cron_hook_name;
self::set_cache( 'woo_feed_sub_cron_list', $feed_sub_cron_list );
}
} else {
self::set_cache( 'woo_feed_sub_cron_list', array( $current_batch_feed_cron_hook_name ) );
}
wp_schedule_event( time() + YEAR_IN_SECONDS, 'woo_feed_corn', $current_batch_feed_cron_hook_name, array( $current_batch_feed_cron_hook_name ) );
}
}
/**
* Scheduled Action Hook For Old Single Cron Jobs.
*
* @param string $option_name Old single cron job name which will be 'woo_feed_update_single_feed'.
*
* @return void
*/
public function handle_old_single_feed( $option_name ) {
$results = Feed::get_single_feed( $option_name ); // phpcs:ignore
// If results variable is empty then check with "AttributeValueByType::FEED_RULES_OPTION_PREFIX" prefix.
if ( empty( $results ) ) {
$option_name_with_prefix = AttributeValueByType::FEED_RULES_OPTION_PREFIX . $option_name;
$results = Feed::get_single_feed( $option_name_with_prefix ); // phpcs:ignore
// If results variable is empty then check with "wf_config" prefix.
if ( empty( $results ) ) {
$option_name_with_prefix = 'wf_config' . $option_name;
$results = Feed::get_single_feed( $option_name_with_prefix ); // phpcs:ignore
// If results variable is empty then delete the "woo_feed_update_single_feed".
if ( empty( $results ) ) {
self::delete_cron_job( 'woo_feed_update_single_feed', $option_name );
return;
}
}
}
$feed_info = $results[0];
if ( ! isset( $feed_info['option_value']['feedrules'] ) ) {
self::delete_cron_job( 'woo_feed_update_single_feed', $option_name );
return;
}
$config = new Config( $feed_info );
// Hook Before Query Products
do_action( 'before_woo_feed_get_product_information', $config );
// Get Product Ids
$ids = QueryFactory::get_ids( $config, array() );
// Hook After Query Products
do_action( 'after_woo_feed_get_product_information', $config );
if ( ! empty( $ids ) ) {
$this->schedule_cron_job_after_product_query( $ids, $feed_info['option_value']['feedrules'], $config );
}
self::delete_cron_job( 'woo_feed_update_single_feed', $option_name );
}
/**
* Execute Single Feed Cron Job And Schedule Sub Batch Cron Jobs.
*
* @param string $cache_key Single cron job key.
*
* @return void
*/
public function woo_feed_cron_update_single_feed( $cache_key ) {
$batch_data = self::get_cache( $cache_key );
$batch_data = json_decode( $batch_data, true );
if (
empty( $batch_data )
|| ! isset( $batch_data['feed_name'] )
|| ! isset( $batch_data['hook_name'] )
|| ! isset( $batch_data['product_ids'] )
) {
return;
}
$feed_name = $batch_data['feed_name'];
$feed_option_name = AttributeValueByType::FEED_RULES_OPTION_PREFIX . $feed_name;
$results = Feed::get_single_feed( $feed_option_name ); // phpcs:ignore
if ( empty( $results ) ) {
$hook_name = $batch_data['hook_name'];
self::delete_cron_job( $hook_name );
return;
}
$option = $results[0];
$feed_info = $option['option_value'];
if ( ! isset( $feed_info['feedrules'] ) || isset( $feed_info['status'] ) && '0' === $feed_info['status'] ) {
return;
}
$config = new Config( $option );
// Hook Before Query Products
do_action( 'before_woo_feed_get_product_information', $config );
// Get Product Ids
$ids = QueryFactory::get_ids( $config, array() );
// Get Cron Batches
$batch_data['product_ids'] = $ids;
self::delete_cache( $batch_data['hook_name'] );
self::set_cache( $batch_data['hook_name'], wp_json_encode( $batch_data ) );
$cron_batched_ids = $this->get_cron_batches( $ids );
// Hook After Query Products
do_action( 'after_woo_feed_get_product_information', $config );
if ( ! count( $cron_batched_ids ) ) {
return;
}
$this->schedule_cron_job_for_sub_batches( $feed_name, $cron_batched_ids, $batch_data, $option, true );
}
/**
* Execute Sub Batch Cron Job And Merge All Sub Batched Feed Files Into A Single Feed File.
*
* @param string $cache_key Sub batch cache key.
*
* @return void
*/
public function woo_feed_cron_update_batched_feed( $cache_key ) { // phpcs:ignore
$batch_data = self::get_cache( $cache_key );
$batch_data = json_decode( $batch_data, true );
// Check if the batch data is valid.
if (
empty( $batch_data )
|| ! isset( $batch_data['product_ids'] )
|| ! isset( $batch_data['offset'] )
|| ! isset( $batch_data['option'] )
|| ! isset( $batch_data['total_offset'] )
|| ! isset( $batch_data['parent_hook_name'] )
) {
return;
}
$product_ids = $batch_data['product_ids'];
$offset = $batch_data['offset'];
$option = $batch_data['option'];
$feed_info = $option['option_value'];
$should_update_last_update_time = false;
if ( $offset === $batch_data['total_offset'] ) {
$should_update_last_update_time = true;
}
try {
$option = FeedHelper::validate_feed( $option );
// Create a new prefix for the current feed body.
add_filter(
'woo_feed_temp_feed_body_prefix',
function ( $prefix ) use ( $offset ) {
if ( $offset === 0 ) {
$prefix_arr = $prefix . $offset . '_';
} else {
$prefix_arr = explode( '_', $prefix );
foreach ( $prefix_arr as $key => $value ) {
if ( ! is_numeric( $value ) ) {
continue;
}
unset( $prefix_arr[ $key ] );
}
$prefix_arr = implode( '_', $prefix_arr ) . $offset . '_';
}
return $prefix_arr;
},
999,
1
);
// Generate feed for the current sub batch.
FeedHelper::generate_cron_batched_feed( $option, $offset, $should_update_last_update_time, $product_ids );
} catch ( \CTXFeed\V5\Helper\Exception $e ) {
$message = 'Error Updating Feed Via CRON Job' . PHP_EOL . 'Caught Exception :: ' . $e->getMessage();
Logs::write_log( $feed_info['feedrules']['filename'], $message, 'critical', $e, true );
Logs::write_fatal_log( $message, $e );
}
/**
* IF current sub batch is last batch for the feed, then update the last update time.
* And merge all the sub batched feed files into a single feed file.
* Then delete all the sub batched feed files.
*/
if ( ! $should_update_last_update_time ) {
return;
}
FeedHelper::save_cron_batched_feed_files( $option, $should_update_last_update_time, true );
$parent_hook_name = $batch_data['parent_hook_name'];
$parent_batch_data = self::get_cache( $parent_hook_name );
$parent_batch_data = json_decode( $parent_batch_data, true );
$cron_batches = $this->get_cron_batches( $parent_batch_data['product_ids'] );
// Reschedule parent cron job.
self::delete_cron_job( $parent_hook_name );
$interval = self::get_feed_cron_interval( $parent_batch_data['product_ids'] );
wp_schedule_event( time() + $interval, 'woo_feed_corn', $parent_hook_name, array( $parent_hook_name ) );
$this->schedule_cron_job_for_sub_batches( $batch_data['feed_name'], $cron_batches, $parent_batch_data, $option, false );
}
/**
* Get Cron Batches
*
* @param array $product_ids of product ids.
*
* @return array
*/
public function get_cron_batches( $product_ids ) {
return array_chunk( $product_ids, self::$settings['product_batch_safe_limit'] );
}
/**
* Get Feed Cron Interval
*
* !IMPORTANT Feed update interval should be single feed based. Currently it is global.
*
* @param array $product_ids of product ids.
*
* @return int
*/
private static function get_feed_cron_interval( $product_ids = array() ) {
/**
* !IMPORTANT: Feed update interval should be single feed based. Currently it is global.
* If a single feed has 10000 products and another feed has 100 products, then the feed with 10000 products will take more time to update.
* So, the feed with 100 products will be updated more frequently than the feed with 10000 products.
*/
$interval = absint( get_option( 'wf_schedule' ) );
if ( ! $interval ) {
$interval = 3600;
}
if (!isset(self::$settings['product_batch_safe_limit'])) {
self::set_cron_settings();
}
$cron_job_per_batch = self::$cron_job_per_batch;
if ( isset( self::$settings['product_batch_safe_limit'] ) ) {
$cron_job_per_batch = self::$settings['product_batch_safe_limit'];
}
if ( count( $product_ids ) > $cron_job_per_batch && $interval < 3600 ) {
$interval = 3600;
}
return apply_filters( 'woo_feed_cron_interval', $interval );
}
/**
* Set Cache Data For Cron Job.
*
* @param string $key Cache Key.
* @param mixed $value Cache Value.
*
* @return void
*/
private static function set_cache( $key, $value ) {
update_option( self::$cache_prefix . $key, $value );
}
/**
* Get Cache Data For Cron Job.
*
* @param string $key Cache Key.
*
* @return mixed
*/
private static function get_cache( $key ) {
$cache = Cache::get( $key, self::$cache_prefix );
if ( $cache ) {
self::set_cache( $key, $cache );
Cache::delete( $key, self::$cache_prefix );
}
return get_option( self::$cache_prefix . $key );
}
/**
* Delete Cache Data For Cron Job.
*
* @param string $key Cache Key.
*/
private static function delete_cache( $key ) {
Cache::delete( $key, self::$cache_prefix );
delete_option( self::$cache_prefix . $key );
}
/**
* Set Cron Settings.
*
* @return void
*/
public static function set_cron_settings()
{
self::$settings = apply_filters(
'woo_feed_cron_settings',
array(
'product_batch_safe_limit' => self::$cron_job_per_batch,
'sub_batch_update_interval' => 10,
'sub_feed_body_prefix' => FeedHelper::get_feed_body_temp_prefix(true),
'single_feed_hook_prefix' => 'woo_feed_update_',
)
);
}
/**
* Is Cron Enabled.
*
* @return bool
*/
private static function is_cron_enabled()
{
return apply_filters('ctx_feed_cron_enabled', Helper::should_init_new_cron_system());
}
}