99use PhpList \Core \Domain \Common \Model \Filter \PaginatedFilter ;
1010use PhpList \Core \Domain \Identity \Model \PrivilegeFlag ;
1111use PhpList \Core \Domain \Subscription \Model \SubscribePage ;
12+ use PhpList \Core \Domain \Subscription \Model \SubscriberList ;
1213use PhpList \Core \Domain \Subscription \Service \Manager \SubscribePageManager ;
14+ use PhpList \Core \Domain \Subscription \Service \Manager \SubscriberAttributeManager ;
15+ use PhpList \Core \Domain \Subscription \Service \Manager \SubscriptionManager ;
1316use PhpList \Core \Security \Authentication ;
1417use PhpList \RestBundle \Common \Controller \BaseController ;
1518use PhpList \RestBundle \Common \Service \Provider \PaginatedDataProvider ;
1619use PhpList \RestBundle \Common \Validator \RequestValidator ;
20+ use PhpList \RestBundle \Subscription \Request \PublicSubscriptionRequest ;
1721use PhpList \RestBundle \Subscription \Request \SubscribePageRequest ;
1822use PhpList \RestBundle \Subscription \Serializer \SubscribePageNormalizer ;
1923use PhpList \RestBundle \Subscription \Serializer \SubscribePagePublicNormalizer ;
24+ use PhpList \RestBundle \Subscription \Serializer \SubscriptionNormalizer ;
2025use Symfony \Bridge \Doctrine \Attribute \MapEntity ;
2126use Symfony \Component \HttpFoundation \JsonResponse ;
2227use Symfony \Component \HttpFoundation \Request ;
@@ -33,6 +38,9 @@ public function __construct(
3338 private readonly SubscribePageNormalizer $ normalizer ,
3439 private readonly EntityManagerInterface $ entityManager ,
3540 private readonly PaginatedDataProvider $ paginatedProvider ,
41+ private readonly SubscriptionManager $ subscriptionManager ,
42+ private readonly SubscriptionNormalizer $ subscriptionNormalizer ,
43+ private readonly SubscriberAttributeManager $ subscriberAttributeManager ,
3644 ) {
3745 parent ::__construct ($ authentication , $ validator );
3846 }
@@ -425,4 +433,102 @@ public function deletePage(
425433
426434 return $ this ->json (null , Response::HTTP_NO_CONTENT );
427435 }
436+
437+ #[Route(
438+ '/{id}/lists/{listId}/subscribers ' ,
439+ name: 'subscribe ' ,
440+ requirements: ['listId ' => '\d+ ' , 'id ' => '\d+ ' ],
441+ methods: ['POST ' ]
442+ )]
443+ #[OA \Post(
444+ path: '/api/v2/subscribe-pages/{id}/lists/{listId}/subscribers ' ,
445+ description: '🚧 **Status: Beta** – This method is under development. Avoid using in production. ' .
446+ 'Subscribe subscriber to a list from subscribe page. ' ,
447+ summary: 'Create subscription ' ,
448+ requestBody: new OA \RequestBody (
449+ description: '' ,
450+ required: true ,
451+ content: new OA \JsonContent (ref: '#/components/schemas/PublicSubscriptionRequest ' )
452+ ),
453+ tags: ['subscriptions ' ],
454+ parameters: [
455+ new OA \Parameter (
456+ name: 'listId ' ,
457+ description: 'List ID ' ,
458+ in: 'path ' ,
459+ required: true ,
460+ schema: new OA \Schema (type: 'string ' )
461+ ),
462+ new OA \Parameter (
463+ name: 'id ' ,
464+ description: 'Subscribe page ID ' ,
465+ in: 'path ' ,
466+ required: true ,
467+ schema: new OA \Schema (type: 'integer ' )
468+ ),
469+ ],
470+ responses: [
471+ new OA \Response (
472+ response: 201 ,
473+ description: 'Success ' ,
474+ content: new OA \JsonContent (
475+ type: 'array ' ,
476+ items: new OA \Items (ref: '#/components/schemas/Subscription ' )
477+ )
478+ ),
479+ new OA \Response (
480+ response: 400 ,
481+ description: 'Failure ' ,
482+ content: new OA \JsonContent (ref: '#/components/schemas/BadRequestResponse ' )
483+ ),
484+ new OA \Response (
485+ response: 404 ,
486+ description: 'Failure ' ,
487+ content: new OA \JsonContent (ref: '#/components/schemas/NotFoundErrorResponse ' )
488+ ),
489+ new OA \Response (
490+ response: 422 ,
491+ description: 'Failure ' ,
492+ content: new OA \JsonContent (ref: '#/components/schemas/ValidationErrorResponse ' )
493+ ),
494+ ]
495+ )]
496+ public function subscribe (
497+ Request $ request ,
498+ int $ id ,
499+ #[MapEntity(mapping: ['listId ' => 'id ' ])] ?SubscriberList $ list = null ,
500+ ): JsonResponse {
501+ $ page = $ this ->subscribePageManager ->findPublicPage (id: $ id );
502+ if (!$ list || !$ page ) {
503+ throw $ this ->createNotFoundException ('Subscriber list or subscribe page not found. ' );
504+ }
505+
506+ /** @var PublicSubscriptionRequest $subscriptionRequest */
507+ $ subscriptionRequest = $ this ->validator ->validate (
508+ request: $ request ,
509+ dtoClass: PublicSubscriptionRequest::class,
510+ beforeValidation: static function (PublicSubscriptionRequest $ dto ) use ($ page ): void {
511+ $ dto ->setSubscribePage ($ page );
512+ }
513+ );
514+ $ subscriberEmail = $ subscriptionRequest ->email ;
515+ $ subscriptions = $ this ->subscriptionManager ->createSubscriptions (
516+ subscriberList: $ list ,
517+ emails: [$ subscriberEmail ],
518+ autoConfirm: false ,
519+ );
520+ $ this ->entityManager ->flush ();
521+
522+ if ($ subscriptionRequest ->attributes !== []) {
523+ $ this ->subscriberAttributeManager ->processAttributes (
524+ subscriber: $ subscriptions [0 ]->getSubscriber (),
525+ attributeData: $ subscriptionRequest ->attributes
526+ );
527+ }
528+ $ this ->entityManager ->flush ();
529+
530+ $ normalized = array_map (fn ($ item ) => $ this ->subscriptionNormalizer ->normalize ($ item ), $ subscriptions );
531+
532+ return $ this ->json ($ normalized , Response::HTTP_CREATED );
533+ }
428534}
0 commit comments