getUsers(); $viewerInfo = $msz->getActiveUser(); $viewingAsGuest = $viewerInfo === null; $viewerId = $viewingAsGuest ? '0' : $viewerInfo->getId(); try { $userInfo = $users->getUser($userId, 'profile'); } catch(RuntimeException $ex) { http_response_code(404); Template::render('profile.index', [ 'profile_is_guest' => $viewingAsGuest, 'profile_is_deleted' => true, 'profile_is_banned' => false, ]); return; } if($userInfo->isDeleted()) { http_response_code(404); Template::render('profile.index', [ 'profile_is_guest' => $viewingAsGuest, 'profile_is_deleted' => true, 'profile_is_banned' => false, ]); return; } $notices = []; $userRank = $users->getUserRank($userInfo); $viewerRank = $users->getUserRank($viewerInfo); $activeBanInfo = $msz->tryGetActiveBan($userInfo); $isBanned = $activeBanInfo !== null; $profileFields = $msz->getProfileFields(); $viewingOwnProfile = (string)$viewerId === $userInfo->getId(); $userPerms = perms_get_user($viewerId)[MSZ_PERMS_USER]; $canManageWarnings = perms_check($userPerms, MSZ_PERM_USER_MANAGE_WARNINGS); $canEdit = !$viewingAsGuest && ((!$isBanned && $viewingOwnProfile) || $viewerInfo->isSuperUser() || ( perms_check($userPerms, MSZ_PERM_USER_MANAGE_USERS) && ($viewingOwnProfile || $viewerRank > $userRank) )); $avatarInfo = new UserAvatarAsset($userInfo); $backgroundInfo = new UserBackgroundAsset($userInfo); if($isEditing) { if(!$canEdit) { echo render_error(403); return; } $perms = perms_check_bulk($userPerms, [ 'edit_profile' => MSZ_PERM_USER_EDIT_PROFILE, 'edit_avatar' => MSZ_PERM_USER_CHANGE_AVATAR, 'edit_background' => MSZ_PERM_USER_CHANGE_BACKGROUND, 'edit_about' => MSZ_PERM_USER_EDIT_ABOUT, 'edit_birthdate' => MSZ_PERM_USER_EDIT_BIRTHDATE, 'edit_signature' => MSZ_PERM_USER_EDIT_SIGNATURE, ]); Template::set([ 'perms' => $perms, 'background_attachments' => UserBackgroundAsset::getAttachmentStringOptions(), ]); if(!empty($_POST) && is_array($_POST)) { if(!CSRF::validateRequest()) { $notices[] = 'Couldn\'t verify you, please refresh the page and retry.'; } else { $profileFieldsSubmit = filter_input(INPUT_POST, 'profile', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY); if(!empty($profileFieldsSubmit)) { if(!$perms['edit_profile']) { $notices[] = 'You\'re not allowed to edit your profile'; } else { $profileFieldInfos = $profileFields->getFields(); $profileFieldsSetInfos = []; $profileFieldsSetValues = []; $profileFieldsRemove = []; foreach($profileFieldInfos as $fieldInfo) { $fieldName = $fieldInfo->getName(); $fieldValue = empty($profileFieldsSubmit[$fieldName]) ? '' : (string)filter_var($profileFieldsSubmit[$fieldName]); if(empty($profileFieldsSubmit[$fieldName])) { $profileFieldsRemove[] = $fieldInfo; continue; } if($fieldInfo->checkValue($fieldValue)) { $profileFieldsSetInfos[] = $fieldInfo; $profileFieldsSetValues[] = $fieldValue; } else $notices[] = sprintf('%s isn\'t properly formatted.', $fieldInfo->getTitle()); unset($fieldName, $fieldValue, $fieldInfo); } if(!empty($profileFieldsRemove)) $profileFields->removeFieldValues($userInfo, $profileFieldsRemove); if(!empty($profileFieldsSetInfos)) $profileFields->setFieldValues($userInfo, $profileFieldsSetInfos, $profileFieldsSetValues); } } if(!empty($_POST['about']) && is_array($_POST['about'])) { if(!$perms['edit_about']) { $notices[] = 'You\'re not allowed to edit your about page.'; } else { $aboutText = (string)($_POST['about']['text'] ?? ''); $aboutParse = (int)($_POST['about']['parser'] ?? Parser::PLAIN); $aboutValid = User::validateProfileAbout($aboutParse, $aboutText); if($aboutValid === '') $users->updateUser($userInfo, aboutContent: $aboutText, aboutParser: $aboutParse); else switch($aboutValid) { case 'parser': $notices[] = 'The selected about section parser is invalid.'; break; case 'long': $notices[] = sprintf('Please keep the length of your about section below %d characters.', User::PROFILE_ABOUT_MAX_LENGTH); break; default: $notices[] = 'Failed to update about section, contact an administator.'; break; } } } if(!empty($_POST['signature']) && is_array($_POST['signature'])) { if(!$perms['edit_signature']) { $notices[] = 'You\'re not allowed to edit your forum signature.'; } else { $sigText = (string)($_POST['signature']['text'] ?? ''); $sigParse = (int)($_POST['signature']['parser'] ?? Parser::PLAIN); $sigValid = User::validateForumSignature($sigParse, $sigText); if($sigValid === '') $users->updateUser($userInfo, signatureContent: $sigText, signatureParser: $sigParse); else switch($sigValid) { case 'parser': $notices[] = 'The selected forum signature parser is invalid.'; break; case 'long': $notices[] = sprintf('Please keep the length of your signature below %d characters.', User::FORUM_SIGNATURE_MAX_LENGTH); break; default: $notices[] = 'Failed to update signature, contact an administator.'; break; } } } if(!empty($_POST['birthdate']) && is_array($_POST['birthdate'])) { if(!$perms['edit_birthdate']) { $notices[] = "You aren't allow to change your birthdate."; } else { $birthYear = (int)($_POST['birthdate']['year'] ?? 0); $birthMonth = (int)($_POST['birthdate']['month'] ?? 0); $birthDay = (int)($_POST['birthdate']['day'] ?? 0); $birthValid = User::validateBirthdate($birthYear, $birthMonth, $birthDay); if($birthValid === '') $users->updateUser($userInfo, birthYear: $birthYear, birthMonth: $birthMonth, birthDay: $birthDay); else switch($birthValid) { case 'year': $notices[] = 'The given birth year is invalid.'; break; case 'date': $notices[] = 'The given birthdate is invalid.'; break; default: $notices[] = 'Something unexpected happened while setting your birthdate.'; break; } } } if(!empty($_FILES['avatar'])) { if(!empty($_POST['avatar']['delete'])) { $avatarInfo->delete(); } else { if(!$perms['edit_avatar']) { $notices[] = 'You aren\'t allow to change your avatar.'; } elseif(!empty($_FILES['avatar']) && is_array($_FILES['avatar']) && !empty($_FILES['avatar']['name']['file'])) { if($_FILES['avatar']['error']['file'] !== UPLOAD_ERR_OK) { switch($_FILES['avatar']['error']['file']) { case UPLOAD_ERR_NO_FILE: $notices[] = 'Select a file before hitting upload!'; break; case UPLOAD_ERR_PARTIAL: $notices[] = 'The upload was interrupted, please try again!'; break; case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_FORM_SIZE: $notices[] = sprintf('Your avatar is not allowed to be larger in file size than %s!', ByteFormat::format($avatarInfo->getMaxBytes())); break; default: $notices[] = 'Unable to save your avatar, contact an administator!'; break; } } else { try { $avatarInfo->setFromPath($_FILES['avatar']['tmp_name']['file']); } catch(InvalidArgumentException $ex) { $exMessage = $ex->getMessage(); $notices[] = match($exMessage) { '$path is not a valid image.' => 'The file you uploaded was not an image!', '$path is not an allowed image file.' => 'This type of image is not supported, keep to PNG, JPG or GIF!', 'Dimensions of $path are too large.' => sprintf('Your avatar can\'t be larger than %dx%d!', $avatarInfo->getMaxWidth(), $avatarInfo->getMaxHeight()), 'File size of $path is too large.' => sprintf('Your avatar is not allowed to be larger in file size than %s!', ByteFormat::format($avatarInfo->getMaxBytes())), default => $exMessage, }; } catch(RuntimeException $ex) { $notices[] = 'Unable to save your avatar, contact an administator!'; } } } } } if(!empty($_FILES['background'])) { if((int)($_POST['background']['attach'] ?? -1) === 0) { $backgroundInfo->delete(); } else { if(!$perms['edit_background']) { $notices[] = 'You aren\'t allow to change your background.'; } elseif(!empty($_FILES['background']) && is_array($_FILES['background'])) { if(!empty($_FILES['background']['name']['file'])) { if($_FILES['background']['error']['file'] !== UPLOAD_ERR_OK) { switch($_FILES['background']['error']['file']) { case UPLOAD_ERR_NO_FILE: $notices[] = 'Select a file before hitting upload!'; break; case UPLOAD_ERR_PARTIAL: $notices[] = 'The upload was interrupted, please try again!'; break; case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_FORM_SIZE: $notices[] = sprintf('Your background is not allowed to be larger in file size than %s!', ByteFormat::format($backgroundProps['max_size'])); break; default: $notices[] = 'Unable to save your background, contact an administator!'; break; } } else { try { $backgroundInfo->setFromPath($_FILES['background']['tmp_name']['file']); } catch(InvalidArgumentException $ex) { $exMessage = $ex->getMessage(); $notices[] = match($exMessage) { '$path is not a valid image.' => 'The file you uploaded was not an image!', '$path is not an allowed image file.' => 'This type of image is not supported, keep to PNG, JPG or GIF!', 'Dimensions of $path are too large.' => sprintf('Your background can\'t be larger than %dx%d!', $backgroundInfo->getMaxWidth(), $backgroundInfo->getMaxHeight()), 'File size of $path is too large.' => sprintf('Your background is not allowed to be larger in file size than %2$s!', ByteFormat::format($backgroundInfo->getMaxBytes())), default => $exMessage, }; } catch(RuntimeException $ex) { $notices[] = 'Unable to save your background, contact an administator!'; } } } $backgroundInfo->setAttachment((int)($_POST['background']['attach'] ?? 0)) ->setBlend(!empty($_POST['background']['attr']['blend'])) ->setSlide(!empty($_POST['background']['attr']['slide'])); } } $users->updateUser($userInfo, backgroundSettings: $backgroundInfo->getSettings()); } } // Unset $isEditing and hope the user doesn't refresh their profile! if(empty($notices)) $isEditing = false; } } $profileStats = DB::prepare(' SELECT ( SELECT COUNT(`topic_id`) FROM `msz_forum_topics` WHERE `user_id` = u.`user_id` AND `topic_deleted` IS NULL ) AS `forum_topic_count`, ( SELECT COUNT(`post_id`) FROM `msz_forum_posts` WHERE `user_id` = u.`user_id` AND `post_deleted` IS NULL ) AS `forum_post_count`, ( SELECT COUNT(`change_id`) FROM `msz_changelog_changes` WHERE `user_id` = u.`user_id` ) AS `changelog_count`, ( SELECT COUNT(`comment_id`) FROM `msz_comments_posts` WHERE `user_id` = u.`user_id` AND `comment_deleted` IS NULL ) AS `comments_count` FROM `msz_users` AS u WHERE `user_id` = :user_id ')->bind('user_id', $userInfo->getId())->fetch(); switch($profileMode) { default: echo render_error(404); return; case 'forum-topics': $template = 'profile.topics'; $topicsCount = forum_topic_count_user($userInfo->getId(), $viewerId); $topicsPagination = new Pagination($topicsCount, 20); if(!$topicsPagination->hasValidOffset()) { echo render_error(404); return; } $topics = forum_topic_listing_user( $userInfo->getId(), $viewerId, $topicsPagination->getOffset(), $topicsPagination->getRange() ); Template::set([ 'title' => $userInfo->getName() . ' / topics', 'canonical_url' => url('user-profile-forum-topics', ['user' => $userInfo->getId(), 'page' => Pagination::param()]), 'profile_topics' => $topics, 'profile_topics_pagination' => $topicsPagination, ]); break; case 'forum-posts': $template = 'profile.posts'; $postsCount = forum_post_count_user($userInfo->getId()); $postsPagination = new Pagination($postsCount, 20); if(!$postsPagination->hasValidOffset()) { echo render_error(404); return; } $posts = forum_post_listing( $userInfo->getId(), $postsPagination->getOffset(), $postsPagination->getRange(), false, true ); Template::set([ 'title' => $userInfo->getName() . ' / posts', 'canonical_url' => url('user-profile-forum-posts', ['user' => $userInfo->getId(), 'page' => Pagination::param()]), 'profile_posts' => $posts, 'profile_posts_pagination' => $postsPagination, ]); break; case '': $template = 'profile.index'; if(!$viewingAsGuest) { Template::set('profile_warnings', $msz->getWarnings()->getWarningsWithDefaultBacklog($userInfo)); if((!$isBanned || $canEdit)) { $activeCategoryStats = forum_get_user_most_active_category_info($userInfo->getId()); $activeCategoryInfo = empty($activeCategoryStats->forum_id) ? null : forum_get($activeCategoryStats->forum_id); $activeTopicStats = forum_get_user_most_active_topic_info($userInfo->getId()); $activeTopicInfo = empty($activeTopicStats->topic_id) ? null : forum_topic_get($activeTopicStats->topic_id); $profileFieldValues = $profileFields->getFieldValues($userInfo); $profileFieldInfos = $profileFieldInfos ?? $profileFields->getFields(fieldValueInfos: $isEditing ? null : $profileFieldValues); $profileFieldFormats = $profileFields->getFieldFormats(fieldValueInfos: $profileFieldValues); $profileFieldRawValues = []; $profileFieldLinkValues = []; $profileFieldDisplayValues = []; // using field infos as the basis for now, uses the correct ordering foreach($profileFieldInfos as $fieldInfo) { unset($fieldValue); foreach($profileFieldValues as $fieldValueTest) if($fieldValueTest->getFieldId() === $fieldInfo->getId()) { $fieldValue = $fieldValueTest; break; } $fieldName = $fieldInfo->getName(); if(isset($fieldValue)) { foreach($profileFieldFormats as $fieldFormatTest) if($fieldFormatTest->getId() === $fieldValue->getFormatId()) { $fieldFormat = $fieldFormatTest; break; } $profileFieldRawValues[$fieldName] = $fieldValue->getValue(); $profileFieldDisplayValues[$fieldName] = $fieldFormat->formatDisplay($fieldValue->getValue()); if($fieldFormat->hasLinkFormat()) $profileFieldLinkValues[$fieldName] = $fieldFormat->formatLink($fieldValue->getValue()); } } Template::set([ 'profile_active_category_stats' => $activeCategoryStats, 'profile_active_category_info' => $activeCategoryInfo, 'profile_active_topic_stats' => $activeTopicStats, 'profile_active_topic_info' => $activeTopicInfo, 'profile_fields_infos' => $profileFieldInfos, 'profile_fields_raw_values' => $profileFieldRawValues, 'profile_fields_display_values' => $profileFieldDisplayValues, 'profile_fields_link_values' => $profileFieldLinkValues, ]); } } break; } if(!empty($template)) { Template::render($template, [ 'profile_viewer' => $viewerInfo, 'profile_user' => $userInfo, 'profile_colour' => $users->getUserColour($userInfo), 'profile_stats' => $profileStats, 'profile_mode' => $profileMode, 'profile_notices' => $notices, 'profile_can_edit' => $canEdit, 'profile_is_editing' => $isEditing, 'profile_is_banned' => $isBanned, 'profile_is_guest' => $viewingAsGuest, 'profile_is_deleted' => false, 'profile_ban_info' => $activeBanInfo, 'profile_avatar_info' => $avatarInfo, 'profile_background_info' => $backgroundInfo, ]); }