Tribe__Events__Aggregator__Record__Queue_Realtime
Facilitates “realtime” processing of an import result insertion queue while the user remains within the editor by means of an ajax update loop.
Source
File: src/Tribe/Aggregator/Record/Queue_Realtime.php
class Tribe__Events__Aggregator__Record__Queue_Realtime {
/** @var Tribe__Events__Aggregator__Record__Queue_Interface */
protected $queue;
/** @var int */
protected $record_id;
/**
* @var Tribe__Events__Ajax__Operations
*/
private $ajax_operations;
/**
* @var Tribe__Events__Aggregator__Record__Queue_Processor
*/
private $queue_processor;
/**
* The Queue_Realtime constructor method.
*
* @param Tribe__Events__Aggregator__Record__Queue_Interface|null $queue An optional Queue instance.
* @param Tribe__Events__Ajax__Operations|null $ajax_operations An optional Ajax Operations instance.
* @param Tribe__Events__Aggregator__Record__Queue_Processor|null $queue_processor An optional Queue_Processor instance.
*/
public function __construct(
Tribe__Events__Aggregator__Record__Queue_Interface $queue = null,
Tribe__Events__Ajax__Operations $ajax_operations = null,
Tribe__Events__Aggregator__Record__Queue_Processor $queue_processor = null
) {
tribe_notice( 'aggregator-update-msg', array( $this, 'render_update_message' ), 'type=warning&dismiss=0' );
add_action( 'wp_ajax_tribe_aggregator_realtime_update', array( $this, 'ajax' ) );
$this->queue = $queue;
$this->ajax_operations = $ajax_operations ? $ajax_operations : new Tribe__Events__Ajax__Operations;
$this->queue_processor = $queue_processor ? $queue_processor : tribe( 'events-aggregator.main' )->queue_processor;
}
/**
* Adds additional data to the tribe_aggregator object (available to our JS).
*/
public function update_loop_vars() {
$percentage = $this->queue->progress_percentage();
$progress = $this->sanitize_progress( $percentage );
$data = array(
'record_id' => $this->record_id,
'check' => $this->get_ajax_nonce(),
'completeMsg' => __( 'Completed!', 'the-events-calendar' ),
'progress' => $progress,
'progressText' => sprintf( __( '%d%% complete', 'the-events-calendar' ), $progress ),
);
wp_localize_script( 'tribe-ea-fields', 'tribe_aggregator_save', $data );
return $data;
}
public function render_update_message() {
if ( ! Tribe__Events__Aggregator__Page::instance()->is_screen() ) {
return;
}
/** @var Tribe__Events__Aggregator__Record__Queue_Processor $processor */
$processor = tribe( 'events-aggregator.main' )->queue_processor;
if ( ! $this->record_id = $processor->next_waiting_record( true ) ) {
return false;
}
$this->queue = $this->queue
? $this->queue
: Tribe__Events__Aggregator__Record__Queue_Processor::build_queue( $this->record_id );
if ( $this->queue->is_empty() ) {
return false;
}
$this->update_loop_vars();
ob_start();
$percent = $this->sanitize_progress( $this->queue->progress_percentage() );
$spinner = '<img src="' . get_admin_url( null, '/images/spinner.gif' ) . '">';
?>
<div class="tribe-message">
<p>
<?php esc_html_e( 'Your import is currently in progress. Don\'t worry, you can safely navigate away–the import will continue in the background.', 'the-events-calendar' ); ?>
</p>
</div>
<ul class="tracker">
<li class="tracked-item track-created"><strong><?php esc_html_e( 'Created:', 'the-events-calendar' ); ?></strong> <span class="value"></span></li>
<li class="tracked-item track-updated"><strong><?php esc_html_e( 'Updated:', 'the-events-calendar' ); ?></strong> <span class="value"></span></li>
<li class="tracked-item track-skipped"><strong><?php esc_html_e( 'Skipped:', 'the-events-calendar' ); ?></strong> <span class="value"></span></li>
</ul>
<div class="progress-container">
<div class="progress" title="<?php echo esc_html( sprintf( __( '%d%% complete', 'the-events-calendar' ), $percent ) ); ?>">
<div class="bar"></div>
</div>
<img src="<?php echo esc_url( get_admin_url( null, '/images/spinner.gif' ) ); ?>">
</div>
<?php
$html = ob_get_clean();
return Tribe__Admin__Notices::instance()->render( 'aggregator-update-msg', $html );
}
/**
* Handle queue ajax requests
*/
public function ajax() {
$this->record_id = (int) $_POST['record'];
// Nonce check
$this->ajax_operations->verify_or_exit( $_POST['check'], $this->get_ajax_nonce_action(), $this->get_unable_to_continue_processing_data() );
// Load the queue
/** @var \Tribe__Events__Aggregator__Record__Queue_Interface $queue */
$queue = $this->queue ? $this->queue : Tribe__Events__Aggregator__Record__Queue_Processor::build_queue( $this->record_id );
// We always need to setup the Current Queue
$this->queue_processor->set_current_queue( $queue );
// Only if it's not empty that we care about processing.
if ( ! $queue->is_empty() ) {
$this->queue_processor->process_batch( $this->record_id );
}
/**
* Include current queue to prevent progress bar from sticking on csv imports
*
* @var \Tribe__Events__Aggregator__Record__Queue_Interface $current_queue
*/
$current_queue = $this->queue_processor->current_queue;
$done = $current_queue->is_empty() && empty( $current_queue->is_fetching );
$percentage = $current_queue->progress_percentage();
$this->ajax_operations->exit_data( $this->get_progress_message_data( $current_queue, $percentage, $done ) );
}
/**
* @param $percentage
*
* @return int|string
*/
private function sanitize_progress( $percentage ) {
if ( $percentage === true ) {
return 100;
}
return is_numeric( $percentage ) ? intval( $percentage ) : 0;
}
/**
* @return string
*/
public function get_ajax_nonce() {
return wp_create_nonce( $this->get_ajax_nonce_action() );
}
/**
* Generates the nonce action string on an event and user base.
*
* @param int|null $event_id An event post ID to override the instance defined one.
*
* @return string
*/
public function get_ajax_nonce_action( $record_id = null ) {
$record_id = $record_id ? $record_id : $this->record_id;
return 'tribe_aggregator_insert_items_' . $record_id . get_current_user_id();
}
/**
* @return mixed|string|void
*/
public function get_unable_to_continue_processing_data() {
return json_encode( array(
'html' => __( 'Unable to continue inserting data. Please reload this page to continue/try again.', 'the-events-calendar' ),
'progress' => false,
'continue' => false,
'complete' => false,
) );
}
/**
* Returns the progress message data.
*
* @param Tribe__Events__Aggregator__Record__Queue_Interface $queue
* @param int $percentage
* @param bool $done
*
* @return mixed|string|void
*/
public function get_progress_message_data( $queue, $percentage, $done ) {
$queue_type = $queue->get_queue_type();
$is_event_queue = $queue_type === Tribe__Events__Main::POSTTYPE;
$activity = $queue->activity();
$error = $queue->has_errors();
$data = array(
'html' => false,
'progress' => $percentage,
'progress_text' => sprintf( __( '%d%% complete', 'the-events-calendar' ), $percentage ),
'continue' => ! $done,
'complete' => $done,
'error' => $error,
'counts' => array(
'total' => $activity->count( $queue_type ),
'created' => $activity->count( $queue_type, 'created' ),
'updated' => $activity->count( $queue_type, 'updated' ),
'skipped' => $activity->count( $queue_type, 'skipped' ),
'category' => $activity->count( 'category', 'created' ),
'images' => $activity->count( 'images', 'created' ),
'venues' => $is_event_queue ? $activity->count( 'venues', 'created' ) : 0,
'organizers' => $is_event_queue ? $activity->count( 'organizer', 'created' ) : 0,
'remaining' => $queue->count(),
),
);
$messages = Tribe__Events__Aggregator__Tabs__New::instance()->get_result_messages( $queue );
if ( $error ) {
$data['error_text'] = '<p>' . implode( ' ', $messages['error'] ) . '</p>';
} elseif ( $done ) {
$data['complete_text'] = '<p>' . implode( ' ', $messages['success'] ) . '</p>';
}
return json_encode( $data );
}
}
Methods
- __construct — The Queue_Realtime constructor method.
- ajax — Handle queue ajax requests
- get_ajax_nonce
- get_ajax_nonce_action — Generates the nonce action string on an event and user base.
- get_progress_message_data — Returns the progress message data.
- get_unable_to_continue_processing_data
- receive_heartbeat — Action to reply every time a heart beat is executed to send the progress of EA if an EA record is present.
- render_update_message
- update_loop_vars — Adds additional data to the tribe_aggregator object (available to our JS).