- Documentation >
- Tutorials >
- Generic field type >
- 8. Data migration
Step 8 - Data migration between field type versions
Adding data migration enables you to change the output of the field type to fit your current needs.
This process is important when a field type needs to be compared for sorting and searching purposes.
Serialization allows changing objects to array by normalizing them, and then to the selected format by encoding them.
In reverse, deserialization changes different formats into arrays by decoding and then denormalizing them into objects.
For more information on Serializer Components, see Symfony documentation.
Normalization
First, you need to add support for normalization in a src/Serializer/Point2D/ValueNormalizer.php
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 | <?php
declare(strict_types=1);
namespace App\Serializer\Point2D;
use App\FieldType\Point2D\Value;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
final class ValueNormalizer implements NormalizerInterface
{
/**
* @return array<?float, ?float>
*/
public function normalize($object, string $format = null, array $context = []): array
{
return [
$object->getX(),
$object->getY(),
];
}
public function supportsNormalization(mixed $data, ?string $format = null, array $context = []): bool
{
return $data instanceof Value;
}
public function getSupportedTypes(?string $format): array
{
return [
Value::class => true,
];
}
}
|
Add Normalizer definition
Next, add the ValueNormalizer
service definition to the config/services.yaml
with a serializer.normalizer
tag:
| services:
App\Serializer\Point2D\ValueNormalizer:
tags:
- { name: serializer.normalizer }
|
Backward compatibility
To accept old versions of the field type you need to add support for denormalization in a src/Serializer/Point2D/ValueDenormalizer.php
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 | <?php
declare(strict_types=1);
namespace App\Serializer\Point2D;
use App\FieldType\Point2D\Value;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
final class ValueDenormalizer implements DenormalizerInterface
{
public function denormalize($data, string $class, string $format = null, array $context = []): mixed
{
if (isset($data['x']) && isset($data['y'])) {
// Support for old format
$data = [$data['x'], $data['y']];
}
return new $class($data);
}
public function supportsDenormalization(mixed $data, string $type, ?string $format = null, array $context = []): bool
{
return $type === Value::class;
}
public function getSupportedTypes(?string $format): array
{
return [
Value::class => true,
];
}
}
|
Add Denormalizer definition
Next, add the ValueDenormalizer
service definition to config/services.yaml
with a serializer.denormalizer
tag:
| services:
App\Serializer\Point2D\ValueDenormalizer:
tags:
- { name: serializer.denormalizer }
|
To change the format on the fly, you need to replace the constructor in src/FieldType/Point2D/Value.php
:
| public function __construct(array $coords = [])
{
if (!empty($coords)) {
$this->x = $coords[0];
$this->y = $coords[1];
}
}
|
Now you can change the internal representation format of the Point 2D field type.