Adds user avatar management

main
Yasen Pramatarov 2024-09-09 15:20:21 +03:00
parent 84664f8b5f
commit fd949f6f4f
5 changed files with 151 additions and 20 deletions

View File

@ -85,6 +85,78 @@ class User {
} }
// remove an avatar
public function removeAvatar($user_id, $old_avatar = '') {
try {
// remove from database
$sql = 'UPDATE users_meta SET
avatar = NULL
WHERE user_id = :user_id';
$query = $this->db->prepare($sql);
$query->execute([
':user_id' => $user_id,
]);
// delete the old avatar file
if ($old_avatar && file_exists($old_avatar)) {
unlink($old_avatar);
}
return true;
} catch (Exception $e) {
return $e->getMessage();
}
}
// change an avatar
public function changeAvatar($user_id, $avatar_file, $avatars_path) {
try {
// check if the file was uploaded
if (isset($avatar_file) && $avatar_file['error'] === UPLOAD_ERR_OK) {
$fileTmpPath = $avatar_file['tmp_name'];
$fileName = $avatar_file['name'];
$fileExtension = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
// validate file extension
if (in_array($fileExtension, ['jpg', 'png', 'jpeg'])) {
$newFileName = md5(time() . $fileName) . '.' . $fileExtension;
$dest_path = $avatars_path . $newFileName;
// move the file to avatars folder
if (move_uploaded_file($fileTmpPath, $dest_path)) {
try {
// update user's avatar path in DB
$sql = 'UPDATE users_meta SET
avatar = :avatar
WHERE user_id = :user_id';
$query = $this->db->prepare($sql);
$query->execute([
':avatar' => $newFileName,
':user_id' => $user_id
]);
// all went OK
$_SESSION['notice'] = 'Avatar updated successfully!';
return true;
} catch (Exception $e) {
return $e->getMessage();
}
} else {
$_SESSION['error'] = 'Error moving the uploaded file.';
}
} else {
$_SESSION['error'] = 'Invalid avatar file type.';
}
} else {
$_SESSION['error'] = 'Error uploading the avatar file.';
}
} catch (Exception $e) {
return $e->getMessage();
}
}
} }
?> ?>

View File

