diff --git a/code_samples/api/product_catalog/src/Command/ProductVariantCommand.php b/code_samples/api/product_catalog/src/Command/ProductVariantCommand.php index 3b685a7fc4..0a69ab3b9c 100644 --- a/code_samples/api/product_catalog/src/Command/ProductVariantCommand.php +++ b/code_samples/api/product_catalog/src/Command/ProductVariantCommand.php @@ -9,7 +9,9 @@ use Ibexa\Contracts\ProductCatalog\Local\LocalProductServiceInterface; use Ibexa\Contracts\ProductCatalog\Local\Values\Product\ProductVariantCreateStruct; use Ibexa\Contracts\ProductCatalog\ProductServiceInterface; +use Ibexa\Contracts\ProductCatalog\Values\Content\Query\Criterion\ProductCriterionAdapter; use Ibexa\Contracts\ProductCatalog\Values\Product\ProductVariantQuery; +use Ibexa\Contracts\ProductCatalog\Values\Product\Query\Criterion; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; @@ -46,12 +48,24 @@ protected function execute(InputInterface $input, OutputInterface $output): int $productCode = $input->getArgument('productCode'); $product = $this->productService->getProduct($productCode); - // Get variants - $variantQuery = new ProductVariantQuery(0, 5); + // Get variants filtered by variant codes + $codeQuery = new ProductVariantQuery(); + $codeQuery->setVariantCodes(['DESK-red', 'DESK-blue']); + $specificVariants = $this->productService->findProductVariants($product, $codeQuery)->getVariants(); - $variants = $this->productService->findProductVariants($product, $variantQuery)->getVariants(); + // Get variants with specific attributes + $combinedQuery = new ProductVariantQuery(); + $combinedQuery->setAttributesCriterion( + new ProductCriterionAdapter( + new Criterion\LogicalAnd([ + new Criterion\ColorAttribute('color', ['red', 'blue']), + new Criterion\IntegerAttribute('size', 42), + ]) + ) + ); + $filteredVariants = $this->productService->findProductVariants($product, $combinedQuery)->getVariants(); - foreach ($variants as $variant) { + foreach ($specificVariants as $variant) { $output->writeln($variant->getName()); $attributes = $variant->getDiscriminatorAttributes(); foreach ($attributes as $attribute) { @@ -61,12 +75,30 @@ protected function execute(InputInterface $input, OutputInterface $output): int // Create a variant $variantCreateStructs = [ - new ProductVariantCreateStruct(['color' => 'oak', 'frame_color' => 'white'], 'DESK1'), - new ProductVariantCreateStruct(['color' => 'white', 'frame_color' => 'black'], 'DESK2'), + new ProductVariantCreateStruct(['color' => 'oak', 'frame_color' => 'white'], 'DESK-red'), + new ProductVariantCreateStruct(['color' => 'white', 'frame_color' => 'black'], 'DESK-blue'), ]; $this->localProductService->createProductVariants($product, $variantCreateStructs); + // Search variants across all products + $query = new ProductVariantQuery(); + $query->setVariantCodes(['DESK-red', 'DESK-blue']); + $variantList = $this->productService->findVariants($query); + + foreach ($variantList->getVariants() as $variant) { + $output->writeln($variant->getName()); + } + + // Search variants with attribute criterion + $colorQuery = new ProductVariantQuery(); + $colorQuery->setAttributesCriterion( + new ProductCriterionAdapter( + new Criterion\ColorAttribute('color', ['red']) + ) + ); + $redVariants = $this->productService->findVariants($colorQuery); + return self::SUCCESS; } } diff --git a/docs/pim/product_api.md b/docs/pim/product_api.md index dad5a2e096..2848e5d915 100644 --- a/docs/pim/product_api.md +++ b/docs/pim/product_api.md @@ -58,20 +58,54 @@ To delete a product, use `LocalProductServiceInterface::deleteProduct()`: ### Product variants -You can access the variants of a product by using `ProductServiceInterface::findProductVariants()`. +#### Searching for variants of a specific product + +You can access the variants of a product by using the [`ProductServiceInterface::findProductVariants()`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-ProductCatalog-ProductServiceInterface.html#method_findProductVariants) method. The method takes the product object and a [`ProductVariantQuery`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-ProductCatalog-Values-Product-ProductVariantQuery.html) object as parameters. -A `ProductVariantQuery` lets you define the offset and limit of the variant query. -The default offset is 0, and limit is 25. +You can filter variants by: + +- variant codes: + +``` php +[[= include_file('code_samples/api/product_catalog/src/Command/ProductVariantCommand.php', 50, 54) =]] +``` + +- product criteria: + +To use [Product Search Criteria](product_search_criteria.md) with [`ProductVariantQuery`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-ProductCatalog-Values-Product-ProductVariantQuery.html), wrap it with the [`ProductCriterionAdapter`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-ProductCatalog-Values-Content-Query-Criterion-ProductCriterionAdapter.html) class, as in the example below: + +``` php hl_lines="4" +[[= include_file('code_samples/api/product_catalog/src/Command/ProductVariantCommand.php', 55, 66) =]] +``` + +From a variant ([`ProductVariantInterface`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-ProductCatalog-Values-ProductVariantInterface.html)), you can access the attributes that are used to generate the variant by using [`ProductVariantInterface::getDiscriminatorAttributes()`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-ProductCatalog-Values-ProductVariantInterface.html#method_getDiscriminatorAttributes). ``` php -[[= include_file('code_samples/api/product_catalog/src/Command/ProductVariantCommand.php', 49, 52) =]] +[[= include_file('code_samples/api/product_catalog/src/Command/ProductVariantCommand.php', 69, 73) =]] ``` -From a variant ([`ProductVariantInterface`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-ProductCatalog-Values-ProductVariantInterface.html)), you can access the attributes that are used to generate the variant by using `ProductVariantInterface::getDiscriminatorAttributes()`. +#### Searching for variants across all products + +To search for variants across all products, use [`ProductServiceInterface::findVariants()`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-ProductCatalog-ProductServiceInterface.html#method_findVariants). +This method takes a [`ProductVariantQuery`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-ProductCatalog-Values-Product-ProductVariantQuery.html) object and returns variants regardless of their base product. + +Unlike `findProductVariants()`, which requires a specific product object, `findVariants()` allows you to search the entire variant catalog. + +You can filter variants by: + +- variant codes: ``` php -[[= include_file('code_samples/api/product_catalog/src/Command/ProductVariantCommand.php', 53, 60) =]] +[[= include_file('code_samples/api/product_catalog/src/Command/ProductVariantCommand.php', 83, 87) =]] +``` + +- product criteria: + +To use [Product Search Criteria](product_search_criteria.md) with [`ProductVariantQuery`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-ProductCatalog-Values-Product-ProductVariantQuery.html), wrap it with the [`ProductCriterionAdapter`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-ProductCatalog-Values-Content-Query-Criterion-ProductCriterionAdapter.html) class, as in the example below: + +``` php hl_lines="4" +[[= include_file('code_samples/api/product_catalog/src/Command/ProductVariantCommand.php', 92, 100) =]] ``` #### Creating variants @@ -81,7 +115,7 @@ This method takes the product and an array of [`ProductVariantCreateStruct`](/ap `ProductVariantCreateStruct` specifies the attribute values and the code for the new variant. ``` php -[[= include_file('code_samples/api/product_catalog/src/Command/ProductVariantCommand.php', 62, 68) =]] +[[= include_file('code_samples/api/product_catalog/src/Command/ProductVariantCommand.php', 85, 91) =]] ``` ### Product assets diff --git a/docs/release_notes/ibexa_dxp_v5.0.md b/docs/release_notes/ibexa_dxp_v5.0.md index 074b312180..e375875a67 100644 --- a/docs/release_notes/ibexa_dxp_v5.0.md +++ b/docs/release_notes/ibexa_dxp_v5.0.md @@ -10,6 +10,15 @@ month_change: false
+ +#### Improved product variant querying + +Product variant querying now supports filtering by variant codes and product attribute criteria. + +You can now use [`ProductServiceInterface::findVariants()`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-ProductCatalog-ProductServiceInterface.html#method_findVariants) method to search for variants across all products, regardless of their base product. + +For more information, see [Product API - Searching variants](product_api.md#searching-for-variants-across-all-products). + [[% set version = 'v5.0.5' %]] [[= release_note_entry_begin("Ibexa DXP " + version, '2026-01-15', ['Headless', 'Experience', 'Commerce']) =]] diff --git a/docs/search/criteria_reference/product_search_criteria.md b/docs/search/criteria_reference/product_search_criteria.md index 35a3948ac3..1a9c3dd6f2 100644 --- a/docs/search/criteria_reference/product_search_criteria.md +++ b/docs/search/criteria_reference/product_search_criteria.md @@ -5,7 +5,11 @@ page_type: reference # Product Search Criteria reference -Product Search Criteria are only supported by [Product Search (`ProductServiceInterface::findProduct`)](product_api.md#products). +Product Search Criteria are supported by [product and product variant search](product_api.md#products) with the following methods: + +- `ProductServiceInterface::findProducts()` +- `ProductServiceInterface::findProductVariants()` +- `ProductServiceInterface::findVariants()` Search Criterion let you filter product by specific attributes, for example, color, availability, or price.