Skip to content

Commit 9a574dc

Browse files
committed
CampaignActionController
1 parent 9bbad8b commit 9a574dc

5 files changed

Lines changed: 366 additions & 313 deletions

File tree

Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\RestBundle\Messaging\Controller;
6+
7+
use Doctrine\ORM\EntityManagerInterface;
8+
use OpenApi\Attributes as OA;
9+
use PhpList\Core\Domain\Messaging\Message\SyncCampaignProcessorMessage;
10+
use PhpList\Core\Domain\Messaging\Model\Message;
11+
use PhpList\Core\Domain\Messaging\Model\Message\MessageStatus;
12+
use PhpList\Core\Domain\Messaging\Service\Manager\MessageManager;
13+
use PhpList\Core\Security\Authentication;
14+
use PhpList\RestBundle\Common\Controller\BaseController;
15+
use PhpList\RestBundle\Common\Validator\RequestValidator;
16+
use PhpList\RestBundle\Messaging\Request\Message\MessageMetadataRequest;
17+
use PhpList\RestBundle\Messaging\Request\ResendMessageToListsRequest;
18+
use PhpList\RestBundle\Messaging\Serializer\MessageNormalizer;
19+
use PhpList\RestBundle\Messaging\Service\CampaignService;
20+
use Symfony\Bridge\Doctrine\Attribute\MapEntity;
21+
use Symfony\Component\HttpFoundation\JsonResponse;
22+
use Symfony\Component\HttpFoundation\Request;
23+
use Symfony\Component\HttpFoundation\Response;
24+
use Symfony\Component\Messenger\MessageBusInterface;
25+
use Symfony\Component\Routing\Attribute\Route;
26+
27+
/**
28+
* This controller provides REST API to manage campaign actions.
29+
*
30+
* @author Tatevik Grigoryan <tatevik@phplist.com>
31+
*/
32+
#[Route('/campaigns', name: 'campaign_')]
33+
class CampaignActionController extends BaseController
34+
{
35+
public function __construct(
36+
Authentication $authentication,
37+
RequestValidator $validator,
38+
private readonly CampaignService $campaignService,
39+
private readonly MessageBusInterface $messageBus,
40+
private readonly EntityManagerInterface $entityManager,
41+
private readonly MessageManager $messageManager,
42+
private readonly MessageNormalizer $messageNormalizer
43+
) {
44+
parent::__construct($authentication, $validator);
45+
}
46+
47+
#[Route('/{messageId}/copy', name: 'copy_campaign', requirements: ['messageId' => '\d+'], methods: ['POST'])]
48+
#[OA\Post(
49+
path: '/api/v2/campaigns/{messageId}/copy',
50+
description: '🚧 **Status: Beta** – This method is under development. Avoid using in production. ' .
51+
'Copies campaign/message by id into a draft message.',
52+
summary: 'Copies campaign/message by id.',
53+
tags: ['campaigns'],
54+
parameters: [
55+
new OA\Parameter(
56+
name: 'php-auth-pw',
57+
description: 'Session key obtained from login',
58+
in: 'header',
59+
required: true,
60+
schema: new OA\Schema(type: 'string')
61+
),
62+
new OA\Parameter(
63+
name: 'messageId',
64+
description: 'message ID',
65+
in: 'path',
66+
required: true,
67+
schema: new OA\Schema(type: 'string')
68+
)
69+
],
70+
responses: [
71+
new OA\Response(
72+
response: 201,
73+
description: 'Success',
74+
content: new OA\JsonContent(ref: '#/components/schemas/Message')
75+
),
76+
new OA\Response(
77+
response: 403,
78+
description: 'Failure',
79+
content: new OA\JsonContent(ref: '#/components/schemas/UnauthorizedResponse')
80+
)
81+
]
82+
)]
83+
public function copyMessage(
84+
Request $request,
85+
#[MapEntity(mapping: ['messageId' => 'id'])] ?Message $message = null
86+
): JsonResponse {
87+
$authUser = $this->requireAuthentication($request);
88+
if ($message === null) {
89+
throw $this->createNotFoundException('Campaign not found.');
90+
}
91+
92+
$message = $this->messageManager->copyAsDraftMessage($message, $authUser);
93+
$this->entityManager->flush();
94+
95+
return $this->json($this->campaignService->getMessage($message), Response::HTTP_CREATED);
96+
}
97+
98+
#[Route('/{messageId}/status', name: 'update_status', requirements: ['messageId' => '\d+'], methods: ['PATCH'])]
99+
#[OA\Patch(
100+
path: '/api/v2/campaigns/{messageId}/status',
101+
description: '🚧 **Status: Beta** – This method is under development. Avoid using in production. ' .
102+
'Updates campaign/message status by id.',
103+
summary: 'Update campaign status by id.',
104+
requestBody: new OA\RequestBody(
105+
description: 'Update message status.',
106+
required: true,
107+
content: new OA\JsonContent(ref: '#/components/schemas/MessageMetadataRequest')
108+
),
109+
tags: ['campaigns'],
110+
parameters: [
111+
new OA\Parameter(
112+
name: 'php-auth-pw',
113+
description: 'Session key obtained from login',
114+
in: 'header',
115+
required: true,
116+
schema: new OA\Schema(
117+
type: 'string'
118+
)
119+
),
120+
new OA\Parameter(
121+
name: 'messageId',
122+
description: 'message ID',
123+
in: 'path',
124+
required: true,
125+
schema: new OA\Schema(type: 'string')
126+
)
127+
],
128+
responses: [
129+
new OA\Response(
130+
response: 200,
131+
description: 'Success',
132+
content: new OA\JsonContent(ref: '#/components/schemas/Message')
133+
),
134+
new OA\Response(
135+
response: 403,
136+
description: 'Failure',
137+
content: new OA\JsonContent(ref: '#/components/schemas/UnauthorizedResponse')
138+
),
139+
new OA\Response(
140+
response: 404,
141+
description: 'Failure',
142+
content: new OA\JsonContent(ref: '#/components/schemas/NotFoundErrorResponse')
143+
),
144+
new OA\Response(
145+
response: 422,
146+
description: 'Failure',
147+
content: new OA\JsonContent(ref: '#/components/schemas/ValidationErrorResponse')
148+
),
149+
]
150+
)]
151+
public function updateMessageStatus(
152+
Request $request,
153+
#[MapEntity(mapping: ['messageId' => 'id'])] ?Message $message = null,
154+
): JsonResponse {
155+
$this->requireAuthentication($request);
156+
if ($message === null) {
157+
throw $this->createNotFoundException('Message not found.');
158+
}
159+
160+
/** @var MessageMetadataRequest $messageMetadataRequest */
161+
$messageMetadataRequest = $this->validator->validate($request, MessageMetadataRequest::class);
162+
163+
$message = $this->messageManager->updateStatus(
164+
$message,
165+
MessageStatus::from($messageMetadataRequest->status),
166+
);
167+
$this->entityManager->flush();
168+
169+
return $this->json($this->messageNormalizer->normalize($message), Response::HTTP_OK);
170+
}
171+
172+
#[Route('/{messageId}/send', name: 'send_campaign', requirements: ['messageId' => '\d+'], methods: ['POST'])]
173+
#[OA\Post(
174+
path: '/api/v2/campaigns/{messageId}/send',
175+
description: '🚧 **Status: Beta** – This method is under development. Avoid using in production. ' .
176+
'Processes/sends campaign/message by id.',
177+
summary: 'Processes/sends campaign/message by id.',
178+
tags: ['campaigns'],
179+
parameters: [
180+
new OA\Parameter(
181+
name: 'php-auth-pw',
182+
description: 'Session key obtained from login',
183+
in: 'header',
184+
required: true,
185+
schema: new OA\Schema(type: 'string')
186+
),
187+
new OA\Parameter(
188+
name: 'messageId',
189+
description: 'message ID',
190+
in: 'path',
191+
required: true,
192+
schema: new OA\Schema(type: 'string')
193+
)
194+
],
195+
responses: [
196+
new OA\Response(
197+
response: 200,
198+
description: 'Success',
199+
content: new OA\JsonContent(ref: '#/components/schemas/Message')
200+
),
201+
new OA\Response(
202+
response: 403,
203+
description: 'Failure',
204+
content: new OA\JsonContent(ref: '#/components/schemas/UnauthorizedResponse')
205+
),
206+
new OA\Response(
207+
response: 404,
208+
description: 'Failure',
209+
content: new OA\JsonContent(ref: '#/components/schemas/NotFoundErrorResponse')
210+
),
211+
]
212+
)]
213+
public function sendMessage(
214+
Request $request,
215+
#[MapEntity(mapping: ['messageId' => 'id'])] ?Message $message = null
216+
): JsonResponse {
217+
$this->requireAuthentication($request);
218+
if ($message === null) {
219+
throw $this->createNotFoundException('Campaign not found.');
220+
}
221+
222+
$this->messageBus->dispatch(new SyncCampaignProcessorMessage($message->getId()));
223+
224+
return $this->json($this->campaignService->getMessage($message), Response::HTTP_OK);
225+
}
226+
227+
#[Route('/{messageId}/resend', name: 'resend_campaign', requirements: ['messageId' => '\d+'], methods: ['POST'])]
228+
#[OA\Post(
229+
path: '/api/v2/campaigns/{messageId}/resend',
230+
description: '🚧 **Status: Beta** – This method is under development. Avoid using in production. ' .
231+
'Processes/sends campaign/message by id to specified mailing lists.',
232+
summary: 'Processes/sends campaign/message by id to lists.',
233+
requestBody: new OA\RequestBody(
234+
description: 'List ids to send this campaign to.',
235+
required: true,
236+
content: new OA\JsonContent(ref: '#/components/schemas/ResendMessageToListsRequest')
237+
),
238+
tags: ['campaigns'],
239+
parameters: [
240+
new OA\Parameter(
241+
name: 'php-auth-pw',
242+
description: 'Session key obtained from login',
243+
in: 'header',
244+
required: true,
245+
schema: new OA\Schema(type: 'string')
246+
),
247+
new OA\Parameter(
248+
name: 'messageId',
249+
description: 'message ID',
250+
in: 'path',
251+
required: true,
252+
schema: new OA\Schema(type: 'string')
253+
)
254+
],
255+
responses: [
256+
new OA\Response(
257+
response: 200,
258+
description: 'Success',
259+
content: new OA\JsonContent(ref: '#/components/schemas/Message')
260+
),
261+
new OA\Response(
262+
response: 403,
263+
description: 'Failure',
264+
content: new OA\JsonContent(ref: '#/components/schemas/UnauthorizedResponse')
265+
)
266+
]
267+
)]
268+
public function resendMessageToLists(
269+
Request $request,
270+
#[MapEntity(mapping: ['messageId' => 'id'])] ?Message $message = null
271+
): JsonResponse {
272+
$this->requireAuthentication($request);
273+
if ($message === null) {
274+
throw $this->createNotFoundException('Campaign not found.');
275+
}
276+
277+
/** @var ResendMessageToListsRequest $resendToListsRequest */
278+
$resendToListsRequest = $this->validator->validate($request, ResendMessageToListsRequest::class);
279+
280+
$this->messageBus->dispatch(
281+
new SyncCampaignProcessorMessage($message->getId(), $resendToListsRequest->listIds)
282+
);
283+
284+
return $this->json($this->campaignService->getMessage($message), Response::HTTP_OK);
285+
}
286+
}

0 commit comments

Comments
 (0)