diff --git a/src/Subscription/Controller/SubscriberController.php b/src/Subscription/Controller/SubscriberController.php
index a281b659..9d3aecb4 100644
--- a/src/Subscription/Controller/SubscriberController.php
+++ b/src/Subscription/Controller/SubscriberController.php
@@ -18,6 +18,7 @@
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Attribute\Route;
/**
@@ -281,4 +282,53 @@ public function deleteSubscriber(
return $this->json(null, Response::HTTP_NO_CONTENT);
}
+
+ #[Route('/confirm', name: 'confirm', methods: ['GET'])]
+ #[OA\Get(
+ path: '/api/v2/subscribers/confirm',
+ description: '🚧 **Status: Beta** – This method is under development. Avoid using in production.',
+ summary: 'Confirm a subscriber by uniqueId.',
+ requestBody: new OA\RequestBody(
+ required: true,
+ content: new OA\JsonContent(
+ properties: [
+ new OA\Property(property: 'uniqueId', type: 'string', example: 'e9d8c9b2e6')
+ ]
+ )
+ ),
+ tags: ['subscribers'],
+ responses: [
+ new OA\Response(
+ response: 200,
+ description: 'Subscriber confirmed',
+ content: new OA\MediaType(
+ mediaType: 'text/html'
+ )
+ ),
+ new OA\Response(
+ response: 400,
+ description: 'Missing or invalid uniqueId'
+ ),
+ new OA\Response(
+ response: 404,
+ description: 'Subscriber not found'
+ )
+ ]
+ )]
+ public function setSubscriberAsConfirmed(Request $request): Response
+ {
+ $uniqueId = $request->query->get('uniqueId');
+
+ if (!$uniqueId) {
+ return new Response('
Missing confirmation code.
', 400);
+ }
+
+ try {
+ $this->subscriberManager->markAsConfirmedByUniqueId($uniqueId);
+ } catch (NotFoundHttpException) {
+ return new Response('Subscriber isn\'t found or already confirmed.
', 404);
+ }
+
+ return new Response('Thank you, your subscription is confirmed!
');
+ }
}
diff --git a/src/Subscription/Controller/SubscriberImportController.php b/src/Subscription/Controller/SubscriberImportController.php
index 57e546d5..683140b8 100644
--- a/src/Subscription/Controller/SubscriberImportController.php
+++ b/src/Subscription/Controller/SubscriberImportController.php
@@ -55,7 +55,7 @@ public function __construct(
description: 'List id to add imported subscribers to',
type: 'string',
default: null,
- pattern: "^\\d+$"
+ pattern: '^\\d+$'
),
new OA\Property(
property: 'update_existing',
diff --git a/tests/Integration/Subscription/Controller/SubscriberControllerTest.php b/tests/Integration/Subscription/Controller/SubscriberControllerTest.php
index 2ee4c226..3ffb4dd2 100644
--- a/tests/Integration/Subscription/Controller/SubscriberControllerTest.php
+++ b/tests/Integration/Subscription/Controller/SubscriberControllerTest.php
@@ -9,6 +9,7 @@
use PhpList\RestBundle\Subscription\Controller\SubscriberController;
use PhpList\RestBundle\Tests\Integration\Common\AbstractTestController;
use PhpList\RestBundle\Tests\Integration\Subscription\Fixtures\SubscriberFixture;
+use Symfony\Component\HttpFoundation\Response;
/**
* Testcase.
@@ -165,4 +166,44 @@ public function testPostSubscribersWithValidSessionKeyAssignsProvidedSubscriberD
static::assertTrue($responseContent['html_email']);
static::assertFalse($responseContent['disabled']);
}
+ public function testSetSubscriberAsConfirmedWithMissingUniqueIdReturnsBadRequestStatus()
+ {
+ self::getClient()->request('get', '/api/v2/subscribers/confirm');
+
+ $response = self::getClient()->getResponse();
+ self::assertSame(Response::HTTP_BAD_REQUEST, $response->getStatusCode());
+ self::assertStringContainsString('Missing confirmation code', $response->getContent());
+ }
+
+ public function testSetSubscriberAsConfirmedWithInvalidUniqueIdReturnsNotFoundStatus()
+ {
+ self::getClient()->request('get', '/api/v2/subscribers/confirm', ['uniqueId' => 'invalid-unique-id']);
+
+ $response = self::getClient()->getResponse();
+ self::assertSame(Response::HTTP_NOT_FOUND, $response->getStatusCode());
+ self::assertStringContainsString('Subscriber isn\'t found', $response->getContent());
+ }
+
+ public function testSetSubscriberAsConfirmedWithValidUniqueIdConfirmsSubscriber()
+ {
+ $email = 'unconfirmed1@example.com';
+ $jsonData = ['email' => $email, 'requestConfirmation' => true];
+
+ $this->authenticatedJsonRequest('post', '/api/v2/subscribers', [], [], [], json_encode($jsonData));
+ $responseContent = $this->getDecodedJsonResponseContent();
+ $uniqueId = $responseContent['unique_id'];
+
+ $subscriberId = $responseContent['id'];
+ $subscriber = $this->subscriberRepository->find($subscriberId);
+ self::assertFalse($subscriber->isConfirmed());
+
+ self::getClient()->request('get', '/api/v2/subscribers/confirm', ['uniqueId' => $uniqueId]);
+
+ $response = self::getClient()->getResponse();
+ self::assertSame(Response::HTTP_OK, $response->getStatusCode());
+ self::assertStringContainsString('Thank you, your subscription is confirmed', $response->getContent());
+
+ $subscriber = $this->subscriberRepository->findOneByUniqueId($uniqueId);
+ self::assertTrue($subscriber->isConfirmed());
+ }
}