Skip to content

Commit

Permalink
add endpoint to list asset predefined metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
lukmzig committed Dec 10, 2024
1 parent e7dacc8 commit 34202b6
Show file tree
Hide file tree
Showing 8 changed files with 211 additions and 10 deletions.
7 changes: 6 additions & 1 deletion src/Metadata/Controller/Asset/GetController.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,12 @@ public function __construct(
/**
* @throws AccessDeniedException
*/
#[Route('/assets/{id}/custom-metadata', name: 'pimcore_studio_api_get_asset_custom_metadata', methods: ['GET'])]
#[Route(
'/assets/{id}/custom-metadata',
name: 'pimcore_studio_api_get_asset_custom_metadata',
requirements: ['id' => '\d+'],
methods: ['GET']
)]
#[IsGranted(UserPermissions::ASSETS->value)]
#[GET(
path: self::PREFIX . '/assets/{id}/custom-metadata',
Expand Down
79 changes: 79 additions & 0 deletions src/Metadata/Controller/Asset/GetPredefinedController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?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\Metadata\Controller\Asset;

use OpenApi\Attributes\Get;
use Pimcore\Bundle\StudioBackendBundle\Controller\AbstractApiController;
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\AccessDeniedException;
use Pimcore\Bundle\StudioBackendBundle\Metadata\MappedParameter\PredefinedMetadataParameter;
use Pimcore\Bundle\StudioBackendBundle\Metadata\Schema\PredefinedMetadata;
use Pimcore\Bundle\StudioBackendBundle\Metadata\Service\MetadataServiceInterface;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Content\ItemsJson;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Parameter\Query\TextFieldParameter;
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\Constant\UserPermissions;
use Pimcore\Bundle\StudioBackendBundle\Util\Trait\ElementProviderTrait;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Attribute\MapQueryString;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
use Symfony\Component\Serializer\SerializerInterface;

