###############################################################################
# ViewMembers.pm #
# $Date: 01 Sep 2026 $ #
###############################################################################
# YaBBForum: Yet another Bulletin Board #
# Open-Source Community Software for Webmasters #
# Version: YaBBForum 3.2 #
# Packaged: 01 Sep 2026 #
# Distributed by: https://yabbforum.nz #
# =========================================================================== #
# Copyright (c) 2000-2026 YaBBForum (yabbforum.nz) - All Rights Reserved. #
# Software by: The YaBBForum Development Team #
# with assistance from the YaBBForum community. #
###############################################################################
# use strict;
our $VERSION = '3.2';
$viewmemberspmver = 'YaBBForum 3.2';
if ( $action eq 'detailedversion' ) { return 1; }
LoadLanguage('MemberList');
is_admin_or_gmod();
my ( $sortmode, $sortorder, $spages );
$MembersPerPage = $TopAmmount;
$maxbar = 100;
sub Ml {
# Decides how to sort memberlist, and gives default sort order
if ( !$barmaxnumb ) { $barmaxnumb = 500; }
if ( $barmaxdepend == 1 ) {
$barmax = 1;
ManageMemberinfo('load');
while ( ( $key, $value ) = each %memberinf ) {
( undef, undef, undef, $memposts ) = split /\|/xsm, $value;
if ( $memposts > $barmax ) { $barmax = $memposts; }
}
undef %memberinf;
}
else {
$barmax = $barmaxnumb;
}
$FORM{'sortform'} ||= $INFO{'sortform'};
if ( !$INFO{'sort'} && !$FORM{'sortform'} ) {
$INFO{'sort'} = $defaultml;
$FORM{'sortform'} = $defaultml;
}
if ( $FORM{'sortform'} eq 'username'
|| $INFO{'sort'} eq 'mlletter'
|| $INFO{'sort'} eq 'username' )
{
$page = 'a';
$showpage = 'A';
while ( $page ne 'z' ) {
$LetterLinks .=
qq($showpage );
$page++;
$showpage++;
}
$LetterLinks .=
qq(Z $ml_txt{'800'} );
}
if ( $INFO{'start'} eq q{} ) { $start = 0; }
else { $start = $INFO{'start'}; $spages = ";start=$start"; }
if ( $INFO{'sort'} ne q{} ) { $sortmode = ';sort=' . $INFO{'sort'}; }
elsif ( $FORM{'sortform'} ne q{} ) {
$sortmode = ';sort=' . $FORM{'sortform'};
}
if ( $INFO{'reversed'} || $FORM{'reversed'} ) {
$selReversed = q~ checked="checked"~;
$sortorder = ';reversed=1';
}
$actualnum = 0;
$numshown = 0;
$selPost_a = q~windowbg2~;
$selReg_a = q~windowbg2~;
$selPos_a = q~windowbg2~;
$selLastOn_a = q~windowbg2~;
$selLastPost_a = q~windowbg2~;
$selLastIM_a = q~windowbg2~;
$selUser_a = q~windowbg2~;
if ( $FORM{'sortform'} eq 'posts' || $INFO{'sort'} eq 'posts' ) {
$selPost_a = q~windowbg~;
$selPost .= q~ selected="selected"~;
MLTop();
}
if ( $FORM{'sortform'} eq 'regdate' || $INFO{'sort'} eq 'regdate' ) {
$selReg .= q~ selected="selected"~;
$selReg_a = q~windowbg~;
MLDate();
}
if ( $FORM{'sortform'} eq 'position' || $INFO{'sort'} eq 'position' ) {
$selPos .= q~ selected="selected"~;
$selPos_a = q~windowbg~;
MLPosition();
}
if ( $FORM{'sortform'} eq 'lastonline' || $INFO{'sort'} eq 'lastonline' ) {
$selLastOn .= q~ selected="selected"~;
$selLastOn_a = q~windowbg~;
MLLastOnline();
}
if ( $FORM{'sortform'} eq 'lastpost' || $INFO{'sort'} eq 'lastpost' ) {
$selLastPost .= q~ selected="selected"~;
$selLastPost_a = q~windowbg~;
MLLastPost();
}
if ( $FORM{'sortform'} eq 'lastim' || $INFO{'sort'} eq 'lastim' ) {
$selLastIm .= q~ selected="selected"~;
$selLastIM_a = q~windowbg~;
MLLastIm();
}
if ( $FORM{'sortform'} eq 'memsearch' || $INFO{'sort'} eq 'memsearch' ) {
FindMembers();
}
if ( $INFO{'sort'} eq q{}
|| $INFO{'sort'} eq 'mlletter'
|| $INFO{'sort'} eq 'username' )
{
$selUser .= q~ selected="selected"~;
$selUser_a = q~windowbg~;
MLByLetter();
}
return;
}
sub MLByLetter {
$letter = lc $INFO{'letter'};
$i = 0;
ManageMemberinfo('load');
foreach my $membername (
sort { lc $memberinf{$a} cmp lc $memberinf{$b} }
keys %memberinf
)
{
( $memrealname, $mememail, undef, undef ) =
split /\|/xsm, $memberinf{$membername};
if ($letter) {
$SearchName = lc( substr $memrealname, 0, 1 );
if ( $SearchName eq $letter ) { $ToShow[$i] = $membername; $i++; }
elsif ( $letter eq 'other'
&& ( ( $SearchName lt 'a' ) || ( $SearchName gt 'z' ) ) )
{
$ToShow[$i] = $membername;
$i++;
}
}
else {
$ToShow[$i] = $membername;
$i++;
}
}
undef %memberinf;
$memcount = @ToShow;
if ( !$memcount && $letter ) {
$pageindex1 =
qq~$admin_img{'index_togl'}~;
$pageindex2 =
qq~$admin_img{'index_togl'}~;
}
else {
buildIndex();
}
buildPages(1);
$bb = $start;
if ($memcount) {
while ( $numshown < $MembersPerPage ) {
showRows( $ToShow[$bb] );
$numshown++;
$bb++;
}
}
else {
if ($letter) {
$yymain .= qq~
|
$ml_txt{'760'}
|
~;
}
}
undef @ToShow;
buildPages(0);
$yytitle = "$ml_txt{'312'} $numshow";
$action_area = 'viewmembers';
AdminTemplate();
return;
}
sub MLTop {
%top_list = ();
ManageMemberinfo('load');
while ( ( $membername, $value ) = each %memberinf ) {
( $memrealname, undef, undef, $memposts ) = split /\|/xsm, $value;
$memposts = sprintf '%06d', ( 999_999 - $memposts );
$top_list{$membername} = qq~$memposts|$memrealname~;
}
undef %memberinf;
my @toplist = sort { lc $top_list{$a} cmp lc $top_list{$b} } keys %top_list;
if ( $FORM{'reversed'} || $INFO{'reversed'} ) {
@toplist = reverse @toplist;
}
$memcount = @toplist;
buildIndex();
buildPages(1);
$bb = $start;
while ( $numshown < $MembersPerPage ) {
showRows( $toplist[$bb] );
$numshown++;
$bb++;
}
undef @toplist;
buildPages(0);
$yytitle = "$ml_txt{'313'} $ml_txt{'314'} $numshow";
$action_area = 'viewmembers';
AdminTemplate();
return;
}
sub MLPosition {
%TopMembers = ();
ManageMemberinfo('load');
while ( ( $membername, $value ) = each %memberinf ) {
( $memberrealname, undef, $memposition, $memposts ) =
split /\|/xsm, $value;
$pstsort = 99_999_999 - $memposts;
$sortgroups = q{};
foreach my $key ( keys %Group ) {
if ( $memposition eq $key ) {
if ( $key eq 'Administrator' ) {
$sortgroups = "aaa.$pstsort.$memberrealname";
}
elsif ( $key eq 'Global Moderator' ) {
$sortgroups = "bbb.$pstsort.$memberrealname";
}
elsif ( $key eq 'Mid Moderator' ) {
$sortgroups = "bcc.$pstsort.$memberrealname";
}
}
}
if ( !$sortgroups ) {
foreach ( sort { $a <=> $b } keys %NoPost ) {
if ( $memposition eq $_ ) {
$sortgroups = "ddd.$memposition.$pstsort.$memberrealname";
}
}
}
if ( !$sortgroups ) {
$sortgroups = "eee.$pstsort.$memposition.$memberrealname";
}
$TopMembers{$membername} = $sortgroups;
}
my @toplist =
sort { lc $TopMembers{$a} cmp lc $TopMembers{$b} } keys %TopMembers;
if ( $FORM{'reversed'} || $INFO{'reversed'} ) {
@toplist = reverse @toplist;
}
$memcount = @toplist;
buildIndex();
buildPages(1);
$bb = $start;
while ( $numshown < $MembersPerPage ) {
showRows( $toplist[$bb] );
$numshown++;
$bb++;
}
undef @toplist;
undef %memberinf;
buildPages(0);
$yytitle = "$ml_txt{'313'} $ml_txt{'4'} $ml_txt{'87'} $numshow";
$action_area = 'viewmembers';
AdminTemplate();
return;
}
sub MLDate {
fopen( MEMBERLISTREAD, "$memberdir/memberlist.txt" );
@tempmemlist = ;
fclose(MEMBERLISTREAD);
if ( $FORM{'reversed'} || $INFO{'reversed'} ) {
@tempmemlist = reverse @tempmemlist;
}
$memcount = @tempmemlist;
buildIndex();
buildPages(1);
$bb = $start;
while ( $numshown < $MembersPerPage ) {
( $membername, undef ) = split /\t/xsm, $tempmemlist[$bb], 2;
showRows($membername);
$numshown++;
$bb++;
}
$yymain .= $TableFooter;
buildPages(0);
$yytitle = "$ml_txt{'313'} $ml_txt{'4'} $ml_txt{'233'}";
$action_area = 'viewmembers';
AdminTemplate();
return;
}
sub showRows {
my ($user) = @_;
if ( $user ne q{} ) {
LoadUser($user);
$date2 = $date;
my $userlastonline = ${ $uid . $user }{'lastonline'};
my $userlastpost = ${ $uid . $user }{'lastpost'};
my $userlastim = ${ $uid . $user }{'lastim'};
$date1 = stringtotime( ${ $uid . $user }{'regdate'} );
calcdifference();
$days_reg = $result;
my ( $tmpa, $tmpb, $tmpc );
if ( $userlastonline eq q{} ) { $userlastonline = q{-};
$date1 = stringtotime( ${ $uid . $user }{'regdate'} );
calcdifference();
$tmpa = $result;
}
else {
$date1 = $userlastonline;
calcdifference();
$userlastonline = $result;
$tmpa = $userlastonline;
}
if ( $userlastpost eq q{} ) { $userlastpost = q{-};
$date1 = stringtotime( ${ $uid . $user }{'regdate'} );
calcdifference();
$tmpb = $result;
}
else {
$date1 = $userlastpost;
calcdifference();
$userlastpost = $result;
$tmpb = $userlastpost;
}
if ( $userlastim eq q{} ) { $userlastim = q{-};
$date1 = stringtotime( ${ $uid . $user }{'regdate'} );
calcdifference();
$tmpc = $result;
}
else {
$date1 = $userlastim;
calcdifference();
$userlastim = $result;
$tmpc = $userlastim;
}
$userlastonline = NumberFormat($userlastonline);
$userlastpost = NumberFormat($userlastpost);
$userlastim = NumberFormat($userlastim);
$userpostcount = NumberFormat( ${ $uid . $user }{'postcount'} );
if ( $user ne 'admin' ) {
$CheckingAll .=
qq~"$days_reg|${$uid.$user}{'postcount'}|$tmpa|$tmpb|$tmpc|$user", ~;
}
$barchart = ${ $uid . $user }{'postcount'};
$bartemp = ( ${ $uid . $user }{'postcount'} * $maxbar );
$barwidth = ( $bartemp / $barmax );
$barwidth = ( $barwidth + 0.5 );
$barwidth = int $barwidth;
if ( $barwidth > $maxbar ) { $barwidth = $maxbar }
if ( $barchart < 1 ) { $Bar = ' '; }
else {
$Bar =
qq~
~;
}
$dr_regdate = timeformat( ${ $uid . $user }{'regtime'} );
$dr_regdate =~ s/(.*)(, 1?[0-9]):[0-9][0-9].*/$1/sm;
my $memberinfo = ' ';
if ( ${ $uid . $user }{'realname'} eq q{} ) {
${ $uid . $user }{'realname'} = $user;
}
if ( ${ $uid . $user }{'position'} eq q{} && $showallgroups ) {
foreach my $postamount ( reverse sort { $a <=> $b } keys %Post ) {
if ( ${ $uid . $user }{'postcount'} > $postamount ) {
(
$memberinfo, $stars, $starpic, $color,
$noshow, $viewperms, $topicperms, $replyperms,
$pollperms, $attachperms
) = split /\|/xsm, $Post{$postamount};
last;
}
}
}
elsif ( ${ $uid . $user }{'position'} ne q{} ) {
$tempgroups = 0;
foreach ( keys %Group ) {
if ( ${ $uid . $user }{'position'} eq $_ ) {
(
$memberinfo, $stars, $starpic, $color,
$noshow, $viewperms, $topicperms, $replyperms,
$pollperms, $attachperms
) = split /\|/xsm, $Group{$_};
$tempgroups = 1;
last;
}
}
if ( !$tempgroups ) {
foreach ( sort { $a <=> $b } keys %NoPost ) {
if ( ${ $uid . $user }{'position'} eq $_ ) {
(
$memberinfo, $stars, $starpic,
$color, $noshow, $viewperms,
$topicperms, $replyperms, $pollperms,
$attachperms
) = split /\|/xsm, $NoPost{$_};
$tempgroups = 1;
last;
}
}
}
if ( !$tempgroups ) {
$memberinfo = ${ $uid . $user }{'position'};
}
}
$yymain .= qq~
| $link{$user} | ~;
if ( $user eq 'admin' || ( $iamgmod && ( ${ $uid . $user }{'position'} eq 'Administrator' || $gmod_access{'deletemultimembers'} ne 'on') ) ) {
$addel = q~ ~;
}
else {
$addel =
qq~~;
$actualnum++;
}
$yymain .= qq~
$memberinfo |
$userpostcount |
$Bar |
$dr_regdate |
$userlastonline |
$userlastpost |
$userlastim |
$addel |
~;
}
return;
}
sub buildIndex {
if ( $memcount != 0 ) {
( undef, undef, $usermemberpage ) =
split /\|/xsm, ${ $uid . $username }{'pageindex'};
# Build the page links list.
my ( $pagetxtindex, $pagedropindex1, $pagedropindex2, $all,
$allselected );
$indexdisplaynum = 3;
$dropdisplaynum = 10;
if ( $FORM{'sortform'} eq q{} ) { $FORM{'sortform'} = $INFO{'sort'}; }
$postdisplaynum = 3;
$startpage = 0;
$max = $memcount;
if ( $INFO{'start'} eq 'all' ) {
$MembersPerPage = $max;
$all = 1;
$allselected = q~ selected="selected"~;
$start = 0;
}
else { $start = $INFO{'start'} || 0; }
$start = $start > $memcount - 1 ? $memcount - 1 : $start;
$start = ( int( $start / $MembersPerPage ) ) * $MembersPerPage;
$tmpa = 1;
$pagenumb = int( ( $memcount - 1 ) / $MembersPerPage ) + 1;
if ( $start >= ( ( $postdisplaynum - 1 ) * $MembersPerPage ) ) {
$startpage = $start - ( ( $postdisplaynum - 1 ) * $MembersPerPage );
$tmpa = int( $startpage / $MembersPerPage ) + 1;
}
if ( $memcount >= $start + ( $postdisplaynum * $MembersPerPage ) ) {
$endpage = $start + ( $postdisplaynum * $MembersPerPage );
}
else { $endpage = $memcount }
$lastpn = int( ( $memcount - 1 ) / $MembersPerPage ) + 1;
$lastptn = ( $lastpn - 1 ) * $MembersPerPage;
$pageindex1 =
qq~$admin_img{'index_togl'} $ml_txt{'139'}: $pagenumb~;
$pageindex2 =
qq~$admin_img{'index_togl'} $ml_txt{'139'}: $pagenumb~;
if ( $pagenumb > 1 || $all ) {
if ( $usermemberpage == 1 ) {
$pagetxtindexst =
qq~
$ml_txt{'139'}: ~;
if ( $startpage > 0 ) {
$pagetxtindex =
qq~1 ... ~;
}
if ( $startpage == $MembersPerPage ) {
$pagetxtindex =
qq~1 ~;
}
foreach my $counter ( $startpage .. ( $endpage - 1 ) ) {
if ( $counter % $MembersPerPage == 0 ) {
$pagetxtindex .=
$start == $counter
? qq~[$tmpa] ~
: qq~$tmpa ~;
$tmpa++;
}
}
if ( $endpage < $memcount - $MembersPerPage ) {
$pageindexadd = q~... ~;
}
if ( $endpage != $memcount ) {
$pageindexadd .=
qq~$lastpn~;
}
$pagetxtindex .= qq~$pageindexadd~;
$pageindex1 = qq~$pagetxtindexst$pagetxtindex~;
$pageindex2 = qq~$pagetxtindexst$pagetxtindex~;
}
else {
$pagedropindex1 =
q~~;
$pagedropindex1 .=
qq~
~;
$pagedropindex2 = $pagedropindex1;
$tstart = $start;
if ( substr( $INFO{'start'}, 0, 3 ) eq 'all' ) {
( $tstart, $start ) = split /\-/xsm, $INFO{'start'};
}
$d_indexpages = $pagenumb / $dropdisplaynum;
$i_indexpages = int( $pagenumb / $dropdisplaynum );
if ( $d_indexpages > $i_indexpages ) {
$indexpages = int( $pagenumb / $dropdisplaynum ) + 1;
}
else { $indexpages = int( $pagenumb / $dropdisplaynum ) }
$selectedindex =
int( ( $start / $MembersPerPage ) / $dropdisplaynum );
if ( $pagenumb > $dropdisplaynum ) {
$pagedropindex1 .=
qq~\n~;
}
$pagedropindex1 .=
q~ ~;
$pagedropindex2 .=
q~ ~;
$tmpMembersPerPage = $MembersPerPage;
if ( substr( $INFO{'start'}, 0, 3 ) eq 'all' ) {
$MembersPerPage = $MembersPerPage * $dropdisplaynum;
}
$prevpage = $start - $tmpMembersPerPage;
$nextpage = $start + $MembersPerPage;
$pagedropindexpvbl =
qq~
~;
$pagedropindexnxbl =
qq~
~;
if ( $start < $MembersPerPage ) {
$pagedropindexpv .=
qq~
~;
}
else {
$pagedropindexpv .=
qq~
~;
}
if ( $nextpage > $lastptn ) {
$pagedropindexnx .=
qq~
~;
}
else {
$pagedropindexnx .=
qq~
~;
}
$pageindex1 = qq~$pagedropindex1~;
$pageindex2 = qq~$pagedropindex2~;
$pageindexjs = qq~
~;
}
}
}
return;
}
sub buildPages {
my ($inp) = @_;
$FindForm .= qq~
~;
$TableHeader .= qq~
~;
}
return;
}
sub MLLastPost {
%TopMembers = ();
ManageMemberinfo('load');
while ( ( $membername, $value ) = each %memberinf ) {
LoadUser($membername);
$TopMembers{$membername} = ${ $uid . $membername }{'lastpost'};
undef %{ $uid . $membername };
}
undef %memberinf;
my @toplist =
reverse sort { $TopMembers{$a} <=> $TopMembers{$b} } keys %TopMembers;
undef %TopMembers;
if ( $FORM{'reversed'} || $INFO{'reversed'} ) {
@toplist = reverse @toplist;
}
$memcount = @toplist;
buildIndex();
buildPages(1);
$bb = $start;
while ( ( $numshown < $MembersPerPage ) ) {
showRows( $toplist[$bb] );
$numshown++;
$bb++;
}
undef @toplist;
buildPages(0);
$yymain .= $TableFooter;
$yytitle = "$ml_txt{'313'} $TopAmmount $ml_txt{'314'}";
$action_area = 'viewmembers';
AdminTemplate();
return;
}
sub MLLastIm {
%TopMembers = ();
ManageMemberinfo('load');
while ( ( $membername, $value ) = each %memberinf ) {
LoadUser($membername);
$TopMembers{$membername} = ${ $uid . $membername }{'lastim'};
undef %{ $uid . $membername };
}
undef %memberinf;
my @toplist =
reverse sort { $TopMembers{$a} <=> $TopMembers{$b} } keys %TopMembers;
undef %TopMembers;
if ( $FORM{'reversed'} || $INFO{'reversed'} ) {
@toplist = reverse @toplist;
}
$memcount = @toplist;
buildIndex();
buildPages(1);
$bb = $start;
while ( ( $numshown < $MembersPerPage ) ) {
showRows( $toplist[$bb] );
$numshown++;
$bb++;
}
undef @toplist;
buildPages(0);
$yymain .= $TableFooter;
$yytitle = "$ml_txt{'313'} $TopAmmount $ml_txt{'314'}";
$action_area = 'viewmembers';
AdminTemplate();
return;
}
sub MLLastOnline {
%TopMembers = ();
ManageMemberinfo('load');
while ( ( $membername, $value ) = each %memberinf ) {
LoadUser($membername);
$TopMembers{$membername} = ${ $uid . $membername }{'lastonline'};
undef %{ $uid . $membername };
}
undef %memberinf;
my @toplist =
reverse sort { $TopMembers{$a} <=> $TopMembers{$b} } keys %TopMembers;
undef %TopMembers;
if ( $FORM{'reversed'} || $INFO{'reversed'} ) {
@toplist = reverse @toplist;
}
$memcount = @toplist;
buildIndex();
buildPages(1);
$bb = $start;
while ( $numshown < $MembersPerPage ) {
showRows( $toplist[$bb] );
$numshown++;
$bb++;
}
undef @toplist;
buildPages(0);
$yymain .= $TableFooter;
$yytitle = "$ml_txt{'313'} $TopAmmount $ml_txt{'314'}";
$action_area = 'viewmembers';
AdminTemplate();
return;
}
sub FindMembers {
$SearchStr = $FORM{'member'} || $INFO{'member'};
$LookFor = qq~^$SearchStr\$~;
$LookFor =~ s/\*+/.*?/gsm;
ManageMemberinfo('load');
my %memberfind = ();
while ( ( $membername, $value ) = each %memberinf ) {
( $memrealname, $mememail, undef ) = split /\|/xsm, $value, 3;
if ( $memrealname =~ /$LookFor/ism ) {
$memberfind{$membername} = $memrealname;
}
elsif ( $mememail =~ /$LookFor/ism ) {
if ( $iamadmin || $iamgmod )
{
$memberfind{$membername} = $memrealname;
}
}
}
@findmemlist =
sort { lc $memberfind{$a} cmp lc $memberfind{$b} } keys %memberfind;
undef %memberfind;
$memcount = @findmemlist;
buildIndex();
buildPages(1);
if ( $memcount > 0 ) {
my $i = $start;
$numshown = 0;
while ( $numshown < $MembersPerPage ) {
chomp $findmemlist[$i];
showRows( $findmemlist[$i] );
$numshown++;
$i++;
}
$isgood = 1;
}
else {
$yymain .= qq~
$ml_txt{'802'} $FORM{'member'}
|
~;
$isgood = 0;
}
undef @findmemlist;
undef %memberinf;
buildPages(0);
$yytitle = "$ml_txt{'313'} $ml_txt{'4'} $ml_txt{'87'} $numshow";
AdminTemplate();
return $isgood;
}
1;