src/Controller/RegistrationController.php line 288
<?phpnamespace App\Controller;use App\Entity\User;use App\Form\RegistrationFormType;use App\Repository\UserRepository;use App\Security\AppAuthenticator;use App\Security\EmailVerifier;use Doctrine\ORM\EntityManagerInterface;use Symfony\Bridge\Twig\Mime\TemplatedEmail;use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;use Symfony\Component\HttpFoundation\Request;use Symfony\Component\HttpFoundation\Response;use Symfony\Component\Mime\Address;use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;use Symfony\Component\Routing\Annotation\Route;use Symfony\Component\Security\Http\Authentication\UserAuthenticatorInterface;use Symfony\Contracts\Translation\TranslatorInterface;use SymfonyCasts\Bundle\VerifyEmail\Exception\VerifyEmailExceptionInterface;use Symfony\Component\HttpFoundation\JsonResponse;use Symfony\Component\Validator\Validator\ValidatorInterface;use Symfony\Component\Validator\Constraints as Assert;use Symfony\Component\Security\Core\Exception\AuthenticationException;class RegistrationController extends AbstractController{private EmailVerifier $emailVerifier;public function __construct(EmailVerifier $emailVerifier){$this->emailVerifier = $emailVerifier;}#[Route('/api/cities', name: 'get_moroccan_cities', methods: ['GET'])]public function getMoroccanCities(): JsonResponse{$cities = ["Casablanca", "Rabat", "Marrakech", "Fes", "Tangier", "Agadir", "Meknes","Oujda", "Kenitra", "Tetouan", "Safi", "El Jadida", "Nador", "Beni Mellal","Khouribga", "Taza", "Mohammedia", "Settat", "Laayoune", "Dakhla"];return new JsonResponse($cities, JsonResponse::HTTP_OK);}#[Route('/api/register', name: 'api_register', methods: ['POST'])]public function apiRegister(Request $request,UserPasswordHasherInterface $userPasswordHasher,UserAuthenticatorInterface $userAuthenticator,AppAuthenticator $authenticator,EntityManagerInterface $entityManager,ValidatorInterface $validator): JsonResponse{// Decode JSON request$data = json_decode($request->getContent(), true);// Check if the necessary fields are present in the requestif (!isset($data['email'], $data['password'], $data['fname'], $data['lname'], $data['phone'])) {return new JsonResponse(['error' => 'Missing required fields'], Response::HTTP_CREATED);}// Validate email format$emailConstraint = new Assert\Email();$emailViolation = $validator->validate($data['email'], $emailConstraint);if (count($emailViolation) > 0) {return new JsonResponse(['error' => 'Invalid email format'], Response::HTTP_CREATED);}// Check if email already exists$existingUser = $entityManager->getRepository(User::class)->findOneBy(['email' => $data['email']]);if ($existingUser) {return new JsonResponse(['error' => 'Email already in use'], Response::HTTP_CREATED);}// Validate phone number format (you can adjust the regex for more specific formats)$phoneConstraint = new Assert\Regex(['pattern' => '/^\+?[0-9]{10,15}$/', // Example regex: Adjust according to your phone number format'message' => 'Invalid phone number format']);$phoneViolation = $validator->validate($data['phone'], $phoneConstraint);if (count($phoneViolation) > 0) {return new JsonResponse(['error' => 'Invalid phone number format'], Response::HTTP_CREATED);}// Create a new User entity$user = new User();$user->setEmail($data['email']);$user->setFname($data['fname']);$user->setLName($data['lname']);$user->setPhone($data['phone']);if (isset($data['type'])) {$user->setType($data['type']);}if (isset($data['identity'])) {$user->setIdentity($data['identity']);}if (isset($data['city'])) {$user->setCity($data['city']);}// Hash the password$user->setPassword($userPasswordHasher->hashPassword($user, $data['password']));// Set default roles and other properties$user->setStatus(0);$user->setRoles(["ROLE_USER"]);// Persist the user to the databasetry {$entityManager->persist($user);$entityManager->flush();} catch (\Exception $e) {return new JsonResponse(['error' => 'Error while saving user to database'], Response::HTTP_INTERNAL_SERVER_ERROR);}// Send email confirmation (if needed for your API, you can skip this if not required)// Authenticate the user (optional, if you want to log them in automatically after registration)try {$userAuthenticator->authenticateUser($user,$authenticator,$request);} catch (AuthenticationException $e) {return new JsonResponse(['error' => 'Authentication error'], Response::HTTP_CREATED);}// Return success response with user details (excluding sensitive data like password)return new JsonResponse(['message' => 'User registered successfully','user' => ['id' => $user->getId(),'email' => $user->getEmail(),'roles' => $user->getRoles()]], Response::HTTP_CREATED);}#[Route('/api/update-profile', name: 'api_update_profile', methods: ['PATCH'])]public function updateProfile(Request $request,EntityManagerInterface $entityManager,ValidatorInterface $validator,UserPasswordHasherInterface $userPasswordHasher): JsonResponse{// Assuming user is authenticated via token or session and we fetch the user ID from the token/session// Here we assume that the user object is retrieved from the security context (i.e., the logged-in user).$user = $this->getUser(); // Get the authenticated userif (!$user) {return new JsonResponse(['error' => 'User not authenticated'], Response::HTTP_OK);}// Decode JSON request$data = json_decode($request->getContent(), true);// Check if the necessary fields are presentif (isset($data['email'])) {// Validate email format$emailConstraint = new Assert\Email();$emailViolation = $validator->validate($data['email'], $emailConstraint);if (count($emailViolation) > 0) {return new JsonResponse(['error' => 'Invalid email format'], Response::HTTP_OK);}// Check if the email already exists for another user (excluding the current user)$existingUser = $entityManager->getRepository(User::class)->findOneBy(['email' => $data['email']]);if ($existingUser && $existingUser->getId() !== $user->getId()) {return new JsonResponse(['error' => 'Email already in use by another user'], Response::HTTP_OK);}}if (isset($data['phone'])) {// Validate phone number format (adjust regex as needed)$phoneConstraint = new Assert\Regex(['pattern' => '/^\+?[0-9]{10,15}$/','message' => 'Invalid phone number format']);$phoneViolation = $validator->validate($data['phone'], $phoneConstraint);if (count($phoneViolation) > 0) {return new JsonResponse(['error' => 'Invalid phone number format'], Response::HTTP_OK);}}// Update the user informationif (isset($data['email'])) {$user->setEmail($data['email']);}if (isset($data['fname'])) {$user->SetFname($data['fname']);}if (isset($data['lname'])) {$user->SetLname($data['lname']);}if (isset($data['phone'])) {$user->SetPhone($data['phone']);}if (isset($data['type'])) {$user->setType($data['type']);}if (isset($data['identity'])) {$user->setIdentity($data['identity']);}if (isset($data['city'])) {$user->setCity($data['city']);}// Optionally update password if provided (ensure password is hashed)if (isset($data['password']) && !empty($data['password'])) {$user->setPassword($userPasswordHasher->hashPassword($user, $data['password']));}// Persist the updated user to the databasetry {$entityManager->persist($user);$entityManager->flush();} catch (\Exception $e) {return new JsonResponse(['error' => 'Error while updating user in the database'], Response::HTTP_OK);}// Return success response with updated user details (excluding sensitive data like password)return new JsonResponse(['message' => 'User profile updated successfully','user' => ['id' => $user->getId(),'email' => $user->getEmail(),'fname' => $user->getFname(),'lname' => $user->getLName(),'phone' => $user->getPhone(),'roles' => $user->getRoles()]], Response::HTTP_OK);}#[Route('/register', name: 'app_register')]public function register(Request $request, UserPasswordHasherInterface $userPasswordHasher, UserAuthenticatorInterface $userAuthenticator, AppAuthenticator $authenticator, EntityManagerInterface $entityManager): Response{$user = new User();$form = $this->createForm(RegistrationFormType::class, $user);$form->handleRequest($request);if ($form->isSubmitted() && $form->isValid()) {// encode the plain password$user->setPassword($userPasswordHasher->hashPassword($user,$form->get('plainPassword')->getData()));$user->setStatus(1);$user->setRoles(["ROLE_USER","ROLE_BTOB_ADMIN"]);$user->setType('B2B');$entityManager->persist($user);$entityManager->flush();// generate a signed url and email it to the user$this->emailVerifier->sendEmailConfirmation('app_verify_email', $user,(new TemplatedEmail())->from(new Address('no-reply@metacard.gift', 'Email confirmation - Metacard'))->to($user->getEmail())->subject('Please Confirm your Email')->htmlTemplate('registration/confirmation_email.html.twig'));// do anything else you need here, like send an emailreturn $userAuthenticator->authenticateUser($user,$authenticator,$request);}return $this->render('registration/register.html.twig', ['registrationForm' => $form->createView(),]);}#[Route('/verify/email', name: 'app_verify_email')]public function verifyUserEmail(Request $request, TranslatorInterface $translator, UserRepository $userRepository): Response{$id = $request->get('id');if (null === $id) {return $this->redirectToRoute('app_register');}$user = $userRepository->find($id);if (null === $user) {return $this->redirectToRoute('app_register');}// validate email confirmation link, sets User::isVerified=true and persiststry {$this->emailVerifier->handleEmailConfirmation($request, $user);} catch (VerifyEmailExceptionInterface $exception) {$this->addFlash('verify_email_error', $translator->trans($exception->getReason(), [], 'VerifyEmailBundle'));return $this->redirectToRoute('app_register');}// @TODO Change the redirect on success and handle or remove the flash message in your templates$this->addFlash('success', 'Your email address has been verified.');return $this->redirectToRoute('dashboard');}}