@@ -5,23 +5,21 @@ Enrich Records with a new Reference Entity Attribute type
5
5
6
6
Reference Entities feature is only available for the **Enterprise Edition **.
7
7
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 `_.
15
9
10
+ .. _in a previous step : ./create_new_attribute_type.html
16
11
17
12
Enrich Records With the Attribute
18
13
---------------------------------
19
14
20
15
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
22
20
23
- 1) Domain Layer
24
- ^^^^^^^^^^^^^^^
21
+ 1) Your New Record Value
22
+ ^^^^^^^^^^^^^^^^^^^^^^^^
25
23
26
24
To enrich a record, we will create a new Record Value for the brand new Attribute type.
27
25
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
31
29
.. code-block :: php
32
30
33
31
<?php
32
+
34
33
namespace Acme\CustomBundle\Domain\Model\Record\Value;
35
34
36
35
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
43
42
44
43
private function __construct(string $metricValue)
45
44
{
46
- Assert::numeric($metricValue, 'The metric value should be a numeric string value');
47
-
48
45
$this->metricValue = $metricValue;
49
46
}
50
47
@@ -70,60 +67,64 @@ Let's create our own ``SimpleMetricData`` that will handle the current data of t
70
67
}
71
68
72
69
73
- That's all for the Domain Layer.
74
-
75
- 2) Application Layer
76
- ^^^^^^^^^^^^^^^^^^^^
70
+ 2) Set a value for the new attribute
71
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
77
72
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 :
79
74
80
75
.. code-block :: php
81
76
82
77
<?php
83
78
84
- namespace Acme\CustomBundle\Application\Attribute\EditAttribute \CommandFactory;
79
+ namespace Acme\CustomBundle\Application\Record\EditRecord \CommandFactory;
85
80
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;
87
83
88
- class EditMetricUnitCommand extends AbstractEditAttributeCommand
84
+ class EditSimpleMetricValueCommand extends AbstractEditValueCommand
89
85
{
90
86
/** @var string */
91
- public $metricUnit ;
87
+ public $metricValue ;
92
88
93
- public function __construct(string $identifier, string $metricUnit )
89
+ public function __construct(SimpleMetricAttribute $attribute, ? string $channel, ? string $locale, string $metricValue )
94
90
{
95
- parent::__construct($identifier );
91
+ parent::__construct($attribute, $channel, $locale );
96
92
97
- $this->metricUnit = $metricUnit ;
93
+ $this->metricValue = $metricValue ;
98
94
}
99
95
}
100
96
97
+
101
98
And its factory to build the command:
102
99
103
100
.. code-block :: php
104
101
105
- namespace Acme\CustomBundle\Application\Attribute\EditAttribute\CommandFactory;
102
+ <?php
106
103
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;
109
110
110
- class EditMetricUnitCommandFactory implements EditAttributeCommandFactoryInterface
111
+ class EditSimpleMetricValueCommandFactory implements EditValueCommandFactoryInterface
111
112
{
112
- public function supports(array $normalizedCommand ): bool
113
+ public function supports(AbstractAttribute $attribute, array $normalizedValue ): bool
113
114
{
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']);
116
119
}
117
120
118
- public function create(array $normalizedCommand ): AbstractEditAttributeCommand
121
+ public function create(AbstractAttribute $attribute, array $normalizedValue ): AbstractEditValueCommand
119
122
{
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']
127
128
);
128
129
129
130
return $command;
@@ -134,63 +135,70 @@ Don't forget to register your factory to be recognized by our registry:
134
135
135
136
.. code-block :: yaml
136
137
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
139
140
tags :
140
- - { name: akeneo_referenceentity.edit_attribute_command_factory, priority: 120 }
141
+ - { name: akeneo_referenceentity.edit_record_value_command_factory }
141
142
142
143
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:
143
144
144
145
.. code-block :: php
145
146
146
147
<?php
147
148
148
- namespace Acme\CustomBundle\Application\Attribute\EditAttribute\AttributeUpdater ;
149
+ namespace Acme\CustomBundle\Application\Record\EditRecord\ValueUpdater ;
149
150
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
158
163
{
159
- public function supports(AbstractAttribute $attribute, AbstractEditAttributeCommand $command): bool
164
+ public function supports(AbstractEditValueCommand $command): bool
160
165
{
161
- return $command instanceof EditMetricUnitCommand && $attribute instanceof SimpleMetricAttribute ;
166
+ return $command instanceof EditSimpleMetricValueCommand ;
162
167
}
163
168
164
- public function __invoke(AbstractAttribute $attribute, AbstractEditAttributeCommand $command): AbstractAttribute
169
+ public function __invoke(Record $record, AbstractEditValueCommand $command): void
165
170
{
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.');
174
173
}
175
174
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);
177
184
178
- return $attribute;
185
+ $value = Value::create($attribute, $channelReference, $localeReference, $metricValue);
186
+ $record->setValue($value);
179
187
}
180
188
}
181
189
182
190
Of course, we need to register this updater to be recognized by our registry:
183
191
184
192
.. code-block :: yaml
185
193
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 }
190
198
191
199
192
- 3) Infrastructure Layer
193
- ^^^^^^^^^^^^^^^^^^^^^^^
200
+ 3) Retrieve our record value
201
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
194
202
195
203
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:
196
204
@@ -228,14 +236,10 @@ And register it for the registry:
228
236
tags :
229
237
- { name: akeneo_referenceentity.data_hydrator }
230
238
231
- .. note ::
232
-
233
- Note that if you want to validate the ``EditSimpleMetricValueCommand ``, you simply have to create a regular Symfony validator.
234
-
235
239
Frontend Part of The New Record Value
236
240
-------------------------------------
237
241
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.
239
243
240
244
To do so, you can put all needed code in one single file but you can (and are encouraged) to split it into multiple
241
245
files if needed.
@@ -244,10 +248,13 @@ To keep this example simple, we will create everything in this file :
244
248
245
249
``src/Acme/CustomBundle/Resources/public/reference-entity/record/simple-metric.tsx ``
246
250
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
251
258
252
259
1) Model
253
260
^^^^^^^^
0 commit comments