Passed
Pull Request — master (#58)
by Paweł
04:04
created

ApiUsersController::removeCourseFromUser()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 24
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 9
c 0
b 0
f 0
dl 0
loc 24
rs 9.9666
cc 4
nc 4
nop 3
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
        }
106
107
108
        return new Response($this->serializer->serialize($user, 'json', ['groups' => ['user_details']]), Response::HTTP_OK);
109
    }
110
111
112
    public function requestPasswordReset(
113
        Request $request,
114
        FormFactoryInterface $formFactory,
115
        EntityManagerInterface $entityManager,
116
        UserManagerInterface $userManager,
117
        UserRepositoryInterface $userRepository,
118
        EventDispatcherInterface $eventDispatcher
119
    ): Response {
120
        $form = $formFactory->create(UserPasswordResetRequestType::class, []);
121
        $form->handleRequest($request);
122
        if ($form->isSubmitted() && $form->isValid()) {
123
            $user = $userRepository->getOneByEmail($form->getData()['email']);
124
            if (null === $user) {
125
                throw new NotFoundHttpException('User was not found');
126
            }
127
            $userManager->setGeneratedPasswordResetToken($user);
128
            $entityManager->flush();
129
130
            $eventDispatcher->dispatch(new UserPasswordChangeRequestEvent($user));
131
132
            return new JsonResponse(['success' => true]);
133
        }
134
135
        return new Response($this->serializer->serialize(ErrorHandler::getErrorsFromForm($form), 'json'), Response::HTTP_BAD_REQUEST);
136
    }
137
138
    public function requestPassword(
139
        Request $request,
140
        FormFactoryInterface $formFactory,
141
        EntityManagerInterface $entityManager,
142
        UserManagerInterface $userManager,
143
        UserRepositoryInterface $userRepository
144
    ): Response {
145
        $form = $formFactory->create(UserPasswordResetType::class, []);
146
        $form->handleRequest($request);
147
        if ($form->isSubmitted() && $form->isValid()) {
148
            $user = $userRepository->getOneByPasswordResetToken($request->query->get('token'));
149
            if (null === $user) {
150
                throw new NotFoundHttpException('User was not found');
151
            }
152
153
            $data = $form->getData();
154
            if ($data['password'] !== $data['repeatedPassword']) {
155
                throw new \InvalidArgumentException('Passwords are not equal');
156
            }
157
158
            $userManager->resetPassword($user, $data['password']);
159
            $entityManager->flush();
160
161
            return new Response($this->serializer->serialize($user, 'json', ['groups' => ['user_details']]), Response::HTTP_OK);
162
        }
163
164
        return new Response($this->serializer->serialize(ErrorHandler::getErrorsFromForm($form), 'json'), Response::HTTP_BAD_REQUEST);
165
    }
166
167
    public function checkEmail(
168
        Request $request,
169
        FormFactoryInterface $formFactory,
170
        UserRepositoryInterface $userRepository
171
    ): Response {
172
        $form = $formFactory->create(UserEmailType::class, []);
173
        $form->handleRequest($request);
174
        if ($form->isSubmitted() && $form->isValid()) {
175
            $user = $userRepository->getOneByEmail($form->getData()['email']);
176
177
            if (null !== $user) {
178
                return new Response($this->serializer->serialize($user, 'json', ['groups' => ['user_details']]), Response::HTTP_OK);
179
            }
180
181
            return new Response(null, Response::HTTP_NOT_FOUND);
182
        }
183
184
        return new Response($this->serializer->serialize(ErrorHandler::getErrorsFromForm($form), 'json'), Response::HTTP_BAD_REQUEST);
185
    }
186
}
187