PluginProbe
ووسلام – همگام سازی ووکامرس و باسلام / 1.8.5
ووسلام – همگام سازی ووکامرس و باسلام v1.8.5
1.10.19 1.10.20 1.10.18 1.10.17 1.10.15 1.10.14 1.10.13 1.10.12 1.10.10 1.10.9 1.10.8 1.10.7 1.10.6 1.10.5 1.10.4 1.10.3 1.10.2 1.10.1 1.10.0 1.9.2 1.9.1 1.9.0 1.8.8 1.8.5 1.8.6 All 53 releases
sync-basalam / includes / Migrations / MigratorService.php

MigratorService.php in ووسلام – همگام سازی ووکامرس و باسلام 1.8.5, at includes/Migrations/MigratorService.php

367 lines 11.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace SyncBasalam\Migrations;
4
5 use SyncBasalam\Admin\Settings\SettingsConfig;
6 use SyncBasalam\Services\WebhookService;
7 use SyncBasalam\Utilities\ProductMetaKey;
8
9 defined('ABSPATH') || exit;
10 class MigratorService
11 {
12 private $wpdb;
13
14 public function __construct()
15 {
16 global $wpdb;
17 $this->wpdb = $wpdb;
18 }
19
20 public function migratePayments()
21 {
22 $source = $this->wpdb->prefix . 'bsl_payments';
23 $target = $this->wpdb->prefix . 'sync_basalam_payments';
24
25 if ($this->tableExists($source) && $this->tableExists($target)) {
26 $this->wpdb->query("INSERT INTO $target (payment_id, invoice_id, user_id, city_id, province_id, order_id)
27 SELECT payment_id, invoice_id, user_id, city_id, province_id, order_id FROM $source");
28 }
29 }
30
31 public function migrateOptions()
32 {
33 $source = $this->wpdb->prefix . 'bsl_map_options';
34 $target = $this->wpdb->prefix . 'sync_basalam_map_options';
35
36 if ($this->tableExists($source) && $this->tableExists($target)) {
37 $this->wpdb->query("INSERT INTO $target (woo_name, sync_basalam_name)
38 SELECT woo_name, bslm_name FROM $source");
39 }
40 }
41
42 public function migrateUploadedPhotos()
43 {
44 $source = $this->wpdb->prefix . 'bsl_uploaded_photo';
45 $target = $this->wpdb->prefix . 'sync_basalam_uploaded_photo';
46
47 if ($this->tableExists($source) && $this->tableExists($target)) {
48 $this->wpdb->query("INSERT INTO $target (woo_photo_id, sync_basalam_photo_id, sync_basalam_photo_url)
49 SELECT woo_photo_id, bslm_photo_id, bslm_photo_url FROM $source");
50 }
51 }
52
53 public function migratePostMeta()
54 {
55 $this->wpdb->query(
56 "UPDATE {$this->wpdb->postmeta}
57 SET meta_key = REPLACE(meta_key, 'bslm_', 'sync_basalam_')
58 WHERE meta_key LIKE '%bslm_%'"
59 );
60
61 $this->wpdb->query(
62 "UPDATE {$this->wpdb->postmeta}
63 SET meta_key = REPLACE(meta_key, 'bsl_', 'sync_basalam_')
64 WHERE meta_key LIKE '%bsl_%'"
65 );
66 }
67
68 public function migrateOptionsRows()
69 {
70 $this->wpdb->query(
71 "UPDATE {$this->wpdb->options}
72 SET option_name = REPLACE(option_name, 'bslm_', 'sync_basalam_')
73 WHERE option_name LIKE '%bslm_%'"
74 );
75
76 $this->wpdb->query(
77 "UPDATE {$this->wpdb->options}
78 SET option_name = REPLACE(option_name, 'bsl_', 'sync_basalam_')
79 WHERE option_name LIKE '%bsl_%'"
80 );
81 }
82
83 public function migrateActions()
84 {
85 $source = $this->wpdb->prefix . 'actionscheduler_actions';
86
87 $this->wpdb->query(
88 $this->wpdb->prepare(
89 "UPDATE $source
90 SET hook = REPLACE(hook, 'bslm_', 'sync_basalam_')
91 WHERE hook LIKE %s AND status = %s",
92 '%bslm_%',
93 'pending'
94 )
95 );
96
97 $this->wpdb->query(
98 $this->wpdb->prepare(
99 "UPDATE $source
100 SET hook = REPLACE(hook, 'bsl_', 'sync_basalam_')
101 WHERE hook LIKE %s AND status = %s",
102 '%bsl_%',
103 'pending'
104 )
105 );
106 }
107
108 public function migrateSettings()
109 {
110 $settingsRowName = 'sync_basalam_settings';
111
112 $settingsSerialized = $this->wpdb->get_var(
113 $this->wpdb->prepare(
114 "SELECT option_value FROM {$this->wpdb->options} WHERE option_name = %s",
115 $settingsRowName
116 )
117 );
118
119 if (!$settingsSerialized) return;
120
121 $settings = maybe_unserialize($settingsSerialized);
122
123 if (!is_array($settings)) return;
124
125 $keyMap = [
126 'basalam_client_id' => 'client_id',
127 'basalam_webhook_id' => 'webhook_id',
128 'basalam_token' => 'token',
129 'basalam_refresh_token' => 'refresh_token',
130 'basalam_vendor_id' => 'vendor_id',
131 'basalam_is_vendor' => 'is_vendor',
132 'basalam_increase' => 'increase_price_value',
133 'basalam_round' => 'round_price',
134 'basalam_webhook_token' => 'webhook_header_token',
135 'basalam_auto_confirm_order' => 'auto_confirm_order',
136 'basalam_product_wholesale' => 'all_products_wholesale',
137 ];
138
139 $newSettings = [];
140 foreach ($settings as $key => $value) {
141 $newSettings[$keyMap[$key] ?? $key] = $value;
142 }
143
144 update_option($settingsRowName, $newSettings);
145 }
146
147 public function renameOldTables()
148 {
149 $tables = [
150 $this->wpdb->prefix . 'bsl_payments',
151 $this->wpdb->prefix . 'bsl_map_options',
152 $this->wpdb->prefix . 'bsl_uploaded_photo',
153 ];
154
155 foreach ($tables as $table) {
156 if ($this->tableExists($table)) {
157 $this->wpdb->query("RENAME TABLE $table TO {$table}_old");
158 }
159 }
160 }
161
162 private function tableExists($table)
163 {
164
165 return $this->wpdb->get_var($this->wpdb->prepare("SHOW TABLES LIKE %s", $table)) === $table;
166 }
167
168 private function columnExists($table, $column)
169 {
170
171 $result = $this->wpdb->get_results($this->wpdb->prepare(
172 "SHOW COLUMNS FROM `$table` LIKE %s",
173 $column
174 ));
175
176 return !empty($result);
177 }
178
179 public function addCreatedAtColumnToUploadedPhoto()
180 {
181
182 $table = $this->wpdb->prefix . 'sync_basalam_uploaded_photo';
183
184 if ($this->tableExists($table) && !$this->columnExists($table, 'created_at')) {
185 $this->wpdb->query("ALTER TABLE $table ADD COLUMN created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP");
186 }
187 }
188
189 public function addNewWebhookEvents()
190 {
191 $webhookService = new WebhookService();
192 $webhookService->setupWebhook();
193 }
194
195 public function addFinancialDataColumns()
196 {
197 $table = $this->wpdb->prefix . 'sync_basalam_payments';
198
199 if (!$this->tableExists($table)) {
200 return;
201 }
202
203 $columns = [
204 'fee_amount' => "ALTER TABLE $table ADD COLUMN fee_amount DECIMAL(10,2) DEFAULT 0",
205 'balance_amount' => "ALTER TABLE $table ADD COLUMN balance_amount DECIMAL(10,2) DEFAULT 0",
206 'purchase_count' => "ALTER TABLE $table ADD COLUMN purchase_count INT DEFAULT 0"
207 ];
208
209 foreach ($columns as $columnName => $sql) {
210 if (!$this->columnExists($table, $columnName)) {
211 $this->wpdb->query($sql);
212 }
213 }
214 }
215
216 public function addUniqueInvoiceIdIndex()
217 {
218 $table = $this->wpdb->prefix . 'sync_basalam_payments';
219
220 if (!$this->tableExists($table)) {
221 return;
222 }
223
224 $existingIndex = $this->wpdb->get_var(
225 $this->wpdb->prepare(
226 "SELECT INDEX_NAME FROM INFORMATION_SCHEMA.STATISTICS
227 WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = %s AND INDEX_NAME = %s LIMIT 1",
228 $table,
229 'unique_invoice_id'
230 )
231 );
232
233 if ($existingIndex) {
234 return;
235 }
236
237 $this->removeDuplicateInvoicePayments($table);
238
239 $this->wpdb->hide_errors();
240 $this->wpdb->query("ALTER TABLE {$table} ADD UNIQUE KEY unique_invoice_id (invoice_id)");
241 $this->wpdb->show_errors();
242 }
243
244 private function removeDuplicateInvoicePayments($table)
245 {
246 $duplicates = $this->wpdb->get_results(
247 "SELECT invoice_id, MIN(id) AS keep_id
248 FROM {$table}
249 WHERE invoice_id IS NOT NULL AND invoice_id > 0
250 GROUP BY invoice_id
251 HAVING COUNT(*) > 1"
252 );
253
254 if (empty($duplicates)) {
255 return;
256 }
257
258 foreach ($duplicates as $duplicate) {
259 $invoiceId = (int) $duplicate->invoice_id;
260 $keepId = (int) $duplicate->keep_id;
261
262 $rowsToDelete = $this->wpdb->get_results(
263 $this->wpdb->prepare(
264 "SELECT id, order_id FROM {$table} WHERE invoice_id = %d AND id <> %d",
265 $invoiceId,
266 $keepId
267 )
268 );
269
270 foreach ($rowsToDelete as $row) {
271 $orderId = (int) ($row->order_id ?? 0);
272 if ($orderId > 0 && function_exists('wc_get_order')) {
273 $order = wc_get_order($orderId);
274 if ($order instanceof \WC_Order) {
275 try {
276 $order->delete(true);
277 } catch (\Throwable $e) {
278 \SyncBasalam\Logger\Logger::error(
279 "حذف سفارش تکراری ووکا�
280 رس با شناسه {$orderId} نا�
281 وفق بود: " . $e->getMessage()
282 );
283 }
284 }
285 }
286
287 $this->wpdb->delete($table, ['id' => (int) $row->id], ['%d']);
288 }
289
290 \SyncBasalam\Logger\Logger::debug(
291 "سفارشات تکراری برای invoice_id {$invoiceId} پاک‌سازی شدند، شناسه نگه‌داشته‌شده: {$keepId}"
292 );
293 }
294 }
295
296 public function addRetryAfterColumnToJobManager()
297 {
298 $tableName = $this->wpdb->prefix . 'sync_basalam_job_manager';
299
300 $columnExists = $this->wpdb->get_var(
301 $this->wpdb->prepare("SHOW COLUMNS FROM `{$tableName}` LIKE %s", 'retry_after')
302 );
303
304 if (!$columnExists) {
305 $this->wpdb->query("ALTER TABLE {$tableName} ADD COLUMN retry_after BIGINT(20) NULL DEFAULT NULL");
306 $this->wpdb->query("ALTER TABLE {$tableName} ADD INDEX idx_retry_after (retry_after)");
307 }
308 }
309
310 public function migrateProductMetaKeysToVendorId()
311 {
312 $settings = get_option('sync_basalam_settings', []);
313 if (!is_array($settings)) return;
314
315 $vendorId = $settings[SettingsConfig::VENDOR_ID] ?? null;
316 $vendorId = preg_replace('/[^a-zA-Z0-9_-]/', '', (string) $vendorId);
317
318 if ($vendorId === '') return;
319
320 $postmetaTable = $this->wpdb->postmeta;
321
322 $metaKeyMap = [
323 ProductMetaKey::PRODUCT_ID => ProductMetaKey::basalamProductId($vendorId),
324 ProductMetaKey::PRODUCT_SYNC_STATUS => ProductMetaKey::basalamProductSyncStatus($vendorId),
325 ProductMetaKey::PRODUCT_STATUS => ProductMetaKey::basalamProductStatus($vendorId),
326 ];
327
328 foreach ($metaKeyMap as $oldMetaKey => $newMetaKey) {
329 if ($oldMetaKey === $newMetaKey) continue;
330
331 $this->wpdb->query(
332 $this->wpdb->prepare(
333 "INSERT INTO {$postmetaTable} (post_id, meta_key, meta_value)
334 SELECT old_meta.post_id, %s, old_meta.meta_value
335 FROM {$postmetaTable} old_meta
336 LEFT JOIN {$postmetaTable} new_meta
337 ON new_meta.post_id = old_meta.post_id
338 AND new_meta.meta_key = %s
339 WHERE old_meta.meta_key = %s
340 AND new_meta.meta_id IS NULL",
341 $newMetaKey,
342 $newMetaKey,
343 $oldMetaKey
344 )
345 );
346
347 $this->wpdb->query(
348 $this->wpdb->prepare(
349 "DELETE FROM {$postmetaTable} WHERE meta_key = %s",
350 $oldMetaKey
351 )
352 );
353 }
354 }
355
356 public function clearAuthTokens()
357 {
358 $settings = get_option('sync_basalam_settings', []);
359 if (!is_array($settings)) return;
360
361 $settings[SettingsConfig::TOKEN] = null;
362 $settings[SettingsConfig::REFRESH_TOKEN] = null;
363
364 update_option('sync_basalam_settings', $settings);
365 }
366 }
367