1717use App \Entity \Job ;
1818use App \Entity \Package ;
1919use App \Entity \User ;
20+ use App \Form \Model \AdminUpdateEmailRequest ;
21+ use App \Form \Type \AdminUpdateEmailType ;
2022use App \Form \Type \ProfileFormType ;
2123use App \Model \DownloadManager ;
2224use App \Model \FavoriteManager ;
2325use App \Security \UserNotifier ;
2426use Pagerfanta \Doctrine \ORM \QueryAdapter ;
2527use Pagerfanta \Pagerfanta ;
28+ use Psr \Log \LoggerInterface ;
2629use Symfony \Component \HttpFoundation \Request ;
2730use Symfony \Component \HttpFoundation \Response ;
2831use Symfony \Component \Routing \Attribute \Route ;
@@ -57,12 +60,62 @@ public function myProfile(Request $req, FavoriteManager $favMgr, DownloadManager
5760 }
5861
5962 #[Route(path: '/users/{name}/ ' , name: 'user_profile ' )]
60- public function publicProfile (Request $ req , #[VarName('name ' )] User $ user , FavoriteManager $ favMgr , DownloadManager $ dlMgr , #[CurrentUser] ?User $ loggedUser = null ): Response
63+ public function publicProfile (Request $ req , #[VarName('name ' )] User $ user , FavoriteManager $ favMgr , DownloadManager $ dlMgr , UserNotifier $ userNotifier , LoggerInterface $ logger , #[CurrentUser] ?User $ loggedUser = null ): Response
6164 {
6265 if ($ req ->attributes ->getString ('name ' ) !== $ user ->getUsername ()) {
6366 return $ this ->redirectToRoute ('user_profile ' , ['name ' => $ user ->getUsername ()]);
6467 }
6568
69+ // Admin email update form
70+ $ adminEmailForm = null ;
71+ if ($ this ->isGranted ('ROLE_ADMIN ' )) {
72+ assert ($ loggedUser !== null );
73+ $ adminUpdateEmailRequest = new AdminUpdateEmailRequest ($ user ->getEmail ());
74+ $ adminEmailForm = $ this ->createForm (AdminUpdateEmailType::class, $ adminUpdateEmailRequest );
75+ $ adminEmailForm ->handleRequest ($ req );
76+
77+ if ($ adminEmailForm ->isSubmitted () && $ adminEmailForm ->isValid ()) {
78+ $ newEmail = $ adminUpdateEmailRequest ->email ;
79+ $ oldEmail = $ user ->getEmail ();
80+
81+ if ($ newEmail === $ oldEmail ) {
82+ $ this ->addFlash ('warning ' , 'Email address unchanged. ' );
83+ } else {
84+ // Check if email is already in use
85+ $ existingUser = $ this ->getEM ()->getRepository (User::class)->findOneBy (['emailCanonical ' => strtolower ($ newEmail )]);
86+ if ($ existingUser && $ existingUser ->getId () !== $ user ->getId ()) {
87+ $ this ->addFlash ('error ' , 'Email address is already in use by another account. ' );
88+ } else {
89+ try {
90+ $ user ->setEmail ($ newEmail );
91+
92+ // Create audit record
93+ $ auditRecord = AuditRecord::emailChanged ($ user , $ loggedUser , $ oldEmail );
94+ $ this ->getEM ()->persist ($ auditRecord );
95+ $ this ->getEM ()->persist ($ user );
96+ $ this ->getEM ()->flush ();
97+
98+ // Send notifications
99+ $ reason = 'Your email has been changed by an administrator from ' . $ oldEmail . ' to ' . $ newEmail ;
100+ $ userNotifier ->notifyChange ($ oldEmail , $ reason );
101+ $ userNotifier ->notifyChange ($ newEmail , $ reason );
102+
103+ $ this ->addFlash ('success ' , 'Email address updated successfully. ' );
104+ return $ this ->redirectToRoute ('user_profile ' , ['name ' => $ user ->getUsername ()]);
105+ } catch (\Exception $ e ) {
106+ $ logger ->error ('Failed to update user email ' , [
107+ 'user_id ' => $ user ->getId (),
108+ 'old_email ' => $ oldEmail ,
109+ 'new_email ' => $ newEmail ,
110+ 'error ' => $ e ->getMessage (),
111+ ]);
112+ $ this ->addFlash ('error ' , 'Failed to update email address. Please try again. ' );
113+ }
114+ }
115+ }
116+ }
117+ }
118+
66119 $ packages = $ this ->getUserPackages ($ req , $ user );
67120
68121 $ data = [
@@ -77,6 +130,9 @@ public function publicProfile(Request $req, #[VarName('name')] User $user, Favor
77130 if (!\count ($ packages ) && ($ this ->isGranted ('ROLE_ADMIN ' ) || $ loggedUser ?->getId() === $ user ->getId ())) {
78131 $ data ['deleteForm ' ] = $ this ->createFormBuilder ([])->getForm ()->createView ();
79132 }
133+ if ($ adminEmailForm !== null ) {
134+ $ data ['adminEmailForm ' ] = $ adminEmailForm ->createView ();
135+ }
80136
81137 return $ this ->render (
82138 'user/public_profile.html.twig ' ,
0 commit comments