Skip to content
Draft
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
e15b038
type fix, add pagination and new data object provider
stunnerparas Nov 26, 2025
54314c4
Apply php-cs-fixer changes
stunnerparas Nov 26, 2025
d79721c
changes
stunnerparas Nov 26, 2025
a41bbfa
Apply php-cs-fixer changes
stunnerparas Nov 26, 2025
097e403
Also add pagination in Pimcore Users
stunnerparas Nov 26, 2025
5f86dbe
Apply php-cs-fixer changes
stunnerparas Nov 26, 2025
c50f9c4
ci issue fix
stunnerparas Nov 26, 2025
5692ef6
ci issue fix
stunnerparas Nov 26, 2025
0054400
changes in export of data object and some code improvement
stunnerparas Nov 26, 2025
6476a45
Data object provider fix issues and rephase and add interface
stunnerparas Nov 27, 2025
cdff53f
Apply php-cs-fixer changes
stunnerparas Nov 27, 2025
dd91417
ci fix
stunnerparas Nov 27, 2025
812764e
Apply php-cs-fixer changes
stunnerparas Nov 27, 2025
b642e54
Fix the review issue and some changes
stunnerparas Nov 27, 2025
8c469a8
Apply php-cs-fixer changes
stunnerparas Nov 27, 2025
ef73aae
ci issue fix
stunnerparas Nov 27, 2025
d82d6da
Apply php-cs-fixer changes
stunnerparas Nov 27, 2025
3a348bc
filter in data object
stunnerparas Nov 27, 2025
9f05de2
Apply php-cs-fixer changes
stunnerparas Nov 27, 2025
361b923
rephase
stunnerparas Nov 27, 2025
503a7f3
Apply php-cs-fixer changes
stunnerparas Nov 27, 2025
41d7791
change delete option
stunnerparas Nov 28, 2025
d722961
Merge branch '1.x' into 840_dataobject
stunnerparas Nov 28, 2025
01bde69
Add assets and pagination
stunnerparas Nov 28, 2025
e8f3dc3
Apply php-cs-fixer changes
stunnerparas Nov 28, 2025
0418b49
Update export of asset
stunnerparas Nov 28, 2025
7b9037b
Apply php-cs-fixer changes
stunnerparas Nov 28, 2025
b287105
sonar issue fix
stunnerparas Nov 28, 2025
cd21709
changes
stunnerparas Nov 28, 2025
d46e66f
Change the assets to zip and some improvements
stunnerparas Dec 1, 2025
5b5b859
Apply php-cs-fixer changes
stunnerparas Dec 1, 2025
28ec677
Ci issue fix
stunnerparas Dec 1, 2025
44e14c9
Apply php-cs-fixer changes
stunnerparas Dec 1, 2025
5b99772
fix
stunnerparas Dec 1, 2025
1c8e506
ci issue fix
stunnerparas Dec 1, 2025
fdd93ec
ci issue fix
stunnerparas Dec 1, 2025
378d169
review fixes
stunnerparas Dec 1, 2025
cf9f3fa
Apply php-cs-fixer changes
stunnerparas Dec 1, 2025
d7a499d
handle for both array and Response
stunnerparas Dec 1, 2025
c3cdf6e
Apply php-cs-fixer changes
stunnerparas Dec 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions config/gdpr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,16 @@ services:
tags: ["pimcore.studio_backend.gdpr_data_provider"]
arguments:
$logsDir: "%kernel.logs_dir%"

Pimcore\Bundle\StudioBackendBundle\Gdpr\Provider\DataObjectProvider:
tags: ["pimcore.studio_backend.gdpr_data_provider"]

Pimcore\Bundle\StudioBackendBundle\Gdpr\Provider\AssetsProvider:
tags: ["pimcore.studio_backend.gdpr_data_provider"]

# --- Legacy Code from the admin-ui-classic-bundle ---
Pimcore\Bundle\StudioBackendBundle\Gdpr\Provider\Legacy\ObjectExporterInterface:
class: Pimcore\Bundle\StudioBackendBundle\Gdpr\Provider\Legacy\ObjectExporter

Pimcore\Bundle\StudioBackendBundle\Gdpr\Provider\Legacy\AssetExporterInterface:
class: Pimcore\Bundle\StudioBackendBundle\Gdpr\Provider\Legacy\AssetExporter
3 changes: 3 additions & 0 deletions src/Gdpr/Attribute/Request/GdprRequestBody.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use OpenApi\Attributes\JsonContent;
use OpenApi\Attributes\Property;
use OpenApi\Attributes\RequestBody;
use Pimcore\Bundle\StudioBackendBundle\Filter\Attribute\Property\FilterProperty;

