- Documentation >
- Content management >
- Data migration >
- Create data migration action
Create data migration action
To create an action that is performed after a migration step, you need:
- An action class, to store any additional data that you might require.
- An action denormalizer, to convert YAML definition into your action class.
- An action executor, to handle the action.
The following example shows how to create an action that assigns a content item to a Section.
First, create an action class, in src/Migrations/Action/AssignSection.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\Migrations\Action;
use Ibexa\Migration\ValueObject\Step\Action;
final class AssignSection implements Action
{
public const TYPE = 'assign_section';
/** @var string */
private $sectionIdentifier;
public function __construct(string $sectionIdentifier)
{
$this->sectionIdentifier = $sectionIdentifier;
}
/**
* @return string
*/
public function getValue(): string
{
return $this->sectionIdentifier;
}
public function getSupportedType(): string
{
return self::TYPE;
}
}
|
Then you need a denormalizer to convert data that comes from YAML into an action object,
in src/Migrations/Action/AssignSectionDenormalizer.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 | <?php
declare(strict_types=1);
namespace App\Migrations\Action;
use Ibexa\Contracts\Migration\Serializer\Denormalizer\AbstractActionDenormalizer;
use Webmozart\Assert\Assert;
final class AssignSectionDenormalizer extends AbstractActionDenormalizer
{
protected function supportsActionName(string $actionName, string $format = null): bool
{
return $actionName === AssignSection::TYPE;
}
/**
* @param array<mixed> $data
* @param string $type
* @param string|null $format
* @param array<mixed> $context
*
* @return \App\Migrations\Action\AssignSection
*/
public function denormalize($data, string $type, string $format = null, array $context = []): AssignSection
{
Assert::keyExists($data, 'value');
return new AssignSection($data['value']);
}
}
|
Then, tag the action denormalizer so it is recognized by the serializer used for migrations.
| services:
App\Migrations\Action\AssignSectionDenormalizer:
autoconfigure: false
tags:
- { name: 'ibexa.migrations.serializer.normalizer' }
|
And finally, add an executor to perform the action, in src/Migrations/Action/AssignSectionExecutor.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
34
35
36
37 | <?php declare(strict_types=1);
namespace App\Migrations\Action;
use Ibexa\Contracts\Core\Repository\ContentService;
use Ibexa\Contracts\Core\Repository\SectionService;
use Ibexa\Contracts\Core\Repository\Values\ValueObject as APIValueObject;
use Ibexa\Migration\StepExecutor\ActionExecutor\ExecutorInterface;
use Ibexa\Migration\ValueObject;
final class AssignSectionExecutor implements ExecutorInterface
{
/** @var \Ibexa\Contracts\Core\Repository\SectionService */
private $sectionService;
/** @var \Ibexa\Contracts\Core\Repository\ContentService */
private $contentService;
public function __construct(
ContentService $contentService,
SectionService $sectionService
) {
$this->sectionService = $sectionService;
$this->contentService = $contentService;
}
/**
* @param \App\Migrations\Action\AssignSection $action
* @param \Ibexa\Contracts\Core\Repository\Values\Content\Content $content
*/
public function handle(ValueObject\Step\Action $action, APIValueObject $content): void
{
$contentInfo = $this->contentService->loadContentInfo($content->id);
$section = $this->sectionService->loadSectionByIdentifier($action->getValue());
$this->sectionService->assignSection($contentInfo, $section);
}
}
|
Tag the executor with ibexa.migrations.executor.action.<type>
tag, where <type>
is the "type" of the step
that executor works with (content
, content_type
, location
, and so on).
The tag has to have a key
property with the action type.
| App\Migrations\Action\AssignSectionExecutor:
tags:
- { name: 'ibexa.migrations.executor.action.content', key: !php/const App\Migrations\Action\AssignSection::TYPE }
|