authInfo->userInfo; $viewingAsGuest = $viewerInfo === null; $viewerId = $viewingAsGuest ? '0' : $viewerInfo->id; try { $userInfo = $msz->usersCtx->getUserInfo($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->deleted) { http_response_code(404); Template::render('profile.index', [ 'profile_is_guest' => $viewingAsGuest, 'profile_is_deleted' => true, 'profile_is_banned' => false, ]); return; } switch($profileMode) { default: Template::throwError(404); case 'forum-topics': Tools::redirect($msz->urls->format('search-query', ['query' => sprintf('type:forum:topic author:%s', $userInfo->name), 'section' => 'topics'])); return; case 'forum-posts': Tools::redirect($msz->urls->format('search-query', ['query' => sprintf('type:forum:post author:%s', $userInfo->name), 'section' => 'posts'])); return; case '': break; } $notices = []; $userRank = $msz->usersCtx->getUserRank($userInfo); $viewerRank = $msz->usersCtx->getUserRank($viewerInfo); $viewerPermsGlobal = $msz->authInfo->getPerms('global'); $viewerPermsUser = $msz->authInfo->getPerms('user'); $activeBanInfo = $msz->usersCtx->tryGetActiveBan($userInfo); $isBanned = $activeBanInfo !== null; $viewingOwnProfile = (string)$viewerId === $userInfo->id; $canManageWarnings = $viewerPermsUser->check(Perm::U_WARNINGS_MANAGE); $canEdit = !$viewingAsGuest && ((!$isBanned && $viewingOwnProfile) || $viewerInfo->super || ( $viewerPermsUser->check(Perm::U_USERS_MANAGE) && ($viewingOwnProfile || $viewerRank > $userRank) )); $avatarInfo = new UserAvatarAsset($userInfo); $backgroundInfo = new UserBackgroundAsset($userInfo); if($isEditing) { if(!$canEdit) Template::throwError(403); $perms = $viewerPermsUser->checkMany([ 'edit_profile' => Perm::U_PROFILE_EDIT, 'edit_avatar' => Perm::U_AVATAR_CHANGE, 'edit_background' => Perm::U_PROFILE_BACKGROUND_CHANGE, 'edit_about' => Perm::U_PROFILE_ABOUT_EDIT, 'edit_birthdate' => Perm::U_PROFILE_BIRTHDATE_EDIT, 'edit_signature' => Perm::U_FORUM_SIGNATURE_EDIT, ]); Template::set([ 'perms' => $perms, 'background_attachments' => UserBackgroundAsset::getAttachmentStringOptions(), ]); if(!empty($_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 = iterator_to_array($msz->profileFields->getFields()); $profileFieldsSetInfos = []; $profileFieldsSetValues = []; $profileFieldsRemove = []; foreach($profileFieldInfos as $fieldInfo) { $fieldName = $fieldInfo->name; $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->title); unset($fieldName, $fieldValue, $fieldInfo); } if(!empty($profileFieldsRemove)) $msz->profileFields->removeFieldValues($userInfo, $profileFieldsRemove); if(!empty($profileFieldsSetInfos)) $msz->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 = $msz->usersCtx->users->validateProfileAbout($aboutParse, $aboutText); if($aboutValid === '') $msz->usersCtx->users->updateUser($userInfo, aboutBody: $aboutText, aboutBodyParser: $aboutParse); else $notices[] = $msz->usersCtx->users->validateProfileAboutText($aboutValid); } } 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 = $msz->usersCtx->users->validateForumSignature($sigParse, $sigText); if($sigValid === '') $msz->usersCtx->users->updateUser($userInfo, signatureBody: $sigText, signatureBodyParser: $sigParse); else $notices[] = $msz->usersCtx->users->validateForumSignatureText($sigValid); } } 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 = $msz->usersCtx->users->validateBirthdate($birthYear, $birthMonth, $birthDay); if($birthValid === '') $msz->usersCtx->users->updateUser($userInfo, birthYear: $birthYear, birthMonth: $birthMonth, birthDay: $birthDay); else $notices[] = $msz->usersCtx->users->validateBirthdateText($birthValid); } } 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(isset($backgroundProps) && is_array($backgroundProps) ? $backgroundProps['max_size'] : 0)); 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 %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'])); } } $msz->usersCtx->users->updateUser($userInfo, backgroundSettings: $backgroundInfo->getSettings()); } } // Unset $isEditing and hope the user doesn't refresh their profile! if(empty($notices)) $isEditing = false; } } // TODO: create user counters so these can be statically kept $profileStats = new stdClass; $profileStats->forum_topic_count = $msz->forumCtx->countTotalUserTopics($userInfo); $profileStats->forum_post_count = $msz->forumCtx->countTotalUserPosts($userInfo); $profileStats->comments_count = $msz->comments->countPosts(userInfo: $userInfo, deleted: false); if(!$viewingAsGuest) { Template::set('profile_warnings', iterator_to_array($msz->usersCtx->warnings->getWarningsWithDefaultBacklog($userInfo))); if((!$isBanned || $canEdit)) { $unranked = $msz->config->getValues([ 'forum_leader.unranked.forum:a', 'forum_leader.unranked.topic:a', ]); $activeCategoryStats = $msz->forumCtx->categories->getMostActiveCategoryInfo( $userInfo, $unranked['forum_leader.unranked.forum'], $unranked['forum_leader.unranked.topic'], deleted: false ); $activeCategoryInfo = $activeCategoryStats->success ? $msz->forumCtx->categories->getCategory(categoryId: $activeCategoryStats->categoryId) : null; $activeTopicStats = $msz->forumCtx->topics->getMostActiveTopicInfo( $userInfo, $unranked['forum_leader.unranked.forum'], $unranked['forum_leader.unranked.topic'], deleted: false ); $activeTopicInfo = $activeTopicStats->success ? $msz->forumCtx->topics->getTopic(topicId: $activeTopicStats->topicId) : null; $profileFieldValues = iterator_to_array($msz->profileFields->getFieldValues($userInfo)); $profileFieldInfos = $profileFieldInfos ?? iterator_to_array($msz->profileFields->getFields(fieldValueInfos: $isEditing ? null : $profileFieldValues)); $profileFieldFormats = iterator_to_array($msz->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->fieldId === $fieldInfo->id) { $fieldValue = $fieldValueTest; break; } $fieldName = $fieldInfo->name; if(isset($fieldValue)) { foreach($profileFieldFormats as $fieldFormatTest) if($fieldFormatTest->id === $fieldValue->formatId) { $fieldFormat = $fieldFormatTest; break; } if(!isset($fieldFormat)) continue; $profileFieldRawValues[$fieldName] = $fieldValue->value; $profileFieldDisplayValues[$fieldName] = $fieldFormat->formatDisplay($fieldValue->value); if($fieldFormat->linkFormat !== null) $profileFieldLinkValues[$fieldName] = $fieldFormat->formatLink($fieldValue->value); } } 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, ]); } } Template::render('profile.index', [ 'profile_viewer' => $viewerInfo, 'profile_user' => $userInfo, 'profile_colour' => $msz->usersCtx->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, 'profile_can_send_messages' => $viewerPermsGlobal->check(Perm::G_MESSAGES_SEND), ]);