togethere.cloud/public_html/account/settings/update_avatar.php

142 lines
5.0 KiB
PHP

<?php
declare(strict_types=1);
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/session_bootstrap.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/file_api_client.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/user_avatar.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/account_suspension.php';
if (empty($_SESSION['logged_in'])) {
header('Location: /login/');
exit();
}
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header('Location: /account/profile/');
exit();
}
try {
$pdo = og_session_get_pdo();
if (!$pdo instanceof PDO) {
throw new RuntimeException('Brak polaczenia z baza.');
}
} catch (Throwable $e) {
header('Location: /account/profile/?error=' . urlencode('Nie udalo sie polaczyc z baza danych.'));
exit();
}
$suspensionState = og_is_current_user_suspended($pdo);
if (!empty($suspensionState['is_suspended'])) {
header('Location: /account/profile/?error=' . urlencode('Twoje konto jest zawieszone. Zmiana zdjecia jest zablokowana.'));
exit();
}
$userId = (int)($_SESSION['user_id'] ?? 0);
if ($userId <= 0) {
header('Location: /login/');
exit();
}
if (!og_ensure_users_avatar_column($pdo)) {
header('Location: /account/profile/?error=' . urlencode('Nie udalo sie przygotowac miejsca na avatar.'));
exit();
}
$upload = $_FILES['avatar_file'] ?? null;
if (!is_array($upload) || ($upload['error'] ?? UPLOAD_ERR_NO_FILE) === UPLOAD_ERR_NO_FILE) {
header('Location: /account/profile/?error=' . urlencode('Wybierz plik ze zdjeciem.'));
exit();
}
if (($upload['error'] ?? UPLOAD_ERR_OK) !== UPLOAD_ERR_OK) {
$uploadErrorCode = (int)$upload['error'];
$errorMessage = 'Blad uploadu pliku (kod: ' . $uploadErrorCode . ').';
if ($uploadErrorCode === UPLOAD_ERR_INI_SIZE || $uploadErrorCode === UPLOAD_ERR_FORM_SIZE) {
$errorMessage = 'Plik jest za duzy dla konfiguracji serwera (PHP). Sprobuj mniejszy obraz.';
} elseif ($uploadErrorCode === UPLOAD_ERR_PARTIAL) {
$errorMessage = 'Plik zostal przeslany tylko czesciowo. Sprobuj ponownie.';
} elseif ($uploadErrorCode === UPLOAD_ERR_NO_TMP_DIR) {
$errorMessage = 'Brak katalogu tymczasowego po stronie serwera.';
} elseif ($uploadErrorCode === UPLOAD_ERR_CANT_WRITE) {
$errorMessage = 'Serwer nie moze zapisac pliku na dysku.';
} elseif ($uploadErrorCode === UPLOAD_ERR_EXTENSION) {
$errorMessage = 'Upload zostal zablokowany przez rozszerzenie PHP.';
}
header('Location: /account/profile/?error=' . urlencode($errorMessage));
exit();
}
$tmpName = (string)($upload['tmp_name'] ?? '');
if ($tmpName === '' || !is_uploaded_file($tmpName)) {
header('Location: /account/profile/?error=' . urlencode('Nieprawidlowy upload pliku.'));
exit();
}
$fileSize = isset($upload['size']) ? (int)$upload['size'] : 0;
$maxFileBytes = 3 * 1024 * 1024;
if ($fileSize <= 0 || $fileSize > $maxFileBytes) {
header('Location: /account/profile/?error=' . urlencode('Plik musi miec od 1B do 3MB.'));
exit();
}
$allowedMime = [
'image/jpeg' => true,
'image/png' => true,
'image/gif' => true,
'image/webp' => true,
];
$detectedMime = null;
if (function_exists('finfo_open')) {
$fi = finfo_open(FILEINFO_MIME_TYPE);
if ($fi) {
$detectedMime = finfo_file($fi, $tmpName) ?: null;
finfo_close($fi);
}
}
$fileMime = (string)($detectedMime ?: ($upload['type'] ?? ''));
if (!isset($allowedMime[$fileMime])) {
header('Location: /account/profile/?error=' . urlencode('Dozwolone sa tylko obrazy JPG, PNG, GIF, WEBP.'));
exit();
}
$originalName = (string)($upload['name'] ?? 'avatar');
$oldAvatarFile = og_get_user_avatar_file($pdo, $userId);
$newAvatarFile = '';
try {
$result = get_file_api_client()->upload('user_files/profile', $tmpName, $originalName, $fileMime);
$newAvatarFile = trim((string)($result['stored_name'] ?? ''));
if ($newAvatarFile === '') {
throw new RuntimeException('Serwis plikow nie zwrocil nazwy pliku.');
}
$stmt = $pdo->prepare('UPDATE users SET profile_avatar_file = ? WHERE id = ?');
$stmt->execute([$newAvatarFile, $userId]);
$_SESSION['profile_avatar_file'] = $newAvatarFile;
if (is_string($oldAvatarFile) && $oldAvatarFile !== '' && $oldAvatarFile !== $newAvatarFile) {
try {
get_file_api_client()->deleteFile('user_files/profile', $oldAvatarFile);
} catch (Throwable $ignored) {
}
}
header('Location: /account/profile/?success=avatar_updated');
exit();
} catch (Throwable $e) {
// Jeśli upload się udał, ale dalszy zapis nie, usuń nowy plik żeby nie zostawiać osieroconych avatarów.
if ($newAvatarFile !== '') {
try {
get_file_api_client()->deleteFile('user_files/profile', $newAvatarFile);
} catch (Throwable $ignored) {
}
}
header('Location: /account/profile/?error=' . urlencode('Nie udalo sie przeslac zdjecia profilowego.'));
exit();
}