More background stuff [laptop]
This commit is contained in:
parent
be861868f2
commit
38bdef2b74
5 changed files with 179 additions and 22 deletions
|
@ -13,7 +13,7 @@
|
|||
&__title {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
background-color: var(--accent-colour);
|
||||
background-image: linear-gradient(0deg, transparent, var(--accent-colour));
|
||||
color: var(--text-colour-header);
|
||||
font-size: 1.17em;
|
||||
font-weight: 700;
|
||||
|
|
|
@ -70,6 +70,7 @@ $settingsErrors = [];
|
|||
$disableAccountOptions = !$app->inDebugMode() && $app->disableRegistration();
|
||||
$avatarFileName = "{$app->getUserId()}.msz";
|
||||
$avatarProps = $app->getAvatarProps();
|
||||
$backgroundProps = $app->getBackgroundProps();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (!tmp_csrf_verify($_POST['csrf'] ?? '')) {
|
||||
|
@ -112,8 +113,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||
|
||||
case 'upload':
|
||||
if (empty($_FILES['avatar'])
|
||||
|| !is_array($_FILES['avatar'])
|
||||
|| empty($_FILES['avatar']['name']['file'])) {
|
||||
|| !is_array($_FILES['avatar'])
|
||||
|| empty($_FILES['avatar']['name']['file'])) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -131,7 +132,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||
|
||||
$setAvatar = user_avatar_set_from_path(
|
||||
$app->getUserId(),
|
||||
$_FILES['avatar']['tmp_name']['file']
|
||||
$_FILES['avatar']['tmp_name']['file'],
|
||||
$avatarProps
|
||||
);
|
||||
|
||||
if ($setAvatar !== MSZ_USER_AVATAR_NO_ERRORS) {
|
||||
|
@ -148,6 +150,51 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||
}
|
||||
}
|
||||
|
||||
if (!empty($_POST['background']) && is_array($_POST['background'])) {
|
||||
switch ($_POST['background']['mode'] ?? '') {
|
||||
case 'delete':
|
||||
user_background_delete($app->getUserId());
|
||||
break;
|
||||
|
||||
case 'upload':
|
||||
if (empty($_FILES['background'])
|
||||
|| !is_array($_FILES['background'])
|
||||
|| empty($_FILES['background']['name']['file'])) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ($_FILES['background']['error']['file'] !== UPLOAD_ERR_OK) {
|
||||
$settingsErrors[] = sprintf(
|
||||
$avatarErrorStrings['upload'][$_FILES['background']['error']['file']]
|
||||
?? $avatarErrorStrings['upload']['default'],
|
||||
$_FILES['background']['error']['file'],
|
||||
byte_symbol($backgroundProps['max_filesize'], true),
|
||||
$backgroundProps['max_width'],
|
||||
$backgroundProps['max_height']
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
$setBackground = user_background_set_from_path(
|
||||
$app->getUserId(),
|
||||
$_FILES['background']['tmp_name']['file'],
|
||||
$backgroundProps
|
||||
);
|
||||
|
||||
if ($setBackground !== MSZ_USER_BACKGROUND_NO_ERRORS) {
|
||||
$settingsErrors[] = sprintf(
|
||||
$avatarErrorStrings['set'][$setBackground]
|
||||
?? $avatarErrorStrings['set']['default'],
|
||||
$setBackground,
|
||||
byte_symbol($backgroundProps['max_filesize'], true),
|
||||
$backgroundProps['max_width'],
|
||||
$backgroundProps['max_height']
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($_POST['session_action'])) {
|
||||
switch ($_POST['session_action']) {
|
||||
case 'kill-all':
|
||||
|
@ -305,13 +352,13 @@ switch ($settingsMode) {
|
|||
$getMail->bindValue('user_id', $app->getUserId());
|
||||
$currentEmail = $getMail->execute() ? $getMail->fetchColumn() : 'Failed to fetch e-mail address.';
|
||||
$userHasAvatar = is_file(build_path($app->getStoragePath(), 'avatars/original', $avatarFileName));
|
||||
$userHasBackground = is_file(build_path($app->getStoragePath(), 'backgrounds/original', $avatarFileName));
|
||||
|
||||
tpl_vars([
|
||||
'avatar_user_id' => $app->getUserId(),
|
||||
'avatar_max_width' => $avatarProps['max_width'],
|
||||
'avatar_max_height' => $avatarProps['max_height'],
|
||||
'avatar_max_filesize' => $avatarProps['max_filesize'],
|
||||
'avatar' => $avatarProps,
|
||||
'background' => $backgroundProps,
|
||||
'user_has_avatar' => $userHasAvatar,
|
||||
'user_has_background' => $userHasBackground,
|
||||
'settings_profile_fields' => $profileFields,
|
||||
'settings_profile_values' => $userFields,
|
||||
'settings_disable_account_options' => $disableAccountOptions,
|
||||
|
|
|
@ -365,7 +365,16 @@ final class Application
|
|||
return [
|
||||
'max_width' => intval($this->config['Avatar']['max_width'] ?? 4000),
|
||||
'max_height' => intval($this->config['Avatar']['max_height'] ?? 4000),
|
||||
'max_filesize' => intval($this->config['Avatar']['max_filesize'] ?? 1000000),
|
||||
'max_size' => intval($this->config['Avatar']['max_filesize'] ?? 1000000),
|
||||
];
|
||||
}
|
||||
|
||||
public function getBackgroundProps(): array
|
||||
{
|
||||
return [
|
||||
'max_width' => intval($this->config['Background']['max_width'] ?? 3840),
|
||||
'max_height' => intval($this->config['Background']['max_height'] ?? 2160),
|
||||
'max_size' => intval($this->config['Background']['max_filesize'] ?? 1000000),
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -60,9 +60,8 @@ define('MSZ_USER_AVATAR_FORMAT', '%d.msz');
|
|||
|
||||
function user_avatar_delete(int $userId): void
|
||||
{
|
||||
$app = Application::getInstance();
|
||||
$avatarFileName = sprintf(MSZ_USER_AVATAR_FORMAT, $userId);
|
||||
$storePath = $app->getStoragePath();
|
||||
$storePath = Application::getInstance()->getStoragePath();
|
||||
|
||||
$deleteThis = [
|
||||
build_path($storePath, 'avatars/original', $avatarFileName),
|
||||
|
@ -164,3 +163,101 @@ function user_avatar_set_from_data(int $userId, string $data, array $options = [
|
|||
|
||||
return $result;
|
||||
}
|
||||
|
||||
define('MSZ_USER_BACKGROUND_FORMAT', '%d.msz');
|
||||
|
||||
function user_background_delete(int $userId): void
|
||||
{
|
||||
$backgroundFileName = sprintf(MSZ_USER_BACKGROUND_FORMAT, $userId);
|
||||
$storePath = Application::getInstance()->getStoragePath();
|
||||
safe_delete(build_path($storePath, 'backgrounds/original', $backgroundFileName));
|
||||
}
|
||||
|
||||
define('MSZ_USER_BACKGROUND_TYPE_PNG', IMAGETYPE_PNG);
|
||||
define('MSZ_USER_BACKGROUND_TYPE_JPG', IMAGETYPE_JPEG);
|
||||
define('MSZ_USER_BACKGROUND_TYPES', [
|
||||
MSZ_USER_BACKGROUND_TYPE_PNG,
|
||||
MSZ_USER_BACKGROUND_TYPE_JPG,
|
||||
]);
|
||||
|
||||
function user_background_is_allowed_type(int $type): bool
|
||||
{
|
||||
return in_array($type, MSZ_USER_BACKGROUND_TYPES, true);
|
||||
}
|
||||
|
||||
define('MSZ_USER_BACKGROUND_OPTIONS', [
|
||||
'max_width' => 3840,
|
||||
'max_height' => 2160,
|
||||
'max_size' => 1000000,
|
||||
]);
|
||||
|
||||
define('MSZ_USER_BACKGROUND_NO_ERRORS', 0);
|
||||
define('MSZ_USER_BACKGROUND_ERROR_INVALID_IMAGE', 1);
|
||||
define('MSZ_USER_BACKGROUND_ERROR_PROHIBITED_TYPE', 2);
|
||||
define('MSZ_USER_BACKGROUND_ERROR_DIMENSIONS_TOO_LARGE', 3);
|
||||
define('MSZ_USER_BACKGROUND_ERROR_DATA_TOO_LARGE', 4);
|
||||
define('MSZ_USER_BACKGROUND_ERROR_TMP_FAILED', 5);
|
||||
define('MSZ_USER_BACKGROUND_ERROR_STORE_FAILED', 6);
|
||||
define('MSZ_USER_BACKGROUND_ERROR_FILE_NOT_FOUND', 7);
|
||||
|
||||
function user_background_set_from_path(int $userId, string $path, array $options = []): int
|
||||
{
|
||||
if (!file_exists($path)) {
|
||||
return MSZ_USER_BACKGROUND_ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
$options = array_merge(MSZ_USER_BACKGROUND_OPTIONS, $options);
|
||||
|
||||
// 0 => width, 1 => height, 2 => type
|
||||
$imageInfo = getimagesize($path);
|
||||
|
||||
if ($imageInfo === false
|
||||
|| count($imageInfo) < 3
|
||||
|| $imageInfo[0] < 1
|
||||
|| $imageInfo[1] < 1) {
|
||||
return MSZ_USER_BACKGROUND_ERROR_INVALID_IMAGE;
|
||||
}
|
||||
|
||||
if (!user_background_is_allowed_type($imageInfo[2])) {
|
||||
return MSZ_USER_BACKGROUND_ERROR_PROHIBITED_TYPE;
|
||||
}
|
||||
|
||||
if ($imageInfo[0] > $options['max_width']
|
||||
|| $imageInfo[1] > $options['max_height']) {
|
||||
return MSZ_USER_BACKGROUND_ERROR_DIMENSIONS_TOO_LARGE;
|
||||
}
|
||||
|
||||
if (filesize($path) > $options['max_size']) {
|
||||
return MSZ_USER_BACKGROUND_ERROR_DATA_TOO_LARGE;
|
||||
}
|
||||
|
||||
user_background_delete($userId);
|
||||
|
||||
$fileName = sprintf(MSZ_USER_BACKGROUND_FORMAT, $userId);
|
||||
$backgroundPath = build_path(
|
||||
create_directory(build_path(Application::getInstance()->getStoragePath(), 'backgrounds/original')),
|
||||
$fileName
|
||||
);
|
||||
|
||||
if (!copy($path, $backgroundPath)) {
|
||||
return MSZ_USER_BACKGROUND_ERROR_STORE_FAILED;
|
||||
}
|
||||
|
||||
return MSZ_USER_BACKGROUND_NO_ERRORS;
|
||||
}
|
||||
|
||||
function user_background_set_from_data(int $userId, string $data, array $options = []): int
|
||||
{
|
||||
$tmp = tempnam(sys_get_temp_dir(), 'msz');
|
||||
|
||||
if ($tmp === false || !file_exists($tmp)) {
|
||||
return MSZ_USER_BACKGROUND_ERROR_TMP_FAILED;
|
||||
}
|
||||
|
||||
chmod($tmp, 644);
|
||||
file_put_contents($tmp, $data);
|
||||
$result = user_background_set_from_path($userId, $tmp, $options);
|
||||
safe_delete($tmp);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
{% extends 'settings/master.twig' %}
|
||||
|
||||
{% if user_has_background %}
|
||||
{% set site_background_url = '/profile.php?m=background&u=' ~ current_user.user_id %}
|
||||
{% endif %}
|
||||
|
||||
{% block settings_content %}
|
||||
<div class="container">
|
||||
<div class="container__title">Account</div>
|
||||
|
@ -125,7 +129,7 @@
|
|||
<div class="container">
|
||||
<div class="container__title">Avatar</div>
|
||||
<form action="" method="post" class="settings__images" enctype="multipart/form-data">
|
||||
<input type="hidden" name="MAX_FILE_SIZE" value="{{ avatar_max_filesize }}">
|
||||
<input type="hidden" name="MAX_FILE_SIZE" value="{{ background.max_size }}">
|
||||
<input type="hidden" name="csrf" value="{{ csrf_token() }}">
|
||||
|
||||
<div class="settings__images__sections">
|
||||
|
@ -133,8 +137,8 @@
|
|||
<ul class="settings__images__requirements__list">
|
||||
<li class="settings__images__requirement settings__images__requirement--header">Guidelines</li>
|
||||
<li class="settings__images__requirement">Keep things sane and suitable for all ages.</li>
|
||||
<li class="settings__images__requirement">Image may not exceed the <strong>{{ avatar_max_filesize|byte_symbol(true) }}</strong> filesize limit.</li>
|
||||
<li class="settings__images__requirement">May not be larger than <strong>{{ avatar_max_width }}x{{ avatar_max_height }}</strong>.</li>
|
||||
<li class="settings__images__requirement">Image may not exceed the <strong>{{ avatar.max_size|byte_symbol(true) }}</strong> filesize limit.</li>
|
||||
<li class="settings__images__requirement">May not be larger than <strong>{{ avatar.max_width }}x{{ avatar.max_height }}</strong>.</li>
|
||||
<li class="settings__images__requirement">Will be centre cropped to be <strong>200x200</strong>.</li>
|
||||
<li class="settings__images__requirement">Animated gif images are allowed.</li>
|
||||
</ul>
|
||||
|
@ -146,7 +150,7 @@
|
|||
<div
|
||||
class="avatar settings__avatar__preview"
|
||||
id="avatar-preview"
|
||||
style="background-image:url('/profile.php?u={{ avatar_user_id }}&m=avatar')"></div>
|
||||
style="background-image:url('/profile.php?u={{ current_user.user_id }}&m=avatar')"></div>
|
||||
<input
|
||||
class="settings__avatar__input"
|
||||
accept="image/png,image/jpeg,image/gif"
|
||||
|
@ -179,7 +183,7 @@
|
|||
|
||||
<script>
|
||||
function updateAvatarPreview(name, url, previewEl, nameEl) {
|
||||
url = url || "/profile.php?u={{ avatar_user_id }}&m=avatar";
|
||||
url = url || "/profile.php?u={{ current_user.user_id }}&m=avatar";
|
||||
previewEl = previewEl || document.getElementById('avatar-preview');
|
||||
nameEl = nameEl || document.getElementById('avatar-name');
|
||||
previewEl.style.backgroundImage = 'url(\'{0}\')'.replace('{0}', url);
|
||||
|
@ -196,7 +200,7 @@
|
|||
<div class="container">
|
||||
<div class="container__title">Background</div>
|
||||
<form action="" method="post" class="settings__images" enctype="multipart/form-data">
|
||||
<input type="hidden" name="MAX_FILE_SIZE" value="{{ avatar_max_filesize }}">
|
||||
<input type="hidden" name="MAX_FILE_SIZE" value="{{ background.max_size }}">
|
||||
<input type="hidden" name="csrf" value="{{ csrf_token() }}">
|
||||
|
||||
<div class="settings__images__sections">
|
||||
|
@ -204,8 +208,8 @@
|
|||
<ul class="settings__images__requirements__list">
|
||||
<li class="settings__images__requirement settings__images__requirement--header">Guidelines</li>
|
||||
<li class="settings__images__requirement">Keep things sane and suitable for all ages.</li>
|
||||
<li class="settings__images__requirement">Image may not exceed the <strong>{{ avatar_max_filesize|byte_symbol(true) }}</strong> filesize limit.</li>
|
||||
<li class="settings__images__requirement">May not be larger than <strong>{{ avatar_max_width }}x{{ avatar_max_height }}</strong>.</li>
|
||||
<li class="settings__images__requirement">Image may not exceed the <strong>{{ background.max_size|byte_symbol(true) }}</strong> filesize limit.</li>
|
||||
<li class="settings__images__requirement">May not be larger than <strong>{{ background.max_width }}x{{ background.max_height }}</strong>.</li>
|
||||
<li class="settings__images__requirement">Animated gif images are <strong>not</strong> allowed.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -232,8 +236,8 @@
|
|||
Upload
|
||||
</button>
|
||||
<button
|
||||
class="settings__avatar__button settings__avatar__button--delete{{ user_has_avatar ? '' : ' settings__avatar__button--disabled' }}"
|
||||
{{ user_has_avatar ? '' : 'disabled' }}
|
||||
class="settings__avatar__button settings__avatar__button--delete{{ user_has_background ? '' : ' settings__avatar__button--disabled' }}"
|
||||
{{ user_has_background ? '' : 'disabled' }}
|
||||
name="background[mode]"
|
||||
value="delete">
|
||||
Delete
|
||||
|
@ -245,7 +249,7 @@
|
|||
|
||||
<script>
|
||||
function updateBackgroundPreview(name, url, previewEl, nameEl) {
|
||||
url = url || "/profile.php?u={{ avatar_user_id }}&m=background";
|
||||
url = url || "/profile.php?u={{ current_user.user_id }}&m=background";
|
||||
previewEl = previewEl || document.body;
|
||||
nameEl = nameEl || document.getElementById('background-name');
|
||||
previewEl.style.setProperty('--site-background-image', 'url(\'{0}\')'.replace('{0}', url));
|
||||
|
|
Loading…
Add table
Reference in a new issue