Skip to content

Commit

Permalink
feat: import export bundle
Browse files Browse the repository at this point in the history
  • Loading branch information
Florian ALEXANDRE committed Aug 1, 2024
1 parent 5c05846 commit 9e8760a
Show file tree
Hide file tree
Showing 12 changed files with 328 additions and 236 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,4 @@ services:

AlmaviaCX\Bundle\IbexaImportExport\Item\ValueTransformer\Ibexa\HtmlToTextBlockTransformer:
tags:
- { name: almaviacx.import_export.item.value_transformer, alias: almaviacx.import_export.item.value_transformer.html_to_textblock}
- { name: almaviacx.import_export.item.value_transformer, alias: almaviacx.import_export.item.value_transformer.html_to_textblock}
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,17 @@ services:
- console.command

AlmaviaCX\Bundle\IbexaImportExport\Reference\ReferenceBag:

AlmaviaCX\Bundle\IbexaImportExport\Writer\Ibexa\Content\IbexaContentCreator:
arguments:
$repository: '@Ibexa\Contracts\Core\Repository\Repository'

AlmaviaCX\Bundle\IbexaImportExport\Writer\Ibexa\Content\IbexaContentUpdater:
arguments:
$repository: '@Ibexa\Contracts\Core\Repository\Repository'

AlmaviaCX\Bundle\IbexaImportExport\Writer\Ibexa\Content\IbexaContentImporter:
arguments:
$repository: '@Ibexa\Contracts\Core\Repository\Repository'
$contentCreator: '@AlmaviaCX\Bundle\IbexaImportExport\Writer\Ibexa\Content\IbexaContentCreator'
$contentUpdater: '@AlmaviaCX\Bundle\IbexaImportExport\Writer\Ibexa\Content\IbexaContentUpdater'
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ services:
arguments:
$repository: '@Ibexa\Contracts\Core\Repository\Repository'
$objectAccessorBuilder: '@AlmaviaCX\Bundle\IbexaImportExport\Accessor\Ibexa\ObjectAccessorBuilder'
$contentImporter: '@AlmaviaCX\Bundle\IbexaImportExport\Writer\Ibexa\Content\IbexaContentImporter'
tags:
- { name: almaviacx.import_export.component, alias: writer.ibexa.content }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,15 @@ public function transform($value, array $options = [])
$tmpFilePath .= '.'.$originalPathInfos['extension'];
}

register_shutdown_function(function () use ($tmpFilePath) {
if (file_exists($tmpFilePath)) {
unlink($tmpFilePath);
}
});
file_put_contents(
$tmpFilePath,
file_get_contents(
$value,
str_replace(' ', '+', $value),
false,
stream_context_create(
[
Expand All @@ -41,10 +46,6 @@ public function transform($value, array $options = [])
)
);

register_shutdown_function(function () use ($tmpFilePath) {
unlink($tmpFilePath);
});

return $tmpFilePath;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ protected function transform($value, array $options = [])
return null;
}

return DateTime::createFromFormat($options['input_format'], $value);
return DateTime::createFromFormat($options['input_format'], (string) $value);
}

protected function configureOptions(OptionsResolver $optionsResolver)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use AlmaviaCX\Bundle\IbexaImportExport\Processor\ProcessorInterface;
use JMS\TranslationBundle\Annotation\Desc;
use Symfony\Component\Translation\TranslatableMessage;
use Throwable;

