| Current File : /home/digitaw/www/wp-content/plugins/simple-history/inc/services/class-import-handler.php |
<?php
namespace Simple_History\Services;
use Simple_History\Dropins\Import_Dropin;
use Simple_History\Dropins\Tools_Menu_Dropin;
use Simple_History\Existing_Data_Importer;
use Simple_History\Helpers;
use Simple_History\Services\Auto_Backfill_Service;
use Simple_History\Services\Service;
/**
* Handles import form submissions via WordPress admin-post hook.
*
* This class is responsible for processing import requests submitted
* from the Import Tools page. It follows WordPress best practices
* by using the admin-post.php routing system to separate business logic
* from UI rendering.
*/
class Import_Handler extends Service {
/**
* Action name for the admin post hook.
*/
const ACTION_NAME = 'simple_history_import_existing_data';
/**
* Action name for deleting imported data.
*/
const DELETE_ACTION_NAME = 'simple_history_delete_imported_data';
/**
* Action name for re-running auto backfill.
*/
const RERUN_ACTION_NAME = 'simple_history_rerun_auto_backfill';
/**
* Option name for storing manual backfill status.
*/
const MANUAL_STATUS_OPTION = 'simple_history_manual_backfill_status';
/**
* Register the service.
*/
public function loaded() {
// Hook into admin-post to handle import form submissions.
add_action( 'admin_post_' . self::ACTION_NAME, [ $this, 'handle' ] );
// Hook into admin-post to handle delete requests.
add_action( 'admin_post_' . self::DELETE_ACTION_NAME, [ $this, 'handle_delete' ] );
// Hook into admin-post to handle re-run auto backfill requests.
add_action( 'admin_post_' . self::RERUN_ACTION_NAME, [ $this, 'handle_rerun' ] );
}
/**
* Handle the import request.
*
* Validates the request, processes the import, and redirects back
* to the Import Tools page with results as URL parameters.
*/
public function handle() {
// Verify nonce.
if ( ! isset( $_POST['simple_history_import_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['simple_history_import_nonce'] ) ), self::ACTION_NAME ) ) {
wp_die( esc_html__( 'Security check failed', 'simple-history' ) );
}
// Check permissions.
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( esc_html__( 'You do not have permission to perform this action', 'simple-history' ) );
}
// Check if manual import is enabled (premium feature).
/**
* Filter to enable manual backfill functionality.
*
* By default, manual backfill is disabled in the free version.
* Premium add-on enables this by returning true.
*
* @param bool $can_run Whether manual import can be run. Default false.
*/
$can_run_manual_import = apply_filters( 'simple_history/backfill/can_run_manual_import', false );
if ( ! $can_run_manual_import ) {
wp_die( esc_html__( 'Manual backfill requires Simple History Premium.', 'simple-history' ) );
}
// Get import options from form.
$import_post_types = isset( $_POST['import_post_types'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['import_post_types'] ) ) : [];
$import_users = isset( $_POST['import_users'] ) && sanitize_text_field( wp_unslash( $_POST['import_users'] ) ) === '1';
// No item limit - import all matching data.
$import_limit = -1;
// Check if "All time" is selected.
$date_range_type = isset( $_POST['date_range_type'] ) ? sanitize_text_field( wp_unslash( $_POST['date_range_type'] ) ) : 'specific';
if ( $date_range_type === 'all_time' ) {
// All time - no date limit.
$days_back = -1;
} else {
// Get date range from value + unit inputs.
$date_range_value = isset( $_POST['date_range_value'] ) ? intval( $_POST['date_range_value'] ) : 0;
$date_range_unit = isset( $_POST['date_range_unit'] ) ? sanitize_text_field( wp_unslash( $_POST['date_range_unit'] ) ) : 'days';
// Convert to days.
if ( $date_range_value <= 0 ) {
// Use default from retention setting.
$days_back = null;
} else {
switch ( $date_range_unit ) {
case 'months':
$days_back = $date_range_value * 30;
break;
case 'years':
$days_back = $date_range_value * 365;
break;
case 'days':
default:
$days_back = $date_range_value;
break;
}
}
}
// Create importer instance.
$importer = new Existing_Data_Importer( $this->simple_history );
// Run import.
$results = $importer->import_all(
[
'post_types' => $import_post_types,
'import_users' => $import_users,
'limit' => $import_limit,
'days_back' => $days_back,
]
);
// Save manual backfill status for persistent display.
// Store the original date range settings for accurate display.
$date_range_value = isset( $_POST['date_range_value'] ) ? intval( $_POST['date_range_value'] ) : 0;
$date_range_unit = isset( $_POST['date_range_unit'] ) ? sanitize_text_field( wp_unslash( $_POST['date_range_unit'] ) ) : 'days';
$manual_status = [
'completed' => true,
'completed_at' => current_time( 'mysql', true ),
'posts_imported' => isset( $results['posts_imported'] ) ? intval( $results['posts_imported'] ) : 0,
'users_imported' => isset( $results['users_imported'] ) ? intval( $results['users_imported'] ) : 0,
'post_events_created' => isset( $results['post_events_created'] ) ? intval( $results['post_events_created'] ) : 0,
'user_events_created' => isset( $results['user_events_created'] ) ? intval( $results['user_events_created'] ) : 0,
'posts_skipped_imported' => isset( $results['posts_skipped_imported'] ) ? intval( $results['posts_skipped_imported'] ) : 0,
'posts_skipped_logged' => isset( $results['posts_skipped_logged'] ) ? intval( $results['posts_skipped_logged'] ) : 0,
'users_skipped_imported' => isset( $results['users_skipped_imported'] ) ? intval( $results['users_skipped_imported'] ) : 0,
'users_skipped_logged' => isset( $results['users_skipped_logged'] ) ? intval( $results['users_skipped_logged'] ) : 0,
'days_back' => $days_back ?? Helpers::get_clear_history_interval(),
'date_range_type' => $date_range_type,
'date_range_value' => $date_range_value,
'date_range_unit' => $date_range_unit,
];
update_option( self::MANUAL_STATUS_OPTION, $manual_status );
// Fire action for SimpleHistory_Logger to log completion.
$manual_status['type'] = 'manual';
do_action( 'simple_history/backfill/completed', $manual_status );
// Redirect back to the page with results as URL parameters.
// Use the proper tab structure for the Tools menu.
$redirect_url = add_query_arg(
[
'page' => Tools_Menu_Dropin::MENU_SLUG,
'selected-tab' => Tools_Menu_Dropin::TOOLS_TAB_SLUG,
'selected-sub-tab' => Import_Dropin::MENU_SLUG,
'import-completed' => '1',
'posts-imported' => isset( $results['posts_imported'] ) ? intval( $results['posts_imported'] ) : 0,
'users-imported' => isset( $results['users_imported'] ) ? intval( $results['users_imported'] ) : 0,
'post-events-created' => isset( $results['post_events_created'] ) ? intval( $results['post_events_created'] ) : 0,
'user-events-created' => isset( $results['user_events_created'] ) ? intval( $results['user_events_created'] ) : 0,
'posts-skipped-imported' => isset( $results['posts_skipped_imported'] ) ? intval( $results['posts_skipped_imported'] ) : 0,
'posts-skipped-logged' => isset( $results['posts_skipped_logged'] ) ? intval( $results['posts_skipped_logged'] ) : 0,
'users-skipped-imported' => isset( $results['users_skipped_imported'] ) ? intval( $results['users_skipped_imported'] ) : 0,
'users-skipped-logged' => isset( $results['users_skipped_logged'] ) ? intval( $results['users_skipped_logged'] ) : 0,
],
admin_url( 'admin.php' )
);
wp_safe_redirect( $redirect_url );
exit;
}
/**
* Handle the delete imported data request.
*
* Validates the request, deletes all imported events, and redirects back
* to the Import Tools page with results as URL parameters.
*
* Note: Delete is only available when dev mode is enabled.
*/
public function handle_delete() {
// Verify nonce.
if ( ! isset( $_POST['simple_history_delete_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['simple_history_delete_nonce'] ) ), self::DELETE_ACTION_NAME ) ) {
wp_die( esc_html__( 'Security check failed', 'simple-history' ) );
}
// Check permissions.
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( esc_html__( 'You do not have permission to perform this action', 'simple-history' ) );
}
// Check if delete is allowed (dev mode only).
if ( ! Helpers::dev_mode_is_enabled() ) {
wp_die( esc_html__( 'Delete backfilled data requires dev mode to be enabled.', 'simple-history' ) );
}
// Create importer instance.
$importer = new Existing_Data_Importer( $this->simple_history );
// Delete all imported events.
$results = $importer->delete_all_imported();
// Update the auto-backfill status to record deletion.
$status = get_option( Auto_Backfill_Service::STATUS_OPTION );
if ( $status ) {
$status['deleted_at'] = current_time( 'mysql', true );
$status['events_deleted'] = $results['events_deleted'];
update_option( Auto_Backfill_Service::STATUS_OPTION, $status );
}
// Redirect back to the page with results as URL parameters.
// Use the proper tab structure for the Tools menu.
$redirect_url = add_query_arg(
[
'page' => Tools_Menu_Dropin::MENU_SLUG,
'selected-tab' => Tools_Menu_Dropin::TOOLS_TAB_SLUG,
'selected-sub-tab' => Import_Dropin::MENU_SLUG,
'delete-completed' => '1',
'events-deleted' => isset( $results['events_deleted'] ) ? intval( $results['events_deleted'] ) : 0,
],
admin_url( 'admin.php' )
);
wp_safe_redirect( $redirect_url );
exit;
}
/**
* Handle the re-run auto backfill request.
*
* Resets the auto-backfill status and schedules the cron event to run again.
*
* Note: Re-run is only available when dev mode is enabled.
*/
public function handle_rerun() {
// Verify nonce.
if ( ! isset( $_POST['simple_history_rerun_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['simple_history_rerun_nonce'] ) ), self::RERUN_ACTION_NAME ) ) {
wp_die( esc_html__( 'Security check failed', 'simple-history' ) );
}
// Check permissions.
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( esc_html__( 'You do not have permission to perform this action', 'simple-history' ) );
}
// Check if re-run is allowed (dev mode only).
if ( ! Helpers::dev_mode_is_enabled() ) {
wp_die( esc_html__( 'Re-running auto backfill requires dev mode to be enabled.', 'simple-history' ) );
}
// Reset the auto-backfill status.
Auto_Backfill_Service::reset_status();
// Schedule the auto-backfill to run.
Auto_Backfill_Service::schedule_auto_backfill();
// Redirect back to the page with success message.
$redirect_url = add_query_arg(
[
'page' => Tools_Menu_Dropin::MENU_SLUG,
'selected-tab' => Tools_Menu_Dropin::TOOLS_TAB_SLUG,
'selected-sub-tab' => Import_Dropin::MENU_SLUG,
'rerun-scheduled' => '1',
],
admin_url( 'admin.php' )
);
wp_safe_redirect( $redirect_url );
exit;
}
}