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 } |