PluginProbe
ووسلام – همگام سازی ووکامرس و باسلام / 1.10.1
ووسلام – همگام سازی ووکامرس و باسلام v1.10.1
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 / Services / Products / UpdateSingleProductService.php

UpdateSingleProductService.php in ووسلام – همگام سازی ووکامرس و باسلام 1.10.1, at includes/Services/Products/UpdateSingleProductService.php

224 lines 8.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace SyncBasalam\Services\Products;
4
5 use SyncBasalam\Config\Endpoints;
6 use SyncBasalam\Services\ApiServiceManager;
7 use SyncBasalam\Jobs\Exceptions\RetryableException;
8 use SyncBasalam\Jobs\Exceptions\NonRetryableException;
9 use SyncBasalam\Utilities\ProductMetaKey;
10
11 defined('ABSPATH') || exit;
12
13 class UpdateSingleProductService
14 {
15 private $apiservice;
16
17 public function __construct()
18 {
19 $this->apiservice = syncBasalamContainer()->get(ApiServiceManager::class);
20 }
21
22 public function updateProductInBasalam($productData, $productId)
23 {
24 if (!get_post_type($productId) === 'product') throw NonRetryableException::invalidData('نوع post �
25 حصول نیست.');
26
27 $productData = apply_filters('sync_basalam_product_data_before_update', $productData, $productId);
28
29 do_action('sync_basalam_before_update_product_api', $productId, $productData);
30
31 $syncBasalamProductId = get_post_meta($productId, ProductMetaKey::basalamProductId(), true);
32
33 $url = sprintf(Endpoints::PRODUCT_UPDATE, $syncBasalamProductId);
34
35 $maxDescriptionRetries = 3;
36 $descriptionRetry = 0;
37
38 while (true) {
39 try {
40 $request = $this->apiservice->patch($url, $productData);
41 break;
42 } catch (RetryableException $e) {
43 throw $e;
44 } catch (NonRetryableException $e) {
45 if ($descriptionRetry < $maxDescriptionRetries && $this->stripForbiddenDescription($e, $productData, $productId, $descriptionRetry)) {
46 $descriptionRetry++;
47 continue;
48 }
49 throw $e;
50 } catch (\Exception $e) {
51 throw new \Exception(esc_html('خطا در ارتباط با API باسلا�
52 : ' . $e->getMessage()));
53 }
54 }
55
56 $body = $request['body'] ?? '';
57
58 if (is_string($body)) $body = json_decode($body, true);
59
60 if ($request['status_code'] != 200) {
61 if ($request['status_code'] == 403) throw NonRetryableException::unauthorized("این �
62 حصول �
63 تعلق به غرفه فعلی نیست.");
64
65 if (!is_array($body)) $body = [];
66
67 if (isset($body['messages'][0]['message'])) $message = $body['messages'][0]['message'];
68 elseif (isset($body[0]['message'])) $message = $body[0]['message'];
69 else $message = '';
70
71 if (isset($body['messages'][0]['fields'][0])) $field = $body['messages'][0]['fields'][0];
72 elseif (isset($body[0]['fields'][0])) $field = $body[0]['fields'][0];
73 else $field = '';
74
75 $errorMessage = $message ?: 'درخواست با خطا �
76 واجه شد.';
77 if ($field) $errorMessage .= ' (فیلد: ' . $field . ')';
78
79 throw NonRetryableException::permanent(esc_html($errorMessage));
80 }
81
82 if (is_wp_error($request)) throw NonRetryableException::permanent('خطایی در ارتباط با سرور رخ داد.');
83
84 $product = \wc_get_product($productId);
85 if ($product && $product->is_type('variable')) {
86 $variations = $product->get_children();
87 if (isset($body['variants'])) {
88 $wcVariations = [];
89 $attributes = $product->get_attributes();
90
91 foreach ($variations as $variationId) {
92 $variation = \wc_get_product($variationId);
93 $attributeValues = [];
94
95 foreach ($attributes as $attributeName => $attribute) {
96 if ($attribute->get_variation()) {
97 $cleanAttributeName = str_replace('attribute_', '', $attributeName);
98 $value = $variation->get_attribute($cleanAttributeName);
99
100 $value = urldecode($value);
101 $value = trim($value);
102 $value = mb_strtolower($value, 'UTF-8');
103 $value = str_replace(['ي', 'ك'], ['ی', 'ک'], $value);
104 $value = str_replace(['-', '_', '–', '—'], ' ', $value);
105 $value = preg_replace('/\s+/', ' ', $value);
106
107 if (!empty($value)) $attributeValues[] = $value;
108 }
109 }
110
111 if (!empty($attributeValues)) {
112 $key = implode("_", $attributeValues);
113 $wcVariations[$key] = $variationId;
114 }
115 }
116
117 $syncBasalamVariations = [];
118 foreach ($body['variants'] as $variant) {
119 $attributeValues = [];
120 if (!empty($variant['properties'])) {
121 foreach ($variant['properties'] as $property) {
122 $val = $property['value']['title'];
123
124 $val = trim($val);
125 $val = mb_strtolower($val, 'UTF-8');
126 $val = str_replace(['ي', 'ك'], ['ی', 'ک'], $val);
127 $val = str_replace(['-', '_', '–', '—'], ' ', $val);
128 $val = preg_replace('/\s+/', ' ', $val);
129
130 if (!empty($val)) $attributeValues[] = $val;
131 }
132 }
133
134 if (!empty($attributeValues)) {
135 $key = implode("_", $attributeValues);
136 $syncBasalamVariations[$key] = $variant['id'];
137 }
138 }
139
140 foreach ($wcVariations as $key => $wcVarId) {
141 if (isset($syncBasalamVariations[$key])) {
142 update_post_meta($wcVarId, 'sync_basalam_variation_id', $syncBasalamVariations[$key]);
143 }
144 }
145 }
146 }
147
148 update_post_meta($productId, ProductMetaKey::basalamProductSyncStatus(), 'synced');
149
150 $result = [
151 'success' => true,
152 'message' => 'فرایند بروزرسانی �
153 حصول با �
154 وفقیت انجا�
155 شد.',
156 'status_code' => 200,
157 ];
158
159 do_action('sync_basalam_after_update_product_api', $productId, $body, $result);
160
161 return $result;
162 }
163
164 private function stripForbiddenDescription(NonRetryableException $e, array &$productData, int $productId, int $attempt): bool
165 {
166 if (!isset($productData['description']) || !is_string($productData['description'])) return false;
167
168 $values = DescriptionErrorSanitizer::extractDescriptionValues($e->getResponseData());
169 if (empty($values)) return false;
170
171 $cleaned = DescriptionErrorSanitizer::sanitize($productData['description'], $values);
172 if ($cleaned === $productData['description']) return false;
173
174 $productData['description'] = $cleaned;
175
176 return true;
177 }
178
179 public function updateProductStatus($productId, $status)
180 {
181 $syncBasalamProductId = get_post_meta($productId, ProductMetaKey::basalamProductId(), true);
182 $url = sprintf(Endpoints::PRODUCT_UPDATE, $syncBasalamProductId);
183
184 $data = ["status" => $status];
185
186 $data = apply_filters('sync_basalam_product_status_data_before_update', $data, $productId, $status);
187
188 do_action('sync_basalam_before_update_product_status', $productId, $status, $data);
189
190 try {
191 $request = $this->apiservice->patch($url, $data);
192 } catch (RetryableException $e) {
193 throw $e;
194 } catch (NonRetryableException $e) {
195 throw $e;
196 } catch (\Exception $e) {
197 throw NonRetryableException::permanent(esc_html($e->getMessage()));
198 }
199
200 if (!is_wp_error($request)) {
201 update_post_meta($productId, ProductMetaKey::basalamProductSyncStatus(), 'synced');
202 update_post_meta($productId, ProductMetaKey::basalamProductStatus(), $status);
203
204 $result = [
205 'success' => true,
206 'message' => 'وضعیت �
207 حصول با �
208 وفقیت در باسلا�
209 تغییر کرد.',
210 'status_code' => 200,
211 ];
212
213 do_action('sync_basalam_after_update_product_status', $productId, $status, $result);
214
215 return $result;
216 }
217
218 throw NonRetryableException::permanent("تغییر وضعیت �
219 حصول در باسلا�
220 نا�
221 وفق بود.");
222 }
223 }
224