#!/usr/bin/perl
#------------------------------------------------------------------------------
# mwForum - Web-based discussion forum
# Copyright (c) 1999-2009 Markus Wichitill
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#------------------------------------------------------------------------------
use strict;
use warnings;
no warnings qw(uninitialized redefine);
# Imports
use MwfMain;
#------------------------------------------------------------------------------
# Init
my ($m, $cfg, $lng, $user, $userId) = MwfMain->new(@_);
# Check if access should be denied
$userId or $m->error('errNoAccess') if $cfg->{userInfoReg};
$m->checkBan($userId);
# Print header
$m->printHeader();
# Get CGI parameters
my $infUserId = $m->paramInt('uid');
# Handle special user IDs
$m->note('errUsrDel') if $infUserId == 0;
$m->note('errUsrFake') if $infUserId == -1;
# Get user
my $infUser = $m->getUser($infUserId);
$infUser or $m->error('errUsrNotFnd');
my $userTitle = $infUser->{title} ? $m->formatUserTitle($infUser->{title}) : "";
# User button links
my @userLinks = ();
push @userLinks, { url => $m->url('message_add', uid => $infUserId),
txt => 'uifMessage', ico => 'write' }
if $userId && $cfg->{messages};
push @userLinks, { url => $m->url('user_ignore', userId => $infUserId),
txt => 'uifIgnore', ico => 'ignore' }
if $userId;
push @userLinks, { url => $m->url('user_watch', userId => $infUserId),
txt => 'uifWatch', ico => 'watch' }
if $userId && $cfg->{watchUsers};
push @userLinks, { url => $m->url('forum_search', uid => $infUserId, mode => 'uid'),
txt => 'uifListPst', ico => 'search' }
if $cfg->{forumSearch};
# Admin button links
my @adminLinks = ();
if ($user->{admin}) {
push @adminLinks, { url => $m->url('user_options', uid => $infUserId, ori => 1),
txt => "Options", ico => 'option' };
push @adminLinks, { url => $m->url('user_admopt', uid => $infUserId, ori => 1),
txt => "Admin", ico => 'option' }
if $user->{admin};
push @adminLinks, { url => $m->url('user_groups', uid => $infUserId, ori => 1),
txt => "Groups", ico => 'group' };
push @adminLinks, { url => $m->url('user_ban', uid => $infUserId),
txt => "Ban", ico => 'ban' };
push @adminLinks, { url => $m->url('user_migrate', uid => $infUserId),
txt => "Migrate", ico => 'merge' };
push @adminLinks, { url => $m->url('user_notify', uid => $infUserId),
txt => "Notify", ico => 'write' };
push @adminLinks, { url => $m->url('user_wipe', uid => $infUserId),
txt => "Wipe", ico => 'wipe' };
push @adminLinks, { url => $m->url('user_confirm', uid => $infUserId, script => 'user_delete',
name => $infUser->{userName}), txt => "Delete", ico => 'delete' };
}
# Print bar
my @navLinks = ({ url => $m->url('forum_show'), txt => 'comUp', ico => 'up' });
$m->printPageBar(mainTitle => $lng->{uifTitle}, subTitle => "$infUser->{userName} $userTitle",
navLinks => \@navLinks, userLinks => \@userLinks, adminLinks => \@adminLinks);
# Notices for admins
if ($user->{admin}) {
# Print whether user is banned
my $ban = $m->fetchHash("
SELECT reason, intReason FROM userBans WHERE userId = ?", $infUserId);
print
"
\n",
"
Banned
\n",
"
\n",
$ban->{reason} ? "Reason: $ban->{reason}
\n" : "",
$ban->{intReason} ? "Internal reason: $ban->{intReason}\n" : "",
"
\n",
"
\n\n"
if $ban;
# Print admin comments
print
"\n",
"
Administrator Comments
\n",
"
\n",
$infUser->{comment}, "\n",
"
\n",
"
\n\n"
if $infUser->{comment};
}
# Print user profile
print
"\n",
"$lng->{uifProfTtl} |
\n";
# Avatar
if ($cfg->{avatars} && $infUser->{avatar}) {
my $avatarUrl = "";
if (index($infUser->{avatar}, "gravatar:") == 0) {
my $md5 = $m->md5(substr($infUser->{avatar}, 9));
$avatarUrl = "http://gravatar.com/avatar/$md5?s=$cfg->{avatarWidth}";
}
else {
$avatarUrl = "$cfg->{attachUrlPath}/avatars/$infUser->{avatar}";
}
print
"\n",
"$lng->{uifProfAvat} | | \n",
"
\n"
if $avatarUrl;
}
# Real name
print
"\n",
"$lng->{uifProfRName} | $infUser->{realName} | \n",
"
\n"
if $infUser->{realName};
# Email address
my $email;
if (!$userId || ($infUser->{hideEmail} && !$user->{admin})) {
$email = $lng->{comHidden};
}
else {
$email = $infUser->{email} ? "$infUser->{email}" : " - ";
$email .= " $lng->{comHidden}" if $infUser->{hideEmail};
}
print
"\n",
"$lng->{uifProfEml} | $email | \n",
"
\n";
# OpenID
print
"\n",
"OpenID | \n",
"",
" $infUser->{openId} | \n",
"
\n"
if $infUser->{openId};
## Homepage
##if (my $homepage = $infUser->{homepage}) {
## $homepage =~ s!(https?://[^\\\s\[\]{}<>|^)`'"]+)!$1!g;
## print
## "\n",
## "$lng->{uifProfPage} | $homepage | \n",
## "
\n";
##}
# Birthday
my $birthdate = "";
$birthdate = $infUser->{birthyear} . "-" if $infUser->{birthyear};
$birthdate .= $infUser->{birthday};
print
"\n",
"$lng->{uifProfBdate} | $birthdate | \n",
"
\n"
if $birthdate;
# Occupation
print
"\n",
"$lng->{uifProfOccup} | $infUser->{occupation} | \n",
"
\n"
if $infUser->{occupation};
# Hobbies
print
"\n",
"$lng->{uifProfHobby} | $infUser->{hobbies} | \n",
"
\n"
if $infUser->{hobbies};
# Location
print
"\n",
"$lng->{uifProfLocat} | $infUser->{location} | \n",
"
\n"
if $infUser->{location};
# GeoIP
if ($cfg->{geoIp} && (!$infUser->{privacy} || $user->{admin})) {
my $countryCode = "";
my $countryName = "";
my $geoIp = undef;
if (eval { require Geo::IP }) {
$geoIp = Geo::IP->open($cfg->{geoIp});
}
elsif (eval { require Geo::IP::PurePerl }) {
$geoIp = Geo::IP::PurePerl->open($cfg->{geoIp});
}
if ($geoIp) {
$countryCode = lc($geoIp->country_code_by_addr($infUser->{lastIp}));
$countryName = $geoIp->country_name_by_addr($infUser->{lastIp});
}
print
"\n",
"$lng->{uifProfGeoIp} | \n",
"$countryName | \n",
"
\n"
if $countryCode;
}
# Messengers
print
"\n",
"$lng->{uifProfIcq} | $infUser->{icq} | \n",
"
\n"
if $infUser->{icq};
# Custom user fields
print
"\n",
"$cfg->{extra1} | $infUser->{extra1} | \n",
"
\n"
if length($infUser->{extra1}) && $cfg->{extra1} && ($cfg->{showExtra1} || $user->{admin});
print
"\n",
"$cfg->{extra2} | $infUser->{extra2} | \n",
"
\n"
if length($infUser->{extra2}) && $cfg->{extra2} && ($cfg->{showExtra2} || $user->{admin});
print
"\n",
"$cfg->{extra3} | $infUser->{extra3} | \n",
"
\n"
if length($infUser->{extra3}) && $cfg->{extra3} && ($cfg->{showExtra3} || $user->{admin});
# Signature
if ($infUser->{signature}) {
my $fakePost = { body => $infUser->{signature} };
$m->dbToDisplay({}, $fakePost);
print
"\n",
"$lng->{uifProfSig} | $fakePost->{body} | \n",
"
\n";
}
# Former usernames
print
"\n",
"$lng->{uifProfOName} | $infUser->{oldNames} | \n",
"
\n"
if $infUser->{oldNames};
print "
\n\n";
# Print public user stats
print
"\n",
"$lng->{uifStatTtl} |
\n";
# Number of posts
print
"\n",
"$lng->{uifStatPNum} | \n",
"$infUser->{postNum} ",
@{$cfg->{userRanks}} ? $m->formatUserRank($infUser->{postNum}) : "", " | \n",
"
\n";
# Average post rating
my $rating = $infUser->{postRating} / 100;
print
"\n",
"$lng->{uifStatAvgRt} | \n",
"$rating ", $m->formatPostRating($rating), " | \n",
"
\n"
if @{$cfg->{postRatings}} && $rating > 0;
# Registration time
my $regTimeStr = $m->formatTime($infUser->{regTime}, $user->{timezone});
print
"\n",
"$lng->{uifStatRegTm} | $regTimeStr | \n",
"
\n";
# Last-on and previous-on time
if ($userId == $infUserId || $user->{admin}) {
my $lastOnTimeStr = $infUser->{lastOnTime}
? $m->formatTime($infUser->{lastOnTime}, $user->{timezone}) : " - ";
my $prevOnTimeStr = $infUser->{prevOnTime}
? $m->formatTime($infUser->{prevOnTime}, $user->{timezone}) : " - ";
print
"\n",
"$lng->{uifStatLOTm} | $lastOnTimeStr | \n",
"
\n",
"\n",
"$lng->{uifStatLRTm} | $prevOnTimeStr | \n",
"
\n";
}
# Last IP address
if ($cfg->{showUserIp} || $user->{admin}) {
my $lastIpStr = $infUser->{lastIp}
? $infUser->{lastIp} : " - ";
$lastIpStr .= " (" . $m->escHtml($infUser->{host}) . ")" if $infUser->{host};
print
"\n",
"$lng->{uifStatLIp} | $lastIpStr | \n",
"
\n";
}
# Admin-only user stats
if ($user->{admin}) {
my $ignoredNum = $m->fetchArray("
SELECT COUNT(*) FROM userIgnores WHERE ignoredId = ?", $infUserId);
my $watchedNum = $m->fetchArray("
SELECT COUNT(*) FROM watchUsers WHERE watchedId = ?", $infUserId);
my $userAgentStr = $infUser->{userAgent} ? $infUser->{userAgent} : " - ";
print
"\n",
"User Agent | $userAgentStr | \n",
"
\n",
"\n",
"Ignored By | $ignoredNum users | \n",
"
\n",
"\n",
"Watched By | $watchedNum users | \n",
"
\n",
"\n",
"Bounce Counter | $infUser->{bounceNum} | \n",
"
\n";
}
print "
\n\n";
# Print badges
if (@{$cfg->{badges}}) {
my $userBadges = $m->fetchAllArray("
SELECT badge FROM userBadges WHERE userId = ?", $infUserId);
if (@$userBadges) {
my @badges = ();
for my $line (@{$cfg->{badges}}) {
my ($id, $bigIcon, $title, $desc) =
$line =~ /(\w+)\s+\w+\s+\S+\s+(\S+)\s+"([^"]+)"\s+"([^"]+)/;
push @badges, [ $id, $title, $bigIcon, $desc ];
}
print
"\n",
"\n",
"$lng->{uifBadges} | \n",
"
\n";
for my $badge (@badges) {
for my $userBadge (@$userBadges) {
if ($userBadge->[0] eq $badge->[0]) {
my $url = "$cfg->{dataPath}/$badge->[2]";
print
"\n",
" $badge->[1] | \n",
"$badge->[3] | \n",
"
\n";
}
}
}
print "
\n\n";
}
}
# Print non-public admin and member status info
if ($userId == $infUserId || $user->{admin}) {
# Get groups
my $groups = $m->fetchAllArray("
SELECT groups.id, groups.title,
CASE WHEN groupAdmins.userId IS NOT NULL THEN '\@' ELSE '' END
FROM groups AS groups
INNER JOIN groupMembers AS groupMembers
ON groupMembers.userId = :infUserId
AND groupMembers.groupId = groups.id
LEFT JOIN groupAdmins AS groupAdmins
ON groupAdmins.userId = :infUserId
AND groupAdmins.groupId = groups.id
ORDER BY groups.title",
{ infUserId => $infUserId });
# Print groups
print
"\n",
"
$lng->{uifGrpMbrTtl}
\n",
"
\n",
"
\n\n";
# Get subscribed boards
my $boards = $m->fetchAllArray("
SELECT boards.id, boards.title
FROM boardSubscriptions AS boardSubscriptions
INNER JOIN boards AS boards
ON boards.id = boardSubscriptions.boardId
INNER JOIN categories AS categories
ON categories.id = boards.categoryId
WHERE boardSubscriptions.userId = :infUserId
ORDER BY categories.pos, boards.pos",
{ infUserId => $infUserId });
# Print subscribed boards
print
"\n",
"
$lng->{uifBrdSubTtl}
\n",
"
\n",
"
\n\n";
}
# Log action and finish
$m->logAction(3, 'user', 'info', $userId, 0, 0, 0, $infUserId);
$m->printFooter();
$m->finish();