/**
* @internal
Expand Down Expand Up @@ -49,6 +50,8 @@ public function __construct()
description: 'The object containing the search values.',
type: 'object'
),

new FilterProperty(),
],
type: 'object',
),
Expand Down
40 changes: 30 additions & 10 deletions src/Gdpr/Attribute/Request/SearchTerms.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,41 @@
final readonly class SearchTerms
{
public function __construct(
#[Property(description: 'The ID to search for.', type: 'string', nullable: true)]
#[Type('string')]
public ?string $id = null,
#[Property(
description: 'The ID to search for.',
type: 'int',
nullable: true,
example: 3
)]
#[Type('int')]
private ?int $id = null,

#[Property(description: 'The first name to search for.', type: 'string', nullable: true)]
#[Property(
description: 'The first name to search for.',
type: 'string',
nullable: true,
example: 'John'
)]
#[Type('string')]
public ?string $firstname = null,
private ?string $firstname = null,

#[Property(description: 'The last name to search for.', type: 'string', nullable: true)]
#[Property(
description: 'The last name to search for.',
type: 'string',
nullable: true,
example: 'Doe'
)]
#[Type('string')]
public ?string $lastname = null,
private ?string $lastname = null,

#[Property(description: 'The email address to search for.', type: 'string', nullable: true)]
#[Property(
description: 'The email address to search for.',
type: 'string',
nullable: true,
example: '[email protected]'
)]
#[Type('string')]
public ?string $email = null,
private ?string $email = null,
) {
if ($this->id === null &&
$this->firstname === null &&
Expand All @@ -54,7 +74,7 @@ public function __construct(
}
}

public function getId(): ?string
public function getId(): ?int
{
return $this->id;
}
Expand Down
13 changes: 10 additions & 3 deletions src/Gdpr/Controller/SearchDataProviderController.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
use Pimcore\Bundle\StudioBackendBundle\Controller\AbstractApiController;
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\NotFoundException;
use Pimcore\Bundle\StudioBackendBundle\Gdpr\Attribute\Request\GdprRequestBody;
use Pimcore\Bundle\StudioBackendBundle\Gdpr\MappedParameter\GdprStructuredSearchRequest;
use Pimcore\Bundle\StudioBackendBundle\Gdpr\MappedParameter\GdprStructuredSearchParameters;
use Pimcore\Bundle\StudioBackendBundle\Gdpr\Schema\GdprSearchResultProperty;
use Pimcore\Bundle\StudioBackendBundle\Gdpr\Service\GdprManagerServiceInterface;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\Content\CollectionJson;
Expand All @@ -26,6 +26,7 @@
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Config\Tags;
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\HttpResponseCodes;
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\UserPermissions;
use Pimcore\Bundle\StudioBackendBundle\Util\Trait\PaginatedResponseTrait;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
use Symfony\Component\Routing\Attribute\Route;
Expand All @@ -37,6 +38,8 @@
*/
final class SearchDataProviderController extends AbstractApiController
{
use PaginatedResponseTrait;

public function __construct(
SerializerInterface $serializer,
private readonly GdprManagerServiceInterface $gdprManagerService,
Expand Down Expand Up @@ -77,11 +80,15 @@ public function __construct(
HttpResponseCodes::UNPROCESSABLE_CONTENT,
])]
public function searchData(
#[MapRequestPayload] GdprStructuredSearchRequest $request
#[MapRequestPayload] GdprStructuredSearchParameters $request
): JsonResponse {

$collection = $this->gdprManagerService->search($request);

return $this->jsonResponse($collection);
return $this->getPaginatedCollection(
$this->serializer,
$collection->getItems(),
$collection->getTotalItems()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

namespace Pimcore\Bundle\StudioBackendBundle\Gdpr\MappedParameter;

use Pimcore\Bundle\StudioBackendBundle\Filter\MappedParameter\FilterParameter;
use Pimcore\Bundle\StudioBackendBundle\Gdpr\Attribute\Request\SearchTerms;
use Symfony\Component\Validator\Constraints\All;
use Symfony\Component\Validator\Constraints\NotBlank;
Expand All @@ -23,7 +24,7 @@
/**
* @internal
*/
final readonly class GdprStructuredSearchRequest
final readonly class GdprStructuredSearchParameters
{
/**
* @param string[] $providers
Expand All @@ -35,7 +36,10 @@ public function __construct(

#[Valid]
#[NotNull]
public SearchTerms $searchTerms
public SearchTerms $searchTerms,

#[Valid]
public FilterParameter $filters
) {
}
}
158 changes: 158 additions & 0 deletions src/Gdpr/Provider/AssetsProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
<?php

/**
* This source file is available under the terms of the
* Pimcore Open Core License (POCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (https://www.pimcore.com)
* @license Pimcore Open Core License (POCL)
*/

namespace Pimcore\Bundle\StudioBackendBundle\Gdpr\Provider;

use Pimcore\Bundle\GenericDataIndexBundle\Enum\Search\SortDirection;
use Pimcore\Bundle\StudioBackendBundle\DataIndex\Provider\AssetQueryProviderInterface;
use Pimcore\Bundle\StudioBackendBundle\DataIndex\Query\QueryInterface;
use Pimcore\Bundle\StudioBackendBundle\DataIndex\Service\AssetSearchServiceInterface;
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\NotFoundException;
use Pimcore\Bundle\StudioBackendBundle\Filter\MappedParameter\FilterParameter;
use Pimcore\Bundle\StudioBackendBundle\Gdpr\Attribute\Request\SearchTerms;
use Pimcore\Bundle\StudioBackendBundle\Gdpr\Provider\Legacy\AssetExporterInterface;
use Pimcore\Bundle\StudioBackendBundle\Gdpr\Schema\GdprDataColumn;
use Pimcore\Bundle\StudioBackendBundle\Gdpr\Schema\GdprDataRow;
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\UserPermissions;
use Pimcore\Model\Asset;

/**
* @internal
*/
final readonly class AssetsProvider implements DataProviderInterface
{
public function __construct(
private AssetQueryProviderInterface $query,
private AssetSearchServiceInterface $searchService,
private AssetExporterInterface $assetExporter
) {
}

/**
* {@inheritdoc}
*/
public function findData(SearchTerms $terms, FilterParameter $options): array
{
$query = $this->query->createAssetQuery();

$query->excludeFolders();

if ($terms->getId() !== null) {
$query->filterInteger('id', $terms->getId());
}

$texts = [
$terms->getFirstname(),
$terms->getLastname(),
$terms->getEmail(),
];

foreach ($texts as $value) {
$value = trim((string)$value);
if ($value !== '') {
$query->filterFullText($value);
}
}

$this->applySearchOptions($query, $options);

$searchResult = $this->searchService->searchAssets($query);

$columns = $this->getAvailableColumns();

$items = $searchResult->getItems();

return array_map(
fn ($item) => new GdprDataRow([
'type' => $item->getType(),
'id' => $item->getId(),
'fullPath' => $item->getFullPath(),
'subType' => $item->getMimeType(),
], $columns),
$items
);
}

private function applySearchOptions(QueryInterface $query, FilterParameter $options): void
{
$query->setPage($options->getPage());
$query->setPageSize($options->getPageSize());

$sortFilter = $options->getSortFilter();

if ($sortFilter->getKey() && $sortFilter->getDirection()) {
$directionEnum = strtolower($sortFilter->getDirection()) === SortDirection::DESC->value
? SortDirection::DESC
: SortDirection::ASC;

$query->orderByField($sortFilter->getKey(), $directionEnum);
}

}

public function getDeleteSwaggerOperationId(): string
{
return 'pimcore_studio_api_assets_batch_delete';
}

/**
* {@inheritdoc}
*/
public function getSingleItemForDownload(int $id): array
{
try {
$asset = Asset::getById((int)$id);

} catch (NotFoundException) {
throw new NotFoundException('Asset Not Found', $id);
}

return $this->assetExporter->doexportAsset($asset);

}

public function getName(): string
{
return 'Assets';
}

public function getKey(): string
{
return 'assets';
}

public function getSortPriority(): int
{
return 8;
}

/**
* {@inheritdoc}
*/
public function getRequiredPermissions(): array
{
return [UserPermissions::ASSETS->value];
}

/**
* {@inheritdoc}
*/
public function getAvailableColumns(): array
{
return [
new GdprDataColumn('type', 'Type'),
new GdprDataColumn('id', 'ID'),
new GdprDataColumn('fullPath', 'Full Path'),
new GdprDataColumn('subType', 'Type'),
];
}
}
Loading
Loading