| 
									
										
										
										
											2024-08-12 11:12:24 +00:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-27 14:36:56 +00:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2024-11-29 16:07:47 +00:00
										 |  |  |  * User profile management | 
					
						
							| 
									
										
										
										
											2024-11-27 14:36:56 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This page ("profile") handles user profile actions such as updating user details, | 
					
						
							|  |  |  |  * avatar management, and assigning or removing user rights. | 
					
						
							|  |  |  |  * It supports both form submissions and displaying profile templates. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Actions handled: | 
					
						
							|  |  |  |  * - `remove`: Remove a user's avatar. | 
					
						
							|  |  |  |  * - `edit`: Edit user profile details, rights, or avatar. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-07 22:36:57 +00:00
										 |  |  | $action = $_REQUEST['action'] ?? ''; | 
					
						
							| 
									
										
										
										
											2025-04-07 12:24:53 +00:00
										 |  |  | $item = $_REQUEST['item'] ?? ''; | 
					
						
							| 
									
										
										
										
											2024-09-09 12:20:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-08 10:48:21 +00:00
										 |  |  | // if a form is submitted, it's from the edit page
 | 
					
						
							|  |  |  | if ($_SERVER['REQUEST_METHOD'] == 'POST') { | 
					
						
							| 
									
										
										
										
											2025-04-07 12:24:53 +00:00
										 |  |  |     // Validate CSRF token
 | 
					
						
							|  |  |  |     require_once '../app/helpers/security.php'; | 
					
						
							|  |  |  |     $security = SecurityHelper::getInstance(); | 
					
						
							|  |  |  |     if (!$security->verifyCsrfToken($_POST['csrf_token'] ?? '')) { | 
					
						
							|  |  |  |         Feedback::flash('ERROR', 'DEFAULT', 'Invalid security token. Please try again.'); | 
					
						
							|  |  |  |         header("Location: $app_root?page=profile"); | 
					
						
							|  |  |  |         exit(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-09-07 20:05:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-17 12:44:47 +00:00
										 |  |  |     require_once '../app/classes/validator.php'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Apply rate limiting for profile operations
 | 
					
						
							|  |  |  |     require_once '../app/includes/rate_limit_middleware.php'; | 
					
						
							| 
									
										
										
										
											2025-02-17 13:15:05 +00:00
										 |  |  |     checkRateLimit($dbWeb, 'profile', $user_id); | 
					
						
							| 
									
										
										
										
											2025-02-17 12:44:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 11:05:38 +00:00
										 |  |  |     // avatar removal
 | 
					
						
							|  |  |  |     if ($item === 'avatar' && $action === 'remove') { | 
					
						
							| 
									
										
										
										
											2025-02-17 12:44:47 +00:00
										 |  |  |         $validator = new Validator(['user_id' => $user_id]); | 
					
						
							|  |  |  |         $rules = [ | 
					
						
							|  |  |  |             'user_id' => [ | 
					
						
							|  |  |  |                 'required' => true, | 
					
						
							|  |  |  |                 'numeric' => true | 
					
						
							|  |  |  |             ] | 
					
						
							|  |  |  |         ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!$validator->validate($rules)) { | 
					
						
							|  |  |  |             Feedback::flash('ERROR', 'DEFAULT', $validator->getFirstError()); | 
					
						
							|  |  |  |             header("Location: $app_root?page=profile"); | 
					
						
							|  |  |  |             exit(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 11:05:38 +00:00
										 |  |  |         $result = $userObject->removeAvatar($user_id, $config['avatars_path'].$userDetails[0]['avatar']); | 
					
						
							|  |  |  |         if ($result === true) { | 
					
						
							| 
									
										
										
										
											2025-02-17 12:46:19 +00:00
										 |  |  |             Feedback::flash('NOTICE', 'DEFAULT', "Avatar for user \"{$userDetails[0]['username']}\" is removed."); | 
					
						
							| 
									
										
										
										
											2024-09-10 11:05:38 +00:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2025-02-17 12:46:19 +00:00
										 |  |  |             Feedback::flash('ERROR', 'DEFAULT', "Removing the avatar failed. Error: $result"); | 
					
						
							| 
									
										
										
										
											2024-09-09 12:20:21 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         header("Location: $app_root?page=profile"); | 
					
						
							|  |  |  |         exit(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-08 10:48:21 +00:00
										 |  |  |     // update the profile
 | 
					
						
							| 
									
										
										
										
											2025-02-17 12:44:47 +00:00
										 |  |  |     $validator = new Validator($_POST); | 
					
						
							|  |  |  |     $rules = [ | 
					
						
							|  |  |  |         'name' => [ | 
					
						
							|  |  |  |             'max' => 100 | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |         'email' => [ | 
					
						
							|  |  |  |             'email' => true, | 
					
						
							|  |  |  |             'max' => 100 | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |         'timezone' => [ | 
					
						
							|  |  |  |             'max' => 50 | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |         'bio' => [ | 
					
						
							|  |  |  |             'max' => 1000 | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!$validator->validate($rules)) { | 
					
						
							|  |  |  |         Feedback::flash('ERROR', 'DEFAULT', $validator->getFirstError()); | 
					
						
							|  |  |  |         header("Location: $app_root?page=profile"); | 
					
						
							|  |  |  |         exit(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-08 10:48:21 +00:00
										 |  |  |     $updatedUser = [ | 
					
						
							| 
									
										
										
										
											2025-02-17 12:44:47 +00:00
										 |  |  |         'name' => htmlspecialchars($_POST['name'] ?? ''), | 
					
						
							|  |  |  |         'email' => filter_var($_POST['email'] ?? '', FILTER_VALIDATE_EMAIL), | 
					
						
							|  |  |  |         'timezone' => htmlspecialchars($_POST['timezone'] ?? ''), | 
					
						
							|  |  |  |         'bio' => htmlspecialchars($_POST['bio'] ?? ''), | 
					
						
							|  |  |  |     ]; | 
					
						
							| 
									
										
										
										
											2024-09-09 12:20:21 +00:00
										 |  |  |     $result = $userObject->editUser($user_id, $updatedUser); | 
					
						
							|  |  |  |     if ($result === true) { | 
					
						
							| 
									
										
										
										
											2025-02-17 12:46:19 +00:00
										 |  |  |         Feedback::flash('NOTICE', 'DEFAULT', "User details for \"{$updatedUser['name']}\" are edited."); | 
					
						
							| 
									
										
										
										
											2024-09-09 12:20:21 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2025-02-17 12:46:19 +00:00
										 |  |  |         Feedback::flash('ERROR', 'DEFAULT', "Editing the user details failed. Error: $result"); | 
					
						
							| 
									
										
										
										
											2024-09-10 11:05:38 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-11 19:51:46 +00:00
										 |  |  |     // update the rights
 | 
					
						
							| 
									
										
										
										
											2025-02-17 12:44:47 +00:00
										 |  |  |     if (isset($_POST['rights'])) { | 
					
						
							|  |  |  |         $validator = new Validator(['rights' => $_POST['rights']]); | 
					
						
							|  |  |  |         $rules = [ | 
					
						
							|  |  |  |             'rights' => [ | 
					
						
							|  |  |  |                 'array' => true | 
					
						
							|  |  |  |             ] | 
					
						
							|  |  |  |         ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!$validator->validate($rules)) { | 
					
						
							|  |  |  |             Feedback::flash('ERROR', 'DEFAULT', $validator->getFirstError()); | 
					
						
							|  |  |  |             header("Location: $app_root?page=profile"); | 
					
						
							|  |  |  |             exit(); | 
					
						
							| 
									
										
										
										
											2024-09-11 19:51:46 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-02-17 12:44:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $newRights = $_POST['rights']; | 
					
						
							|  |  |  |         // extract the new right_ids
 | 
					
						
							|  |  |  |         $userRightsIds = array_column($userRights, 'right_id'); | 
					
						
							|  |  |  |         // what rights we need to add
 | 
					
						
							|  |  |  |         $rightsToAdd = array_diff($newRights, $userRightsIds); | 
					
						
							|  |  |  |         if (!empty($rightsToAdd)) { | 
					
						
							|  |  |  |             foreach ($rightsToAdd as $rightId) { | 
					
						
							|  |  |  |                 $userObject->addUserRight($user_id, $rightId); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         // what rights we need to remove
 | 
					
						
							|  |  |  |         $rightsToRemove = array_diff($userRightsIds, $newRights); | 
					
						
							|  |  |  |         if (!empty($rightsToRemove)) { | 
					
						
							|  |  |  |             foreach ($rightsToRemove as $rightId) { | 
					
						
							|  |  |  |                 $userObject->removeUserRight($user_id, $rightId); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-09-11 19:51:46 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 11:05:38 +00:00
										 |  |  |     // update the avatar
 | 
					
						
							|  |  |  |     if (!empty($_FILES['avatar_file']['tmp_name'])) { | 
					
						
							|  |  |  |         $result = $userObject->changeAvatar($user_id, $_FILES['avatar_file'], $config['avatars_path']); | 
					
						
							| 
									
										
										
										
											2024-09-09 12:20:21 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-09-07 22:36:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-08 10:48:21 +00:00
										 |  |  |     header("Location: $app_root?page=profile"); | 
					
						
							|  |  |  |     exit(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // no form submitted, show the templates
 | 
					
						
							|  |  |  | } else { | 
					
						
							| 
									
										
										
										
											2024-09-09 12:20:21 +00:00
										 |  |  |     $avatar = !empty($userDetails[0]['avatar']) ? $config['avatars_path'] . $userDetails[0]['avatar'] : $config['default_avatar']; | 
					
						
							| 
									
										
										
										
											2024-09-09 12:54:32 +00:00
										 |  |  |     $default_avatar = empty($userDetails[0]['avatar']) ? true : false; | 
					
						
							| 
									
										
										
										
											2024-09-08 10:48:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-07 12:24:53 +00:00
										 |  |  |     // Generate CSRF token if not exists
 | 
					
						
							|  |  |  |     require_once '../app/helpers/security.php'; | 
					
						
							|  |  |  |     $security = SecurityHelper::getInstance(); | 
					
						
							|  |  |  |     $security->generateCsrfToken(); | 
					
						
							| 
									
										
										
										
											2024-09-08 10:48:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-07 12:24:53 +00:00
										 |  |  |     switch ($action) { | 
					
						
							| 
									
										
										
										
											2024-09-08 10:48:21 +00:00
										 |  |  |         case 'edit': | 
					
						
							| 
									
										
										
										
											2024-09-11 19:51:46 +00:00
										 |  |  |             $allRights = $userObject->getAllRights(); | 
					
						
							| 
									
										
										
										
											2024-09-13 10:04:15 +00:00
										 |  |  |             $allTimezones = timezone_identifiers_list(); | 
					
						
							|  |  |  |             // if timezone is already set, we pass a flag for JS to not autodetect browser timezone
 | 
					
						
							|  |  |  |             $isTimezoneSet = !empty($userDetails[0]['timezone']); | 
					
						
							| 
									
										
										
										
											2025-02-17 12:44:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             // Get any new feedback messages
 | 
					
						
							| 
									
										
										
										
											2025-02-17 14:50:57 +00:00
										 |  |  |             include '../app/helpers/feedback.php'; | 
					
						
							| 
									
										
										
										
											2025-02-17 12:44:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             // Load the template
 | 
					
						
							| 
									
										
										
										
											2024-09-08 10:48:21 +00:00
										 |  |  |             include '../app/templates/profile-edit.php'; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         default: | 
					
						
							| 
									
										
										
										
											2025-02-17 12:44:47 +00:00
										 |  |  |             // Get any new feedback messages
 | 
					
						
							| 
									
										
										
										
											2025-02-17 14:50:57 +00:00
										 |  |  |             include '../app/helpers/feedback.php'; | 
					
						
							| 
									
										
										
										
											2025-02-17 12:44:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             // Load the template
 | 
					
						
							| 
									
										
										
										
											2024-09-08 10:48:21 +00:00
										 |  |  |             include '../app/templates/profile.php'; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-09-07 22:36:57 +00:00
										 |  |  | } |