Skip to content

Commit 1e5c0df

Browse files
committed
ISSUE-345: template id validation
1 parent 70b7c55 commit 1e5c0df

File tree

10 files changed

+103
-9
lines changed

10 files changed

+103
-9
lines changed

config/services/validators.yml

+5
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,8 @@ services:
1313
autowire: true
1414
autoconfigure: true
1515
tags: [ 'validator.constraint_validator' ]
16+
17+
PhpList\RestBundle\Validator\TemplateExistsValidator:
18+
autowire: true
19+
autoconfigure: true
20+
tags: [ 'validator.constraint_validator' ]

src/Controller/CampaignController.php

+14-1
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,13 @@ public function getMessages(Request $request): JsonResponse
109109
schema: new OA\Schema(
110110
type: 'string'
111111
)
112+
),
113+
new OA\Parameter(
114+
name: 'messageId',
115+
description: 'message ID',
116+
in: 'path',
117+
required: true,
118+
schema: new OA\Schema(type: 'string')
112119
)
113120
],
114121
responses: [
@@ -143,6 +150,7 @@ public function getMessage(
143150
required: true,
144151
content: new OA\JsonContent(
145152
properties: [
153+
new OA\Property(property: 'template_id', type: 'integer', example: 1),
146154
new OA\Property(
147155
property: 'message_content',
148156
properties: [
@@ -182,6 +190,12 @@ enum: ['html', 'text', 'invite'],
182190
new OA\Property(
183191
property: 'message_schedule',
184192
properties: [
193+
new OA\Property(
194+
property: 'embargo',
195+
type: 'string',
196+
format: 'date-time',
197+
example: '2025-04-17 09:00:00'
198+
),
185199
new OA\Property(property: 'repeat_interval', type: 'string', example: '24 hours'),
186200
new OA\Property(
187201
property: 'repeat_until',
@@ -205,7 +219,6 @@ enum: ['html', 'text', 'invite'],
205219
new OA\Property(property: 'from_field', type: 'string', example: '[email protected]'),
206220
new OA\Property(property: 'to_field', type: 'string', example: '[email protected]'),
207221
new OA\Property(property: 'reply_to', type: 'string', example: '[email protected]'),
208-
new OA\Property(property: 'embargo', type: 'string', example: '2025-04-17 09:00:00'),
209222
new OA\Property(property: 'user_selection', type: 'string', example: 'all-active-users'),
210223
],
211224
type: 'object'

src/Entity/Request/CreateMessageRequest.php

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use PhpList\RestBundle\Entity\Request\Message\MessageOptionsRequest;
1111
use PhpList\RestBundle\Entity\Request\Message\MessageScheduleRequest;
1212
use Symfony\Component\Validator\Constraints as Assert;
13+
use PhpList\RestBundle\Validator as CustomAssert;
1314

1415
class CreateMessageRequest implements RequestInterface
1516
{
@@ -32,4 +33,7 @@ class CreateMessageRequest implements RequestInterface
3233
#[Assert\Valid]
3334
#[Assert\NotNull]
3435
public MessageOptionsRequest $options;
36+
37+
#[CustomAssert\TemplateExists]
38+
public ?int $templateId;
3539
}

src/Entity/Request/Message/MessageOptionsRequest.php

-3
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,5 @@ class MessageOptionsRequest
1717
#[Assert\Email]
1818
public ?string $replyTo = null;
1919

20-
#[Assert\NotBlank]
21-
public string $embargo;
22-
2320
public ?string $userSelection = null;
2421
}

src/Entity/Request/Message/MessageScheduleRequest.php

+3
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,7 @@ class MessageScheduleRequest
1919

2020
#[Assert\DateTime]
2121
public string $requeueUntil;
22+
23+
#[Assert\NotBlank]
24+
public string $embargo;
2225
}

src/OpenApi/SwaggerSchemasEntity.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@
125125
new OA\Property(property: 'repeat_until', type: 'string', format: 'date-time', nullable: true),
126126
new OA\Property(property: 'requeue_interval', type: 'string', nullable: true),
127127
new OA\Property(property: 'requeue_until', type: 'string', format: 'date-time', nullable: true),
128+
new OA\Property(property: 'embargo', type: 'string', example: '2023-01-01T12:00:00Z', nullable: true),
128129
],
129130
type: 'object'
130131
),
@@ -139,7 +140,6 @@
139140
),
140141
new OA\Property(property: 'to_field', type: 'string', example: '', nullable: true),
141142
new OA\Property(property: 'reply_to', type: 'string', nullable: true),
142-
new OA\Property(property: 'embargo', type: 'string', example: '2023-01-01T12:00:00Z', nullable: true),
143143
new OA\Property(property: 'user_selection', type: 'string', nullable: true),
144144
],
145145
type: 'object'

src/Serializer/MessageNormalizer.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,12 @@ public function normalize($object, string $format = null, array $context = []):
5858
'repeat_until' => $object->getSchedule()->getRepeatUntil()?->format('Y-m-d\TH:i:sP'),
5959
'requeue_interval' => $object->getSchedule()->getRequeueInterval(),
6060
'requeue_until' => $object->getSchedule()->getRequeueUntil()?->format('Y-m-d\TH:i:sP'),
61+
'embargo' => $object->getSchedule()->getEmbargo()?->format('Y-m-d\TH:i:sP'),
6162
],
6263
'message_options' => [
6364
'from_field' => $object->getOptions()->getFromField(),
6465
'to_field' => $object->getOptions()->getToField(),
6566
'reply_to' => $object->getOptions()->getReplyTo(),
66-
'embargo' => $object->getOptions()->getEmbargo()?->format('Y-m-d\TH:i:sP'),
6767
'user_selection' => $object->getOptions()->getUserSelection(),
6868
],
6969
];

