Skip to content

Commit c9cd5f8

Browse files
authored
[Class Definitions] - Bulk Export/Import (#1690)
* add class bulk export/import * Apply php-cs-fixer changes * code style * Apply php-cs-fixer changes * code style * Apply php-cs-fixer changes
1 parent daa0490 commit c9cd5f8

44 files changed

Lines changed: 2571 additions & 8 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

config/class.yaml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,23 @@ services:
5959
Pimcore\Bundle\StudioBackendBundle\Class\Service\FieldsByTypeServiceInterface:
6060
class: Pimcore\Bundle\StudioBackendBundle\Class\Service\FieldsByTypeService
6161

62+
Pimcore\Bundle\StudioBackendBundle\Class\Service\BulkExport\BulkExportServiceInterface:
63+
class: Pimcore\Bundle\StudioBackendBundle\Class\Service\BulkExport\BulkExportService
64+
65+
Pimcore\Bundle\StudioBackendBundle\Class\Service\BulkImport\BulkImportFileServiceInterface:
66+
class: Pimcore\Bundle\StudioBackendBundle\Class\Service\BulkImport\BulkImportFileService
67+
68+
Pimcore\Bundle\StudioBackendBundle\Class\Service\BulkImport\BulkImportServiceInterface:
69+
class: Pimcore\Bundle\StudioBackendBundle\Class\Service\BulkImport\BulkImportService
70+
71+
Pimcore\Bundle\StudioBackendBundle\Class\Service\BulkImport\BulkImportExecutorInterface:
72+
class: Pimcore\Bundle\StudioBackendBundle\Class\Service\BulkImport\BulkImportExecutor
73+
74+
Pimcore\Bundle\StudioBackendBundle\Class\Service\BulkImport\BulkImportDataResolver: ~
75+
76+
Pimcore\Bundle\StudioBackendBundle\Class\Service\BulkImport\BulkImportJobServiceInterface:
77+
class: Pimcore\Bundle\StudioBackendBundle\Class\Service\BulkImport\BulkImportJobService
78+
6279
#
6380
# Repositories
6481
#
@@ -155,3 +172,19 @@ services:
155172

156173
Pimcore\Bundle\StudioBackendBundle\Class\Hydrator\SelectOption\DetailHydratorInterface:
157174
class: Pimcore\Bundle\StudioBackendBundle\Class\Hydrator\SelectOption\DetailHydrator
175+
176+
Pimcore\Bundle\StudioBackendBundle\Class\Hydrator\BulkExport\BulkExportHydratorInterface:
177+
class: Pimcore\Bundle\StudioBackendBundle\Class\Hydrator\BulkExport\BulkExportHydrator
178+
179+
#
180+
# Handler
181+
#
182+
183+
Pimcore\Bundle\StudioBackendBundle\Class\ExecutionEngine\AutomationAction\Messenger\Handler\BulkImportHandler: ~
184+
Pimcore\Bundle\StudioBackendBundle\Class\ExecutionEngine\AutomationAction\Messenger\Handler\BulkImportCleanupHandler: ~
185+
186+
#
187+
# Event Subscriber
188+
#
189+
190+
Pimcore\Bundle\StudioBackendBundle\Class\EventSubscriber\BulkImportSubscriber: ~

config/pimcore/execution_engine.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,6 @@ framework:
3232
Pimcore\Bundle\StudioBackendBundle\Tag\ExecutionEngine\AutomationAction\Messenger\Messages\BatchTagOperationMessage: pimcore_generic_execution_engine
3333
Pimcore\Bundle\StudioBackendBundle\RecycleBin\ExecutionEngine\Messages\DeleteItemsMessage: pimcore_generic_execution_engine
3434
Pimcore\Bundle\StudioBackendBundle\RecycleBin\ExecutionEngine\Messages\RestoreItemsMessage: pimcore_generic_execution_engine
35-
Pimcore\Bundle\StudioBackendBundle\Element\ExecutionEngine\AutomationAction\Messenger\Messages\ElementUsageReplaceMessage: pimcore_generic_execution_engine
35+
Pimcore\Bundle\StudioBackendBundle\Element\ExecutionEngine\AutomationAction\Messenger\Messages\ElementUsageReplaceMessage: pimcore_generic_execution_engine
36+
Pimcore\Bundle\StudioBackendBundle\Class\ExecutionEngine\AutomationAction\Messenger\Messages\BulkImportMessage: pimcore_generic_execution_engine
37+
Pimcore\Bundle\StudioBackendBundle\Class\ExecutionEngine\AutomationAction\Messenger\Messages\BulkImportCleanupMessage: pimcore_generic_execution_engine

doc/05_Additional_Custom_Attributes.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ final class AssetEvent extends AbstractPreResponseEvent
8181
- `pre_response.bundle_seo.redirect.import_stats`
8282
- `pre_response.bundle_seo.redirect.list`
8383
- `pre_response.bundle_seo.redirect.status`
84+
- `pre_response.class.bulk_export_available_item`
85+
- `pre_response.class.bulk_import_prepare`
86+
- `pre_response.class.bulk_import_result_item`
8487
- `pre_response.class_definition`
8588
- `pre_response.class_definition.visible_field`
8689
- `pre_response.class_definition.collection`
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
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\BulkExport;
15+
16+
use OpenApi\Attributes\Get;
17+
use Pimcore\Bundle\StudioBackendBundle\Class\Schema\BulkExport\BulkExportAvailableItem;
18+
use Pimcore\Bundle\StudioBackendBundle\Class\Service\BulkExport\BulkExportServiceInterface;
19+
use Pimcore\Bundle\StudioBackendBundle\Controller\AbstractApiController;
20+
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\EnvironmentException;
21+
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\UserNotFoundException;
22+
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\Content\ItemsJson;
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 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+
33+
/**
34+
* @internal
35+
*/
36+
final class AvailableController extends AbstractApiController
37+
{
38+
private const string ROUTE = '/class/bulk-export/available';
39+
40+
public function __construct(
41+
SerializerInterface $serializer,
42+
private readonly BulkExportServiceInterface $bulkExportService,
43+
) {
44+
parent::__construct($serializer);
45+
}
46+
47+
/**
48+
* @throws EnvironmentException|UserNotFoundException
49+
*/
50+
#[Route(
51+
path: self::ROUTE,
52+
name: 'pimcore_studio_api_class_bulk_export_available',
53+
methods: ['GET'],
54+
)]
55+
#[IsGranted(UserPermissions::DATA_OBJECTS->value)]
56+
#[Get(
57+
path: self::PREFIX . self::ROUTE,
58+
operationId: 'class_bulk_export_available',
59+
description: 'class_bulk_export_available_description',
60+
summary: 'class_bulk_export_available_summary',
61+
tags: [Tags::ClassDefinition->value],
62+
)]
63+
#[SuccessResponse(
64+
description: 'class_bulk_export_available_success_response',
65+
content: new ItemsJson(BulkExportAvailableItem::class)
66+
)]
67+
#[DefaultResponses([
68+
HttpResponseCodes::UNAUTHORIZED,
69+
])]
70+
public function getAvailableItems(): JsonResponse
71+
{
72+
return $this->jsonResponse(
73+
['items' => $this->bulkExportService->getAvailableItems()]
74+
);
75+
}
76+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
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\BulkExport;
15+
16+
use OpenApi\Attributes\Post;
17+
use Pimcore\Bundle\StudioBackendBundle\Class\MappedParameter\BulkExportParameters;
18+
use Pimcore\Bundle\StudioBackendBundle\Class\Service\BulkExport\BulkExportServiceInterface;
19+
use Pimcore\Bundle\StudioBackendBundle\Controller\AbstractApiController;
20+
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\EnvironmentException;
21+
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\NotFoundException;
22+
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\UserNotFoundException;
23+
use Pimcore\Bundle\StudioBackendBundle\Export\Service\DownloadServiceInterface;
24+
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Request\ReferenceRequestBody;
25+
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\Content\MediaType;
26+
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\DefaultResponses;
27+
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\Header\ContentDisposition;
28+
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\SuccessResponse;
29+
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Config\Tags;
30+
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\Asset\MimeTypes;
31+
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\HttpResponseCodes;
32+
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\UserPermissions;
33+
use Symfony\Component\HttpFoundation\Response;
34+
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
35+
use Symfony\Component\Routing\Attribute\Route;
36+
use Symfony\Component\Security\Http\Attribute\IsGranted;
37+
use Symfony\Component\Serializer\SerializerInterface;
38+
39+
/**
40+
* @internal
41+
*/
42+
final class ExportController extends AbstractApiController
43+
{
44+
private const string ROUTE = '/class/bulk-export';
45+
46+
public function __construct(
47+
SerializerInterface $serializer,
48+
private readonly BulkExportServiceInterface $bulkExportService,
49+
private readonly DownloadServiceInterface $downloadService,
50+
) {
51+
parent::__construct($serializer);
52+
}
53+
54+
/**
55+
* @throws EnvironmentException|NotFoundException|UserNotFoundException
56+
*/
57+
#[Route(
58+
path: self::ROUTE,
59+
name: 'pimcore_studio_api_class_bulk_export',
60+
methods: ['POST'],
61+
)]
62+
#[IsGranted(UserPermissions::DATA_OBJECTS->value)]
63+
#[Post(
64+
path: self::PREFIX . self::ROUTE,
65+
operationId: 'class_bulk_export',
66+
description: 'class_bulk_export_description',
67+
summary: 'class_bulk_export_summary',
68+
tags: [Tags::ClassDefinition->value],
69+
)]
70+
#[ReferenceRequestBody(BulkExportParameters::class)]
71+
#[SuccessResponse(
72+
description: 'class_bulk_export_success_response',
73+
content: [new MediaType(MimeTypes::JSON->value)],
74+
headers: [new ContentDisposition(fileName: 'bulk_export.json')]
75+
)]
76+
#[DefaultResponses([
77+
HttpResponseCodes::UNAUTHORIZED,
78+
HttpResponseCodes::NOT_FOUND,
79+
])]
80+
public function exportItems(
81+
#[MapRequestPayload] BulkExportParameters $parameters
82+
): Response {
83+
$export = $this->bulkExportService->exportItems($parameters);
84+
85+
return $this->downloadService->downloadJSON(
86+
$export->getJson(),
87+
$export->getFileName()
88+
);
89+
}
90+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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\BulkImport;
15+
16+
use OpenApi\Attributes\Delete;
17+
use Pimcore\Bundle\StudioBackendBundle\Class\Service\BulkImport\BulkImportFileServiceInterface;
18+
use Pimcore\Bundle\StudioBackendBundle\Controller\AbstractApiController;
19+
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\EnvironmentException;
20+
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\NotFoundException;
21+
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Parameter\Path\StringParameter;
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 Symfony\Component\HttpFoundation\Response;
28+
use Symfony\Component\Routing\Attribute\Route;
29+
use Symfony\Component\Security\Http\Attribute\IsGranted;
30+
use Symfony\Component\Serializer\SerializerInterface;
31+
32+
/**
33+
* @internal
34+
*/
35+
final class DeleteBulkFileController extends AbstractApiController
36+
{
37+
private const string ROUTE = '/class/bulk-import/{fileId}';
38+
39+
public function __construct(
40+
SerializerInterface $serializer,
41+
private readonly BulkImportFileServiceInterface $bulkImportFileService,
42+
) {
43+
parent::__construct($serializer);
44+
}
45+
46+
/**
47+
* @throws NotFoundException
48+
* @throws EnvironmentException
49+
*/
50+
#[Route(
51+
path: self::ROUTE,
52+
name: 'pimcore_studio_api_class_bulk_import_delete_file',
53+
methods: ['DELETE'],
54+
)]
55+
#[IsGranted(UserPermissions::DATA_OBJECTS->value)]
56+
#[Delete(
57+
path: self::PREFIX . self::ROUTE,
58+
operationId: 'class_bulk_import_delete_file',
59+
description: 'class_bulk_import_delete_file_description',
60+
summary: 'class_bulk_import_delete_file_summary',
61+
tags: [Tags::ClassDefinition->value],
62+
)]
63+
#[StringParameter(
64+
name: 'fileId',
65+
example: '6792e2b43f0a7',
66+
description: 'File identifier returned by the prepare import endpoint',
67+
required: true
68+
)]
69+
#[SuccessResponse(
70+
description: 'class_bulk_import_delete_file_success_response',
71+
)]
72+
#[DefaultResponses([
73+
HttpResponseCodes::UNAUTHORIZED,
74+
HttpResponseCodes::NOT_FOUND,
75+
])]
76+
public function deleteBulkFile(string $fileId): Response
77+
{
78+
$this->bulkImportFileService->deleteBulkFile($fileId);
79+
80+
return new Response();
81+
}
82+
}

0 commit comments

Comments
 (0)