fix: include languages.pl content when saving categories to shopPRO

shopPRO's products/update clears ALL language fields (name, description,
short_description, etc.) for any language not included in the payload.
Sending only {"categories":[...]} wiped them out.

saveProductCategoriesJson() now:
1. Looks up the local orderPRO product via findMappedProductId()
2. Loads per-integration translation (with global fallback)
3. Includes languages.pl in the payload alongside categories

Also adds ProductRepository to MarketplaceController constructor.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-27 19:27:39 +01:00
parent a2a7934de6
commit bfff05a61b
2 changed files with 40 additions and 3 deletions

View File

@@ -92,7 +92,8 @@ return static function (Application $app): void {
$auth,
$marketplaceRepository,
$integrationRepository,
$shopProClient
$shopProClient,
$productRepository
);
$authMiddleware = new AuthMiddleware($auth);

View File

@@ -10,6 +10,7 @@ use App\Core\Security\Csrf;
use App\Core\Support\Flash;
use App\Core\View\Template;
use App\Modules\Auth\AuthService;
use App\Modules\Products\ProductRepository;
use App\Modules\Settings\IntegrationRepository;
use App\Modules\Settings\ShopProClient;
@@ -21,7 +22,8 @@ final class MarketplaceController
private readonly AuthService $auth,
private readonly MarketplaceRepository $marketplace,
private readonly IntegrationRepository $integrationRepository,
private readonly ShopProClient $shopProClient
private readonly ShopProClient $shopProClient,
private readonly ProductRepository $productRepository
) {
}
@@ -177,12 +179,46 @@ final class MarketplaceController
? array_values(array_filter(array_map('intval', $body['category_ids']), static fn(int $id): bool => $id > 0))
: [];
$payload = ['categories' => $categoryIds];
// Include language content so shopPRO doesn't clear name/description when saving categories.
// Use per-integration translation if set, otherwise fall back to global product translation.
$localProductId = $this->integrationRepository->findMappedProductId(
'shoppro',
(string) $externalProductId,
$integrationId
);
if ($localProductId !== null && $localProductId > 0) {
$integrationTranslation = null;
foreach ($this->productRepository->findIntegrationTranslations($localProductId) as $row) {
if ((int) ($row['integration_id'] ?? 0) === $integrationId) {
$integrationTranslation = $row;
break;
}
}
$global = $this->productRepository->findById($localProductId, 'pl');
if ($global !== null) {
$name = (string) ($integrationTranslation['name'] ?? $global['name'] ?? '');
$payload['languages'] = [
'pl' => [
'name' => $name !== '' ? $name : ('orderPRO #' . $localProductId),
'short_description' => $integrationTranslation['short_description'] ?? $global['short_description'] ?? null,
'description' => $integrationTranslation['description'] ?? $global['description'] ?? null,
'meta_title' => $global['meta_title'] ?? null,
'meta_description' => $global['meta_description'] ?? null,
'meta_keywords' => $global['meta_keywords'] ?? null,
'seo_link' => $global['seo_link'] ?? null,
],
];
}
}
$result = $this->shopProClient->updateProduct(
(string) ($creds['base_url'] ?? ''),
(string) ($creds['api_key'] ?? ''),
(int) ($creds['timeout_seconds'] ?? 10),
$externalProductId,
['categories' => $categoryIds]
$payload
);
if (!($result['ok'] ?? false)) {