src/Service/Manager/MessageManager.php

+10-3
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,18 @@
88
use PhpList\Core\Domain\Model\Identity\Administrator;
99
use PhpList\Core\Domain\Model\Messaging\Message;
1010
use PhpList\Core\Domain\Repository\Messaging\MessageRepository;
11+
use PhpList\Core\Domain\Repository\Messaging\TemplateRepository;
1112
use PhpList\RestBundle\Entity\Request\CreateMessageRequest;
1213

1314
class MessageManager
1415
{
1516
private MessageRepository $messageRepository;
17+
private TemplateRepository $templateRepository;
1618

17-
public function __construct(MessageRepository $messageRepository)
19+
public function __construct(MessageRepository $messageRepository, TemplateRepository $templateRepository)
1820
{
1921
$this->messageRepository = $messageRepository;
22+
$this->templateRepository = $templateRepository;
2023
}
2124

2225
public function createMessage(CreateMessageRequest $createMessageRequest, Administrator $authUser): Message
@@ -32,6 +35,7 @@ public function createMessage(CreateMessageRequest $createMessageRequest, Admini
3235
new DateTime($createMessageRequest->schedule->repeatUntil),
3336
$createMessageRequest->schedule->requeueInterval,
3437
new DateTime($createMessageRequest->schedule->requeueUntil),
38+
new DateTime($createMessageRequest->schedule->embargo),
3539
);
3640

3741
$metadata = new Message\MessageMetadata($createMessageRequest->metadata->status);
@@ -47,13 +51,16 @@ public function createMessage(CreateMessageRequest $createMessageRequest, Admini
4751
$createMessageRequest->options->fromField ?? '',
4852
$createMessageRequest->options->toField ?? '',
4953
$createMessageRequest->options->replyTo ?? '',
50-
new DateTime($createMessageRequest->options->embargo),
5154
$createMessageRequest->options->userSelection,
5255
null,
5356
null
5457
);
5558

56-
$message = new Message($format, $schedule, $metadata, $content, $options, $authUser);
59+
if ($createMessageRequest->templateId > 0) {
60+
$template = $this->templateRepository->find($createMessageRequest->templateId);
61+
}
62+
63+
$message = new Message($format, $schedule, $metadata, $content, $options, $authUser, $template ?? null);
5764

5865
$this->messageRepository->save($message);
5966

src/Validator/TemplateExists.php

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\RestBundle\Validator;
6+
7+
use Symfony\Component\Validator\Constraint;
8+
9+
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
10+
class TemplateExists extends Constraint
11+
{
12+
public string $message = 'Template with id "{{ value }}" does not exists.';
13+
public string $mode = 'strict';
14+
15+
public function __construct(?string $mode = null, ?string $message = null, ?array $groups = null, $payload = null)
16+
{
17+
parent::__construct([], $groups, $payload);
18+
19+
$this->mode = $mode ?? $this->mode;
20+
$this->message = $message ?? $this->message;
21+
}
22+
}
+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\RestBundle\Validator;
6+
7+
use PhpList\Core\Domain\Repository\Messaging\TemplateRepository;
8+
use Symfony\Component\HttpKernel\Exception\ConflictHttpException;
9+
use Symfony\Component\Validator\Constraint;
10+
use Symfony\Component\Validator\ConstraintValidator;
11+
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
12+
use Symfony\Component\Validator\Exception\UnexpectedValueException;
13+
14+
class TemplateExistsValidator extends ConstraintValidator
15+
{
16+
private TemplateRepository $templateRepository;
17+
18+
public function __construct(TemplateRepository $templateRepository)
19+
{
20+
$this->templateRepository = $templateRepository;
21+
}
22+
23+
public function validate($value, Constraint $constraint): void
24+
{
25+
if (!$constraint instanceof TemplateExists) {
26+
throw new UnexpectedTypeException($constraint, TemplateExists::class);
27+
}
28+
29+
if (null === $value || '' === $value) {
30+
return;
31+
}
32+
33+
if (!is_int($value)) {
34+
throw new UnexpectedValueException($value, 'integer');
35+
}
36+
37+
$existingUser = $this->templateRepository->find($value);
38+
39+
if (!$existingUser) {
40+
throw new ConflictHttpException('Template with that id does not exists.');
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)