Skip to content

Commit 3e08262

Browse files
committed
ISSUE-345: template controller
1 parent 09a1ff7 commit 3e08262

File tree

7 files changed

+224
-15
lines changed

7 files changed

+224
-15
lines changed

config/services/normalizers.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,11 @@ services:
3030
PhpList\RestBundle\Serializer\MessageNormalizer:
3131
tags: [ 'serializer.normalizer' ]
3232
autowire: true
33+
34+
PhpList\RestBundle\Serializer\TemplateImageNormalizer:
35+
tags: [ 'serializer.normalizer' ]
36+
autowire: true
37+
38+
PhpList\RestBundle\Serializer\TemplateNormalizer:
39+
tags: [ 'serializer.normalizer' ]
40+
autowire: true

src/Controller/TemplateController.php

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
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\Repository\Messaging\TemplateRepository;
9+
use PhpList\Core\Security\Authentication;
10+
use PhpList\RestBundle\Controller\Traits\AuthenticationTrait;
11+
use PhpList\RestBundle\Serializer\TemplateNormalizer;
12+
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
13+
use Symfony\Component\HttpFoundation\JsonResponse;
14+
use Symfony\Component\HttpFoundation\Request;
15+
use Symfony\Component\HttpFoundation\Response;
16+
use Symfony\Component\Routing\Attribute\Route;
17+
18+
/**
19+
* This controller provides REST API to manage templates.
20+
*
21+
* @author Tatevik Grigoryan <[email protected]>
22+
*/
23+
#[Route('/templates')]
24+
class TemplateController extends AbstractController
25+
{
26+
use AuthenticationTrait;
27+
28+
private TemplateRepository $templateRepository;
29+
private TemplateNormalizer $normalizer;
30+
31+
public function __construct(
32+
Authentication $authentication,
33+
TemplateRepository $templateRepository,
34+
TemplateNormalizer $normalizer,
35+
) {
36+
$this->authentication = $authentication;
37+
$this->templateRepository = $templateRepository;
38+
$this->normalizer = $normalizer;
39+
}
40+
41+
#[Route('', name: 'get_templates', methods: ['GET'])]
42+
#[OA\Get(
43+
path: '/templates',
44+
description: 'Returns a JSON list of all templates.',
45+
summary: 'Gets a list of all templates.',
46+
tags: ['templates'],
47+
parameters: [
48+
new OA\Parameter(
49+
name: 'session',
50+
description: 'Session ID obtained from authentication',
51+
in: 'header',
52+
required: true,
53+
schema: new OA\Schema(
54+
type: 'string'
55+
)
56+
)
57+
],
58+
responses: [
59+
new OA\Response(
60+
response: 200,
61+
description: 'Success',
62+
content: new OA\JsonContent(
63+
type: 'array',
64+
items: new OA\Items(ref: '#/components/schemas/Template')
65+
)
66+
),
67+
new OA\Response(
68+
response: 403,
69+
description: 'Failure',
70+
content: new OA\JsonContent(ref: '#/components/schemas/UnauthorizedResponse')
71+
)
72+
]
73+
)]
74+
public function getTemplates(Request $request): JsonResponse
75+
{
76+
$this->requireAuthentication($request);
77+
$data = $this->templateRepository->findAll();
78+
79+
$normalized = array_map(function ($item) {
80+
return $this->normalizer->normalize($item);
81+
}, $data);
82+
83+
return new JsonResponse($normalized, Response::HTTP_OK);
84+
}
85+
}

src/OpenApi/SwaggerSchemasResponseEntity.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,27 @@
6161
],
6262
type: 'object'
6363
)]
64+
#[OA\Schema(
65+
schema: 'TemplateImage',
66+
properties: [
67+
new OA\Property(property: 'id', type: 'integer', example: 12),
68+
new OA\Property(property: 'template_id', type: 'integer', example: 1),
69+
new OA\Property(property: 'mimetype', type: 'string', example: 'image/png', nullable: true),
70+
new OA\Property(property: 'filename', type: 'string', example: 'header.png', nullable: true),
71+
new OA\Property(
72+
property: 'data',
73+
description: 'Base64-encoded image data',
74+
type: 'string',
75+
format: 'byte',
76+
example: 'iVBORw0KGgoAAAANSUhEUgAAA...',
77+
nullable: true
78+
),
79+
new OA\Property(property: 'width', type: 'integer', example: 600, nullable: true),
80+
new OA\Property(property: 'height', type: 'integer', example: 200, nullable: true),
81+
],
82+
type: 'object',
83+
nullable: true
84+
)]
6485
#[OA\Schema(
6586
schema: 'Template',
6687
properties: [
@@ -69,6 +90,12 @@
6990
new OA\Property(property: 'template', type: 'string', example: 'Hello World!', nullable: true),
7091
new OA\Property(property: 'template_text', type: 'string', nullable: true),
7192
new OA\Property(property: 'order', type: 'integer', nullable: true),
93+
new OA\Property(
94+
property: 'images',
95+
type: 'array',
96+
items: new OA\Items(ref: '#/components/schemas/TemplateImage'),
97+
nullable: true
98+
),
7299
],
73100
type: 'object',
74101
nullable: true

src/Serializer/MessageNormalizer.php

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99

1010
class MessageNormalizer implements NormalizerInterface
1111
{
12+
public function __construct(private readonly TemplateNormalizer $templateNormalizer)
13+
{
14+
}
15+
1216
/**
1317
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
1418
*/
@@ -18,16 +22,11 @@ public function normalize($object, string $format = null, array $context = []):
1822
return [];
1923
}
2024

