[ // Company info 'company_name' => 'easy_invoice_company_name', 'company_address' => 'easy_invoice_company_address', 'company_logo' => 'easy_invoice_company_logo', 'company_additional_info' => 'easy_invoice_company_additional_info', 'company_email' => 'easy_invoice_company_email', 'company_phone' => 'easy_invoice_company_phone', 'company_website' => 'easy_invoice_company_website', 'company_vat' => 'easy_invoice_company_vat', 'company_registration' => 'easy_invoice_company_registration', // Currency settings 'currency_code' => 'easy_invoice_currency_code', 'currency_symbol' => 'easy_invoice_currency_symbol', 'currency_position' => 'easy_invoice_currency_position', 'decimal_separator' => 'easy_invoice_decimal_separator', 'thousand_separator' => 'easy_invoice_thousands_separator', 'decimal_precision' => 'easy_invoice_decimal_precision', 'currency_symbol_type' => 'easy_invoice_currency_symbol_type', // Tax settings 'tax_rate' => 'easy_invoice_tax_rate', 'tax_name' => 'easy_invoice_tax_name', 'tax_type' => 'easy_invoice_tax_entry_method', 'tax_enabled' => 'easy_invoice_tax_enabled', 'tax_label' => 'easy_invoice_tax_label', 'tax_number' => 'easy_invoice_tax_number', // PDF settings 'pdf_paper_size' => 'easy_invoice_pdf_paper_size', 'pdf_font_family' => 'easy_invoice_pdf_font_family', 'pdf_font_size' => 'easy_invoice_pdf_font_size', 'pdf_margin_top' => 'easy_invoice_pdf_margin_top', 'pdf_margin_bottom' => 'easy_invoice_pdf_margin_bottom', 'pdf_margin_left' => 'easy_invoice_pdf_margin_left', 'pdf_margin_right' => 'easy_invoice_pdf_margin_right', // Template settings 'invoice_template' => 'easy_invoice_invoice_template', 'quote_template' => 'easy_invoice_quote_template', 'template_color' => 'easy_invoice_template_color', 'template_font' => 'easy_invoice_template_font', 'template_font_size' => 'easy_invoice_template_font_size', // Watermark settings 'invoice_watermark_type' => 'easy_invoice_pro_invoice_watermark_type', 'invoice_watermark_text' => 'easy_invoice_pro_invoice_text_watermark', 'invoice_watermark_image' => 'easy_invoice_pro_invoice_image_watermark', 'invoice_watermark_opacity' => 'easy_invoice_pro_invoice_watermark_opacity', 'invoice_watermark_color' => 'easy_invoice_pro_invoice_text_watermark_color', 'invoice_watermark_size' => 'easy_invoice_pro_invoice_image_watermark_size', 'quote_watermark_type' => 'easy_invoice_pro_quote_watermark_type', 'quote_watermark_text' => 'easy_invoice_pro_quote_text_watermark', 'quote_watermark_image' => 'easy_invoice_pro_quote_image_watermark', 'quote_watermark_opacity' => 'easy_invoice_pro_quote_watermark_opacity', 'quote_watermark_color' => 'easy_invoice_pro_quote_text_watermark_color', 'quote_watermark_size' => 'easy_invoice_pro_quote_image_watermark_size', // Client settings 'client_portal_enabled' => 'easy_invoice_client_portal_enabled', 'client_registration_enabled' => 'easy_invoice_client_registration_enabled', 'client_login_redirect' => 'easy_invoice_client_login_redirect', 'client_registration_redirect' => 'easy_invoice_client_registration_redirect', // Notification settings 'notification_invoice_created' => 'easy_invoice_notification_invoice_created', 'notification_invoice_sent' => 'easy_invoice_notification_invoice_sent', 'notification_invoice_viewed' => 'easy_invoice_notification_invoice_viewed', 'notification_invoice_paid' => 'easy_invoice_notification_invoice_paid', 'notification_quote_created' => 'easy_invoice_notification_quote_created', 'notification_quote_sent' => 'easy_invoice_notification_quote_sent', 'notification_quote_viewed' => 'easy_invoice_notification_quote_viewed', 'notification_quote_accepted' => 'easy_invoice_notification_quote_accepted', 'notification_quote_declined' => 'easy_invoice_notification_quote_declined' ], // Invoice settings 'easy_invoice_invoice_settings' => [ 'next_number' => 'easy_invoice_next_invoice_number', 'prefix' => 'easy_invoice_invoice_prefix', 'starting_number' => 'easy_invoice_invoice_starting_number', 'due_days' => 'easy_invoice_invoice_due_days', 'footer_text' => 'easy_invoice_invoice_footer_text', 'terms_conditions' => 'easy_invoice_invoice_terms_conditions', 'show_adjust_field' => 'easy_invoice_invoice_show_adjust_field', 'enable_payment_button' => 'easy_invoice_enable_payment_button', 'payment_button_link' => 'easy_invoice_payment_button_link' ], // Quote settings 'easy_invoice_quote_settings' => [ 'next_number' => 'easy_invoice_next_quote_number', 'prefix' => 'easy_invoice_quote_prefix', 'starting_number' => 'easy_invoice_quote_starting_number', 'footer_text' => 'easy_invoice_quote_footer_text', 'terms_conditions' => 'easy_invoice_quote_terms_conditions', 'show_adjust_field' => 'easy_invoice_quote_show_adjust_field', 'accept_text' => 'easy_invoice_quote_accept_text', 'accepted_message' => 'easy_invoice_quote_accepted_message', 'accept_button' => 'easy_invoice_quote_accept_button', 'accept_action' => 'easy_invoice_quote_accept_action', 'decline_reason_required' => 'easy_invoice_quote_decline_reason_required', 'declined_message' => 'easy_invoice_quote_declined_message' ], // Payment settings 'easy_invoice_payment_settings' => [ 'paypal_email' => 'easy_invoice_paypal_email', 'paypal_label' => 'easy_invoice_paypal_label', 'paypal_mode' => 'easy_invoice_paypal_mode', 'payment_methods' => 'easy_invoice_payment_methods', 'thankyou_page' => 'easy_invoice_thankyou_page', 'payment_terms' => 'easy_invoice_payment_terms', 'payment_reminder_days' => 'easy_invoice_payment_reminder_days' ], // Email settings 'easy_invoice_email_settings' => [ 'from_name' => 'easy_invoice_email_from_name', 'from_address' => 'easy_invoice_email_from_address', 'reply_to' => 'easy_invoice_email_reply_to', 'reply_to_name' => 'easy_invoice_email_reply_to_name', 'bcc_admin' => 'easy_invoice_bcc_admin', 'admin_email' => 'easy_invoice_admin_email', 'enable_styling' => 'easy_invoice_enable_email_styling', 'logo' => 'easy_invoice_email_logo', 'footer_text' => 'easy_invoice_email_footer_text', 'invoice_email_enabled' => 'easy_invoice_invoice_email_enabled', 'invoice_email_subject' => 'easy_invoice_invoice_email_subject', 'invoice_email_body' => 'easy_invoice_invoice_email_body', 'quote_email_enabled' => 'easy_invoice_quote_email_enabled', 'quote_email_subject' => 'easy_invoice_quote_email_subject', 'quote_email_body' => 'easy_invoice_quote_email_body', 'payment_email_enabled' => 'easy_invoice_payment_email_enabled', 'payment_email_subject' => 'easy_invoice_payment_email_subject', 'payment_email_body' => 'easy_invoice_payment_email_body', 'reminder_subject' => 'easy_invoice_reminder_subject', 'reminder_body' => 'easy_invoice_reminder_body' ], // Pro settings 'easy_invoice_pro_settings' => [ 'license_key' => 'easy_invoice_pro_license_key', 'license_status' => 'easy_invoice_pro_license_status', 'license_expiry' => 'easy_invoice_pro_license_expiry', 'license_type' => 'easy_invoice_pro_license_type' ], // System settings 'easy_invoice_system_settings' => [ 'version' => 'easy_invoice_version', 'first_install_time' => 'easy_invoice_first_install_time', 'post_types_registered' => 'easy_invoice_post_types_registered', 'last_rewrite_flush' => 'easy_invoice_last_rewrite_flush', 'flush_rewrite_rules' => 'easy_invoice_flush_rewrite_rules' ] ]; /** * New options mapping. * Maps new option names to their actual database names. * * @since 2.0.0 * @var array */ private $new_options = [ // Core settings 'easy_invoice_version' => 'easy_invoice_version', 'easy_invoice_currency_code' => 'easy_invoice_currency_code', 'easy_invoice_tax_rate' => 'easy_invoice_tax_rate', 'easy_invoice_tax_name' => 'easy_invoice_tax_name', 'easy_invoice_tax_entry_method' => 'easy_invoice_tax_entry_method', 'easy_invoice_tax_enabled' => 'easy_invoice_tax_enabled', // Business settings 'easy_invoice_company_name' => 'easy_invoice_company_name', 'easy_invoice_company_address' => 'easy_invoice_company_address', 'easy_invoice_company_logo' => 'easy_invoice_company_logo', 'easy_invoice_company_additional_info' => 'easy_invoice_company_additional_info', 'easy_invoice_company_email' => 'easy_invoice_company_email', 'easy_invoice_company_phone' => 'easy_invoice_company_phone', 'easy_invoice_company_website' => 'easy_invoice_company_website', // Invoice settings 'easy_invoice_next_invoice_number' => 'easy_invoice_next_invoice_number', 'easy_invoice_invoice_prefix' => 'easy_invoice_invoice_prefix', 'easy_invoice_invoice_permalink' => 'easy_invoice_invoice_permalink', 'easy_invoice_invoice_show_adjust_field' => 'easy_invoice_invoice_show_adjust_field', 'easy_invoice_invoice_footer_text' => 'easy_invoice_invoice_footer_text', 'easy_invoice_invoice_terms_conditions' => 'easy_invoice_invoice_terms_conditions', 'easy_invoice_enable_payment_button' => 'easy_invoice_enable_payment_button', 'easy_invoice_payment_button_link' => 'easy_invoice_payment_button_link', 'easy_invoice_predefined_items' => 'easy_invoice_predefined_items', 'easy_invoice_invoice_starting_number' => 'easy_invoice_invoice_starting_number', 'easy_invoice_invoice_due_days' => 'easy_invoice_invoice_due_days', // Quote settings 'easy_invoice_next_quote_number' => 'easy_invoice_next_quote_number', 'easy_invoice_quote_prefix' => 'easy_invoice_quote_prefix', 'easy_invoice_quote_permalink' => 'easy_invoice_quote_permalink', 'easy_invoice_quote_show_adjust_field' => 'easy_invoice_quote_show_adjust_field', 'easy_invoice_quote_footer_text' => 'easy_invoice_quote_footer_text', 'easy_invoice_quote_terms_conditions' => 'easy_invoice_quote_terms_conditions', 'easy_invoice_quote_accept_text' => 'easy_invoice_quote_accept_text', 'easy_invoice_quote_accepted_message' => 'easy_invoice_quote_accepted_message', 'easy_invoice_quote_accept_button' => 'easy_invoice_quote_accept_button', 'easy_invoice_quote_accept_action' => 'easy_invoice_quote_accept_action', 'easy_invoice_quote_decline_reason_required' => 'easy_invoice_quote_decline_reason_required', 'easy_invoice_quote_declined_message' => 'easy_invoice_quote_declined_message', 'easy_invoice_quote_starting_number' => 'easy_invoice_quote_starting_number', // Currency settings 'easy_invoice_currency_symbol_type' => 'easy_invoice_currency_symbol_type', 'easy_invoice_decimal_precision' => 'easy_invoice_decimal_precision', 'easy_invoice_decimal_separator' => 'easy_invoice_decimal_separator', 'easy_invoice_thousands_separator' => 'easy_invoice_thousands_separator', 'easy_invoice_currency_position' => 'easy_invoice_currency_position', 'easy_invoice_currency_symbol' => 'easy_invoice_currency_symbol', // Payment settings 'easy_invoice_paypal_email' => 'easy_invoice_paypal_email', 'easy_invoice_paypal_label' => 'easy_invoice_paypal_label', 'easy_invoice_paypal_mode' => 'easy_invoice_paypal_mode', 'easy_invoice_payment_methods' => 'easy_invoice_payment_methods', 'easy_invoice_thankyou_page' => 'easy_invoice_thankyou_page', 'easy_invoice_payment_gateway_order' => 'easy_invoice_payment_gateway_order', // Email settings 'easy_invoice_email_from_address' => 'easy_invoice_email_from_address', 'easy_invoice_email_from_name' => 'easy_invoice_email_from_name', 'easy_invoice_email_reply_to' => 'easy_invoice_email_reply_to', 'easy_invoice_email_reply_to_name' => 'easy_invoice_email_reply_to_name', 'easy_invoice_enable_email_styling' => 'easy_invoice_enable_email_styling', 'easy_invoice_email_logo' => 'easy_invoice_email_logo', 'easy_invoice_email_footer_text' => 'easy_invoice_email_footer_text', 'easy_invoice_bcc_admin' => 'easy_invoice_bcc_admin', 'easy_invoice_admin_email' => 'easy_invoice_admin_email', 'easy_invoice_invoice_email_enabled' => 'easy_invoice_invoice_email_enabled', 'easy_invoice_invoice_email_subject' => 'easy_invoice_invoice_email_subject', 'easy_invoice_invoice_email_body' => 'easy_invoice_invoice_email_body', 'easy_invoice_reminder_subject' => 'easy_invoice_reminder_subject', 'easy_invoice_reminder_body' => 'easy_invoice_reminder_body', 'easy_invoice_payment_email_enabled' => 'easy_invoice_payment_email_enabled', 'easy_invoice_payment_email_subject' => 'easy_invoice_payment_email_subject', 'easy_invoice_payment_email_body' => 'easy_invoice_payment_email_body', 'easy_invoice_quote_email_enabled' => 'easy_invoice_quote_email_enabled', 'easy_invoice_quote_email_subject' => 'easy_invoice_quote_email_subject', 'easy_invoice_quote_email_body' => 'easy_invoice_quote_email_body', 'easy_invoice_quote_accepted_subject' => 'easy_invoice_quote_accepted_subject', 'easy_invoice_quote_accepted_body' => 'easy_invoice_quote_accepted_body', 'easy_invoice_quote_declined_subject' => 'easy_invoice_quote_declined_subject', 'easy_invoice_quote_declined_body' => 'easy_invoice_quote_declined_body', // System settings 'easy_invoice_flush_rewrite_rules' => 'easy_invoice_flush_rewrite_rules', 'easy_invoice_first_install_time' => 'easy_invoice_first_install_time', 'easy_invoice_post_types_registered' => 'easy_invoice_post_types_registered', 'easy_invoice_last_rewrite_flush' => 'easy_invoice_last_rewrite_flush', // Additional settings 'easy_invoice_payment_terms' => 'easy_invoice_payment_terms', 'easy_invoice_payment_reminder_days' => 'easy_invoice_payment_reminder_days', ]; /** * Check if migration is needed. * * @since 2.0.0 * @return bool */ public function is_needed(): bool { // Check if any old options exist foreach ( $this->old_options as $old_option => $new_option ) { if ( $this->option_exists( $old_option ) ) { $this->log( sprintf( 'Found option %s that needs migration', $old_option ) ); return true; } } return false; } /** * Run the migration. * * @since 2.0.0 * @return array */ public function migrate(): array { $this->log( 'Starting options migration' ); try { $migrated_count = 0; $errors = []; foreach ( $this->old_options as $old_option => $new_option ) { $result = $this->migrate_option( $old_option, $new_option ); if ( $result['success'] ) { $migrated_count++; $this->log( sprintf( 'Successfully migrated option %s to %s', $old_option, $new_option ) ); } else { $errors[] = $result['message']; $this->log( sprintf( 'Failed to migrate option %s: %s', $old_option, $result['message'] ), 'error' ); } } if ( empty( $errors ) ) { return $this->success_result( sprintf( 'Successfully migrated %d options', $migrated_count ) ); } else { return $this->error_result( 'Options migration completed with errors: ' . implode( ', ', $errors ) ); } } catch ( \Exception $e ) { $this->log( 'Options migration failed: ' . $e->getMessage(), 'error' ); return $this->error_result( 'Options migration failed: ' . $e->getMessage() ); } } /** * Migrate a specific option. * * @since 2.0.0 * @param string $old_option Old option name. * @param string $new_option New option name. * @return array */ private function migrate_option( string $old_option, string $new_option ): array { if ( ! $this->option_exists( $old_option ) ) { return [ 'success' => true, 'message' => sprintf( 'Option %s does not exist', $old_option ), ]; } try { $option_value = get_option( $old_option ); if ( $option_value === false ) { return [ 'success' => true, 'message' => sprintf( 'Option %s has no value', $old_option ), ]; } // Transform option value if needed $transformed_value = $this->transform_option_value( $old_option, $option_value ); // Update new option $update_result = $this->update_option_safe( $new_option, $transformed_value ); if ( $update_result ) { // Delete old option after successful migration $this->delete_option_safe( $old_option ); return [ 'success' => true, 'message' => sprintf( 'Successfully migrated option %s', $old_option ), ]; } else { return [ 'success' => false, 'message' => sprintf( 'Failed to update new option %s', $new_option ), ]; } } catch ( \Exception $e ) { return [ 'success' => false, 'message' => $e->getMessage(), ]; } } /** * Transform option value for new structure. * * @since 2.0.0 * @param string $option_name Option name. * @param mixed $option_value Option value. * @return mixed */ private function transform_option_value( string $option_name, $option_value ) { // Handle nested settings arrays if (is_array($option_value)) { $transformed = []; // Get the mapping for this settings group $mappings = $this->old_options[$option_name] ?? []; if (!empty($mappings)) { foreach ($option_value as $key => $value) { // Check if we have a mapping for this key if (isset($mappings[$key])) { $new_key = $mappings[$key]; // Transform the value if needed switch ($key) { case 'payment_methods': $transformed[$new_key] = $this->transform_payment_methods($value); break; case 'tax_type': $transformed[$new_key] = $this->transform_tax_type($value); break; case 'currency_position': $transformed[$new_key] = $this->transform_currency_position($value); break; default: $transformed[$new_key] = $value; } } } } return $transformed; } return $option_value; } /** * Transform tax type value. * * @param string $value Old tax type value * @return string New tax type value */ private function transform_tax_type($value) { $map = [ 'inclusive' => 'inclusive', 'exclusive' => 'exclusive', 'none' => 'none' ]; return $map[$value] ?? 'exclusive'; } /** * Transform currency position value. * * @param string $value Old currency position value * @return string New currency position value */ private function transform_currency_position($value) { $map = [ 'left' => 'before', 'right' => 'after', 'left_space' => 'before_space', 'right_space' => 'after_space' ]; return $map[$value] ?? 'before'; } /** * Transform payment methods array. * * @param array $methods Old payment methods array * @return array New payment methods array */ private function transform_payment_methods($methods) { if (!is_array($methods)) { return []; } $transformed = []; foreach ($methods as $method) { if (is_array($method)) { $transformed[] = [ 'id' => $method['id'] ?? '', 'name' => $method['name'] ?? '', 'description' => $method['description'] ?? '', 'enabled' => isset($method['enabled']) ? (bool)$method['enabled'] : true, 'settings' => $method['settings'] ?? [] ]; } } return $transformed; } /** * Transform settings option. * * @since 2.0.0 * @param mixed $settings Settings value. * @return mixed */ private function transform_settings( $settings ) { if ( ! is_array( $settings ) ) { return $settings; } // Add any specific settings transformations here // For example, rename keys, restructure arrays, etc. return $settings; } /** * Transform email settings option. * * @since 2.0.0 * @param mixed $email_settings Email settings value. * @return mixed */ private function transform_email_settings( $email_settings ) { if ( ! is_array( $email_settings ) ) { return $email_settings; } // Add any specific email settings transformations here return $email_settings; } }