PluginProbe
ووسلام – همگام سازی ووکامرس و باسلام / 1.10.20
ووسلام – همگام سازی ووکامرس و باسلام v1.10.20
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
← All changes | includes/Services/Products/CreateSingleProductService.php +75 -14 1.9.21.10.20 View file →
@@ -1,4 +1,4 @@
1 1 <?php
2 2
3 3 namespace SyncBasalam\Services\Products;
4 4
@@ -7,9 +7,10 @@
7 7 use SyncBasalam\Config\Endpoints;
8 8 use SyncBasalam\Services\ApiServiceManager;
9 9 use SyncBasalam\Jobs\Exceptions\RetryableException;
10 10 use SyncBasalam\Jobs\Exceptions\NonRetryableException;
11 -use SyncBasalam\Utilities\ProductMetaKey;
11 +use SyncBasalam\Utilities\ProductMetaKey;
12 +use SyncBasalam\Services\VendorSyncPolicy;
12 13
13 14 defined('ABSPATH') || exit;
14 15
15 16 class CreateSingleProductService
@@ -22,11 +23,16 @@
22 23 $this->apiservice = syncBasalamContainer()->get(ApiServiceManager::class);
23 24 $this->validator = $validator ?: new CreateProductDataValidator();
24 25 }
25 26
26 - public function createProductInBasalam($productData, $productId)
27 - {
28 - $productData = apply_filters('sync_basalam_product_data_before_create', $productData, $productId);
27 + public function createProductInBasalam($productData, $productId)
28 + {
29 + $vendorSyncPolicy = syncBasalamContainer()->get(VendorSyncPolicy::class);
30 + if (!$vendorSyncPolicy->canCreate()) {
31 + throw NonRetryableException::invalidData($vendorSyncPolicy->getRestrictionMessage(false));
32 + }
33 +
34 + $productData = apply_filters('sync_basalam_product_data_before_create', $productData, $productId);
29 35 $this->ValidCreateProductData($productData, $productId);
30 36
31 37 do_action('sync_basalam_before_create_product_api', $productId, $productData);
32 38
@@ -33,17 +39,46 @@
33 39 $vendorId = syncBasalamSettings()->getSettings(SettingsConfig::VENDOR_ID);
34 40
35 41 $url = sprintf(Endpoints::PRODUCT_CREATE, $vendorId);
36 42
37 - try {
38 - $request = $this->apiservice->post($url, $productData);
39 - } catch (RetryableException $e) {
40 - throw $e;
41 - } catch (NonRetryableException $e) {
42 - throw $e;
43 - } catch (\Exception $e) {
44 - throw new \Exception(esc_html($e->getMessage()));
45 - }
43 + $maxDescriptionRetries = 3;
44 + $descriptionRetry = 0;
45 + $skuRetry = false;
46 +
47 + while (true) {
48 + try {
49 + $request = $this->apiservice->post($url, $productData);
50 + } catch (RetryableException $e) {
51 + if ($this->retryWithoutDuplicateSku($productData, $e, $skuRetry)) {
52 + continue;
53 + }
54 +
55 + throw $e;
56 + } catch (NonRetryableException $e) {
57 + if ($this->retryWithoutDuplicateSku($productData, $e, $skuRetry)) {
58 + continue;
59 + }
60 +
61 + if ($descriptionRetry < $maxDescriptionRetries && $this->stripForbiddenDescription($e, $productData, $productId, $descriptionRetry)) {
62 + $descriptionRetry++;
63 + continue;
64 + }
65 + throw $e;
66 + } catch (\Exception $e) {
67 + if ($this->retryWithoutDuplicateSku($productData, $e, $skuRetry)) {
68 + continue;
69 + }
70 +
71 + throw new \Exception(esc_html($e->getMessage()));
72 + }
73 +
74 + // Some API adapters return a non-2xx response instead of throwing it.
75 + if ($this->retryWithoutDuplicateSku($productData, $request, $skuRetry)) {
76 + continue;
77 + }
78 +
79 + break;
80 + }
46 81
47 82 if ($request['status_code'] != 201 && isset($request['status_code'])) {
48 83
49 84 $body = $request['body'] ?? '';
@@ -166,9 +201,35 @@
166 201
167 202 throw new \Exception("فرایند اضافه کردن محصول ناموفق بود");
168 203 }
169 204
170 - private function ValidCreateProductData(array $productData, int $productId): void
205 + private function stripForbiddenDescription(NonRetryableException $e, array &$productData, int $productId, int $attempt): bool
206 + {
207 + if (!isset($productData['description']) || !is_string($productData['description'])) return false;
208 +
209 + $values = DescriptionErrorSanitizer::extractDescriptionValues($e->getResponseData());
210 + if (empty($values)) return false;
211 +
212 + $cleaned = DescriptionErrorSanitizer::sanitize($productData['description'], $values);
213 + if ($cleaned === $productData['description']) return false;
214 +
215 + $productData['description'] = $cleaned;
216 +
217 + return true;
218 + }
219 +
220 + private function retryWithoutDuplicateSku(array &$productData, $error, bool &$retried): bool
221 + {
222 + if ($retried || !ProductSkuRetry::hasSku($productData)) return false;
223 + if (!ProductSkuRetry::isDuplicateSkuError($error)) return false;
224 +
225 + $productData = ProductSkuRetry::withoutSkus($productData);
226 + $retried = true;
227 +
228 + return true;
229 + }
230 +
231 + private function ValidCreateProductData(array $productData, int $productId): void
171 232 {
172 233 $validation = $this->validator->validate($productData, $productId);
173 234
174 235 if (!$validation['valid']) {