Passed
Push — master ( e717c7...e31763 )
by
unknown
08:28 queued 13s
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 Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
18
use Symfony\Component\HttpFoundation\RequestStack;
19
use Symfony\Component\HttpFoundation\Response;
20
use Symfony\Component\Routing\Annotation\Route;
21
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
22
use \Symfony\Component\Routing\Generator\UrlGeneratorInterface;
23
24
#[Route('/validate')]
25
class ValidationTokenController extends AbstractController
26
{
27
    public function __construct(
28
        private readonly ValidationTokenHelper $validationTokenHelper,
29
        private readonly ValidationTokenRepository $tokenRepository,
30
        private readonly TrackEDefaultRepository $trackEDefaultRepository,
31
        private readonly TicketRepository $ticketRepository,
32
        private readonly UserRepository $userRepository,
33
        private readonly TicketRelUserRepository $ticketRelUserRepository,
34
        private readonly TokenStorageInterface $tokenStorage,
35
        private readonly RequestStack $requestStack
36
    ) {}
37
38
    #[Route('/{type}/{hash}', name: 'chamilo_core_validate_token')]
39
    public function validate(string $type, string $hash): Response
40
    {
41
        $userId = $this->requestStack->getCurrentRequest()->query->get('user_id');
42
        $userId = $userId !== null ? (int) $userId : null;
43
44
        $token = $this->tokenRepository->findOneBy([
45
            'type' => $this->validationTokenHelper->getTypeId($type),
46
            'hash' => $hash
47
        ]);
48
49
        if (!$token) {
50
            throw $this->createNotFoundException('Invalid token.');
51
        }
52
53
        // Process the action related to the token type
54
        $this->processAction($token, $userId);
55
56
        // Remove the used token
57
        $this->tokenRepository->remove($token, true);
58
59
        // Register the token usage event
60
        $this->registerTokenUsedEvent($token);
61
62
        if ('ticket' === $type) {
63
            $ticketId = $token->getResourceId();
64
            return $this->redirect('/main/ticket/ticket_details.php?ticket_id=' . $ticketId);
65
        }
66
67
        return $this->render('@ChamiloCore/Validation/success.html.twig', [
68
            'type' => $type,
69
        ]);
70
    }
71
72
    #[Route('/test/generate-token/{type}/{resourceId}', name: 'test_generate_token')]
73
    public function testGenerateToken(string $type, int $resourceId): Response
74
    {
75
        $typeId = $this->validationTokenHelper->getTypeId($type);
76
        $token = new ValidationToken($typeId, $resourceId);
77
        $this->tokenRepository->save($token, true);
78
79
        $validationLink = $this->generateUrl('validate_token', [
80
            'type' => $type,
81
            'hash' => $token->getHash(),
82
        ], UrlGeneratorInterface::ABSOLUTE_URL);
83
84
        return new Response("Generated token: {$token->getHash()}<br>Validation link: <a href='{$validationLink}'>{$validationLink}</a>");
85
    }
86
87
    /**
88
     * Processes the action associated with the given token type.
89
     */
90
    private function processAction(ValidationToken $token, ?int $userId): void
91
    {
92
        switch ($token->getType()) {
93
            case ValidationTokenHelper::TYPE_TICKET:
94
                $this->unsubscribeUserFromTicket($token->getResourceId(), $userId);
95
                break;
96
            default:
97
                throw new \InvalidArgumentException('Unrecognized token type');
98
        }
99
    }
100
101
    /**
102
     * Unsubscribes a user from a ticket.
103
     */
104
    private function unsubscribeUserFromTicket(int $ticketId, ?int $userId): void
105
    {
106
        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...
107
            throw $this->createAccessDeniedException('User not authenticated.');
108
        }
109
110
        $ticket = $this->ticketRepository->find($ticketId);
111
        $user = $this->userRepository->find($userId);
112
113
        if ($ticket && $user) {
114
            $this->ticketRelUserRepository->unsubscribeUserFromTicket($user, $ticket);
115
            $this->trackEDefaultRepository->registerTicketUnsubscribeEvent($ticketId, $userId);
116
        } else {
117
            throw $this->createNotFoundException('Ticket or User not found.');
118
        }
119
    }
120
121
    /**
122
     * Registers the usage event of a validation token.
123
     */
124
    private function registerTokenUsedEvent(ValidationToken $token): void
125
    {
126
        $userId = $this->getUserId();
127
        $this->trackEDefaultRepository->registerTokenUsedEvent($token, $userId);
128
    }
129
130
    /**
131
     * Retrieves the current authenticated user's ID.
132
     */
133
    private function getUserId(): ?int
134
    {
135
        $user = $this->tokenStorage->getToken()?->getUser();
136
        return $user instanceof User ? $user->getId() : null;
137
    }
138
}
139