Skip to content

Commit ee11ada

Browse files
IBX-9147: Symbol attribute type described in Developer Documentation - v4.6 (#2525)
* Symbol attribute type described * Fixes after review * PHP CS Fixes * Resolved conflicts in product search criteria * Added composer dependency * fixes * review fixes * PHP & JS CS Fixes * symbol_attribute_type.md moved to Attributes folder * fixes; mysql added * fix in the table * fix --------- Co-authored-by: julitafalcondusza <[email protected]> Co-authored-by: Marek Nocoń <[email protected]>
1 parent efe8775 commit ee11ada

File tree

10 files changed

+225
-2
lines changed

10 files changed

+225
-2
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php declare(strict_types=1);
2+
3+
use Ibexa\Contracts\ProductCatalog\Values\Product\ProductQuery;
4+
use Ibexa\Contracts\ProductCatalogSymbolAttribute\Search\Criterion\SymbolAttribute;
5+
6+
$query = new ProductQuery();
7+
$query->setFilter(new SymbolAttribute('ean', ['5023920187205']));
8+
/** @var \Ibexa\Contracts\ProductCatalog\ProductServiceInterface $productService */
9+
$results = $productService->findProducts($query);
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\PIM\Symbol\Format\Checksum;
6+
7+
use Ibexa\Contracts\ProductCatalog\Values\AttributeDefinitionInterface;
8+
use Ibexa\Contracts\ProductCatalogSymbolAttribute\Value\ChecksumInterface;
9+
10+
final class LuhnChecksum implements ChecksumInterface
11+
{
12+
public function validate(AttributeDefinitionInterface $attributeDefinition, string $value): bool
13+
{
14+
$digits = $this->getDigits($value);
15+
16+
$count = count($digits);
17+
$total = 0;
18+
for ($i = $count - 2; $i >= 0; $i -= 2) {
19+
$digit = $digits[$i];
20+
if ($i % 2 === 0) {
21+
$digit *= 2;
22+
}
23+
24+
$total += $digit > 9 ? $digit - 9 : $digit;
25+
}
26+
27+
$checksum = $digits[$count - 1];
28+
29+
return $total + $checksum === 0;
30+
}
31+
32+
/**
33+
* Returns an array of digits from the given value (skipping any formatting characters).
34+
*
35+
* @return int[]
36+
*/
37+
private function getDigits(string $value): array
38+
{
39+
$chars = array_filter(
40+
str_split($value),
41+
static fn (string $char): bool => $char !== '-'
42+
);
43+
44+
return array_map('intval', array_values($chars));
45+
}
46+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
CREATE TABLE ibexa_product_specification_attribute_symbol (id INT NOT NULL, value VARCHAR(160) DEFAULT NULL, INDEX ibexa_product_specification_attribute_symbol_value_idx (value), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_520_ci` ENGINE = InnoDB;
2+
ALTER TABLE ibexa_product_specification_attribute_symbol ADD CONSTRAINT ibexa_product_specification_attribute_symbol_fk FOREIGN KEY (id) REFERENCES ibexa_product_specification_attribute (id) ON UPDATE CASCADE ON DELETE CASCADE
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CREATE TABLE ibexa_product_specification_attribute_symbol (id INT NOT NULL, value VARCHAR(160) DEFAULT NULL, PRIMARY KEY(id));
2+
CREATE INDEX ibexa_product_specification_attribute_symbol_value_idx ON ibexa_product_specification_attribute_symbol (value);
3+
ALTER TABLE ibexa_product_specification_attribute_symbol ADD CONSTRAINT ibexa_product_specification_attribute_symbol_fk FOREIGN KEY (id) REFERENCES ibexa_product_specification_attribute (id) ON UPDATE CASCADE ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE;

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@
7070
"ibexa/twig-components": "~4.6.x-dev",
7171
"ibexa/tree-builder": "~4.6.x-dev",
7272
"ibexa/discounts": "~4.6.x-dev",
73-
"ibexa/discounts-codes": "~4.6.x-dev"
73+
"ibexa/discounts-codes": "~4.6.x-dev",
74+
"ibexa/product-catalog-symbol-attribute": "~4.6.x-dev"
7475
},
7576
"scripts": {
7677
"fix-cs": "php-cs-fixer fix --config=.php-cs-fixer.php -v --show-progress=dots",

docs/ibexa_products/editions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,4 @@ The features brought by LTS Updates become standard parts of the next LTS releas
6565
| [AI Actions](ai_actions_guide.md) | &#10004; | &#10004; | &#10004; |
6666
| [Date and time attribute type](date_and_time.md) | &#10004; | &#10004; | &#10004; |
6767
| [Discounts](discounts.md) | | | &#10004; |
68+
| [Symbol attribute type](symbol_attribute_type.md) | &#10004; | &#10004; | &#10004; |
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
---
2+
description: Create a symbol attribute type that enables for the efficient representation of string-based values while enforcing their format in product specifications.
3+
edition: lts-update
4+
---
5+
6+
# Symbol attribute type
7+
8+
The Symbol attribute type LTS update enables the efficient representation of string-based data and enforces their format in product specifications.
9+
10+
This feature allows you to store standard product identifiers (such as EAN or ISBN) in the [Product Information Management](pim_guide.md) system.
11+
12+
## Installation
13+
14+
### Download the bundle
15+
16+
To get the most recent stable version of this bundle, open a command terminal, navigate to your project directory, and run the following command:
17+
18+
``` bash
19+
composer require ibexa/product-catalog-symbol-attribute
20+
```
21+
22+
### Enable the bundle
23+
24+
Symfony Flex enables and configures the `IbexaProductCatalogSymbolAttributeBundle` automatically.
25+
If you don't use it, you can manually enable this bundle by adding the line below to the Kernel of your project:
26+
27+
``` php
28+
// config/bundles.php
29+
30+
return [
31+
// ...
32+
Ibexa\Bundle\ProductCatalogSymbolAttribute\IbexaProductCatalogSymbolAttributeBundle::class => ['all' => true],
33+
// ...
34+
];
35+
```
36+
37+
### Update database schema
38+
39+
To store symbol attribute values, the `IbexaProductCatalogSymbolAttributeBundle` needs an extra table.
40+
The following SQL query can be used to build the required database structure:
41+
42+
=== "MySQL"
43+
44+
``` sql
45+
[[= include_file('code_samples/symbol_attribute/config/mysql/symbol_attribute.sql', glue=' ') =]]
46+
```
47+
48+
=== "PostgreSQL"
49+
50+
``` sql
51+
[[= include_file('code_samples/symbol_attribute/config/postgresql/symbol_attribute.sql', glue=' ') =]]
52+
```
53+
54+
### Create symbol attribute definition (optional)
55+
56+
Now, you're able to define symbol attributes at this point.
57+
58+
To create symbol attribute definition, in the back office, go to **Product catalog** -> **Attributes**, and click **Create**.
59+
Then, choose **Symbol** attribute type.
60+
61+
## Build-in symbol attribute formats
62+
63+
The built-in symbol attribute formats in `ibexa/product-catalog-symbol-attribute` are listed below:
64+
65+
| Name | Description | Example |
66+
|-----------------|-----------------|-----------------|
67+
| Generic | Accepts any string value | #FR1.2 |
68+
| Generic (alphabetic characters only) | Accepts any string value that contais only letters | ABCD |
69+
| Generic (digits only) | Accepts any string value that contais only digits | 123456 |
70+
| Generic (alphanumeric characters only) | Accepts any string value that contains only letters or digits | 2N6405G |
71+
| Generic (hexadecimal digits only) | Accepts any string value that contains only hexadecimal digits (digits or A-F characters) | DEADBEEF |
72+
| EAN-8 | European Article Number (8 characters) | 96385074 |
73+
| EAN-13 | European Article Number (13 characters) | 5023920187205 |
74+
| EAN-14 | European Article Number (14 characters) | 12345678901231 |
75+
| ISBN-10 | International Standard Book Number (10 characters) | 0-19-852663-6 |
76+
| ISBN-13 | International Standard Book Number (13 characters) | 978-1-86197-876-9 |
77+
78+
!!! caution
79+
80+
Maximum length of the symbol value is 160 characters.
81+
82+
## Create custom symbol attribute format
83+
84+
Under the `ibexa_product_catalog_symbol_attribute.formats` key, you can use configuration to create your own symbol format.
85+
86+
See the example below:
87+
88+
``` yaml
89+
ibexa_product_catalog_symbol_attribute:
90+
formats:
91+
manufacturer_part_number:
92+
name: 'Manufacturer Part Number'
93+
pattern: '/^[A-Z]{3}-\d{5}$/'
94+
examples:
95+
- 'RPI-14645'
96+
- 'MSS-24827'
97+
- 'SEE-15444'
98+
```
99+
100+
This following example specifies the format for a "Manufacturer Part Number", defined with the `manufacturer_part_number` identifier.
101+
102+
The pattern is specified using a regular expression.
103+
According to the pattern option, the attribute value:
104+
105+
- must be a string
106+
- begins with three capital letters (A-Z), followed by a hyphen ("-")
107+
- ends with five digits (0-9), with no other characters before or after
108+
109+
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.
110+
111+
To validate checksum of symbol:
112+
113+
1\. Create a class implementing the `\Ibexa\Contracts\ProductCatalogSymbolAttribute\Value\ChecksumInterface` interface.
114+
115+
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.
116+
117+
See below the example implementation of checksum validation using Luhn formula:
118+
119+
``` php
120+
[[= include_file('code_samples/pim/Symbol/Format/Checksum/LuhnChecksum.php') =]]
121+
```
122+
123+
Example service definition:
124+
125+
``` yaml
126+
services:
127+
App\PIM\Symbol\Format\Checksum\LuhnChecksum:
128+
tags:
129+
- name: ibexa.product_catalog.attribute.symbol.checksum
130+
format: my_format
131+
```
132+
The format attribute (`my_format`) is the identifier used under the `ibexa_product_catalog_symbol_attribute.formats` key.
133+
134+
## Search for products with given symbol attribute
135+
136+
You can use `SymbolAttribute` Search Criterion to find products by symbol attribute:
137+
138+
For more information, see [SymbolAttribute Criterion](symbolattribute_criterion.md).

docs/search/criteria_reference/product_search_criteria.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,4 @@ Search Criterion let you filter product by specific attributes, for example, col
4242
|[RangeMeasurementAttributeMinimum](rangemeasurementattributeminimum_criterion.md)|Minimum value of product's measurement attribute|
4343
|[SelectionAttribute](selectionattribute_criterion.md)|Value of product's selection attribute|
4444
|[SimpleMeasurementAttribute](simplemeasurementattribute_criterion.md)|Value of product's measurement attribute|
45-
45+
|[SymbolAttribute](symbolattribute_criterion.md)|Value of product's symbol attribute|
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
description: SymbolAttribute Criterion
3+
edition: lts-update
4+
---
5+
6+
# SymbolAttributeCriterion
7+
8+
The `SymbolAttribute` Search Criterion searches for products by [symbol attribute](symbol_attribute_type.md).
9+
10+
## Arguments
11+
12+
- `identifier` - identifier of the format
13+
- `value` - array with the values to search for
14+
15+
## Example
16+
17+
### PHP
18+
19+
``` php
20+
[[= include_file('code_samples/back_office/search/src/Query/SymbolAttributeTypeQuery.php') =]]
21+
```

mkdocs.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ nav:
349349
- Products: pim/products.md
350350
- Attributes:
351351
- Date and Time attribute: pim/attributes/date_and_time.md
352+
- Symbol attribute type: pim/attributes/symbol_attribute_type.md
352353
- Product API: pim/product_api.md
353354
- Catalogs: pim/catalogs.md
354355
- Catalog API: pim/catalog_api.md
@@ -592,6 +593,7 @@ nav:
592593
- RangeMeasurementAttributeMaximum: search/criteria_reference/rangemeasurementattributemaximum_criterion.md
593594
- SimpleMeasurementAttribute: search/criteria_reference/simplemeasurementattribute_criterion.md
594595
- SelectionAttribute: search/criteria_reference/selectionattribute_criterion.md
596+
- SymbolAttribute: search/criteria_reference/symbolattribute_criterion.md
595597
- Order Search Criteria:
596598
- Order Search Criteria: search/criteria_reference/order_search_criteria.md
597599
- CompanyName: search/criteria_reference/order_company_name_criterion.md

0 commit comments

Comments
 (0)