/**
* @internal
*/
final class GetPredefinedController extends AbstractApiController
{
use ElementProviderTrait;

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

/**
* @throws AccessDeniedException
*/
#[Route('/assets/predefined-metadata', name: 'pimcore_studio_api_get_asset_predefined_metadata', methods: ['GET'])]
#[IsGranted(UserPermissions::ASSETS->value)]
#[GET(
path: self::PREFIX . '/assets/predefined-metadata',
operationId: 'asset_get_predefined_metadata',
description: 'asset_get_predefined_metadata_description',
summary: 'asset_get_predefined_metadata_summary',
tags: [Tags::Metadata->name]
)]
#[TextFieldParameter(name: 'subType', description: 'subtype of the asset', required: false, example: 'image')]
#[TextFieldParameter(name: 'group', description: 'group of the metadata', required: true, example: 'default')]
#[SuccessResponse(
description: 'asset_get_predefined_metadata_success_response',
content: new ItemsJson(PredefinedMetadata::class)
)]
#[DefaultResponses([
HttpResponseCodes::UNAUTHORIZED,
HttpResponseCodes::NOT_FOUND,
])]
public function getAssetPredefinedMetadata(#[MapQueryString] PredefinedMetadataParameter $parameters): JsonResponse
{
return $this->jsonResponse(['items' => $this->metadataService->getAssetPredefinedMetadata($parameters)]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
use Pimcore\Bundle\StudioBackendBundle\Event\AbstractPreResponseEvent;
use Pimcore\Bundle\StudioBackendBundle\Metadata\Schema\PredefinedMetadata;

final class PredefinedMetadataEvent extends AbstractPreResponseEvent
final class PredefinedMetadataAllEvent extends AbstractPreResponseEvent
{
public const EVENT_NAME = 'pre_response.asset_predefined_metadata';
public const EVENT_NAME = 'pre_response.asset_predefined_metadata_all';

public function __construct(
private readonly PredefinedMetadata $predefinedMetadata
Expand Down
39 changes: 39 additions & 0 deletions src/Metadata/Event/PreResponse/PredefinedMetadataGroupEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?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\Metadata\Event\PreResponse;

use Pimcore\Bundle\StudioBackendBundle\Event\AbstractPreResponseEvent;
use Pimcore\Bundle\StudioBackendBundle\Metadata\Schema\PredefinedMetadata;

final class PredefinedMetadataGroupEvent extends AbstractPreResponseEvent
{
public const EVENT_NAME = 'pre_response.asset_predefined_metadata_group';

public function __construct(
private readonly PredefinedMetadata $predefinedMetadata
) {
parent::__construct($predefinedMetadata);
}

/**
* Use this to get additional infos out of the response object
*/
public function getPredefinedMetadata(): PredefinedMetadata
{
return $this->predefinedMetadata;
}
}
39 changes: 39 additions & 0 deletions src/Metadata/MappedParameter/PredefinedMetadataParameter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?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\Metadata\MappedParameter;

/**
* @internal
*/
final readonly class PredefinedMetadataParameter
{
public function __construct(
private ?string $subType = null,
private string $group,
) {
}

public function getSubType(): ?string
{
return $this->subType;
}

public function getGroup(): string
{
return $this->group;
}
}
42 changes: 35 additions & 7 deletions src/Metadata/Service/MetadataService.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@
use Pimcore\Bundle\StaticResolverBundle\Models\Element\ServiceResolverInterface;
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\AccessDeniedException;
use Pimcore\Bundle\StudioBackendBundle\Metadata\Event\PreResponse\CustomMetadataEvent;
use Pimcore\Bundle\StudioBackendBundle\Metadata\Event\PreResponse\PredefinedMetadataEvent;
use Pimcore\Bundle\StudioBackendBundle\Metadata\Event\PreResponse\PredefinedMetadataAllEvent;
use Pimcore\Bundle\StudioBackendBundle\Metadata\Event\PreResponse\PredefinedMetadataGroupEvent;
use Pimcore\Bundle\StudioBackendBundle\Metadata\Hydrator\MetadataHydratorInterface;
use Pimcore\Bundle\StudioBackendBundle\Metadata\MappedParameter\MetadataParameters;
use Pimcore\Bundle\StudioBackendBundle\Metadata\MappedParameter\PredefinedMetadataParameter;
use Pimcore\Bundle\StudioBackendBundle\Metadata\Repository\MetadataRepositoryInterface;
use Pimcore\Bundle\StudioBackendBundle\Metadata\Schema\CustomMetadata;
use Pimcore\Bundle\StudioBackendBundle\Security\Service\SecurityServiceInterface;
Expand All @@ -38,6 +40,8 @@
{
use ElementProviderTrait;

private const DEFAULT_GROUP = 'default';

public function __construct(
private MetadataRepositoryInterface $metadataRepository,
private SecurityServiceInterface $securityService,
Expand Down Expand Up @@ -97,15 +101,39 @@ public function getPredefinedMetadata(MetadataParameters $parameters): array
{
$originalPredefinedMetadata = $this->metadataRepository->getAllPredefinedMetadataDefinitions($parameters);

$predefinedMetadata = [];
return $this->hydrateMetadataAndDispatchEvent(
$originalPredefinedMetadata,
PredefinedMetadataAllEvent::class,
PredefinedMetadataAllEvent::EVENT_NAME
);
}

public function getAssetPredefinedMetadata(PredefinedMetadataParameter $parameters): array
{
$predefinedMetadata = $this->metadataRepository->getAllPredefinedMetadata();
$subType = $parameters->getSubType();
$group = $parameters->getGroup();

$filteredMetadata = array_filter($predefinedMetadata, static function ($item) use ($subType, $group) {
return
(empty($item->getTargetSubtype()) || $item->getTargetSubtype() === $subType) &&
($group === self::DEFAULT_GROUP || $group === $item->getGroup());
});

return $this->hydrateMetadataAndDispatchEvent(
$filteredMetadata,
PredefinedMetadataGroupEvent::class,
PredefinedMetadataGroupEvent::EVENT_NAME
);
}

foreach ($originalPredefinedMetadata as $predefined) {
private function hydrateMetadataAndDispatchEvent(array $list, string $eventClass, string $eventName): array
{
$predefinedMetadata = [];
foreach ($list as $predefined) {
$metadata = $this->hydrator->hydratePredefined($predefined);

$this->eventDispatcher->dispatch(
new PredefinedMetadataEvent($metadata),
PredefinedMetadataEvent::EVENT_NAME
);
$this->eventDispatcher->dispatch(new $eventClass($metadata), $eventName);
$predefinedMetadata[] = $metadata;
}

Expand Down
6 changes: 6 additions & 0 deletions src/Metadata/Service/MetadataServiceInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

use Pimcore\Bundle\StudioBackendBundle\Exception\Api\AccessDeniedException;
use Pimcore\Bundle\StudioBackendBundle\Metadata\MappedParameter\MetadataParameters;
use Pimcore\Bundle\StudioBackendBundle\Metadata\MappedParameter\PredefinedMetadataParameter;
use Pimcore\Bundle\StudioBackendBundle\Metadata\Schema\CustomMetadata;
use Pimcore\Bundle\StudioBackendBundle\Metadata\Schema\PredefinedMetadata;

Expand All @@ -39,4 +40,9 @@ public function getCustomMetadata(int $id): array;
* @return array<int, PredefinedMetadata>
*/
public function getPredefinedMetadata(MetadataParameters $parameters): array;

/**
* @return array<int, PredefinedMetadata>
*/
public function getAssetPredefinedMetadata(PredefinedMetadataParameter $parameters): array;
}
5 changes: 5 additions & 0 deletions translations/studio_api_docs.en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ asset_get_tree_description: |
You can use different query parameters to filter the assets and it is possible to exclude folders from the result completely
asset_get_tree_success_response: Paginated assets with total count as header param as JSON
asset_get_tree_summary: Get all asset data for the tree
asset_get_predefined_metadata_description: |
Get asset predefined metadata collection. <br>
You can filter based on the given asset <strong>{subType}</strong> and metadata <strong>{group}</strong>
asset_get_predefined_metadata_success_response: Asset predefined metadata collection
asset_get_predefined_metadata_summary: Get asset predefined metadata collection
asset_image_create_thumbnail_description: |
Create a new image thumbnail based on the provided <strong>{id}</strong> and configuration parameters. <br>
The <strong>{id}</strong> must be an ID of existing asset image
Expand Down

0 comments on commit 34202b6

Please sign in to comment.