Skip to content

Commit

Permalink
feat: add custom avatar functionality (#248)
Browse files Browse the repository at this point in the history
Co-authored-by: Dante Bradshaw <[email protected]>
  • Loading branch information
ellite and DanteB918 authored Mar 24, 2024
1 parent 40bcf34 commit 1dbebd3
Show file tree
Hide file tree
Showing 22 changed files with 387 additions and 41 deletions.
39 changes: 39 additions & 0 deletions endpoints/user/delete_avatar.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

require_once '../../includes/connect_endpoint.php';

session_start();

if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}

$input = json_decode(file_get_contents('php://input'), true);
if (isset($input['avatar'])) {
$avatar = "images/uploads/logos/avatars/".$input['avatar'];
$sql = "SELECT avatar FROM user";
$stmt = $db->prepare($sql);
$result = $stmt->execute();
$userAvatar = $result->fetchArray(SQLITE3_ASSOC)['avatar'];

// Check if $avatar matches the avatar in the user table
if ($avatar === $userAvatar) {
echo json_encode(array("success" => false));
} else {
// The avatars do not match
$filePath = "../../" . $avatar;
if (file_exists($filePath)) {
unlink($filePath);
echo json_encode(array("success" => true, "message" => translate("success", $i18n)));
} else {
echo json_encode(array("success" => false, "message" => translate("error", $i18n)));
}
}
} else {
echo json_encode(array("success" => false, "message" => translate("error", $i18n)));
}

