class Users { /** * Get $Classes (list of classes keyed by ID) and $ClassLevels * (list of classes keyed by level) * @return array ($Classes, $ClassLevels) */ public static function get_classes() { global $Debug; // Get permissions list($Classes, $ClassLevels) = G::$Cache->get_value('classes'); if (!$Classes || !$ClassLevels) { $QueryID = G::$DB->get_query_id(); G::$DB->query(' SELECT ID, Name, Abbreviation, Level, Secondary FROM permissions ORDER BY Level'); $Classes = G::$DB->to_array('ID'); $ClassLevels = G::$DB->to_array('Level'); G::$DB->set_query_id($QueryID); G::$Cache->cache_value('classes', array($Classes, $ClassLevels), 0); } $Debug->set_flag('Loaded permissions'); return array($Classes, $ClassLevels); } /** * Get user info, is used for the current user and usernames all over the site. * * @param $UserID int The UserID to get info for * @return array with the following keys: * int ID * string Username * int PermissionID * array Paranoia - $Paranoia array sent to paranoia.class * boolean Artist * boolean Donor * string Warned - When their warning expires in international time format * string Avatar - URL * boolean Enabled * string Title * string CatchupTime - When they last caught up on forums * boolean Visible - If false, they don't show up on peer lists * array ExtraClasses - Secondary classes. * int EffectiveClass - the highest level of their main and secondary classes */ public static function user_info($UserID) { global $Classes; $UserInfo = G::$Cache->get_value("user_info_$UserID"); // the !isset($UserInfo['Paranoia']) can be removed after a transition period if (empty($UserInfo) || empty($UserInfo['ID']) || !isset($UserInfo['Paranoia']) || empty($UserInfo['Class'])) { $OldQueryID = G::$DB->get_query_id(); G::$DB->query(" SELECT m.ID, m.Username, m.PermissionID, m.Paranoia, i.Artist, i.Donor, i.Warned, i.Avatar, m.Enabled, m.Title, i.CatchupTime, m.Visible, la.Type AS LockedAccount, GROUP_CONCAT(ul.PermissionID SEPARATOR ',') AS Levels FROM users_main AS m INNER JOIN users_info AS i ON i.UserID = m.ID LEFT JOIN locked_accounts AS la ON la.UserID = m.ID LEFT JOIN users_levels AS ul ON ul.UserID = m.ID WHERE m.ID = '$UserID' GROUP BY m.ID"); if (!G::$DB->has_results()) { // Deleted user, maybe? $UserInfo = array( 'ID' => $UserID, 'Username' => '', 'PermissionID' => 0, 'Paranoia' => array(), 'Artist' => false, 'Donor' => false, 'Warned' => '0000-00-00 00:00:00', 'Avatar' => '', 'Enabled' => 0, 'Title' => '', 'CatchupTime' => 0, 'Visible' => '1', 'Levels' => '', 'Class' => 0); } else { $UserInfo = G::$DB->next_record(MYSQLI_ASSOC, array('Paranoia', 'Title')); $UserInfo['CatchupTime'] = strtotime($UserInfo['CatchupTime']); $UserInfo['Paranoia'] = unserialize($UserInfo['Paranoia']); if ($UserInfo['Paranoia'] === false) { $UserInfo['Paranoia'] = array(); } $UserInfo['Class'] = $Classes[$UserInfo['PermissionID']]['Level']; } if (isset($UserInfo['LockedAccount']) && $UserInfo['LockedAccount'] == "") { unset($UserInfo['LockedAccount']); } if (!empty($UserInfo['Levels'])) { $UserInfo['ExtraClasses'] = array_fill_keys(explode(',', $UserInfo['Levels']), 1); } else { $UserInfo['ExtraClasses'] = array(); } unset($UserInfo['Levels']); $EffectiveClass = $UserInfo['Class']; foreach ($UserInfo['ExtraClasses'] as $Class => $Val) { $EffectiveClass = max($EffectiveClass, $Classes[$Class]['Level']); } $UserInfo['EffectiveClass'] = $EffectiveClass; G::$Cache->cache_value("user_info_$UserID", $UserInfo, 2592000); G::$DB->set_query_id($OldQueryID); } if (strtotime($UserInfo['Warned']) < time()) { $UserInfo['Warned'] = '0000-00-00 00:00:00'; G::$Cache->cache_value("user_info_$UserID", $UserInfo, 2592000); } return $UserInfo; } /** * Gets the heavy user info * Only used for current user * * @param $UserID The userid to get the information for * @return fetched heavy info. * Just read the goddamn code, I don't have time to comment this shit. */ public static function user_heavy_info($UserID) { $HeavyInfo = G::$Cache->get_value("user_info_heavy_$UserID"); if (empty($HeavyInfo)) { $QueryID = G::$DB->get_query_id(); G::$DB->query(" SELECT m.Invites, m.torrent_pass, m.IP, m.CustomPermissions, m.can_leech AS CanLeech, i.AuthKey, i.RatioWatchEnds, i.RatioWatchDownload, i.StyleID, i.StyleURL, i.DisableInvites, i.DisablePosting, i.DisableUpload, i.DisableWiki, i.DisableAvatar, i.DisablePM, i.DisableNips, i.DisableRequests, i.DisableForums, i.DisableTagging," . " i.SiteOptions, i.DownloadAlt, i.LastReadNews, i.LastReadBlog, i.RestrictedForums, i.PermittedForums, m.FLTokens, m.BonusPoints, m.HnR, m.PermissionID FROM users_main AS m INNER JOIN users_info AS i ON i.UserID = m.ID WHERE m.ID = '$UserID'"); $HeavyInfo = G::$DB->next_record(MYSQLI_ASSOC, array('CustomPermissions', 'SiteOptions')); if (!empty($HeavyInfo['CustomPermissions'])) { $HeavyInfo['CustomPermissions'] = unserialize($HeavyInfo['CustomPermissions']); } else { $HeavyInfo['CustomPermissions'] = array(); } if (!empty($HeavyInfo['RestrictedForums'])) { $RestrictedForums = array_map('trim', explode(',', $HeavyInfo['RestrictedForums'])); } else { $RestrictedForums = array(); } unset($HeavyInfo['RestrictedForums']); if (!empty($HeavyInfo['PermittedForums'])) { $PermittedForums = array_map('trim', explode(',', $HeavyInfo['PermittedForums'])); } else { $PermittedForums = array(); } unset($HeavyInfo['PermittedForums']); G::$DB->query(" SELECT PermissionID FROM users_levels WHERE UserID = $UserID"); $PermIDs = G::$DB->collect('PermissionID'); foreach ($PermIDs AS $PermID) { $Perms = Permissions::get_permissions($PermID); if (!empty($Perms['PermittedForums'])) { $PermittedForums = array_merge($PermittedForums, array_map('trim', explode(',', $Perms['PermittedForums']))); } } $Perms = Permissions::get_permissions($HeavyInfo['PermissionID']); unset($HeavyInfo['PermissionID']); if (!empty($Perms['PermittedForums'])) { $PermittedForums = array_merge($PermittedForums, array_map('trim', explode(',', $Perms['PermittedForums']))); } if (!empty($PermittedForums) || !empty($RestrictedForums)) { $HeavyInfo['CustomForums'] = array(); foreach ($RestrictedForums as $ForumID) { $HeavyInfo['CustomForums'][$ForumID] = 0; } foreach ($PermittedForums as $ForumID) { $HeavyInfo['CustomForums'][$ForumID] = 1; } } else { $HeavyInfo['CustomForums'] = null; } if (isset($HeavyInfo['CustomForums'][''])) { unset($HeavyInfo['CustomForums']['']); } $HeavyInfo['SiteOptions'] = unserialize($HeavyInfo['SiteOptions']); if (!empty($HeavyInfo['SiteOptions'])) { $HeavyInfo = array_merge($HeavyInfo, $HeavyInfo['SiteOptions']); } unset($HeavyInfo['SiteOptions']); G::$DB->set_query_id($QueryID); G::$Cache->cache_value("user_info_heavy_$UserID", $HeavyInfo, 0); } return $HeavyInfo; } /** * Updates the site options in the database * * @param int $UserID the UserID to set the options for * @param array $NewOptions the new options to set * @return false if $NewOptions is empty, true otherwise */ public static function update_site_options($UserID, $NewOptions) { if (!is_number($UserID)) { error(0); } if (empty($NewOptions)) { return false; } $QueryID = G::$DB->get_query_id(); // Get SiteOptions G::$DB->query(" SELECT SiteOptions FROM users_info WHERE UserID = $UserID"); list($SiteOptions) = G::$DB->next_record(MYSQLI_NUM, false); $SiteOptions = unserialize($SiteOptions); // Get HeavyInfo $HeavyInfo = Users::user_heavy_info($UserID); // Insert new/replace old options $SiteOptions = array_merge($SiteOptions, $NewOptions); $HeavyInfo = array_merge($HeavyInfo, $NewOptions); // Update DB G::$DB->query(" UPDATE users_info SET SiteOptions = '".db_string(serialize($SiteOptions))."' WHERE UserID = $UserID"); G::$DB->set_query_id($QueryID); // Update cache G::$Cache->cache_value("user_info_heavy_$UserID", $HeavyInfo, 0); // Update G::$LoggedUser if the options are changed for the current if (G::$LoggedUser['ID'] == $UserID) { G::$LoggedUser = array_merge(G::$LoggedUser, $NewOptions); G::$LoggedUser['ID'] = $UserID; // We don't want to allow userid switching } return true; } /** * Generates a check list of release types, ordered by the user or default * @param array $SiteOptions * @param boolean $Default Returns the default list if true */ public static function release_order(&$SiteOptions, $Default = false) { global $ReleaseTypes; $RT = $ReleaseTypes + array( 1024 => 'Guest Appearance', 1023 => 'Remixed By', 1022 => 'Composition', 1021 => 'Produced By'); if ($Default || empty($SiteOptions['SortHide'])) { $Sort =& $RT; $Defaults = !empty($SiteOptions['HideTypes']); } else { $Sort =& $SiteOptions['SortHide']; $MissingTypes = array_diff_key($RT, $Sort); if (!empty($MissingTypes)) { foreach (array_keys($MissingTypes) as $Missing) { $Sort[$Missing] = 0; } } } foreach ($Sort as $Key => $Val) { if (isset($Defaults)) { $Checked = $Defaults && isset($SiteOptions['HideTypes'][$Key]) ? ' checked="checked"' : ''; } else { if (!isset($RT[$Key])) { continue; } $Checked = $Val ? ' checked="checked"' : ''; $Val = $RT[$Key]; } $ID = $Key. '_' . (int)(!!$Checked); // The HTML is indented this far for proper indentation in the generated HTML // on user.php?action=edit ?>
' : '';
$Str .= ($IsEnabled && $UserInfo['Enabled'] == 2) ? '
' : '';
if ($Badges) {
$ClassesDisplay = array();
foreach (array_intersect_key($SecondaryClasses, $UserInfo['ExtraClasses']) as $PermID => $PermShort) {
$ClassesDisplay[] = ''.$PermShort.'';
}
if (!empty($ClassesDisplay)) {
$Str .= ' '.implode(' ', $ClassesDisplay);
}
}
if ($Class) {
foreach (array_keys($UserInfo['ExtraClasses']) as $ExtraClass) {
$Str .= ' ['.Users::make_class_abbrev_string($ExtraClass).']';
}
if ($Title) {
$Str .= ' ('.Users::make_class_string($UserInfo['PermissionID']).')';
} else {
$Str .= ' ('.Users::make_class_string($UserInfo['PermissionID']).')';
}
}
if ($Title) {
// Image proxy CTs
if (check_perms('site_proxy_images') && !empty($UserInfo['Title'])) {
$UserInfo['Title'] = preg_replace_callback('~src=("?)(http.+?)(["\s>])~',
function($Matches) {
return 'src=' . $Matches[1] . ImageTools::process($Matches[2]) . $Matches[3];
},
$UserInfo['Title']);
}
if ($UserInfo['Title']) {
$Str .= ' ('.$UserInfo['Title'].')';
}
}
return $Str;
}
/**
* Given a class ID, return its name.
*
* @param int $ClassID
* @return string name
*/
public static function make_class_string($ClassID) {
global $Classes;
return $Classes[$ClassID]['Name'];
}
public static function make_class_abbrev_string($ClassID) {
global $Classes;
return ''.$Classes[$ClassID]['Abbreviation'].'';
}
/**
* Returns an array with User Bookmark data: group IDs, collage data, torrent data
* @param string|int $UserID
* @return array Group IDs, Bookmark Data, Torrent List
*/
public static function get_bookmarks($UserID) {
$UserID = (int)$UserID;
if (($Data = G::$Cache->get_value("bookmarks_group_ids_$UserID"))) {
list($GroupIDs, $BookmarkData) = $Data;
} else {
$QueryID = G::$DB->get_query_id();
G::$DB->query("
SELECT GroupID, Sort, `Time`
FROM bookmarks_torrents
WHERE UserID = $UserID
ORDER BY Sort, `Time` ASC");
$GroupIDs = G::$DB->collect('GroupID');
$BookmarkData = G::$DB->to_array('GroupID', MYSQLI_ASSOC);
G::$DB->set_query_id($QueryID);
G::$Cache->cache_value("bookmarks_group_ids_$UserID",
array($GroupIDs, $BookmarkData), 3600);
}
$TorrentList = Torrents::get_groups($GroupIDs);
return array($GroupIDs, $BookmarkData, $TorrentList);
}
/**
* Generate HTML for a user's avatar or just return the avatar URL
* @param unknown $Avatar
* @param unknown $UserID
* @param unknown $Username
* @param unknown $Setting
* @param number $Size
* @param string $ReturnHTML
* @return string
*/
public static function show_avatar($Avatar, $UserID, $Username, $Setting, $Size = 150, $ReturnHTML = true) {
$Avatar = ImageTools::process($Avatar, false, 'avatar', $UserID);
$Style = 'style="max-height: 400px;"';
$AvatarMouseOverText = '';
$SecondAvatar = '';
$Class = 'class="double_avatar"';
$EnabledRewards = Donations::get_enabled_rewards($UserID);
if ($EnabledRewards['HasAvatarMouseOverText']) {
$Rewards = Donations::get_rewards($UserID);
$AvatarMouseOverText = $Rewards['AvatarMouseOverText'];
}
if (!empty($AvatarMouseOverText)) {
$AvatarMouseOverText = "title=\"$AvatarMouseOverText\" alt=\"$AvatarMouseOverText\"";
} else {
$AvatarMouseOverText = "alt=\"$Username's avatar\"";
}
if ($EnabledRewards['HasSecondAvatar'] && !empty($Rewards['SecondAvatar'])) {
$SecondAvatar = ' data-gazelle-second-avatar="' . ImageTools::process($Rewards['SecondAvatar'], false, 'avatar2', $UserID) . '"';
}
// case 1 is avatars disabled
switch ($Setting) {
case 0:
if (!empty($Avatar)) {
$ToReturn = ($ReturnHTML ? "