Skip to content

Commit 30c7451

Browse files
committed
ISSUE-345: attribute definition controller
1 parent ab87412 commit 30c7451

11 files changed

+694
-29
lines changed

config/services/normalizers.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,9 @@ services:
4343
tags: [ 'serializer.normalizer' ]
4444
autowire: true
4545

46+
PhpList\RestBundle\Serializer\AttributeDefinitionNormalizer:
47+
tags: [ 'serializer.normalizer' ]
48+
autowire: true
49+
4650
PhpList\RestBundle\Serializer\CursorPaginationNormalizer:
4751
autowire: true

src/Controller/AdministratorController.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,10 @@ public function createAdministrator(
135135
): JsonResponse {
136136
$this->requireAuthentication($request);
137137

138-
/** @var CreateAdministratorRequest $createAdministratorRequest */
139-
$createAdministratorRequest = $validator->validate($request, CreateAdministratorRequest::class);
138+
/** @var CreateAdministratorRequest $createRequest */
139+
$createRequest = $validator->validate($request, CreateAdministratorRequest::class);
140140

141-
$administrator = $this->administratorManager->createAdministrator($createAdministratorRequest->getDto());
141+
$administrator = $this->administratorManager->createAdministrator($createRequest->getDto());
142142
$json = $normalizer->normalize($administrator, 'json');
143143

144144
return $this->json($json, Response::HTTP_CREATED);
@@ -225,9 +225,9 @@ public function updateAdministrator(
225225
if (!$administrator) {
226226
throw $this->createNotFoundException('Administrator not found.');
227227
}
228-
/** @var UpdateAdministratorRequest $updateAdministratorRequest */
229-
$updateAdministratorRequest = $this->validator->validate($request, UpdateAdministratorRequest::class);
230-
$this->administratorManager->updateAdministrator($administrator, $updateAdministratorRequest->getDto());
228+
/** @var UpdateAdministratorRequest $updateRequest */
229+
$updateRequest = $this->validator->validate($request, UpdateAdministratorRequest::class);
230+
$this->administratorManager->updateAdministrator($administrator, $updateRequest->getDto());
231231

232232
return $this->json(null, Response::HTTP_OK);
233233
}
Lines changed: 361 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,361 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\RestBundle\Controller;
6+
7+
use OpenApi\Attributes as OA;
8+
use PhpList\Core\Domain\Model\Subscription\AttributeDefinition;
9+
use PhpList\Core\Domain\Service\Manager\AttributeDefinitionManager;
10+
use PhpList\Core\Security\Authentication;
11+
use PhpList\RestBundle\Entity\Request\CreateAttributeDefinitionRequest;
12+
use PhpList\RestBundle\Entity\Request\UpdateAttributeDefinitionRequest;
13+
use PhpList\RestBundle\Serializer\AttributeDefinitionNormalizer;
14+
use PhpList\RestBundle\Service\Provider\PaginatedDataProvider;
15+
use PhpList\RestBundle\Validator\RequestValidator;
16+
use Symfony\Bridge\Doctrine\Attribute\MapEntity;
17+
use Symfony\Component\HttpFoundation\JsonResponse;
18+
use Symfony\Component\HttpFoundation\Request;
19+
use Symfony\Component\HttpFoundation\Response;
20+
use Symfony\Component\Routing\Attribute\Route;
21+
22+
#[Route('/attributes')]
23+
class AttributeDefinitionController extends BaseController
24+
{
25+
private AttributeDefinitionManager $definitionManager;
26+
private AttributeDefinitionNormalizer $normalizer;
27+
private PaginatedDataProvider $paginatedDataProvider;
28+
29+
public function __construct(
30+
Authentication $authentication,
31+
RequestValidator $validator,
32+
AttributeDefinitionManager $definitionManager,
33+
AttributeDefinitionNormalizer $normalizer,
34+
PaginatedDataProvider $paginatedDataProvider
35+
) {
36+
parent::__construct($authentication, $validator);
37+
$this->definitionManager = $definitionManager;
38+
$this->normalizer = $normalizer;
39+
$this->paginatedDataProvider = $paginatedDataProvider;
40+
}
41+
42+
#[Route('', name: 'create_attribute_definition', methods: ['POST'])]
43+
#[OA\Post(
44+
path: '/attributes',
45+
description: 'Returns created subscriber attribute definition.',
46+
summary: 'Create a subscriber attribute definition.',
47+
requestBody: new OA\RequestBody(
48+
description: 'Pass parameters to create subscriber attribute.',
49+
required: true,
50+
content: new OA\JsonContent(
51+
required: ['name'],
52+
properties: [
53+
new OA\Property(property: 'name', type: 'string', format: 'string', example: 'Country'),
54+
new OA\Property(property: 'type', type: 'string', example: 'checkbox'),
55+
new OA\Property(property: 'order', type: 'number', example: 12),
56+
new OA\Property(property: 'default_value', type: 'string', example: 'United States'),
57+
new OA\Property(property: 'required', type: 'boolean', example: true),
58+
new OA\Property(property: 'table_name', type: 'string', example: 'list_attributes'),
59+
]
60+
)
61+
),
62+
tags: ['attributes'],
63+
parameters: [
64+
new OA\Parameter(
65+
name: 'session',
66+
description: 'Session ID obtained from authentication',
67+
in: 'header',
68+
required: true,
69+
schema: new OA\Schema(
70+
type: 'string'
71+
)
72+
)
73+
],
74+
responses: [
75+
new OA\Response(
76+
response: 201,
77+
description: 'Success',
78+
content: new OA\JsonContent(ref: '#/components/schemas/AttributeDefinition')
79+
),
80+
new OA\Response(
81+
response: 403,
82+
description: 'Failure',
83+
content: new OA\JsonContent(ref: '#/components/schemas/UnauthorizedResponse')
84+
),
85+
new OA\Response(
86+
response: 422,
87+
description: 'Failure',
88+
content: new OA\JsonContent(ref: '#/components/schemas/ValidationErrorResponse')
89+
),
90+
]
91+
)]
92+
public function create(Request $request,): JsonResponse
93+
{
94+
$this->requireAuthentication($request);
95+
96+
/** @var CreateAttributeDefinitionRequest $definitionRequest */
97+
$definitionRequest = $this->validator->validate($request, CreateAttributeDefinitionRequest::class);
98+
99+
$attributeDefinition = $this->definitionManager->create($definitionRequest->getDto());
100+
$json = $this->normalizer->normalize($attributeDefinition, 'json');
101+
102+
return $this->json($json, Response::HTTP_CREATED);
103+
}
104+
105+
#[Route('/{definitionId}', name: 'update_attribute_definition', methods: ['PUT'])]
106+
#[OA\Put(
107+
path: '/attributes/{definitionId}',
108+
description: 'Returns updated subscriber attribute definition.',
109+
summary: 'Update a subscriber attribute definition.',
110+
requestBody: new OA\RequestBody(
111+
description: 'Pass parameters to update subscriber attribute.',
112+
required: true,
113+
content: new OA\JsonContent(
114+
required: ['name'],
115+
properties: [
116+
new OA\Property(property: 'name', type: 'string', format: 'string', example: 'Country'),
117+
new OA\Property(property: 'type', type: 'string', example: 'checkbox'),
118+
new OA\Property(property: 'order', type: 'number', example: 12),
119+
new OA\Property(property: 'default_value', type: 'string', example: 'United States'),
120+
new OA\Property(property: 'required', type: 'boolean', example: true),
121+
new OA\Property(property: 'table_name', type: 'string', example: 'list_attributes'),
122+
]
123+
)
124+
),
125+
tags: ['attributes'],
126+
parameters: [
127+
new OA\Parameter(
128+
name: 'definitionId',
129+
description: 'Definition ID',
130+
in: 'path',
131+
required: true,
132+
schema: new OA\Schema(type: 'string')
133+
),
134+
new OA\Parameter(
135+
name: 'session',
136+
description: 'Session ID obtained from authentication',
137+
in: 'header',
138+
required: true,
139+
schema: new OA\Schema(type: 'string')
140+
)
141+
],
142+
responses: [
143+
new OA\Response(
144+
response: 200,
145+
description: 'Success',
146+
content: new OA\JsonContent(ref: '#/components/schemas/AttributeDefinition')
147+
),
148+
new OA\Response(
149+
response: 403,
150+
description: 'Failure',
151+
content: new OA\JsonContent(ref: '#/components/schemas/UnauthorizedResponse')
152+
),
153+
new OA\Response(
154+
response: 422,
155+
description: 'Failure',
156+
content: new OA\JsonContent(ref: '#/components/schemas/ValidationErrorResponse')
157+
),
158+
]
159+
)]
160+
public function update(
161+
Request $request,
162+
#[MapEntity(mapping: ['definitionId' => 'id'])] ?AttributeDefinition $attributeDefinition,
163+
): JsonResponse {
164+
$this->requireAuthentication($request);
165+
if (!$attributeDefinition) {
166+
throw $this->createNotFoundException('Attribute definition not found.');
167+
}
168+
169+
/** @var UpdateAttributeDefinitionRequest $definitionRequest */
170+
$definitionRequest = $this->validator->validate($request, UpdateAttributeDefinitionRequest::class);
171+
172+
$attributeDefinition = $this->definitionManager->update(
173+
$attributeDefinition,
174+
$definitionRequest->getDto(),
175+
);
176+
$json = $this->normalizer->normalize($attributeDefinition, 'json');
177+
178+
return $this->json($json, Response::HTTP_OK);
179+
}
180+
181+
#[Route('/{definitionId}', name: 'delete_attribute_definition', methods: ['DELETE'])]
182+
#[OA\Delete(
183+
path: '/attributes/{definitionId}',
184+
description: 'Deletes a single subscriber attribute definition.',
185+
summary: 'Deletes an attribute definition.',
186+
tags: ['attributes'],
187+
parameters: [
188+
new OA\Parameter(
189+
name: 'session',
190+
description: 'Session ID',
191+
in: 'header',
192+
required: true,
193+
schema: new OA\Schema(type: 'string')
194+
),
195+
new OA\Parameter(
196+
name: 'definitionId',
197+
description: 'Definition ID',
198+
in: 'path',
199+
required: true,
200+
schema: new OA\Schema(type: 'string')
201+
)
202+
],
203+
responses: [
204+
new OA\Response(
205+
response: 200,
206+
description: 'Success'
207+
),
208+
new OA\Response(
209+
response: 403,
210+
description: 'Failure',
211+
content: new OA\JsonContent(ref: '#/components/schemas/UnauthorizedResponse')
212+
),
213+
new OA\Response(
214+
response: 404,
215+
description: 'Failure',
216+
content: new OA\JsonContent(ref: '#/components/schemas/NotFoundErrorResponse')
217+
)
218+
]
219+
)]
220+
public function delete(
221+
Request $request,
222+
#[MapEntity(mapping: ['definitionId' => 'id'])] ?AttributeDefinition $attributeDefinition,
223+
): JsonResponse {
224+
$this->requireAuthentication($request);
225+
if (!$attributeDefinition) {
226+
throw $this->createNotFoundException('Attribute definition not found.');
227+
}
228+
229+
$this->definitionManager->delete($attributeDefinition);
230+
231+
return $this->json(null, Response::HTTP_NO_CONTENT);
232+
}
233+
234+
#[Route('', name: 'get_attribute_definitions', methods: ['GET'])]
235+
#[OA\Get(
236+
path: '/attributes',
237+
description: 'Returns a JSON list of all subscriber attribute definitions.',
238+
summary: 'Gets a list of all subscriber attribute definitions.',
239+
tags: ['attributes'],
240+
parameters: [
241+
new OA\Parameter(
242+
name: 'session',
243+
description: 'Session ID obtained from authentication',
244+
in: 'header',
245+
required: true,
246+
schema: new OA\Schema(
247+
type: 'string'
248+
)
249+
),
250+
new OA\Parameter(
251+
name: 'after_id',
252+
description: 'Last id (starting from 0)',
253+
in: 'query',
254+
required: false,
255+
schema: new OA\Schema(type: 'integer', default: 1, minimum: 1)
256+
),
257+
new OA\Parameter(
258+
name: 'limit',
259+
description: 'Number of results per page',
260+
in: 'query',
261+
required: false,
262+
schema: new OA\Schema(type: 'integer', default: 25, maximum: 100, minimum: 1)
263+
)
264+
],
265+
responses: [
266+
new OA\Response(
267+
response: 200,
268+
description: 'Success',
269+
content: new OA\JsonContent(
270+
properties: [
271+
new OA\Property(
272+
property: 'items',
273+
type: 'array',
274+
items: new OA\Items(ref: '#/components/schemas/AttributeDefinition')
275+
),
276+
new OA\Property(property: 'pagination', ref: '#/components/schemas/CursorPagination')
277+
],
278+
type: 'object'
279+
)
280+
),
281+
new OA\Response(
282+
response: 403,
283+
description: 'Failure',
284+
content: new OA\JsonContent(ref: '#/components/schemas/UnauthorizedResponse')
285+
)
286+
]
287+
)]
288+
public function getPaginated(Request $request,): JsonResponse
289+
{
290+
$this->requireAuthentication($request);
291+
292+
return $this->json(
293+
$this->paginatedDataProvider->getPaginatedList($request, $this->normalizer, AttributeDefinition::class),
294+
Response::HTTP_OK
295+
);
296+
}
297+
298+
#[Route('/{definitionId}', name: 'get_attribute_definition', methods: ['GET'])]
299+
#[OA\Get(
300+
path: '/attributes/{definitionId}',
301+
description: 'Returns a single attribute with specified ID.',
302+
summary: 'Gets attribute with specified ID.',
303+
tags: ['attributes'],
304+
parameters: [
305+
new OA\Parameter(
306+
name: 'definitionId',
307+
description: 'Definition ID',
308+
in: 'path',
309+
required: true,
310+
schema: new OA\Schema(type: 'string')
311+
),
312+
new OA\Parameter(
313+
name: 'session',
314+
description: 'Session ID obtained from authentication',
315+
in: 'header',
316+
required: true,
317+
schema: new OA\Schema(type: 'string')
318+
)
319+
],
320+
responses: [
321+
new OA\Response(
322+
response: 200,
323+
description: 'Success',
324+
content: new OA\JsonContent(ref: '#/components/schemas/AttributeDefinition')
325+
),
326+
new OA\Response(
327+
response: 403,
328+
description: 'Failure',
329+
content: new OA\JsonContent(ref: '#/components/schemas/UnauthorizedResponse')
330+
),
331+
new OA\Response(
332+
response: 404,
333+
description: 'Failure',
334+
content: new OA\JsonContent(
335+
properties: [
336+
new OA\Property(
337+
property: 'message',
338+
type: 'string',
339+
example: 'There is no attribute with that ID.'
340+
)
341+
],
342+
type: 'object'
343+
)
344+
)
345+
]
346+
)]
347+
public function getAttributeDefinition(
348+
Request $request,
349+
#[MapEntity(mapping: ['definitionId' => 'id'])] ?AttributeDefinition $attributeDefinition,
350+
): JsonResponse {
351+
$this->requireAuthentication($request);
352+
if (!$attributeDefinition) {
353+
throw $this->createNotFoundException('Attribute definition not found.');
354+
}
355+
356+
return $this->json(
357+
$this->normalizer->normalize($attributeDefinition),
358+
Response::HTTP_OK
359+
);
360+
}
361+
}

0 commit comments

Comments
 (0)