?>
105 changes: 105 additions & 0 deletions endpoints/user/save_user.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,95 @@ function update_exchange_rate($db) {
$row = $result->fetchArray(SQLITE3_ASSOC);
$mainCurrencyId = $row['main_currency'];

function sanitizeFilename($filename) {
$filename = preg_replace("/[^a-zA-Z0-9\s]/", "", $filename);
$filename = str_replace(" ", "-", $filename);
$filename = str_replace(".", "", $filename);
return $filename;
}

function validateFileExtension($fileExtension) {
$allowedExtensions = ['png', 'jpg', 'jpeg', 'gif', 'jtif', 'webp'];
return in_array($fileExtension, $allowedExtensions);
}

function resizeAndUploadAvatar($uploadedFile, $uploadDir, $name) {
$targetWidth = 80;
$targetHeight = 80;

$timestamp = time();
$originalFileName = $uploadedFile['name'];
$fileExtension = strtolower(pathinfo($originalFileName, PATHINFO_EXTENSION));
$fileExtension = validateFileExtension($fileExtension) ? $fileExtension : 'png';
$fileName = $timestamp . '-avatars-' . sanitizeFilename($name) . '.' . $fileExtension;
$uploadFile = $uploadDir . $fileName;

if (move_uploaded_file($uploadedFile['tmp_name'], $uploadFile)) {
$fileInfo = getimagesize($uploadFile);

if ($fileInfo !== false) {
$width = $fileInfo[0];
$height = $fileInfo[1];

// Load the image based on its format
if ($fileExtension === 'png') {
$image = imagecreatefrompng($uploadFile);
} elseif ($fileExtension === 'jpg' || $fileExtension === 'jpeg') {
$image = imagecreatefromjpeg($uploadFile);
} elseif ($fileExtension === 'gif') {
$image = imagecreatefromgif($uploadFile);
} elseif ($fileExtension === 'webp') {
$image = imagecreatefromwebp($uploadFile);
} else {
// Handle other image formats as needed
return "";
}

// Enable alpha channel (transparency) for PNG images
if ($fileExtension === 'png') {
imagesavealpha($image, true);
}

$newWidth = $width;
$newHeight = $height;

if ($width > $targetWidth) {
$newWidth = $targetWidth;
$newHeight = ($targetWidth / $width) * $height;
}

if ($newHeight > $targetHeight) {
$newWidth = ($targetHeight / $newHeight) * $newWidth;
$newHeight = $targetHeight;
}

$resizedImage = imagecreatetruecolor($newWidth, $newHeight);
imagesavealpha($resizedImage, true);
$transparency = imagecolorallocatealpha($resizedImage, 0, 0, 0, 127);
imagefill($resizedImage, 0, 0, $transparency);
imagecopyresampled($resizedImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);

if ($fileExtension === 'png') {
imagepng($resizedImage, $uploadFile);
} elseif ($fileExtension === 'jpg' || $fileExtension === 'jpeg') {
imagejpeg($resizedImage, $uploadFile);
} elseif ($fileExtension === 'gif') {
imagegif($resizedImage, $uploadFile);
} elseif ($fileExtension === 'webp') {
imagewebp($resizedImage, $uploadFile);
} else {
return "";
}

imagedestroy($image);
imagedestroy($resizedImage);
return "images/uploads/logos/avatars/".$fileName;
}
}

return "";
}

if (isset($_SESSION['username']) && isset($_POST['username']) && isset($_POST['email']) && isset($_POST['avatar'])) {
$oldUsername = $_SESSION['username'];
$username = validate($_POST['username']);
Expand All @@ -93,6 +182,22 @@ function update_exchange_rate($db) {
$main_currency = $_POST['main_currency'];
$language = $_POST['language'];

if (! empty($_FILES['profile_pic']["name"])) {
$file = $_FILES['profile_pic'];

$fileType = mime_content_type($_FILES['profile_pic']['tmp_name']);
if (strpos($fileType, 'image') === false) {
$response = [
"success" => false,
"errorMessage" => translate('fill_all_fields', $i18n)
];
echo json_encode($response);
exit();
}
$name = $file['name'];
$avatar = resizeAndUploadAvatar($_FILES['profile_pic'], '../../images/uploads/logos/avatars/', $name);
}

if (isset($_POST['password']) && $_POST['password'] != "") {
$password = $_POST['password'];
if (isset($_POST['confirm_password'])) {
Expand Down
2 changes: 1 addition & 1 deletion includes/header.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
<nav>
<div class="dropdown">
<button class="dropbtn" onClick="toggleDropdown()">
<img src="images/avatars/<?= $userData['avatar'] ?>.svg" alt="me" id="avatar">
<img src="<?= $userData['avatar'] ?>" alt="me" id="avatar">
<span id="user"><?= $username ?></span>
</button>
<div class="dropdown-content">
Expand Down
4 changes: 3 additions & 1 deletion includes/i18n/de.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@
'icons' => "Icons",
'payment_icons' => "Zahlungsweisen Icons",
// Settings page
'upload_avatar' => "Avatar hochladen",
'file_type_error' => "Dateityp nicht unterstützt",
'user_details' => "Benutzerdetails",
"household" => "Haushalt",
"save_member" => "Mitglied speichern",
Expand Down Expand Up @@ -223,4 +225,4 @@
];


?>
?>
2 changes: 2 additions & 0 deletions includes/i18n/el.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@
'icons' => "Εικονίδια",
'payment_icons' => "Εικονίδια Payment",
// Settings page
'upload_avatar' => "μεταφόρτωση άβαταρ",
'file_type_error' => "Το αρχείο πρέπει να είναι τύπου jpg, jpeg, png, webp ή gif",
'user_details' => "Λεπτομέρειες χρήστη",
"household" => "Νοικοκυριό",
"save_member" => "Αποθήκευση μέλους",
Expand Down
2 changes: 2 additions & 0 deletions includes/i18n/en.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@
'icons' => "Icons",
'payment_icons' => "Payment Icons",
// Settings page
'upload_avatar' => "Upload Avatar",
'file_type_error' => "The file type supplied is not supported.",
'user_details' => "User Details",
"household" => "Household",
"save_member" => "Save Member",
Expand Down
4 changes: 3 additions & 1 deletion includes/i18n/es.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@
'icons' => "Iconos",
'payment_icons' => "Iconos de Pago",
// Settings page
'upload_avatar' => "Subir avatar",
'file_type_error' => "El archivo debe ser una imagen en formato PNG, JPG, WEBP o SVG",
'user_details' => "Detalles del Usuario",
"household" => "Hogar",
"save_member" => "Guardar Miembro",
Expand Down Expand Up @@ -223,4 +225,4 @@
];


?>
?>
4 changes: 3 additions & 1 deletion includes/i18n/fr.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@
'icons' => "Icônes",
'payment_icons' => "Icônes de paiement",
// Page de paramètres
'upload_avatar' => "Télécharger un Avatar",
'file_type_error' => "Le type de fichier n'est pas pris en charge",
'user_details' => "Détails de l'utilisateur",
"household" => "Ménage",
"save_member" => "Enregistrer le membre",
Expand Down Expand Up @@ -223,4 +225,4 @@
];


?>
?>
2 changes: 2 additions & 0 deletions includes/i18n/jp.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@
'icons' => "アイコン",
'payment_icons' => "支払いアイコン",
// Settings page
'upload_avatar' => "アバターをアップロードする",
'file_type_error' => "ファイルタイプが許可されていません",
'user_details' => "ユーザー詳細",
"household" => "世帯",
"save_member" => "世帯員を保存",
Expand Down
4 changes: 3 additions & 1 deletion includes/i18n/pt.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@
'icons' => "Ícones",
'payment_icons' => "Ícones de Pagamentos",
// Settings page
'upload_avatar' => "Enviar avatar",
'file_type_error' => "Tipo de ficheiro não permitido",
'user_details' => "Detalhes do utilizador",
"household" => "Agregado",
"save_member" => "Guardar Membro",
Expand Down Expand Up @@ -222,4 +224,4 @@

];

?>
?>
2 changes: 2 additions & 0 deletions includes/i18n/pt_br.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@
'icons' => "Ícones",
'payment_icons' => "Ícones de pagamento",
// Settings page
'upload_avatar' => "Carregar avatar",
'file_type_error' => "Tipo de arquivo não permitido",
'user_details' => "Informações do Usuário",
"household" => "Membros",
"save_member" => "Salvar membro",
Expand Down
2 changes: 2 additions & 0 deletions includes/i18n/tr.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@
'icons' => "İkonlar",
'payment_icons' => "Ödeme İkonları",
// Settings page
'upload_avatar' => "Avatarı yükle",
'file_type_error' => "Dosya türü izin verilmiyor",
'user_details' => "Kullanıcı Detayları",
"household" => "Hane",
"save_member" => "Üyeyi Kaydet",
Expand Down
4 changes: 3 additions & 1 deletion includes/i18n/zh_cn.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@
'payment_icons' => "支付图标",

// 设置页面
'upload_avatar' => "上传头像",
'file_type_error' => "文件类型不允许",
'user_details' => "用户详情",
"household" => "家庭",
"save_member" => "保存成员",
Expand Down Expand Up @@ -239,4 +241,4 @@

];

