payfrit-api/api/auth/avatar.php
John Mizerek aa986507fd Remove all Lucee references — uploads now live under /opt/payfrit-api
- Moved uploads from Lucee webroot to /opt/payfrit-api/uploads/
- Updated nginx on both dev and biz to alias /uploads/ to new path
- Replaced luceeWebroot() with uploadsRoot() helper
- Temp files now use /opt/payfrit-api/temp/
- No more /opt/lucee or /var/www/biz.payfrit.com references

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 22:26:52 -07:00

110 lines
3.4 KiB
PHP

<?php
require_once __DIR__ . '/../helpers.php';
runAuth();
/*
Avatar Upload/Get API
GET: Returns avatar URL for authenticated user
POST: Uploads new avatar image (multipart form data)
Stores images as: /uploads/users/{UserID}.jpg
*/
global $userId;
if ($userId <= 0) {
apiAbort(['OK' => false, 'ERROR' => 'not_logged_in', 'MESSAGE' => 'Authentication required']);
}
$uploadsDir = uploadsRoot() . '/users';
$avatarUrl = baseUrl() . '/uploads/users/';
// Find existing avatar (check multiple extensions)
function findAvatarFile(string $dir, int $uid): ?string {
foreach (['jpg', 'jpeg', 'png', 'gif', 'webp'] as $ext) {
$path = "$dir/$uid.$ext";
if (file_exists($path)) return $path;
}
return null;
}
$existingAvatar = findAvatarFile($uploadsDir, $userId);
// GET — return current avatar URL
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$hasAvatar = $existingAvatar !== null;
$filename = $hasAvatar ? basename($existingAvatar) : '';
jsonResponse([
'OK' => true,
'HAS_AVATAR' => $hasAvatar,
'AVATAR_URL' => $hasAvatar ? $avatarUrl . $filename . '?t=' . time() : '',
]);
}
// POST — upload new avatar
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!isset($_FILES['avatar']) || $_FILES['avatar']['error'] !== UPLOAD_ERR_OK) {
apiAbort(['OK' => false, 'ERROR' => 'missing_file', 'MESSAGE' => 'No avatar file provided']);
}
$file = $_FILES['avatar'];
$allowed = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $file['tmp_name']);
finfo_close($finfo);
if (!in_array($mime, $allowed, true)) {
apiAbort(['OK' => false, 'ERROR' => 'invalid_type', 'MESSAGE' => 'Only JPEG, PNG, GIF, or WebP images are accepted']);
}
if (!is_dir($uploadsDir)) {
mkdir($uploadsDir, 0755, true);
}
$destPath = "$uploadsDir/$userId.jpg";
// Load, resize, and save as JPEG
$img = match ($mime) {
'image/jpeg' => imagecreatefromjpeg($file['tmp_name']),
'image/png' => imagecreatefrompng($file['tmp_name']),
'image/gif' => imagecreatefromgif($file['tmp_name']),
'image/webp' => imagecreatefromwebp($file['tmp_name']),
};
if ($img) {
$w = imagesx($img);
$h = imagesy($img);
if ($w > 500 || $h > 500) {
$ratio = min(500 / $w, 500 / $h);
$newW = (int) ($w * $ratio);
$newH = (int) ($h * $ratio);
$resized = imagecreatetruecolor($newW, $newH);
imagecopyresampled($resized, $img, 0, 0, 0, 0, $newW, $newH, $w, $h);
imagedestroy($img);
$img = $resized;
}
imagejpeg($img, $destPath, 85);
imagedestroy($img);
} else {
// Fallback: just move the file
move_uploaded_file($file['tmp_name'], $destPath);
}
// Delete old avatar with different extension
if ($existingAvatar && $existingAvatar !== $destPath && file_exists($existingAvatar)) {
unlink($existingAvatar);
}
// Update DB
queryTimed("UPDATE Users SET ImageExtension = 'jpg' WHERE ID = ?", [$userId]);
jsonResponse([
'OK' => true,
'MESSAGE' => 'Avatar uploaded successfully',
'AVATAR_URL' => $avatarUrl . $userId . '.jpg?t=' . time(),
]);
}
apiAbort(['OK' => false, 'ERROR' => 'bad_method', 'MESSAGE' => 'Use GET or POST']);