Skip to content

Commit

Permalink
[Data Object Editor] Add Endpoint to get fieldcollection (#581)
Browse files Browse the repository at this point in the history
* Add field collection layout endpopint.

* Apply php-cs-fixer changes

* fix style.

* fix style.

* Move Hydrator to FieldCollection namespace.

---------

Co-authored-by: martineiber <[email protected]>
  • Loading branch information
martineiber and martineiber authored Nov 27, 2024
1 parent 5680cea commit 758fe40
Show file tree
Hide file tree
Showing 10 changed files with 490 additions and 1 deletion.
25 changes: 25 additions & 0 deletions config/class.yaml
Original file line number Diff line number Diff line change
@@ -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
82 changes: 82 additions & 0 deletions src/Class/Controller/FieldCollection/LayoutController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php
declare(strict_types=1);

/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PCL
*/

namespace Pimcore\Bundle\StudioBackendBundle\Class\Controller\FieldCollection;

use Exception;
use OpenApi\Attributes\Get;
use Pimcore\Bundle\StudioBackendBundle\Class\Schema\LayoutDefinition;
use Pimcore\Bundle\StudioBackendBundle\Class\Service\FieldCollection\LayoutDefinitionServiceInterface;
use Pimcore\Bundle\StudioBackendBundle\Controller\AbstractApiController;
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\NotFoundException;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Parameter\Path\IdParameter;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Property\GenericCollection;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\Content\CollectionJson;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\DefaultResponses;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\SuccessResponse;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Config\Tags;
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\HttpResponseCodes;
use Pimcore\Bundle\StudioBackendBundle\Util\Trait\PaginatedResponseTrait;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Serializer\SerializerInterface;
use function count;

final class LayoutController extends AbstractApiController
{
use PaginatedResponseTrait;

public function __construct(
SerializerInterface $serializer,
private readonly LayoutDefinitionServiceInterface $layoutDefinitionService,
) {
parent::__construct($serializer);
}

/**
* @throws Exception|NotFoundException
*/
#[Route(
'/class/field-collection/{objectId}/object/layout',
name: 'pimcore_studio_api_class_field_collection_object_layout',
methods: ['GET']
)]
#[Get(
path: self::PREFIX . '/class/field-collection/{objectId}/object/layout',
operationId: 'class_field_collection_object_layout',
description: 'class_field_collection_object_layout_description',
summary: 'class_field_collection_object_layout_summary',
tags: [Tags::ClassDefinition->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),
);
}
}
35 changes: 35 additions & 0 deletions src/Class/Event/FieldCollection/LayoutDefinitionEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php
declare(strict_types=1);

/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PCL
*/

namespace Pimcore\Bundle\StudioBackendBundle\Class\Event\FieldCollection;

use Pimcore\Bundle\StudioBackendBundle\Class\Schema\LayoutDefinition;
use Pimcore\Bundle\StudioBackendBundle\Event\AbstractPreResponseEvent;

final class LayoutDefinitionEvent extends AbstractPreResponseEvent
{
public const EVENT_NAME = 'pre_response.field_collection.layout_definition';

public function __construct(private readonly LayoutDefinition $layoutDefinition)
{
parent::__construct($this->layoutDefinition);
}

public function getLayoutDefinition(): LayoutDefinition
{
return $this->layoutDefinition;
}
}
46 changes: 46 additions & 0 deletions src/Class/Hydrator/FieldCollection/LayoutDefinitionHydrator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php
declare(strict_types=1);

/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PCL
*/

namespace Pimcore\Bundle\StudioBackendBundle\Class\Hydrator\FieldCollection;

use Pimcore\Bundle\StudioBackendBundle\Class\Schema\LayoutDefinition;
use Pimcore\Model\DataObject\Fieldcollection\Definition as FieldCollectionDefinition;

/**
* @internal
*/
final class LayoutDefinitionHydrator implements LayoutDefinitionHydratorInterface
{
public function hydrate(FieldCollectionDefinition $data): LayoutDefinition
{
$layout = $data->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(),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);

/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PCL
*/

namespace Pimcore\Bundle\StudioBackendBundle\Class\Hydrator\FieldCollection;

use Pimcore\Bundle\StudioBackendBundle\Class\Schema\LayoutDefinition;
use Pimcore\Model\DataObject\Fieldcollection\Definition as FieldCollectionDefinition;

/**
* @internal
*/
interface LayoutDefinitionHydratorInterface
{
public function hydrate(FieldCollectionDefinition $data): LayoutDefinition;
}
133 changes: 133 additions & 0 deletions src/Class/Schema/LayoutDefinition.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<?php
declare(strict_types=1);

/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PCL
*/

namespace Pimcore\Bundle\StudioBackendBundle\Class\Schema;

use OpenApi\Attributes\Items;
use OpenApi\Attributes\Property;
use OpenApi\Attributes\Schema;
use Pimcore\Bundle\StudioBackendBundle\Util\Schema\AdditionalAttributesInterface;
use Pimcore\Bundle\StudioBackendBundle\Util\Trait\AdditionalAttributesTrait;

/**
* @internal
*/
#[Schema(
title: 'Field Collection Layout Definition',
required: [
'key',
'title',
'width',
'height',
'collapsible',
'collapsed',
'datatype',
'children',
],
type: 'object'
)]
final class LayoutDefinition implements AdditionalAttributesInterface
{
use AdditionalAttributesTrait;

public function __construct(
#[Property(description: 'Key of Field Collection', type: 'string')]
private readonly string $key,
#[Property(description: 'Data Type', type: 'string', example: 'layout')]
private readonly string $datatype,
#[Property(description: 'Group', type: 'string', example: 'Group Name')]
private readonly ?string $group = null,
#[Property(description: 'Name', type: 'string', example: 'Layout')]
private readonly ?string $name = null,
#[Property(description: 'Type', type: 'string')]
private readonly ?string $type = null,
#[Property(description: 'Region', type: 'string')]
private readonly ?string $region = null,
#[Property(description: 'Title', type: 'string')]
private readonly ?string $title = null,
#[Property(description: 'Width', type: 'integer', example: 0)]
private readonly int $width = 0,
#[Property(description: 'Height', type: 'integer', example: 0)]
private readonly int $height = 0,
#[Property(description: 'Collapsible', type: 'boolean', example: false)]
private readonly bool $collapsible = false,
#[Property(description: 'collapsed', type: 'boolean', example: false)]
private readonly bool $collapsed = false,
#[Property(description: 'Children', type: 'array', items: new Items(), example: '[]')]
private readonly array $children = [],
) {
}

public function getKey(): string
{
return $this->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;
}
}
Loading

0 comments on commit 758fe40

Please sign in to comment.