diff --git a/src/Commerce/ShopSearchService.php b/src/Commerce/ShopSearchService.php index 2523381..52ab874 100644 --- a/src/Commerce/ShopSearchService.php +++ b/src/Commerce/ShopSearchService.php @@ -393,8 +393,22 @@ final class ShopSearchService ); if ($minimalResults !== null) { + $this->resetLastSearchFailure(); return $minimalResults; } + + $ultraSafeResults = $this->retryWithUltraSafeCriteria( + query: $query, + commerceIntent: $commerceIntent, + originalPrompt: $originalPrompt, + usesHistoryContext: $usesHistoryContext, + previousException: $e + ); + + if ($ultraSafeResults !== null) { + $this->resetLastSearchFailure(); + return $ultraSafeResults; + } } $this->recordFailedSearch($e); @@ -455,7 +469,6 @@ final class ShopSearchService TransportExceptionInterface | \RuntimeException $safeException ) { - $this->recordFailedSearch($safeException); $this->logger->warning('Shop search safe criteria retry failed', [ 'commerceIntent' => $commerceIntent, 'originalPrompt' => $originalPrompt, @@ -510,7 +523,6 @@ final class ShopSearchService TransportExceptionInterface | \RuntimeException $minimalException ) { - $this->recordFailedSearch($minimalException); $this->logger->warning('Shop search minimal UTF-8-safe criteria retry failed', [ 'commerceIntent' => $commerceIntent, 'originalPrompt' => $originalPrompt, @@ -525,6 +537,59 @@ final class ShopSearchService } } + /** + * @return ShopProductResult[]|null + */ + private function retryWithUltraSafeCriteria( + CommerceSearchQuery $query, + string $commerceIntent, + string $originalPrompt, + bool $usesHistoryContext, + StoreApiException $previousException + ): ?array { + $this->logger->warning('Shop search retrying with ultra-safe UTF-8 criteria', [ + 'commerceIntent' => $commerceIntent, + 'originalPrompt' => $originalPrompt, + 'normalizedPrompt' => $query->normalizedPrompt, + 'searchText' => $query->searchText, + 'usesHistoryContext' => $usesHistoryContext, + 'previousStatusCode' => $previousException->getStatusCode(), + 'previousUtf8Failure' => $previousException->isUtf8Failure(), + 'previousExceptionMessage' => $previousException->getMessage(), + ]); + + try { + $ultraSafeCriteria = $this->criteriaBuilder->buildUltraSafe($query, $this->maxResults); + $response = $this->storeApiClient->searchProducts($ultraSafeCriteria); + + return $this->mapAndLogSearchResponse( + response: $response, + query: $query, + commerceIntent: $commerceIntent, + originalPrompt: $originalPrompt, + usesHistoryContext: $usesHistoryContext, + usedSafeCriteria: true + ); + } catch ( + ClientExceptionInterface | + RedirectionExceptionInterface | + ServerExceptionInterface | + TransportExceptionInterface | + \RuntimeException $ultraSafeException + ) { + $this->logger->warning('Shop search ultra-safe UTF-8 criteria retry failed', [ + 'commerceIntent' => $commerceIntent, + 'originalPrompt' => $originalPrompt, + 'normalizedPrompt' => $query->normalizedPrompt, + 'searchText' => $query->searchText, + 'usesHistoryContext' => $usesHistoryContext, + 'exceptionClass' => $ultraSafeException::class, + 'exceptionMessage' => $ultraSafeException->getMessage(), + ]); + + return null; + } + } /** * @param array $response * @return ShopProductResult[] @@ -559,6 +624,32 @@ final class ShopSearchService return $rankedProducts; } + /** + * @param array $row + */ + private function extractProductName(array $row): string + { + $translatedName = trim((string) ($row['translated']['name'] ?? '')); + + if ($translatedName !== '') { + return $translatedName; + } + + $name = trim((string) ($row['name'] ?? '')); + + if ($name !== '') { + return $name; + } + + $productNumber = trim((string) ($row['productNumber'] ?? '')); + + if ($productNumber !== '') { + return 'Produkt ' . $productNumber; + } + + return ''; + } + private function logShopSearchFailure( CommerceSearchQuery $query, string $commerceIntent, @@ -959,7 +1050,7 @@ final class ShopSearchService $results[] = new ShopProductResult( id: (string) ($row['id'] ?? ''), - name: trim((string) ($row['translated']['name'] ?? '')), + name: $this->extractProductName($row), productNumber: isset($row['productNumber']) ? (string) $row['productNumber'] : null, manufacturer: $this->extractManufacturer($row), price: $this->extractPrice($row), diff --git a/src/Shopware/ShopwareCriteriaBuilder.php b/src/Shopware/ShopwareCriteriaBuilder.php index 614754c..7645a04 100644 --- a/src/Shopware/ShopwareCriteriaBuilder.php +++ b/src/Shopware/ShopwareCriteriaBuilder.php @@ -11,7 +11,7 @@ final class ShopwareCriteriaBuilder public function build( CommerceSearchQuery $query, ?int $limit = 25, - ?bool $grouping = true + ?bool $grouping = false ): array { return $this->buildCriteria( @@ -29,7 +29,7 @@ final class ShopwareCriteriaBuilder public function buildSafe( CommerceSearchQuery $query, ?int $limit = 25, - ?bool $grouping = true + ?bool $grouping = false ): array { return $this->buildCriteria( @@ -51,7 +51,7 @@ final class ShopwareCriteriaBuilder public function buildMinimal( CommerceSearchQuery $query, ?int $limit = 25, - ?bool $grouping = true + ?bool $grouping = false ): array { return $this->buildCriteria(