Passed
Push — dependabot/npm_and_yarn/nanoid... ( aaf2c9...c4aa90 )
by
unknown
14:37 queued 06:22
created

ValidationTokenController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 0
nc 1
nop 8
dl 0
loc 10
rs 10
c 1
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
2
3
declare(strict_types=1);
4
5
/* For licensing terms, see /license.txt */
6
7
namespace Chamilo\CoreBundle\Controller;
8
9
use Chamilo\CoreBundle\Entity\User;
10
use Chamilo\CoreBundle\Entity\ValidationToken;
11
use Chamilo\CoreBundle\Repository\Node\UserRepository;
12
use Chamilo\CoreBundle\Repository\TicketRelUserRepository;
13
use Chamilo\CoreBundle\Repository\TicketRepository;
14
use Chamilo\CoreBundle\Repository\TrackEDefaultRepository;
15
use Chamilo\CoreBundle\Repository\ValidationTokenRepository;
16
use Chamilo\CoreBundle\ServiceHelper\ValidationTokenHelper;
17
use InvalidArgumentException;
18
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
19
use Symfony\Component\HttpFoundation\RequestStack;
20
use Symfony\Component\HttpFoundation\Response;
21
use Symfony\Component\Routing\Annotation\Route;
22
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
23
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
24
25
#[Route('/validate')]
26
class ValidationTokenController extends AbstractController
27
{
28
    public function __construct(
29
        private readonly ValidationTokenHelper $validationTokenHelper,
30
        private readonly ValidationTokenRepository $tokenRepository,
31
        private readonly TrackEDefaultRepository $trackEDefaultRepository,
32
        private readonly TicketRepository $ticketRepository,
33
        private readonly UserRepository $userRepository,
34
        private readonly TicketRelUserRepository $ticketRelUserRepository,
35
        private readonly TokenStorageInterface $tokenStorage,
36
        private readonly RequestStack $requestStack
37
    ) {}
38
39
    #[Route('/{type}/{hash}', name: 'chamilo_core_validate_token')]
40
    public function validate(string $type, string $hash): Response
41
    {
42
        $userId = $this->requestStack->getCurrentRequest()->query->get('user_id');
43
        $userId = null !== $userId ? (int) $userId : null;
44
45
        $token = $this->tokenRepository->findOneBy([
46
            'type' => $this->validationTokenHelper->getTypeId($type),
47
            'hash' => $hash,
48
        ]);
49
50
        if (!$token) {
51
            throw $this->createNotFoundException('Invalid token.');
52
        }
53
54
        // Process the action related to the token type
55
        $this->processAction($token, $userId);
56
57
        // Remove the used token
58
        $this->tokenRepository->remove($token, true);
59
60
        // Register the token usage event
61
        $this->registerTokenUsedEvent($token);
62
63
        if ('ticket' === $type) {
64
            $ticketId = $token->getResourceId();
65
66
            return $this->redirect('/main/ticket/ticket_details.php?ticket_id='.$ticketId);
67
        }
68
69
        return $this->render('@ChamiloCore/Validation/success.html.twig', [
70
            'type' => $type,
71
        ]);
72
    }
73
74
    #[Route('/test/generate-token/{type}/{resourceId}', name: 'test_generate_token')]
75
    public function testGenerateToken(string $type, int $resourceId): Response
76
    {
77
        $typeId = $this->validationTokenHelper->getTypeId($type);
78
        $token = new ValidationToken($typeId, $resourceId);
79
        $this->tokenRepository->save($token, true);
80
81
        $validationLink = $this->generateUrl('validate_token', [
82
            'type' => $type,
83
            'hash' => $token->getHash(),
84
        ], UrlGeneratorInterface::ABSOLUTE_URL);
85
86
        return new Response("Generated token: {$token->getHash()}<br>Validation link: <a href='{$validationLink}'>{$validationLink}</a>");
87
    }
88
89
    /**
90
     * Processes the action associated with the given token type.
91
     */
92
    private function processAction(ValidationToken $token, ?int $userId): void
93
    {
94
        switch ($token->getType()) {
95
            case ValidationTokenHelper::TYPE_TICKET:
96
                $this->unsubscribeUserFromTicket($token->getResourceId(), $userId);
97
98
                break;
99
100
            default:
101
                throw new InvalidArgumentException('Unrecognized token type');
102
        }
103
    }
104
105
    /**
106
     * Unsubscribes a user from a ticket.
107
     */
108
    private function unsubscribeUserFromTicket(int $ticketId, ?int $userId): void
109
    {
110
        if (!$userId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $userId of type integer|null is loosely compared to false; this is ambiguous if the integer can be 0. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
111
            throw $this->createAccessDeniedException('User not authenticated.');
112
        }
113
114
        $ticket = $this->ticketRepository->find($ticketId);
115
        $user = $this->userRepository->find($userId);
116
117
        if ($ticket && $user) {
118
            $this->ticketRelUserRepository->unsubscribeUserFromTicket($user, $ticket);
119
            $this->trackEDefaultRepository->registerTicketUnsubscribeEvent($ticketId, $userId);
120
        } else {
121
            throw $this->createNotFoundException('Ticket or User not found.');
122
        }
123
    }
124
125
    /**
126
     * Registers the usage event of a validation token.
127
     */
128
    private function registerTokenUsedEvent(ValidationToken $token): void
129
    {
130
        $userId = $this->getUserId();
131
        $this->trackEDefaultRepository->registerTokenUsedEvent($token, $userId);
132
    }
133
134
    /**
135
     * Retrieves the current authenticated user's ID.
136
     */
137
    private function getUserId(): ?int
138
    {
139
        $user = $this->tokenStorage->getToken()?->getUser();
140
141
        return $user instanceof User ? $user->getId() : null;
142
    }
143
}
144