25+
$template = $object->getTemplate();
2126
return [
2227
'id' => $object->getId(),
2328
'unique_id' => $object->getUuid(),
24-
'template' => $object->getTemplate()?->getId() ? [
25-
'id' => $object->getTemplate()->getId(),
26-
'title' => $object->getTemplate()->getTitle(),
27-
'template' => $object->getTemplate()->getTemplate(),
28-
'template_text' => $object->getTemplate()->getTemplateText(),
29-
'order' => $object->getTemplate()->getListOrder(),
30-
] : null,
29+
'template' => $template?->getId() ? $this->templateNormalizer->normalize($template) : null,
3130
'message_content' => [
3231
'subject' => $object->getContent()->getSubject(),
3332
'text' => $object->getContent()->getText(),
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\RestBundle\Serializer;
6+
7+
use PhpList\Core\Domain\Model\Messaging\TemplateImage;
8+
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
9+
10+
class TemplateImageNormalizer implements NormalizerInterface
11+
{
12+
/**
13+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
14+
*/
15+
public function normalize($object, string $format = null, array $context = []): array
16+
{
17+
if (!$object instanceof TemplateImage) {
18+
return [];
19+
}
20+
21+
return [
22+
'id' => $object->getId(),
23+
'template_id' => $object->getTemplate()?->getId(),
24+
'mimetype' => $object->getMimeType(),
25+
'filename' => $object->getFilename(),
26+
'data' => base64_encode($object->getData() ?? ''),
27+
'width' => $object->getWidth(),
28+
'height' => $object->getHeight(),
29+
];
30+
}
31+
32+
/**
33+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
34+
*/
35+
public function supportsNormalization($data, string $format = null): bool
36+
{
37+
return $data instanceof TemplateImage;
38+
}
39+
}

src/Serializer/TemplateNormalizer.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\RestBundle\Serializer;
6+
7+
use PhpList\Core\Domain\Model\Messaging\Template;
8+
use PhpList\Core\Domain\Model\Messaging\TemplateImage;
9+
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
10+
11+
class TemplateNormalizer implements NormalizerInterface
12+
{
13+
public function __construct(private readonly TemplateImageNormalizer $templateImageNormalizer)
14+
{
15+
}
16+
17+
/**
18+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
19+
*/
20+
public function normalize($object, string $format = null, array $context = []): array
21+
{
22+
if (!$object instanceof Template) {
23+
return [];
24+
}
25+
26+
return [
27+
'id' => $object->getId(),
28+
'title' => $object->getTitle(),
29+
'template' => $object->getTemplate(),
30+
'template_text' => $object->getTemplateText(),
31+
'order' => $object->getListOrder(),
32+
'images' => $object->getImages()->toArray() ? array_map(function (TemplateImage $image) {
33+
return $this->templateImageNormalizer->normalize($image);
34+
}, $object->getImages()->toArray()) : null
35+
];
36+
}
37+
38+
/**
39+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
40+
*/
41+
public function supportsNormalization($data, string $format = null): bool
42+
{
43+
return $data instanceof Template;
44+
}
45+
}

tests/Unit/Serializer/MessageNormalizerTest.php

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,25 @@
1313
use PhpList\Core\Domain\Model\Messaging\Message\MessageSchedule;
1414
use PhpList\Core\Domain\Model\Messaging\Template;
1515
use PhpList\RestBundle\Serializer\MessageNormalizer;
16+
use PhpList\RestBundle\Serializer\TemplateImageNormalizer;
17+
use PhpList\RestBundle\Serializer\TemplateNormalizer;
1618
use PHPUnit\Framework\TestCase;
1719

1820
class MessageNormalizerTest extends TestCase
1921
{
20-
public function testSupportsNormalization(): void
22+
private MessageNormalizer $normalizer;
23+
24+
public function __construct(string $name)
2125
{
22-
$normalizer = new MessageNormalizer();
26+
parent::__construct($name);
27+
$this->normalizer = new MessageNormalizer(new TemplateNormalizer(new TemplateImageNormalizer()));
28+
}
2329

30+
public function testSupportsNormalization(): void
31+
{
2432
$message = $this->createMock(Message::class);
25-
$this->assertTrue($normalizer->supportsNormalization($message));
26-
$this->assertFalse($normalizer->supportsNormalization(new \stdClass()));
33+
$this->assertTrue($this->normalizer->supportsNormalization($message));
34+
$this->assertFalse($this->normalizer->supportsNormalization(new \stdClass()));
2735
}
2836

2937
public function testNormalizeReturnsExpectedArray(): void
@@ -70,8 +78,7 @@ public function testNormalizeReturnsExpectedArray(): void
7078
$message->method('getSchedule')->willReturn($schedule);
7179
$message->method('getOptions')->willReturn($options);
7280

73-
$normalizer = new MessageNormalizer();
74-
$result = $normalizer->normalize($message);
81+
$result = $this->normalizer->normalize($message);
7582

7683
$this->assertSame(1, $result['id']);
7784
$this->assertSame('uuid-123', $result['unique_id']);
@@ -84,7 +91,6 @@ public function testNormalizeReturnsExpectedArray(): void
8491

8592
public function testNormalizeWithInvalidObjectReturnsEmptyArray(): void
8693
{
87-
$normalizer = new MessageNormalizer();
88-
$this->assertSame([], $normalizer->normalize(new \stdClass()));
94+
$this->assertSame([], $this->normalizer->normalize(new \stdClass()));
8995
}
9096
}

0 commit comments

Comments
 (0)