Making background processes and importers store progress #62
This commit is contained in:
parent
b94a39689a
commit
9eec2bb4b2
|
@ -105,14 +105,17 @@ abstract class Background_Process extends \WP_Background_Process {
|
|||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function update( $key, $data ) {
|
||||
public function update( $key, $batch ) {
|
||||
$data = $batch->data;
|
||||
if ( ! empty( $data ) ) {
|
||||
global $wpdb;
|
||||
$wpdb->update(
|
||||
$this->table,
|
||||
[
|
||||
'data' => maybe_serialize($data),
|
||||
'processed_last' => date('Y-m-d H:i:s')
|
||||
'processed_last' => date('Y-m-d H:i:s'),
|
||||
'progress_label' => $batch->progress_label,
|
||||
'progress_value' => $batch->progress_value
|
||||
],
|
||||
['ID' => $key]
|
||||
);
|
||||
|
@ -221,7 +224,7 @@ abstract class Background_Process extends \WP_Background_Process {
|
|||
|
||||
// TODO: find a way to catch and log PHP errors as
|
||||
try {
|
||||
$task = $this->task( $batch->data, $batch->key );
|
||||
$task = $this->task( $batch );
|
||||
} catch (\Exception $e) {
|
||||
// TODO: Add Stacktrace
|
||||
$this->write_error_log($batch->key, ['Fatal Error: ' . $e->getMessage()]);
|
||||
|
|
|
@ -500,7 +500,7 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
|
|||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function task( $item, $key );
|
||||
abstract protected function task( $item );
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,11 @@ class Background_Importer extends Background_Process {
|
|||
*/
|
||||
protected $action = 'import';
|
||||
|
||||
function task($data, $key) {
|
||||
function task($batch) {
|
||||
|
||||
$data = $batch->data;
|
||||
$key = $batch->key;
|
||||
|
||||
$className = $data['class_name'];
|
||||
if (class_exists($className)) {
|
||||
$object = new $className($data);
|
||||
|
@ -26,7 +29,13 @@ class Background_Importer extends Background_Process {
|
|||
if (false === $runned) {
|
||||
return false;
|
||||
}
|
||||
return $object->_to_Array();
|
||||
|
||||
$batch->progress_label = $object->get_progress_label();
|
||||
$batch->progress_value = $object->get_progress_value();
|
||||
|
||||
$batch->data = $object->_to_Array(true);
|
||||
|
||||
return $batch;
|
||||
}
|
||||
return false;
|
||||
|
||||
|
|
|
@ -22,6 +22,12 @@ class Importer_Handler {
|
|||
'slug' => 'csv',
|
||||
'class_name' => '\Tainacan\Importer\CSV'
|
||||
]);
|
||||
$this->register_importer([
|
||||
'name' => 'Test Importer',
|
||||
'description' => __('Create 2 test colletions with random items', 'tainacan'),
|
||||
'slug' => 'test',
|
||||
'class_name' => '\Tainacan\Importer\Test_Importer'
|
||||
]);
|
||||
|
||||
do_action('tainacan_register_importers');
|
||||
|
||||
|
|
|
@ -108,6 +108,7 @@ abstract class Importer {
|
|||
protected $steps = [
|
||||
[
|
||||
'name' => 'Import Items',
|
||||
'progress_label' => 'Importing Items',
|
||||
'callback' => 'process_collections'
|
||||
]
|
||||
];
|
||||
|
@ -516,6 +517,131 @@ abstract class Importer {
|
|||
return $this->abort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current label to be displayed below the progress bar to give
|
||||
* feedback to the user.
|
||||
*
|
||||
* It automatically gets the attribute progress_label from the current step running.
|
||||
*
|
||||
* Importers may change this label whenever they want
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_progress_label() {
|
||||
$current_step = $this->get_current_step();
|
||||
$steps = $this->get_current_step();
|
||||
$label = '';
|
||||
if ( isset($steps[$current_step]) ) {
|
||||
$step = $steps[$current_step];
|
||||
if ( isset($step['progress_label']) ) {
|
||||
$label = $step['progress_label'];
|
||||
} elseif ( isset($step['name']) ) {
|
||||
$label = $step['name'];
|
||||
}
|
||||
}
|
||||
|
||||
if ( sizeof($steps) > 1 ) {
|
||||
$preLabel = sprintf( __('Step %d of %d', 'tainacan'), $current_step + 1, sizeof($steps) );
|
||||
$label = $preLabel . ': ' . $label;
|
||||
}
|
||||
|
||||
if ( empty($label) ) {
|
||||
$label = __('Running Importer', 'tainacan');
|
||||
}
|
||||
|
||||
return $label;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current value to build the progress bar and give feedback to the user
|
||||
* on the background process that is running the importer.
|
||||
*
|
||||
* It does so by comparing the "size" attribute with the $in_step_count class attribute
|
||||
* where size indicates the total size of iterations the step will take and $this->in_step_count
|
||||
* is the current iteration.
|
||||
*
|
||||
* For the step with "process_items" as a callback, this method will look for the the $this->collections array
|
||||
* and sum the value of all "total_items" attributes of each collection. Then it will look for
|
||||
* $this->get_current_collection and $this->set_current_collection_item to calculate the progress.
|
||||
*
|
||||
* The value must be from 0 to 100
|
||||
*
|
||||
* If a negative value is passed, it is assumed that the progress is unknown
|
||||
*/
|
||||
public function get_progress_value() {
|
||||
$current_step = $this->get_current_step();
|
||||
$steps = $this->get_current_step();
|
||||
$value = -1;
|
||||
|
||||
if ( isset($steps[$current_step]) ) {
|
||||
$step = $steps[$current_step];
|
||||
|
||||
if ($step['callback'] == 'process_items') {
|
||||
|
||||
$totalItems = 0;
|
||||
$currentItem = $this->get_current_collection_item();
|
||||
$current_collection = $this->get_current_collection();
|
||||
$collections = $this->get_collections();
|
||||
|
||||
foreach ($collections as $i => $col) {
|
||||
if ( isset($col['total_items']) && is_integer($col['total_items']) ) {
|
||||
$totalItems += $col['total_items'];
|
||||
if ($i < $current_collection) {
|
||||
$currentItem += $col['total_items'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($totalItems > 0) {
|
||||
$value = round( ($currentItem/$totalItems) * 100 );
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
if ( isset($step['total']) && is_integer($step['total']) && $step['total'] > 0 ) {
|
||||
$current = $this->get_in_step_count();
|
||||
$value = round( ($current/$step['total']) * 100 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the total attribute for the current step
|
||||
*
|
||||
* The "total" attribute of a step indicates the number of iterations this step will take to complete.
|
||||
*
|
||||
* The iteration is counted using $this->in_step_count attribute, and comparing the two values gives us
|
||||
* the current progress of the process.
|
||||
*
|
||||
*/
|
||||
protected function set_current_step_total(int $value) {
|
||||
$this->set_step_total($this->get_current_step(), $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the total attribute for a given step
|
||||
*
|
||||
* The "total" attribute of a step indicates the number of iterations this step will take to complete.
|
||||
*
|
||||
* The iteration is counted using $this->in_step_count attribute, and comparing the two values gives us
|
||||
* the current progress of the process.
|
||||
*
|
||||
*/
|
||||
protected function set_step_total(int $step, int $value) {
|
||||
$steps = $this->get_steps();
|
||||
if (isset($steps[$step]) && is_array($steps[$step])) {
|
||||
$steps[$step]['total'] = $value;
|
||||
$this->set_steps($steps);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////
|
||||
// Abstract methods
|
||||
|
|
|
@ -35,23 +35,29 @@ class Test_Importer extends Importer {
|
|||
|
||||
[
|
||||
'name' => 'Create Taxonomies',
|
||||
'progress_label' => 'Creating taxonomies',
|
||||
'callback' => 'create_taxonomies'
|
||||
],
|
||||
[
|
||||
'name' => 'Create Collections',
|
||||
'progress_label' => 'Creating Collections',
|
||||
'callback' => 'create_collections'
|
||||
],
|
||||
[
|
||||
'name' => 'Import Items',
|
||||
'progress_label' => 'Importing items',
|
||||
'callback' => 'process_collections'
|
||||
],
|
||||
[
|
||||
'name' => 'Post-configure taxonomies',
|
||||
'progress_label' => 'post processing taxonomies',
|
||||
'callback' => 'close_taxonomies'
|
||||
],
|
||||
[
|
||||
'name' => 'Finalize',
|
||||
'callback' => 'finish_processing'
|
||||
'progress_label' => 'Finalizing',
|
||||
'callback' => 'finish_processing',
|
||||
'total' => 5
|
||||
]
|
||||
|
||||
];
|
||||
|
|
|
@ -15,12 +15,25 @@ function tainacan_create_bd_process_db() {
|
|||
data longtext NOT NULL,
|
||||
action text NOT NULL,
|
||||
done boolean not null default 0,
|
||||
progress_label text,
|
||||
progress_value int,
|
||||
PRIMARY KEY (ID),
|
||||
KEY user_id (user_id),
|
||||
KEY action (action($max_index_length))
|
||||
) $charset_collate;\n";
|
||||
|
||||
$wpdb->query($query);
|
||||
|
||||
$column_exists = $wpdb->get_results( "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'wp_t' AND column_name = 'progress_label'" );
|
||||
|
||||
if(empty($column_exists)) {
|
||||
$wpdb->query("
|
||||
ALTER TABLE {$wpdb->prefix}tnc_bg_process
|
||||
ADD progress_label text,
|
||||
ADD progress_value int
|
||||
");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue