Skip to content

Commit

Permalink
Wrap collection response into an object and set total items (#31)
Browse files Browse the repository at this point in the history
* Wrap collection response into an object and set total items

* Apply php-cs-fixer changes

* Restructure

* Rename property

* Update minor stuff

* CS fix

* Remove unecessary brackets

* Add DataObjectCollection

* Apply php-cs-fixer changes

---------

Co-authored-by: mattamon <[email protected]>
  • Loading branch information
mattamon and mattamon authored Apr 18, 2024
1 parent cbb674f commit 05c5668
Show file tree
Hide file tree
Showing 10 changed files with 203 additions and 45 deletions.
14 changes: 7 additions & 7 deletions config/filters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,23 @@ services:
class: Pimcore\Bundle\StudioApiBundle\Service\Filter\FilterService

Pimcore\Bundle\StudioApiBundle\Filter\PageFilter:
tags: [ 'pimcore.studio_api.collection.filter' ]
tags: [ 'pimcore.studio_api.filter' ]

Pimcore\Bundle\StudioApiBundle\Filter\PageSizeFilter:
tags: [ 'pimcore.studio_api.collection.filter' ]
tags: [ 'pimcore.studio_api.filter' ]

Pimcore\Bundle\StudioApiBundle\Filter\ExcludeFolderFilter:
tags: [ 'pimcore.studio_api.collection.filter' ]
tags: [ 'pimcore.studio_api.filter' ]

Pimcore\Bundle\StudioApiBundle\Filter\IdSearchFilter:
tags: [ 'pimcore.studio_api.collection.filter' ]
tags: [ 'pimcore.studio_api.filter' ]

Pimcore\Bundle\StudioApiBundle\Filter\ParentIdFilter:
tags: [ 'pimcore.studio_api.collection.filter' ]
tags: [ 'pimcore.studio_api.filter' ]

Pimcore\Bundle\StudioApiBundle\Filter\PathFilter:
tags: [ 'pimcore.studio_api.collection.filter' ]
tags: [ 'pimcore.studio_api.filter' ]

# DataObject
Pimcore\Bundle\StudioApiBundle\Filter\DataObject\ClassIdFilter:
tags: [ 'pimcore.studio_api.collection.data_object.filter' ]
tags: [ 'pimcore.studio_api.data_object.filter' ]
37 changes: 37 additions & 0 deletions src/Attributes/Response/Content/CollectionJson.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?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\StudioApiBundle\Attributes\Response\Content;

use OpenApi\Attributes\JsonContent;
use OpenApi\Attributes\Property;

/**
* @internal
*/
final class CollectionJson extends JsonContent
{
public function __construct(Property $collection)
{
parent::__construct(
properties: [
new Property('totalItems', title: 'totalItems', type: 'integer', example: 666),
$collection,
],
type: 'object',
);
}
}
56 changes: 56 additions & 0 deletions src/Attributes/Response/Property/AssetCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?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\StudioApiBundle\Attributes\Response\Property;

use OpenApi\Attributes\Items;
use OpenApi\Attributes\Property;
use OpenApi\Attributes\Schema;
use Pimcore\Bundle\StudioApiBundle\Response\Asset\Archive;
use Pimcore\Bundle\StudioApiBundle\Response\Asset\Audio;
use Pimcore\Bundle\StudioApiBundle\Response\Asset\Document;
use Pimcore\Bundle\StudioApiBundle\Response\Asset\Folder;
use Pimcore\Bundle\StudioApiBundle\Response\Asset\Image;
use Pimcore\Bundle\StudioApiBundle\Response\Asset\Text;
use Pimcore\Bundle\StudioApiBundle\Response\Asset\Unknown;
use Pimcore\Bundle\StudioApiBundle\Response\Asset\Video;

/**
* @internal
*/
final class AssetCollection extends Property
{
public function __construct()
{
parent::__construct(
'items',
title: 'items',
type: 'array',
items: new Items(
anyOf: [
new Schema(ref: Image::class),
new Schema(ref: Document::class),
new Schema(ref: Audio::class),
new Schema(ref: Video::class),
new Schema(ref: Archive::class),
new Schema(ref: Text::class),
new Schema(ref: Folder::class),
new Schema(ref: Unknown::class),
]
)
);
}
}
42 changes: 42 additions & 0 deletions src/Attributes/Response/Property/DataObjectCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?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\StudioApiBundle\Attributes\Response\Property;

use OpenApi\Attributes\Items;
use OpenApi\Attributes\Property;
use OpenApi\Attributes\Schema;
use Pimcore\Bundle\StudioApiBundle\Response\DataObject;

/**
* @internal
*/
final class DataObjectCollection extends Property
{
public function __construct()
{
parent::__construct(
'items',
title: 'items',
type: 'array',
items: new Items(
anyOf: [
new Schema(ref: DataObject::class),
]
)
);
}
}
31 changes: 3 additions & 28 deletions src/Controller/Api/Assets/CollectionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@
namespace Pimcore\Bundle\StudioApiBundle\Controller\Api\Assets;

use OpenApi\Attributes\Get;
use OpenApi\Attributes\Items;
use OpenApi\Attributes\JsonContent;
use OpenApi\Attributes\Schema;
use Pimcore\Bundle\StudioApiBundle\Attributes\Parameters\Query\ExcludeFoldersParameter;
use Pimcore\Bundle\StudioApiBundle\Attributes\Parameters\Query\IdSearchTermParameter;
use Pimcore\Bundle\StudioApiBundle\Attributes\Parameters\Query\PageParameter;
Expand All @@ -28,21 +25,15 @@
use Pimcore\Bundle\StudioApiBundle\Attributes\Parameters\Query\PathIncludeDescendantsParameter;
use Pimcore\Bundle\StudioApiBundle\Attributes\Parameters\Query\PathIncludeParentParameter;
use Pimcore\Bundle\StudioApiBundle\Attributes\Parameters\Query\PathParameter;
use Pimcore\Bundle\StudioApiBundle\Attributes\Response\Content\CollectionJson;
use Pimcore\Bundle\StudioApiBundle\Attributes\Response\Property\AssetCollection;
use Pimcore\Bundle\StudioApiBundle\Attributes\Response\SuccessResponse;
use Pimcore\Bundle\StudioApiBundle\Attributes\Response\UnauthorizedResponse;
use Pimcore\Bundle\StudioApiBundle\Config\Tags;
use Pimcore\Bundle\StudioApiBundle\Controller\Api\AbstractApiController;
use Pimcore\Bundle\StudioApiBundle\Controller\Trait\PaginatedResponseTrait;
use Pimcore\Bundle\StudioApiBundle\Exception\InvalidQueryTypeException;
use Pimcore\Bundle\StudioApiBundle\Request\Query\Filter\Parameters;
use Pimcore\Bundle\StudioApiBundle\Response\Asset\Archive;
use Pimcore\Bundle\StudioApiBundle\Response\Asset\Audio;
use Pimcore\Bundle\StudioApiBundle\Response\Asset\Document;
use Pimcore\Bundle\StudioApiBundle\Response\Asset\Folder;
use Pimcore\Bundle\StudioApiBundle\Response\Asset\Image;
use Pimcore\Bundle\StudioApiBundle\Response\Asset\Text;
use Pimcore\Bundle\StudioApiBundle\Response\Asset\Unknown;
use Pimcore\Bundle\StudioApiBundle\Response\Asset\Video;
use Pimcore\Bundle\StudioApiBundle\Service\AssetSearchServiceInterface;
use Pimcore\Bundle\StudioApiBundle\Service\Filter\FilterServiceInterface;
use Pimcore\Bundle\StudioApiBundle\Service\GenericData\V1\AssetQuery;
Expand Down Expand Up @@ -89,23 +80,7 @@ public function __construct(
#[PathIncludeDescendantsParameter]
#[SuccessResponse(
description: 'Paginated assets with total count as header param',
content: new JsonContent(
type: 'array',
items: new Items(
description: 'Asset or Image object',
anyOf: [
// TODO maybe find an easier way of describing this
new Schema(ref: Archive::class),
new Schema(ref: Audio::class),
new Schema(ref: Document::class),
new Schema(ref: Folder::class),
new Schema(ref: Image::class),
new Schema(ref: Text::class),
new Schema(ref: Unknown::class),
new Schema(ref: Video::class),
]
)
)
content: new CollectionJson(new AssetCollection())
)]
#[UnauthorizedResponse]
public function getAssets(#[MapQueryString] Parameters $parameters): JsonResponse
Expand Down
7 changes: 3 additions & 4 deletions src/Controller/Api/DataObjects/CollectionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
namespace Pimcore\Bundle\StudioApiBundle\Controller\Api\DataObjects;

use OpenApi\Attributes\Get;
use OpenApi\Attributes\Items;
use OpenApi\Attributes\JsonContent;
use Pimcore\Bundle\StudioApiBundle\Attributes\Parameters\Query\ClassIdParameter;
use Pimcore\Bundle\StudioApiBundle\Attributes\Parameters\Query\ExcludeFoldersParameter;
use Pimcore\Bundle\StudioApiBundle\Attributes\Parameters\Query\IdSearchTermParameter;
Expand All @@ -28,14 +26,15 @@
use Pimcore\Bundle\StudioApiBundle\Attributes\Parameters\Query\PathIncludeDescendantsParameter;
use Pimcore\Bundle\StudioApiBundle\Attributes\Parameters\Query\PathIncludeParentParameter;
use Pimcore\Bundle\StudioApiBundle\Attributes\Parameters\Query\PathParameter;
use Pimcore\Bundle\StudioApiBundle\Attributes\Response\Content\CollectionJson;
use Pimcore\Bundle\StudioApiBundle\Attributes\Response\Property\DataObjectCollection;
use Pimcore\Bundle\StudioApiBundle\Attributes\Response\SuccessResponse;
use Pimcore\Bundle\StudioApiBundle\Attributes\Response\UnauthorizedResponse;
use Pimcore\Bundle\StudioApiBundle\Config\Tags;
use Pimcore\Bundle\StudioApiBundle\Controller\Api\AbstractApiController;
use Pimcore\Bundle\StudioApiBundle\Controller\Trait\PaginatedResponseTrait;
use Pimcore\Bundle\StudioApiBundle\Exception\InvalidQueryTypeException;
use Pimcore\Bundle\StudioApiBundle\Request\Query\Filter\DataObjectParameters;
use Pimcore\Bundle\StudioApiBundle\Response\DataObject;
use Pimcore\Bundle\StudioApiBundle\Service\DataObjectSearchServiceInterface;
use Pimcore\Bundle\StudioApiBundle\Service\Filter\FilterServiceInterface;
use Pimcore\Bundle\StudioApiBundle\Service\GenericData\V1\DataObjectQuery;
Expand Down Expand Up @@ -80,7 +79,7 @@ public function __construct(
#[ClassIdParameter]
#[SuccessResponse(
description: 'Paginated data objects with total count as header param',
content: new JsonContent(type: 'array', items: new Items(ref: DataObject::class))
content: new CollectionJson(new DataObjectCollection())
)]
#[UnauthorizedResponse]
public function getDataObjects(#[MapQueryString] DataObjectParameters $parameters): JsonResponse
Expand Down
3 changes: 2 additions & 1 deletion src/Controller/Trait/PaginatedResponseTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

namespace Pimcore\Bundle\StudioApiBundle\Controller\Trait;

use Pimcore\Bundle\StudioApiBundle\Response\Collection;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Serializer\SerializerInterface;

Expand All @@ -31,7 +32,7 @@ protected function getPaginatedCollection(
array $data,
int $totalItems = 0
): JsonResponse {
$serialized = $serializer->serialize($data, 'json');
$serialized = $serializer->serialize(new Collection($totalItems, $data), 'json');

return new JsonResponse($serialized, 200, [self::HEADER_TOTAL_ITEMS => $totalItems], true);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Response/Asset/Image.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public function __construct(
private readonly bool $isVectorGraphic,
#[Property(description: 'is animated', type: 'boolean', example: false)]
private readonly bool $isAnimated,
#[Property(description: 'path to thumbnail', type: 'string', example: '/path/to/element/thumbnail.jpg')]
#[Property(description: 'path to thumbnail', type: 'string', example: '/path/to/element/hulk-smash.jpg')]
private readonly string $thumbnailPath,
string $iconName,
bool $hasChildren,
Expand Down
48 changes: 48 additions & 0 deletions src/Response/Collection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?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\StudioApiBundle\Response;

use OpenApi\Attributes\Property;
use OpenApi\Attributes\Schema;

/**
* @internal
*/
#[Schema(
title: 'Collection',
type: 'object'
)]
final readonly class Collection
{
public function __construct(
#[Property(description: 'total items', type: 'integer', example: 666)]
private int $totalItems,
#[Property(description: 'items', type: 'mixed', example: ['Asset', 'Folder', 'Document', 'DataObject'])]
private array $items
) {
}

public function getTotalItems(): int
{
return $this->totalItems;
}

public function getItems(): array
{
return $this->items;
}
}
8 changes: 4 additions & 4 deletions src/Service/Filter/Loader/TaggedIteratorAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@
*/
final class TaggedIteratorAdapter implements FilterLoaderInterface
{
public const FILTER_TAG = 'pimcore.studio_api.collection.filter';
public const FILTER_TAG = 'pimcore.studio_api.filter';

public const FILTER_ASSET_TAG = 'pimcore.studio_api.collection.asset.filter';
public const FILTER_ASSET_TAG = 'pimcore.studio_api.asset.filter';

public const FILTER_DATA_OBJECT_TAG = 'pimcore.studio_api.collection.data_object.filter';
public const FILTER_DATA_OBJECT_TAG = 'pimcore.studio_api.data_object.filter';

public const FILTER_DOCUMENT_TAG = 'pimcore.studio_api.collection.document.filter';
public const FILTER_DOCUMENT_TAG = 'pimcore.studio_api.document.filter';

public function __construct(
#[TaggedIterator(self::FILTER_TAG)]
Expand Down

0 comments on commit 05c5668

Please sign in to comment.