Content Create:
{ action: assign_content_locations, value: '{"add": [369,153]}' }
Content Update(NOT SUPPORTED NOW):
{ action: assign_content_locations, value: '{"add": [154],"remove": [369,153]}' }
| <?php | |
| declare(strict_types=1); | |
| namespace App\Actions\Location; | |
| use Ibexa\Platform\Migration\ValueObject\Step\Action; | |
| final class AssignContentLocations implements Action | |
| { | |
| public const TYPE = 'assign_content_locations'; | |
| /** | |
| * @var string | |
| */ | |
| private $value; | |
| public function __construct(string $value = null) | |
| { | |
| $this->value = $value; | |
| } | |
| /** | |
| * @return string | |
| */ | |
| public function getValue() | |
| { | |
| try { | |
| return \json_decode($this->value, true, 512, JSON_THROW_ON_ERROR); | |
| } catch (\JsonException $e) { | |
| throw new \RuntimeException('Value of field `assign_content_locations` has invalid JSON', $e->getCode(), $e); | |
| } | |
| } | |
| public function getSupportedType(): string | |
| { | |
| return self::TYPE; | |
| } | |
| } |
| <?php | |
| declare(strict_types=1); | |
| namespace App\Actions\Location; | |
| use Ibexa\Platform\Migration\ValueObject\Step\Action; | |
| use Symfony\Component\Serializer\Normalizer\CacheableSupportsMethodInterface; | |
| use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; | |
| use Webmozart\Assert\Assert; | |
| /** | |
| * | |
| * Class AssignContentLocationsActionDenormalizer | |
| * | |
| */ | |
| final class AssignContentLocationsActionDenormalizer implements DenormalizerInterface, CacheableSupportsMethodInterface | |
| { | |
| /** | |
| * @var array<string, class-string> | |
| */ | |
| private $map; | |
| /** | |
| * @param array<array{ | |
| * action: string, | |
| * class: class-string, | |
| * }> $supportedActions | |
| */ | |
| public function __construct(array $supportedActions) | |
| { | |
| $this->map = $this->mapSupportedActions($supportedActions); | |
| } | |
| private function mapSupportedActions(array $supportedActions): array | |
| { | |
| return array_column($supportedActions, 'class', 'action'); | |
| } | |
| public function denormalize($data, string $type, string $format = null, array $context = []) | |
| { | |
| Assert::keyExists($data, 'value'); | |
| return new AssignContentLocations($data['value']); | |
| } | |
| public function hasCacheableSupportsMethod(): bool | |
| { | |
| return true; | |
| } | |
| public function supportsDenormalization($data, string $type, string $format = null) | |
| { | |
| return Action::class === $type; | |
| } | |
| } |
| <?php | |
| declare(strict_types=1); | |
| namespace App\Actions\Location; | |
| use eZ\Publish\API\Repository\ContentService; | |
| use eZ\Publish\API\Repository\LocationService; | |
| use Ibexa\Platform\Migration\ValueObject; | |
| use Ibexa\Platform\Migration\StepExecutor\ActionExecutor\ExecutorInterface; | |
| use eZ\Publish\API\Repository\Values\ValueObject as APIValueObject; | |
| /** | |
| * Usage { action: assign_content_locations, value: '{"add": [369,153],"remove": [153]}'} | |
| * | |
| * Class AssignContentLocationsExecutor | |
| */ | |
| final class AssignContentLocationsExecutor implements ExecutorInterface | |
| { | |
| /*** @var LocationService */ | |
| private $locationService; | |
| private ContentService $contentService; | |
| public function __construct( | |
| LocationService $locationService | |
| ) { | |
| $this->locationService = $locationService; | |
| } | |
| /** | |
| * @param AssignContentLocations $action | |
| * @param \eZ\Publish\API\Repository\Values\Content\Content $content | |
| */ | |
| public function handle(ValueObject\Step\Action $action, APIValueObject $content): void | |
| { | |
| $values = array_filter($action->getValue()); | |
| $contentInfo = $content->contentInfo; | |
| if(array_key_exists('add',$values) && is_array($values) ){ | |
| try { | |
| foreach ($values['add'] as $parentLocationId){ | |
| $locationCreateStruct = $this->locationService->newLocationCreateStruct($parentLocationId); | |
| $this->locationService->createLocation($contentInfo, $locationCreateStruct); | |
| } | |
| } catch (\Exception $e) { | |
| throw new \RuntimeException('create Location(s) during `assign_content_locations` has failed with: '. $e->getMessage(), $e->getCode(), $e); | |
| } | |
| } | |
| //throw an error when deleteLocation: Could not find 'location' with identifier '123456' | |
| // if(array_key_exists('remove',$values) && is_array($values) ){ | |
| // try { | |
| // foreach ($values['remove'] as $parentLocationId){ | |
| // $contentLocations = $this->locationService->loadLocations($contentInfo); | |
| // foreach ($contentLocations as $location){ | |
| // if(in_array((string)$parentLocationId,explode('/',$location->pathString))){ | |
| // $this->locationService->deleteLocation($location); | |
| // } | |
| // } | |
| // } | |
| // } catch (\Exception $e) { | |
| // throw new \RuntimeException('remove location(s) during `assign_content_locations` has failed with: '. $e->getMessage(), $e->getCode(), $e,); | |
| // } | |
| // } | |
| } | |
| } |
| services: | |
| _defaults: | |
| autowire: true | |
| autoconfigure: false | |
| public: false | |
| #Custom Executor to assign content to many locations on content create only ! (Update not supported in v.3.3.3) | |
| App\Actions\Location\AssignContentLocationsExecutor: | |
| tags: | |
| - { name: 'ibexa.migrations.executor.action.content', key: !php/const \App\Actions\Location\AssignContentLocations::TYPE } | |
| # Add a denormalizer class. | |
| App\Actions\Location\AssignContentLocationsActionDenormalizer: | |
| arguments: | |
| - | |
| - | |
| action: !php/const \App\Actions\Location\AssignContentLocations::TYPE | |
| class: App\Actions\Location\AssignContentLocations | |
| tags: | |
| - { name: 'ibexa.migrations.serializer.normalizer', priority: 20 } |