class ProcessorAggregator extends AbstractProcessor implements ProcessorInterface
{
Expand All @@ -18,11 +19,20 @@ class ProcessorAggregator extends AbstractProcessor implements ProcessorInterfac
public function processItem($item)
{
$processors = $this->getProcessors();
foreach ($processors as $processor) {
$item = ($processor)($item);
if (false === $item) {
return;
try {
foreach ($processors as $processor) {
$item = ($processor)($item);
if (false === $item) {
return;
}
}
} catch (Throwable $e) {
if ($this->getOption('errorBubbling', true)) {
throw $e;
}
$this->logger->logException($e);

return null;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@

/**
* @property array<ComponentReference> $processors
* @property bool $errorBubbling
*/
class ProcessorAggregatorOptions extends ProcessorOptions
{
use ProcessorReferenceAggregationTrait;

protected bool $errorBubbling = true;

public function merge(ComponentOptions $overrideOptions): ComponentOptions
{
dd($overrideOptions);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

namespace AlmaviaCX\Bundle\IbexaImportExport\Writer\Ibexa\Content;

use Ibexa\Contracts\Core\Repository\Repository;
use Ibexa\Contracts\Core\Repository\Values\Content\ContentStruct;
use Ibexa\Contracts\Core\Repository\Values\ContentType\ContentType;
use Ibexa\Contracts\Core\Repository\Values\ContentType\FieldDefinition;

class AbstractIbexaContentHandler
{
protected Repository $repository;

public function __construct(
Repository $repository
) {
$this->repository = $repository;
}

/**
* @param array<string, mixed> $fieldsByLanguages
*/
protected function setContentFields(
ContentType $contentType,
ContentStruct $contentStruct,
array $fieldsByLanguages
): void {
foreach ($fieldsByLanguages as $languageCode => $fields) {
foreach ($fields as $fieldID => $field) {
$fieldDefinition = $contentType->getFieldDefinition($fieldID);
if ($fieldDefinition instanceof FieldDefinition) {
$contentStruct->setField($fieldID, $field, $languageCode);
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php

declare(strict_types=1);

namespace AlmaviaCX\Bundle\IbexaImportExport\Writer\Ibexa\Content;

use DateTime;
use Exception;
use Ibexa\Contracts\Core\Repository\Values\Content\Content;
use Ibexa\Contracts\Core\Repository\Values\Content\Location;

class IbexaContentCreator extends AbstractIbexaContentHandler
{
/**
* @param array<string|int, int|string|Location> $parentLocationIdList
* @param array<string, mixed> $fieldsByLanguages
*
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentFieldValidationException
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException
*/
public function __invoke(
string $contentTypeIdentifier,
array $parentLocationIdList,
array $fieldsByLanguages,
string $remoteId,
int $ownerId = null,
string $languageCode = 'eng-GB',
int $sectionId = null,
$modificationDate = null,
bool $hidden = false
): Content {
$contentType = $this->repository->getContentTypeService()->loadContentTypeByIdentifier(
$contentTypeIdentifier
);

/* Creating new content create structure */
$contentCreateStruct = $this->repository->getContentService()->newContentCreateStruct(
$contentType,
$languageCode
);
$contentCreateStruct->remoteId = $remoteId;
$contentCreateStruct->ownerId = $ownerId;
if (null !== $modificationDate) {
$contentCreateStruct->modificationDate = $modificationDate instanceof DateTime ?
$modificationDate :
DateTime::createFromFormat('U', (string) $modificationDate);
}

if ($sectionId) {
$contentCreateStruct->sectionId = $sectionId;
}

/* Update content structure fields */
$this->setContentFields($contentType, $contentCreateStruct, $fieldsByLanguages);

/* Assigning the content locations */
$locationCreateStructs = [];
foreach ($parentLocationIdList as $locationRemoteId => $parentLocationId) {
if (empty($parentLocationId)) {
throw new Exception('Parent location id cannot be empty');
}
if ($parentLocationId instanceof Location) {
$parentLocationId = $parentLocationId->id;
}
if (is_string($parentLocationId)) {
$parentLocationId = $this->repository->getLocationService()->loadLocationByRemoteId(
$parentLocationId
)->id;
}
$locationCreateStruct = $this->repository->getLocationService()->newLocationCreateStruct(
$parentLocationId
);
if (is_string($locationRemoteId)) {
$locationCreateStruct->remoteId = $locationRemoteId;
}
if ($hidden) {
$locationCreateStruct->hidden = true;
}
$locationCreateStructs[] = $locationCreateStruct;
}

/* Creating new draft */
$draft = $this->repository->getContentService()->createContent(
$contentCreateStruct,
$locationCreateStructs
);

/* Publish the new content draft */
return $this->repository->getContentService()->publishVersion($draft->versionInfo);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

declare(strict_types=1);

namespace AlmaviaCX\Bundle\IbexaImportExport\Writer\Ibexa\Content;

use Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException;
use Ibexa\Contracts\Core\Repository\Repository;

class IbexaContentImporter
{
protected Repository $repository;
protected IbexaContentUpdater $contentUpdater;
protected IbexaContentCreator $contentCreator;

public function __construct(
Repository $repository,
IbexaContentUpdater $contentUpdater,
IbexaContentCreator $contentCreator
) {
$this->contentCreator = $contentCreator;
$this->contentUpdater = $contentUpdater;
$this->repository = $repository;
}

/**
* @param \AlmaviaCX\Bundle\IbexaImportExport\Writer\Ibexa\Content\IbexaContentData $contentData
*
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentFieldValidationException
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException
*
* @return \Ibexa\Contracts\Core\Repository\Values\Content\Content
*/
public function __invoke(IbexaContentData $contentData, bool $allowUpdate = true)
{
$remoteId = $contentData->getContentRemoteId();
$ownerId = $contentData->getOwnerId();
if (null === $ownerId) {
$ownerId = $this->repository
->getPermissionResolver()
->getCurrentUserReference()
->getUserId();
}

try {
try {
$content = $this->repository->getContentService()->loadContentByRemoteId(
$contentData->getContentRemoteId()
);
if (!$allowUpdate) {
return $content;
}

return ($this->contentUpdater)(
$content,
$contentData->getFields(),
$ownerId,
$contentData->getMainLanguageCode()
);
} catch (NotFoundException $exception) {
return ($this->contentCreator)(
$contentData->getContentTypeIdentifier(),
$contentData->getParentLocationIdList(),
$contentData->getFields(),
$remoteId,
$ownerId,
$contentData->getMainLanguageCode(),
$contentData->getSectionId(),
$contentData->getModificationDate()
);
}
} catch (\Throwable $exception) {
dump($exception);
throw $exception;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

declare(strict_types=1);

namespace AlmaviaCX\Bundle\IbexaImportExport\Writer\Ibexa\Content;

use Ibexa\Contracts\Core\Repository\Values\Content\Content;

class IbexaContentUpdater extends AbstractIbexaContentHandler
{
/**
* @param array<string, mixed> $fieldsByLanguages
*
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentFieldValidationException
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException
*/
public function __invoke(
Content $content,
array $fieldsByLanguages,
int $ownerId = null,
string $mainLanguageCode = 'eng-GB'
): Content {
$contentType = $this->repository->getContentTypeService()->loadContentType(
$content->contentInfo->contentTypeId
);

$contentInfo = $content->contentInfo;
$contentDraft = $this->repository->getContentService()->createContentDraft($contentInfo);

/* Creating new content update structure */
$contentUpdateStruct = $this->repository
->getContentService()
->newContentUpdateStruct();
$contentUpdateStruct->initialLanguageCode = $mainLanguageCode; // set language for new version
$contentUpdateStruct->creatorId = $ownerId;

$this->setContentFields(
$contentType,
$contentUpdateStruct,
$fieldsByLanguages,
);

$contentDraft = $this->repository->getContentService()->updateContent(
$contentDraft->versionInfo,
$contentUpdateStruct
);

/* Publish the new content draft */
return $this->repository->getContentService()->publishVersion($contentDraft->versionInfo);
}
}
Loading

0 comments on commit 9e8760a

Please sign in to comment.