Skip to content

Commit

Permalink
Add responses and new way for default responses
Browse files Browse the repository at this point in the history
  • Loading branch information
mattamon committed May 22, 2024
1 parent 44c1b90 commit 0e3b8a7
Show file tree
Hide file tree
Showing 7 changed files with 201 additions and 23 deletions.
37 changes: 37 additions & 0 deletions src/Note/Attributes/Response/Property/NoteCollection.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\StudioBackendBundle\Note\Attributes\Response\Property;

use OpenApi\Attributes\Items;
use OpenApi\Attributes\Property;
use Pimcore\Bundle\StudioBackendBundle\Note\Schema\Note;

/**
* @internal
*/
final class NoteCollection extends Property
{
public function __construct()
{
parent::__construct(
'items',
title: 'items',
type: 'array',
items: new Items(ref: Note::class)
);
}
}
24 changes: 12 additions & 12 deletions src/Note/Controller/Element/CollectionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

use OpenApi\Attributes\Get;
use Pimcore\Bundle\StudioBackendBundle\Controller\AbstractApiController;
use Pimcore\Bundle\StudioBackendBundle\Note\Attributes\Response\Property\NoteCollection;
use Pimcore\Bundle\StudioBackendBundle\Note\Request\NoteElement;
use Pimcore\Bundle\StudioBackendBundle\Note\Request\NoteParameters;
use Pimcore\Bundle\StudioBackendBundle\Note\Service\NoteServiceInterface;
Expand All @@ -26,12 +27,11 @@
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attributes\Parameters\Query\FilterParameter;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attributes\Parameters\Query\PageParameter;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attributes\Parameters\Query\PageSizeParameter;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attributes\Response\Error\BadRequestResponse;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attributes\Response\Error\MethodNotAllowedResponse;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attributes\Response\Error\UnauthorizedResponse;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attributes\Response\Error\UnprocessableContentResponse;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attributes\Response\Error\UnsupportedMediaTypeResponse;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attributes\Response\Content\CollectionJson;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attributes\Response\DefaultResponses;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attributes\Response\SuccessResponse;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Config\Tags;
use Pimcore\Bundle\StudioBackendBundle\Util\Constants\HttpResponseCodes;
use Pimcore\Bundle\StudioBackendBundle\Util\Traits\PaginatedResponseTrait;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Attribute\MapQueryString;
Expand All @@ -53,8 +53,6 @@ public function __construct(
parent::__construct($serializer);
}



