Passed
Push — master ( 366f40...c67819 )
by Christian
13:04 queued 10s
created

src/Storefront/Controller/NewsletterController.php (2 issues)

Labels
Severity
1
<?php declare(strict_types=1);
2
3
namespace Shopware\Storefront\Controller;
4
5
use Shopware\Core\Checkout\Customer\CustomerEntity;
6
use Shopware\Core\Content\Newsletter\SalesChannel\AbstractNewsletterConfirmRoute;
7
use Shopware\Core\Content\Newsletter\SalesChannel\AbstractNewsletterSubscribeRoute;
8
use Shopware\Core\Content\Newsletter\SalesChannel\AbstractNewsletterUnsubscribeRoute;
9
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
10
use Shopware\Core\Framework\Routing\Annotation\LoginRequired;
11
use Shopware\Core\Framework\Routing\Annotation\RouteScope;
12
use Shopware\Core\Framework\Routing\Annotation\Since;
13
use Shopware\Core\Framework\Validation\DataBag\QueryDataBag;
14
use Shopware\Core\Framework\Validation\DataBag\RequestDataBag;
15
use Shopware\Core\System\SalesChannel\SalesChannelContext;
16
use Shopware\Storefront\Framework\Captcha\Annotation\Captcha;
17
use Shopware\Storefront\Framework\Routing\RequestTransformer;
18
use Shopware\Storefront\Page\Newsletter\Subscribe\NewsletterSubscribePageLoader;
19
use Symfony\Component\HttpFoundation\Request;
20
use Symfony\Component\HttpFoundation\Response;
21
use Symfony\Component\Routing\Annotation\Route;
22
23
/**
24
 * @RouteScope(scopes={"storefront"})
25
 */
