diff --git a/config/assets.yaml b/config/assets.yaml index 5a984165b..f156a954b 100644 --- a/config/assets.yaml +++ b/config/assets.yaml @@ -15,9 +15,6 @@ services: Pimcore\Bundle\StudioBackendBundle\Asset\Hydrator\CustomSettingsHydratorInterface: class: Pimcore\Bundle\StudioBackendBundle\Asset\Hydrator\CustomSettingsHydrator - Pimcore\Bundle\StudioBackendBundle\Asset\Hydrator\CustomMetadataHydratorInterface: - class: Pimcore\Bundle\StudioBackendBundle\Asset\Hydrator\CustomMetadataHydrator - # Encoder Pimcore\Bundle\StudioBackendBundle\Asset\Encoder\TextEncoderInterface: class: Pimcore\Bundle\StudioBackendBundle\Asset\Encoder\TextEncoder @@ -29,8 +26,7 @@ services: Pimcore\Bundle\StudioBackendBundle\Asset\Service\Data\CustomSettingsServiceInterface: class: Pimcore\Bundle\StudioBackendBundle\Asset\Service\Data\CustomSettingsService - Pimcore\Bundle\StudioBackendBundle\Asset\Service\Data\CustomMetadataServiceInterface: - class: Pimcore\Bundle\StudioBackendBundle\Asset\Service\Data\CustomMetadataService + Pimcore\Bundle\StudioBackendBundle\Asset\Service\Data\TextServiceInterface: class: Pimcore\Bundle\StudioBackendBundle\Asset\Service\Data\TextService @@ -73,21 +69,12 @@ services: Pimcore\Bundle\StudioBackendBundle\Asset\Updater\Adapter\ImageAdapter: tags: [ 'pimcore.studio_backend.update_adapter' ] - Pimcore\Bundle\StudioBackendBundle\Asset\Updater\Adapter\CustomMetadataAdapter: - tags: [ 'pimcore.studio_backend.update_adapter' ] - Pimcore\Bundle\StudioBackendBundle\Asset\Updater\Adapter\CustomSettingsAdapter: tags: [ 'pimcore.studio_backend.update_adapter' ] Pimcore\Bundle\StudioBackendBundle\Asset\Updater\Adapter\DataAdapter: tags: [ 'pimcore.studio_backend.update_adapter' ] - # - # Patcher - # - - Pimcore\Bundle\StudioBackendBundle\Asset\Patcher\Adapter\MetadataAdapter: - tags: [ 'pimcore.studio_backend.patch_adapter' ] # # Handler diff --git a/config/documents.yaml b/config/documents.yaml index 1bce398c9..f198214c6 100644 --- a/config/documents.yaml +++ b/config/documents.yaml @@ -4,6 +4,35 @@ services: autoconfigure: true public: false - # Secvices + # controllers are imported separately to make sure they're public + # and have a tag that allows actions to type-hint services + Pimcore\Bundle\StudioBackendBundle\Document\Controller\: + resource: '../src/Document/Controller' + public: true + tags: [ 'controller.service_arguments' ] + + # + # Services + # + Pimcore\Bundle\StudioBackendBundle\Document\Service\DocumentServiceInterface: - class: Pimcore\Bundle\StudioBackendBundle\Document\Service\DocumentService \ No newline at end of file + class: Pimcore\Bundle\StudioBackendBundle\Document\Service\DocumentService + + Pimcore\Bundle\StudioBackendBundle\Document\Service\SiteServiceInterface: + class: Pimcore\Bundle\StudioBackendBundle\Document\Service\SiteService + + + # + # Repositories + # + + Pimcore\Bundle\StudioBackendBundle\Document\Repository\SiteRepositoryInterface: + class: Pimcore\Bundle\StudioBackendBundle\Document\Repository\SiteRepository + + + # + # Hydrators + # + + Pimcore\Bundle\StudioBackendBundle\Document\Hydrator\SiteHydratorInterface: + class: Pimcore\Bundle\StudioBackendBundle\Document\Hydrator\SiteHydrator \ No newline at end of file diff --git a/config/metadata.yaml b/config/metadata.yaml index 45e448531..107d767c5 100644 --- a/config/metadata.yaml +++ b/config/metadata.yaml @@ -4,9 +4,30 @@ services: autoconfigure: true public: false - # - # Repository - # + # controllers are imported separately to make sure they're public + # and have a tag that allows actions to type-hint services + Pimcore\Bundle\StudioBackendBundle\Metadata\Controller\: + resource: '../src/Metadata/Controller' + public: true + tags: [ 'controller.service_arguments' ] + + # Service + Pimcore\Bundle\StudioBackendBundle\Metadata\Service\MetadataServiceInterface: + class: Pimcore\Bundle\StudioBackendBundle\Metadata\Service\MetadataService + + + # Hydrator + Pimcore\Bundle\StudioBackendBundle\Metadata\Hydrator\MetadataHydratorInterface: + class: Pimcore\Bundle\StudioBackendBundle\Metadata\Hydrator\MetadataHydrator + + # Repository Pimcore\Bundle\StudioBackendBundle\Metadata\Repository\MetadataRepositoryInterface: class: Pimcore\Bundle\StudioBackendBundle\Metadata\Repository\MetadataRepository + + Pimcore\Bundle\StudioBackendBundle\Metadata\Updater\Adapter\CustomMetadataAdapter: + tags: [ 'pimcore.studio_backend.update_adapter' ] + + # Patcher + Pimcore\Bundle\StudioBackendBundle\Metadata\Patcher\Adapter\CustomMetadataAdapter: + tags: [ 'pimcore.studio_backend.patch_adapter' ] diff --git a/src/Asset/Controller/Video/ImageThumbnailStreamController.php b/src/Asset/Controller/Video/ImageThumbnailStreamController.php index 200af814a..828c77ea8 100644 --- a/src/Asset/Controller/Video/ImageThumbnailStreamController.php +++ b/src/Asset/Controller/Video/ImageThumbnailStreamController.php @@ -81,7 +81,7 @@ public function __construct( operationId: 'asset_video_image_thumbnail_stream', description: 'asset_video_image_thumbnail_stream_description', summary: 'asset_video_image_thumbnail_stream_summary', - tags: [Tags::Assets->name] + tags: [Tags::Assets->value] )] #[IdParameter(type: 'video')] #[WidthParameter('Width of the video image thumbnail', 265)] diff --git a/src/DataObject/Data/Adapter/AdvancedManyToManyObjectRelationAdapter.php b/src/DataObject/Data/Adapter/AdvancedManyToManyObjectRelationAdapter.php index 308e30e54..ae5ca460c 100644 --- a/src/DataObject/Data/Adapter/AdvancedManyToManyObjectRelationAdapter.php +++ b/src/DataObject/Data/Adapter/AdvancedManyToManyObjectRelationAdapter.php @@ -17,7 +17,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; use Pimcore\Bundle\StaticResolverBundle\Models\DataObject\ConcreteObjectResolverInterface; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; diff --git a/src/DataObject/Data/Adapter/AdvancedManyToManyRelationAdapter.php b/src/DataObject/Data/Adapter/AdvancedManyToManyRelationAdapter.php index baee63971..9764a3b7b 100644 --- a/src/DataObject/Data/Adapter/AdvancedManyToManyRelationAdapter.php +++ b/src/DataObject/Data/Adapter/AdvancedManyToManyRelationAdapter.php @@ -18,7 +18,7 @@ use Exception; use Pimcore\Bundle\StaticResolverBundle\Models\Element\ServiceResolverInterface; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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\Trait\ElementProviderTrait; diff --git a/src/DataObject/Data/Adapter/BlockAdapter.php b/src/DataObject/Data/Adapter/BlockAdapter.php index 584eb9a1b..0b3599ba2 100644 --- a/src/DataObject/Data/Adapter/BlockAdapter.php +++ b/src/DataObject/Data/Adapter/BlockAdapter.php @@ -18,11 +18,12 @@ use Exception; use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\DataNormalizerInterface; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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\Service\DataAdapterServiceInterface; use Pimcore\Bundle\StudioBackendBundle\DataObject\Service\DataServiceInterface; +use Pimcore\Bundle\StudioBackendBundle\DataObject\Util\Trait\ValidateFieldTypeTrait; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidDataTypeException; use Pimcore\Model\DataObject\ClassDefinition\Data; use Pimcore\Model\DataObject\ClassDefinition\Data\Block; @@ -38,6 +39,8 @@ #[AutoconfigureTag(DataAdapterLoaderInterface::ADAPTER_TAG)] final readonly class BlockAdapter implements SetterDataInterface, DataNormalizerInterface { + use ValidateFieldTypeTrait; + public function __construct( private DataAdapterServiceInterface $dataAdapterService, private DataServiceInterface $dataService @@ -82,7 +85,7 @@ public function normalize( /** @var BlockElement $fieldValue */ foreach ($block as $key => $fieldValue) { $blockDefinition = $fieldDefinitions[$key]; - $resultItems[$key] = $this->dataService->getNormalizedValue( + $resultItem[$key] = $this->dataService->getNormalizedValue( $fieldValue->getData(), $blockDefinition, ); @@ -148,13 +151,24 @@ private function processBlockElement( $fieldContextData = $this->createFieldContextData($element, $fieldDefinition, $contextData); foreach ($fieldDefinitions as $elementName => $fd) { - $resultElement[$elementName] = $this->createBlockElement( + $adapter = $this->dataAdapterService->tryDataAdapter($fd->getFieldType()); + if (!$adapter) { + continue; + } + + $value = $this->createBlockElement( + $adapter, $element, $fd, $elementName, $blockElement, $fieldContextData ); + if (!$value) { + continue; + } + + $resultElement[$elementName] = $value; } return $resultElement; @@ -164,24 +178,37 @@ private function processBlockElement( * @throws Exception */ private function createBlockElement( + SetterDataInterface $adapter, Concrete $element, Data $fieldDefinition, string $elementName, ?array $blockElement, ?FieldContextData $fieldContextData = null - ): BlockElement { + ): ?BlockElement { $elementType = $fieldDefinition->getFieldtype(); $elementData = $blockElement[$elementName] ?? null; - $adapter = $this->dataAdapterService->getDataAdapter($elementType); - $blockData = $adapter->getDataForSetter( + $data = $adapter->getDataForSetter( $element, $fieldDefinition, $elementName, [$elementName => $elementData], $fieldContextData ); + if (!$this->validateEncryptedField($fieldDefinition, $data)) { + return null; + } - return new BlockElement($elementName, $elementType, $blockData); + return new BlockElement( + $elementName, + $elementType, + $adapter->getDataForSetter( + $element, + $fieldDefinition, + $elementName, + [$elementName => $elementData], + $fieldContextData + ) + ); } } diff --git a/src/DataObject/Data/Adapter/BooleanAdapter.php b/src/DataObject/Data/Adapter/BooleanAdapter.php index fe4577e5b..6b9ab8b98 100644 --- a/src/DataObject/Data/Adapter/BooleanAdapter.php +++ b/src/DataObject/Data/Adapter/BooleanAdapter.php @@ -16,7 +16,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; diff --git a/src/DataObject/Data/Adapter/CalculatedValueAdapter.php b/src/DataObject/Data/Adapter/CalculatedValueAdapter.php index 116a00706..0e85d5140 100644 --- a/src/DataObject/Data/Adapter/CalculatedValueAdapter.php +++ b/src/DataObject/Data/Adapter/CalculatedValueAdapter.php @@ -16,7 +16,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; diff --git a/src/DataObject/Data/Adapter/CheckboxAdapter.php b/src/DataObject/Data/Adapter/CheckboxAdapter.php index b8be6a3e8..e2827d285 100644 --- a/src/DataObject/Data/Adapter/CheckboxAdapter.php +++ b/src/DataObject/Data/Adapter/CheckboxAdapter.php @@ -16,7 +16,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; diff --git a/src/DataObject/Data/Adapter/ClassificationStoreAdapter.php b/src/DataObject/Data/Adapter/ClassificationStoreAdapter.php index 5392f4e37..d13ce3682 100644 --- a/src/DataObject/Data/Adapter/ClassificationStoreAdapter.php +++ b/src/DataObject/Data/Adapter/ClassificationStoreAdapter.php @@ -23,11 +23,12 @@ use Pimcore\Bundle\StaticResolverBundle\Models\DataObject\ClassificationStore\GroupConfigResolverInterface; use Pimcore\Bundle\StaticResolverBundle\Models\DataObject\ClassificationStore\ServiceResolverInterface; use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\DataNormalizerInterface; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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\Service\DataAdapterServiceInterface; use Pimcore\Bundle\StudioBackendBundle\DataObject\Service\DataServiceInterface; +use Pimcore\Bundle\StudioBackendBundle\DataObject\Util\Trait\ValidateFieldTypeTrait; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\DatabaseException; use Pimcore\Model\DataObject\ClassDefinition\Data; use Pimcore\Model\DataObject\ClassDefinition\Data\Classificationstore as ClassificationstoreDefinition; @@ -47,6 +48,8 @@ #[AutoconfigureTag(DataAdapterLoaderInterface::ADAPTER_TAG)] final readonly class ClassificationStoreAdapter implements SetterDataInterface, DataNormalizerInterface { + use ValidateFieldTypeTrait; + public function __construct( private DefinitionCacheResolverInterface $definitionCacheResolver, private DataAdapterServiceInterface $dataAdapterService, @@ -182,13 +185,20 @@ private function processGroupKeys( continue; } - $adapter = $this->dataAdapterService->getDataAdapter($fieldDefinition->getFieldType()); + $adapter = $this->dataAdapterService->tryDataAdapter($fieldDefinition->getFieldType()); + if ($adapter === null) { + continue; + } + $setterData = $adapter->getDataForSetter( $element, $fieldDefinition, $fieldDefinition->getName(), [$fieldDefinition->getName() => $value] ); + if (!$this->validateEncryptedField($fieldDefinition, $setterData)) { + continue; + } $container->setLocalizedKeyValue($groupId, $keyId, $setterData, $language); } diff --git a/src/DataObject/Data/Adapter/ConsentAdapter.php b/src/DataObject/Data/Adapter/ConsentAdapter.php index 75b160aa1..6d546b980 100644 --- a/src/DataObject/Data/Adapter/ConsentAdapter.php +++ b/src/DataObject/Data/Adapter/ConsentAdapter.php @@ -17,7 +17,9 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; use Exception; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\DataNormalizerInterface; +use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Model\ConsentData; +use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Model\FieldContextData; use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\SetterDataInterface; use Pimcore\Bundle\StudioBackendBundle\DataObject\Service\DataAdapterLoaderInterface; use Pimcore\DataObject\Consent\Service; @@ -30,7 +32,7 @@ * @internal */ #[AutoconfigureTag(DataAdapterLoaderInterface::ADAPTER_TAG)] -final readonly class ConsentAdapter implements SetterDataInterface +final readonly class ConsentAdapter implements SetterDataInterface, DataNormalizerInterface { public function __construct( private Service $service @@ -76,4 +78,19 @@ public function getDataForSetter( return new Consent($value, $noteId); } + + public function normalize( + mixed $value, + Data $fieldDefinition + ): ?ConsentData { + if (!$value instanceof Consent) { + return null; + } + + return new ConsentData( + $value->getConsent(), + $value->getNoteId(), + $value->getSummaryString(), + ); + } } diff --git a/src/DataObject/Data/Adapter/DateAdapter.php b/src/DataObject/Data/Adapter/DateAdapter.php index c251c8ad4..57cf688e4 100644 --- a/src/DataObject/Data/Adapter/DateAdapter.php +++ b/src/DataObject/Data/Adapter/DateAdapter.php @@ -17,7 +17,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; use Carbon\Carbon; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; diff --git a/src/DataObject/Data/Adapter/DateRangeAdapter.php b/src/DataObject/Data/Adapter/DateRangeAdapter.php index 08bd982be..8cdfbabe2 100644 --- a/src/DataObject/Data/Adapter/DateRangeAdapter.php +++ b/src/DataObject/Data/Adapter/DateRangeAdapter.php @@ -18,7 +18,7 @@ use Carbon\Carbon; use Carbon\CarbonPeriod; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; diff --git a/src/DataObject/Data/Adapter/EncryptedFieldAdapter.php b/src/DataObject/Data/Adapter/EncryptedFieldAdapter.php index 89c7ec625..c150709c1 100644 --- a/src/DataObject/Data/Adapter/EncryptedFieldAdapter.php +++ b/src/DataObject/Data/Adapter/EncryptedFieldAdapter.php @@ -16,11 +16,12 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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\Service\DataAdapterServiceInterface; use Pimcore\Model\DataObject\ClassDefinition\Data; +use Pimcore\Model\DataObject\ClassDefinition\Data\EncryptedField as EncryptedFieldDefinition; use Pimcore\Model\DataObject\Concrete; use Pimcore\Model\DataObject\Data\EncryptedField; use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag; @@ -43,7 +44,7 @@ public function getDataForSetter( array $data, ?FieldContextData $contextData = null ): ?EncryptedField { - if (!($fieldDefinition instanceof Data\EncryptedField)) { + if (!$fieldDefinition instanceof EncryptedFieldDefinition) { return null; } @@ -51,9 +52,33 @@ public function getDataForSetter( if (!$delegateFieldDefinition) { return null; } - $adapter = $this->dataAdapterService->getDataAdapter($delegateFieldDefinition->getFieldType()); - $result = $adapter->getDataForSetter($element, $delegateFieldDefinition, $key, $data); - return new EncryptedField($fieldDefinition->getDelegate(), $result); + return $this->handleDelegatedField( + $element, + $delegateFieldDefinition, + $fieldDefinition, + $key, + $data, + $contextData + ); + } + + private function handleDelegatedField( + Concrete $element, + Data $delegateFieldDefinition, + EncryptedFieldDefinition $fieldDefinition, + string $key, + array $data, + ?FieldContextData $contextData = null + ): ?EncryptedField { + $adapter = $this->dataAdapterService->tryDataAdapter($fieldDefinition->getFieldType()); + if ($adapter instanceof SetterDataInterface) { + return new EncryptedField( + $fieldDefinition->getDelegate(), + $adapter->getDataForSetter($element, $delegateFieldDefinition, $key, $data, $contextData) + ); + } + + return null; } } diff --git a/src/DataObject/Data/Adapter/ExternalImageAdapter.php b/src/DataObject/Data/Adapter/ExternalImageAdapter.php index bfc7bc925..7d801bd4d 100644 --- a/src/DataObject/Data/Adapter/ExternalImageAdapter.php +++ b/src/DataObject/Data/Adapter/ExternalImageAdapter.php @@ -16,7 +16,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; diff --git a/src/DataObject/Data/Adapter/FieldCollectionsAdapter.php b/src/DataObject/Data/Adapter/FieldCollectionsAdapter.php index 6a314767e..434e0276b 100644 --- a/src/DataObject/Data/Adapter/FieldCollectionsAdapter.php +++ b/src/DataObject/Data/Adapter/FieldCollectionsAdapter.php @@ -19,11 +19,12 @@ use Exception; use Pimcore\Bundle\StaticResolverBundle\Models\DataObject\FieldCollection\DefinitionResolverInterface; use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\DataNormalizerInterface; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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\Service\DataAdapterServiceInterface; use Pimcore\Bundle\StudioBackendBundle\DataObject\Service\DataServiceInterface; +use Pimcore\Bundle\StudioBackendBundle\DataObject\Util\Trait\ValidateFieldTypeTrait; use Pimcore\Model\DataObject\ClassDefinition\Data; use Pimcore\Model\DataObject\ClassDefinition\Data\Fieldcollections; use Pimcore\Model\DataObject\Concrete; @@ -38,6 +39,12 @@ #[AutoconfigureTag(DataAdapterLoaderInterface::ADAPTER_TAG)] final readonly class FieldCollectionsAdapter implements SetterDataInterface, DataNormalizerInterface { + use ValidateFieldTypeTrait; + + private const TYPE_KEY = 'type'; + + private const DATA_KEY = 'data'; + public function __construct( private DataAdapterServiceInterface $dataAdapterService, private DataServiceInterface $dataService, @@ -69,7 +76,7 @@ public function getDataForSetter( $collection = $this->createCollection( $element, $fieldDefinition, - $collectionRaw['type'], + $collectionRaw[self::TYPE_KEY], $collectionData, $count ); @@ -97,15 +104,13 @@ public function normalize( if (!$fieldCollectionDefinition) { continue; } - $resultItem = ['type' => $type]; + $resultItem = [self::TYPE_KEY => $type, self::DATA_KEY => []]; foreach ($fieldCollectionDefinition->getFieldDefinitions() as $collectionFieldDefinition) { $getter = 'get' . ucfirst($collectionFieldDefinition->getName()); $value = $item->$getter(); - $resultItem[$collectionFieldDefinition->getName()] = $this->dataService->getNormalizedValue( - $value, - $collectionFieldDefinition, - ); + $resultItem[self::DATA_KEY][$collectionFieldDefinition->getName()] = + $this->dataService->getNormalizedValue($value, $collectionFieldDefinition); } $resultItems[] = $resultItem; @@ -146,18 +151,23 @@ private function processCollectionRaw( foreach ($collectionDef?->getFieldDefinitions() as $elementName => $fd) { $elementValue = $blockElement[$elementName] ?? null; - if (!$elementValue) { + $adapter = $this->dataAdapterService->tryDataAdapter($fd->getFieldType()); + if (!$elementValue || !$adapter) { continue; } - $adapter = $this->dataAdapterService->getDataAdapter($fd->getFieldType()); - $collectionData[$elementName] = $adapter->getDataForSetter( + $value = $adapter->getDataForSetter( $element, $fd, $elementName, [$elementName => $elementValue], $fieldContextData ); + if (!$this->validateEncryptedField($fieldDefinition, $value)) { + continue; + } + + $collectionData[$elementName] = $value; } return $collectionData; diff --git a/src/DataObject/Data/Adapter/GeoBoundsAdapter.php b/src/DataObject/Data/Adapter/GeoBoundsAdapter.php index d9c375664..cb11289d3 100644 --- a/src/DataObject/Data/Adapter/GeoBoundsAdapter.php +++ b/src/DataObject/Data/Adapter/GeoBoundsAdapter.php @@ -16,7 +16,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; diff --git a/src/DataObject/Data/Adapter/GeoPointAdapter.php b/src/DataObject/Data/Adapter/GeoPointAdapter.php index 3ac692810..ec493522d 100644 --- a/src/DataObject/Data/Adapter/GeoPointAdapter.php +++ b/src/DataObject/Data/Adapter/GeoPointAdapter.php @@ -16,7 +16,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; diff --git a/src/DataObject/Data/Adapter/GeoPointsAdapter.php b/src/DataObject/Data/Adapter/GeoPointsAdapter.php index 829cde79e..82fc7b6ef 100644 --- a/src/DataObject/Data/Adapter/GeoPointsAdapter.php +++ b/src/DataObject/Data/Adapter/GeoPointsAdapter.php @@ -16,7 +16,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; diff --git a/src/DataObject/Data/Adapter/HotspotImageAdapter.php b/src/DataObject/Data/Adapter/HotspotImageAdapter.php index c2c23a1be..0b9c9a252 100644 --- a/src/DataObject/Data/Adapter/HotspotImageAdapter.php +++ b/src/DataObject/Data/Adapter/HotspotImageAdapter.php @@ -17,7 +17,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; use Pimcore\Bundle\StaticResolverBundle\Models\Element\ServiceResolverInterface; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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\Exception\Api\NotFoundException; diff --git a/src/DataObject/Data/Adapter/ImageAdapter.php b/src/DataObject/Data/Adapter/ImageAdapter.php index 10076b0d9..1e4aee60a 100644 --- a/src/DataObject/Data/Adapter/ImageAdapter.php +++ b/src/DataObject/Data/Adapter/ImageAdapter.php @@ -17,7 +17,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; use Pimcore\Bundle\StaticResolverBundle\Models\Asset\AssetResolverInterface; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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\Trait\ElementProviderTrait; diff --git a/src/DataObject/Data/Adapter/ImageGalleryAdapter.php b/src/DataObject/Data/Adapter/ImageGalleryAdapter.php index 56d49e218..afbe06d81 100644 --- a/src/DataObject/Data/Adapter/ImageGalleryAdapter.php +++ b/src/DataObject/Data/Adapter/ImageGalleryAdapter.php @@ -16,7 +16,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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\Trait\ElementProviderTrait; diff --git a/src/DataObject/Data/Adapter/InputQuantityValueAdapter.php b/src/DataObject/Data/Adapter/InputQuantityValueAdapter.php index 8052080df..08a019a1b 100644 --- a/src/DataObject/Data/Adapter/InputQuantityValueAdapter.php +++ b/src/DataObject/Data/Adapter/InputQuantityValueAdapter.php @@ -16,7 +16,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; diff --git a/src/DataObject/Data/Adapter/LinkAdapter.php b/src/DataObject/Data/Adapter/LinkAdapter.php index 08dc7180b..84377dcf7 100644 --- a/src/DataObject/Data/Adapter/LinkAdapter.php +++ b/src/DataObject/Data/Adapter/LinkAdapter.php @@ -17,7 +17,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; use Exception; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; diff --git a/src/DataObject/Data/Adapter/LocalizedFieldsAdapter.php b/src/DataObject/Data/Adapter/LocalizedFieldsAdapter.php index 6891020b3..fa2ce28cf 100644 --- a/src/DataObject/Data/Adapter/LocalizedFieldsAdapter.php +++ b/src/DataObject/Data/Adapter/LocalizedFieldsAdapter.php @@ -18,11 +18,12 @@ use Exception; use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\DataNormalizerInterface; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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\Service\DataAdapterServiceInterface; use Pimcore\Bundle\StudioBackendBundle\DataObject\Service\DataServiceInterface; +use Pimcore\Bundle\StudioBackendBundle\DataObject\Util\Trait\ValidateFieldTypeTrait; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\DatabaseException; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException; use Pimcore\Bundle\StudioBackendBundle\Security\Service\SecurityServiceInterface; @@ -43,6 +44,8 @@ #[AutoconfigureTag(DataAdapterLoaderInterface::ADAPTER_TAG)] final readonly class LocalizedFieldsAdapter implements SetterDataInterface, DataNormalizerInterface { + use ValidateFieldTypeTrait; + public function __construct( private DataAdapterServiceInterface $dataAdapterService, private DataServiceInterface $dataService, @@ -75,18 +78,23 @@ public function getDataForSetter( continue; } - $adapter = $this->dataAdapterService->getDataAdapter($childFieldDefinition->getFieldType()); - $localizedField->setLocalizedValue( + $adapter = $this->dataAdapterService->tryDataAdapter($childFieldDefinition->getFieldType()); + if (!$adapter) { + continue; + } + + $value = $adapter->getDataForSetter( + $element, + $childFieldDefinition, $name, - $adapter->getDataForSetter( - $element, - $childFieldDefinition, - $name, - [$name => $fieldData], - new FieldContextData(language: $language) - ), - $language + [$name => $fieldData], + new FieldContextData(language: $language) ); + if (!$this->validateEncryptedField($childFieldDefinition, $value)) { + continue; + } + + $localizedField->setLocalizedValue($name, $value, $language); } } diff --git a/src/DataObject/Data/Adapter/ManyToManyObjectRelationAdapter.php b/src/DataObject/Data/Adapter/ManyToManyObjectRelationAdapter.php index ba88a9b41..d65622a10 100644 --- a/src/DataObject/Data/Adapter/ManyToManyObjectRelationAdapter.php +++ b/src/DataObject/Data/Adapter/ManyToManyObjectRelationAdapter.php @@ -17,7 +17,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; use Pimcore\Bundle\StaticResolverBundle\Models\DataObject\ConcreteObjectResolverInterface; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; diff --git a/src/DataObject/Data/Adapter/ManyToManyRelationAdapter.php b/src/DataObject/Data/Adapter/ManyToManyRelationAdapter.php index 35ab54fe1..8c679f8fe 100644 --- a/src/DataObject/Data/Adapter/ManyToManyRelationAdapter.php +++ b/src/DataObject/Data/Adapter/ManyToManyRelationAdapter.php @@ -18,8 +18,8 @@ use Pimcore\Bundle\StaticResolverBundle\Models\Element\ServiceResolverInterface; use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\DataNormalizerInterface; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\RelationData; +use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Model\FieldContextData; +use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Model\RelationData; use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\SetterDataInterface; use Pimcore\Bundle\StudioBackendBundle\DataObject\Service\DataAdapterLoaderInterface; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\NotFoundException; @@ -78,7 +78,7 @@ public function normalize( $relation->getId(), $elementType, $this->getSubType($relation), - $relation->getFullPath(), + $relation->getRealFullPath(), $this->getPublished($relation) ); } diff --git a/src/DataObject/Data/Adapter/ManyToOneRelationAdapter.php b/src/DataObject/Data/Adapter/ManyToOneRelationAdapter.php index 0ce6cd906..5a93423bb 100644 --- a/src/DataObject/Data/Adapter/ManyToOneRelationAdapter.php +++ b/src/DataObject/Data/Adapter/ManyToOneRelationAdapter.php @@ -17,7 +17,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; use Pimcore\Bundle\StaticResolverBundle\Models\Element\ServiceResolverInterface; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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\Exception\Api\NotFoundException; diff --git a/src/DataObject/Data/Adapter/MultiSelectAdapter.php b/src/DataObject/Data/Adapter/MultiSelectAdapter.php index ae40c4531..b17cd25ec 100644 --- a/src/DataObject/Data/Adapter/MultiSelectAdapter.php +++ b/src/DataObject/Data/Adapter/MultiSelectAdapter.php @@ -16,7 +16,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; diff --git a/src/DataObject/Data/Adapter/NumericAdapter.php b/src/DataObject/Data/Adapter/NumericAdapter.php index a09632d27..c39c1e266 100644 --- a/src/DataObject/Data/Adapter/NumericAdapter.php +++ b/src/DataObject/Data/Adapter/NumericAdapter.php @@ -16,7 +16,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; diff --git a/src/DataObject/Data/Adapter/NumericRangeAdapter.php b/src/DataObject/Data/Adapter/NumericRangeAdapter.php index ad6469ea8..d8fc8844c 100644 --- a/src/DataObject/Data/Adapter/NumericRangeAdapter.php +++ b/src/DataObject/Data/Adapter/NumericRangeAdapter.php @@ -16,7 +16,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; diff --git a/src/DataObject/Data/Adapter/ObjectBricksAdapter.php b/src/DataObject/Data/Adapter/ObjectBricksAdapter.php index a1b15656e..64a04ae72 100644 --- a/src/DataObject/Data/Adapter/ObjectBricksAdapter.php +++ b/src/DataObject/Data/Adapter/ObjectBricksAdapter.php @@ -19,11 +19,12 @@ use Exception; use Pimcore\Bundle\StaticResolverBundle\Models\DataObject\Objectbrick\DefinitionResolverInterface; use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\DataNormalizerInterface; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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\Service\DataAdapterServiceInterface; use Pimcore\Bundle\StudioBackendBundle\DataObject\Service\DataServiceInterface; +use Pimcore\Bundle\StudioBackendBundle\DataObject\Util\Trait\ValidateFieldTypeTrait; use Pimcore\Model\DataObject\ClassDefinition\Data; use Pimcore\Model\DataObject\ClassDefinition\Data\Objectbricks; use Pimcore\Model\DataObject\Concrete; @@ -39,6 +40,8 @@ #[AutoconfigureTag(DataAdapterLoaderInterface::ADAPTER_TAG)] final readonly class ObjectBricksAdapter implements SetterDataInterface, DataNormalizerInterface { + use ValidateFieldTypeTrait; + public function __construct( private DataAdapterServiceInterface $dataAdapterService, private DataServiceInterface $dataService, @@ -177,19 +180,24 @@ private function getCollectionData( ): array { $collectionData = []; foreach ($collectionDef->getFieldDefinitions() as $fd) { + $adapter = $this->dataAdapterService->tryDataAdapter($fd->getFieldType()); $fieldName = $fd->getName(); - if (!array_key_exists($fieldName, $rawData)) { + if (!array_key_exists($fieldName, $rawData) || !$adapter) { continue; } - $adapter = $this->dataAdapterService->getDataAdapter($fd->getFieldType()); - $collectionData[$fd->getName()] = $adapter->getDataForSetter( + $value = $adapter->getDataForSetter( $element, $fd, $fieldName, [$fieldName => $rawData[$fieldName]], new FieldContextData($brick) ); + if (!$this->validateEncryptedField($fd, $value)) { + continue; + } + + $collectionData[$fieldName] = $value; } return $collectionData; diff --git a/src/DataObject/Data/Adapter/QuantityValueAdapter.php b/src/DataObject/Data/Adapter/QuantityValueAdapter.php index 4c510f07f..0642013d8 100644 --- a/src/DataObject/Data/Adapter/QuantityValueAdapter.php +++ b/src/DataObject/Data/Adapter/QuantityValueAdapter.php @@ -16,7 +16,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; diff --git a/src/DataObject/Data/Adapter/QuantityValueRangeAdapter.php b/src/DataObject/Data/Adapter/QuantityValueRangeAdapter.php index da130f3a1..502ceb151 100644 --- a/src/DataObject/Data/Adapter/QuantityValueRangeAdapter.php +++ b/src/DataObject/Data/Adapter/QuantityValueRangeAdapter.php @@ -16,7 +16,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; diff --git a/src/DataObject/Data/Adapter/ReverseObjectRelationAdapter.php b/src/DataObject/Data/Adapter/ReverseObjectRelationAdapter.php index a0cd40e15..53d9c60d1 100644 --- a/src/DataObject/Data/Adapter/ReverseObjectRelationAdapter.php +++ b/src/DataObject/Data/Adapter/ReverseObjectRelationAdapter.php @@ -19,7 +19,7 @@ use Exception; use Pimcore\Bundle\StaticResolverBundle\Models\DataObject\ClassDefinitionResolverInterface; use Pimcore\Bundle\StaticResolverBundle\Models\DataObject\ConcreteObjectResolverInterface; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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\Security\Service\SecurityServiceInterface; diff --git a/src/DataObject/Data/Adapter/RgbaColorAdapter.php b/src/DataObject/Data/Adapter/RgbaColorAdapter.php index 11e7b6d3a..294e15feb 100644 --- a/src/DataObject/Data/Adapter/RgbaColorAdapter.php +++ b/src/DataObject/Data/Adapter/RgbaColorAdapter.php @@ -16,7 +16,8 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; @@ -28,7 +29,7 @@ * @internal */ #[AutoconfigureTag(DataAdapterLoaderInterface::ADAPTER_TAG)] -final readonly class RgbaColorAdapter implements SetterDataInterface +final readonly class RgbaColorAdapter implements SetterDataInterface, DataNormalizerInterface { public function getDataForSetter( Concrete $element, @@ -43,4 +44,15 @@ public function getDataForSetter( return new RgbaColor($r, $g, $b, $a); } + + public function normalize( + mixed $value, + Data $fieldDefinition + ): ?string { + if (!$value instanceof RgbaColor) { + return null; + } + + return $value->getHex(true); + } } diff --git a/src/DataObject/Data/Adapter/SelectAdapter.php b/src/DataObject/Data/Adapter/SelectAdapter.php index 06f7569b5..1c31c2fc5 100644 --- a/src/DataObject/Data/Adapter/SelectAdapter.php +++ b/src/DataObject/Data/Adapter/SelectAdapter.php @@ -16,7 +16,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; diff --git a/src/DataObject/Data/Adapter/SliderAdapter.php b/src/DataObject/Data/Adapter/SliderAdapter.php index eaa7ddd80..d742ae9b6 100644 --- a/src/DataObject/Data/Adapter/SliderAdapter.php +++ b/src/DataObject/Data/Adapter/SliderAdapter.php @@ -16,7 +16,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; diff --git a/src/DataObject/Data/Adapter/StringAdapter.php b/src/DataObject/Data/Adapter/StringAdapter.php index d49be5830..9ec32ca62 100644 --- a/src/DataObject/Data/Adapter/StringAdapter.php +++ b/src/DataObject/Data/Adapter/StringAdapter.php @@ -16,7 +16,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; diff --git a/src/DataObject/Data/Adapter/StructuredTableAdapter.php b/src/DataObject/Data/Adapter/StructuredTableAdapter.php index 7721b4e99..d9ead2bb9 100644 --- a/src/DataObject/Data/Adapter/StructuredTableAdapter.php +++ b/src/DataObject/Data/Adapter/StructuredTableAdapter.php @@ -16,7 +16,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; diff --git a/src/DataObject/Data/Adapter/TableAdapter.php b/src/DataObject/Data/Adapter/TableAdapter.php index 5c5263788..bfabf655d 100644 --- a/src/DataObject/Data/Adapter/TableAdapter.php +++ b/src/DataObject/Data/Adapter/TableAdapter.php @@ -17,7 +17,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; use Exception; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; diff --git a/src/DataObject/Data/Adapter/UrlSlugAdapter.php b/src/DataObject/Data/Adapter/UrlSlugAdapter.php index 996449c18..49a87eac4 100644 --- a/src/DataObject/Data/Adapter/UrlSlugAdapter.php +++ b/src/DataObject/Data/Adapter/UrlSlugAdapter.php @@ -17,7 +17,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; use Exception; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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; diff --git a/src/DataObject/Data/Adapter/VideoAdapter.php b/src/DataObject/Data/Adapter/VideoAdapter.php index 3f697ed92..fc020d114 100644 --- a/src/DataObject/Data/Adapter/VideoAdapter.php +++ b/src/DataObject/Data/Adapter/VideoAdapter.php @@ -17,7 +17,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Adapter; use Pimcore\Bundle\StaticResolverBundle\Models\Asset\AssetResolverInterface; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\FieldContextData; +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\ElementTypes; diff --git a/src/DataObject/Data/ClassData.php b/src/DataObject/Data/Model/ClassData.php similarity index 94% rename from src/DataObject/Data/ClassData.php rename to src/DataObject/Data/Model/ClassData.php index 4ca473a7f..376bf2c5c 100644 --- a/src/DataObject/Data/ClassData.php +++ b/src/DataObject/Data/Model/ClassData.php @@ -14,7 +14,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data; +namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Model; /** * @internal diff --git a/src/DataObject/Data/Model/ConsentData.php b/src/DataObject/Data/Model/ConsentData.php new file mode 100644 index 000000000..4aaa66b9a --- /dev/null +++ b/src/DataObject/Data/Model/ConsentData.php @@ -0,0 +1,45 @@ +consent; + } + + public function getNoteId(): ?int + { + return $this->noteId; + } + + public function getNoteContent(): string + { + return $this->noteContent; + } +} diff --git a/src/DataObject/Data/FieldContextData.php b/src/DataObject/Data/Model/FieldContextData.php similarity index 96% rename from src/DataObject/Data/FieldContextData.php rename to src/DataObject/Data/Model/FieldContextData.php index cb1b2d18a..519431d0e 100644 --- a/src/DataObject/Data/FieldContextData.php +++ b/src/DataObject/Data/Model/FieldContextData.php @@ -14,7 +14,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data; +namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Model; use Pimcore\Model\DataObject\Data\BlockElement; use Pimcore\Model\DataObject\Fieldcollection; diff --git a/src/DataObject/Data/RelationData.php b/src/DataObject/Data/Model/RelationData.php similarity index 94% rename from src/DataObject/Data/RelationData.php rename to src/DataObject/Data/Model/RelationData.php index 97e3297fa..58a0097e2 100644 --- a/src/DataObject/Data/RelationData.php +++ b/src/DataObject/Data/Model/RelationData.php @@ -14,7 +14,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data; +namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Model; /** * @internal diff --git a/src/DataObject/Data/SetterDataInterface.php b/src/DataObject/Data/SetterDataInterface.php index 8183a5312..2def3854f 100644 --- a/src/DataObject/Data/SetterDataInterface.php +++ b/src/DataObject/Data/SetterDataInterface.php @@ -16,6 +16,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Data; +use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Model\FieldContextData; use Pimcore\Model\DataObject\ClassDefinition\Data; use Pimcore\Model\DataObject\Concrete; diff --git a/src/DataObject/Service/DataAdapterService.php b/src/DataObject/Service/DataAdapterService.php index cac29b63f..76813f0aa 100644 --- a/src/DataObject/Service/DataAdapterService.php +++ b/src/DataObject/Service/DataAdapterService.php @@ -54,10 +54,23 @@ public function getFieldDefinitionAdapterClass(string $fieldDefinitionType): str ); } + /** + * @throws InvalidArgumentException + */ public function getDataAdapter(string $fieldDefinitionType): SetterDataInterface { return $this->dataAdapterLoader->loadAdapter( $this->getFieldDefinitionAdapterClass($fieldDefinitionType) ); } + + // ToDo: Consider removing this method and using getDataAdapter when field types from bundles are implemented + public function tryDataAdapter(string $fieldDefinitionType): ?SetterDataInterface + { + try { + return $this->getDataAdapter($fieldDefinitionType); + } catch (InvalidArgumentException) { + return null; + } + } } diff --git a/src/DataObject/Service/DataAdapterServiceInterface.php b/src/DataObject/Service/DataAdapterServiceInterface.php index 6fdfffed7..c3968ab6e 100644 --- a/src/DataObject/Service/DataAdapterServiceInterface.php +++ b/src/DataObject/Service/DataAdapterServiceInterface.php @@ -31,5 +31,10 @@ public function getAdaptersMapping(): array; */ public function getFieldDefinitionAdapterClass(string $fieldDefinitionType): string; + /** + * @throws InvalidArgumentException + */ public function getDataAdapter(string $fieldDefinitionType): SetterDataInterface; + + public function tryDataAdapter(string $fieldDefinitionType): ?SetterDataInterface; } diff --git a/src/DataObject/Service/DataService.php b/src/DataObject/Service/DataService.php index 4981daa7e..fee605dec 100644 --- a/src/DataObject/Service/DataService.php +++ b/src/DataObject/Service/DataService.php @@ -17,8 +17,8 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Service; use Exception; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\ClassData; use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\DataNormalizerInterface; +use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Model\ClassData; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\NotFoundException; use Pimcore\Model\DataObject\ClassDefinition\Data; use Pimcore\Model\DataObject\Concrete; @@ -49,10 +49,12 @@ public function getObjectData(Concrete $dataObject): array foreach ($fieldDefinitions as $key => $fieldDefinition) { try { - $data[$key] = $this->getNormalizedValue($dataObject->get($key), $fieldDefinition); + $value = $dataObject->get($key); } catch (Exception) { throw new NotFoundException(type: 'field', id: $key); } + + $data[$key] = $this->getNormalizedValue($value, $fieldDefinition); } return $data; @@ -85,7 +87,7 @@ public function getNormalizedValue( return null; } - $adapter = $this->dataAdapterService->getDataAdapter($fieldDefinition->getFieldType()); + $adapter = $this->dataAdapterService->tryDataAdapter($fieldDefinition->getFieldType()); if ($adapter instanceof DataNormalizerInterface) { return $adapter->normalize($value, $fieldDefinition); } diff --git a/src/DataObject/Service/DataServiceInterface.php b/src/DataObject/Service/DataServiceInterface.php index 8ebc53b6c..619496661 100644 --- a/src/DataObject/Service/DataServiceInterface.php +++ b/src/DataObject/Service/DataServiceInterface.php @@ -16,7 +16,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Service; -use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\ClassData; +use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\Model\ClassData; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\NotFoundException; use Pimcore\Model\DataObject\ClassDefinition\Data; use Pimcore\Model\DataObject\Concrete; diff --git a/src/DataObject/Service/Loader/TaggedIteratorDataAdapter.php b/src/DataObject/Service/Loader/TaggedIteratorDataAdapter.php index ac7e84b21..3de81935b 100644 --- a/src/DataObject/Service/Loader/TaggedIteratorDataAdapter.php +++ b/src/DataObject/Service/Loader/TaggedIteratorDataAdapter.php @@ -16,9 +16,9 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataObject\Service\Loader; -use InvalidArgumentException; use Pimcore\Bundle\StudioBackendBundle\DataObject\Data\SetterDataInterface; use Pimcore\Bundle\StudioBackendBundle\DataObject\Service\DataAdapterLoaderInterface; +use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException; use Symfony\Component\DependencyInjection\Attribute\TaggedIterator; use function get_class; use function sprintf; diff --git a/src/DataObject/Util/Trait/ValidateFieldTypeTrait.php b/src/DataObject/Util/Trait/ValidateFieldTypeTrait.php new file mode 100644 index 000000000..a7f6b6bd3 --- /dev/null +++ b/src/DataObject/Util/Trait/ValidateFieldTypeTrait.php @@ -0,0 +1,32 @@ +value)] + #[Get( + path: self::PREFIX . '/documents/sites/list-available', + operationId: 'documents_list_available_sites', + description: 'documents_list_available_sites_description', + summary: 'documents_list_available_sites_summary', + tags: [Tags::Documents->value] + )] + #[ExcludeMainSiteParameter] + #[SuccessResponse( + description: 'documents_list_available_sites_success_response', + content: new AvailableSitesJson() + )] + #[DefaultResponses([ + HttpResponseCodes::UNAUTHORIZED, + ])] + public function getAvailableSites( + #[MapQueryString] MappedParameter $parameter + ): JsonResponse { + return $this->jsonResponse(['items' => $this->siteService->getAvailableSites($parameter)]); + } +} diff --git a/src/Document/Event/PreResponse/SiteEvent.php b/src/Document/Event/PreResponse/SiteEvent.php new file mode 100644 index 000000000..d6300e3a0 --- /dev/null +++ b/src/Document/Event/PreResponse/SiteEvent.php @@ -0,0 +1,39 @@ +site; + } +} diff --git a/src/Document/Hydrator/SiteHydrator.php b/src/Document/Hydrator/SiteHydrator.php new file mode 100644 index 000000000..577d1337c --- /dev/null +++ b/src/Document/Hydrator/SiteHydrator.php @@ -0,0 +1,37 @@ +getId(), + $siteModel->getDomains(), + $siteModel->getMainDomain(), + $siteModel->getRootId(), + $siteModel->getRootPath(), + ); + } +} diff --git a/src/Document/Hydrator/SiteHydratorInterface.php b/src/Document/Hydrator/SiteHydratorInterface.php new file mode 100644 index 000000000..5c456805c --- /dev/null +++ b/src/Document/Hydrator/SiteHydratorInterface.php @@ -0,0 +1,28 @@ +excludeMainSite === 'true'; // TODO: symfony 7.1 will support bool type + } +} diff --git a/src/Document/OpenApi/Attribute/Parameter/Query/ExcludeMainSiteParameter.php b/src/Document/OpenApi/Attribute/Parameter/Query/ExcludeMainSiteParameter.php new file mode 100644 index 000000000..68a8cf55f --- /dev/null +++ b/src/Document/OpenApi/Attribute/Parameter/Query/ExcludeMainSiteParameter.php @@ -0,0 +1,35 @@ +load(); + } +} diff --git a/src/Asset/Hydrator/CustomMetadataHydratorInterface.php b/src/Document/Repository/SiteRepositoryInterface.php similarity index 66% rename from src/Asset/Hydrator/CustomMetadataHydratorInterface.php rename to src/Document/Repository/SiteRepositoryInterface.php index 8042d70d0..9a6b4ce96 100644 --- a/src/Asset/Hydrator/CustomMetadataHydratorInterface.php +++ b/src/Document/Repository/SiteRepositoryInterface.php @@ -14,14 +14,17 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Bundle\StudioBackendBundle\Asset\Hydrator; +namespace Pimcore\Bundle\StudioBackendBundle\Document\Repository; -use Pimcore\Bundle\StudioBackendBundle\Asset\Schema\CustomMetadata; +use Pimcore\Model\Site; /** * @internal */ -interface CustomMetadataHydratorInterface +interface SiteRepositoryInterface { - public function hydrate(array $customMetadata): CustomMetadata; + /** + * @return Site[] + */ + public function listSites(): array; } diff --git a/src/Document/Schema/Site.php b/src/Document/Schema/Site.php new file mode 100644 index 000000000..98927f0ef --- /dev/null +++ b/src/Document/Schema/Site.php @@ -0,0 +1,77 @@ +id; + } + + public function getRootId(): ?int + { + return $this->rootId; + } + + public function getRootPath(): ?string + { + return $this->rootPath; + } + + public function getDomains(): array + { + return $this->domains; + } + + public function getDomain(): string + { + return $this->domain; + } +} diff --git a/src/Document/Service/SiteService.php b/src/Document/Service/SiteService.php new file mode 100644 index 000000000..a1e8349f0 --- /dev/null +++ b/src/Document/Service/SiteService.php @@ -0,0 +1,66 @@ +getExcludeMainSite() === false) { + $sites[] = $this->getMainSite(); + } + + $siteList = $this->siteRepository->listSites(); + foreach ($siteList as $siteEntry) { + $site = $this->siteHydrator->hydrate($siteEntry); + + $this->eventDispatcher->dispatch(new SiteEvent($site), SiteEvent::EVENT_NAME); + $sites[] = $site; + } + + return $sites; + } + + private function getMainSite(): Site + { + return new Site(0, [], 'main_site', 1, '/'); + } +} diff --git a/src/Document/Service/SiteServiceInterface.php b/src/Document/Service/SiteServiceInterface.php new file mode 100644 index 000000000..f5ff2af86 --- /dev/null +++ b/src/Document/Service/SiteServiceInterface.php @@ -0,0 +1,31 @@ +name] + tags: [Tags::Metadata->name] )] #[IdParameter(type: ElementTypes::TYPE_ASSET)] #[SuccessResponse( @@ -72,6 +72,6 @@ public function __construct( ])] public function getAssetCustomMetadataById(int $id): JsonResponse { - return $this->jsonResponse(['items' => $this->customMetadataService->getCustomMetadata($id)]); + return $this->jsonResponse(['items' => $this->metadataService->getCustomMetadata($id)]); } } diff --git a/src/Metadata/Controller/CollectionController.php b/src/Metadata/Controller/CollectionController.php new file mode 100644 index 000000000..6d6740c32 --- /dev/null +++ b/src/Metadata/Controller/CollectionController.php @@ -0,0 +1,71 @@ +name] + )] + #[FilterRequestBody] + #[SuccessResponse( + description: 'metadata_get_collection_success_response', + content: new ItemsJson(PredefinedMetadata::class) + )] + #[DefaultResponses([ + HttpResponseCodes::UNAUTHORIZED, + ])] + public function getMetadata( + #[MapRequestPayload] MetadataParameters $parameters = new MetadataParameters() + ): JsonResponse { + return $this->jsonResponse(['items' => $this->metadataService->getPredefinedMetadata($parameters)]); + } +} diff --git a/src/Asset/Event/PreResponse/CustomMetadataEvent.php b/src/Metadata/Event/PreResponse/CustomMetadataEvent.php similarity index 87% rename from src/Asset/Event/PreResponse/CustomMetadataEvent.php rename to src/Metadata/Event/PreResponse/CustomMetadataEvent.php index de004e182..b6f7e3f27 100644 --- a/src/Asset/Event/PreResponse/CustomMetadataEvent.php +++ b/src/Metadata/Event/PreResponse/CustomMetadataEvent.php @@ -14,10 +14,10 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Bundle\StudioBackendBundle\Asset\Event\PreResponse; +namespace Pimcore\Bundle\StudioBackendBundle\Metadata\Event\PreResponse; -use Pimcore\Bundle\StudioBackendBundle\Asset\Schema\CustomMetadata; use Pimcore\Bundle\StudioBackendBundle\Event\AbstractPreResponseEvent; +use Pimcore\Bundle\StudioBackendBundle\Metadata\Schema\CustomMetadata; final class CustomMetadataEvent extends AbstractPreResponseEvent { diff --git a/src/Metadata/Event/PreResponse/PredefinedMetadataEvent.php b/src/Metadata/Event/PreResponse/PredefinedMetadataEvent.php new file mode 100644 index 000000000..a694fb309 --- /dev/null +++ b/src/Metadata/Event/PreResponse/PredefinedMetadataEvent.php @@ -0,0 +1,39 @@ +predefinedMetadata; + } +} diff --git a/src/Asset/Event/PreSet/CustomMetadataEvent.php b/src/Metadata/Event/PreSet/CustomMetadataEvent.php similarity index 93% rename from src/Asset/Event/PreSet/CustomMetadataEvent.php rename to src/Metadata/Event/PreSet/CustomMetadataEvent.php index ab111c96e..6ccef73b3 100644 --- a/src/Asset/Event/PreSet/CustomMetadataEvent.php +++ b/src/Metadata/Event/PreSet/CustomMetadataEvent.php @@ -14,7 +14,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Bundle\StudioBackendBundle\Asset\Event\PreSet; +namespace Pimcore\Bundle\StudioBackendBundle\Metadata\Event\PreSet; use Symfony\Contracts\EventDispatcher\Event; diff --git a/src/Asset/Hydrator/CustomMetadataHydrator.php b/src/Metadata/Hydrator/MetadataHydrator.php similarity index 52% rename from src/Asset/Hydrator/CustomMetadataHydrator.php rename to src/Metadata/Hydrator/MetadataHydrator.php index f6357ace1..91d257da4 100644 --- a/src/Asset/Hydrator/CustomMetadataHydrator.php +++ b/src/Metadata/Hydrator/MetadataHydrator.php @@ -14,16 +14,18 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Bundle\StudioBackendBundle\Asset\Hydrator; +namespace Pimcore\Bundle\StudioBackendBundle\Metadata\Hydrator; -use Pimcore\Bundle\StudioBackendBundle\Asset\Schema\CustomMetadata; +use Pimcore\Bundle\StudioBackendBundle\Metadata\Schema\CustomMetadata; +use Pimcore\Bundle\StudioBackendBundle\Metadata\Schema\PredefinedMetadata; use Pimcore\Bundle\StudioBackendBundle\Resolver\Element\ReferenceResolverInterface; use Pimcore\Model\Element\ElementInterface; +use Pimcore\Model\Metadata\Predefined; /** * @internal */ -final readonly class CustomMetadataHydrator implements CustomMetadataHydratorInterface +final readonly class MetadataHydrator implements MetadataHydratorInterface { public function __construct(private ReferenceResolverInterface $referenceResolver) { @@ -42,6 +44,27 @@ public function hydrate(array $customMetadata): CustomMetadata ); } + public function hydratePredefined(Predefined $predefined): PredefinedMetadata + { + return new PredefinedMetadata( + $predefined->getId(), + $predefined->getName(), + $predefined->getDescription(), + $predefined->getType(), + $predefined->getTargetSubType(), + $this->resolveDefinitionData( + $predefined->getData(), + $predefined->getType(), + ), + $predefined->getConfig(), + $predefined->getLanguage(), + $predefined->getGroup(), + $predefined->getCreationDate(), + $predefined->getModificationDate(), + $predefined->isWriteable() + ); + } + private function resolveData(mixed $data, string $type): mixed { return match (true) { @@ -54,4 +77,17 @@ private function resolveData(mixed $data, string $type): mixed default => $data, }; } + + private function resolveDefinitionData(mixed $data, string $type): mixed + { + if (!$data) { + return $data; + } + + return match ($type) { + 'asset', 'document', 'object' => $this->referenceResolver->resolveData($type, (int)$data), + 'checkbox' => (bool)$data, + default => $data + }; + } } diff --git a/src/Metadata/Hydrator/MetadataHydratorInterface.php b/src/Metadata/Hydrator/MetadataHydratorInterface.php new file mode 100644 index 000000000..5170f6598 --- /dev/null +++ b/src/Metadata/Hydrator/MetadataHydratorInterface.php @@ -0,0 +1,31 @@ +filter; + } +} diff --git a/src/Asset/Patcher/Adapter/MetadataAdapter.php b/src/Metadata/Patcher/Adapter/CustomMetadataAdapter.php similarity index 93% rename from src/Asset/Patcher/Adapter/MetadataAdapter.php rename to src/Metadata/Patcher/Adapter/CustomMetadataAdapter.php index 154f01db9..bcc62a250 100644 --- a/src/Asset/Patcher/Adapter/MetadataAdapter.php +++ b/src/Metadata/Patcher/Adapter/CustomMetadataAdapter.php @@ -14,11 +14,11 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Bundle\StudioBackendBundle\Asset\Patcher\Adapter; +namespace Pimcore\Bundle\StudioBackendBundle\Metadata\Patcher\Adapter; -use Pimcore\Bundle\StudioBackendBundle\Asset\Service\Data\CustomMetadataServiceInterface; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException; use Pimcore\Bundle\StudioBackendBundle\Metadata\Repository\MetadataRepositoryInterface; +use Pimcore\Bundle\StudioBackendBundle\Metadata\Service\MetadataServiceInterface; use Pimcore\Bundle\StudioBackendBundle\Patcher\Service\Loader\PatchAdapterInterface; use Pimcore\Bundle\StudioBackendBundle\Patcher\Service\Loader\TaggedIteratorAdapter; use Pimcore\Bundle\StudioBackendBundle\Util\Constant\ElementTypes; @@ -32,7 +32,7 @@ * @internal */ #[AutoconfigureTag(TaggedIteratorAdapter::ADAPTER_TAG)] -final class MetadataAdapter implements PatchAdapterInterface +final class CustomMetadataAdapter implements PatchAdapterInterface { private const INDEX_KEY = 'metadata'; @@ -111,7 +111,7 @@ private function processNewMetadataEntry(array $metadata): array throw new InvalidArgumentException('Metadata name is required'); } - if (in_array($metadata['name'], CustomMetadataServiceInterface::DEFAULT_METADATA, true)) { + if (in_array($metadata['name'], MetadataServiceInterface::DEFAULT_METADATA, true)) { return $this->addDefaultMetadata($metadata); } diff --git a/src/Metadata/Repository/MetadataRepository.php b/src/Metadata/Repository/MetadataRepository.php index e7b45e841..9999c9537 100644 --- a/src/Metadata/Repository/MetadataRepository.php +++ b/src/Metadata/Repository/MetadataRepository.php @@ -17,6 +17,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\Metadata\Repository; use Pimcore\Bundle\StaticResolverBundle\Models\Metadata\Predefined\PredefinedResolverInterface; +use Pimcore\Bundle\StudioBackendBundle\Metadata\MappedParameter\MetadataParameters; use Pimcore\Model\Metadata\Predefined; use Pimcore\Model\Metadata\Predefined\Listing; @@ -37,6 +38,25 @@ public function getAllPredefinedMetadata(): array return (new Listing())->load(); } + public function getAllPredefinedMetadataDefinitions(MetadataParameters $metadataParameters): array + { + $listing = new Listing(); + $filter = $metadataParameters->getFilter(); + if ($filter !== null) { + $listing->setFilter(function (Predefined $predefined) use ($filter) { + foreach ($predefined->getObjectVars() as $value) { + if (stripos((string)$value, $filter) !== false) { + return true; + } + } + + return false; + }); + } + + return $listing->getDefinitions(); + } + public function getPredefinedMetadataByName(string $name): ?Predefined { return $this->predefinedResolver->getByName($name); diff --git a/src/Metadata/Repository/MetadataRepositoryInterface.php b/src/Metadata/Repository/MetadataRepositoryInterface.php index 9cb5b8d0d..9dde51462 100644 --- a/src/Metadata/Repository/MetadataRepositoryInterface.php +++ b/src/Metadata/Repository/MetadataRepositoryInterface.php @@ -16,6 +16,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\Metadata\Repository; +use Pimcore\Bundle\StudioBackendBundle\Metadata\MappedParameter\MetadataParameters; use Pimcore\Model\Metadata\Predefined; /** @@ -28,5 +29,7 @@ interface MetadataRepositoryInterface */ public function getAllPredefinedMetadata(): array; + public function getAllPredefinedMetadataDefinitions(MetadataParameters $metadataParameters): array; + public function getPredefinedMetadataByName(string $name): ?Predefined; } diff --git a/src/Asset/Schema/CustomMetadata.php b/src/Metadata/Schema/CustomMetadata.php similarity index 92% rename from src/Asset/Schema/CustomMetadata.php rename to src/Metadata/Schema/CustomMetadata.php index 0c2c30a11..4249f11a1 100644 --- a/src/Asset/Schema/CustomMetadata.php +++ b/src/Metadata/Schema/CustomMetadata.php @@ -14,7 +14,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Bundle\StudioBackendBundle\Asset\Schema; +namespace Pimcore\Bundle\StudioBackendBundle\Metadata\Schema; use OpenApi\Attributes\Property; use OpenApi\Attributes\Schema; @@ -37,7 +37,7 @@ public function __construct( private readonly string $language, #[Property(description: 'Type', type: 'string', example: 'input')] private readonly string $type, - #[Property(description: 'Data', type: 'string', example: 'data')] + #[Property(description: 'Data', type: 'mixed', example: 'data')] private readonly mixed $data ) { } diff --git a/src/Metadata/Schema/PredefinedMetadata.php b/src/Metadata/Schema/PredefinedMetadata.php new file mode 100644 index 000000000..afc6a852c --- /dev/null +++ b/src/Metadata/Schema/PredefinedMetadata.php @@ -0,0 +1,120 @@ +id; + } + + public function getName(): string + { + return $this->name; + } + + public function getDescription(): ?string + { + return $this->description; + } + + public function getType(): string + { + return $this->type; + } + + public function getTargetSubType(): ?string + { + return $this->targetSubType; + } + + public function getData(): mixed + { + return $this->data; + } + + public function getConfig(): ?string + { + return $this->config; + } + + public function getLanguage(): ?string + { + return $this->language; + } + + public function getGroup(): ?string + { + return $this->group; + } + + public function getCreationDate(): int + { + return $this->creationDate; + } + + public function getModificationDate(): int + { + return $this->modificationDate; + } + + public function isWriteable(): bool + { + return $this->isWriteable; + } +} diff --git a/src/Asset/Service/Data/CustomMetadataService.php b/src/Metadata/Service/MetadataService.php similarity index 63% rename from src/Asset/Service/Data/CustomMetadataService.php rename to src/Metadata/Service/MetadataService.php index d42fd3598..0f82397c2 100644 --- a/src/Asset/Service/Data/CustomMetadataService.php +++ b/src/Metadata/Service/MetadataService.php @@ -14,13 +14,16 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Bundle\StudioBackendBundle\Asset\Service\Data; +namespace Pimcore\Bundle\StudioBackendBundle\Metadata\Service; use Pimcore\Bundle\StaticResolverBundle\Models\Element\ServiceResolverInterface; -use Pimcore\Bundle\StudioBackendBundle\Asset\Event\PreResponse\CustomMetadataEvent; -use Pimcore\Bundle\StudioBackendBundle\Asset\Hydrator\CustomMetadataHydratorInterface; -use Pimcore\Bundle\StudioBackendBundle\Asset\Schema\CustomMetadata; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\AccessDeniedException; +use Pimcore\Bundle\StudioBackendBundle\Metadata\Event\PreResponse\CustomMetadataEvent; +use Pimcore\Bundle\StudioBackendBundle\Metadata\Event\PreResponse\PredefinedMetadataEvent; +use Pimcore\Bundle\StudioBackendBundle\Metadata\Hydrator\MetadataHydratorInterface; +use Pimcore\Bundle\StudioBackendBundle\Metadata\MappedParameter\MetadataParameters; +use Pimcore\Bundle\StudioBackendBundle\Metadata\Repository\MetadataRepositoryInterface; +use Pimcore\Bundle\StudioBackendBundle\Metadata\Schema\CustomMetadata; use Pimcore\Bundle\StudioBackendBundle\Security\Service\SecurityServiceInterface; use Pimcore\Bundle\StudioBackendBundle\Util\Constant\ElementPermissions; use Pimcore\Bundle\StudioBackendBundle\Util\Constant\ElementTypes; @@ -31,15 +34,16 @@ /** * @internal */ -final readonly class CustomMetadataService implements CustomMetadataServiceInterface +final readonly class MetadataService implements MetadataServiceInterface { use ElementProviderTrait; public function __construct( - private CustomMetadataHydratorInterface $hydrator, + private MetadataRepositoryInterface $metadataRepository, private SecurityServiceInterface $securityService, private ServiceResolverInterface $serviceResolver, - private EventDispatcherInterface $eventDispatcher + private EventDispatcherInterface $eventDispatcher, + private MetadataHydratorInterface $hydrator ) { } @@ -88,4 +92,23 @@ public function getCustomMetadata(int $id): array return $customMetadata; } + + public function getPredefinedMetadata(MetadataParameters $parameters): array + { + $originalPredefinedMetadata = $this->metadataRepository->getAllPredefinedMetadataDefinitions($parameters); + + $predefinedMetadata = []; + + foreach ($originalPredefinedMetadata as $predefined) { + $metadata = $this->hydrator->hydratePredefined($predefined); + + $this->eventDispatcher->dispatch( + new PredefinedMetadataEvent($metadata), + PredefinedMetadataEvent::EVENT_NAME + ); + $predefinedMetadata[] = $metadata; + } + + return $predefinedMetadata; + } } diff --git a/src/Asset/Service/Data/CustomMetadataServiceInterface.php b/src/Metadata/Service/MetadataServiceInterface.php similarity index 62% rename from src/Asset/Service/Data/CustomMetadataServiceInterface.php rename to src/Metadata/Service/MetadataServiceInterface.php index 5e9d6421e..3d56a6301 100644 --- a/src/Asset/Service/Data/CustomMetadataServiceInterface.php +++ b/src/Metadata/Service/MetadataServiceInterface.php @@ -14,15 +14,17 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Bundle\StudioBackendBundle\Asset\Service\Data; +namespace Pimcore\Bundle\StudioBackendBundle\Metadata\Service; -use Pimcore\Bundle\StudioBackendBundle\Asset\Schema\CustomMetadata; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\AccessDeniedException; +use Pimcore\Bundle\StudioBackendBundle\Metadata\MappedParameter\MetadataParameters; +use Pimcore\Bundle\StudioBackendBundle\Metadata\Schema\CustomMetadata; +use Pimcore\Bundle\StudioBackendBundle\Metadata\Schema\PredefinedMetadata; /** * @internal */ -interface CustomMetadataServiceInterface +interface MetadataServiceInterface { public const DEFAULT_METADATA = ['title', 'alt', 'copyright']; @@ -30,7 +32,11 @@ interface CustomMetadataServiceInterface * @return array * * @throws AccessDeniedException - * */ public function getCustomMetadata(int $id): array; + + /** + * @return array + */ + public function getPredefinedMetadata(MetadataParameters $parameters): array; } diff --git a/src/Asset/Updater/Adapter/CustomMetadataAdapter.php b/src/Metadata/Updater/Adapter/CustomMetadataAdapter.php similarity index 92% rename from src/Asset/Updater/Adapter/CustomMetadataAdapter.php rename to src/Metadata/Updater/Adapter/CustomMetadataAdapter.php index 3fd43b1c9..90ae74b29 100644 --- a/src/Asset/Updater/Adapter/CustomMetadataAdapter.php +++ b/src/Metadata/Updater/Adapter/CustomMetadataAdapter.php @@ -14,9 +14,9 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Bundle\StudioBackendBundle\Asset\Updater\Adapter; +namespace Pimcore\Bundle\StudioBackendBundle\Metadata\Updater\Adapter; -use Pimcore\Bundle\StudioBackendBundle\Asset\Event\PreSet\CustomMetadataEvent; +use Pimcore\Bundle\StudioBackendBundle\Metadata\Event\PreSet\CustomMetadataEvent; use Pimcore\Bundle\StudioBackendBundle\Updater\Adapter\UpdateAdapterInterface; use Pimcore\Bundle\StudioBackendBundle\Util\Constant\ElementTypes; use Pimcore\Model\Asset; diff --git a/src/OpenApi/Config/Tags.php b/src/OpenApi/Config/Tags.php index be9dfaea4..80c36f4a7 100644 --- a/src/OpenApi/Config/Tags.php +++ b/src/OpenApi/Config/Tags.php @@ -53,6 +53,10 @@ name: Tags::Dependencies->value, description: 'tag_dependencies_description' )] +#[Tag( + name: Tags::Documents->value, + description: 'tag_documents_description' +)] #[Tag( name: Tags::Elements->value, description: 'tag_elements_description' @@ -69,6 +73,10 @@ name: Tags::Mercure->value, description: 'tag_mercure_description' )] +#[Tag( + name: Tags::Metadata->value, + description: 'tag_metadata_description' +)] #[Tag( name: Tags::Notes->value, description: 'tag_notes_description' @@ -127,10 +135,12 @@ enum Tags: string case DataObjects = 'Data Objects'; case DataObjectsGrid = 'Data Object Grid'; case Dependencies = 'Dependencies'; + case Documents = 'Documents'; case Elements = 'Elements'; case ExecutionEngine = 'Execution Engine'; case Emails = 'E-Mails'; case Mercure = 'Mercure'; + case Metadata = 'Metadata'; case Notes = 'Notes'; case Notifications = 'Notifications'; case Properties = 'Properties'; diff --git a/src/Resolver/Element/ReferenceResolver.php b/src/Resolver/Element/ReferenceResolver.php index 5c0adac56..8077f44bb 100644 --- a/src/Resolver/Element/ReferenceResolver.php +++ b/src/Resolver/Element/ReferenceResolver.php @@ -15,11 +15,15 @@ namespace Pimcore\Bundle\StudioBackendBundle\Resolver\Element; +use Pimcore\Bundle\StaticResolverBundle\Models\Element\ServiceResolverInterface; +use Pimcore\Bundle\StudioBackendBundle\Util\Trait\ElementProviderTrait; use Pimcore\Model\Element\AbstractElement; use Pimcore\Model\Element\ElementInterface; final class ReferenceResolver implements ReferenceResolverInterface { + use ElementProviderTrait; + private const ALLOWED_MODEL_PROPERTIES = [ 'key', 'filename', @@ -33,6 +37,10 @@ final class ReferenceResolver implements ReferenceResolverInterface */ private array $cache = []; + public function __construct(private ServiceResolverInterface $serviceResolver) + { + } + public function resolve(ElementInterface $element): array { if (isset($this->cache[$element->getId()])) { @@ -53,4 +61,11 @@ public function resolve(ElementInterface $element): array return $data; } + + public function resolveData(string $type, int $id): mixed + { + $element = $this->getElement($this->serviceResolver, $type, $id); + + return $this->resolve($element); + } } diff --git a/src/Resolver/Element/ReferenceResolverInterface.php b/src/Resolver/Element/ReferenceResolverInterface.php index 81301ffca..e24505380 100644 --- a/src/Resolver/Element/ReferenceResolverInterface.php +++ b/src/Resolver/Element/ReferenceResolverInterface.php @@ -20,4 +20,6 @@ interface ReferenceResolverInterface { public function resolve(ElementInterface $element): array; + + public function resolveData(string $type, int $id): mixed; } diff --git a/src/Updater/Service/UpdateService.php b/src/Updater/Service/UpdateService.php index 42a65a1c0..b4a80f55f 100644 --- a/src/Updater/Service/UpdateService.php +++ b/src/Updater/Service/UpdateService.php @@ -20,6 +20,7 @@ use Pimcore\Bundle\GenericDataIndexBundle\Service\SearchIndex\IndexQueue\SynchronousProcessingServiceInterface; use Pimcore\Bundle\StaticResolverBundle\Models\Element\ServiceResolverInterface; use Pimcore\Bundle\StudioBackendBundle\DataObject\Service\DataAdapterServiceInterface; +use Pimcore\Bundle\StudioBackendBundle\DataObject\Util\Trait\ValidateFieldTypeTrait; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\ElementSavingFailedException; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\NotFoundException; use Pimcore\Bundle\StudioBackendBundle\Security\Service\SecurityServiceInterface; @@ -33,6 +34,7 @@ final readonly class UpdateService implements UpdateServiceInterface { use ElementProviderTrait; + use ValidateFieldTypeTrait; private const EDITABLE_DATA_KEY = 'editableData'; @@ -78,17 +80,21 @@ private function updateEditableData(Concrete $element, array $editableData): voi $class = $element->getClass(); foreach ($editableData as $key => $value) { $fieldDefinition = $class->getFieldDefinition($key); - if ($fieldDefinition === null) { + if ($fieldDefinition === null || !array_key_exists($key, $editableData)) { continue; } - $data = array_key_exists($key, $editableData) - ? $this->dataAdapterService - ->getDataAdapter($fieldDefinition->getFieldType()) - ->getDataForSetter($element, $fieldDefinition, $key, $editableData) - : null; + $adapter = $this->dataAdapterService->tryDataAdapter($fieldDefinition->getFieldtype()); + if ($adapter === null) { + continue; + } + + $value = $adapter->getDataForSetter($element, $fieldDefinition, $key, $editableData); + if (!$this->validateEncryptedField($fieldDefinition, $value)) { + continue; + } - $element->setValue($key, $data); + $element->setValue($key, $value); } } catch (Exception $e) { diff --git a/translations/studio_api_docs.en.yaml b/translations/studio_api_docs.en.yaml index 1664c9fa5..f30bde537 100644 --- a/translations/studio_api_docs.en.yaml +++ b/translations/studio_api_docs.en.yaml @@ -201,6 +201,10 @@ data_object_update_by_id_description: | Update needs to have the complete data present.
You can create/update/delete list entries like properties.
If you want to update only a single field, use the PATCH method. data_object_update_by_id_success_response: Successfully updated data object data_object_update_by_id_summary: Update a data object by ID +documents_list_available_sites_description: | + List all available sites +documents_list_available_sites_success_response: List of available sites +documents_list_available_sites_summary: List all available sites element_delete_created_response: Successfully created jobRun for deleting element and its children element_delete_description: | @@ -281,6 +285,9 @@ logout_summary: Logout and invalidate current session for active user. mercure_create_cookie_description: Retrieve JWT token for Mercure hub as cookie mercure_create_cookie_success_response: Retrieve JWT token for Mercure hub as cookie mercure_create_cookie_summary: Retrieve JWT token for Mercure hub as cookie +metadata_get_collection_description: Get predefined metadata collection with basic filter options +metadata_get_collection_success_response: Predefined metadata collection +metadata_get_collection_summary: Get predefined metadata collection note_delete_by_id_description: | Delete the note with the given {id} note_delete_by_id_success_response: Successfully deleted note @@ -434,6 +441,7 @@ tag_delete_by_id_description: | tag_delete_by_id_success_response: ID of successfully deleted tag tag_delete_by_id_summary: Delete a specific tag tag_dependencies_description: Get dependencies for a single element +tag_documents_description: Document operations to get/update/create/delete documents tag_elements_description: Get element properties for a single element based on its type and provided parameters tag_emails_description: E-mail operations to get/update/create/delete/test emails and @@ -453,6 +461,7 @@ tag_get_collection_for_element_by_type_and_id_summary: Get tags for an element tag_get_collection_success_response: All tags for a parent filtered based on type and query parameters tag_get_collection_summary: Get all tags for a parent tag_mercure_description: Retrieve JWT token for Mercure hub as cookie +tag_metadata_description: Metadata operations to get/update/create/delete metadata tag_notes_description: Note operations to list/delete notes tag_notifications_description: Notification operations to get/delete/send notifications tag_properties_description: Property operations to get/update/create/delete properties