#[Route('/notes/{elementType}/{id}', name: 'pimcore_studio_api_get_element_notes', methods: ['GET'])]
#[Get(
path: self::API_PATH . '/notes/{elementType}/{id}',
Expand All @@ -68,11 +66,13 @@ public function __construct(
#[PageParameter]
#[PageSizeParameter(50)]
#[FilterParameter('notes')]
#[BadRequestResponse]
#[UnauthorizedResponse]
#[MethodNotAllowedResponse]
#[UnsupportedMediaTypeResponse]
#[UnprocessableContentResponse]
#[SuccessResponse(
description: 'Paginated assets with total count as header param',
content: new CollectionJson(new NoteCollection())
)]
#[DefaultResponses([
HttpResponseCodes::UNAUTHORIZED
])]
public function getNotes(
string $elementType,
int $id,
Expand Down
15 changes: 5 additions & 10 deletions src/Note/Controller/Element/CreateController.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,9 @@
use Pimcore\Bundle\StudioBackendBundle\Note\Service\NoteServiceInterface;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attributes\Parameters\Path\ElementTypeParameter;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attributes\Parameters\Path\IdParameter;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attributes\Response\Error\BadRequestResponse;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attributes\Response\Error\MethodNotAllowedResponse;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attributes\Response\Error\UnauthorizedResponse;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attributes\Response\Error\UnprocessableContentResponse;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attributes\Response\Error\UnsupportedMediaTypeResponse;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attributes\Response\DefaultResponses;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Config\Tags;
use Pimcore\Bundle\StudioBackendBundle\Util\Constants\HttpResponseCodes;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
use Symfony\Component\Routing\Attribute\Route;
Expand Down Expand Up @@ -59,11 +56,9 @@ public function __construct(
#[ElementTypeParameter]
#[IdParameter(type: 'element')]
#[CreateNoteRequestBody]
#[BadRequestResponse]
#[UnauthorizedResponse]
#[MethodNotAllowedResponse]
#[UnsupportedMediaTypeResponse]
#[UnprocessableContentResponse]
#[DefaultResponses([
HttpResponseCodes::UNAUTHORIZED
])]
public function createNote(
string $elementType,
int $id,
Expand Down
7 changes: 6 additions & 1 deletion src/Note/Repository/NoteRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

namespace Pimcore\Bundle\StudioBackendBundle\Note\Repository;

use Pimcore\Bundle\StaticResolverBundle\Models\Element\NoteResolverInterface;
use Pimcore\Bundle\StudioBackendBundle\Note\Request\NoteElement;
use Pimcore\Bundle\StudioBackendBundle\Note\Request\NoteParameters;
use Pimcore\Bundle\StudioBackendBundle\Note\Schema\CreateNote;
Expand All @@ -27,6 +28,10 @@
*/
final readonly class NoteRepository implements NoteRepositoryInterface
{
public function __construct(private NoteResolverInterface $noteResolver)
{
}

public function createNote(NoteElement $noteElement, CreateNote $createNote): Note
{
$note = new Note();
Expand All @@ -44,7 +49,7 @@ public function createNote(NoteElement $noteElement, CreateNote $createNote): No

public function getNote(int $id): Note
{
return Note::getById($id);
return $this->noteResolver->getById($id);
}

public function listNotes(NoteElement $noteElement, NoteParameters $parameters): NoteListing
Expand Down
33 changes: 33 additions & 0 deletions src/Note/Schema/Note.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,61 @@

namespace Pimcore\Bundle\StudioBackendBundle\Note\Schema;

use OpenApi\Attributes\AdditionalProperties;
use OpenApi\Attributes\Items;
use OpenApi\Attributes\Property;
use OpenApi\Attributes\Schema;
use Pimcore\Bundle\StudioBackendBundle\Util\Schema\AdditionalAttributesInterface;
use Pimcore\Bundle\StudioBackendBundle\Util\Traits\AdditionalAttributesTrait;

/**
* @internal
*/
#[Schema(
title: 'Note',
type: 'object'
)]
final class Note implements AdditionalAttributesInterface
{
use AdditionalAttributesTrait;

public function __construct(
#[Property(description: 'id', type: 'integer', example: 666)]
private readonly int $id,
#[Property(description: 'type', type: 'string', example: 'Type of note')]
private readonly string $type,
#[Property(description: 'Id of element', type: 'integer', example: 667)]
private readonly int $cId,
#[Property(description: 'Type of element', type: 'string', example: 'asset')]
private readonly string $cType,
#[Property(description: 'Path of element', type: 'string', example: '/path/to/element')]
private readonly string $cPath,
#[Property(description: 'Creation date of note', type: 'integer', example: 1634025600)]
private readonly int $date,
#[Property(description: 'title', type: 'string', example: 'Title of note')]
private readonly string $title,
#[Property(description: 'description', type: 'string', example: 'This is a description')]
private readonly string $description,
#[Property(description: 'Locked', type: 'boolean', example: false)]
private readonly bool $locked,
#[Property(
description: 'Data of note',
type: 'object',
example: 'Can be pretty much anything',
additionalProperties: new AdditionalProperties(
oneOf: [
new Schema(type: 'string'),
new Schema(type: 'number'),
new Schema(type: 'boolean'),
new Schema(type: 'object'),
new Schema(type: 'array', items: new Items()),
]
)
)]
private readonly array $data,
#[Property(description: 'User ID', type: 'integer', example: 1)]
private readonly ?int $userId,
#[Property(description: 'Username', type: 'string', example: 'shaquille.oatmeal')]
private readonly ?string $userName
)
{
Expand Down
75 changes: 75 additions & 0 deletions src/OpenApi/Attributes/Response/DefaultResponses.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?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\OpenApi\Attributes\Response;

use Attribute;
use OpenApi\Attributes\JsonContent;
use OpenApi\Attributes\Response;
use OpenApi\Attributes\Schema;
use Pimcore\Bundle\StudioBackendBundle\Response\Schemas;
use Pimcore\Bundle\StudioBackendBundle\Util\Constants\HttpResponseCodes;

/**
* @internal
*/
#[Attribute(Attribute::TARGET_METHOD)]
final class DefaultResponses extends Response
{
private array $defaultErrorCodes = [
HttpResponseCodes::BAD_REQUEST,
HttpResponseCodes::METHOD_NOT_ALLOWED,
HttpResponseCodes::UNSUPPORTED_MEDIA_TYPE,
HttpResponseCodes::UNPROCESSABLE_CONTENT,
];

public function __construct(array $codes = [])
{
$description = $this->generateDescription($codes);

parent::__construct(
response: 'default',
description: $description,
content: new JsonContent(
oneOf: array_map(static function ($class) {
return new Schema(ref: $class);
}, Schemas::ERRORS),
)
);
}

private function generateDescription(array $errorCodes): string
{
// merge the default error codes with the provided ones
$errorCodes = array_merge($this->defaultErrorCodes, $errorCodes);

// Sort the array of enums by http status code
usort($errorCodes, static function($a, $b) {
return $a->value <=> $b->value;
});

// Generate description block of http codes
$errorCodes = array_map(function ($code) {
return sprintf('%s - %s', $code->value, $this->generateNiceName($code->name));
}, $errorCodes);

return implode('<br>', $errorCodes);
}

private function generateNiceName(string $name): string {
return ucwords(str_replace('_', ' ', strtolower($name)));
}
}
33 changes: 33 additions & 0 deletions src/Util/Constants/HttpResponseCodes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?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\Util\Constants;

/**
* @internal
*/
enum HttpResponseCodes: int
{
case SUCCESS = 200;
case NOT_COMPLETED = 202;
case BAD_REQUEST = 400;
case UNAUTHORIZED = 401;
case FORBIDDEN = 403;
case NOT_FOUND = 404;
case METHOD_NOT_ALLOWED = 405;
case UNSUPPORTED_MEDIA_TYPE = 415;
case UNPROCESSABLE_CONTENT = 422;
}

0 comments on commit 0e3b8a7

Please sign in to comment.