26
class NewsletterController extends StorefrontController
27
{
28
    /**
29
     * @var NewsletterSubscribePageLoader
30
     */
31
    private $newsletterConfirmRegisterPageLoader;
32
33
    /**
34
     * @var EntityRepositoryInterface
35
     */
36
    private $customerRepository;
37
38
    /**
39
     * @var AbstractNewsletterSubscribeRoute
40
     */
41
    private $newsletterSubscribeRoute;
42
43
    /**
44
     * @var AbstractNewsletterConfirmRoute
45
     */
46
    private $newsletterConfirmRoute;
47
48
    /**
49
     * @var AbstractNewsletterUnsubscribeRoute
50
     */
51
    private $newsletterUnsubscribeRoute;
52
53
    public function __construct(
54
        NewsletterSubscribePageLoader $newsletterConfirmRegisterPageLoader,
55
        EntityRepositoryInterface $customerRepository,
56
        AbstractNewsletterSubscribeRoute $newsletterSubscribeRoute,
57
        AbstractNewsletterConfirmRoute $newsletterConfirmRoute,
58
        AbstractNewsletterUnsubscribeRoute $newsletterUnsubscribeRoute
59
    ) {
60
        $this->newsletterConfirmRegisterPageLoader = $newsletterConfirmRegisterPageLoader;
61
        $this->customerRepository = $customerRepository;
62
        $this->newsletterSubscribeRoute = $newsletterSubscribeRoute;
63
        $this->newsletterConfirmRoute = $newsletterConfirmRoute;
64
        $this->newsletterUnsubscribeRoute = $newsletterUnsubscribeRoute;
65
    }
66
67
    /**
68
     * @Since("6.0.0.0")
69
     * @Route("/newsletter-subscribe", name="frontend.newsletter.subscribe", methods={"GET"})
70
     */
71
    public function subscribeMail(SalesChannelContext $context, Request $request, QueryDataBag $queryDataBag): Response
72
    {
73
        try {
74
            $this->newsletterConfirmRoute->confirm($queryDataBag->toRequestDataBag(), $context);
75
        } catch (\Throwable $throwable) {
76
            $this->addFlash('danger', $this->trans('newsletter.subscriptionConfirmationFailed'));
77
78
            throw new \Exception($throwable->getMessage(), $throwable->getCode(), $throwable);
79
        }
80
81
        $page = $this->newsletterConfirmRegisterPageLoader->load($request, $context);
82
83
        return $this->renderStorefront('@Storefront/storefront/page/newsletter/confirm-subscribe.html.twig', ['page' => $page]);
84
    }
85
86
    /**
87
     * @Since("6.0.0.0")
88
     * @LoginRequired()
89
     * @Route("/widgets/account/newsletter", name="frontend.account.newsletter", methods={"POST"}, defaults={"XmlHttpRequest"=true})
90
     * @Captcha
91
     */
92
    public function subscribeCustomer(Request $request, RequestDataBag $dataBag, SalesChannelContext $context, ?CustomerEntity $customer = null): Response
93
    {
94
        /* @deprecated tag:v6.4.0 - Parameter $customer will be mandatory when using with @LoginRequired() */
95
        if (!$customer) {
96
            $customer = $context->getCustomer();
97
        }
98
99
        $subscribed = $request->get('option', false) === 'direct';
100
101
        if (!$subscribed) {
102
            $dataBag->set('option', 'unsubscribe');
103
        }
104
105
        $dataBag->set('storefrontUrl', $request->attributes->get(RequestTransformer::STOREFRONT_URL));
106
107
        $messages = [];
108
        $success = null;
109
110
        if ($subscribed) {
111
            try {
112
                $this->newsletterSubscribeRoute->subscribe(
113
                    $this->hydrateFromCustomer($dataBag, $customer),
0 ignored issues
show
It seems like $customer can also be of type null; however, parameter $customer of Shopware\Storefront\Cont...::hydrateFromCustomer() does only seem to accept Shopware\Core\Checkout\Customer\CustomerEntity, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

113
                    $this->hydrateFromCustomer($dataBag, /** @scrutinizer ignore-type */ $customer),
Loading history...
114
                    $context,
115
                    false
116
                );
117
118
                $this->setNewsletterFlag($customer, true, $context);
0 ignored issues
show
It seems like $customer can also be of type null; however, parameter $customer of Shopware\Storefront\Cont...er::setNewsletterFlag() does only seem to accept Shopware\Core\Checkout\Customer\CustomerEntity, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

118
                $this->setNewsletterFlag(/** @scrutinizer ignore-type */ $customer, true, $context);
Loading history...
119
120
                $success = true;
121
                $messages[] = ['type' => 'success', 'text' => $this->trans('newsletter.subscriptionConfirmationSuccess')];
122
            } catch (\Exception $exception) {
123
                $success = false;
124
                $messages[] = ['type' => 'danger', 'text' => $this->trans('newsletter.subscriptionConfirmationFailed')];
125
            }
126
127
            return $this->renderStorefront('@Storefront/storefront/page/account/newsletter.html.twig', [
128
                'customer' => $customer,
129
                'messages' => $messages,
130
                'success' => $success,
131
            ]);
132
        }
133
134
        try {
135
            $this->newsletterUnsubscribeRoute->unsubscribe(
136
                $this->hydrateFromCustomer($dataBag, $customer),
137
                $context
138
            );
139
            $this->setNewsletterFlag($customer, false, $context);
140
141
            $success = true;
142
            $messages[] = ['type' => 'success', 'text' => $this->trans('newsletter.subscriptionRevokeSuccess')];
143
        } catch (\Exception $exception) {
144
            $success = false;
145
            $messages[] = ['type' => 'danger', 'text' => $this->trans('error.message-default')];
146
        }
147
148
        return $this->renderStorefront('@Storefront/storefront/page/account/newsletter.html.twig', [
149
            'customer' => $customer,
150
            'messages' => $messages,
151
            'success' => $success,
152
        ]);
153
    }
154
155
    private function hydrateFromCustomer(RequestDataBag $dataBag, CustomerEntity $customer): RequestDataBag
156
    {
157
        $dataBag->set('email', $customer->getEmail());
158
        $dataBag->set('salutationId', $customer->getSalutationId());
159
        $dataBag->set('title', $customer->getTitle());
160
        $dataBag->set('firstName', $customer->getFirstName());
161
        $dataBag->set('lastName', $customer->getLastName());
162
        $dataBag->set('zipCode', $customer->getDefaultShippingAddress()->getZipCode());
163
        $dataBag->set('city', $customer->getDefaultShippingAddress()->getCity());
164
165
        return $dataBag;
166
    }
167
168
    private function setNewsletterFlag(CustomerEntity $customer, bool $newsletter, SalesChannelContext $context): void
169
    {
170
        $customer->setNewsletter($newsletter);
171
172
        $this->customerRepository->update(
173
            [
174
                ['id' => $customer->getId(), 'newsletter' => $newsletter],
175
            ],
176
            $context->getContext()
177
        );
178
    }
179
}
180