PluginProbe
Easy Invoice – Invoice Generator, PDF Quotes & Payments / 2.3.2
Easy Invoice – Invoice Generator, PDF Quotes & Payments v2.3.2
2.4.0 2.4.1 2.3.8 2.3.7 2.3.6 2.3.5 2.3.4 2.3.3 2.3.2 2.3.1 2.2.0 2.1.21 2.1.20 2.1.19 2.1.18 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.13 2.1.14 2.1.15 2.1.16 2.1.2 All 57 releases
easy-invoice / includes / Migration / MigrationLoader.php

MigrationLoader.php in Easy Invoice – Invoice Generator, PDF Quotes & Payments 2.3.2, at includes/Migration/MigrationLoader.php

311 lines 10.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Migration Loader for Easy Invoice
4 *
5 * @package EasyInvoice
6 * @subpackage Migration
7 * @since 2.0.0
8 */
9
10 namespace EasyInvoice\Migration;
11
12 use EasyInvoice\Migration\Src\SettingsMigration;
13 use EasyInvoice\Migration\Src\ClientMigration;
14 use EasyInvoice\Migration\Src\PostTypeMigration;
15 use EasyInvoice\Migration\Src\MetaMigration;
16 use EasyInvoice\Migration\Src\ProOptionsMigration;
17 use EasyInvoice\Migration\Src\DataCleanupMigration;
18
19 /**
20 * Migration loader class.
21 *
22 * Handles migration-related initialization, asset loading, and AJAX handlers.
23 *
24 * @since 2.0.0
25 */
26 class MigrationLoader {
27
28 /**
29 * Migration runner instance.
30 *
31 * @since 2.0.0
32 * @var MigrationRunner
33 */
34 private static $migration_runner;
35
36 /**
37 * Initialize the migration loader.
38 *
39 * @since 2.0.0
40 * @return void
41 */
42 public static function init() {
43 // Initialize migration runner with version checker
44 self::$migration_runner = new MigrationRunner(VersionChecker::get_instance());
45
46 // Add AJAX handlers
47 add_action('wp_ajax_easy_invoice_migration', [__CLASS__, 'handle_ajax_migration']);
48 add_action('wp_ajax_easy_invoice_migration_status', [__CLASS__, 'handle_check_status']);
49 add_action('wp_ajax_easy_invoice_migration_counts', [__CLASS__, 'handle_get_migration_counts']);
50 add_action('wp_ajax_easy_invoice_migration_cleanup', [__CLASS__, 'handle_ajax_cleanup']);
51 }
52
53 /**
54 * Handle AJAX migration request.
55 *
56 * @since 2.0.0
57 * @return void
58 */
59 public static function handle_ajax_migration() {
60 // Check nonce
61 if (!wp_verify_nonce($_POST['nonce'], 'easy_invoice_migration_nonce')) {
62 wp_die('Security check failed');
63 }
64
65 // Check permissions
66 if (!current_user_can('manage_options')) {
67 wp_die('Insufficient permissions');
68 }
69
70 try {
71 $step = isset($_POST['step']) ? sanitize_text_field($_POST['step']) : '';
72
73 if (empty($step)) {
74 // Run full migration
75 $result = self::$migration_runner->run_migration();
76 } else {
77 // Run specific step
78 $result = self::$migration_runner->run_migration_step($step);
79 }
80
81 if ($result['success']) {
82 wp_send_json_success($result);
83 } else {
84 wp_send_json_error($result);
85 }
86
87 } catch (\Exception $e) {
88 wp_send_json_error([
89 'message' => $e->getMessage(),
90 ]);
91 }
92 }
93
94 /**
95 * Handle AJAX check status request.
96 *
97 * @since 2.0.0
98 * @return void
99 */
100 public static function handle_check_status() {
101 // Check nonce
102 if (!wp_verify_nonce($_GET['nonce'], 'easy_invoice_migration_nonce')) {
103 wp_die('Security check failed');
104 }
105
106 // Check permissions
107 if (!current_user_can('manage_options')) {
108 wp_die('Insufficient permissions');
109 }
110
111 try {
112 $status = self::$migration_runner->get_migration_status();
113 wp_send_json_success($status);
114
115 } catch (\Exception $e) {
116 wp_send_json_error([
117 'message' => $e->getMessage(),
118 ]);
119 }
120 }
121
122 /**
123 * Handle AJAX get migration counts request.
124 *
125 * @since 2.0.0
126 * @return void
127 */
128 public static function handle_get_migration_counts() {
129 // Check nonce
130 if (!wp_verify_nonce($_GET['nonce'], 'easy_invoice_migration_nonce')) {
131 wp_die('Security check failed');
132 }
133
134 // Check permissions
135 if (!current_user_can('manage_options')) {
136 wp_die('Insufficient permissions');
137 }
138
139 try {
140 global $wpdb;
141
142 // First, temporarily register old post types to ensure they're recognized
143 self::register_old_post_types();
144
145 // Count old post types using direct SQL queries with all possible statuses
146 $invoice_count = (int)$wpdb->get_var($wpdb->prepare(
147 "SELECT COUNT(*) FROM {$wpdb->posts}
148 WHERE post_type = %s
149 ",
150 'easy-invoice'
151 ));
152
153 $quote_count = (int)$wpdb->get_var($wpdb->prepare(
154 "SELECT COUNT(*) FROM {$wpdb->posts}
155 WHERE post_type = %s
156 ",
157 'easy-invoice-quotes'
158 ));
159
160 $payment_count = (int)$wpdb->get_var($wpdb->prepare(
161 "SELECT COUNT(*) FROM {$wpdb->posts}
162 WHERE post_type = %s
163 ",
164 'easy-invoice-payment'
165 ));
166
167 // Double-check with meta data
168 $invoice_meta_count = (int)$wpdb->get_var($wpdb->prepare(
169 "SELECT COUNT(DISTINCT post_id) FROM {$wpdb->postmeta} pm
170 JOIN {$wpdb->posts} p ON p.ID = pm.post_id
171 WHERE p.post_type = %s
172 ",
173 'easy-invoice'
174 ));
175
176 $quote_meta_count = (int)$wpdb->get_var($wpdb->prepare(
177 "SELECT COUNT(DISTINCT post_id) FROM {$wpdb->postmeta} pm
178 JOIN {$wpdb->posts} p ON p.ID = pm.post_id
179 WHERE p.post_type = %s
180 ",
181 'easy-invoice-quotes'
182 ));
183
184 $payment_meta_count = (int)$wpdb->get_var($wpdb->prepare(
185 "SELECT COUNT(DISTINCT post_id) FROM {$wpdb->postmeta} pm
186 JOIN {$wpdb->posts} p ON p.ID = pm.post_id
187 WHERE p.post_type = %s
188 ",
189 'easy-invoice-payment'
190 ));
191
192 // Use the higher count between posts and meta
193 $invoice_count = max($invoice_count, $invoice_meta_count);
194 $quote_count = max($quote_count, $quote_meta_count);
195 $payment_count = max($payment_count, $payment_meta_count);
196
197 // Count old options
198 $options_count = 0;
199 $old_options = [
200 'easy_invoice_version', 'easy_invoice_currency', 'easy_invoice_tax_rate',
201 'easy_invoice_tax_name', 'easy_invoice_business_name', 'easy_invoice_business_address',
202 'easy_invoice_invoice_number', 'easy_invoice_quote_number', 'easy_invoice_payment_gateway_paypal_email',
203 'easy_invoice_terms_conditions', 'easy_invoice_quote_terms_conditions', 'easy_invoice_pre_defined_line_items',
204 'easy_invoice_currency_symbol_type', 'easy_invoice_price_number_decimals', 'easy_invoice_decimal_separator',
205 'easy_invoice_thousand_separator', 'easy_invoice_currency_position', 'easy_invoice_email_from_address',
206 'easy_invoice_email_from_name', 'easy_invoice_email_send_admin_copy', 'easy_invoice_queue_flush_rewrite_rules',
207 'easy_invoice_first_install_time', 'easy_invoice_payment_methods', 'easy_invoice_payment_gateway_order',
208 'easy_invoice_payment_email_enabled', 'easy_invoice_payment_email_subject', 'easy_invoice_payment_email_body',
209 'easy_invoice_payment_terms', 'easy_invoice_payment_reminder_days'
210 ];
211
212 // Count options using direct SQL query
213 $option_placeholders = implode(',', array_fill(0, count($old_options), '%s'));
214 $options_count = (int)$wpdb->get_var($wpdb->prepare(
215 "SELECT COUNT(*) FROM {$wpdb->options} WHERE option_name IN ($option_placeholders)",
216 $old_options
217 ));
218
219 wp_send_json_success([
220 'invoices' => $invoice_count,
221 'quotes' => $quote_count,
222 'payments' => $payment_count,
223 'options' => $options_count,
224 'details' => [
225 'invoice_meta_count' => $invoice_meta_count,
226 'quote_meta_count' => $quote_meta_count,
227 'payment_meta_count' => $payment_meta_count
228 ]
229 ]);
230
231 } catch (\Exception $e) {
232 wp_send_json_error([
233 'message' => $e->getMessage(),
234 ]);
235 }
236 }
237
238 /**
239 * Handle AJAX cleanup request.
240 *
241 * @since 2.0.0
242 * @return void
243 */
244 public static function handle_ajax_cleanup() {
245 // Check nonce
246 if (!wp_verify_nonce($_POST['nonce'], 'easy_invoice_migration_nonce')) {
247 wp_die('Security check failed');
248 }
249
250 // Check permissions
251 if (!current_user_can('manage_options')) {
252 wp_die('Insufficient permissions');
253 }
254
255 try {
256 $cleanup_options = isset($_POST['options']) ? (array)$_POST['options'] : [];
257 $result = self::$migration_runner->run_migration_step('cleanup', $cleanup_options);
258
259 if ($result['success']) {
260 wp_send_json_success($result);
261 } else {
262 wp_send_json_error($result);
263 }
264
265 } catch (\Exception $e) {
266 wp_send_json_error([
267 'message' => $e->getMessage(),
268 ]);
269 }
270 }
271
272 /**
273 * Register old post types temporarily.
274 *
275 * @since 2.0.0
276 * @return void
277 */
278 private static function register_old_post_types() {
279 // Only register if not already registered
280 if (!post_type_exists('easy-invoice')) {
281 register_post_type('easy-invoice', [
282 'public' => false,
283 'show_ui' => false,
284 'capability_type' => 'post',
285 'supports' => ['title', 'editor', 'custom-fields'],
286 'can_export' => true
287 ]);
288 }
289
290 if (!post_type_exists('easy-invoice-quotes')) {
291 register_post_type('easy-invoice-quotes', [
292 'public' => false,
293 'show_ui' => false,
294 'capability_type' => 'post',
295 'supports' => ['title', 'editor', 'custom-fields'],
296 'can_export' => true
297 ]);
298 }
299
300 if (!post_type_exists('easy-invoice-payment')) {
301 register_post_type('easy-invoice-payment', [
302 'public' => false,
303 'show_ui' => false,
304 'capability_type' => 'post',
305 'supports' => ['title', 'editor', 'custom-fields'],
306 'can_export' => true
307 ]);
308 }
309 }
310 }
311