Passed
Push — trunk ( c83b87...a87e38 )
by Christian
22:40 queued 02:13
created

AuthController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
nc 1
nop 8
dl 0
loc 18
rs 10
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php declare(strict_types=1);
2
3
namespace Shopware\Storefront\Controller;
4
5
use Shopware\Core\Checkout\Customer\Exception\BadCredentialsException;
6
use Shopware\Core\Checkout\Customer\Exception\CustomerAuthThrottledException;
7
use Shopware\Core\Checkout\Customer\Exception\CustomerNotFoundByHashException;
8
use Shopware\Core\Checkout\Customer\Exception\CustomerNotFoundException;
9
use Shopware\Core\Checkout\Customer\Exception\CustomerOptinNotCompletedException;
10
use Shopware\Core\Checkout\Customer\Exception\CustomerRecoveryHashExpiredException;
11
use Shopware\Core\Checkout\Customer\SalesChannel\AbstractLoginRoute;
12
use Shopware\Core\Checkout\Customer\SalesChannel\AbstractLogoutRoute;
13
use Shopware\Core\Checkout\Customer\SalesChannel\AbstractResetPasswordRoute;
14
use Shopware\Core\Checkout\Customer\SalesChannel\AbstractSendPasswordRecoveryMailRoute;
15
use Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException;
16
use Shopware\Core\Framework\RateLimiter\Exception\RateLimitExceededException;
17
use Shopware\Core\Framework\Routing\Annotation\Since;
18
use Shopware\Core\Framework\Validation\DataBag\RequestDataBag;
19
use Shopware\Core\Framework\Validation\Exception\ConstraintViolationException;
20
use Shopware\Core\PlatformRequest;
21
use Shopware\Core\System\SalesChannel\Context\SalesChannelContextServiceInterface;
22
use Shopware\Core\System\SalesChannel\Context\SalesChannelContextServiceParameters;
23
use Shopware\Core\System\SalesChannel\SalesChannelContext;
24
use Shopware\Storefront\Checkout\Cart\SalesChannel\StorefrontCartFacade;
25
use Shopware\Storefront\Framework\Routing\Annotation\NoStore;
26
use Shopware\Storefront\Framework\Routing\RequestTransformer;
27
use Shopware\Storefront\Page\Account\Login\AccountGuestLoginPageLoadedHook;
28
use Shopware\Storefront\Page\Account\Login\AccountLoginPageLoadedHook;
29
use Shopware\Storefront\Page\Account\Login\AccountLoginPageLoader;
30
use Shopware\Storefront\Page\Account\RecoverPassword\AccountRecoverPasswordPageLoadedHook;
31
use Shopware\Storefront\Page\Account\RecoverPassword\AccountRecoverPasswordPageLoader;
32
use Symfony\Component\HttpFoundation\Request;
33
use Symfony\Component\HttpFoundation\Response;
34
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
35
use Symfony\Component\Routing\Annotation\Route;
36
37
/**
38
 * @package storefront
39
 *
40
 * @Route(defaults={"_routeScope"={"storefront"}})
41
 *
42
 * @internal
43
 */
