Skip to content

Commit 3cec7c9

Browse files
committed
ISSUE-345: get campaigns endpoint
1 parent 46beb03 commit 3cec7c9

File tree

6 files changed

+285
-0
lines changed

6 files changed

+285
-0
lines changed

config/services/normalizers.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,7 @@ services:
2626
PhpList\RestBundle\Serializer\SubscriptionNormalizer:
2727
tags: [ 'serializer.normalizer' ]
2828
autowire: true
29+
30+
PhpList\RestBundle\Serializer\MessageNormalizer:
31+
tags: [ 'serializer.normalizer' ]
32+
autowire: true

config/services/providers.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
services:
2+
_defaults:
3+
autowire: true
4+
autoconfigure: true
5+
public: false
6+
7+
PhpList\RestBundle\Service\Provider\MessageProvider:
8+
autowire: true
9+
autoconfigure: true

src/Controller/CampaignController.php

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

src/OpenApi/SwaggerSchemasEntity.php

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,86 @@
6161
],
6262
type: 'object'
6363
)]
64+
#[OA\Schema(
65+
schema: 'Template',
66+
properties: [
67+
new OA\Property(property: 'id', type: 'integer', example: 1),
68+
new OA\Property(property: 'title', type: 'string', example: 'Newsletter'),
69+
new OA\Property(property: 'template', type: 'string', example: 'Hello World!', nullable: true),
70+
new OA\Property(property: 'template_text', type: 'string', nullable: true),
71+
new OA\Property(property: 'order', type: 'integer', nullable: true),
72+
],
73+
type: 'object',
74+
nullable: true
75+
)]
76+
#[OA\Schema(
77+
schema: 'Message',
78+
properties: [
79+
new OA\Property(property: 'id', type: 'integer'),
80+
new OA\Property(property: 'unique_id', type: 'string', example: '2df6b147-8470-45ed-8e4e-86aa01af400d'),
81+
new OA\Property(
82+
property: 'template',
83+
ref: '#/components/schemas/Template',
84+
nullable: true
85+
),
86+
new OA\Property(
87+
property: 'message_content',
88+
properties: [
89+
new OA\Property(property: 'subject', type: 'string', example: 'Newsletter'),
90+
new OA\Property(property: 'text', type: 'string', example: 'Hello World!'),
91+
new OA\Property(property: 'text_message', type: 'string'),
92+
new OA\Property(property: 'footer', type: 'string', example: 'This is a footer'),
93+
],
94+
type: 'object'
95+
),
96+
new OA\Property(
97+
property: 'message_format',
98+
properties: [
99+
new OA\Property(property: 'html_formated', type: 'boolean'),
100+
new OA\Property(property: 'send_format', type: 'string', example: 'text', nullable: true),
101+
new OA\Property(property: 'as_text', type: 'boolean', example: true),
102+
new OA\Property(property: 'as_html', type: 'boolean'),
103+
new OA\Property(property: 'as_pdf', type: 'boolean'),
104+
new OA\Property(property: 'as_text_and_html', type: 'boolean'),
105+
new OA\Property(property: 'as_text_and_pdf', type: 'boolean'),
106+
],
107+
type: 'object'
108+
),
109+
new OA\Property(
110+
property: 'message_metadata',
111+
properties: [
112+
new OA\Property(property: 'status', type: 'string', example: 'sent'),
113+
new OA\Property(property: 'processed', type: 'bool', example: true),
114+
new OA\Property(property: 'views', type: 'integer', example: 12),
115+
new OA\Property(property: 'bounce_count', type: 'integer'),
116+
new OA\Property(property: 'entered', type: 'string', format: 'date-time', nullable: true),
117+
new OA\Property(property: 'sent', type: 'string', format: 'date-time', nullable: true),
118+
],
119+
type: 'object'
120+
),
121+
new OA\Property(
122+
property: 'message_schedule',
123+
properties: [
124+
new OA\Property(property: 'repeat_interval', type: 'string', nullable: true),
125+
new OA\Property(property: 'repeat_until', type: 'string', format: 'date-time', nullable: true),
126+
new OA\Property(property: 'requeue_interval', type: 'string', nullable: true),
127+
new OA\Property(property: 'requeue_until', type: 'string', format: 'date-time', nullable: true),
128+
],
129+
type: 'object'
130+
),
131+
new OA\Property(
132+
property: 'message_options',
133+
properties: [
134+
new OA\Property(property: 'from_field', type: 'string', example: ' My Name <[email protected]>', nullable: true),
135+
new OA\Property(property: 'to_field', type: 'string', example: '', nullable: true),
136+
new OA\Property(property: 'reply_to', type: 'string', nullable: true),
137+
new OA\Property(property: 'embargo', type: 'string', example: '2023-01-01T12:00:00Z', nullable: true),
138+
new OA\Property(property: 'user_selection', type: 'string', nullable: true),
139+
],
140+
type: 'object'),
141+
],
142+
type: 'object'
143+
)]
64144
class SwaggerSchemasEntity
65145
{
66146
}

