From 9dd820d47f6063abcaba1506aa045d6c42598f39 Mon Sep 17 00:00:00 2001 From: Charles Date: Wed, 27 Aug 2025 14:52:46 +0200 Subject: [PATCH] Edit user data --- config/services.yaml | 1 + src/Controller/UserController.php | 67 ++++++++++++++++++------ src/Form/UserForm.php | 10 +++- src/Service/UserService.php | 34 +++++++++++- templates/user/edit.html.twig | 2 +- templates/user/userInformation.html.twig | 2 +- 6 files changed, 97 insertions(+), 19 deletions(-) diff --git a/config/services.yaml b/config/services.yaml index 50292e8..cb3f174 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -7,6 +7,7 @@ parameters: aws_url: '%env(AWS_ENDPOINT)%' aws_public_url: '%env(AWS_ENDPOINT)%' logos_directory: '%kernel.project_dir%/public/uploads/logos' + profile_directory: '%kernel.project_dir%/public/uploads/profile' services: # default configuration for services in *this* file diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php index 007be43..dc00825 100644 --- a/src/Controller/UserController.php +++ b/src/Controller/UserController.php @@ -14,6 +14,7 @@ use App\Service\UserService; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Asset\Packages; +use Symfony\Component\HttpFoundation\File\Exception\FileException; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; @@ -25,9 +26,9 @@ class UserController extends AbstractController private const ACCESS_DENIED = 'Access denied'; public function __construct( - private readonly EntityManagerInterface $entityManager, - private readonly UserService $userService, - private readonly ActionService $actionService, private readonly UserOrganizationAppService $userOrganizationAppService, + private readonly EntityManagerInterface $entityManager, + private readonly UserService $userService, + private readonly ActionService $actionService, private readonly UserOrganizationAppService $userOrganizationAppService, ) { } @@ -72,30 +73,29 @@ class UserController extends AbstractController { $this->denyAccessUnlessGranted('ROLE_USER'); $actingUser = $this->userService->getUserByIdentifier($this->getUser()->getUserIdentifier()); - if($this->userService->hasAccessTo($actingUser)){ + if ($this->userService->hasAccessTo($actingUser)) { $user = $this->entityManager->getRepository(User::class)->find($id); - try{ + try { $orgId = $request->query->get('organizationId'); - if($orgId){ - $orgs = $this->entityManager->getRepository(Organizations::class)->findBy(['id' =>$orgId]); + if ($orgId) { + $orgs = $this->entityManager->getRepository(Organizations::class)->findBy(['id' => $orgId]); $uo = $this->entityManager->getRepository(UsersOrganizations::class)->findBy(['users' => $user, 'organization' => $orgs, 'isActive' => true]); - if(!$uo){ + if (!$uo) { throw $this->createNotFoundException(self::NOT_FOUND); } - } - else{ - $uo = $this->entityManager->getRepository(UsersOrganizations::class)->findBy(['users'=> $user, 'isActive' => true]); - foreach ($uo as $u){ + } else { + $uo = $this->entityManager->getRepository(UsersOrganizations::class)->findBy(['users' => $user, 'isActive' => true]); + foreach ($uo as $u) { $orgs[] = $u->getOrganization(); } } - $uoa = $this->entityManager->getRepository(UserOrganizatonApp::class)->findBy(['userOrganization'=> $uo, 'isActive' => true]); + $uoa = $this->entityManager->getRepository(UserOrganizatonApp::class)->findBy(['userOrganization' => $uo, 'isActive' => true]); $uoa = $this->userOrganizationAppService->groupUserOrganizationAppsByApplication($uoa); $this->actionService->createAction("View user information", $user, null, $user->getUserIdentifier()); - }catch(\Exception $e){ + } catch (\Exception $e) { //ignore } - }else{ + } else { throw $this->createAccessDeniedException(self::ACCESS_DENIED); } @@ -105,4 +105,41 @@ class UserController extends AbstractController 'orgs' => $orgs ?? null, ]); } + + #[Route('/edit/{id}', name: 'edit', methods: ['GET', 'POST'])] + public function edit(int $id, Request $request): Response + { + $this->denyAccessUnlessGranted('ROLE_USER'); + $actingUser = $this->userService->getUserByIdentifier($this->getUser()->getUserIdentifier()); + if ($this->userService->hasAccessTo($actingUser)) { + $user = $this->entityManager->getRepository(User::class)->find($id); + if (!$user) { + throw $this->createNotFoundException(self::NOT_FOUND); + } + $form = $this->createForm(UserForm::class, $user); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + // Handle file upload + $logoFile = $form->get('pictureUrl')->getData(); + + if ($logoFile) { + $this->userService->handleProfilePicture($user, $logoFile); + + } + $user->setModifiedAt(new \DateTimeImmutable('now')); + $this->entityManager->persist($user); + $this->entityManager->flush(); + $this->actionService->createAction("Edit user information", $user, null, $user->getUserIdentifier()); + + return $this->redirectToRoute('user_show', ['id' => $user->getId()]); + } + + return $this->render('user/edit.html.twig', [ + 'user' => $user, + 'form' => $form->createView(), + ]); + } + throw $this->createAccessDeniedException(self::ACCESS_DENIED); + } } diff --git a/src/Form/UserForm.php b/src/Form/UserForm.php index 5df2589..d52d709 100644 --- a/src/Form/UserForm.php +++ b/src/Form/UserForm.php @@ -4,7 +4,9 @@ namespace App\Form; use App\Entity\User; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\DateTimeType; use Symfony\Component\Form\Extension\Core\Type\EmailType; +use Symfony\Component\Form\Extension\Core\Type\FileType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; @@ -17,7 +19,13 @@ class UserForm extends AbstractType ->add('email', EmailType::class, ['required' => true, 'label' => 'Email*']) ->add('name', TextType::class, ['required' => true, 'label' => 'Prénom*']) ->add('surname', TextType::class, ['required' => true, 'label' => 'Nom*']) - ->add('phoneNumber', TextType::class, ['required' => false, 'label' => 'Numéro de téléphone']); + ->add('phoneNumber', TextType::class, ['required' => false, 'label' => 'Numéro de téléphone']) + ->add('pictureUrl', FileType::class, [ + 'required' => false, + 'label' => 'Logo', + 'mapped' => false, // Important if the entity property is not directly mapped + 'attr' => ['accept' => 'image/*'], + ]); } public function configureOptions(OptionsResolver $resolver): void diff --git a/src/Service/UserService.php b/src/Service/UserService.php index 0cf2ef1..4e5b427 100644 --- a/src/Service/UserService.php +++ b/src/Service/UserService.php @@ -13,18 +13,22 @@ use Doctrine\ORM\EntityNotFoundException; use Exception; use League\Bundle\OAuth2ServerBundle\Model\AccessToken; use Random\RandomException; +use SebastianBergmann\CodeCoverage\Util\DirectoryCouldNotBeCreatedException; use Symfony\Bundle\SecurityBundle\Security; +use Symfony\Component\HttpFoundation\File\Exception\FileException; class UserService { public const NOT_FOUND = 'Entity not found'; + private string $profileDirectory; public function __construct(private readonly EntityManagerInterface $entityManager, private readonly Security $security, + string $profileDirectory ) { - // Constructor logic if needed + $this->profileDirectory = $profileDirectory; } /** @@ -232,4 +236,32 @@ class UserService // Use a fixed key (e.g., 0 or 'none') to avoid collisions with real org IDs return ['none' => $group]; } + + public function handleProfilePicture(User $user, $logoFile): void + { + // Get file extension + $extension = $logoFile->guessExtension(); + + // Create custom filename: userNameUserSurname_ddmmyyhhmmss + $customFilename = $user->getName() . $user->getSurname() . '_' . date('dmyHis') . '.' . $extension; + + // Define upload directory + $uploadDirectory = $this->profileDirectory; + // Create directory if it doesn't exist + if (!is_dir($uploadDirectory) && !mkdir($uploadDirectory, 0755, true) && !is_dir($uploadDirectory)) { + throw new DirectoryCouldNotBeCreatedException(sprintf('Directory "%s" was not created', $uploadDirectory)); + } + try { + + // Move the file to the upload directory + $logoFile->move($uploadDirectory, $customFilename); + + // Update user entity with the file path (relative to public directory) + $user->setPictureUrl('uploads/profile/' . $customFilename); + + } catch (FileException $e) { + // Handle upload error + throw new FileException('File upload failed: ' . $e->getMessage()); + } + } } diff --git a/templates/user/edit.html.twig b/templates/user/edit.html.twig index 58302c2..ac41d80 100644 --- a/templates/user/edit.html.twig +++ b/templates/user/edit.html.twig @@ -5,7 +5,7 @@

Modifier l'utilisateur

- Supprimer +{# Supprimer#}
diff --git a/templates/user/userInformation.html.twig b/templates/user/userInformation.html.twig index ea43471..71c4355 100644 --- a/templates/user/userInformation.html.twig +++ b/templates/user/userInformation.html.twig @@ -3,7 +3,7 @@

{{ user.surname|capitalize }} {{ user.name|capitalize }}

-{# Modifier#} + Modifier

Email: {{ user.email }}