Skip to content

Commit 636839e

Browse files
mcop1lukmzig
andauthored
Studio UI Development - Class Definitions - Classes - Tree (#1582)
* Added endpoint to return creatable class definitions only * Apply php-cs-fixer changes * add class definition config tree * Apply php-cs-fixer changes * fix type * fix method name * fix method name --------- Co-authored-by: lukmzig <lukas.mzigot@pimcore.com> Co-authored-by: lukmzig <30526586+lukmzig@users.noreply.github.com>
1 parent d8eee34 commit 636839e

20 files changed

Lines changed: 737 additions & 16 deletions

config/class.yaml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ services:
2323
Pimcore\Bundle\StudioBackendBundle\Class\Service\ClassDefinitionServiceInterface:
2424
class: Pimcore\Bundle\StudioBackendBundle\Class\Service\ClassDefinitionService
2525

26+
Pimcore\Bundle\StudioBackendBundle\Class\Service\ClassDefinitionTreeServiceInterface:
27+
class: Pimcore\Bundle\StudioBackendBundle\Class\Service\ClassDefinitionTreeService
28+
2629
Pimcore\Bundle\StudioBackendBundle\Class\Service\CustomLayoutServiceInterface:
2730
class: Pimcore\Bundle\StudioBackendBundle\Class\Service\CustomLayoutService
2831

@@ -61,4 +64,10 @@ services:
6164
class: Pimcore\Bundle\StudioBackendBundle\Class\Hydrator\CustomLayout\CustomLayoutHydrator
6265

6366
Pimcore\Bundle\StudioBackendBundle\Class\Hydrator\Folder\ClassDefinitionFolderItemHydratorInterface:
64-
class: Pimcore\Bundle\StudioBackendBundle\Class\Hydrator\Folder\ClassDefinitionFolderItemHydrator
67+
class: Pimcore\Bundle\StudioBackendBundle\Class\Hydrator\Folder\ClassDefinitionFolderItemHydrator
68+
69+
Pimcore\Bundle\StudioBackendBundle\Class\Hydrator\Tree\NodeHydratorInterface:
70+
class: Pimcore\Bundle\StudioBackendBundle\Class\Hydrator\Tree\NodeHydrator
71+
72+
Pimcore\Bundle\StudioBackendBundle\Class\Hydrator\Tree\FolderNodeHydratorInterface:
73+
class: Pimcore\Bundle\StudioBackendBundle\Class\Hydrator\Tree\FolderNodeHydrator
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
/**
5+
* This source file is available under the terms of the
6+
* Pimcore Open Core License (POCL)
7+
* Full copyright and license information is available in
8+
* LICENSE.md which is distributed with this source code.
9+
*
10+
* @copyright Copyright (c) Pimcore GmbH (https://www.pimcore.com)
11+
* @license Pimcore Open Core License (POCL)
12+
*/
13+
14+
namespace Pimcore\Bundle\StudioBackendBundle\Class\Attribute\Request;
15+
16+
use Attribute;
17+
use OpenApi\Attributes\JsonContent;
18+
use OpenApi\Attributes\RequestBody;
19+
use Pimcore\Bundle\StudioBackendBundle\Class\MappedParameter\ClassDefinitionTreeParameter;
20+
21+
#[Attribute(Attribute::TARGET_METHOD)]
22+
final class ClassDefinitionTreeRequestBody extends RequestBody
23+
{
24+
public function __construct()
25+
{
26+
parent::__construct(
27+
required: true,
28+
content: new JsonContent(ref: ClassDefinitionTreeParameter::class)
29+
);
30+
}
31+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
/**
5+
* This source file is available under the terms of the
6+
* Pimcore Open Core License (POCL)
7+
* Full copyright and license information is available in
8+
* LICENSE.md which is distributed with this source code.
9+
*
10+
* @copyright Copyright (c) Pimcore GmbH (https://www.pimcore.com)
11+
* @license Pimcore Open Core License (POCL)
12+
*/
13+
14+
namespace Pimcore\Bundle\StudioBackendBundle\Class\Attribute\Response\Property;
15+
16+
use OpenApi\Attributes\Items;
17+
use OpenApi\Attributes\Property;
18+
use OpenApi\Attributes\Schema;
19+
use Pimcore\Bundle\StudioBackendBundle\Class\Schema\ClassDefinitionTreeNode;
20+
use Pimcore\Bundle\StudioBackendBundle\Class\Schema\ClassDefinitionTreeNodeFolder;
21+
22+
/**
23+
* @internal
24+
*/
25+
final class AnyOfClassDefinitionNodes extends Property
26+
{
27+
public function __construct()
28+
{
29+
parent::__construct(
30+
'items',
31+
title: 'items',
32+
type: 'array',
33+
items: new Items(
34+
anyOf: array_map(static function ($class) {
35+
return new Schema(ref: $class);
36+
}, [ClassDefinitionTreeNode::class, ClassDefinitionTreeNodeFolder::class])
37+
)
38+
);
39+
}
40+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
/**
5+
* This source file is available under the terms of the
6+
* Pimcore Open Core License (POCL)
7+
* Full copyright and license information is available in
8+
* LICENSE.md which is distributed with this source code.
9+
*
10+
* @copyright Copyright (c) Pimcore GmbH (https://www.pimcore.com)
11+
* @license Pimcore Open Core License (POCL)
12+
*/
13+
14+
namespace Pimcore\Bundle\StudioBackendBundle\Class\Controller;
15+
16+
use OpenApi\Attributes\Get;
17+
use Pimcore\Bundle\StudioBackendBundle\Class\Schema\ClassDefinitionList;
18+
use Pimcore\Bundle\StudioBackendBundle\Class\Service\ClassDefinitionServiceInterface;
19+
use Pimcore\Bundle\StudioBackendBundle\Controller\AbstractApiController;
20+
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Property\GenericCollection;
21+
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\Content\CollectionJson;
22+
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\DefaultResponses;
23+
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\SuccessResponse;
24+
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Config\Tags;
25+
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\HttpResponseCodes;
26+
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\UserPermissions;
27+
use Pimcore\Bundle\StudioBackendBundle\Util\Trait\PaginatedResponseTrait;
28+
use Symfony\Component\HttpFoundation\JsonResponse;
29+
use Symfony\Component\Routing\Attribute\Route;
30+
use Symfony\Component\Security\Http\Attribute\IsGranted;
31+
use Symfony\Component\Serializer\SerializerInterface;
32+
use function count;
33+
34+
final class CreatableCollectionController extends AbstractApiController
35+
{
36+
use PaginatedResponseTrait;
37+
38+
public function __construct(
39+
SerializerInterface $serializer,
40+
private readonly ClassDefinitionServiceInterface $classDefinitionService
41+
) {
42+
parent::__construct($serializer);
43+
}
44+
45+
#[Route(
46+
'/class/collection/creatable',
47+
name: 'pimcore_studio_api_classes_collection_creatable',
48+
methods: ['GET']
49+
)]
50+
#[IsGranted(UserPermissions::DATA_OBJECTS->value)]
51+
#[Get(
52+
path: self::PREFIX . '/class/collection/creatable',
53+
operationId: 'class_definition_collection_creatable',
54+
description: 'class_definition_collection_creatable_description',
55+
summary: 'class_definition_collection_creatable_summary',
56+
tags: [Tags::ClassDefinition->value],
57+
)]
58+
#[SuccessResponse(
59+
description: 'class_definition_collection_creatable_success_response',
60+
content: new CollectionJson(new GenericCollection(ClassDefinitionList::class))
61+
)]
62+
#[DefaultResponses([
63+
HttpResponseCodes::UNAUTHORIZED,
64+
])]
65+
public function listClasses(): JsonResponse
66+
{
67+
$items = $this->classDefinitionService->getClassDefinitionCollection(true);
68+
69+
return $this->getPaginatedCollection(
70+
$this->serializer,
71+
$items,
72+
count($items)
73+
);
74+
}
75+
}

