| 1 |
<?php |
| 2 |
/** |
| 3 |
* Pro Options Migration for Easy Invoice |
| 4 |
* |
| 5 |
* @package EasyInvoice |
| 6 |
* @subpackage Migration |
| 7 |
* @since 2.0.0 |
| 8 |
*/ |
| 9 |
|
| 10 |
namespace EasyInvoice\Migration\Src; |
| 11 |
|
| 12 |
/** |
| 13 |
* Pro Options Migration Class |
| 14 |
* |
| 15 |
* Migrates pro-specific options from old pro plugin to new pro plugin. |
| 16 |
* |
| 17 |
* @since 2.0.0 |
| 18 |
*/ |
| 19 |
class ProOptionsMigration extends AbstractMigration { |
| 20 |
|
| 21 |
/** |
| 22 |
* Migration description. |
| 23 |
* |
| 24 |
* @since 2.0.0 |
| 25 |
* @var string |
| 26 |
*/ |
| 27 |
protected $description = 'Migrate pro-specific options from old pro plugin'; |
| 28 |
|
| 29 |
/** |
| 30 |
* Option mappings. |
| 31 |
* |
| 32 |
* @since 2.0.0 |
| 33 |
* @var array |
| 34 |
*/ |
| 35 |
private $option_mappings = [ |
| 36 |
// Profile/Restriction settings |
| 37 |
'easy_invoice_restrict_invoice' => 'easy_invoice_pro_restrict_invoice_to_client', |
| 38 |
'easy_invoice_restrict_quote' => 'easy_invoice_pro_restrict_quote_to_client', |
| 39 |
|
| 40 |
// Permalink settings |
| 41 |
'easy_invoice_permalink_for_invoice' => 'easy_invoice_pro_secure_invoice_slug', |
| 42 |
'easy_invoice_permalink_for_quotes' => 'easy_invoice_pro_secure_quote_slug', |
| 43 |
'easy_invoice_protect_invoice' => 'easy_invoice_pro_enable_secure_links', |
| 44 |
'easy_invoice_protect_quote' => 'easy_invoice_pro_enable_secure_links', |
| 45 |
|
| 46 |
// PDF Header settings |
| 47 |
'easy_invoice_pdf_header_background_color' => 'easy_invoice_pro_pdf_header_background_color', |
| 48 |
'easy_invoice_pdf_header_padding_left' => 'easy_invoice_pro_pdf_header_padding_left', |
| 49 |
'easy_invoice_pdf_header_padding_right' => 'easy_invoice_pro_pdf_header_padding_right', |
| 50 |
'easy_invoice_pdf_header_padding_top' => 'easy_invoice_pro_pdf_header_padding_top', |
| 51 |
'easy_invoice_pdf_header_padding_bottom' => 'easy_invoice_pro_pdf_header_padding_bottom', |
| 52 |
|
| 53 |
// PDF Body settings |
| 54 |
'easy_invoice_pdf_content_area_background_color' => 'easy_invoice_pro_pdf_content_background_color', |
| 55 |
'easy_invoice_pdf_content_area_padding_left' => 'easy_invoice_pro_pdf_content_padding_left', |
| 56 |
'easy_invoice_pdf_content_area_padding_right' => 'easy_invoice_pro_pdf_content_padding_right', |
| 57 |
'easy_invoice_pdf_content_area_padding_top' => 'easy_invoice_pro_pdf_content_padding_top', |
| 58 |
'easy_invoice_pdf_content_area_padding_bottom' => 'easy_invoice_pro_pdf_content_padding_bottom', |
| 59 |
|
| 60 |
// PDF Footer settings |
| 61 |
'easy_invoice_pdf_footer_background_color' => 'easy_invoice_pro_pdf_footer_background_color', |
| 62 |
'easy_invoice_pdf_footer_padding_left' => 'easy_invoice_pro_pdf_footer_padding_left', |
| 63 |
'easy_invoice_pdf_footer_padding_right' => 'easy_invoice_pro_pdf_footer_padding_right', |
| 64 |
'easy_invoice_pdf_footer_padding_top' => 'easy_invoice_pro_pdf_footer_padding_top', |
| 65 |
'easy_invoice_pdf_footer_padding_bottom' => 'easy_invoice_pro_pdf_footer_padding_bottom', |
| 66 |
'easy_invoice_pdf_footer_show_page_number' => 'easy_invoice_pro_pdf_show_page_number', |
| 67 |
|
| 68 |
// PDF Watermark settings |
| 69 |
'easy_invoice_pdf_text_watermark' => 'easy_invoice_pro_text_watermark', |
| 70 |
'easy_invoice_pdf_show_invoice_status_watermark' => 'easy_invoice_pro_status_watermark_enable', |
| 71 |
'easy_invoice_pdf_show_quote_status_watermark' => 'easy_invoice_pro_status_watermark_enable', |
| 72 |
'easy_invoice_pdf_text_watermark_alpha' => 'easy_invoice_pro_watermark_opacity', |
| 73 |
'easy_invoice_pdf_text_watermark_angle' => 'easy_invoice_pro_text_watermark_angle', |
| 74 |
'easy_invoice_pdf_image_watermark' => 'easy_invoice_pro_image_watermark', |
| 75 |
'easy_invoice_pdf_image_watermark_alpha' => 'easy_invoice_pro_image_watermark_opacity', |
| 76 |
'easy_invoice_pdf_image_watermark_size_x' => 'easy_invoice_pro_image_watermark_size', |
| 77 |
'easy_invoice_pdf_image_watermark_size_y' => 'easy_invoice_pro_image_watermark_size', |
| 78 |
'easy_invoice_pdf_image_watermark_position_x' => 'easy_invoice_pro_image_watermark_position_x', |
| 79 |
'easy_invoice_pdf_image_watermark_position_y' => 'easy_invoice_pro_image_watermark_position_y', |
| 80 |
|
| 81 |
// PDF General settings |
| 82 |
'easy_invoice_pdf_page_orientation' => 'easy_invoice_pro_orientation', |
| 83 |
'easy_invoice_pdf_download_preview' => 'easy_invoice_pro_pdf_download_preview', |
| 84 |
'easy_invoice_pdf_page_margin_left' => 'easy_invoice_pro_margins_left', |
| 85 |
'easy_invoice_pdf_page_margin_right' => 'easy_invoice_pro_margins_right', |
| 86 |
'easy_invoice_pdf_page_margin_top' => 'easy_invoice_pro_margins_top', |
| 87 |
'easy_invoice_pdf_page_margin_bottom' => 'easy_invoice_pro_margins_bottom', |
| 88 |
'easy_invoice_pdf_page_margin_header' => 'easy_invoice_pro_margins_header', |
| 89 |
'easy_invoice_pdf_page_margin_footer' => 'easy_invoice_pro_margins_footer', |
| 90 |
|
| 91 |
// PDF Protection settings |
| 92 |
'easy_invoice_pdf_page_enable_protection' => 'easy_invoice_pro_pdf_enable_protection', |
| 93 |
'easy_invoice_pdf_page_protected_permissions' => 'easy_invoice_pro_pdf_protected_permissions', |
| 94 |
'easy_invoice_pdf_page_user_password' => 'easy_invoice_pro_pdf_user_password', |
| 95 |
'easy_invoice_pdf_page_owner_password' => 'easy_invoice_pro_pdf_owner_password' |
| 96 |
]; |
| 97 |
|
| 98 |
/** |
| 99 |
* Check if migration is needed. |
| 100 |
* |
| 101 |
* @since 2.0.0 |
| 102 |
* @return bool |
| 103 |
*/ |
| 104 |
public function is_needed(): bool { |
| 105 |
// Check if any old pro options exist |
| 106 |
foreach (array_keys($this->option_mappings) as $old_option) { |
| 107 |
if ($this->option_exists($old_option)) { |
| 108 |
$this->log(sprintf('Found old pro option: %s', $old_option)); |
| 109 |
return true; |
| 110 |
} |
| 111 |
} |
| 112 |
|
| 113 |
return false; |
| 114 |
} |
| 115 |
|
| 116 |
/** |
| 117 |
* Run the migration. |
| 118 |
* |
| 119 |
* @since 2.0.0 |
| 120 |
* @return array |
| 121 |
*/ |
| 122 |
public function migrate(): array { |
| 123 |
$this->log('Starting pro options migration'); |
| 124 |
|
| 125 |
try { |
| 126 |
$migrated_count = 0; |
| 127 |
$errors = []; |
| 128 |
|
| 129 |
foreach ($this->option_mappings as $old_option => $new_option) { |
| 130 |
try { |
| 131 |
$old_value = get_option($old_option); |
| 132 |
|
| 133 |
if ($old_value !== false) { |
| 134 |
// Transform the value |
| 135 |
$new_value = $this->transform_option_value($old_option, $old_value); |
| 136 |
|
| 137 |
// Save to new option |
| 138 |
$result = $this->update_option_safe($new_option, $new_value); |
| 139 |
|
| 140 |
if ($result) { |
| 141 |
$migrated_count++; |
| 142 |
|
| 143 |
// Delete old option after successful migration |
| 144 |
delete_option($old_option); |
| 145 |
} else { |
| 146 |
$errors[] = sprintf('Failed to update option %s', $new_option); |
| 147 |
} |
| 148 |
} |
| 149 |
} catch (\Exception $e) { |
| 150 |
$errors[] = sprintf('Failed to migrate option %s: %s', $old_option, $e->getMessage()); |
| 151 |
} |
| 152 |
} |
| 153 |
|
| 154 |
$this->log(sprintf('Pro options migration completed. Migrated: %d, Errors: %d', $migrated_count, count($errors))); |
| 155 |
|
| 156 |
return [ |
| 157 |
'success' => empty($errors), |
| 158 |
'migrated' => $migrated_count, |
| 159 |
'errors' => $errors |
| 160 |
]; |
| 161 |
|
| 162 |
} catch (\Exception $e) { |
| 163 |
$this->log('Pro options migration failed: ' . $e->getMessage()); |
| 164 |
return [ |
| 165 |
'success' => false, |
| 166 |
'migrated' => 0, |
| 167 |
'errors' => [$e->getMessage()] |
| 168 |
]; |
| 169 |
} |
| 170 |
} |
| 171 |
|
| 172 |
/** |
| 173 |
* Transform option value based on key. |
| 174 |
* |
| 175 |
* @since 2.0.0 |
| 176 |
* @param string $old_option Old option name |
| 177 |
* @param mixed $old_value Old option value |
| 178 |
* @return mixed |
| 179 |
*/ |
| 180 |
private function transform_option_value(string $old_option, $old_value) { |
| 181 |
// Handle boolean values |
| 182 |
if (strpos($old_option, 'protect_') !== false || |
| 183 |
strpos($old_option, 'restrict_') !== false || |
| 184 |
strpos($old_option, 'show_') !== false || |
| 185 |
strpos($old_option, 'enable_') !== false) { |
| 186 |
return ValueTransformer::transform_boolean($old_value); |
| 187 |
} |
| 188 |
|
| 189 |
// Handle orientation |
| 190 |
if ($old_option === 'easy_invoice_pdf_page_orientation') { |
| 191 |
return $old_value === 'vertical' ? 'portrait' : 'landscape'; |
| 192 |
} |
| 193 |
|
| 194 |
// Handle download/preview mode |
| 195 |
if ($old_option === 'easy_invoice_pdf_download_preview') { |
| 196 |
return $old_value === 'download' ? 'download' : 'preview'; |
| 197 |
} |
| 198 |
|
| 199 |
// Handle opacity values |
| 200 |
if (strpos($old_option, '_alpha') !== false) { |
| 201 |
return min(100, max(0, intval($old_value * 100))); |
| 202 |
} |
| 203 |
|
| 204 |
// Handle watermark size |
| 205 |
if (strpos($old_option, '_watermark_size_') !== false) { |
| 206 |
return max(50, min(500, intval($old_value))); |
| 207 |
} |
| 208 |
|
| 209 |
// Handle watermark angle |
| 210 |
if ($old_option === 'easy_invoice_pdf_text_watermark_angle') { |
| 211 |
return max(0, min(360, intval($old_value))); |
| 212 |
} |
| 213 |
|
| 214 |
// Handle padding and margin values |
| 215 |
if (strpos($old_option, '_padding_') !== false || |
| 216 |
strpos($old_option, '_margin_') !== false) { |
| 217 |
return max(0, min(100, intval($old_value))); |
| 218 |
} |
| 219 |
|
| 220 |
// Handle color values |
| 221 |
if (strpos($old_option, '_color') !== false) { |
| 222 |
return preg_match('/^#[a-f0-9]{6}$/i', $old_value) ? $old_value : '#FFFFFF'; |
| 223 |
} |
| 224 |
|
| 225 |
return $old_value; |
| 226 |
} |
| 227 |
} |
| 228 |
|