Skip to content

Commit b040e6d

Browse files
committed
Finish documentation about custom ref entity attribute
1 parent 3c526ce commit b040e6d

10 files changed

+1018
-456
lines changed
Loading
Loading
Loading
Loading
Loading
Loading

reference_entities/add_custom_property_to_your_custom_attribute_type.rst

+867
Large diffs are not rendered by default.

reference_entities/create_new_attribute_type.rst

+64-377
Large diffs are not rendered by default.

reference_entities/enrich_a_record_with_new_attribute_type.rst

+86-79
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,21 @@ Enrich Records with a new Reference Entity Attribute type
55

66
Reference Entities feature is only available for the **Enterprise Edition**.
77

8-
This cookbook will present how to enrich Records with a custom Reference Entity Attribute Type we just created in this step (create_new_attribute_type.rst).
9-
10-
11-
Requirements
12-
------------
13-
14-
Please be sure to follow the creation steps before following this guide.
8+
This cookbook will present how to enrich Records with a custom Reference Entity Attribute Type we just created `in a previous step`_.
159

10+
.. _in a previous step: ./create_new_attribute_type.html
1611

1712
Enrich Records With the Attribute
1813
---------------------------------
1914

2015
In the previous tutorial, we've created a custom simple metric attribute.
21-
In this tutorial, we will be able to enrich this attribute directly in the records of the reference entity.
16+
In this tutorial, we will be able to enrich this attribute directly in the records of the reference entity, for example here, the Surface attribute:
17+
18+
.. image:: ../_images/reference_entities/enrich_record_simple_metric_attribute.png
19+
:alt: Enrich a Simple Metric value on a record
2220

23-
1) Domain Layer
24-
^^^^^^^^^^^^^^^
21+
1) Your New Record Value
22+
^^^^^^^^^^^^^^^^^^^^^^^^
2523

2624
To enrich a record, we will create a new Record Value for the brand new Attribute type.
2725
For example, we already have the ``TextData`` class for attribute type "Text".
@@ -31,6 +29,7 @@ Let's create our own ``SimpleMetricData`` that will handle the current data of t
3129
.. code-block:: php
3230
3331
<?php
32+
3433
namespace Acme\CustomBundle\Domain\Model\Record\Value;
3534
3635
use Akeneo\ReferenceEntity\Domain\Model\Record\Value\ValueDataInterface;
@@ -43,8 +42,6 @@ Let's create our own ``SimpleMetricData`` that will handle the current data of t
4342
4443
private function __construct(string $metricValue)
4544
{
46-
Assert::numeric($metricValue, 'The metric value should be a numeric string value');
47-
4845
$this->metricValue = $metricValue;
4946
}
5047
@@ -70,60 +67,64 @@ Let's create our own ``SimpleMetricData`` that will handle the current data of t
7067
}
7168
7269
73-
That's all for the Domain Layer.
74-
75-
2) Application Layer
76-
^^^^^^^^^^^^^^^^^^^^
70+
2) Set a value for the new attribute
71+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7772

78-
Regarding the Application Layer, we will create a command first:
73+
Let's start by creating a command to represent the intent of updating the value:
7974

8075
.. code-block:: php
8176
8277
<?php
8378
84-
namespace Acme\CustomBundle\Application\Attribute\EditAttribute\CommandFactory;
79+
namespace Acme\CustomBundle\Application\Record\EditRecord\CommandFactory;
8580
86-
use Akeneo\ReferenceEntity\Application\Attribute\EditAttribute\CommandFactory\AbstractEditAttributeCommand;
81+
use Acme\CustomBundle\Domain\Model\Attribute\SimpleMetricAttribute;
82+
use Akeneo\ReferenceEntity\Application\Record\EditRecord\CommandFactory\AbstractEditValueCommand;
8783
88-
class EditMetricUnitCommand extends AbstractEditAttributeCommand
84+
class EditSimpleMetricValueCommand extends AbstractEditValueCommand
8985
{
9086
/** @var string */
91-
public $metricUnit;
87+
public $metricValue;
9288
93-
public function __construct(string $identifier, string $metricUnit)
89+
public function __construct(SimpleMetricAttribute $attribute, ?string $channel, ?string $locale, string $metricValue)
9490
{
95-
parent::__construct($identifier);
91+
parent::__construct($attribute, $channel, $locale);
9692
97-
$this->metricUnit = $metricUnit;
93+
$this->metricValue = $metricValue;
9894
}
9995
}
10096
97+
10198
And its factory to build the command:
10299

