getUsers(); $forum = $msz->getForum(); $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; } switch($profileMode) { default: echo render_error(404); return; case 'forum-topics': url_redirect('search-query', ['query' => sprintf('type:forum:topic author:%s', $userInfo->getName()), 'section' => 'topics']); return; case 'forum-posts': url_redirect('search-query', ['query' => sprintf('type:forum:post author:%s', $userInfo->getName()), 'section' => 'posts']); return; case '': break; } $notices = []; $userRank = $users->getUserRank($userInfo); $viewerRank = $viewingAsGuest ? 0 : $users->getUserRank($viewerInfo); $viewerPerms = $msz->getAuthInfo()->getPerms('user'); $activeBanInfo = $msz->tryGetActiveBan($userInfo); $isBanned = $activeBanInfo !== null; $profileFields = $msz->getProfileFields(); $viewingOwnProfile = (string)$viewerId === $userInfo->getId(); $canManageWarnings = $viewerPerms->check(Perm::U_WARNINGS_MANAGE); $canEdit = !$viewingAsGuest && ((!$isBanned && $viewingOwnProfile) || $viewerInfo->isSuperUser() || ( $viewerPerms->check(Perm::U_USERS_MANAGE) && ($viewingOwnProfile || $viewerRank > $userRank) )); $avatarInfo = new UserAvatarAsset($userInfo); $backgroundInfo = new UserBackgroundAsset($userInfo); if($isEditing) { if(!$canEdit) { echo render_error(403); return; } $perms = $viewerPerms->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) && 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 = $users->validateProfileAbout($aboutParse, $aboutText); if($aboutValid === '') $users->updateUser($userInfo, aboutContent: $aboutText, aboutParser: $aboutParse); else $notices[] = $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 = $users->validateForumSignature($sigParse, $sigText); if($sigValid === '') $users->updateUser($userInfo, signatureContent: $sigText, signatureParser: $sigParse); else $notices[] = $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 = $users->validateBirthdate($birthYear, $birthMonth, $birthDay); if($birthValid === '') $users->updateUser($userInfo, birthYear: $birthYear, birthMonth: $birthMonth, birthDay: $birthDay); else $notices[] = $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($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; } } // TODO: create user counters so these can be statically kept $profileStats = new stdClass; $profileStats->forum_topic_count = $forum->countTopics(userInfo: $userInfo, deleted: false); $profileStats->forum_post_count = $forum->countPosts(userInfo: $userInfo, deleted: false); $profileStats->comments_count = $msz->getComments()->countPosts(userInfo: $userInfo, deleted: false); if(!$viewingAsGuest) { Template::set('profile_warnings', $msz->getWarnings()->getWarningsWithDefaultBacklog($userInfo)); if((!$isBanned || $canEdit)) { $unranked = $cfg->getValues([ 'forum_leader.unranked.forum:a', 'forum_leader.unranked.topic:a', ]); $activeCategoryStats = $forum->getMostActiveCategoryInfo( $userInfo, $unranked['forum_leader.unranked.forum'], $unranked['forum_leader.unranked.topic'], deleted: false ); $activeCategoryInfo = $activeCategoryStats->success ? $forum->getCategory(categoryId: $activeCategoryStats->categoryId) : null; $activeTopicStats = $forum->getMostActiveTopicInfo( $userInfo, $unranked['forum_leader.unranked.forum'], $unranked['forum_leader.unranked.topic'], deleted: false ); $activeTopicInfo = $activeTopicStats->success ? $forum->getTopic(topicId: $activeTopicStats->topicId) : null; $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, ]); } } Template::render('profile.index', [ '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, ]);