run_migration(); } else { // Run specific step $result = self::$migration_runner->run_migration_step($step); } if ($result['success']) { wp_send_json_success($result); } else { wp_send_json_error($result); } } catch (\Exception $e) { wp_send_json_error([ 'message' => $e->getMessage(), ]); } } /** * Handle AJAX check status request. * * @since 2.0.0 * @return void */ public static function handle_check_status() { // Check nonce if (!wp_verify_nonce($_GET['nonce'], 'easy_invoice_migration_nonce')) { wp_die('Security check failed'); } // Check permissions if (!current_user_can('manage_options')) { wp_die('Insufficient permissions'); } try { $status = self::$migration_runner->get_migration_status(); wp_send_json_success($status); } catch (\Exception $e) { wp_send_json_error([ 'message' => $e->getMessage(), ]); } } /** * Handle AJAX get migration counts request. * * @since 2.0.0 * @return void */ public static function handle_get_migration_counts() { // Check nonce if (!wp_verify_nonce($_GET['nonce'], 'easy_invoice_migration_nonce')) { wp_die('Security check failed'); } // Check permissions if (!current_user_can('manage_options')) { wp_die('Insufficient permissions'); } try { global $wpdb; // First, temporarily register old post types to ensure they're recognized self::register_old_post_types(); // Count old post types using direct SQL queries with all possible statuses $invoice_count = (int)$wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type = %s ", 'easy-invoice' )); $quote_count = (int)$wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type = %s ", 'easy-invoice-quotes' )); $payment_count = (int)$wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type = %s ", 'easy-invoice-payment' )); // Double-check with meta data $invoice_meta_count = (int)$wpdb->get_var($wpdb->prepare( "SELECT COUNT(DISTINCT post_id) FROM {$wpdb->postmeta} pm JOIN {$wpdb->posts} p ON p.ID = pm.post_id WHERE p.post_type = %s ", 'easy-invoice' )); $quote_meta_count = (int)$wpdb->get_var($wpdb->prepare( "SELECT COUNT(DISTINCT post_id) FROM {$wpdb->postmeta} pm JOIN {$wpdb->posts} p ON p.ID = pm.post_id WHERE p.post_type = %s ", 'easy-invoice-quotes' )); $payment_meta_count = (int)$wpdb->get_var($wpdb->prepare( "SELECT COUNT(DISTINCT post_id) FROM {$wpdb->postmeta} pm JOIN {$wpdb->posts} p ON p.ID = pm.post_id WHERE p.post_type = %s ", 'easy-invoice-payment' )); // Use the higher count between posts and meta $invoice_count = max($invoice_count, $invoice_meta_count); $quote_count = max($quote_count, $quote_meta_count); $payment_count = max($payment_count, $payment_meta_count); // Count old options $options_count = 0; $old_options = [ 'easy_invoice_version', 'easy_invoice_currency', 'easy_invoice_tax_rate', 'easy_invoice_tax_name', 'easy_invoice_business_name', 'easy_invoice_business_address', 'easy_invoice_invoice_number', 'easy_invoice_quote_number', 'easy_invoice_payment_gateway_paypal_email', 'easy_invoice_terms_conditions', 'easy_invoice_quote_terms_conditions', 'easy_invoice_pre_defined_line_items', 'easy_invoice_currency_symbol_type', 'easy_invoice_price_number_decimals', 'easy_invoice_decimal_separator', 'easy_invoice_thousand_separator', 'easy_invoice_currency_position', 'easy_invoice_email_from_address', 'easy_invoice_email_from_name', 'easy_invoice_email_send_admin_copy', 'easy_invoice_queue_flush_rewrite_rules', 'easy_invoice_first_install_time', 'easy_invoice_payment_methods', 'easy_invoice_payment_gateway_order', 'easy_invoice_payment_email_enabled', 'easy_invoice_payment_email_subject', 'easy_invoice_payment_email_body', 'easy_invoice_payment_terms', 'easy_invoice_payment_reminder_days' ]; // Count options using direct SQL query $option_placeholders = implode(',', array_fill(0, count($old_options), '%s')); $options_count = (int)$wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->options} WHERE option_name IN ($option_placeholders)", $old_options )); wp_send_json_success([ 'invoices' => $invoice_count, 'quotes' => $quote_count, 'payments' => $payment_count, 'options' => $options_count, 'details' => [ 'invoice_meta_count' => $invoice_meta_count, 'quote_meta_count' => $quote_meta_count, 'payment_meta_count' => $payment_meta_count ] ]); } catch (\Exception $e) { wp_send_json_error([ 'message' => $e->getMessage(), ]); } } /** * Handle AJAX cleanup request. * * @since 2.0.0 * @return void */ public static function handle_ajax_cleanup() { // Check nonce if (!wp_verify_nonce($_POST['nonce'], 'easy_invoice_migration_nonce')) { wp_die('Security check failed'); } // Check permissions if (!current_user_can('manage_options')) { wp_die('Insufficient permissions'); } try { $cleanup_options = isset($_POST['options']) ? (array)$_POST['options'] : []; $result = self::$migration_runner->run_migration_step('cleanup', $cleanup_options); if ($result['success']) { wp_send_json_success($result); } else { wp_send_json_error($result); } } catch (\Exception $e) { wp_send_json_error([ 'message' => $e->getMessage(), ]); } } /** * Register old post types temporarily. * * @since 2.0.0 * @return void */ private static function register_old_post_types() { // Only register if not already registered if (!post_type_exists('easy-invoice')) { register_post_type('easy-invoice', [ 'public' => false, 'show_ui' => false, 'capability_type' => 'post', 'supports' => ['title', 'editor', 'custom-fields'], 'can_export' => true ]); } if (!post_type_exists('easy-invoice-quotes')) { register_post_type('easy-invoice-quotes', [ 'public' => false, 'show_ui' => false, 'capability_type' => 'post', 'supports' => ['title', 'editor', 'custom-fields'], 'can_export' => true ]); } if (!post_type_exists('easy-invoice-payment')) { register_post_type('easy-invoice-payment', [ 'public' => false, 'show_ui' => false, 'capability_type' => 'post', 'supports' => ['title', 'editor', 'custom-fields'], 'can_export' => true ]); } } }