src/Class/Controller/GetController.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public function __construct(
4545
#[Route(
4646
'/class/definition/{dataObjectClass}',
4747
name: 'pimcore_studio_api_class_definition_get',
48+
requirements: ['dataObjectClass' => '^(?!configuration-view(/|$)).+'],
4849
methods: ['GET']
4950
)]
5051
#[IsGranted(UserPermissions::DATA_OBJECTS->value)]
@@ -72,7 +73,7 @@ public function __construct(
7273
public function getClassDefinition(string $dataObjectClass): JsonResponse
7374
{
7475
return $this->jsonResponse(
75-
$this->classDefinitionService->getClassDefinition($dataObjectClass)
76+
$this->classDefinitionService->getClassDefinitionByName($dataObjectClass)
7677
);
7778
}
7879
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
/**
5+
* This source file is available under the terms of the
6+
* Pimcore Open Core License (POCL)
7+
* Full copyright and license information is available in
8+
* LICENSE.md which is distributed with this source code.
9+
*
10+
* @copyright Copyright (c) Pimcore GmbH (https://www.pimcore.com)
11+
* @license Pimcore Open Core License (POCL)
12+
*/
13+
14+
namespace Pimcore\Bundle\StudioBackendBundle\Class\Controller;
15+
16+
use OpenApi\Attributes\Get;
17+
use Pimcore\Bundle\StudioBackendBundle\Class\Attribute\Response\Property\AnyOfClassDefinitionNodes;
18+
use Pimcore\Bundle\StudioBackendBundle\Class\MappedParameter\ClassDefinitionTreeParameter;
19+
use Pimcore\Bundle\StudioBackendBundle\Class\Service\ClassDefinitionTreeServiceInterface;
20+
use Pimcore\Bundle\StudioBackendBundle\Controller\AbstractApiController;
21+
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Parameter\Query\BoolParameter;
22+
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\Content\CollectionJson;
23+
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\DefaultResponses;
24+
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\SuccessResponse;
25+
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Config\Tags;
26+
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\HttpResponseCodes;
27+
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\UserPermissions;
28+
use Pimcore\Bundle\StudioBackendBundle\Util\Trait\PaginatedResponseTrait;
29+
use Symfony\Component\HttpFoundation\JsonResponse;
30+
use Symfony\Component\HttpKernel\Attribute\MapQueryString;
31+
use Symfony\Component\Routing\Attribute\Route;
32+
use Symfony\Component\Security\Http\Attribute\IsGranted;
33+
use Symfony\Component\Serializer\SerializerInterface;
34+
use function count;
35+
36+
/**
37+
* @internal
38+
*/
39+
final class TreeController extends AbstractApiController
40+
{
41+
use PaginatedResponseTrait;
42+
43+
private const string ROUTE = '/class/definition/configuration-view/tree';
44+
45+
public function __construct(
46+
SerializerInterface $serializer,
47+
private readonly ClassDefinitionTreeServiceInterface $treeService,
48+
) {
49+
parent::__construct($serializer);
50+
}
51+
52+
#[Route(self::ROUTE, name: 'pimcore_studio_api_classes_tree', methods: ['GET'])]
53+
#[IsGranted(UserPermissions::CLASS_DEFINITION->value)]
54+
#[Get(
55+
path: self::PREFIX . self::ROUTE,
56+
operationId: 'class_definition_get_tree',
57+
description: 'class_definition_get_tree_description',
58+
summary: 'class_definition_get_tree_summary',
59+
tags: [Tags::ClassDefinition->value]
60+
)]
61+
#[BoolParameter('withGroup', description: 'Whether to group the results.', example: true)]
62+
#[SuccessResponse(
63+
description: 'class_definition_get_tree_success_response',
64+
content: new CollectionJson(new AnyOfClassDefinitionNodes())
65+
)]
66+
#[DefaultResponses([HttpResponseCodes::UNAUTHORIZED])]
67+
public function getClassDefinitionTree(#[MapQueryString] ClassDefinitionTreeParameter $parameters): JsonResponse
68+
{
69+
$definitions = $this->treeService->getTree($parameters->isWithGroup());
70+
71+
return $this->getPaginatedCollection(
72+
$this->serializer,
73+
$definitions,
74+
count($definitions)
75+
);
76+
}
77+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
/**
5+
* This source file is available under the terms of the
6+
* Pimcore Open Core License (POCL)
7+
* Full copyright and license information is available in
8+
* LICENSE.md which is distributed with this source code.
9+
*
10+
* @copyright Copyright (c) Pimcore GmbH (https://www.pimcore.com)
11+
* @license Pimcore Open Core License (POCL)
12+
*/
13+
14+
namespace Pimcore\Bundle\StudioBackendBundle\Class\Hydrator\Tree;
15+
16+
use Pimcore\Bundle\StudioBackendBundle\Class\Schema\ClassDefinitionTreeNodeFolder;
17+
use Pimcore\Bundle\StudioBackendBundle\Response\ElementIcon;
18+
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\ElementIconTypes;
19+
20+
/**
21+
* @internal
22+
*/
23+
final readonly class FolderNodeHydrator implements FolderNodeHydratorInterface
24+
{
25+
private const string ICON_NAME = 'class_folder';
26+
27+
/**
28+
* {@inheritdoc}
29+
*/
30+
public function hydrate(string $groupName, array $children): ClassDefinitionTreeNodeFolder
31+
{
32+
return new ClassDefinitionTreeNodeFolder(
33+
'folder_' . $groupName,
34+
$groupName,
35+
$groupName,
36+
new ElementIcon(ElementIconTypes::NAME->value, self::ICON_NAME),
37+
null,
38+
$children
39+
);
40+
}
41+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
/**
5+
* This source file is available under the terms of the
6+
* Pimcore Open Core License (POCL)
7+
* Full copyright and license information is available in
8+
* LICENSE.md which is distributed with this source code.
9+
*
10+
* @copyright Copyright (c) Pimcore GmbH (https://www.pimcore.com)
11+
* @license Pimcore Open Core License (POCL)
12+
*/
13+
14+
namespace Pimcore\Bundle\StudioBackendBundle\Class\Hydrator\Tree;
15+
16+
use Pimcore\Bundle\StudioBackendBundle\Class\Schema\ClassDefinitionTreeNode;
17+
use Pimcore\Bundle\StudioBackendBundle\Class\Schema\ClassDefinitionTreeNodeFolder;
18+
19+
/**
20+
* @internal
21+
*/
22+
interface FolderNodeHydratorInterface
23+
{
24+
/**
25+
* @param ClassDefinitionTreeNode[] $children
26+
*/
27+
public function hydrate(string $groupName, array $children): ClassDefinitionTreeNodeFolder;
28+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
/**
5+
* This source file is available under the terms of the
6+
* Pimcore Open Core License (POCL)
7+
* Full copyright and license information is available in
8+
* LICENSE.md which is distributed with this source code.
9+
*
10+
* @copyright Copyright (c) Pimcore GmbH (https://www.pimcore.com)
11+
* @license Pimcore Open Core License (POCL)
12+
*/
13+
14+
namespace Pimcore\Bundle\StudioBackendBundle\Class\Hydrator\Tree;
15+
16+
use Pimcore\Bundle\StudioBackendBundle\Class\Schema\ClassDefinitionTreeNode;
17+
use Pimcore\Bundle\StudioBackendBundle\Icon\Service\IconServiceInterface;
18+
use Pimcore\Model\DataObject\ClassDefinition;
19+
use Pimcore\Model\DataObject\ClassDefinition\Data\Objectbricks;
20+
21+
/**
22+
* @internal
23+
*/
24+
final readonly class NodeHydrator implements NodeHydratorInterface
25+
{
26+
public function __construct(
27+
private IconServiceInterface $iconService
28+
) {
29+
}
30+
31+
public function hydrate(ClassDefinition $class): ClassDefinitionTreeNode
32+
{
33+
$hasBrickField = false;
34+
foreach ($class->getFieldDefinitions() as $fieldDefinition) {
35+
if ($fieldDefinition instanceof Objectbricks) {
36+
$hasBrickField = true;
37+
38+
break;
39+
}
40+
}
41+
42+
return new ClassDefinitionTreeNode(
43+
$class->getId(),
44+
$class->getName(),
45+
$class->getTitle(),
46+
$this->iconService->getIconForClassDefinition($class->getIcon()),
47+
$class->getGroup(),
48+
$class->isEnableGridLocking(),
49+
$hasBrickField
50+
);
51+
}
52+
}

0 commit comments

Comments
 (0)