diff --git a/config/class.yaml b/config/class.yaml new file mode 100644 index 00000000..1de06806 --- /dev/null +++ b/config/class.yaml @@ -0,0 +1,25 @@ +services: + _defaults: + autowire: true + autoconfigure: true + public: false + + # controllers are imported separately to make sure they're public + # and have a tag that allows actions to type-hint services + Pimcore\Bundle\StudioBackendBundle\Class\Controller\: + resource: '../src/Class/Controller' + public: true + tags: [ 'controller.service_arguments' ] + + # + # Services + # + Pimcore\Bundle\StudioBackendBundle\Class\Service\FieldCollection\LayoutDefinitionServiceInterface: + class: Pimcore\Bundle\StudioBackendBundle\Class\Service\FieldCollection\LayoutDefinitionService + + + # + # Hydrators + # + Pimcore\Bundle\StudioBackendBundle\Class\Hydrator\FieldCollection\LayoutDefinitionHydratorInterface: + class: Pimcore\Bundle\StudioBackendBundle\Class\Hydrator\FieldCollection\LayoutDefinitionHydrator \ No newline at end of file diff --git a/src/Class/Controller/FieldCollection/LayoutController.php b/src/Class/Controller/FieldCollection/LayoutController.php new file mode 100644 index 00000000..64bd5e2f --- /dev/null +++ b/src/Class/Controller/FieldCollection/LayoutController.php @@ -0,0 +1,82 @@ +value], + )] + #[IdParameter(name: 'objectId', required: true)] + #[SuccessResponse( + description: 'class_field_collection_object_layout_success_response', + content: new CollectionJson(new GenericCollection(LayoutDefinition::class)) + )] + #[DefaultResponses([ + HttpResponseCodes::NOT_FOUND, + ])] + public function getFieldCollectionLayoutForObject(int $objectId): JsonResponse + { + $items = $this->layoutDefinitionService->getLayoutDefinitionsForObject($objectId); + + return $this->getPaginatedCollection( + $this->serializer, + $items, + count($items), + ); + } +} diff --git a/src/Class/Event/FieldCollection/LayoutDefinitionEvent.php b/src/Class/Event/FieldCollection/LayoutDefinitionEvent.php new file mode 100644 index 00000000..66d41765 --- /dev/null +++ b/src/Class/Event/FieldCollection/LayoutDefinitionEvent.php @@ -0,0 +1,35 @@ +layoutDefinition); + } + + public function getLayoutDefinition(): LayoutDefinition + { + return $this->layoutDefinition; + } +} diff --git a/src/Class/Hydrator/FieldCollection/LayoutDefinitionHydrator.php b/src/Class/Hydrator/FieldCollection/LayoutDefinitionHydrator.php new file mode 100644 index 00000000..ddafa45c --- /dev/null +++ b/src/Class/Hydrator/FieldCollection/LayoutDefinitionHydrator.php @@ -0,0 +1,46 @@ +getLayoutDefinitions(); + + return new LayoutDefinition( + $data->getKey(), + $layout->getDatatype(), + $data->getGroup(), + $layout->getName(), + $layout->getType(), + $layout->getRegion(), + $layout->getTitle(), + $layout->getWidth(), + $layout->getHeight(), + $layout->getCollapsible(), + $layout->getCollapsed(), + $layout->getChildren(), + ); + } +} diff --git a/src/Class/Hydrator/FieldCollection/LayoutDefinitionHydratorInterface.php b/src/Class/Hydrator/FieldCollection/LayoutDefinitionHydratorInterface.php new file mode 100644 index 00000000..f0691955 --- /dev/null +++ b/src/Class/Hydrator/FieldCollection/LayoutDefinitionHydratorInterface.php @@ -0,0 +1,28 @@ +key; + } + + public function getGroup(): ?string + { + return $this->group; + } + + public function getName(): ?string + { + return $this->name; + } + + public function getType(): ?string + { + return $this->type; + } + + public function getRegion(): ?string + { + return $this->region; + } + + public function getTitle(): ?string + { + return $this->title; + } + + public function getWidth(): int + { + return $this->width; + } + + public function getHeight(): int + { + return $this->height; + } + + public function isCollapsible(): bool + { + return $this->collapsible; + } + + public function isCollapsed(): bool + { + return $this->collapsed; + } + + public function getDatatype(): string + { + return $this->datatype; + } + + public function getChildren(): array + { + return $this->children; + } +} diff --git a/src/Class/Service/FieldCollection/LayoutDefinitionService.php b/src/Class/Service/FieldCollection/LayoutDefinitionService.php new file mode 100644 index 00000000..7aa5b9ad --- /dev/null +++ b/src/Class/Service/FieldCollection/LayoutDefinitionService.php @@ -0,0 +1,99 @@ +dataObjectResolver->getById($dataObjectId); + + if (!$dataObject) { + throw new NotFoundException('data Object', $dataObjectId); + } + + $this->collectFieldCollectionTypes( + $this->classDefinitionResolver->getById($dataObject->getClassId()) + ); + + $layoutDefinitions = []; + foreach ($this->fieldCollectionTypes as $fieldCollectionType) { + $layoutDefinitions[] = $this->getLayoutDefinitionByType($fieldCollectionType); + } + + return $layoutDefinitions; + } + + /** + * @throws Exception + */ + private function getLayoutDefinitionByType(string $name): LayoutDefinition + { + $definition = $this->definitionResolver->getByKey($name); + + if (!$definition) { + throw new NotFoundException('Field Collection Definition', $name); + } + + $layoutDefinition = $this->layoutDefinitionHydrator->hydrate($definition); + + $this->eventDispatcher->dispatch( + new LayoutDefinitionEvent($layoutDefinition), + LayoutDefinitionEvent::EVENT_NAME + ); + + return $layoutDefinition; + } + + private function collectFieldCollectionTypes(ClassDefinitionInterface $classDefinition): void + { + foreach ($classDefinition->getFieldDefinitions() as $fieldDefinition) { + if ($fieldDefinition instanceof DataObject\ClassDefinition\Data\Fieldcollections) { + $this->fieldCollectionTypes = [...$this->fieldCollectionTypes, ...$fieldDefinition->getAllowedTypes()]; + } + } + } +} diff --git a/src/Class/Service/FieldCollection/LayoutDefinitionServiceInterface.php b/src/Class/Service/FieldCollection/LayoutDefinitionServiceInterface.php new file mode 100644 index 00000000..d8ea9c67 --- /dev/null +++ b/src/Class/Service/FieldCollection/LayoutDefinitionServiceInterface.php @@ -0,0 +1,31 @@ +value, description: 'tag_authorization_description' )] +#[Tag( + name: Tags::ClassDefinition->value, + description: 'tag_class_description' +)] #[Tag( name: Tags::DataObjects->value, description: 'tag_dataobjects_description' @@ -119,6 +123,7 @@ enum Tags: string case AssetGrid = 'Asset Grid'; case AssetThumbnails = 'Asset Thumbnails'; case Authorization = 'Authorization'; + case ClassDefinition = 'Class Definition'; case DataObjects = 'Data Objects'; case DataObjectsGrid = 'Data Object Grid'; case Dependencies = 'Dependencies'; diff --git a/translations/studio_api_docs.en.yaml b/translations/studio_api_docs.en.yaml index 5cc6b1f7..85e20292 100644 --- a/translations/studio_api_docs.en.yaml +++ b/translations/studio_api_docs.en.yaml @@ -416,6 +416,7 @@ tag_assign_to_element_success_response: Successfully assigned tag to element tag_assign_to_element_summary: Assign a tag to an element tag_authorization_description: Session-based login via username and password or logout and invalidate the session +tag_class_description: Class definition operations tag_batch_operation_to_elements_by_type_and_id_description: | Batch assign/replace multiple tags of the given parent based on the {elementId} and {elementType} to the children.
Operation parameter {operation} must be one of the assignreplace. @@ -599,4 +600,8 @@ user_default_key_bindings_summary: Get default key bindings user_default_key_bindings_response: List of default key bindings user_upload_image_summary: Upload user image user_get_image_summary: Get user profile image -user_get_image_success_response: User profile image \ No newline at end of file +user_get_image_success_response: User profile image +class_field_collection_object_layout_description: | + Get all layouts from the field collection for an given object +class_field_collection_object_layout_summary: Get all layouts from the field collection for an given object +class_field_collection_object_layout_success_response: List of layouts \ No newline at end of file