@ -5,32 +5,56 @@ require '../app/classes/user.php';
$userObject = new User($dbWeb); $userObject = new User($dbWeb);
$userDetails = $userObject->getUserDetails($user);
// if a form is submitted, it's from the edit page // if a form is submitted, it's from the edit page
if ($_SERVER['REQUEST_METHOD'] == 'POST') { if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$user_id = $userObject->getUserId($user)[0]['id']; $user_id = $userObject->getUserId($user)[0]['id'];
$item = $_REQUEST['item'] ?? '';
// avatar editing
if ($item === 'avatar') {
switch ($action) {
case 'remove':
$result = $userObject->removeAvatar($user_id, $config['avatars_path'].$userDetails[0]['avatar']);
if ($result === true) {
$_SESSION['notice'] = "Avatar for user \"{$user}\" is removed.";
} else {
$_SESSION['error'] = "Removing the avatar failed. Error: $result";
}
break;
case 'edit':
$result = $userObject->changeAvatar($user_id, $_FILES['avatar_file'], $config['avatars_path']);
break;
default:
$_SESSION['error'] = "Unspecified avatar editing action.";
}
header("Location: $app_root?page=profile");
exit();
}
// update the profile // update the profile
$updatedUser = [ $updatedUser = [
'name' => $_POST['name'] ?? '', 'name' => $_POST['name'] ?? '',
'email' => $_POST['email'] ?? '', 'email' => $_POST['email'] ?? '',
// 'avatar' => ,
'bio' => $_POST['bio'] ?? '', 'bio' => $_POST['bio'] ?? '',
]; ];
$result = $userObject->editUser($user_id, $updatedUser); $result = $userObject->editUser($user_id, $updatedUser);
if ($result === true) { if ($result === true) {
$_SESSION['notice'] = "User details for \"{$updatedUser['name']}\" are edited."; $_SESSION['notice'] = "User details for \"{$updatedUser['name']}\" are edited.";
} else { } else {
$_SESSION['error'] = "Editing the user details failed. Error: $result"; $_SESSION['error'] = "Editing the user details failed. Error: $result";
} }
header("Location: $app_root?page=profile"); header("Location: $app_root?page=profile");
exit(); exit();
// no form submitted, show the templates // no form submitted, show the templates
} else { } else {
$userDetails = $userObject->getUserDetails($user); $avatar = !empty($userDetails[0]['avatar']) ? $config['avatars_path'] . $userDetails[0]['avatar'] : $config['default_avatar'];
$avatar = !empty($userDetails['avatar']) ? 'uploads/avatars/'.$userDetails['avatar'] : $config['default_avatar'];
switch ($action) { switch ($action) {

View File

@ -5,18 +5,28 @@
<p class="h4 card-header">Profile of <?= $userDetails[0]['username'] ?></p> <p class="h4 card-header">Profile of <?= $userDetails[0]['username'] ?></p>
<div class="card-body"> <div class="card-body">
<form method="POST" action="<?= $app_root ?>?page=profile"> <div class="row">
<p class="border rounded bg-light mb-4"><small>edit the profile fields</small></p>
<div class="row"> <div class="col-md-4 avatar-container">
<p class="border rounded bg-light mb-4"><small>edit the profile fields</small></p> <div>
<img class="avatar-img" src="<?= $app_root . htmlspecialchars($avatar) ?>" alt="avatar" />
<div class="col-md-4"> <form method="POST" action="<?= $app_root ?>?page=profile&action=edit&item=avatar" enctype="multipart/form-data">
<div class="border" style="width:200px; height: 200px;"> <label for="avatar-upload" class="avatar-btn btn btn-primary"><small>select avatar</small></label>
<img src="<?= $app_root . htmlspecialchars($avatar) ?>" width="200" height="200" alt="avatar" /> <input type="file" id="avatar-upload" name="avatar_file" accept="image/*" style="display:none;">
</div> <input type="submit" class="avatar-btn btn btn-success" value="upload new avatar">
</form>
<form method="POST" action="<?= $app_root ?>?page=profile&action=remove&item=avatar">
<input type="submit" id="avatar-remove" class="avatar-btn btn btn-danger" value="remove avatar" />
</form>
</div> </div>
</div>
<div class="col-md-8"> <div class="col-md-8">
<form method="POST" action="<?= $app_root ?>?page=profile">
<!--div class="row mb-3"> <!--div class="row mb-3">
<div class="col-md-4 text-end"> <div class="col-md-4 text-end">
@ -76,3 +86,13 @@
</div> </div>
</div> </div>
<!-- /user profile --> <!-- /user profile -->
<script>
document.getElementById('avatar-upload').addEventListener('change', function(event) {
const reader = new FileReader();
reader.onload = function() {
document.querySelector('.avatar-img').src = reader.result;
};
reader.readAsDataURL(event.target.files[0]);
});
</script>

View File

@ -7,9 +7,9 @@
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-4 avatar-container">
<div class="border" style="width:200px; height: 200px;"> <div>
<img src="<?= $app_root . htmlspecialchars($avatar) ?>" width="200" height="200" alt="avatar" /> <img class="avatar-img" src="<?= $app_root . htmlspecialchars($avatar) ?>" alt="avatar" />
</div> </div>
</div> </div>

View File

@ -171,3 +171,18 @@
font-family: inherit; font-family: inherit;
font-size: 14px; font-size: 14px;
} }
/* avatar */
.avatar-container {
text-align: center;
}
.avatar-img {
width: 200px;
height: 200px;
border-radius: 50%;
object-fit: cover; /* Ensures proper cropping of image */
border: 3px solid #ccc;
}
.avatar-btn {
margin-top: 10px;
}