<?php
/**
* Queue class for migration handling.
*
* @since 4.12.0
*/
namespace Tribe\Tickets\Migration;
/**
* Class Queue
*
* @package Tribe\Tickets\Migration
*/
class Queue {
/**
* Queue Identifier.
*
* @since 4.12.0
*
* @var string
*/
public $queue_id = '';
/**
* Which action will be triggered as an single cron event.
*
* @since 4.12.0
*
* @var string
*/
protected $single_key;
/**
* Which action will be triggered as an ongoing scheduled cron event.
*
* @since 4.12.0
*
* @var string
*/
protected $scheduled_key;
/**
* Batch offset key used to track migration progress.
*
* @since 4.12.0
*
* @var string
*/
protected $batch_offset_key;
/**
* Number of items to be processed in a single batch.
*
* @since 4.12.0
*
* @var int
*/
protected $batch_size = 200;
/**
* Queue Hooks.
*
* @since 4.12.0
*/
public function hooks() {
if ( null === $this->single_key ) {
$this->single_key = 'tribe_tickets_migrate_single_' . $this->queue_id;
}
if ( null === $this->scheduled_key ) {
$this->scheduled_key = 'tribe_tickets_migrate_' . $this->queue_id;
}
if ( null === $this->batch_offset_key ) {
$this->batch_offset_key = 'tribe_tickets_migrate_offset_' . $this->batch_offset_key;
}
add_action( $this->single_key, [ $this, 'process_queue' ], 20, 0 );
add_action( $this->scheduled_key, [ $this, 'process_queue' ], 20, 0 );
// We can add custom ET+ deactivation handling based on TEC, but this isn't needed right now.
add_action( 'tribe_events_blog_deactivate', [ $this, 'clear_scheduled_task' ] );
}
/**
* Register scheduled task to be used for processing batches on plugin activation.
*
* @since 4.12.0
*/
public function register_scheduled_task() {
if ( wp_next_scheduled( $this->scheduled_key ) ) {
return;
}
$interval = $this->get_cron_interval();
if ( null === $interval ) {
return;
}
wp_schedule_event( time(), $interval, $this->scheduled_key );
}
/**
* Clear the scheduled task on plugin deactivation.
*
* @since 4.12.0
*/
public function clear_scheduled_task() {
wp_clear_scheduled_hook( $this->scheduled_key );
}
/**
* Processes the next waiting batch of orders to migrate, if there are any.
*
* @since 4.12.0
*
* @param null|int $batch_size Batch processing size override.
*/
public function process_queue( $batch_size = null ) {
if ( null === $batch_size ) {
$batch_size = $this->get_batch_size();
}
$current_offset = $this->get_current_offset();
if ( 'complete' === $current_offset ) {
$this->clear_scheduled_task();
return;
}
$this->batch_size = (int) $batch_size;
$processed = $this->process( $current_offset );
// if no items are processed or not processed clear the task.
if ( empty( $processed['processed'] ) && empty( $processed['not_processed'] ) ) {
update_option( $this->batch_offset_key, 'complete', false );
$this->clear_scheduled_task();
return;
}
$this->update_offset( $processed['not_processed'] );
}
/**
* Processes the next waiting batch of orders to migrate, if there are any.
*
* @since 4.12.0
*
* @param int $current_offset The current offset being used.
*
* @return array List of processed and not processed counts.
*/
public function process( $current_offset = 0 ) {
$counts = [
'processed' => 0,
'not_processed' => 0,
];
$posts = $this->get_posts( $current_offset );
if ( empty( $posts ) ) {
return $counts;
}
foreach ( $posts as $post ) {
$processed = $this->process_post( $post );
if ( $processed ) {
$counts['processed'] ++;
} else {
$counts['not_processed'] ++;
}
}
return $counts;
}
/**
* Process post in queue.
*
* @since 4.12.0
*
* @param WP_Post|int $post The post object or post ID, depending on what $this->get_query() is set to return.
*
* @return bool Whether the post was processed.
*/
public function process_post( $post ) {
return false;
}
/**
* Get posts for migrating.
*
* @since 4.12.0
*
* @param int $current_offset The current offset being used.
*
* @return int[]|WP_Post[] List of post IDs or post objects.
*/
public function get_posts( $current_offset ) {
return [];
}
/**
* Get the Current offset number.
*
* @since 4.12.0
*
* @return string|int Current offset number.
*/
public function get_current_offset() {
$current_offset = get_option( $this->batch_offset_key );
// Set up default current offset.
if ( false === $current_offset || '' === $current_offset ) {
$current_offset = 0;
}
return $current_offset;
}
/**
* Update the Offset Number with the Current Batch.
*
* @since 4.12.0
*
* @param int $not_processed the number of orders not processed.
*/
protected function update_offset( $not_processed ) {
$current_offset = $this->get_current_offset();
// Only set if numeric.
if ( ! is_numeric( $current_offset ) ) {
return;
}
$current_offset = (int) $current_offset;
$current_offset += $not_processed;
update_option( $this->batch_offset_key, $current_offset, false );
}
/**
* Get the size to be used by each batch processed.
*
* @since 4.12.0
*
* @return int The batch size used by the migration.
*/
protected function get_batch_size() {
/**
* Controls the size of each batch processed by default (ie, during cron updates of record inserts/updates).
*
* @since 4.12.0
*
* @param int $batch_size The batch size used by the migration.
*/
return (int) apply_filters( "tribe_tickets_migration_queue_batch_size_{$this->queue_id}", $this->batch_size );
}
/**
* Get the cron interval to be used by each batch processed.
*
* @since 4.12.0
*
* @return int The batch size used by the migration.
*/
protected function get_cron_interval() {
/**
* Filter the interval at which to process the migration queue.
*
* By default the interval "hourly" is specified, however other intervals such as "daily"
* and "twicedaily" can normally be substituted.
*
* @since 4.12.0
*
* @param string|null $interval Cron interval or null to disable it.
*
* @see 'cron_schedules'
*
* @see wp_schedule_event()
*/
return apply_filters( "tribe_tickets_migration_queue_interval_{$this->queue_id}", 'hourly' );
}
}
|