103100
.. code-block:: php
104101
105-
namespace Acme\CustomBundle\Application\Attribute\EditAttribute\CommandFactory;
102+
<?php
106103
107-
use Akeneo\ReferenceEntity\Application\Attribute\EditAttribute\CommandFactory\AbstractEditAttributeCommand;
108-
use Akeneo\ReferenceEntity\Application\Attribute\EditAttribute\CommandFactory\EditAttributeCommandFactoryInterface;
104+
namespace Acme\CustomBundle\Application\Record\EditRecord\CommandFactory;
105+
106+
use Acme\CustomBundle\Domain\Model\Attribute\SimpleMetricAttribute;
107+
use Akeneo\ReferenceEntity\Application\Record\EditRecord\CommandFactory\AbstractEditValueCommand;
108+
use Akeneo\ReferenceEntity\Application\Record\EditRecord\CommandFactory\EditValueCommandFactoryInterface;
109+
use Akeneo\ReferenceEntity\Domain\Model\Attribute\AbstractAttribute;
109110
110-
class EditMetricUnitCommandFactory implements EditAttributeCommandFactoryInterface
111+
class EditSimpleMetricValueCommandFactory implements EditValueCommandFactoryInterface
111112
{
112-
public function supports(array $normalizedCommand): bool
113+
public function supports(AbstractAttribute $attribute, array $normalizedValue): bool
113114
{
114-
return array_key_exists('unit', $normalizedCommand)
115-
&& array_key_exists('identifier', $normalizedCommand);
115+
return
116+
$attribute instanceof SimpleMetricAttribute &&
117+
'' !== $normalizedValue['data'] &&
118+
is_string($normalizedValue['data']);
116119
}
117120
118-
public function create(array $normalizedCommand): AbstractEditAttributeCommand
121+
public function create(AbstractAttribute $attribute, array $normalizedValue): AbstractEditValueCommand
119122
{
120-
if (!$this->supports($normalizedCommand)) {
121-
throw new \RuntimeException('Impossible to create an edit unit property command.');
122-
}
123-
124-
$command = new EditMetricUnitCommand(
125-
$normalizedCommand['identifier'],
126-
$normalizedCommand['unit']
123+
$command = new EditSimpleMetricValueCommand(
124+
$attribute,
125+
$normalizedValue['channel'],
126+
$normalizedValue['locale'],
127+
$normalizedValue['data']
127128
);
128129
129130
return $command;
@@ -134,63 +135,70 @@ Don't forget to register your factory to be recognized by our registry:
134135

135136
.. code-block:: yaml
136137
137-
acme.application.factory.edit_metric_unit_command_factory:
138-
class: Acme\CustomBundle\Application\Attribute\EditAttribute\CommandFactory\EditMetricUnitCommandFactory
138+
acme.application.factory.record.edit_simple_metric_value_command_factory:
139+
class: Acme\CustomBundle\Application\Record\EditRecord\CommandFactory\EditSimpleMetricValueCommandFactory
139140
tags:
140-
- { name: akeneo_referenceentity.edit_attribute_command_factory, priority: 120 }
141+
- { name: akeneo_referenceentity.edit_record_value_command_factory }
141142
142143
Now that we have our command, we need a specific value updater that will be able to understand this command to update a simple metric value:
143144

144145
.. code-block:: php
145146
146147
<?php
147148
148-
namespace Acme\CustomBundle\Application\Attribute\EditAttribute\AttributeUpdater;
149+
namespace Acme\CustomBundle\Application\Record\EditRecord\ValueUpdater;
149150
150-
use Acme\CustomBundle\Application\Attribute\EditAttribute\CommandFactory\EditMetricUnitCommand;
151-
use Acme\CustomBundle\Domain\Model\Attribute\AttributeMetricUnit;
152-
use Acme\CustomBundle\Domain\Model\Attribute\SimpleMetricAttribute;
153-
use Akeneo\ReferenceEntity\Application\Attribute\EditAttribute\AttributeUpdater\AttributeUpdaterInterface;
154-
use Akeneo\ReferenceEntity\Application\Attribute\EditAttribute\CommandFactory\AbstractEditAttributeCommand;
155-
use Akeneo\ReferenceEntity\Domain\Model\Attribute\AbstractAttribute;
156-
157-
class MetricUnitUpdater implements AttributeUpdaterInterface
151+
use Acme\CustomBundle\Application\Record\EditRecord\CommandFactory\EditSimpleMetricValueCommand;
152+
use Acme\CustomBundle\Domain\Model\Record\Value\SimpleMetricData;
153+
use Akeneo\ReferenceEntity\Application\Record\EditRecord\CommandFactory\AbstractEditValueCommand;
154+
use Akeneo\ReferenceEntity\Application\Record\EditRecord\ValueUpdater\ValueUpdaterInterface;
155+
use Akeneo\ReferenceEntity\Domain\Model\ChannelIdentifier;
156+
use Akeneo\ReferenceEntity\Domain\Model\LocaleIdentifier;
157+
use Akeneo\ReferenceEntity\Domain\Model\Record\Record;
158+
use Akeneo\ReferenceEntity\Domain\Model\Record\Value\ChannelReference;
159+
use Akeneo\ReferenceEntity\Domain\Model\Record\Value\LocaleReference;
160+
use Akeneo\ReferenceEntity\Domain\Model\Record\Value\Value;
161+
162+
class SimpleMetricUpdater implements ValueUpdaterInterface
158163
{
159-
public function supports(AbstractAttribute $attribute, AbstractEditAttributeCommand $command): bool
164+
public function supports(AbstractEditValueCommand $command): bool
160165
{
161-
return $command instanceof EditMetricUnitCommand && $attribute instanceof SimpleMetricAttribute;
166+
return $command instanceof EditSimpleMetricValueCommand;
162167
}
163168
164-
public function __invoke(AbstractAttribute $attribute, AbstractEditAttributeCommand $command): AbstractAttribute
169+
public function __invoke(Record $record, AbstractEditValueCommand $command): void
165170
{
166-
if (!$command instanceof EditMetricUnitCommand) {
167-
throw new \RuntimeException(
168-
sprintf(
169-
'Expected command of type "%s", "%s" given',
170-
EditMetricUnitCommand::class,
171-
get_class($command)
172-
)
173-
);
171+
if (!$this->supports($command)) {
172+
throw new \RuntimeException('Impossible to update the value of the record with the given command.');
174173
}
175174
176-
$attribute->setUnit(AttributeMetricUnit::fromString($command->metricUnit));
175+
$attribute = $command->attribute->getIdentifier();
176+
$channelReference = (null !== $command->channel) ?
177+
ChannelReference::fromChannelIdentifier(ChannelIdentifier::fromCode($command->channel)) :
178+
ChannelReference::noReference();
179+
$localeReference = (null !== $command->locale) ?
180+
LocaleReference::fromLocaleIdentifier(LocaleIdentifier::fromCode($command->locale)) :
181+
LocaleReference::noReference();
182+
183+
$metricValue = SimpleMetricData::createFromNormalize($command->metricValue);
177184
178-
return $attribute;
185+
$value = Value::create($attribute, $channelReference, $localeReference, $metricValue);
186+
$record->setValue($value);
179187
}
180188
}
181189
182190
Of course, we need to register this updater to be recognized by our registry:
183191

184192
.. code-block:: yaml
185193
186-
acme.application.edit_attribute.attribute_updater.metric_unit:
187-
class: Acme\CustomBundle\Application\Attribute\EditAttribute\AttributeUpdater\MetricUnitUpdater
188-
tags:
189-
- { name: akeneo_referenceentity.attribute_updater, priority: 120 }
194+
acme.application.edit_record.record_value_updater.simple_metric_updater:
195+
class: Acme\CustomBundle\Application\Record\EditRecord\ValueUpdater\SimpleMetricUpdater
196+
tags:
197+
- { name: akeneo_referenceentity.record_value_updater }
190198
191199
192-
3) Infrastructure Layer
193-
^^^^^^^^^^^^^^^^^^^^^^^
200+
3) Retrieve our record value
201+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
194202

195203
Now that we can enrich our record with this new type of value, we need to create a dedicated hydrator, to hydrate our new record value from the DB:
196204

@@ -228,14 +236,10 @@ And register it for the registry:
228236
tags:
229237
- { name: akeneo_referenceentity.data_hydrator }
230238
231-
.. note::
232-
233-
Note that if you want to validate the ``EditSimpleMetricValueCommand``, you simply have to create a regular Symfony validator.
234-
235239
Frontend Part of The New Record Value
236240
-------------------------------------
237241

238-
To be able to create your brand new Simple Metric Record Value, we need to add some code in the frontend part.
242+
To be able to enrich your records with this new attribute, we need to add some code in the frontend part.
239243

240244
To do so, you can put all needed code in one single file but you can (and are encouraged) to split it into multiple
241245
files if needed.
@@ -244,10 +248,13 @@ To keep this example simple, we will create everything in this file :
244248

245249
``src/Acme/CustomBundle/Resources/public/reference-entity/record/simple-metric.tsx``
246250

247-
If you create a new Record Value, Akeneo will need three things to manage it in the frontend:
248-
- A model: a representation of your Record Value, it's properties and overall behaviour
249-
- A view: as a React component to be able to render a user interface in the Record Form and dispatch events to the application
250-
- A cell: as a React component to be able to render a cell in the Record Grid
251+
.. note::
252+
253+
If you create a new Record Value, Akeneo will need three things to manage it in the frontend:
254+
255+
- A **model**: a representation of your Record Value, it's properties and overall behaviour
256+
- A **view**: as a React component to be able to render a user interface in the Record Form and dispatch events to the application
257+
- A **cell**: as a React component to be able to render a cell in the Record Grid
251258

252259
1) Model
253260
^^^^^^^^

reference_entities/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ Reference entities are objects related to products with their own attributes and
1616
configure_entity_limits
1717
create_new_attribute_type
1818
enrich_a_record_with_new_attribute_type
19+
add_custom_property_to_your_custom_attribute_type

0 commit comments

Comments
 (0)