diff --git a/src/lib/Persistence/Legacy/Content/FieldHandler.php b/src/lib/Persistence/Legacy/Content/FieldHandler.php index da16face3b..592fd861ba 100644 --- a/src/lib/Persistence/Legacy/Content/FieldHandler.php +++ b/src/lib/Persistence/Legacy/Content/FieldHandler.php @@ -151,6 +151,10 @@ protected function getEmptyField(FieldDefinition $fieldDefinition, $languageCode public function createExistingFieldsInNewVersion(Content $content) { foreach ($content->fields as $field) { + if ($field->id === null) { + // Virtual field with default value, skip creating field as it has no id + continue; + } $this->createExistingFieldInNewVersion($field, $content); } } diff --git a/src/lib/Persistence/Legacy/Content/Mapper.php b/src/lib/Persistence/Legacy/Content/Mapper.php index b7cf7823be..c5e107fc97 100644 --- a/src/lib/Persistence/Legacy/Content/Mapper.php +++ b/src/lib/Persistence/Legacy/Content/Mapper.php @@ -14,6 +14,8 @@ use Ibexa\Contracts\Core\Persistence\Content\Language\Handler as LanguageHandler; use Ibexa\Contracts\Core\Persistence\Content\Relation; use Ibexa\Contracts\Core\Persistence\Content\Relation\CreateStruct as RelationCreateStruct; +use Ibexa\Contracts\Core\Persistence\Content\Type\FieldDefinition; +use Ibexa\Contracts\Core\Persistence\Content\Type\Handler as ContentTypeHandler; use Ibexa\Contracts\Core\Persistence\Content\VersionInfo; use Ibexa\Core\Base\Exceptions\NotFoundException; use Ibexa\Core\Persistence\Legacy\Content\FieldValue\ConverterRegistry as Registry; @@ -39,16 +41,22 @@ class Mapper */ protected $languageHandler; + private ContentTypeHandler $contentTypeHandler; + /** * Creates a new mapper. * * @param \Ibexa\Core\Persistence\Legacy\Content\FieldValue\ConverterRegistry $converterRegistry * @param \Ibexa\Contracts\Core\Persistence\Content\Language\Handler $languageHandler */ - public function __construct(Registry $converterRegistry, LanguageHandler $languageHandler) - { + public function __construct( + Registry $converterRegistry, + LanguageHandler $languageHandler, + ContentTypeHandler $contentTypeHandler + ) { $this->converterRegistry = $converterRegistry; $this->languageHandler = $languageHandler; + $this->contentTypeHandler = $contentTypeHandler; } /** @@ -191,15 +199,23 @@ public function extractContentFromRows(array $rows, array $nameRows, $prefix = ' $contentInfos = []; $versionInfos = []; $fields = []; + $fieldDefinitions = []; foreach ($rows as $row) { $contentId = (int)$row["{$prefix}id"]; + $contentTypeId = (int)$row["{$prefix}contentclass_id"]; if (!isset($contentInfos[$contentId])) { $contentInfos[$contentId] = $this->extractContentInfoFromRow($row, $prefix); } if (!isset($versionInfos[$contentId])) { $versionInfos[$contentId] = []; } + if (!isset($fieldDefinitions[$contentId])) { + $contentType = $this->contentTypeHandler->load($contentTypeId); + foreach ($contentType->fieldDefinitions as $fieldDefinition) { + $fieldDefinitions[$contentId][$fieldDefinition->id] = $fieldDefinition; + } + } $versionId = (int)$row['ezcontentobject_version_id']; if (!isset($versionInfos[$contentId][$versionId])) { @@ -207,8 +223,10 @@ public function extractContentFromRows(array $rows, array $nameRows, $prefix = ' } $fieldId = (int)$row['ezcontentobject_attribute_id']; - if (!isset($fields[$contentId][$versionId][$fieldId])) { + $fieldDefinitionId = (int)$row["ezcontentobject_attribute_contentclassattribute_id"]; + if (!isset($fields[$contentId][$versionId][$fieldId]) && isset($fieldDefinitions[$contentId][$fieldDefinitionId])) { $fields[$contentId][$versionId][$fieldId] = $this->extractFieldFromRow($row); + unset($fieldDefinitions[$contentId][$fieldDefinitionId]); } } @@ -227,6 +245,15 @@ public function extractContentFromRows(array $rows, array $nameRows, $prefix = ' $content->versionInfo->names = $names; $content->versionInfo->contentInfo = $contentInfo; $content->fields = array_values($fields[$contentId][$versionId]); + + foreach ($fieldDefinitions[$contentId] as $fieldDefinition) { + $languageCode = $this->determineEmptyFieldLanguageCode($content); + $content->fields[] = $this->createEmptyField( + $fieldDefinition, + $languageCode + ); + } + $results[] = $content; } } @@ -578,6 +605,26 @@ public function createRelationFromCreateStruct(RelationCreateStruct $struct) return $relation; } + + private function createEmptyField(FieldDefinition $fieldDefinition, string $languageCode): Field + { + $field = new Field(); + $field->fieldDefinitionId = $fieldDefinition->id; + $field->type = $fieldDefinition->fieldType; + $field->value = $fieldDefinition->defaultValue; + $field->languageCode = $languageCode; + + return $field; + } + + private function determineEmptyFieldLanguageCode(Content $content): string + { + foreach ($content->fields as $field) { + return $field->languageCode; + } + + return $content->versionInfo->initialLanguageCode;; + } } class_alias(Mapper::class, 'eZ\Publish\Core\Persistence\Legacy\Content\Mapper'); diff --git a/src/lib/Persistence/Legacy/Content/Type/Handler.php b/src/lib/Persistence/Legacy/Content/Type/Handler.php index 4f04557b13..e8f99ccfe9 100644 --- a/src/lib/Persistence/Legacy/Content/Type/Handler.php +++ b/src/lib/Persistence/Legacy/Content/Type/Handler.php @@ -622,7 +622,6 @@ public function publish($contentTypeId) try { $fromType = $this->load($contentTypeId, Type::STATUS_DEFINED); - $this->updateHandler->updateContentObjects($fromType, $toType); $this->updateHandler->deleteOldType($fromType); } catch (Exception\TypeNotFound $e) { // If no old type is found, no updates are necessary to it diff --git a/src/lib/Resources/settings/storage_engines/legacy/content.yml b/src/lib/Resources/settings/storage_engines/legacy/content.yml index df3457e00e..639f675f3a 100644 --- a/src/lib/Resources/settings/storage_engines/legacy/content.yml +++ b/src/lib/Resources/settings/storage_engines/legacy/content.yml @@ -9,6 +9,7 @@ services: arguments: - '@Ibexa\Core\Persistence\Legacy\Content\FieldValue\ConverterRegistry' - '@ibexa.spi.persistence.legacy.language.handler' + - '@ibexa.spi.persistence.legacy.content_type.handler' Ibexa\Core\Persistence\Legacy\Content\Gateway\DoctrineDatabase.inner: class: Ibexa\Core\Persistence\Legacy\Content\Gateway\DoctrineDatabase