Initial Commit
This commit is contained in:
109
dependencies/woocommerce/action-scheduler/classes/migration/ActionMigrator.php
vendored
Normal file
109
dependencies/woocommerce/action-scheduler/classes/migration/ActionMigrator.php
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Action_Scheduler\Migration;
|
||||
|
||||
/**
|
||||
* Class ActionMigrator
|
||||
*
|
||||
* @package Action_Scheduler\Migration
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ActionMigrator {
|
||||
/** var ActionScheduler_Store */
|
||||
private $source;
|
||||
|
||||
/** var ActionScheduler_Store */
|
||||
private $destination;
|
||||
|
||||
/** var LogMigrator */
|
||||
private $log_migrator;
|
||||
|
||||
/**
|
||||
* ActionMigrator constructor.
|
||||
*
|
||||
* @param ActionScheduler_Store $source_store Source store object.
|
||||
* @param ActionScheduler_Store $destination_store Destination store object.
|
||||
* @param LogMigrator $log_migrator Log migrator object.
|
||||
*/
|
||||
public function __construct( \ActionScheduler_Store $source_store, \ActionScheduler_Store $destination_store, LogMigrator $log_migrator ) {
|
||||
$this->source = $source_store;
|
||||
$this->destination = $destination_store;
|
||||
$this->log_migrator = $log_migrator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate an action.
|
||||
*
|
||||
* @param int $source_action_id Action ID.
|
||||
*
|
||||
* @return int 0|new action ID
|
||||
*/
|
||||
public function migrate( $source_action_id ) {
|
||||
try {
|
||||
$action = $this->source->fetch_action( $source_action_id );
|
||||
$status = $this->source->get_status( $source_action_id );
|
||||
} catch ( \Exception $e ) {
|
||||
$action = null;
|
||||
$status = '';
|
||||
}
|
||||
|
||||
if ( is_null( $action ) || empty( $status ) || ! $action->get_schedule()->get_date() ) {
|
||||
// null action or empty status means the fetch operation failed or the action didn't exist
|
||||
// null schedule means it's missing vital data
|
||||
// delete it and move on
|
||||
try {
|
||||
$this->source->delete_action( $source_action_id );
|
||||
} catch ( \Exception $e ) {
|
||||
// nothing to do, it didn't exist in the first place
|
||||
}
|
||||
do_action( 'action_scheduler/no_action_to_migrate', $source_action_id, $this->source, $this->destination );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
// Make sure the last attempt date is set correctly for completed and failed actions
|
||||
$last_attempt_date = ( $status !== \ActionScheduler_Store::STATUS_PENDING ) ? $this->source->get_date( $source_action_id ) : null;
|
||||
|
||||
$destination_action_id = $this->destination->save_action( $action, null, $last_attempt_date );
|
||||
} catch ( \Exception $e ) {
|
||||
do_action( 'action_scheduler/migrate_action_failed', $source_action_id, $this->source, $this->destination );
|
||||
|
||||
return 0; // could not save the action in the new store
|
||||
}
|
||||
|
||||
try {
|
||||
switch ( $status ) {
|
||||
case \ActionScheduler_Store::STATUS_FAILED :
|
||||
$this->destination->mark_failure( $destination_action_id );
|
||||
break;
|
||||
case \ActionScheduler_Store::STATUS_CANCELED :
|
||||
$this->destination->cancel_action( $destination_action_id );
|
||||
break;
|
||||
}
|
||||
|
||||
$this->log_migrator->migrate( $source_action_id, $destination_action_id );
|
||||
$this->source->delete_action( $source_action_id );
|
||||
|
||||
$test_action = $this->source->fetch_action( $source_action_id );
|
||||
if ( ! is_a( $test_action, 'ActionScheduler_NullAction' ) ) {
|
||||
throw new \RuntimeException( sprintf( __( 'Unable to remove source migrated action %s', 'action-scheduler' ), $source_action_id ) );
|
||||
}
|
||||
do_action( 'action_scheduler/migrated_action', $source_action_id, $destination_action_id, $this->source, $this->destination );
|
||||
|
||||
return $destination_action_id;
|
||||
} catch ( \Exception $e ) {
|
||||
// could not delete from the old store
|
||||
$this->source->mark_migrated( $source_action_id );
|
||||
do_action( 'action_scheduler/migrate_action_incomplete', $source_action_id, $destination_action_id, $this->source, $this->destination );
|
||||
do_action( 'action_scheduler/migrated_action', $source_action_id, $destination_action_id, $this->source, $this->destination );
|
||||
|
||||
return $destination_action_id;
|
||||
}
|
||||
}
|
||||
}
|
47
dependencies/woocommerce/action-scheduler/classes/migration/ActionScheduler_DBStoreMigrator.php
vendored
Normal file
47
dependencies/woocommerce/action-scheduler/classes/migration/ActionScheduler_DBStoreMigrator.php
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class ActionScheduler_DBStoreMigrator
|
||||
*
|
||||
* A class for direct saving of actions to the table data store during migration.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
class ActionScheduler_DBStoreMigrator extends ActionScheduler_DBStore {
|
||||
|
||||
/**
|
||||
* Save an action with optional last attempt date.
|
||||
*
|
||||
* Normally, saving an action sets its attempted date to 0000-00-00 00:00:00 because when an action is first saved,
|
||||
* it can't have been attempted yet, but migrated completed actions will have an attempted date, so we need to save
|
||||
* that when first saving the action.
|
||||
*
|
||||
* @param ActionScheduler_Action $action
|
||||
* @param \DateTime $scheduled_date Optional date of the first instance to store.
|
||||
* @param \DateTime $last_attempt_date Optional date the action was last attempted.
|
||||
*
|
||||
* @return string The action ID
|
||||
* @throws \RuntimeException When the action is not saved.
|
||||
*/
|
||||
public function save_action( ActionScheduler_Action $action, \DateTime $scheduled_date = null, \DateTime $last_attempt_date = null ){
|
||||
try {
|
||||
/** @var \wpdb $wpdb */
|
||||
global $wpdb;
|
||||
|
||||
$action_id = parent::save_action( $action, $scheduled_date );
|
||||
|
||||
if ( null !== $last_attempt_date ) {
|
||||
$data = [
|
||||
'last_attempt_gmt' => $this->get_scheduled_date_string( $action, $last_attempt_date ),
|
||||
'last_attempt_local' => $this->get_scheduled_date_string_local( $action, $last_attempt_date ),
|
||||
];
|
||||
|
||||
$wpdb->update( $wpdb->actionscheduler_actions, $data, array( 'action_id' => $action_id ), array( '%s', '%s' ), array( '%d' ) );
|
||||
}
|
||||
|
||||
return $action_id;
|
||||
} catch ( \Exception $e ) {
|
||||
throw new \RuntimeException( sprintf( __( 'Error saving action: %s', 'action-scheduler' ), $e->getMessage() ), 0 );
|
||||
}
|
||||
}
|
||||
}
|
86
dependencies/woocommerce/action-scheduler/classes/migration/BatchFetcher.php
vendored
Normal file
86
dependencies/woocommerce/action-scheduler/classes/migration/BatchFetcher.php
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Action_Scheduler\Migration;
|
||||
|
||||
|
||||
use ActionScheduler_Store as Store;
|
||||
|
||||
/**
|
||||
* Class BatchFetcher
|
||||
*
|
||||
* @package Action_Scheduler\Migration
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class BatchFetcher {
|
||||
/** var ActionScheduler_Store */
|
||||
private $store;
|
||||
|
||||
/**
|
||||
* BatchFetcher constructor.
|
||||
*
|
||||
* @param ActionScheduler_Store $source_store Source store object.
|
||||
*/
|
||||
public function __construct( Store $source_store ) {
|
||||
$this->store = $source_store;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a list of actions.
|
||||
*
|
||||
* @param int $count The number of actions to retrieve
|
||||
*
|
||||
* @return int[] A list of action IDs
|
||||
*/
|
||||
public function fetch( $count = 10 ) {
|
||||
foreach ( $this->get_query_strategies( $count ) as $query ) {
|
||||
$action_ids = $this->store->query_actions( $query );
|
||||
if ( ! empty( $action_ids ) ) {
|
||||
return $action_ids;
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a list of prioritized of action search parameters.
|
||||
*
|
||||
* @param int $count Number of actions to find.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_query_strategies( $count ) {
|
||||
$now = as_get_datetime_object();
|
||||
$args = [
|
||||
'date' => $now,
|
||||
'per_page' => $count,
|
||||
'offset' => 0,
|
||||
'orderby' => 'date',
|
||||
'order' => 'ASC',
|
||||
];
|
||||
|
||||
$priorities = [
|
||||
Store::STATUS_PENDING,
|
||||
Store::STATUS_FAILED,
|
||||
Store::STATUS_CANCELED,
|
||||
Store::STATUS_COMPLETE,
|
||||
Store::STATUS_RUNNING,
|
||||
'', // any other unanticipated status
|
||||
];
|
||||
|
||||
foreach ( $priorities as $status ) {
|
||||
yield wp_parse_args( [
|
||||
'status' => $status,
|
||||
'date_compare' => '<=',
|
||||
], $args );
|
||||
yield wp_parse_args( [
|
||||
'status' => $status,
|
||||
'date_compare' => '>=',
|
||||
], $args );
|
||||
}
|
||||
}
|
||||
}
|
168
dependencies/woocommerce/action-scheduler/classes/migration/Config.php
vendored
Normal file
168
dependencies/woocommerce/action-scheduler/classes/migration/Config.php
vendored
Normal file
@ -0,0 +1,168 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Action_Scheduler\Migration;
|
||||
|
||||
use Action_Scheduler\WP_CLI\ProgressBar;
|
||||
use ActionScheduler_Logger as Logger;
|
||||
use ActionScheduler_Store as Store;
|
||||
|
||||
/**
|
||||
* Class Config
|
||||
*
|
||||
* @package Action_Scheduler\Migration
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* A config builder for the ActionScheduler\Migration\Runner class
|
||||
*/
|
||||
class Config {
|
||||
/** @var ActionScheduler_Store */
|
||||
private $source_store;
|
||||
|
||||
/** @var ActionScheduler_Logger */
|
||||
private $source_logger;
|
||||
|
||||
/** @var ActionScheduler_Store */
|
||||
private $destination_store;
|
||||
|
||||
/** @var ActionScheduler_Logger */
|
||||
private $destination_logger;
|
||||
|
||||
/** @var Progress bar */
|
||||
private $progress_bar;
|
||||
|
||||
/** @var bool */
|
||||
private $dry_run = false;
|
||||
|
||||
/**
|
||||
* Config constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the configured source store.
|
||||
*
|
||||
* @return ActionScheduler_Store
|
||||
*/
|
||||
public function get_source_store() {
|
||||
if ( empty( $this->source_store ) ) {
|
||||
throw new \RuntimeException( __( 'Source store must be configured before running a migration', 'action-scheduler' ) );
|
||||
}
|
||||
|
||||
return $this->source_store;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the configured source store.
|
||||
*
|
||||
* @param ActionScheduler_Store $store Source store object.
|
||||
*/
|
||||
public function set_source_store( Store $store ) {
|
||||
$this->source_store = $store;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the configured source loger.
|
||||
*
|
||||
* @return ActionScheduler_Logger
|
||||
*/
|
||||
public function get_source_logger() {
|
||||
if ( empty( $this->source_logger ) ) {
|
||||
throw new \RuntimeException( __( 'Source logger must be configured before running a migration', 'action-scheduler' ) );
|
||||
}
|
||||
|
||||
return $this->source_logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the configured source logger.
|
||||
*
|
||||
* @param ActionScheduler_Logger $logger
|
||||
*/
|
||||
public function set_source_logger( Logger $logger ) {
|
||||
$this->source_logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the configured destination store.
|
||||
*
|
||||
* @return ActionScheduler_Store
|
||||
*/
|
||||
public function get_destination_store() {
|
||||
if ( empty( $this->destination_store ) ) {
|
||||
throw new \RuntimeException( __( 'Destination store must be configured before running a migration', 'action-scheduler' ) );
|
||||
}
|
||||
|
||||
return $this->destination_store;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the configured destination store.
|
||||
*
|
||||
* @param ActionScheduler_Store $store
|
||||
*/
|
||||
public function set_destination_store( Store $store ) {
|
||||
$this->destination_store = $store;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the configured destination logger.
|
||||
*
|
||||
* @return ActionScheduler_Logger
|
||||
*/
|
||||
public function get_destination_logger() {
|
||||
if ( empty( $this->destination_logger ) ) {
|
||||
throw new \RuntimeException( __( 'Destination logger must be configured before running a migration', 'action-scheduler' ) );
|
||||
}
|
||||
|
||||
return $this->destination_logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the configured destination logger.
|
||||
*
|
||||
* @param ActionScheduler_Logger $logger
|
||||
*/
|
||||
public function set_destination_logger( Logger $logger ) {
|
||||
$this->destination_logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get flag indicating whether it's a dry run.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function get_dry_run() {
|
||||
return $this->dry_run;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set flag indicating whether it's a dry run.
|
||||
*
|
||||
* @param bool $dry_run
|
||||
*/
|
||||
public function set_dry_run( $dry_run ) {
|
||||
$this->dry_run = (bool) $dry_run;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get progress bar object.
|
||||
*
|
||||
* @return ActionScheduler\WPCLI\ProgressBar
|
||||
*/
|
||||
public function get_progress_bar() {
|
||||
return $this->progress_bar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set progress bar object.
|
||||
*
|
||||
* @param ActionScheduler\WPCLI\ProgressBar $progress_bar
|
||||
*/
|
||||
public function set_progress_bar( ProgressBar $progress_bar ) {
|
||||
$this->progress_bar = $progress_bar;
|
||||
}
|
||||
}
|
226
dependencies/woocommerce/action-scheduler/classes/migration/Controller.php
vendored
Normal file
226
dependencies/woocommerce/action-scheduler/classes/migration/Controller.php
vendored
Normal file
@ -0,0 +1,226 @@
|
||||
<?php
|
||||
|
||||
namespace Action_Scheduler\Migration;
|
||||
|
||||
use ActionScheduler_DataController;
|
||||
use ActionScheduler_LoggerSchema;
|
||||
use ActionScheduler_StoreSchema;
|
||||
use Action_Scheduler\WP_CLI\ProgressBar;
|
||||
|
||||
/**
|
||||
* Class Controller
|
||||
*
|
||||
* The main plugin/initialization class for migration to custom tables.
|
||||
*
|
||||
* @package Action_Scheduler\Migration
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class Controller {
|
||||
private static $instance;
|
||||
|
||||
/** @var Action_Scheduler\Migration\Scheduler */
|
||||
private $migration_scheduler;
|
||||
|
||||
/** @var string */
|
||||
private $store_classname;
|
||||
|
||||
/** @var string */
|
||||
private $logger_classname;
|
||||
|
||||
/** @var bool */
|
||||
private $migrate_custom_store;
|
||||
|
||||
/**
|
||||
* Controller constructor.
|
||||
*
|
||||
* @param Scheduler $migration_scheduler Migration scheduler object.
|
||||
*/
|
||||
protected function __construct( Scheduler $migration_scheduler ) {
|
||||
$this->migration_scheduler = $migration_scheduler;
|
||||
$this->store_classname = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the action store class name.
|
||||
*
|
||||
* @param string $class Classname of the store class.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_store_class( $class ) {
|
||||
if ( \ActionScheduler_DataController::is_migration_complete() ) {
|
||||
return \ActionScheduler_DataController::DATASTORE_CLASS;
|
||||
} elseif ( \ActionScheduler_Store::DEFAULT_CLASS !== $class ) {
|
||||
$this->store_classname = $class;
|
||||
return $class;
|
||||
} else {
|
||||
return 'ActionScheduler_HybridStore';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the action logger class name.
|
||||
*
|
||||
* @param string $class Classname of the logger class.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_logger_class( $class ) {
|
||||
\ActionScheduler_Store::instance();
|
||||
|
||||
if ( $this->has_custom_datastore() ) {
|
||||
$this->logger_classname = $class;
|
||||
return $class;
|
||||
} else {
|
||||
return \ActionScheduler_DataController::LOGGER_CLASS;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get flag indicating whether a custom datastore is in use.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has_custom_datastore() {
|
||||
return (bool) $this->store_classname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the background migration process.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function schedule_migration() {
|
||||
$logging_tables = new ActionScheduler_LoggerSchema();
|
||||
$store_tables = new ActionScheduler_StoreSchema();
|
||||
|
||||
/*
|
||||
* In some unusual cases, the expected tables may not have been created. In such cases
|
||||
* we do not schedule a migration as doing so will lead to fatal error conditions.
|
||||
*
|
||||
* In such cases the user will likely visit the Tools > Scheduled Actions screen to
|
||||
* investigate, and will see appropriate messaging (this step also triggers an attempt
|
||||
* to rebuild any missing tables).
|
||||
*
|
||||
* @see https://github.com/woocommerce/action-scheduler/issues/653
|
||||
*/
|
||||
if (
|
||||
ActionScheduler_DataController::is_migration_complete()
|
||||
|| $this->migration_scheduler->is_migration_scheduled()
|
||||
|| ! $store_tables->tables_exist()
|
||||
|| ! $logging_tables->tables_exist()
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->migration_scheduler->schedule_migration();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default migration config object
|
||||
*
|
||||
* @return ActionScheduler\Migration\Config
|
||||
*/
|
||||
public function get_migration_config_object() {
|
||||
static $config = null;
|
||||
|
||||
if ( ! $config ) {
|
||||
$source_store = $this->store_classname ? new $this->store_classname() : new \ActionScheduler_wpPostStore();
|
||||
$source_logger = $this->logger_classname ? new $this->logger_classname() : new \ActionScheduler_wpCommentLogger();
|
||||
|
||||
$config = new Config();
|
||||
$config->set_source_store( $source_store );
|
||||
$config->set_source_logger( $source_logger );
|
||||
$config->set_destination_store( new \ActionScheduler_DBStoreMigrator() );
|
||||
$config->set_destination_logger( new \ActionScheduler_DBLogger() );
|
||||
|
||||
if ( defined( 'WP_CLI' ) && WP_CLI ) {
|
||||
$config->set_progress_bar( new ProgressBar( '', 0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
return apply_filters( 'action_scheduler/migration_config', $config );
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook dashboard migration notice.
|
||||
*/
|
||||
public function hook_admin_notices() {
|
||||
if ( ! $this->allow_migration() || \ActionScheduler_DataController::is_migration_complete() ) {
|
||||
return;
|
||||
}
|
||||
add_action( 'admin_notices', array( $this, 'display_migration_notice' ), 10, 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a dashboard notice that migration is in progress.
|
||||
*/
|
||||
public function display_migration_notice() {
|
||||
printf( '<div class="notice notice-warning"><p>%s</p></div>', esc_html__( 'Action Scheduler migration in progress. The list of scheduled actions may be incomplete.', 'action-scheduler' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add store classes. Hook migration.
|
||||
*/
|
||||
private function hook() {
|
||||
add_filter( 'action_scheduler_store_class', array( $this, 'get_store_class' ), 100, 1 );
|
||||
add_filter( 'action_scheduler_logger_class', array( $this, 'get_logger_class' ), 100, 1 );
|
||||
add_action( 'init', array( $this, 'maybe_hook_migration' ) );
|
||||
add_action( 'wp_loaded', array( $this, 'schedule_migration' ) );
|
||||
|
||||
// Action Scheduler may be displayed as a Tools screen or WooCommerce > Status administration screen
|
||||
add_action( 'load-tools_page_action-scheduler', array( $this, 'hook_admin_notices' ), 10, 0 );
|
||||
add_action( 'load-woocommerce_page_wc-status', array( $this, 'hook_admin_notices' ), 10, 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Possibly hook the migration scheduler action.
|
||||
*
|
||||
* @author Jeremy Pry
|
||||
*/
|
||||
public function maybe_hook_migration() {
|
||||
if ( ! $this->allow_migration() || \ActionScheduler_DataController::is_migration_complete() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->migration_scheduler->hook();
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow datastores to enable migration to AS tables.
|
||||
*/
|
||||
public function allow_migration() {
|
||||
if ( ! \ActionScheduler_DataController::dependencies_met() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( null === $this->migrate_custom_store ) {
|
||||
$this->migrate_custom_store = apply_filters( 'action_scheduler_migrate_data_store', false );
|
||||
}
|
||||
|
||||
return ( ! $this->has_custom_datastore() ) || $this->migrate_custom_store;
|
||||
}
|
||||
|
||||
/**
|
||||
* Proceed with the migration if the dependencies have been met.
|
||||
*/
|
||||
public static function init() {
|
||||
if ( \ActionScheduler_DataController::dependencies_met() ) {
|
||||
self::instance()->hook();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Singleton factory.
|
||||
*/
|
||||
public static function instance() {
|
||||
if ( ! isset( self::$instance ) ) {
|
||||
self::$instance = new static( new Scheduler() );
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
}
|
28
dependencies/woocommerce/action-scheduler/classes/migration/DryRun_ActionMigrator.php
vendored
Normal file
28
dependencies/woocommerce/action-scheduler/classes/migration/DryRun_ActionMigrator.php
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Action_Scheduler\Migration;
|
||||
|
||||
/**
|
||||
* Class DryRun_ActionMigrator
|
||||
*
|
||||
* @package Action_Scheduler\Migration
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class DryRun_ActionMigrator extends ActionMigrator {
|
||||
/**
|
||||
* Simulate migrating an action.
|
||||
*
|
||||
* @param int $source_action_id Action ID.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function migrate( $source_action_id ) {
|
||||
do_action( 'action_scheduler/migrate_action_dry_run', $source_action_id );
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
23
dependencies/woocommerce/action-scheduler/classes/migration/DryRun_LogMigrator.php
vendored
Normal file
23
dependencies/woocommerce/action-scheduler/classes/migration/DryRun_LogMigrator.php
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Action_Scheduler\Migration;
|
||||
|
||||
/**
|
||||
* Class DryRun_LogMigrator
|
||||
*
|
||||
* @package Action_Scheduler\Migration
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class DryRun_LogMigrator extends LogMigrator {
|
||||
/**
|
||||
* Simulate migrating an action log.
|
||||
*
|
||||
* @param int $source_action_id Source logger object.
|
||||
* @param int $destination_action_id Destination logger object.
|
||||
*/
|
||||
public function migrate( $source_action_id, $destination_action_id ) {
|
||||
// no-op
|
||||
}
|
||||
}
|
49
dependencies/woocommerce/action-scheduler/classes/migration/LogMigrator.php
vendored
Normal file
49
dependencies/woocommerce/action-scheduler/classes/migration/LogMigrator.php
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Action_Scheduler\Migration;
|
||||
|
||||
use ActionScheduler_Logger;
|
||||
|
||||
/**
|
||||
* Class LogMigrator
|
||||
*
|
||||
* @package Action_Scheduler\Migration
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class LogMigrator {
|
||||
/** @var ActionScheduler_Logger */
|
||||
private $source;
|
||||
|
||||
/** @var ActionScheduler_Logger */
|
||||
private $destination;
|
||||
|
||||
/**
|
||||
* ActionMigrator constructor.
|
||||
*
|
||||
* @param ActionScheduler_Logger $source_logger Source logger object.
|
||||
* @param ActionScheduler_Logger $destination_Logger Destination logger object.
|
||||
*/
|
||||
public function __construct( ActionScheduler_Logger $source_logger, ActionScheduler_Logger $destination_Logger ) {
|
||||
$this->source = $source_logger;
|
||||
$this->destination = $destination_Logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate an action log.
|
||||
*
|
||||
* @param int $source_action_id Source logger object.
|
||||
* @param int $destination_action_id Destination logger object.
|
||||
*/
|
||||
public function migrate( $source_action_id, $destination_action_id ) {
|
||||
$logs = $this->source->get_logs( $source_action_id );
|
||||
foreach ( $logs as $log ) {
|
||||
if ( $log->get_action_id() == $source_action_id ) {
|
||||
$this->destination->log( $destination_action_id, $log->get_message(), $log->get_date() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
136
dependencies/woocommerce/action-scheduler/classes/migration/Runner.php
vendored
Normal file
136
dependencies/woocommerce/action-scheduler/classes/migration/Runner.php
vendored
Normal file
@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Action_Scheduler\Migration;
|
||||
|
||||
/**
|
||||
* Class Runner
|
||||
*
|
||||
* @package Action_Scheduler\Migration
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class Runner {
|
||||
/** @var ActionScheduler_Store */
|
||||
private $source_store;
|
||||
|
||||
/** @var ActionScheduler_Store */
|
||||
private $destination_store;
|
||||
|
||||
/** @var ActionScheduler_Logger */
|
||||
private $source_logger;
|
||||
|
||||
/** @var ActionScheduler_Logger */
|
||||
private $destination_logger;
|
||||
|
||||
/** @var BatchFetcher */
|
||||
private $batch_fetcher;
|
||||
|
||||
/** @var ActionMigrator */
|
||||
private $action_migrator;
|
||||
|
||||
/** @var LogMigrator */
|
||||
private $log_migrator;
|
||||
|
||||
/** @var ProgressBar */
|
||||
private $progress_bar;
|
||||
|
||||
/**
|
||||
* Runner constructor.
|
||||
*
|
||||
* @param Config $config Migration configuration object.
|
||||
*/
|
||||
public function __construct( Config $config ) {
|
||||
$this->source_store = $config->get_source_store();
|
||||
$this->destination_store = $config->get_destination_store();
|
||||
$this->source_logger = $config->get_source_logger();
|
||||
$this->destination_logger = $config->get_destination_logger();
|
||||
|
||||
$this->batch_fetcher = new BatchFetcher( $this->source_store );
|
||||
if ( $config->get_dry_run() ) {
|
||||
$this->log_migrator = new DryRun_LogMigrator( $this->source_logger, $this->destination_logger );
|
||||
$this->action_migrator = new DryRun_ActionMigrator( $this->source_store, $this->destination_store, $this->log_migrator );
|
||||
} else {
|
||||
$this->log_migrator = new LogMigrator( $this->source_logger, $this->destination_logger );
|
||||
$this->action_migrator = new ActionMigrator( $this->source_store, $this->destination_store, $this->log_migrator );
|
||||
}
|
||||
|
||||
if ( defined( 'WP_CLI' ) && WP_CLI ) {
|
||||
$this->progress_bar = $config->get_progress_bar();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run migration batch.
|
||||
*
|
||||
* @param int $batch_size Optional batch size. Default 10.
|
||||
*
|
||||
* @return int Size of batch processed.
|
||||
*/
|
||||
public function run( $batch_size = 10 ) {
|
||||
$batch = $this->batch_fetcher->fetch( $batch_size );
|
||||
$batch_size = count( $batch );
|
||||
|
||||
if ( ! $batch_size ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( $this->progress_bar ) {
|
||||
/* translators: %d: amount of actions */
|
||||
$this->progress_bar->set_message( sprintf( _n( 'Migrating %d action', 'Migrating %d actions', $batch_size, 'action-scheduler' ), $batch_size ) );
|
||||
$this->progress_bar->set_count( $batch_size );
|
||||
}
|
||||
|
||||
$this->migrate_actions( $batch );
|
||||
|
||||
return $batch_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Migration a batch of actions.
|
||||
*
|
||||
* @param array $action_ids List of action IDs to migrate.
|
||||
*/
|
||||
public function migrate_actions( array $action_ids ) {
|
||||
do_action( 'action_scheduler/migration_batch_starting', $action_ids );
|
||||
|
||||
\ActionScheduler::logger()->unhook_stored_action();
|
||||
$this->destination_logger->unhook_stored_action();
|
||||
|
||||
foreach ( $action_ids as $source_action_id ) {
|
||||
$destination_action_id = $this->action_migrator->migrate( $source_action_id );
|
||||
if ( $destination_action_id ) {
|
||||
$this->destination_logger->log( $destination_action_id, sprintf(
|
||||
/* translators: 1: source action ID 2: source store class 3: destination action ID 4: destination store class */
|
||||
__( 'Migrated action with ID %1$d in %2$s to ID %3$d in %4$s', 'action-scheduler' ),
|
||||
$source_action_id,
|
||||
get_class( $this->source_store ),
|
||||
$destination_action_id,
|
||||
get_class( $this->destination_store )
|
||||
) );
|
||||
}
|
||||
|
||||
if ( $this->progress_bar ) {
|
||||
$this->progress_bar->tick();
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->progress_bar ) {
|
||||
$this->progress_bar->finish();
|
||||
}
|
||||
|
||||
\ActionScheduler::logger()->hook_stored_action();
|
||||
|
||||
do_action( 'action_scheduler/migration_batch_complete', $action_ids );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize destination store and logger.
|
||||
*/
|
||||
public function init_destination() {
|
||||
$this->destination_store->init();
|
||||
$this->destination_logger->init();
|
||||
}
|
||||
}
|
128
dependencies/woocommerce/action-scheduler/classes/migration/Scheduler.php
vendored
Normal file
128
dependencies/woocommerce/action-scheduler/classes/migration/Scheduler.php
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Action_Scheduler\Migration;
|
||||
|
||||
/**
|
||||
* Class Scheduler
|
||||
*
|
||||
* @package Action_Scheduler\WP_CLI
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class Scheduler {
|
||||
/** Migration action hook. */
|
||||
const HOOK = 'action_scheduler/migration_hook';
|
||||
|
||||
/** Migration action group. */
|
||||
const GROUP = 'action-scheduler-migration';
|
||||
|
||||
/**
|
||||
* Set up the callback for the scheduled job.
|
||||
*/
|
||||
public function hook() {
|
||||
add_action( self::HOOK, array( $this, 'run_migration' ), 10, 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the callback for the scheduled job.
|
||||
*/
|
||||
public function unhook() {
|
||||
remove_action( self::HOOK, array( $this, 'run_migration' ), 10 );
|
||||
}
|
||||
|
||||
/**
|
||||
* The migration callback.
|
||||
*/
|
||||
public function run_migration() {
|
||||
$migration_runner = $this->get_migration_runner();
|
||||
$count = $migration_runner->run( $this->get_batch_size() );
|
||||
|
||||
if ( $count === 0 ) {
|
||||
$this->mark_complete();
|
||||
} else {
|
||||
$this->schedule_migration( time() + $this->get_schedule_interval() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the migration complete.
|
||||
*/
|
||||
public function mark_complete() {
|
||||
$this->unschedule_migration();
|
||||
|
||||
\ActionScheduler_DataController::mark_migration_complete();
|
||||
do_action( 'action_scheduler/migration_complete' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a flag indicating whether the migration is scheduled.
|
||||
*
|
||||
* @return bool Whether there is a pending action in the store to handle the migration
|
||||
*/
|
||||
public function is_migration_scheduled() {
|
||||
$next = as_next_scheduled_action( self::HOOK );
|
||||
|
||||
return ! empty( $next );
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the migration.
|
||||
*
|
||||
* @param int $when Optional timestamp to run the next migration batch. Defaults to now.
|
||||
*
|
||||
* @return string The action ID
|
||||
*/
|
||||
public function schedule_migration( $when = 0 ) {
|
||||
$next = as_next_scheduled_action( self::HOOK );
|
||||
|
||||
if ( ! empty( $next ) ) {
|
||||
return $next;
|
||||
}
|
||||
|
||||
if ( empty( $when ) ) {
|
||||
$when = time() + MINUTE_IN_SECONDS;
|
||||
}
|
||||
|
||||
return as_schedule_single_action( $when, self::HOOK, array(), self::GROUP );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the scheduled migration action.
|
||||
*/
|
||||
public function unschedule_migration() {
|
||||
as_unschedule_action( self::HOOK, null, self::GROUP );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get migration batch schedule interval.
|
||||
*
|
||||
* @return int Seconds between migration runs. Defaults to 0 seconds to allow chaining migration via Async Runners.
|
||||
*/
|
||||
private function get_schedule_interval() {
|
||||
return (int) apply_filters( 'action_scheduler/migration_interval', 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get migration batch size.
|
||||
*
|
||||
* @return int Number of actions to migrate in each batch. Defaults to 250.
|
||||
*/
|
||||
private function get_batch_size() {
|
||||
return (int) apply_filters( 'action_scheduler/migration_batch_size', 250 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get migration runner object.
|
||||
*
|
||||
* @return Runner
|
||||
*/
|
||||
private function get_migration_runner() {
|
||||
$config = Controller::instance()->get_migration_config_object();
|
||||
|
||||
return new Runner( $config );
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user