ApiUsersController::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace App\Controller;
6
7
use App\Event\UserCreateEvent;
8
use App\Event\UserPasswordChangeRequestEvent;
9
use App\Form\ErrorHandler;
10
use App\Form\RegisterUserType;
11
use App\Form\UserEmailType;
12
use App\Form\UserPasswordResetRequestType;
13
use App\Form\UserPasswordResetType;
14
use App\Manager\UserManagerInterface;
15
use App\Repository\UserRepositoryInterface;
16
use Doctrine\ORM\EntityManagerInterface;
17
use SWP\Component\Common\Exception\NotFoundHttpException;
18
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
19
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
20
use Symfony\Component\Form\FormFactoryInterface;
21
use Symfony\Component\HttpFoundation\JsonResponse;
22
use Symfony\Component\HttpFoundation\Request;
23
use Symfony\Component\HttpFoundation\Response;
24
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
25
use Symfony\Component\Serializer\SerializerInterface;
26
27
final class ApiUsersController extends AbstractController
28
{
29
    protected SerializerInterface $serializer;
30
31
    public function __construct(SerializerInterface $serializer)
32
    {
33
        $this->serializer = $serializer;
34
    }
35
36
    public function getCurrentUser(): Response
37
    {
38
        return new Response($this->serializer->serialize($this->getUser(), 'json', [
39
            'groups' => [
40
                'user_details',
41
                'course_details',
42
            ],
43
        ]));
44
    }
45
46
    public function registerOrUpdateUser(
47
        Request $request,
48
        FormFactoryInterface $formFactory,
49
        EntityManagerInterface $entityManager,
50
        UserManagerInterface $userManager,
51
        TokenStorageInterface $tokenStorage,
52
        EventDispatcherInterface $eventDispatcher
53
    ): Response {
54
        if (!$request->request->has('email')) {
55
            return new JsonResponse(['message' => 'User email is not provided'], Response::HTTP_BAD_REQUEST);
56
        }
57
58
        $user = $userManager->getOrCreateUser($request->request->get('email'));
59
        $form = $formFactory->create(RegisterUserType::class, $user);
60
        $form->handleRequest($request);
61
        if ($form->isSubmitted() && $form->isValid()) {
62
            if (null !== $courseTitleOrSku = $form->get('course')->getData()) {
63
                $userManager->addCourseByTitleOrSku($user, $courseTitleOrSku);
64
            }
65
66
            $newUser = false;
67
            if (!$entityManager->contains($user)) {
68
                $entityManager->persist($user);
69
                $newUser = true;
70
            }
71
72
            $entityManager->flush();
73
            $tokenStorage->getToken()->setUser($user);
74
75
            if ($newUser) {
76
                $eventDispatcher->dispatch(new UserCreateEvent($user));
77
            }
78
79
            return new Response($this->serializer->serialize($user, 'json', ['groups' => ['user_details']]), Response::HTTP_CREATED);
80
        }
81
82
        return new Response($this->serializer->serialize(ErrorHandler::getErrorsFromForm($form), 'json'), Response::HTTP_BAD_REQUEST);
83
    }
84
85
    public function removeCourseFromUser(
86
        Request $request,
87
        EntityManagerInterface $entityManager,
88
        UserManagerInterface $userManager
89
    ): Response
90
    {
91
        if (!$request->request->has('email')) {
92
            return new JsonResponse(['message' => 'User email is not provided'], Response::HTTP_BAD_REQUEST);
93
        }
94
95
        if (!$request->request->has('course')) {
96
            return new JsonResponse(['message' => 'Course title is not provided'], Response::HTTP_BAD_REQUEST);
97
        }
98
99
        $user = $userManager->getOrCreateUser($request->request->get('email'));
100
101
        if (null !== $courseTitle = $request->request->get('course')) {
102
            $userManager->removeCourseByTitleOrSku($user, $courseTitle);
103
104
            $entityManager->flush();
105
            $entityManager->refresh($user);
106
        }
107
108
109
        return new Response($this->serializer->serialize($user, 'json', ['groups' => ['user_details']]), Response::HTTP_OK);
110
    }
111
112
113
    public function requestPasswordReset(
114
        Request $request,
115
        FormFactoryInterface $formFactory,
116
        EntityManagerInterface $entityManager,
117
        UserManagerInterface $userManager,
118
        UserRepositoryInterface $userRepository,
119
        EventDispatcherInterface $eventDispatcher
120
    ): Response {
121
        $form = $formFactory->create(UserPasswordResetRequestType::class, []);
122
        $form->handleRequest($request);
123
        if ($form->isSubmitted() && $form->isValid()) {
124
            $user = $userRepository->getOneByEmail($form->getData()['email']);
125
            if (null === $user) {
126
                throw new NotFoundHttpException('User was not found');
127
            }
128
            $userManager->setGeneratedPasswordResetToken($user);
129
            $entityManager->flush();
130
131
            $eventDispatcher->dispatch(new UserPasswordChangeRequestEvent($user));
132
133
            return new JsonResponse(['success' => true]);
134
        }
135
136
        return new Response($this->serializer->serialize(ErrorHandler::getErrorsFromForm($form), 'json'), Response::HTTP_BAD_REQUEST);
137
    }
138
139
    public function requestPassword(
140
        Request $request,
141
        FormFactoryInterface $formFactory,
142
        EntityManagerInterface $entityManager,
143
        UserManagerInterface $userManager,
144
        UserRepositoryInterface $userRepository
145
    ): Response {
146
        $form = $formFactory->create(UserPasswordResetType::class, []);
147
        $form->handleRequest($request);
148
        if ($form->isSubmitted() && $form->isValid()) {
149
            $user = $userRepository->getOneByPasswordResetToken($request->query->get('token'));
150
            if (null === $user) {
151
                throw new NotFoundHttpException('User was not found');
152
            }
153
154
            $data = $form->getData();
155
            if ($data['password'] !== $data['repeatedPassword']) {
156
                throw new \InvalidArgumentException('Passwords are not equal');
157
            }
158
159
            $userManager->resetPassword($user, $data['password']);
160
            $entityManager->flush();
161
162
            return new Response($this->serializer->serialize($user, 'json', ['groups' => ['user_details']]), Response::HTTP_OK);
163
        }
164
165
        return new Response($this->serializer->serialize(ErrorHandler::getErrorsFromForm($form), 'json'), Response::HTTP_BAD_REQUEST);
166
    }
167
168
    public function checkEmail(
169
        Request $request,
170
        FormFactoryInterface $formFactory,
171
        UserRepositoryInterface $userRepository
172
    ): Response {
173
        $form = $formFactory->create(UserEmailType::class, []);
174
        $form->handleRequest($request);
175
        if ($form->isSubmitted() && $form->isValid()) {
176
            $user = $userRepository->getOneByEmail($form->getData()['email']);
177
178
            if (null !== $user) {
179
                return new Response($this->serializer->serialize($user, 'json', ['groups' => ['user_details']]), Response::HTTP_OK);
180
            }
181
182
            return new Response(null, Response::HTTP_NOT_FOUND);
183
        }
184
185
        return new Response($this->serializer->serialize(ErrorHandler::getErrorsFromForm($form), 'json'), Response::HTTP_BAD_REQUEST);
186
    }
187
}
188