PluginProbe
ووسلام – همگام سازی ووکامرس و باسلام / 1.10.6
ووسلام – همگام سازی ووکامرس و باسلام v1.10.6
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 / CreateSingleProductService.php

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

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