Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IBX-9147: Symbol attribute type described in Developer Documentation #2525

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions code_samples/pim/Symbol/Format/Checksum/LuhnChecksum.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace App\PIM\Symbol\Format\Checksum;

use Ibexa\Contracts\ProductCatalog\Values\AttributeDefinitionInterface;
use Ibexa\Contracts\ProductCatalogSymbolAttribute\Value\ChecksumInterface;

final class LuhnChecksum implements ChecksumInterface

Check failure on line 10 in code_samples/pim/Symbol/Format/Checksum/LuhnChecksum.php

View workflow job for this annotation

GitHub Actions / Validate code samples (8.3)

Class App\PIM\Symbol\Format\Checksum\LuhnChecksum implements unknown interface Ibexa\Contracts\ProductCatalogSymbolAttribute\Value\ChecksumInterface.
{
public function validate(AttributeDefinitionInterface $attributeDefinition, string $value): bool
{
$digits = $this->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));
}
}
138 changes: 138 additions & 0 deletions docs/pim/symbol_attribute_type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
---

Check warning on line 1 in docs/pim/symbol_attribute_type.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/pim/symbol_attribute_type.md#L1

[Ibexa.ReadingLevel] The grade level is 9.26. Aim for 8th grade or lower by using shorter sentences and words.
Raw output
{"message": "[Ibexa.ReadingLevel] The grade level is 9.26. Aim for 8th grade or lower by using shorter sentences and words.", "location": {"path": "docs/pim/symbol_attribute_type.md", "range": {"start": {"line": 1, "column": 1}}}, "severity": "WARNING"}
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.
julitafalcondusza marked this conversation as resolved.
Show resolved Hide resolved

This feature allows you to store standard product identifiers (such as EAN or ISBN) in the [Product Information Management](pim_guide.md) system.

## Installation

### Download the bundle

To get the most recent stable version of this bundle, open a command terminal, navigate to your project directory, and run the following command:

``` bash
composer require ibexa/product-catalog-symbol-attribute
```

### Enable the bundle

Symfony Flex enables and configures the `IbexaProductCatalogSymbolAttributeBundle` automatically.
If you don't use it, you can manually enable this bundle by adding the line below to the Kernel of your project:

``` php
// config/bundles.php

return [
// ...
Ibexa\Bundle\ProductCatalogSymbolAttribute\IbexaProductCatalogSymbolAttributeBundle::class => ['all' => true],
// ...
];
```

### Update database schema

To store symbol attribute values, the `IbexaProductCatalogSymbolAttributeBundle` needs an extra table.
The following SQL query can be used to build the required database structure:

``` sql
create table ibexa_product_specification_attribute_symbol (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This query is not working on PostgreSQL - we need to have a separate entry for PostgreSQL

id int not null primary key,
value varchar(255) null,
constraint ibexa_product_specification_attribute_symbol_fk
foreign key (id) references ibexa_product_specification_attribute (id)
on update cascade on delete cascade
) collate = utf8mb4_unicode_520_ci;

create index ibexa_product_specification_attribute_symbol_value_idx
on ibexa_product_specification_attribute_symbol (value);
```

### Create symbol attribute definition (optional)

Now, you're able to define symbol attributes at this point.

To create symbol attribute definition, in the back office, go to **Product catalog** -> **Attributes**, and click **Create**.
Then, choose **Symbol** attribute type.

## 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) | 29033706 |
| EAN-13 | European Article Number (13 characters) | 5023920187205 |
| EAN-14 | European Article Number (14 characters) | 50239201872050 |
| 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 numbers (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.

julitafalcondusza marked this conversation as resolved.
Show resolved Hide resolved
## 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).
1 change: 1 addition & 0 deletions docs/search/criteria_reference/product_search_criteria.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Search Criterion let you filter product by specific attributes, for example: col
|[ProductName](productname_criterion.md)|Product's name|
|[RangeMeasurementAttributeMinimum](rangemeasurementattributeminimum_criterion.md)|Minimum value of product's measurement attribute|
|[RangeMeasurementAttributeMaximum](rangemeasurementattributemaximum_criterion.md)|Maximum value of product's measurement attribute|
|[SymbolAttribute](symbolattribute_criterion.md)|Value of product's symbol attribute|
|[SimpleMeasurementAttribute](simplemeasurementattribute_criterion.md)|Value of product's measurement attribute|
|[BasePrice](baseprice_criterion.md)|Product's base price|
|[CustomPrice](customprice_criterion.md)|Product's custom price|
Expand Down
28 changes: 28 additions & 0 deletions docs/search/criteria_reference/symbolattribute_criterion.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---

Check warning on line 1 in docs/search/criteria_reference/symbolattribute_criterion.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/search/criteria_reference/symbolattribute_criterion.md#L1

[Ibexa.ReadingLevel] The grade level is 6.58. Aim for 8th grade or lower by using shorter sentences and words.
Raw output
{"message": "[Ibexa.ReadingLevel] The grade level is 6.58. Aim for 8th grade or lower by using shorter sentences and words.", "location": {"path": "docs/search/criteria_reference/symbolattribute_criterion.md", "range": {"start": {"line": 1, "column": 1}}}, "severity": "WARNING"}
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
<?php

use Ibexa\Contracts\ProductCatalog\Values\Product\ProductQuery;
use Ibexa\Contracts\ProductCatalogSymbolAttribute\Search\Criterion\SymbolAttribute;

$query = new ProductQuery();
$query->setFilter(new SymbolAttribute('ean', ['5023920187205']));
/** @var \Ibexa\Contracts\ProductCatalog\ProductServiceInterface $productService*/
$results = $productService->findProducts($query);
```
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ nav:
- Create product code generator: pim/create_product_code_generator.md
- Create custom catalog filter: pim/create_custom_catalog_filter.md
- Create custom name schema: pim/create_custom_name_schema_strategy.md
- Use symbol attribute type: pim/symbol_attribute_type.md
- Add remote PIM support: pim/add_remote_pim_support.md
- Commerce:
- Commerce: commerce/commerce.md
Expand Down
Loading