diff --git a/src/Modules/Marketplace/MarketplaceController.php b/src/Modules/Marketplace/MarketplaceController.php index e610e3b..0c29886 100644 --- a/src/Modules/Marketplace/MarketplaceController.php +++ b/src/Modules/Marketplace/MarketplaceController.php @@ -17,7 +17,9 @@ final class MarketplaceController private readonly Template $template, private readonly Translator $translator, private readonly AuthService $auth, - private readonly MarketplaceRepository $marketplace + private readonly MarketplaceRepository $marketplace, + private readonly \App\Modules\Settings\IntegrationRepository $integrationRepository, + private readonly \App\Modules\Settings\ShopProClient $shopProClient ) { } @@ -70,5 +72,122 @@ final class MarketplaceController return Response::html($html); } + + public function categoriesJson(Request $request): Response + { + $integrationId = max(0, (int) $request->input('integration_id', 0)); + if ($integrationId <= 0) { + return Response::json(['ok' => false, 'message' => 'Brak integration_id.'], 400); + } + + $integration = $this->marketplace->findActiveIntegrationById($integrationId); + if ($integration === null) { + return Response::json(['ok' => false, 'message' => 'Integracja nie istnieje lub jest nieaktywna.'], 404); + } + + $creds = $this->integrationRepository->findApiCredentials($integrationId); + if ($creds === null) { + return Response::json(['ok' => false, 'message' => 'Brak danych uwierzytelniających.'], 404); + } + + $result = $this->shopProClient->fetchCategories( + (string) ($creds['base_url'] ?? ''), + (string) ($creds['api_key'] ?? ''), + (int) ($creds['timeout_seconds'] ?? 10) + ); + + if (!($result['ok'] ?? false)) { + return Response::json(['ok' => false, 'message' => $result['message']], 502); + } + + return Response::json(['ok' => true, 'categories' => $result['categories']]); + } + + public function productCategoriesJson(Request $request): Response + { + $integrationId = max(0, (int) $request->input('integration_id', 0)); + $externalProductId = max(0, (int) $request->input('external_product_id', 0)); + + if ($integrationId <= 0 || $externalProductId <= 0) { + return Response::json(['ok' => false, 'message' => 'Brak wymaganych parametrów.'], 400); + } + + $integration = $this->marketplace->findActiveIntegrationById($integrationId); + if ($integration === null) { + return Response::json(['ok' => false, 'message' => 'Integracja nie istnieje.'], 404); + } + + $creds = $this->integrationRepository->findApiCredentials($integrationId); + if ($creds === null) { + return Response::json(['ok' => false, 'message' => 'Brak danych uwierzytelniających.'], 404); + } + + $result = $this->shopProClient->fetchProductById( + (string) ($creds['base_url'] ?? ''), + (string) ($creds['api_key'] ?? ''), + (int) ($creds['timeout_seconds'] ?? 10), + $externalProductId + ); + + if (!($result['ok'] ?? false)) { + return Response::json(['ok' => false, 'message' => $result['message']], 502); + } + + $product = is_array($result['product'] ?? null) ? $result['product'] : []; + $categoryIds = isset($product['categories']) && is_array($product['categories']) + ? array_values(array_filter(array_map('intval', $product['categories']), static fn(int $id): bool => $id > 0)) + : []; + + return Response::json(['ok' => true, 'current_category_ids' => $categoryIds]); + } + + public function saveProductCategoriesJson(Request $request): Response + { + $integrationId = max(0, (int) $request->input('integration_id', 0)); + $externalProductId = max(0, (int) $request->input('external_product_id', 0)); + + if ($integrationId <= 0 || $externalProductId <= 0) { + return Response::json(['ok' => false, 'message' => 'Brak wymaganych parametrów.'], 400); + } + + $rawBody = (string) file_get_contents('php://input'); + $body = json_decode($rawBody, true); + if (!is_array($body)) { + return Response::json(['ok' => false, 'message' => 'Nieprawidłowe ciało żądania JSON.'], 400); + } + + $csrfToken = (string) ($body['_token'] ?? ''); + if (!\App\Core\Security\Csrf::validate($csrfToken)) { + return Response::json(['ok' => false, 'message' => 'Nieprawidłowy token CSRF.'], 403); + } + + $integration = $this->marketplace->findActiveIntegrationById($integrationId); + if ($integration === null) { + return Response::json(['ok' => false, 'message' => 'Integracja nie istnieje lub jest nieaktywna.'], 404); + } + + $creds = $this->integrationRepository->findApiCredentials($integrationId); + if ($creds === null) { + return Response::json(['ok' => false, 'message' => 'Brak danych uwierzytelniających.'], 404); + } + + $categoryIds = isset($body['category_ids']) && is_array($body['category_ids']) + ? array_values(array_filter(array_map('intval', $body['category_ids']), static fn(int $id): bool => $id > 0)) + : []; + + $result = $this->shopProClient->updateProduct( + (string) ($creds['base_url'] ?? ''), + (string) ($creds['api_key'] ?? ''), + (int) ($creds['timeout_seconds'] ?? 10), + $externalProductId, + ['categories' => $categoryIds] + ); + + if (!($result['ok'] ?? false)) { + return Response::json(['ok' => false, 'message' => $result['message']], 502); + } + + return Response::json(['ok' => true]); + } }