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 {
|
&__title {
|
||||||
display: block;
|
display: block;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
background-color: var(--accent-colour);
|
background-image: linear-gradient(0deg, transparent, var(--accent-colour));
|
||||||
color: var(--text-colour-header);
|
color: var(--text-colour-header);
|
||||||
font-size: 1.17em;
|
font-size: 1.17em;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
|
|
@ -70,6 +70,7 @@ $settingsErrors = [];
|
||||||
$disableAccountOptions = !$app->inDebugMode() && $app->disableRegistration();
|
$disableAccountOptions = !$app->inDebugMode() && $app->disableRegistration();
|
||||||
$avatarFileName = "{$app->getUserId()}.msz";
|
$avatarFileName = "{$app->getUserId()}.msz";
|
||||||
$avatarProps = $app->getAvatarProps();
|
$avatarProps = $app->getAvatarProps();
|
||||||
|
$backgroundProps = $app->getBackgroundProps();
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
if (!tmp_csrf_verify($_POST['csrf'] ?? '')) {
|
if (!tmp_csrf_verify($_POST['csrf'] ?? '')) {
|
||||||
|
@ -131,7 +132,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
|
||||||
$setAvatar = user_avatar_set_from_path(
|
$setAvatar = user_avatar_set_from_path(
|
||||||
$app->getUserId(),
|
$app->getUserId(),
|
||||||
$_FILES['avatar']['tmp_name']['file']
|
$_FILES['avatar']['tmp_name']['file'],
|
||||||
|
$avatarProps
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($setAvatar !== MSZ_USER_AVATAR_NO_ERRORS) {
|
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'])) {
|
if (!empty($_POST['session_action'])) {
|
||||||
switch ($_POST['session_action']) {
|
switch ($_POST['session_action']) {
|
||||||
case 'kill-all':
|
case 'kill-all':
|
||||||
|
@ -305,13 +352,13 @@ switch ($settingsMode) {
|
||||||
$getMail->bindValue('user_id', $app->getUserId());
|
$getMail->bindValue('user_id', $app->getUserId());
|
||||||
$currentEmail = $getMail->execute() ? $getMail->fetchColumn() : 'Failed to fetch e-mail address.';
|
$currentEmail = $getMail->execute() ? $getMail->fetchColumn() : 'Failed to fetch e-mail address.';
|
||||||
$userHasAvatar = is_file(build_path($app->getStoragePath(), 'avatars/original', $avatarFileName));
|
$userHasAvatar = is_file(build_path($app->getStoragePath(), 'avatars/original', $avatarFileName));
|
||||||
|
$userHasBackground = is_file(build_path($app->getStoragePath(), 'backgrounds/original', $avatarFileName));
|
||||||
|
|
||||||
tpl_vars([
|
tpl_vars([
|
||||||
'avatar_user_id' => $app->getUserId(),
|
'avatar' => $avatarProps,
|
||||||
'avatar_max_width' => $avatarProps['max_width'],
|
'background' => $backgroundProps,
|
||||||
'avatar_max_height' => $avatarProps['max_height'],
|
|
||||||
'avatar_max_filesize' => $avatarProps['max_filesize'],
|
|
||||||
'user_has_avatar' => $userHasAvatar,
|
'user_has_avatar' => $userHasAvatar,
|
||||||
|
'user_has_background' => $userHasBackground,
|
||||||
'settings_profile_fields' => $profileFields,
|
'settings_profile_fields' => $profileFields,
|
||||||
'settings_profile_values' => $userFields,
|
'settings_profile_values' => $userFields,
|
||||||
'settings_disable_account_options' => $disableAccountOptions,
|
'settings_disable_account_options' => $disableAccountOptions,
|
||||||
|
|
|
@ -365,7 +365,16 @@ final class Application
|
||||||
return [
|
return [
|
||||||
'max_width' => intval($this->config['Avatar']['max_width'] ?? 4000),
|
'max_width' => intval($this->config['Avatar']['max_width'] ?? 4000),
|
||||||
'max_height' => intval($this->config['Avatar']['max_height'] ?? 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
|
function user_avatar_delete(int $userId): void
|
||||||
{
|
{
|
||||||
$app = Application::getInstance();
|
|
||||||
$avatarFileName = sprintf(MSZ_USER_AVATAR_FORMAT, $userId);
|
$avatarFileName = sprintf(MSZ_USER_AVATAR_FORMAT, $userId);
|
||||||
$storePath = $app->getStoragePath();
|
$storePath = Application::getInstance()->getStoragePath();
|
||||||
|
|
||||||
$deleteThis = [
|
$deleteThis = [
|
||||||
build_path($storePath, 'avatars/original', $avatarFileName),
|
build_path($storePath, 'avatars/original', $avatarFileName),
|
||||||
|
@ -164,3 +163,101 @@ function user_avatar_set_from_data(int $userId, string $data, array $options = [
|
||||||
|
|
||||||
return $result;
|
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' %}
|
{% 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 %}
|
{% block settings_content %}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="container__title">Account</div>
|
<div class="container__title">Account</div>
|
||||||
|
@ -125,7 +129,7 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="container__title">Avatar</div>
|
<div class="container__title">Avatar</div>
|
||||||
<form action="" method="post" class="settings__images" enctype="multipart/form-data">
|
<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() }}">
|
<input type="hidden" name="csrf" value="{{ csrf_token() }}">
|
||||||
|
|
||||||
<div class="settings__images__sections">
|
<div class="settings__images__sections">
|
||||||
|
@ -133,8 +137,8 @@
|
||||||
<ul class="settings__images__requirements__list">
|
<ul class="settings__images__requirements__list">
|
||||||
<li class="settings__images__requirement settings__images__requirement--header">Guidelines</li>
|
<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">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">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">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">Will be centre cropped to be <strong>200x200</strong>.</li>
|
||||||
<li class="settings__images__requirement">Animated gif images are allowed.</li>
|
<li class="settings__images__requirement">Animated gif images are allowed.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -146,7 +150,7 @@
|
||||||
<div
|
<div
|
||||||
class="avatar settings__avatar__preview"
|
class="avatar settings__avatar__preview"
|
||||||
id="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
|
<input
|
||||||
class="settings__avatar__input"
|
class="settings__avatar__input"
|
||||||
accept="image/png,image/jpeg,image/gif"
|
accept="image/png,image/jpeg,image/gif"
|
||||||
|
@ -179,7 +183,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function updateAvatarPreview(name, url, previewEl, nameEl) {
|
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');
|
previewEl = previewEl || document.getElementById('avatar-preview');
|
||||||
nameEl = nameEl || document.getElementById('avatar-name');
|
nameEl = nameEl || document.getElementById('avatar-name');
|
||||||
previewEl.style.backgroundImage = 'url(\'{0}\')'.replace('{0}', url);
|
previewEl.style.backgroundImage = 'url(\'{0}\')'.replace('{0}', url);
|
||||||
|
@ -196,7 +200,7 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="container__title">Background</div>
|
<div class="container__title">Background</div>
|
||||||
<form action="" method="post" class="settings__images" enctype="multipart/form-data">
|
<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() }}">
|
<input type="hidden" name="csrf" value="{{ csrf_token() }}">
|
||||||
|
|
||||||
<div class="settings__images__sections">
|
<div class="settings__images__sections">
|
||||||
|
@ -204,8 +208,8 @@
|
||||||
<ul class="settings__images__requirements__list">
|
<ul class="settings__images__requirements__list">
|
||||||
<li class="settings__images__requirement settings__images__requirement--header">Guidelines</li>
|
<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">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">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>{{ avatar_max_width }}x{{ avatar_max_height }}</strong>.</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>
|
<li class="settings__images__requirement">Animated gif images are <strong>not</strong> allowed.</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -232,8 +236,8 @@
|
||||||
Upload
|
Upload
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="settings__avatar__button settings__avatar__button--delete{{ user_has_avatar ? '' : ' settings__avatar__button--disabled' }}"
|
class="settings__avatar__button settings__avatar__button--delete{{ user_has_background ? '' : ' settings__avatar__button--disabled' }}"
|
||||||
{{ user_has_avatar ? '' : 'disabled' }}
|
{{ user_has_background ? '' : 'disabled' }}
|
||||||
name="background[mode]"
|
name="background[mode]"
|
||||||
value="delete">
|
value="delete">
|
||||||
Delete
|
Delete
|
||||||
|
@ -245,7 +249,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function updateBackgroundPreview(name, url, previewEl, nameEl) {
|
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;
|
previewEl = previewEl || document.body;
|
||||||
nameEl = nameEl || document.getElementById('background-name');
|
nameEl = nameEl || document.getElementById('background-name');
|
||||||
previewEl.style.setProperty('--site-background-image', 'url(\'{0}\')'.replace('{0}', url));
|
previewEl.style.setProperty('--site-background-image', 'url(\'{0}\')'.replace('{0}', url));
|
||||||
|
|
Loading…
Add table
Reference in a new issue