diff --git a/code_samples/back_office/search/src/Query/SymbolAttributeTypeQuery.php b/code_samples/back_office/search/src/Query/SymbolAttributeTypeQuery.php new file mode 100644 index 0000000000..2c449d97b8 --- /dev/null +++ b/code_samples/back_office/search/src/Query/SymbolAttributeTypeQuery.php @@ -0,0 +1,9 @@ +setFilter(new SymbolAttribute('ean', ['5023920187205'])); +/** @var \Ibexa\Contracts\ProductCatalog\ProductServiceInterface $productService */ +$results = $productService->findProducts($query); diff --git a/code_samples/pim/Symbol/Format/Checksum/LuhnChecksum.php b/code_samples/pim/Symbol/Format/Checksum/LuhnChecksum.php new file mode 100644 index 0000000000..2860f9aec9 --- /dev/null +++ b/code_samples/pim/Symbol/Format/Checksum/LuhnChecksum.php @@ -0,0 +1,46 @@ +getDigits($value); + + $count = count($digits); + $total = 0; + for ($i = $count - 2; $i >= 0; $i -= 2) { + $digit = $digits[$i]; + if ($i % 2 === 0) { + $digit *= 2; + } + + $total += $digit > 9 ? $digit - 9 : $digit; + } + + $checksum = $digits[$count - 1]; + + return $total + $checksum === 0; + } + + /** + * Returns an array of digits from the given value (skipping any formatting characters). + * + * @return int[] + */ + private function getDigits(string $value): array + { + $chars = array_filter( + str_split($value), + static fn (string $char): bool => $char !== '-' + ); + + return array_map('intval', array_values($chars)); + } +} diff --git a/composer.json b/composer.json index b10ebeca7b..b24e245968 100644 --- a/composer.json +++ b/composer.json @@ -70,7 +70,8 @@ "ibexa/tree-builder": "~5.0.x-dev", "ibexa/discounts": "~5.0.x-dev", "ibexa/discounts-codes": "~5.0.x-dev", - "ibexa/core-search": "~5.0.x-dev" + "ibexa/core-search": "~5.0.x-dev", + "ibexa/product-catalog-symbol-attribute": "~5.0.x-dev" }, "scripts": { "fix-cs": "php-cs-fixer fix --config=.php-cs-fixer.php -v --show-progress=dots", diff --git a/docs/pim/attributes/symbol_attribute_type.md b/docs/pim/attributes/symbol_attribute_type.md new file mode 100644 index 0000000000..edbb5308db --- /dev/null +++ b/docs/pim/attributes/symbol_attribute_type.md @@ -0,0 +1,87 @@ +--- +description: Create a symbol attribute type that enables for the efficient representation of string-based values while enforcing their format in product specifications. +--- + +# Symbol attribute type + +In product specifications, the symbol attribute type enables the efficient representation of string-based data and enforces their format. + +This feature allows you to store standard product identifiers (such as EAN or ISBN) in the [Product Information Management](pim_guide.md) system. + +## Build-in symbol attribute formats + +The built-in symbol attribute formats in `ibexa/product-catalog-symbol-attribute` are listed below: + +| Name | Description | Example | +|-----------------|-----------------|-----------------| +| Generic | Accepts any string value | #FR1.2 | +| Generic (alphabetic characters only) | Accepts any string value that contais only letters | ABCD | +| Generic (digits only) | Accepts any string value that contais only digits | 123456 | +| Generic (alphanumeric characters only) | Accepts any string value that contains only letters or digits | 2N6405G | +| Generic (hexadecimal digits only) | Accepts any string value that contains only hexadecimal digits (digits or A-F characters) | DEADBEEF | +| EAN-8 | European Article Number (8 characters) | 96385074 | +| EAN-13 | European Article Number (13 characters) | 5023920187205 | +| EAN-14 | European Article Number (14 characters) | 12345678901231 | +| ISBN-10 | International Standard Book Number (10 characters) | 0-19-852663-6 | +| ISBN-13 | International Standard Book Number (13 characters) | 978-1-86197-876-9 | + +!!! caution + + Maximum length of the symbol value is 160 characters. + +## Create custom symbol attribute format + +Under the `ibexa_product_catalog_symbol_attribute.formats` key, you can use configuration to create your own symbol format. + +See the example below: + +``` yaml +ibexa_product_catalog_symbol_attribute: + formats: + manufacturer_part_number: + name: 'Manufacturer Part Number' + pattern: '/^[A-Z]{3}-\d{5}$/' + examples: + - 'RPI-14645' + - 'MSS-24827' + - 'SEE-15444' +``` +This following example specifies the format for a "Manufacturer Part Number", defined with the `manufacturer_part_number` identifier. + +The pattern is specified using a regular expression. +According to the pattern option, the attribute value: + +- must be a string +- begins with three capital letters (A-Z), followed by a hyphen ("-") +- ends with five digits (0-9), with no other characters before or after + +Certain formats, such as the International Standard Book Number (ISBN-10) and the European Article Number (EAN-13), contain checksum digits and are self-validating. + +To validate checksum of symbol: + +1\. Create a class implementing the `\Ibexa\Contracts\ProductCatalogSymbolAttribute\Value\ChecksumInterface` interface. + +2\. Register the class as a service using the `ibexa.product_catalog.attribute.symbol.checksum` tag and specify the format identifier using the `format` attribute. + +See below the example implementation of checksum validation using Luhn formula: + +``` php +[[= include_file('code_samples/pim/Symbol/Format/Checksum/LuhnChecksum.php') =]] +``` + +Example service definition: + +``` yaml +services: + App\PIM\Symbol\Format\Checksum\LuhnChecksum: + tags: + - name: ibexa.product_catalog.attribute.symbol.checksum + format: my_format +``` +The format attribute (`my_format`) is the identifier used under the `ibexa_product_catalog_symbol_attribute.formats` key. + +## Search for products with given symbol attribute + +You can use `SymbolAttribute` Search Criterion to find products by symbol attribute: + +For more information, see [SymbolAttribute Criterion](symbolattribute_criterion.md). \ No newline at end of file diff --git a/docs/search/criteria_reference/product_search_criteria.md b/docs/search/criteria_reference/product_search_criteria.md index a31f6cabbc..cb6bef392c 100644 --- a/docs/search/criteria_reference/product_search_criteria.md +++ b/docs/search/criteria_reference/product_search_criteria.md @@ -42,4 +42,4 @@ Search Criterion let you filter product by specific attributes, for example, col |[RangeMeasurementAttributeMinimum](rangemeasurementattributeminimum_criterion.md)|Minimum value of product's measurement attribute| |[SelectionAttribute](selectionattribute_criterion.md)|Value of product's selection attribute| |[SimpleMeasurementAttribute](simplemeasurementattribute_criterion.md)|Value of product's measurement attribute| - +|[SymbolAttribute](symbolattribute_criterion.md)|Value of product's symbol attribute| \ No newline at end of file diff --git a/docs/search/criteria_reference/symbolattribute_criterion.md b/docs/search/criteria_reference/symbolattribute_criterion.md new file mode 100644 index 0000000000..8e99a390ac --- /dev/null +++ b/docs/search/criteria_reference/symbolattribute_criterion.md @@ -0,0 +1,20 @@ +--- +description: SymbolAttribute Criterion +--- + +# SymbolAttributeCriterion + +The `SymbolAttribute` Search Criterion searches for products by [symbol attribute](symbol_attribute_type.md). + +## Arguments + +- `identifier` - identifier of the format +- `value` - array with the values to search for + +## Example + +### PHP + +``` php +[[= include_file('code_samples/back_office/search/src/Query/SymbolAttributeTypeQuery.php') =]] +``` \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index bcf7fb9bd2..fcb9d69b33 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -346,6 +346,7 @@ nav: - Products: pim/products.md - Attributes: - Date and Time attribute: pim/attributes/date_and_time.md + - Symbol attribute type: pim/attributes/symbol_attribute_type.md - Product API: pim/product_api.md - Catalogs: pim/catalogs.md - Catalog API: pim/catalog_api.md @@ -589,6 +590,7 @@ nav: - RangeMeasurementAttributeMaximum: search/criteria_reference/rangemeasurementattributemaximum_criterion.md - SimpleMeasurementAttribute: search/criteria_reference/simplemeasurementattribute_criterion.md - SelectionAttribute: search/criteria_reference/selectionattribute_criterion.md + - SymbolAttribute: search/criteria_reference/symbolattribute_criterion.md - Order Search Criteria: - Order Search Criteria: search/criteria_reference/order_search_criteria.md - CompanyName: search/criteria_reference/order_company_name_criterion.md