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,16 +5,41 @@ require '../app/classes/user.php';
$userObject = new User($dbWeb);
$userDetails = $userObject->getUserDetails($user);
// if a form is submitted, it's from the edit page
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$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
$updatedUser = [
'name' => $_POST['name'] ?? '',
'email' => $_POST['email'] ?? '',
// 'avatar' => ,
'bio' => $_POST['bio'] ?? '',
];
$result = $userObject->editUser($user_id, $updatedUser);
@ -29,8 +54,7 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// no form submitted, show the templates
} else {
$userDetails = $userObject->getUserDetails($user);
$avatar = !empty($userDetails['avatar']) ? 'uploads/avatars/'.$userDetails['avatar'] : $config['default_avatar'];
$avatar = !empty($userDetails[0]['avatar']) ? $config['avatars_path'] . $userDetails[0]['avatar'] : $config['default_avatar'];
switch ($action) {

View File

@ -5,19 +5,29 @@
<p class="h4 card-header">Profile of <?= $userDetails[0]['username'] ?></p>
<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="col-md-4">
<div class="border" style="width:200px; height: 200px;">
<img src="<?= $app_root . htmlspecialchars($avatar) ?>" width="200" height="200" alt="avatar" />
<div class="col-md-4 avatar-container">
<div>
<img class="avatar-img" src="<?= $app_root . htmlspecialchars($avatar) ?>" alt="avatar" />
<form method="POST" action="<?= $app_root ?>?page=profile&action=edit&item=avatar" enctype="multipart/form-data">
<label for="avatar-upload" class="avatar-btn btn btn-primary"><small>select avatar</small></label>
<input type="file" id="avatar-upload" name="avatar_file" accept="image/*" style="display:none;">
<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 class="col-md-8">
<form method="POST" action="<?= $app_root ?>?page=profile">
<!--div class="row mb-3">
<div class="col-md-4 text-end">
<label for="username" class="form-label"><small>username:</small></label>
@ -76,3 +86,13 @@
</div>
</div>
<!-- /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="col-md-4">
<div class="border" style="width:200px; height: 200px;">
<img src="<?= $app_root . htmlspecialchars($avatar) ?>" width="200" height="200" alt="avatar" />
<div class="col-md-4 avatar-container">
<div>
<img class="avatar-img" src="<?= $app_root . htmlspecialchars($avatar) ?>" alt="avatar" />
</div>
</div>

View File

@ -171,3 +171,18 @@
font-family: inherit;
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;
}