PluginProbe
Easy Invoice – Invoice Generator, PDF Quotes & Payments / 2.3.7
Easy Invoice – Invoice Generator, PDF Quotes & Payments v2.3.7
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 / Src / OptionsMigration.php

OptionsMigration.php in Easy Invoice – Invoice Generator, PDF Quotes & Payments 2.3.7, at includes/Migration/Src/OptionsMigration.php

550 lines 23.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Options Migration
4 *
5 * Migrates options from old plugin to new plugin structure.
6 *
7 * @since 2.0.0
8 * @package EasyInvoice
9 */
10
11 namespace EasyInvoice\Migration\Src;
12
13 /**
14 * Options Migration Class
15 *
16 * @since 2.0.0
17 */
18 class OptionsMigration extends AbstractMigration {
19
20 /**
21 * Old options to migrate.
22 * Maps old option names to new option names.
23 *
24 * @since 2.0.0
25 * @var array
26 */
27 private $old_options = [
28 // Core settings
29 'easy_invoice_settings' => [
30 // Company info
31 'company_name' => 'easy_invoice_company_name',
32 'company_address' => 'easy_invoice_company_address',
33 'company_logo' => 'easy_invoice_company_logo',
34 'company_additional_info' => 'easy_invoice_company_additional_info',
35 'company_email' => 'easy_invoice_company_email',
36 'company_phone' => 'easy_invoice_company_phone',
37 'company_website' => 'easy_invoice_company_website',
38 'company_vat' => 'easy_invoice_company_vat',
39 'company_registration' => 'easy_invoice_company_registration',
40
41 // Currency settings
42 'currency_code' => 'easy_invoice_currency_code',
43 'currency_symbol' => 'easy_invoice_currency_symbol',
44 'currency_position' => 'easy_invoice_currency_position',
45 'decimal_separator' => 'easy_invoice_decimal_separator',
46 'thousand_separator' => 'easy_invoice_thousands_separator',
47 'decimal_precision' => 'easy_invoice_decimal_precision',
48 'currency_symbol_type' => 'easy_invoice_currency_symbol_type',
49
50 // Tax settings
51 'tax_rate' => 'easy_invoice_tax_rate',
52 'tax_name' => 'easy_invoice_tax_name',
53 'tax_type' => 'easy_invoice_tax_entry_method',
54 'tax_enabled' => 'easy_invoice_tax_enabled',
55 'tax_label' => 'easy_invoice_tax_label',
56 'tax_number' => 'easy_invoice_tax_number',
57
58 // PDF settings
59 'pdf_paper_size' => 'easy_invoice_pdf_paper_size',
60 'pdf_font_family' => 'easy_invoice_pdf_font_family',
61 'pdf_font_size' => 'easy_invoice_pdf_font_size',
62 'pdf_margin_top' => 'easy_invoice_pdf_margin_top',
63 'pdf_margin_bottom' => 'easy_invoice_pdf_margin_bottom',
64 'pdf_margin_left' => 'easy_invoice_pdf_margin_left',
65 'pdf_margin_right' => 'easy_invoice_pdf_margin_right',
66
67 // Template settings
68 'invoice_template' => 'easy_invoice_invoice_template',
69 'quote_template' => 'easy_invoice_quote_template',
70 'template_color' => 'easy_invoice_template_color',
71 'template_font' => 'easy_invoice_template_font',
72 'template_font_size' => 'easy_invoice_template_font_size',
73
74 // Watermark settings
75 'invoice_watermark_type' => 'easy_invoice_pro_invoice_watermark_type',
76 'invoice_watermark_text' => 'easy_invoice_pro_invoice_text_watermark',
77 'invoice_watermark_image' => 'easy_invoice_pro_invoice_image_watermark',
78 'invoice_watermark_opacity' => 'easy_invoice_pro_invoice_watermark_opacity',
79 'invoice_watermark_color' => 'easy_invoice_pro_invoice_text_watermark_color',
80 'invoice_watermark_size' => 'easy_invoice_pro_invoice_image_watermark_size',
81 'quote_watermark_type' => 'easy_invoice_pro_quote_watermark_type',
82 'quote_watermark_text' => 'easy_invoice_pro_quote_text_watermark',
83 'quote_watermark_image' => 'easy_invoice_pro_quote_image_watermark',
84 'quote_watermark_opacity' => 'easy_invoice_pro_quote_watermark_opacity',
85 'quote_watermark_color' => 'easy_invoice_pro_quote_text_watermark_color',
86 'quote_watermark_size' => 'easy_invoice_pro_quote_image_watermark_size',
87
88 // Client settings
89 'client_portal_enabled' => 'easy_invoice_client_portal_enabled',
90 'client_registration_enabled' => 'easy_invoice_client_registration_enabled',
91 'client_login_redirect' => 'easy_invoice_client_login_redirect',
92 'client_registration_redirect' => 'easy_invoice_client_registration_redirect',
93
94 // Notification settings
95 'notification_invoice_created' => 'easy_invoice_notification_invoice_created',
96 'notification_invoice_sent' => 'easy_invoice_notification_invoice_sent',
97 'notification_invoice_viewed' => 'easy_invoice_notification_invoice_viewed',
98 'notification_invoice_paid' => 'easy_invoice_notification_invoice_paid',
99 'notification_quote_created' => 'easy_invoice_notification_quote_created',
100 'notification_quote_sent' => 'easy_invoice_notification_quote_sent',
101 'notification_quote_viewed' => 'easy_invoice_notification_quote_viewed',
102 'notification_quote_accepted' => 'easy_invoice_notification_quote_accepted',
103 'notification_quote_declined' => 'easy_invoice_notification_quote_declined'
104 ],
105
106 // Invoice settings
107 'easy_invoice_invoice_settings' => [
108 'next_number' => 'easy_invoice_next_invoice_number',
109 'prefix' => 'easy_invoice_invoice_prefix',
110 'starting_number' => 'easy_invoice_invoice_starting_number',
111 'due_days' => 'easy_invoice_invoice_due_days',
112 'footer_text' => 'easy_invoice_invoice_footer_text',
113 'terms_conditions' => 'easy_invoice_invoice_terms_conditions',
114 'show_adjust_field' => 'easy_invoice_invoice_show_adjust_field',
115 'enable_payment_button' => 'easy_invoice_enable_payment_button',
116 'payment_button_link' => 'easy_invoice_payment_button_link'
117 ],
118
119 // Quote settings
120 'easy_invoice_quote_settings' => [
121 'next_number' => 'easy_invoice_next_quote_number',
122 'prefix' => 'easy_invoice_quote_prefix',
123 'starting_number' => 'easy_invoice_quote_starting_number',
124 'footer_text' => 'easy_invoice_quote_footer_text',
125 'terms_conditions' => 'easy_invoice_quote_terms_conditions',
126 'show_adjust_field' => 'easy_invoice_quote_show_adjust_field',
127 'accept_text' => 'easy_invoice_quote_accept_text',
128 'accepted_message' => 'easy_invoice_quote_accepted_message',
129 'accept_button' => 'easy_invoice_quote_accept_button',
130 'accept_action' => 'easy_invoice_quote_accept_action',
131 'decline_reason_required' => 'easy_invoice_quote_decline_reason_required',
132 'declined_message' => 'easy_invoice_quote_declined_message'
133 ],
134
135 // Payment settings
136 'easy_invoice_payment_settings' => [
137 'paypal_email' => 'easy_invoice_paypal_email',
138 'paypal_label' => 'easy_invoice_paypal_label',
139 'paypal_mode' => 'easy_invoice_paypal_mode',
140 'payment_methods' => 'easy_invoice_payment_methods',
141 'thankyou_page' => 'easy_invoice_thankyou_page',
142 'payment_terms' => 'easy_invoice_payment_terms',
143 'payment_reminder_days' => 'easy_invoice_payment_reminder_days'
144 ],
145
146 // Email settings
147 'easy_invoice_email_settings' => [
148 'from_name' => 'easy_invoice_email_from_name',
149 'from_address' => 'easy_invoice_email_from_address',
150 'reply_to' => 'easy_invoice_email_reply_to',
151 'reply_to_name' => 'easy_invoice_email_reply_to_name',
152 'bcc_admin' => 'easy_invoice_bcc_admin',
153 'admin_email' => 'easy_invoice_admin_email',
154 'enable_styling' => 'easy_invoice_enable_email_styling',
155 'logo' => 'easy_invoice_email_logo',
156 'footer_text' => 'easy_invoice_email_footer_text',
157 'invoice_email_enabled' => 'easy_invoice_invoice_email_enabled',
158 'invoice_email_subject' => 'easy_invoice_invoice_email_subject',
159 'invoice_email_body' => 'easy_invoice_invoice_email_body',
160 'quote_email_enabled' => 'easy_invoice_quote_email_enabled',
161 'quote_email_subject' => 'easy_invoice_quote_email_subject',
162 'quote_email_body' => 'easy_invoice_quote_email_body',
163 'payment_email_enabled' => 'easy_invoice_payment_email_enabled',
164 'payment_email_subject' => 'easy_invoice_payment_email_subject',
165 'payment_email_body' => 'easy_invoice_payment_email_body',
166 'reminder_subject' => 'easy_invoice_reminder_subject',
167 'reminder_body' => 'easy_invoice_reminder_body'
168 ],
169
170 // Pro settings
171 'easy_invoice_pro_settings' => [
172 'license_key' => 'easy_invoice_pro_license_key',
173 'license_status' => 'easy_invoice_pro_license_status',
174 'license_expiry' => 'easy_invoice_pro_license_expiry',
175 'license_type' => 'easy_invoice_pro_license_type'
176 ],
177
178 // System settings
179 'easy_invoice_system_settings' => [
180 'version' => 'easy_invoice_version',
181 'first_install_time' => 'easy_invoice_first_install_time',
182 'post_types_registered' => 'easy_invoice_post_types_registered',
183 'last_rewrite_flush' => 'easy_invoice_last_rewrite_flush',
184 'flush_rewrite_rules' => 'easy_invoice_flush_rewrite_rules'
185 ]
186 ];
187
188 /**
189 * New options mapping.
190 * Maps new option names to their actual database names.
191 *
192 * @since 2.0.0
193 * @var array
194 */
195 private $new_options = [
196 // Core settings
197 'easy_invoice_version' => 'easy_invoice_version',
198 'easy_invoice_currency_code' => 'easy_invoice_currency_code',
199 'easy_invoice_tax_rate' => 'easy_invoice_tax_rate',
200 'easy_invoice_tax_name' => 'easy_invoice_tax_name',
201 'easy_invoice_tax_entry_method' => 'easy_invoice_tax_entry_method',
202 'easy_invoice_tax_enabled' => 'easy_invoice_tax_enabled',
203
204 // Business settings
205 'easy_invoice_company_name' => 'easy_invoice_company_name',
206 'easy_invoice_company_address' => 'easy_invoice_company_address',
207 'easy_invoice_company_logo' => 'easy_invoice_company_logo',
208 'easy_invoice_company_additional_info' => 'easy_invoice_company_additional_info',
209 'easy_invoice_company_email' => 'easy_invoice_company_email',
210 'easy_invoice_company_phone' => 'easy_invoice_company_phone',
211 'easy_invoice_company_website' => 'easy_invoice_company_website',
212
213 // Invoice settings
214 'easy_invoice_next_invoice_number' => 'easy_invoice_next_invoice_number',
215 'easy_invoice_invoice_prefix' => 'easy_invoice_invoice_prefix',
216 'easy_invoice_invoice_permalink' => 'easy_invoice_invoice_permalink',
217 'easy_invoice_invoice_show_adjust_field' => 'easy_invoice_invoice_show_adjust_field',
218 'easy_invoice_invoice_footer_text' => 'easy_invoice_invoice_footer_text',
219 'easy_invoice_invoice_terms_conditions' => 'easy_invoice_invoice_terms_conditions',
220 'easy_invoice_enable_payment_button' => 'easy_invoice_enable_payment_button',
221 'easy_invoice_payment_button_link' => 'easy_invoice_payment_button_link',
222 'easy_invoice_predefined_items' => 'easy_invoice_predefined_items',
223 'easy_invoice_invoice_starting_number' => 'easy_invoice_invoice_starting_number',
224 'easy_invoice_invoice_due_days' => 'easy_invoice_invoice_due_days',
225
226 // Quote settings
227 'easy_invoice_next_quote_number' => 'easy_invoice_next_quote_number',
228 'easy_invoice_quote_prefix' => 'easy_invoice_quote_prefix',
229 'easy_invoice_quote_permalink' => 'easy_invoice_quote_permalink',
230 'easy_invoice_quote_show_adjust_field' => 'easy_invoice_quote_show_adjust_field',
231 'easy_invoice_quote_footer_text' => 'easy_invoice_quote_footer_text',
232 'easy_invoice_quote_terms_conditions' => 'easy_invoice_quote_terms_conditions',
233 'easy_invoice_quote_accept_text' => 'easy_invoice_quote_accept_text',
234 'easy_invoice_quote_accepted_message' => 'easy_invoice_quote_accepted_message',
235 'easy_invoice_quote_accept_button' => 'easy_invoice_quote_accept_button',
236 'easy_invoice_quote_accept_action' => 'easy_invoice_quote_accept_action',
237 'easy_invoice_quote_decline_reason_required' => 'easy_invoice_quote_decline_reason_required',
238 'easy_invoice_quote_declined_message' => 'easy_invoice_quote_declined_message',
239 'easy_invoice_quote_starting_number' => 'easy_invoice_quote_starting_number',
240
241 // Currency settings
242 'easy_invoice_currency_symbol_type' => 'easy_invoice_currency_symbol_type',
243 'easy_invoice_decimal_precision' => 'easy_invoice_decimal_precision',
244 'easy_invoice_decimal_separator' => 'easy_invoice_decimal_separator',
245 'easy_invoice_thousands_separator' => 'easy_invoice_thousands_separator',
246 'easy_invoice_currency_position' => 'easy_invoice_currency_position',
247 'easy_invoice_currency_symbol' => 'easy_invoice_currency_symbol',
248
249 // Payment settings
250 'easy_invoice_paypal_email' => 'easy_invoice_paypal_email',
251 'easy_invoice_paypal_label' => 'easy_invoice_paypal_label',
252 'easy_invoice_paypal_mode' => 'easy_invoice_paypal_mode',
253 'easy_invoice_payment_methods' => 'easy_invoice_payment_methods',
254 'easy_invoice_thankyou_page' => 'easy_invoice_thankyou_page',
255 'easy_invoice_payment_gateway_order' => 'easy_invoice_payment_gateway_order',
256
257 // Email settings
258 'easy_invoice_email_from_address' => 'easy_invoice_email_from_address',
259 'easy_invoice_email_from_name' => 'easy_invoice_email_from_name',
260 'easy_invoice_email_reply_to' => 'easy_invoice_email_reply_to',
261 'easy_invoice_email_reply_to_name' => 'easy_invoice_email_reply_to_name',
262 'easy_invoice_enable_email_styling' => 'easy_invoice_enable_email_styling',
263 'easy_invoice_email_logo' => 'easy_invoice_email_logo',
264 'easy_invoice_email_footer_text' => 'easy_invoice_email_footer_text',
265 'easy_invoice_bcc_admin' => 'easy_invoice_bcc_admin',
266 'easy_invoice_admin_email' => 'easy_invoice_admin_email',
267 'easy_invoice_invoice_email_enabled' => 'easy_invoice_invoice_email_enabled',
268 'easy_invoice_invoice_email_subject' => 'easy_invoice_invoice_email_subject',
269 'easy_invoice_invoice_email_body' => 'easy_invoice_invoice_email_body',
270 'easy_invoice_reminder_subject' => 'easy_invoice_reminder_subject',
271 'easy_invoice_reminder_body' => 'easy_invoice_reminder_body',
272 'easy_invoice_payment_email_enabled' => 'easy_invoice_payment_email_enabled',
273 'easy_invoice_payment_email_subject' => 'easy_invoice_payment_email_subject',
274 'easy_invoice_payment_email_body' => 'easy_invoice_payment_email_body',
275 'easy_invoice_quote_email_enabled' => 'easy_invoice_quote_email_enabled',
276 'easy_invoice_quote_email_subject' => 'easy_invoice_quote_email_subject',
277 'easy_invoice_quote_email_body' => 'easy_invoice_quote_email_body',
278 'easy_invoice_quote_accepted_subject' => 'easy_invoice_quote_accepted_subject',
279 'easy_invoice_quote_accepted_body' => 'easy_invoice_quote_accepted_body',
280 'easy_invoice_quote_declined_subject' => 'easy_invoice_quote_declined_subject',
281 'easy_invoice_quote_declined_body' => 'easy_invoice_quote_declined_body',
282
283 // System settings
284 'easy_invoice_flush_rewrite_rules' => 'easy_invoice_flush_rewrite_rules',
285 'easy_invoice_first_install_time' => 'easy_invoice_first_install_time',
286 'easy_invoice_post_types_registered' => 'easy_invoice_post_types_registered',
287 'easy_invoice_last_rewrite_flush' => 'easy_invoice_last_rewrite_flush',
288
289 // Additional settings
290 'easy_invoice_payment_terms' => 'easy_invoice_payment_terms',
291 'easy_invoice_payment_reminder_days' => 'easy_invoice_payment_reminder_days',
292 ];
293
294 /**
295 * Check if migration is needed.
296 *
297 * @since 2.0.0
298 * @return bool
299 */
300 public function is_needed(): bool {
301 // Check if any old options exist
302 foreach ( $this->old_options as $old_option => $new_option ) {
303 if ( $this->option_exists( $old_option ) ) {
304 $this->log( sprintf( 'Found option %s that needs migration', $old_option ) );
305 return true;
306 }
307 }
308
309 return false;
310 }
311
312 /**
313 * Run the migration.
314 *
315 * @since 2.0.0
316 * @return array
317 */
318 public function migrate(): array {
319 $this->log( 'Starting options migration' );
320
321 try {
322 $migrated_count = 0;
323 $errors = [];
324
325 foreach ( $this->old_options as $old_option => $new_option ) {
326 $result = $this->migrate_option( $old_option, $new_option );
327
328 if ( $result['success'] ) {
329 $migrated_count++;
330 $this->log( sprintf( 'Successfully migrated option %s to %s', $old_option, $new_option ) );
331 } else {
332 $errors[] = $result['message'];
333 $this->log( sprintf( 'Failed to migrate option %s: %s', $old_option, $result['message'] ), 'error' );
334 }
335 }
336
337 if ( empty( $errors ) ) {
338 return $this->success_result( sprintf( 'Successfully migrated %d options', $migrated_count ) );
339 } else {
340 return $this->error_result( 'Options migration completed with errors: ' . implode( ', ', $errors ) );
341 }
342
343 } catch ( \Exception $e ) {
344 $this->log( 'Options migration failed: ' . $e->getMessage(), 'error' );
345 return $this->error_result( 'Options migration failed: ' . $e->getMessage() );
346 }
347 }
348
349 /**
350 * Migrate a specific option.
351 *
352 * @since 2.0.0
353 * @param string $old_option Old option name.
354 * @param string $new_option New option name.
355 * @return array
356 */
357 private function migrate_option( string $old_option, string $new_option ): array {
358 if ( ! $this->option_exists( $old_option ) ) {
359 return [
360 'success' => true,
361 'message' => sprintf( 'Option %s does not exist', $old_option ),
362 ];
363 }
364
365 try {
366 $option_value = get_option( $old_option );
367
368 if ( $option_value === false ) {
369 return [
370 'success' => true,
371 'message' => sprintf( 'Option %s has no value', $old_option ),
372 ];
373 }
374
375 // Transform option value if needed
376 $transformed_value = $this->transform_option_value( $old_option, $option_value );
377
378 // Update new option
379 $update_result = $this->update_option_safe( $new_option, $transformed_value );
380
381 if ( $update_result ) {
382 // Delete old option after successful migration
383 $this->delete_option_safe( $old_option );
384
385 return [
386 'success' => true,
387 'message' => sprintf( 'Successfully migrated option %s', $old_option ),
388 ];
389 } else {
390 return [
391 'success' => false,
392 'message' => sprintf( 'Failed to update new option %s', $new_option ),
393 ];
394 }
395
396 } catch ( \Exception $e ) {
397 return [
398 'success' => false,
399 'message' => $e->getMessage(),
400 ];
401 }
402 }
403
404 /**
405 * Transform option value for new structure.
406 *
407 * @since 2.0.0
408 * @param string $option_name Option name.
409 * @param mixed $option_value Option value.
410 * @return mixed
411 */
412 private function transform_option_value( string $option_name, $option_value ) {
413 // Handle nested settings arrays
414 if (is_array($option_value)) {
415 $transformed = [];
416
417 // Get the mapping for this settings group
418 $mappings = $this->old_options[$option_name] ?? [];
419
420 if (!empty($mappings)) {
421 foreach ($option_value as $key => $value) {
422 // Check if we have a mapping for this key
423 if (isset($mappings[$key])) {
424 $new_key = $mappings[$key];
425
426 // Transform the value if needed
427 switch ($key) {
428 case 'payment_methods':
429 $transformed[$new_key] = $this->transform_payment_methods($value);
430 break;
431
432 case 'tax_type':
433 $transformed[$new_key] = $this->transform_tax_type($value);
434 break;
435
436 case 'currency_position':
437 $transformed[$new_key] = $this->transform_currency_position($value);
438 break;
439
440 default:
441 $transformed[$new_key] = $value;
442 }
443 }
444 }
445 }
446
447 return $transformed;
448 }
449
450 return $option_value;
451 }
452
453 /**
454 * Transform tax type value.
455 *
456 * @param string $value Old tax type value
457 * @return string New tax type value
458 */
459 private function transform_tax_type($value) {
460 $map = [
461 'inclusive' => 'inclusive',
462 'exclusive' => 'exclusive',
463 'none' => 'none'
464 ];
465
466 return $map[$value] ?? 'exclusive';
467 }
468
469 /**
470 * Transform currency position value.
471 *
472 * @param string $value Old currency position value
473 * @return string New currency position value
474 */
475 private function transform_currency_position($value) {
476 $map = [
477 'left' => 'before',
478 'right' => 'after',
479 'left_space' => 'before_space',
480 'right_space' => 'after_space'
481 ];
482
483 return $map[$value] ?? 'before';
484 }
485
486 /**
487 * Transform payment methods array.
488 *
489 * @param array $methods Old payment methods array
490 * @return array New payment methods array
491 */
492 private function transform_payment_methods($methods) {
493 if (!is_array($methods)) {
494 return [];
495 }
496
497 $transformed = [];
498 foreach ($methods as $method) {
499 if (is_array($method)) {
500 $transformed[] = [
501 'id' => $method['id'] ?? '',
502 'name' => $method['name'] ?? '',
503 'description' => $method['description'] ?? '',
504 'enabled' => isset($method['enabled']) ? (bool)$method['enabled'] : true,
505 'settings' => $method['settings'] ?? []
506 ];
507 }
508 }
509
510 return $transformed;
511 }
512
513 /**
514 * Transform settings option.
515 *
516 * @since 2.0.0
517 * @param mixed $settings Settings value.
518 * @return mixed
519 */
520 private function transform_settings( $settings ) {
521 if ( ! is_array( $settings ) ) {
522 return $settings;
523 }
524
525 // Add any specific settings transformations here
526 // For example, rename keys, restructure arrays, etc.
527
528 return $settings;
529 }
530
531 /**
532 * Transform email settings option.
533 *
534 * @since 2.0.0
535 * @param mixed $email_settings Email settings value.
536 * @return mixed
537 */
538 private function transform_email_settings( $email_settings ) {
539 if ( ! is_array( $email_settings ) ) {
540 return $email_settings;
541 }
542
543 // Add any specific email settings transformations here
544
545 return $email_settings;
546 }
547
548
549 }
550