?>
?>
2 changes: 2 additions & 0 deletions includes/i18n/zh_tw.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@
'icons' => "圖示",
'payment_icons' => "付款圖示",
// 設定頁面
'upload_avatar' => "上传头像",
'file_type_error' => "文件类型不允许",
'user_details' => "使用者詳細資訊",
"household" => "家庭",
"save_member" => "儲存成員",
Expand Down
2 changes: 1 addition & 1 deletion includes/version.php
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<?php
$version = "v1.17.3";
$version = "v1.18.0";
?>
25 changes: 25 additions & 0 deletions migrations/000013.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

/**
* This migration script updates the avatar field of the user table to use the new avatar path.
*/

/** @noinspection PhpUndefinedVariableInspection */
$sql = "SELECT avatar FROM user";
$stmt = $db->prepare($sql);
$result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC);

if ($row) {
$avatar = $row['avatar'];

if (strlen($avatar) < 2) {
$avatarFullPath = "images/avatars/" . $avatar . ".svg";
$sql = "UPDATE user SET avatar = :avatarFullPath";
$stmt = $db->prepare($sql);
$stmt->bindValue(':avatarFullPath', $avatarFullPath, SQLITE3_TEXT);
$stmt->execute();
}
}

?>
2 changes: 1 addition & 1 deletion registration.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function validate($value) {
$confirm_password = $_POST['confirm_password'];
$main_currency = $_POST['main_currency'];
$language = $_POST['language'];
$avatar = "0";
$avatar = "images/avatars/0.svg";

if ($password != $confirm_password) {
$passwordMismatch = true;
Expand Down
Loading

0 comments on commit 1dbebd3

Please sign in to comment.