From 1718ec424d980eb94e2c2a939a77ba65864b6371 Mon Sep 17 00:00:00 2001 From: lukmzig <30526586+lukmzig@users.noreply.github.com> Date: Wed, 22 Jan 2025 15:40:10 +0100 Subject: [PATCH] [Data Object] Adjust getDataForSetter method of data object adapters (#701) * adapt first adapter * fix date and boolean adapters * Fixed VideoAdapter, UrlSlugAdapter * Fixed StructuredTableAdapter.php * fix geo adapters * Fixed qv and qvr adapter * fix image adapters * Fixed iqv adapter * Make sure to use object as type for getting data objects from core * fix advance relations adapters * fix encrypted field adapter * Fixed object bricks adapter * Fixed block adapter * Adaptions for ClassificationStoreAdapter * Fixed ClassificationStoreAdapter.php * Apply php-cs-fixer changes * fix sonar * Apply php-cs-fixer changes * use denormalize method as default setter value * Apply php-cs-fixer changes * Apply php-cs-fixer changes * fix typo * add missing strict types --------- Co-authored-by: Marco Perberschlager --- config/data_objects.yaml | 3 -- config/pimcore/config.yaml | 3 +- .../AdvancedManyToManyRelationAdapter.php | 2 + src/DataObject/Data/Adapter/BlockAdapter.php | 3 +- .../Data/Adapter/BooleanAdapter.php | 7 +-- .../Data/Adapter/CheckboxAdapter.php | 45 ---------------- .../Adapter/ClassificationStoreAdapter.php | 40 ++++++++------ .../Data/Adapter/ConsentAdapter.php | 6 +-- src/DataObject/Data/Adapter/DateAdapter.php | 2 +- .../Data/Adapter/DateRangeAdapter.php | 26 +++++----- .../Data/Adapter/EncryptedFieldAdapter.php | 2 +- .../Data/Adapter/ExternalImageAdapter.php | 9 ++-- .../Data/Adapter/GeoBoundsAdapter.php | 41 ++++++++++++--- .../Data/Adapter/GeoPointAdapter.php | 6 ++- .../Data/Adapter/GeoPointsAdapter.php | 8 ++- .../Data/Adapter/HotspotImageAdapter.php | 23 ++++---- .../Adapter/InputQuantityValueAdapter.php | 5 +- .../Data/Adapter/LocalizedFieldsAdapter.php | 4 +- .../Adapter/ManyToManyRelationAdapter.php | 2 + .../Data/Adapter/NumericAdapter.php | 2 +- .../Data/Adapter/ObjectBricksAdapter.php | 52 ++++++++++++------- .../Data/Adapter/QuantityValueAdapter.php | 5 +- .../Adapter/QuantityValueRangeAdapter.php | 5 +- src/DataObject/Data/Adapter/SelectAdapter.php | 2 +- src/DataObject/Data/Adapter/SliderAdapter.php | 2 +- src/DataObject/Data/Adapter/StringAdapter.php | 2 +- .../Data/Adapter/StructuredTableAdapter.php | 5 +- .../Data/Adapter/UrlSlugAdapter.php | 27 ++-------- src/DataObject/Data/Adapter/VideoAdapter.php | 12 ++--- src/DataObject/Service/PreviewUrlService.php | 2 +- .../Util/Trait/DefaultSetterValueTrait.php | 10 ++-- .../Constant/DataObject/ContainerTypes.php | 1 + src/Util/Constant/DataObject/Coordinates.php | 27 ++++++++++ src/Util/Constant/DownloadFormats.php | 1 + src/Util/Constant/ElementIconTypes.php | 1 + 35 files changed, 199 insertions(+), 194 deletions(-) delete mode 100644 src/DataObject/Data/Adapter/CheckboxAdapter.php create mode 100644 src/Util/Constant/DataObject/Coordinates.php diff --git a/config/data_objects.yaml b/config/data_objects.yaml index f1c96843c..45091a47a 100644 --- a/config/data_objects.yaml +++ b/config/data_objects.yaml @@ -93,9 +93,6 @@ services: Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter\CalculatedValueAdapter: tags: [ 'pimcore.studio_backend.data_adapter' ] - Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter\CheckboxAdapter: - tags: [ 'pimcore.studio_backend.data_adapter' ] - Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter\ClassificationStoreAdapter: tags: [ 'pimcore.studio_backend.data_adapter' ] diff --git a/config/pimcore/config.yaml b/config/pimcore/config.yaml index 53c3cf9c2..9e4406968 100644 --- a/config/pimcore/config.yaml +++ b/config/pimcore/config.yaml @@ -65,10 +65,9 @@ pimcore_studio_backend: - "advancedManyToManyObjectRelation" Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter\BooleanAdapter: - "booleanSelect" + - "checkbox" Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter\CalculatedValueAdapter: - "calculatedValue" - Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter\CheckboxAdapter: - - "checkbox" Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter\ClassificationStoreAdapter: - "classificationstore" Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter\DateAdapter: diff --git a/src/DataObject/Data/Adapter/AdvancedManyToManyRelationAdapter.php b/src/DataObject/Data/Adapter/AdvancedManyToManyRelationAdapter.php index 75c3f31ee..151f16e4e 100644 --- a/src/DataObject/Data/Adapter/AdvancedManyToManyRelationAdapter.php +++ b/src/DataObject/Data/Adapter/AdvancedManyToManyRelationAdapter.php @@ -24,6 +24,7 @@ use Pimcore\Bundle\StudioBackendBundle\DataObject\Service\DataAdapterLoaderInterface; use Pimcore\Bundle\StudioBackendBundle\DataObject\Util\Trait\RelationDataTrait; use Pimcore\Bundle\StudioBackendBundle\DataObject\Util\Trait\RelationMetadataTrait; +use Pimcore\Bundle\StudioBackendBundle\Util\Trait\ElementProviderTrait; use Pimcore\Model\DataObject\ClassDefinition\Data; use Pimcore\Model\DataObject\ClassDefinition\Data\AdvancedManyToManyRelation; use Pimcore\Model\DataObject\Concrete; @@ -37,6 +38,7 @@ #[AutoconfigureTag(DataAdapterLoaderInterface::ADAPTER_TAG)] final readonly class AdvancedManyToManyRelationAdapter implements SetterDataInterface, DataNormalizerInterface { + use ElementProviderTrait; use RelationDataTrait; use RelationMetadataTrait; diff --git a/src/DataObject/Data/Adapter/BlockAdapter.php b/src/DataObject/Data/Adapter/BlockAdapter.php index 140251b34..a7e990c63 100644 --- a/src/DataObject/Data/Adapter/BlockAdapter.php +++ b/src/DataObject/Data/Adapter/BlockAdapter.php @@ -146,7 +146,6 @@ private function processBlockElement( ?FieldContextData $contextData = null ): array { $resultElement = []; - $blockElement = $rawBlockElement['data'] ?? null; $fieldDefinitions = $fieldDefinition->getFieldDefinitions(); $fieldContextData = $this->createFieldContextData($element, $fieldDefinition, $contextData); @@ -161,7 +160,7 @@ private function processBlockElement( $element, $fd, $elementName, - $blockElement, + $rawBlockElement, $fieldContextData ); if (!$value) { diff --git a/src/DataObject/Data/Adapter/BooleanAdapter.php b/src/DataObject/Data/Adapter/BooleanAdapter.php index 6b9ab8b98..3eb4d4bc4 100644 --- a/src/DataObject/Data/Adapter/BooleanAdapter.php +++ b/src/DataObject/Data/Adapter/BooleanAdapter.php @@ -36,10 +36,7 @@ public function getDataForSetter( array $data, ?FieldContextData $contextData = null ): ?bool { - return match((int) $data[$key]) { - 1 => true, - -1 => false, - default => null, - }; + + return $data[$key] ?? null; } } diff --git a/src/DataObject/Data/Adapter/CheckboxAdapter.php b/src/DataObject/Data/Adapter/CheckboxAdapter.php deleted file mode 100644 index e2827d285..000000000 --- a/src/DataObject/Data/Adapter/CheckboxAdapter.php +++ /dev/null @@ -1,45 +0,0 @@ -getDefaultDataForSetter($element, $fieldDefinition, $key, $data); - } -} diff --git a/src/DataObject/Data/Adapter/ClassificationStoreAdapter.php b/src/DataObject/Data/Adapter/ClassificationStoreAdapter.php index 9434b505e..8efe04897 100644 --- a/src/DataObject/Data/Adapter/ClassificationStoreAdapter.php +++ b/src/DataObject/Data/Adapter/ClassificationStoreAdapter.php @@ -43,7 +43,6 @@ use Pimcore\Model\DataObject\Concrete; use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag; use function in_array; -use function is_array; /** * @internal @@ -82,11 +81,17 @@ public function getDataForSetter( } $store = $data[$key]; + $activeGroups = $store['activeGroups'] ?? []; + if (empty($activeGroups)) { + return null; + } + $groupCollectionMapping = $store['groupCollectionMapping'] ?? []; $container = $this->getContainer($element, $key, $contextData); - $this->setMapping($container, $store); - if (is_array($store['data'])) { - $this->setStoreValues($element, $fieldDefinition, $container, $store); + if (!empty($groupCollectionMapping)) { + $this->setMapping($container, $store['activeGroups'], $store['groupCollectionMapping']); } + unset($store['activeGroups'], $store['groupCollectionMapping']); + $this->setStoreValues($element, $fieldDefinition, $container, $store); $this->cleanupStoreGroups($container); return $container; @@ -105,7 +110,10 @@ public function normalize( $validLanguages = $this->getValidLanguages($fieldDefinition); $resultItems = []; - foreach ($this->getActiveGroups($value) as $groupId => $groupConfig) { + $resultItems['activeGroups'] = $value->getActiveGroups(); + $resultItems['groupCollectionMapping'] = $value->getGroupCollectionMappings(); + + foreach ($this->getActiveGroupsConfig($resultItems['activeGroups']) as $groupId => $groupConfig) { $resultItems[$groupId] = []; $keys = $this->getClassificationStoreKeysFromGroup($groupId); foreach ($validLanguages as $validLanguage) { @@ -174,11 +182,11 @@ private function getContainer( return $container; } - private function setMapping(Classificationstore $container, array $data): void - { - $activeGroups = $data['activeGroups']; - $groupCollectionMapping = $data['groupCollectionMapping']; - + private function setMapping( + Classificationstore $container, + array $activeGroups, + array $groupCollectionMapping + ): void { $correctedMapping = array_filter($groupCollectionMapping, static function ($groupId) use ($activeGroups) { return isset($activeGroups[$groupId]) && $activeGroups[$groupId]; }, ARRAY_FILTER_USE_KEY); @@ -195,9 +203,11 @@ private function setStoreValues( Classificationstore $container, array $store ): void { - $activeGroups = $store['activeGroups']; - foreach ($store['data'] as $language => $groups) { - foreach ($groups as $groupId => $keys) { + + $activeGroups = []; + + foreach ($store as $groupId => $groupData) { + foreach ($groupData as $language => $keys) { $this->processGroupKeys($element, $definition, $container, $language, $groupId, $keys); $activeGroups[$groupId] = true; } @@ -293,10 +303,10 @@ private function getValidLanguages(ClassificationstoreDefinition $classification /** * @return GroupConfig[] */ - private function getActiveGroups(ClassificationstoreModel $value): array + private function getActiveGroupsConfig(array $activeGroups): array { $groups = []; - foreach ($value->getActiveGroups() as $groupId => $active) { + foreach ($activeGroups as $groupId => $active) { if ($active) { $groupConfig = $this->groupConfigResolver->getById($groupId); if ($groupConfig) { diff --git a/src/DataObject/Data/Adapter/ConsentAdapter.php b/src/DataObject/Data/Adapter/ConsentAdapter.php index 6d546b980..e67f6602d 100644 --- a/src/DataObject/Data/Adapter/ConsentAdapter.php +++ b/src/DataObject/Data/Adapter/ConsentAdapter.php @@ -49,13 +49,9 @@ public function getDataForSetter( array $data, ?FieldContextData $contextData = null ): Consent { - $value = $data[$key] ?? null; + $value = $data[$key] ? $data[$key]['consent'] : null; $noteId = null; - if ($value === 'false') { - $value = false; - } - /** @var Consent|null $oldData */ $oldData = $element->get($key); diff --git a/src/DataObject/Data/Adapter/DateAdapter.php b/src/DataObject/Data/Adapter/DateAdapter.php index 57cf688e4..a3eb48cf6 100644 --- a/src/DataObject/Data/Adapter/DateAdapter.php +++ b/src/DataObject/Data/Adapter/DateAdapter.php @@ -44,7 +44,7 @@ public function getDataForSetter( if (is_numeric($dateData)) { /** @var Date|Datetime $fieldDefinition */ - return $fieldDefinition->denormalize($dateData / 1000); + return $fieldDefinition->denormalize($dateData); } if (is_string($dateData)) { diff --git a/src/DataObject/Data/Adapter/DateRangeAdapter.php b/src/DataObject/Data/Adapter/DateRangeAdapter.php index 8cdfbabe2..38072a631 100644 --- a/src/DataObject/Data/Adapter/DateRangeAdapter.php +++ b/src/DataObject/Data/Adapter/DateRangeAdapter.php @@ -16,21 +16,22 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; -use Carbon\Carbon; use Carbon\CarbonPeriod; +use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\DataNormalizerInterface; use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Model\FieldContextData; use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\SetterDataInterface; use Pimcore\Bundle\StudioBackendBundle\DataObject\Service\DataAdapterLoaderInterface; use Pimcore\Model\DataObject\ClassDefinition\Data; use Pimcore\Model\DataObject\Concrete; use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag; +use function count; use function is_array; /** * @internal */ #[AutoconfigureTag(DataAdapterLoaderInterface::ADAPTER_TAG)] -final readonly class DateRangeAdapter implements SetterDataInterface +final readonly class DateRangeAdapter implements SetterDataInterface, DataNormalizerInterface { public function getDataForSetter( Concrete $element, @@ -41,21 +42,22 @@ public function getDataForSetter( ): ?CarbonPeriod { $dateData = $data[$key]; - if (is_array($dateData) && isset($dateData['start_date'], $dateData['end_date'])) { - $startDate = $this->getDateFromTimestamp($data['start_date'] / 1000); - $endDate = $this->getDateFromTimestamp($data['end_date'] / 1000); - - return CarbonPeriod::create($startDate, $endDate); + if (!is_array($dateData) || count($dateData) !== 2) { + return null; } - return null; + return CarbonPeriod::create($dateData[0], $dateData[1]); } - private function getDateFromTimestamp(float|int|string $timestamp): Carbon + public function normalize(mixed $value, Data $fieldDefinition): array { - $date = new Carbon(); - $date->setTimestamp($timestamp); + if (!$value instanceof CarbonPeriod) { + return []; + } - return $date; + return [ + $value->getStartDate(), + $value->getEndDate(), + ]; } } diff --git a/src/DataObject/Data/Adapter/EncryptedFieldAdapter.php b/src/DataObject/Data/Adapter/EncryptedFieldAdapter.php index 15431bad9..f3c00d482 100644 --- a/src/DataObject/Data/Adapter/EncryptedFieldAdapter.php +++ b/src/DataObject/Data/Adapter/EncryptedFieldAdapter.php @@ -93,7 +93,7 @@ private function handleDelegatedField( array $data, ?FieldContextData $contextData = null ): ?EncryptedField { - $adapter = $this->dataAdapterService->tryDataAdapter($fieldDefinition->getFieldType()); + $adapter = $this->dataAdapterService->tryDataAdapter($delegateFieldDefinition->getFieldType()); if ($adapter instanceof SetterDataInterface) { return new EncryptedField( $fieldDefinition->getDelegate(), diff --git a/src/DataObject/Data/Adapter/ExternalImageAdapter.php b/src/DataObject/Data/Adapter/ExternalImageAdapter.php index 7d801bd4d..b4ff8ad88 100644 --- a/src/DataObject/Data/Adapter/ExternalImageAdapter.php +++ b/src/DataObject/Data/Adapter/ExternalImageAdapter.php @@ -36,12 +36,9 @@ public function getDataForSetter( string $key, array $data, ?FieldContextData $contextData = null - ): ?string { - $imageData = $data[$key] ?? null; - if (!$imageData instanceof ExternalImage) { - return null; - } + ): ?ExternalImage { + $url = $data[$key]['url'] ?? null; - return $imageData->getUrl(); + return $url ? new ExternalImage($url) : null; } } diff --git a/src/DataObject/Data/Adapter/GeoBoundsAdapter.php b/src/DataObject/Data/Adapter/GeoBoundsAdapter.php index cb11289d3..c0a449fff 100644 --- a/src/DataObject/Data/Adapter/GeoBoundsAdapter.php +++ b/src/DataObject/Data/Adapter/GeoBoundsAdapter.php @@ -19,6 +19,7 @@ use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Model\FieldContextData; use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\SetterDataInterface; use Pimcore\Bundle\StudioBackendBundle\DataObject\Service\DataAdapterLoaderInterface; +use Pimcore\Bundle\StudioBackendBundle\Util\Constant\DataObject\Coordinates; use Pimcore\Model\DataObject\ClassDefinition\Data; use Pimcore\Model\DataObject\Concrete; use Pimcore\Model\DataObject\Data\Geobounds; @@ -32,6 +33,12 @@ #[AutoconfigureTag(DataAdapterLoaderInterface::ADAPTER_TAG)] final readonly class GeoBoundsAdapter implements SetterDataInterface { + private const string NORTH_EAST = 'northEast'; + + private const string SOUTH_WEST = 'southWest'; + + private const array DIRECTIONS = [self::NORTH_EAST, self::SOUTH_WEST]; + public function getDataForSetter( Concrete $element, Data $fieldDefinition, @@ -40,17 +47,37 @@ public function getDataForSetter( ?FieldContextData $contextData = null ): ?Geobounds { - $geoPointData = $data[$key]; - if (!is_array($geoPointData) || - $geoPointData['NElongitude'] === null || $geoPointData['NElatitude'] === null || - $geoPointData['SWlongitude'] === null || $geoPointData['SWlatitude'] === null - ) { + $geoBoundsData = $data[$key]; + if ($this->validateBounds($geoBoundsData) === false) { return null; } return new Geobounds( - new GeoCoordinates($data['NElatitude'], $data['NElongitude']), - new GeoCoordinates($data['SWlatitude'], $data['SWlongitude']) + new GeoCoordinates( + $geoBoundsData[self::NORTH_EAST][Coordinates::LATITUDE->value], + $geoBoundsData[self::NORTH_EAST][Coordinates::LONGITUDE->value] + ), + new GeoCoordinates( + $geoBoundsData[self::SOUTH_WEST][Coordinates::LATITUDE->value], + $geoBoundsData[self::SOUTH_WEST][Coordinates::LONGITUDE->value] + ) ); } + + private function validateBounds(array $data): bool + { + foreach (self::DIRECTIONS as $direction) { + if (!isset($data[$direction]) || !is_array($data[$direction])) { + return false; + } + + foreach (Coordinates::values() as $coordinate) { + if (empty($data[$direction][$coordinate])) { + return false; + } + } + } + + return true; + } } diff --git a/src/DataObject/Data/Adapter/GeoPointAdapter.php b/src/DataObject/Data/Adapter/GeoPointAdapter.php index ec493522d..24b1bc7a7 100644 --- a/src/DataObject/Data/Adapter/GeoPointAdapter.php +++ b/src/DataObject/Data/Adapter/GeoPointAdapter.php @@ -19,6 +19,7 @@ use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Model\FieldContextData; use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\SetterDataInterface; use Pimcore\Bundle\StudioBackendBundle\DataObject\Service\DataAdapterLoaderInterface; +use Pimcore\Bundle\StudioBackendBundle\Util\Constant\DataObject\Coordinates; use Pimcore\Model\DataObject\ClassDefinition\Data; use Pimcore\Model\DataObject\Concrete; use Pimcore\Model\DataObject\Data\GeoCoordinates; @@ -44,6 +45,9 @@ public function getDataForSetter( return null; } - return new GeoCoordinates($geoPointData['latitude'], $geoPointData['longitude']); + return new GeoCoordinates( + $geoPointData[Coordinates::LATITUDE->value], + $geoPointData[Coordinates::LONGITUDE->value] + ); } } diff --git a/src/DataObject/Data/Adapter/GeoPointsAdapter.php b/src/DataObject/Data/Adapter/GeoPointsAdapter.php index 82fc7b6ef..441cf6e49 100644 --- a/src/DataObject/Data/Adapter/GeoPointsAdapter.php +++ b/src/DataObject/Data/Adapter/GeoPointsAdapter.php @@ -19,6 +19,7 @@ use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Model\FieldContextData; use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\SetterDataInterface; use Pimcore\Bundle\StudioBackendBundle\DataObject\Service\DataAdapterLoaderInterface; +use Pimcore\Bundle\StudioBackendBundle\Util\Constant\DataObject\Coordinates; use Pimcore\Model\DataObject\ClassDefinition\Data; use Pimcore\Model\DataObject\Concrete; use Pimcore\Model\DataObject\Data\GeoCoordinates; @@ -48,8 +49,11 @@ public function getDataForSetter( } $points = []; - foreach ($data as $point) { - $points[] = new GeoCoordinates($point['latitude'], $point['longitude']); + foreach ($geoPointData as $point) { + $points[] = new GeoCoordinates( + $point[Coordinates::LATITUDE->value], + $point[Coordinates::LONGITUDE->value] + ); } return $points; diff --git a/src/DataObject/Data/Adapter/HotspotImageAdapter.php b/src/DataObject/Data/Adapter/HotspotImageAdapter.php index 0b9c9a252..b712a1876 100644 --- a/src/DataObject/Data/Adapter/HotspotImageAdapter.php +++ b/src/DataObject/Data/Adapter/HotspotImageAdapter.php @@ -52,19 +52,20 @@ public function getDataForSetter( ): ?Hotspotimage { $data = $data[$key]; + $imageId = !empty($data['image']['id']) && $data['image']['id'] > 0 ? $data['image']['id'] : null; + if ($imageId === null) { + return null; + } + $data['marker'] = $this->processData($data['marker'] ?? []); $data['hotspots'] = $this->processData($data['hotspots'] ?? []); - if (!empty($data['id']) && (int)$data['id'] > 0) { - return new Hotspotimage( - $data['id'], - $data['hotspots'], - $data['marker'], - $data['crop'] ?? [] - ); - } - - return null; + return new Hotspotimage( + $imageId, + $data['hotspots'], + $data['marker'], + $data['crop'] + ); } private function processData(array $data): array @@ -88,7 +89,7 @@ private function processMetaData(array $metaData): array $item = new MarkerHotspotItem($item); if ($this->isValidItem($item)) { try { - $element = $this->getElementByPath($this->serviceResolver, $item['type'], $item->getValue()); + $element = $this->getElement($this->serviceResolver, $item['type'], $item->getValue()); } catch (NotFoundException) { continue; } diff --git a/src/DataObject/Data/Adapter/InputQuantityValueAdapter.php b/src/DataObject/Data/Adapter/InputQuantityValueAdapter.php index 08a019a1b..c54d01bb9 100644 --- a/src/DataObject/Data/Adapter/InputQuantityValueAdapter.php +++ b/src/DataObject/Data/Adapter/InputQuantityValueAdapter.php @@ -19,7 +19,6 @@ use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Model\FieldContextData; use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\SetterDataInterface; use Pimcore\Bundle\StudioBackendBundle\DataObject\Service\DataAdapterLoaderInterface; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Util\Trait\DefaultSetterValueTrait; use Pimcore\Model\DataObject\ClassDefinition\Data; use Pimcore\Model\DataObject\Concrete; use Pimcore\Model\DataObject\Data\InputQuantityValue; @@ -31,8 +30,6 @@ #[AutoconfigureTag(DataAdapterLoaderInterface::ADAPTER_TAG)] final readonly class InputQuantityValueAdapter implements SetterDataInterface { - use DefaultSetterValueTrait; - public function getDataForSetter( Concrete $element, Data $fieldDefinition, @@ -41,7 +38,7 @@ public function getDataForSetter( ?FieldContextData $contextData = null ): ?InputQuantityValue { $value = $data[$key]['value'] ?? null; - $unit = $data[$key]['unit'] ?? null; + $unit = $data[$key]['unitId'] ?? null; if (!$value) { return null; diff --git a/src/DataObject/Data/Adapter/LocalizedFieldsAdapter.php b/src/DataObject/Data/Adapter/LocalizedFieldsAdapter.php index c7a5633c7..08269e85f 100644 --- a/src/DataObject/Data/Adapter/LocalizedFieldsAdapter.php +++ b/src/DataObject/Data/Adapter/LocalizedFieldsAdapter.php @@ -80,8 +80,8 @@ public function getDataForSetter( $localizedField = $this->getLocalizedField($contextData); $localizedField->setObject($element); - foreach ($languageData as $language => $fields) { - foreach ($fields as $name => $fieldData) { + foreach ($languageData as $name => $localizedData) { + foreach ($localizedData as $language => $fieldData) { $childFieldDefinition = $fieldDefinition->getFieldDefinition($name); if ($childFieldDefinition === null) { continue; diff --git a/src/DataObject/Data/Adapter/ManyToManyRelationAdapter.php b/src/DataObject/Data/Adapter/ManyToManyRelationAdapter.php index 5a5c8dc6e..084ecd633 100644 --- a/src/DataObject/Data/Adapter/ManyToManyRelationAdapter.php +++ b/src/DataObject/Data/Adapter/ManyToManyRelationAdapter.php @@ -24,6 +24,7 @@ use Pimcore\Bundle\StudioBackendBundle\DataObject\Service\DataAdapterLoaderInterface; use Pimcore\Bundle\StudioBackendBundle\DataObject\Util\Trait\RelationDataTrait; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\NotFoundException; +use Pimcore\Bundle\StudioBackendBundle\Util\Trait\ElementProviderTrait; use Pimcore\Model\DataObject\ClassDefinition\Data; use Pimcore\Model\DataObject\Concrete; use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag; @@ -35,6 +36,7 @@ #[AutoconfigureTag(DataAdapterLoaderInterface::ADAPTER_TAG)] final readonly class ManyToManyRelationAdapter implements SetterDataInterface, DataNormalizerInterface { + use ElementProviderTrait; use RelationDataTrait; public function __construct( diff --git a/src/DataObject/Data/Adapter/NumericAdapter.php b/src/DataObject/Data/Adapter/NumericAdapter.php index c39c1e266..dac002021 100644 --- a/src/DataObject/Data/Adapter/NumericAdapter.php +++ b/src/DataObject/Data/Adapter/NumericAdapter.php @@ -40,6 +40,6 @@ public function getDataForSetter( ?FieldContextData $contextData = null ): float|int|string|null { - return $this->getDefaultDataForSetter($element, $fieldDefinition, $key, $data); + return $this->getDefaultDataForSetter($fieldDefinition, $key, $data); } } diff --git a/src/DataObject/Data/Adapter/ObjectBricksAdapter.php b/src/DataObject/Data/Adapter/ObjectBricksAdapter.php index 58bf667ea..594224ca4 100644 --- a/src/DataObject/Data/Adapter/ObjectBricksAdapter.php +++ b/src/DataObject/Data/Adapter/ObjectBricksAdapter.php @@ -34,7 +34,6 @@ use Pimcore\Model\DataObject\Objectbrick\Data\AbstractData; use Pimcore\Model\DataObject\Objectbrick\Definition; use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag; -use function array_key_exists; /** * @internal @@ -70,9 +69,18 @@ public function getDataForSetter( } $brickData = $data[$key]; $container = $this->getContainer($element, $key, $fieldDefinition->getName(), $contextData); + $brickKeys = array_keys($brickData); - foreach ($brickData as $collectionRaw) { - $this->processBrickData($element, $container, $fieldDefinition, $collectionRaw); + foreach ($brickKeys as $brickKey) { + $brick = $this->getBrick($element, $container, $brickKey); + $brick->setFieldname($fieldDefinition->getName()); + $brickValue = $brickData[$brickKey]; + + if ($this->checkDeleteBrick($brick, $brickValue)) { + continue; + } + + $this->processBrickData($element, $container, $brick, $brickValue); } return $container; @@ -191,34 +199,28 @@ private function getBrick(Concrete $element, Objectbrick $container, string $bri private function processBrickData( Concrete $element, Objectbrick $container, - Data $fieldDefinition, - array $collectionRaw + AbstractData $brick, + array $brickValue ): void { - $collectionDef = $this->definitionResolver->getByKey($collectionRaw['type']); - if ($collectionDef === null) { - return; - } - - $brick = $this->getBrick($element, $container, $collectionRaw['type']); - $brick->setFieldname($fieldDefinition->getName()); - if ($collectionRaw['data'] === 'deleted') { - $brick->setDoDelete(true); + $brickKey = $brick->getType(); + $collectionDef = $this->definitionResolver->getByKey($brickKey); + if ($collectionDef === null) { return; } $brick->setValues($this->getCollectionData( $collectionDef, - $collectionRaw['data'], + $brickValue, $element, $brick, )); - $container->set($collectionRaw['type'], $brick); + $container->set($brickKey, $brick); } private function getCollectionData( Definition $collectionDef, - array $rawData, + array $brickValue, Concrete $element, AbstractData $brick ): array { @@ -226,7 +228,7 @@ private function getCollectionData( foreach ($collectionDef->getFieldDefinitions() as $fd) { $adapter = $this->dataAdapterService->tryDataAdapter($fd->getFieldType()); $fieldName = $fd->getName(); - if (!array_key_exists($fieldName, $rawData) || !$adapter) { + if (!$adapter) { continue; } @@ -234,7 +236,7 @@ private function getCollectionData( $element, $fd, $fieldName, - [$fieldName => $rawData[$fieldName]], + [$fieldName => $brickValue[$fieldName]], new FieldContextData($brick) ); if (!$this->validateEncryptedField($fd, $value)) { @@ -246,4 +248,16 @@ private function getCollectionData( return $collectionData; } + + private function checkDeleteBrick(AbstractData $brick, array $brickValue): bool + { + $action = $brickValue['action'] ?? null; + if ($action === 'deleted') { + $brick->setDoDelete(true); + + return true; + } + + return false; + } } diff --git a/src/DataObject/Data/Adapter/QuantityValueAdapter.php b/src/DataObject/Data/Adapter/QuantityValueAdapter.php index 0642013d8..9ad741e5f 100644 --- a/src/DataObject/Data/Adapter/QuantityValueAdapter.php +++ b/src/DataObject/Data/Adapter/QuantityValueAdapter.php @@ -19,7 +19,6 @@ use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Model\FieldContextData; use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\SetterDataInterface; use Pimcore\Bundle\StudioBackendBundle\DataObject\Service\DataAdapterLoaderInterface; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Util\Trait\DefaultSetterValueTrait; use Pimcore\Model\DataObject\ClassDefinition\Data; use Pimcore\Model\DataObject\Concrete; use Pimcore\Model\DataObject\Data\QuantityValue; @@ -31,8 +30,6 @@ #[AutoconfigureTag(DataAdapterLoaderInterface::ADAPTER_TAG)] final readonly class QuantityValueAdapter implements SetterDataInterface { - use DefaultSetterValueTrait; - public function getDataForSetter( Concrete $element, Data $fieldDefinition, @@ -41,7 +38,7 @@ public function getDataForSetter( ?FieldContextData $contextData = null ): ?QuantityValue { $value = $data[$key]['value'] ?? null; - $unit = $data[$key]['unit'] ?? null; + $unit = $data[$key]['unitId'] ?? null; if ($unit === -1) { $unit = null; diff --git a/src/DataObject/Data/Adapter/QuantityValueRangeAdapter.php b/src/DataObject/Data/Adapter/QuantityValueRangeAdapter.php index 502ceb151..7be5adee4 100644 --- a/src/DataObject/Data/Adapter/QuantityValueRangeAdapter.php +++ b/src/DataObject/Data/Adapter/QuantityValueRangeAdapter.php @@ -19,7 +19,6 @@ use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Model\FieldContextData; use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\SetterDataInterface; use Pimcore\Bundle\StudioBackendBundle\DataObject\Service\DataAdapterLoaderInterface; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Util\Trait\DefaultSetterValueTrait; use Pimcore\Model\DataObject\ClassDefinition\Data; use Pimcore\Model\DataObject\Concrete; use Pimcore\Model\DataObject\Data\QuantityValueRange; @@ -31,8 +30,6 @@ #[AutoconfigureTag(DataAdapterLoaderInterface::ADAPTER_TAG)] final readonly class QuantityValueRangeAdapter implements SetterDataInterface { - use DefaultSetterValueTrait; - public function getDataForSetter( Concrete $element, Data $fieldDefinition, @@ -42,7 +39,7 @@ public function getDataForSetter( ): ?QuantityValueRange { $min = empty($data[$key]['minimum']) ? null : $data[$key]['minimum']; $max = empty($data[$key]['maximum']) ? null : $data[$key]['maximum']; - $unit = $data[$key]['unit'] ?? null; + $unit = $data[$key]['unitId'] ?? null; if (!$min && !$max) { return null; diff --git a/src/DataObject/Data/Adapter/SelectAdapter.php b/src/DataObject/Data/Adapter/SelectAdapter.php index 1c31c2fc5..1496b166b 100644 --- a/src/DataObject/Data/Adapter/SelectAdapter.php +++ b/src/DataObject/Data/Adapter/SelectAdapter.php @@ -40,6 +40,6 @@ public function getDataForSetter( ?FieldContextData $contextData = null ): null|string|int { - return $this->getDefaultDataForSetter($element, $fieldDefinition, $key, $data); + return $this->getDefaultDataForSetter($fieldDefinition, $key, $data); } } diff --git a/src/DataObject/Data/Adapter/SliderAdapter.php b/src/DataObject/Data/Adapter/SliderAdapter.php index d742ae9b6..15a6aebae 100644 --- a/src/DataObject/Data/Adapter/SliderAdapter.php +++ b/src/DataObject/Data/Adapter/SliderAdapter.php @@ -40,6 +40,6 @@ public function getDataForSetter( ?FieldContextData $contextData = null ): ?float { - return $this->getDefaultDataForSetter($element, $fieldDefinition, $key, $data); + return $this->getDefaultDataForSetter($fieldDefinition, $key, $data); } } diff --git a/src/DataObject/Data/Adapter/StringAdapter.php b/src/DataObject/Data/Adapter/StringAdapter.php index 9ec32ca62..e0333f20a 100644 --- a/src/DataObject/Data/Adapter/StringAdapter.php +++ b/src/DataObject/Data/Adapter/StringAdapter.php @@ -43,6 +43,6 @@ public function getDataForSetter( return null; } - return $this->getDefaultDataForSetter($element, $fieldDefinition, $key, $data); + return $this->getDefaultDataForSetter($fieldDefinition, $key, $data); } } diff --git a/src/DataObject/Data/Adapter/StructuredTableAdapter.php b/src/DataObject/Data/Adapter/StructuredTableAdapter.php index d9ead2bb9..4fdba33ad 100644 --- a/src/DataObject/Data/Adapter/StructuredTableAdapter.php +++ b/src/DataObject/Data/Adapter/StructuredTableAdapter.php @@ -38,14 +38,13 @@ public function getDataForSetter( array $data, ?FieldContextData $contextData = null ): ?StructuredTable { - $table = new StructuredTable(); $tableData = []; - foreach ($data[$key] as $dataLine) { + foreach ($data[$key] as $id => $dataLine) { /** @var StructuredTableDefinition $fieldDefinition */ $cols = $fieldDefinition->getCols(); foreach ($cols as $col) { - $tableData[$dataLine['__row_identifyer']][$col['key']] = $dataLine[$col['key']]; + $tableData[$id][$col['key']] = $dataLine[$col['key']]; } } $table->setData($tableData); diff --git a/src/DataObject/Data/Adapter/UrlSlugAdapter.php b/src/DataObject/Data/Adapter/UrlSlugAdapter.php index 49a87eac4..498d93c92 100644 --- a/src/DataObject/Data/Adapter/UrlSlugAdapter.php +++ b/src/DataObject/Data/Adapter/UrlSlugAdapter.php @@ -23,7 +23,6 @@ use Pimcore\Model\DataObject\ClassDefinition\Data; use Pimcore\Model\DataObject\Concrete; use Pimcore\Model\DataObject\Data\UrlSlug; -use Pimcore\Model\Site; use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag; use function is_array; @@ -48,31 +47,13 @@ public function getDataForSetter( return []; } $result = []; - foreach ($urlData as $slug) { - if ($slug instanceof UrlSlug) { - $siteId = $slug->getSiteId(); - $resultItem = [ - 'slug' => $slug->getSlug(), - 'siteId' => $siteId, - 'domain' => $this->getDomain($siteId), - ]; + foreach ($urlData as $slugData) { + $siteId = $slugData['siteId']; + $slug = $slugData['slug']; - $result[$siteId] = $resultItem; - } + $result[$siteId] = new UrlSlug($slug, $siteId); } return $result; } - - /** - * @throws Exception - */ - private function getDomain(?int $siteId): ?string - { - if ($siteId === null) { - return null; - } - - return Site::getById($siteId)?->getMainDomain(); - } } diff --git a/src/DataObject/Data/Adapter/VideoAdapter.php b/src/DataObject/Data/Adapter/VideoAdapter.php index 535c8ba50..006009e0d 100644 --- a/src/DataObject/Data/Adapter/VideoAdapter.php +++ b/src/DataObject/Data/Adapter/VideoAdapter.php @@ -55,13 +55,12 @@ public function getDataForSetter( return null; } - $adapterData['data'] = $this->resolveAssetIfNeeded($adapterData['type'] ?? null, $adapterData['data']); - if ($adapterData['data'] === null) { - return null; + $type = $adapterData['type'] ?? null; + if ($type === ElementTypes::TYPE_ASSET) { + $adapterData['data'] = $this->resolveAssetIfNeeded($type, $adapterData['data']['fullPath']); + $adapterData['poster'] = $this->getAssetByPath($adapterData['poster'] ?? null); } - $adapterData['poster'] = $this->getAssetByPath($adapterData['poster'] ?? null); - return $this->createVideoObject($adapterData); } @@ -100,7 +99,8 @@ public function normalize(mixed $value, Data $fieldDefinition): mixed $data['poster']['fullPath'] = $value->getPoster()?->getRealFullPath(); } - if (isset($data['data'])) { + $type = $data['type'] ?? ''; + if (isset($data['data']) && $type === ElementTypes::TYPE_ASSET) { $data['data']['fullPath'] = $value->getData()?->getRealFullPath(); $data['data']['subtype'] = $value->getData()?->getType(); } diff --git a/src/DataObject/Service/PreviewUrlService.php b/src/DataObject/Service/PreviewUrlService.php index 68d1d700c..f611eb511 100644 --- a/src/DataObject/Service/PreviewUrlService.php +++ b/src/DataObject/Service/PreviewUrlService.php @@ -27,7 +27,7 @@ use Symfony\Component\HttpFoundation\RequestStack; /** - * @interal + * @internal */ final readonly class PreviewUrlService implements PreviewUrlServiceInterface { diff --git a/src/DataObject/Util/Trait/DefaultSetterValueTrait.php b/src/DataObject/Util/Trait/DefaultSetterValueTrait.php index c1d8dd2ae..e2808be9c 100644 --- a/src/DataObject/Util/Trait/DefaultSetterValueTrait.php +++ b/src/DataObject/Util/Trait/DefaultSetterValueTrait.php @@ -17,8 +17,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Util\Trait; use Pimcore\Model\DataObject\ClassDefinition\Data; -use Pimcore\Model\DataObject\ClassDefinition\Data\ResourcePersistenceAwareInterface; -use Pimcore\Model\DataObject\Concrete; +use Pimcore\Normalizer\NormalizerInterface; use function array_key_exists; /** @@ -26,13 +25,12 @@ */ trait DefaultSetterValueTrait { - public function getDefaultDataForSetter(Concrete $element, Data $fieldDefinition, string $key, array $data): mixed + public function getDefaultDataForSetter(Data $fieldDefinition, string $key, array $data): mixed { - if (!array_key_exists($key, $data)) { + if (!array_key_exists($key, $data) || !$fieldDefinition instanceof NormalizerInterface) { return null; } - /** @var ResourcePersistenceAwareInterface $fieldDefinition */ - return $fieldDefinition->getDataFromResource($data[$key], $element); + return $fieldDefinition->denormalize($data[$key]); } } diff --git a/src/Util/Constant/DataObject/ContainerTypes.php b/src/Util/Constant/DataObject/ContainerTypes.php index 463a25ebc..8576914f8 100644 --- a/src/Util/Constant/DataObject/ContainerTypes.php +++ b/src/Util/Constant/DataObject/ContainerTypes.php @@ -1,4 +1,5 @@