44
class AuthController extends StorefrontController
45
{
46
    private AccountLoginPageLoader $loginPageLoader;
47
48
    private AbstractSendPasswordRecoveryMailRoute $sendPasswordRecoveryMailRoute;
49
50
    private AbstractResetPasswordRoute $resetPasswordRoute;
51
52
    private AbstractLoginRoute $loginRoute;
53
54
    private AbstractLogoutRoute $logoutRoute;
55
56
    private StorefrontCartFacade $cartFacade;
57
58
    private AccountRecoverPasswordPageLoader $recoverPasswordPageLoader;
59
60
    private SalesChannelContextServiceInterface $salesChannelContext;
61
62
    /**
63
     * @internal
64
     */
65
    public function __construct(
66
        AccountLoginPageLoader $loginPageLoader,
67
        AbstractSendPasswordRecoveryMailRoute $sendPasswordRecoveryMailRoute,
68
        AbstractResetPasswordRoute $resetPasswordRoute,
69
        AbstractLoginRoute $loginRoute,
70
        AbstractLogoutRoute $logoutRoute,
71
        StorefrontCartFacade $cartFacade,
72
        AccountRecoverPasswordPageLoader $recoverPasswordPageLoader,
73
        SalesChannelContextServiceInterface $salesChannelContextService
74
    ) {
75
        $this->loginPageLoader = $loginPageLoader;
76
        $this->sendPasswordRecoveryMailRoute = $sendPasswordRecoveryMailRoute;
77
        $this->resetPasswordRoute = $resetPasswordRoute;
78
        $this->loginRoute = $loginRoute;
79
        $this->logoutRoute = $logoutRoute;
80
        $this->cartFacade = $cartFacade;
81
        $this->recoverPasswordPageLoader = $recoverPasswordPageLoader;
82
        $this->salesChannelContext = $salesChannelContextService;
83
    }
84
85
    /**
86
     * @Since("6.0.0.0")
87
     * @Route("/account/login", name="frontend.account.login.page", methods={"GET"})
88
     * @NoStore
89
     */
90
    public function loginPage(Request $request, RequestDataBag $data, SalesChannelContext $context): Response
91
    {
92
        /** @var string $redirect */
93
        $redirect = $request->get('redirectTo', 'frontend.account.home.page');
94
95
        $customer = $context->getCustomer();
96
97
        if ($customer !== null && $customer->getGuest() === false) {
98
            $request->request->set('redirectTo', $redirect);
99
100
            return $this->createActionResponse($request);
101
        }
102
103
        $page = $this->loginPageLoader->load($request, $context);
104
105
        $this->hook(new AccountLoginPageLoadedHook($page, $context));
106
107
        return $this->renderStorefront('@Storefront/storefront/page/account/register/index.html.twig', [
108
            'redirectTo' => $redirect,
109
            'redirectParameters' => $request->get('redirectParameters', json_encode([])),
110
            'page' => $page,
111
            'loginError' => (bool) $request->get('loginError'),
112
            'waitTime' => $request->get('waitTime'),
113
            'errorSnippet' => $request->get('errorSnippet'),
114
            'data' => $data,
115
        ]);
116
    }
117
118
    /**
119
     * @Since("6.3.4.1")
120
     * @Route("/account/guest/login", name="frontend.account.guest.login.page", methods={"GET"})
121
     * @NoStore
122
     */
123
    public function guestLoginPage(Request $request, SalesChannelContext $context): Response
124
    {
125
        /** @var string $redirect */
126
        $redirect = $request->get('redirectTo', 'frontend.account.home.page');
127
128
        $customer = $context->getCustomer();
129
130
        if ($customer !== null) {
131
            $request->request->set('redirectTo', $redirect);
132
133
            return $this->createActionResponse($request);
134
        }
135
136
        $waitTime = (int) $request->get('waitTime');
137
        if ($waitTime) {
138
            $this->addFlash(self::INFO, $this->trans('account.loginThrottled', ['%seconds%' => $waitTime]));
139
        }
140
141
        if ((bool) $request->get('loginError')) {
142
            $this->addFlash(self::DANGER, $this->trans('account.orderGuestLoginWrongCredentials'));
143
        }
144
145
        $page = $this->loginPageLoader->load($request, $context);
146
147
        $this->hook(new AccountGuestLoginPageLoadedHook($page, $context));
148
149
        return $this->renderStorefront('@Storefront/storefront/page/account/guest-auth.html.twig', [
150
            'redirectTo' => $redirect,
151
            'redirectParameters' => $request->get('redirectParameters', json_encode([])),
152
            'page' => $page,
153
        ]);
154
    }
155
156
    /**
157
     * @Since("6.0.0.0")
158
     * @Route("/account/logout", name="frontend.account.logout.page", methods={"GET"})
159
     */
160
    public function logout(Request $request, SalesChannelContext $context, RequestDataBag $dataBag): Response
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

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

160
    public function logout(/** @scrutinizer ignore-unused */ Request $request, SalesChannelContext $context, RequestDataBag $dataBag): Response

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
161
    {
162
        if ($context->getCustomer() === null) {
163
            return $this->redirectToRoute('frontend.account.login.page');
164
        }
165
166
        try {
167
            $this->logoutRoute->logout($context, $dataBag);
168
            $this->addFlash(self::SUCCESS, $this->trans('account.logoutSucceeded'));
169
170
            $parameters = [];
171
        } catch (ConstraintViolationException $formViolations) {
172
            $parameters = ['formViolations' => $formViolations];
173
        }
174
175
        return $this->redirectToRoute('frontend.account.login.page', $parameters);
176
    }
177
178
    /**
179
     * @Since("6.0.0.0")
180
     * @Route("/account/login", name="frontend.account.login", methods={"POST"}, defaults={"XmlHttpRequest"=true})
181
     */
182
    public function login(Request $request, RequestDataBag $data, SalesChannelContext $context): Response
183
    {
184
        $customer = $context->getCustomer();
185
186
        if ($customer !== null && $customer->getGuest() === false) {
187
            return $this->createActionResponse($request);
188
        }
189
190
        try {
191
            $token = $this->loginRoute->login($data, $context)->getToken();
192
            $cartBeforeNewContext = $this->cartFacade->get($token, $context);
193
194
            $newContext = $this->salesChannelContext->get(
195
                new SalesChannelContextServiceParameters(
196
                    $context->getSalesChannelId(),
197
                    $token,
198
                    $context->getLanguageIdChain()[0],
199
                    $context->getCurrencyId(),
200
                    $context->getDomainId(),
201
                    $context->getContext()
202
                )
203
            );
204
205
            // Update the sales channel context for CacheResponseSubscriber
206
            $request->attributes->set(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT, $newContext);
207
208
            if (!empty($token)) {
209
                $this->addCartErrors($cartBeforeNewContext);
210
211
                return $this->createActionResponse($request);
212
            }
213
        } catch (BadCredentialsException | UnauthorizedHttpException | CustomerOptinNotCompletedException | CustomerAuthThrottledException $e) {
214
            if ($e instanceof CustomerOptinNotCompletedException) {
215
                $errorSnippet = $e->getSnippetKey();
216
            }
217
218
            if ($e instanceof CustomerAuthThrottledException) {
219
                $waitTime = $e->getWaitTime();
220
            }
221
        }
222
223
        $data->set('password', null);
224
225
        return $this->forwardToRoute(
226
            'frontend.account.login.page',
227
            [
228
                'loginError' => true,
229
                'errorSnippet' => $errorSnippet ?? null,
230
                'waitTime' => $waitTime ?? null,
231
            ]
232
        );
233
    }
234
235
    /**
236
     * @Since("6.1.0.0")
237
     * @Route("/account/recover", name="frontend.account.recover.page", methods={"GET"})
238
     */
239
    public function recoverAccountForm(Request $request, SalesChannelContext $context): Response
240
    {
241
        $page = $this->loginPageLoader->load($request, $context);
242
243
        return $this->renderStorefront('@Storefront/storefront/page/account/profile/recover-password.html.twig', [
244
            'page' => $page,
245
        ]);
246
    }
247
248
    /**
249
     * @Since("6.1.0.0")
250
     * @Route("/account/recover", name="frontend.account.recover.request", methods={"POST"})
251
     */
252
    public function generateAccountRecovery(Request $request, RequestDataBag $data, SalesChannelContext $context): Response
253
    {
254
        try {
255
            $data->get('email')
256
                ->set('storefrontUrl', $request->attributes->get(RequestTransformer::STOREFRONT_URL));
257
258
            $this->sendPasswordRecoveryMailRoute->sendRecoveryMail(
259
                $data->get('email')->toRequestDataBag(),
260
                $context,
261
                false
262
            );
263
264
            $this->addFlash(self::SUCCESS, $this->trans('account.recoveryMailSend'));
265
        } catch (CustomerNotFoundException $e) {
266
            $this->addFlash(self::SUCCESS, $this->trans('account.recoveryMailSend'));
267
        } catch (InconsistentCriteriaIdsException $e) {
268
            $this->addFlash(self::DANGER, $this->trans('error.message-default'));
269
        } catch (RateLimitExceededException $e) {
270
            $this->addFlash(self::INFO, $this->trans('error.rateLimitExceeded', ['%seconds%' => $e->getWaitTime()]));
271
        }
272
273
        return $this->redirectToRoute('frontend.account.recover.page');
274
    }
275
276
    /**
277
     * @Since("6.1.0.0")
278
     * @Route("/account/recover/password", name="frontend.account.recover.password.page", methods={"GET"})
279
     */
280
    public function resetPasswordForm(Request $request, SalesChannelContext $context): Response
281
    {
282
        /** @var ?string $hash */
283
        $hash = $request->get('hash');
284
285
        if (!$hash || !\is_string($hash)) {
286
            $this->addFlash(self::DANGER, $this->trans('account.passwordHashNotFound'));
287
288
            return $this->redirectToRoute('frontend.account.recover.request');
289
        }
290
291
        try {
292
            $page = $this->recoverPasswordPageLoader->load($request, $context, $hash);
293
        } catch (ConstraintViolationException $e) {
294
            $this->addFlash(self::DANGER, $this->trans('account.passwordHashNotFound'));
295
296
            return $this->redirectToRoute('frontend.account.recover.request');
297
        }
298
299
        $this->hook(new AccountRecoverPasswordPageLoadedHook($page, $context));
300
301
        if ($page->getHash() === null || $page->isHashExpired()) {
302
            $this->addFlash(self::DANGER, $this->trans('account.passwordHashNotFound'));
303
304
            return $this->redirectToRoute('frontend.account.recover.request');
305
        }
306
307
        return $this->renderStorefront('@Storefront/storefront/page/account/profile/reset-password.html.twig', [
308
            'page' => $page,
309
            'formViolations' => $request->get('formViolations'),
310
        ]);
311
    }
312
313
    /**
314
     * @Since("6.1.0.0")
315
     * @Route("/account/recover/password", name="frontend.account.recover.password.reset", methods={"POST"})
316
     */
317
    public function resetPassword(RequestDataBag $data, SalesChannelContext $context): Response
318
    {
319
        $hash = $data->get('password')->get('hash');
320
321
        try {
322
            $pw = $data->get('password');
323
324
            $this->resetPasswordRoute->resetPassword($pw->toRequestDataBag(), $context);
325
326
            $this->addFlash(self::SUCCESS, $this->trans('account.passwordChangeSuccess'));
327
        } catch (ConstraintViolationException $formViolations) {
328
            $this->addFlash(self::DANGER, $this->trans('account.passwordChangeNoSuccess'));
329
330
            return $this->forwardToRoute(
331
                'frontend.account.recover.password.page',
332
                ['hash' => $hash, 'formViolations' => $formViolations, 'passwordFormViolation' => true]
333
            );
334
        } catch (CustomerNotFoundByHashException $e) {
335
            $this->addFlash(self::DANGER, $this->trans('account.passwordChangeNoSuccess'));
336
337
            return $this->forwardToRoute('frontend.account.recover.request');
338
        } catch (CustomerRecoveryHashExpiredException $e) {
339
            $this->addFlash(self::DANGER, $this->trans('account.passwordHashExpired'));
340
341
            return $this->forwardToRoute('frontend.account.recover.request');
342
        }
343
344
        return $this->redirectToRoute('frontend.account.profile.page');
345
    }
346
}
347