src/Serializer/MessageNormalizer.php

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\RestBundle\Serializer;
6+
7+
use PhpList\Core\Domain\Model\Messaging\Message;
8+
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
9+
10+
class MessageNormalizer 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 Message) {
18+
return [];
19+
}
20+
21+
return [
22+
'id' => $object->getId(),
23+
'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,
31+
'message_content' => [
32+
'subject' => $object->getContent()->getSubject(),
33+
'text' => $object->getContent()->getText(),
34+
'text_message' => $object->getContent()->getTextMessage(),
35+
'footer' => $object->getContent()->getFooter(),
36+
],
37+
'message_format' => [
38+
'html_formated' => $object->getFormat()->isHtmlFormatted(),
39+
'send_format' => $object->getFormat()->getSendFormat(),
40+
'as_text' => $object->getFormat()->isAsText(),
41+
'as_html' => $object->getFormat()->isAsHtml(),
42+
'as_pdf' => $object->getFormat()->isAsPdf(),
43+
'as_text_and_html' => $object->getFormat()->isAsTextAndHtml(),
44+
'as_text_and_pdf' => $object->getFormat()->isAsTextAndPdf(),
45+
],
46+
'message_metadata' => [
47+
'status' => $object->getMetadata()->getStatus(),
48+
'processed' => $object->getMetadata()->isProcessed(),
49+
'views' => $object->getMetadata()->getViews(),
50+
'bounce_count' => $object->getMetadata()->getBounceCount(),
51+
'entered' => $object->getMetadata()->getEntered()?->format('Y-m-d\TH:i:sP'),
52+
'sent' => $object->getMetadata()->getSent()?->format('Y-m-d\TH:i:sP'),
53+
],
54+
'message_schedule' => [
55+
'repeat_interval' => $object->getSchedule()->getRepeatInterval(),
56+
'repeat_until' => $object->getSchedule()->getRepeatUntil()?->format('Y-m-d\TH:i:sP'),
57+
'requeue_interval' => $object->getSchedule()->getRequeueInterval(),
58+
'requeue_until' => $object->getSchedule()->getRequeueUntil()?->format('Y-m-d\TH:i:sP'),
59+
],
60+
'message_options' => [
61+
'from_field' => $object->getOptions()->getFromField(),
62+
'to_field' => $object->getOptions()->getToField(),
63+
'reply_to' => $object->getOptions()->getReplyTo(),
64+
'embargo' => $object->getOptions()->getEmbargo(),
65+
'user_selection' => $object->getOptions()->getUserSelection(),
66+
],
67+
];
68+
}
69+
70+
/**
71+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
72+
*/
73+
public function supportsNormalization($data, string $format = null): bool
74+
{
75+
return $data instanceof Message;
76+
}
77+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\RestBundle\Service\Provider;
6+
7+
use PhpList\Core\Domain\Model\Identity\Administrator;
8+
use PhpList\Core\Domain\Model\Messaging\Message;
9+
use PhpList\Core\Domain\Repository\Messaging\MessageRepository;
10+
11+
class MessageProvider
12+
{
13+
private MessageRepository $messageRepository;
14+
15+
public function __construct(
16+
MessageRepository $messageRepository,
17+
) {
18+
$this->messageRepository = $messageRepository;
19+
}
20+
21+
/** @return Message[] */
22+
public function getMessagesByOwner(Administrator $owner): array
23+
{
24+
return $this->messageRepository->getByOwnerId($owner->getId());
25+
}
26+
}

0 commit comments

Comments
 (0)