namespace WPForms\Migrations\Tasks;
* Upgrade task base class.
abstract class UpgradeBaseTask extends Task {
private const START = 'start';
private const IN_PROGRESS = 'in progress';
private const COMPLETED = 'completed';
* Option name to store the task status.
* @throws RuntimeException If class name doesn't contain a version.
public function __construct() {
$class_parts = explode( '\\', static::class );
$short_class_name = end( $class_parts );
$short_class_name = strtolower( preg_replace( '/(?<!^)[A-Z]/', '_$0', $short_class_name ) );
$this->action = 'wpforms_process_migration_' . $short_class_name;
$this->status_option = $this->action . '_status';
parent::__construct( $this->action );
* Get current task status.
private function get_status(): string {
return (string) get_option( $this->status_option );
* Use the constants self::START, self::IN_PROGRESS, self::COMPLETED.
* @param string $status New status.
private function update_status( string $status ): void {
update_option( $this->status_option, $status );
* Initialize the task with all the proper checks.
public function init(): void {
$status = $this->get_status();
if ( ! $status || $status === self::COMPLETED ) {
$this->set_task_properties();
if ( $status !== self::START ) {
$this->update_status( self::IN_PROGRESS );
* @param array $args Task arguments.
protected function create_task( array $args = [] ): void {
$tasks = wpforms()->obj( 'tasks' );
'error' => "Object is not available: `null` returned by `wpforms()->obj( 'tasks' )`",
'class' => static::class,
->create( $this->action )
abstract protected function set_task_properties(): void;
protected function hooks(): void {
add_action( $this->action, [ $this, 'migrate' ] );
add_action( 'action_scheduler_after_process_queue', [ $this, 'after_process_queue' ] );
* @param int $meta_id Action meta id.
* @noinspection PhpMissingParamTypeInspection
public function migrate( $meta_id ): void {
$params = ( new Meta() )->get( $meta_id );
if ( ! $params || ! isset( $params->data ) ) {
$this->process_migration( (array) $params->data );
* Execute an async migration task.
* @param array $data Migration data.
abstract protected function process_migration( array $data ): void;
* Set the status as completed after processing all queue action.
public function after_process_queue(): void {
$tasks = wpforms()->obj( 'tasks' );
'error' => "Object is not available: `null` returned by `wpforms()->obj( 'tasks' )`",
'class' => static::class,
if ( $tasks->is_scheduled( $this->action ) ) {
$this->finish_migration();
protected function finish_migration(): void {
$this->update_status( self::COMPLETED );
* Create migration tasks using the `create_task` method
* or `finish_migration` method to complete it.
abstract protected function init_migration(): void;
* Determine if the task is completed.
* Remove the status option to allow running the task again.
* @return bool True if a task is completed.
public function is_completed(): bool {
$status = $this->get_status();
$is_completed = $status === self::COMPLETED;
delete_option( $this->status_option );
public function maybe_start(): void {
$status = $this->get_status();
$this->update_status( self::START );