###############################################################################
# MyCenter.pm #
# $Date: 01.09.2026 $ #
###############################################################################
# YaBB: Yet another Bulletin Board #
# Open-Source Community Software for Webmasters #
# Version: YaBBForum 3.1 #
# Packaged: 01 Sep, 2026 #
# Distributed by: https://yabbforum.nz #
# =========================================================================== #
# Copyright (c) 2000-2026 YaBB (yabbforum.nz) - All Rights Reserved. #
# Software by: The YaBB Development Team #
# with assistance from the YaBB community. #
###############################################################################
# use strict;
# use warnings;
no warnings qw(uninitialized once);
use CGI::Carp qw(fatalsToBrowser);
our $VERSION = '3.1';
$mycenterpmver = 'YaBBForum 3.1';
if ( $action eq 'detailedversion' ) { return 1; }
LoadLanguage('InstantMessage');
LoadLanguage('MyCenter');
LoadLanguage('Profile');
get_micon();
get_template('MyCenter');
get_gmod();
$pm_lev = PMlev();
$mycenter_txt{'welcometxt'} =~ s/USERLABEL/${$uid.$username}{'realname'}/gxsm;
$showIM = q{};
$IM_box = q{};
$showProfile = q{};
$PMfileToOpen = q{};
$sendBMess = q{};
$isBMess = q{};
$showFavorites = q{};
$showNotifications = q{};
sub mycenter {
if ($iamguest) { fatal_error('im_members_only'); }
LoadBroadcastMessages($username); # get the BM infos
$IM_box = q{};
my $PMfileToOpen = q{};
my @otherStoreFolders = ();
my $otherStoreSelect = q{};
$replyguest = $INFO{'replyguest'} || $FORM{'replyguest'};
## select view by action
if ( $action =~ /^im/sm
|| $action eq 'deletemultimessages'
|| $action eq 'pmsearch' )
{
$view = 'pm';
}
elsif ( $action eq 'mycenter' ) { $view = 'mycenter'; }
elsif ($action eq 'shownotify'
|| $action =~ /^notify/xsm
|| $action eq 'boardnotify2' )
{
$view = 'notify';
$mctitle = $img_txt{'418'};
}
elsif ( $action eq 'myusersrecentposts' ) { $view = 'recentposts'; }
elsif ( $action eq 'favorites' ) {
$view = 'favorites';
$mctitle = $img_txt{'70'};
}
elsif ( $action =~ /^my/xsm ) { $view = 'profile'; }
## viewing PMs
if ( $view eq 'pm' ) { # pm views
## viewing a message box
require Sources::InstantMessage;
if ( $action eq 'im'
|| $action eq 'imoutbox'
|| $action eq 'imstorage' )
{
my $foundextra = 0;
foreach my $storefolder ( split /\|/xsm, ${$username}{'PMfolders'} )
{
if ( $storefolder ne $INFO{'viewfolder'} ) {
push @otherStoreFolders, $storefolder;
$foundextra = 1;
}
}
if ( $foundextra > 0 ) {
$otherStoreSelect =
qq~ $inmes_txt{'storein'} ~;
}
}
## inbox
if ( $action eq 'im'
|| ( $action eq 'imshow' && $INFO{'caller'} == 1 ) )
{
$mctitle = $inmes_txt{'inbox'};
$status = $inmes_imtxt{'status'};
$senderinfo = $inmes_txt{'318'};
$callerid = 1;
$boxtxt = $inmes_txt{'316'};
$movebutton =
qq~$otherStoreSelect $inmes_txt{'storeor'}~;
$IM_box = $inmes_txt{'inbox'};
if ( $INFO{'focus'} eq 'bmess' || $INFO{'bmess'} eq 'yes' ) {
$IM_box = $inmes_txt{'broadcast'};
$callerid = 5;
}
$PMfileToOpen = 'msg';
}
## draft box
elsif ( $action eq 'imdraft' ) {
$mctitle = $inmes_txt{'draft'};
$status = $inmes_imtxt{'status'};
$senderinfo = $inmes_txt{'324'};
$callerid = 4;
$boxtxt = $inmes_txt{'draft'};
$movebutton = q{};
$IM_box = $inmes_txt{'draft'};
$PMfileToOpen = 'imdraft';
}
## outbox
elsif ( $action eq 'imoutbox'
|| ( $action eq 'imshow' && $INFO{'caller'} == 2 ) )
{
$mctitle = $inmes_txt{'773'};
$status = $inmes_imtxt{'status'};
$senderinfo = $inmes_txt{'324'};
$callerid = 2;
$boxtxt = $inmes_txt{'outbox'};
$movebutton =
qq~$otherStoreSelect $inmes_txt{'storeor'}~;
$IM_box = $inmes_txt{'outbox'};
$PMfileToOpen = 'outbox';
}
# store
elsif ( $action eq 'imstorage'
|| ( $action eq 'imshow' && $INFO{'caller'} == 3 ) )
{
$mctitle = $inmes_txt{'storage'};
$status = q{};
$senderinfo = $inmes_txt{'318'};
if ( $INFO{'viewfolder'} eq 'out' ) {
$senderinfo = $inmes_txt{'324'};
}
elsif ( $INFO{'viewfolder'} ne 'in' ) {
$senderinfo = qq~$inmes_txt{'318'} / $inmes_txt{'324'}~;
}
$callerid = 3;
$boxtxt = $inmes_txt{'storage'};
$movebutton =
qq~$otherStoreSelect $inmes_txt{'storeor'}~;
$IM_box = $inmes_txt{'storage'};
fopen( THREADS, "$memberdir/$username.imstore" );
@threads = ;
fclose(THREADS);
$threadid = $INFO{'id'};
foreach my $thread (@threads) {
chomp $thread;
if ( $thread =~ /$threadid/xsm ) {
@fold = split /\|/xsm, $thread;
if ( $fold[13] eq 'in' || $fold[13] eq 'out' ) {
$folder = qq~$im_folders_txt{$fold[13]}~;
}
else { $folder = $fold[13]; }
}
}
if ( $INFO{'viewfolder'} eq 'in' || $INFO{'viewfolder'} eq 'out' ) {
$IM_box .= qq~ › $im_folders_txt{"$INFO{'viewfolder'}"}~;
}
elsif ( $INFO{'viewfolder'} ) {
$IM_box .= qq~ › $INFO{'viewfolder'}~;
}
$mctitle .= qq~ › $folder~;
$PMfileToOpen = 'imstore';
}
## sending a message / previewing
elsif ( $action eq 'imsend' )
{
$IM_box = $inmes_txt{'148'};
if ( $INFO{'forward'} == 1 ) { $IM_box = $inmes_txt{'forward'}; }
if ( $INFO{'reply'} ) { $IM_box = $inmes_txt{'replymess'}; }
IMPost();
buildIMsend();
doshowims();
}
## posting the message or draft
elsif ( $action eq 'imsend2' || $FORM{'draft'} ) {
$IM_box = $inmes_txt{'148'};
if ( $INFO{'forward'} == 1 ) { $IM_box = $inmes_txt{'forward'}; }
if ( $INFO{'reply'} ) { $IM_box = $inmes_txt{'replymess'}; }
IMsendMessage();
}
elsif ( $action eq 'imshow' && $INFO{'caller'} == 5 ) {
$mctitle = $inmes_txt{'broadcast'};
$status = $inmes_imtxt{'status'};
$senderinfo = $inmes_txt{'318'};
$callerid = 5;
$boxtxt = $inmes_txt{'316'};
$movebutton =
qq~$otherStoreSelect $inmes_txt{'storeor'}~;
$IM_box = $inmes_txt{'broadcast'};
$PMfileToOpen = 'msg';
}
}
## viewing front page
elsif ( $view eq 'mycenter' ) {
$mctitle = "$inmes_txt{'mycenter'}";
}
## viewing my profile
elsif ( $view eq 'profile' ) {
$mctitle = "$mc_menus{'profile'}";
}
## viewing my recent posts
elsif ( $view eq 'recentposts' ) {
$mctitle =
"$inmes_txt{'viewrecentposts'} $inmes_txt{'viewrecentposts2'}";
}
## draw the container
drawPMbox($PMfileToOpen);
LoadIMs();
# navigation link
$yynavigation =
qq~› $img_txt{'mycenter'} › $mctitle~;
## set template up
$mycenter_template =~ s/{yabb mcviewmenu}/$MCViewMenu/gsm;
$mycenter_template =~ s/{yabb mcmenu}/$yymcmenu/gsm;
$mycenter_template =~ s/{yabb mcpmmenu}/$MCPmMenu/gsm;
$mycenter_template =~ s/{yabb mcprofmenu}/$MCProfMenu/gsm;
$mycenter_template =~ s/{yabb mcpostsmenu}/$MCPostsMenu/gsm;
$mycenter_template =~
s/{yabb mcglobformstart}/$MCGlobalFormStart/gsm;
$mycenter_template =~
s/{yabb mcglobformend}/ ($MCGlobalFormStart ? "<\/form>" : q{}) /esm;
$mycenter_template =~ s/{yabb mccontent}/$MCContent/gsm;
$mycenter_template =~ s/{yabb mctitle}/$mctitle/gsm;
$mycenter_template =~ s/{yabb selecthtml}/$selecthtml/gsm;
$mycenter_template =~ s/{yabb forumjump}//gsm;
## end new style box
$yymain .= $mycenter_template;
template();
return;
}
sub AddFolder {
if ($iamguest) { fatal_error('im_members_only'); }
my $storefolders = ${$username}{'PMfolders'};
my @currStoreFolders = split /\|/xsm, ${$username}{'PMfolders'};
my $newStoreFolders = 'in|out';
my $newFolderName = $FORM{'newfolder'};
chomp $newFolderName;
my $x = 0;
NXTFDR: foreach my $currStoreFolder (@currStoreFolders) {
if ( $FORM{'newfolder'} ) {
if ( $newFolderName =~ /[^0-9A-Za-z \-_]/xsm ) {
fatal_error( 'invalid_character', $inmes_txt{'foldererror'} );
}
if ( $FORM{'newfolder'} eq $currStoreFolder ) {
fatal_error('im_folder_exists');
}
}
elsif ( $FORM{'delfolders'} ) {
if ( $currStoreFolder ne 'in'
&& $currStoreFolder ne 'out'
&& $FORM{"delfolder$x"} ne 'del' )
{
$newStoreFolders .= qq~|$currStoreFolder~;
}
}
$x++;
}
if ( $FORM{'newfolder'} ) {
${$username}{'PMfolders'} = qq~$storefolders|$FORM{'newfolder'}~;
}
elsif ( $FORM{'delfolders'} ) {
${$username}{'PMfolders'} = $newStoreFolders;
}
buildIMS( $username, 'update' );
$yySetLocation = qq~$scripturl?action=mycenter~;
redirectexit();
return;
}
## call an unopened message back
sub CallBack {
if ($iamguest) { fatal_error('im_members_only'); }
my $receiver = $INFO{'receiver'}; # set variables from GET - localised
if ( $receiver && $receiver !~ /,/xsm ) {
$receiver = decloak($receiver);
if ( CallBackRec( $receiver, $INFO{'rid'}, 1 ) ) {
fatal_error('im_deleted');
}
updateIMS( $receiver, $INFO{'rid'}, 'callback' );
}
elsif ($receiver) {
foreach my $rec ( split /,/xsm, $receiver ) {
$rec = decloak($rec);
if ( CallBackRec( $rec, $INFO{'rid'}, 0 ) ) {
fatal_error('im_deleted_multi');
}
}
foreach my $rec ( split /,/xsm, $receiver ) {
$rec = decloak($rec);
CallBackRec( $rec, $INFO{'rid'}, 1 );
updateIMS( $rec, $INFO{'rid'}, 'callback' );
}
}
updateMessageFlag( $username, $INFO{'rid'}, 'outbox', q{}, 'c' );
$yySetLocation = qq~$scripturl?action=imoutbox~;
redirectexit();
return;
}
sub CallBackRec {
my ( $receiver, $rid, $do_it ) = @_;
fopen( RECMSG, "$memberdir/$receiver.msg" );
my @rims = ;
fclose(RECMSG);
my ( $nodel, $rmessageid, $fromuser, $flags );
if ($do_it) { fopen( REVMSG, ">$memberdir/$receiver.msg" ); }
## run through and drop the message line
foreach (@rims) {
(
$rmessageid, $fromuser, undef, undef, undef,
undef, undef, undef, undef, undef,
undef, undef, $flags, undef
) = split /\|/xsm, $_, 14;
if ( !$do_it ) {
if ( $rmessageid == $rid && $fromuser eq $username ) {
if ( $flags !~ /u/ism ) { $nodel = 1; }
last;
}
}
else {
if ( $rmessageid != $rid || $fromuser ne $username ) {
print {REVMSG} $_ or croak "$croak{'print'} REVMSG";
}
elsif ( $flags !~ /u/ism ) {
print {REVMSG} $_ or croak "$croak{'print'} REVMSG";
$nodel = 1;
}
}
}
if ($do_it) { fclose(REVMSG); }
return $nodel;
}
sub checkIMS { # lookup value in pm file
my ( $user, $id, $checkfor ) = @_;
## has the message been opened by the receiver? 1 = yes 0 = no
if ( $checkfor eq 'messageopened' ) {
my $messageFoundFlag = checkMessageFlag( $user, $id, 'msg', 'u' );
if ( $messageFoundFlag == 1 ) { return 0; }
else {
$messageFoundFlag = checkMessageFlag( $user, $id, 'imstore', 'u' );
}
if ( $messageFoundFlag == 1 ) { return 0; }
else { return 1; }
## has the message been replied to? 1 = yes 0 = no
}
elsif ( $checkfor eq 'messagereplied' ) {
## check in msg and imstore
my $messageFoundFlag = checkMessageFlag( $user, $id, 'msg', 'r' );
if ( $messageFoundFlag == 1 ) { return 1; }
else {
$messageFoundFlag = checkMessageFlag( $user, $id, 'imstore', 'r' );
}
if ( $messageFoundFlag == 1 ) { return 1; }
else { return 0; }
}
return;
}
sub checkMessageFlag {
# look for $user.$pmFile, find $id message and check for $messageFlag
my ( $user, $id, $pmFile, $messageFlag ) = @_;
my $messageFoundFlag = 0;
if ( %{ 'MF' . $user . $pmFile } ) {
if ( exists ${ 'MF' . $user . $pmFile }{$id}
&& ${ 'MF' . $user . $pmFile }{$id} =~ /$messageFlag/ism )
{
$messageFoundFlag = 1;
}
}
elsif ( -e "$memberdir/$user.$pmFile" ) {
fopen( USERMSG, "$memberdir/$user.$pmFile" );
my @userMessages = ;
fclose(USERMSG);
my ( $uMessageId, $uMessageFlags );
foreach (@userMessages) {
(
$uMessageId, undef, undef, undef, undef,
undef, undef, undef, undef, undef,
undef, undef, $uMessageFlags, undef
) = split /\|/xsm, $_, 14;
${ 'MF' . $user . $pmFile }{$uMessageId} = $uMessageFlags;
if ( $uMessageId == $id && $uMessageFlags =~ /$messageFlag/ism ) {
$messageFoundFlag = 1;
}
}
}
return $messageFoundFlag;
}
sub updateMessageFlag {
# look for $user.$pmFile, find $id message and check for $messageFlag. change to $newMessageFlag
my ( $user, $id, $pmFile, $messageFlag, $newMessageFlag ) = @_;
my $messageFoundFlag = 0;
if (
(
!exists ${ 'MF' . $user . $pmFile }{$id}
|| ( $messageFlag ne q{}
&& ${ 'MF' . $user . $pmFile }{$id} =~ /$messageFlag/xsm )
|| ( $messageFlag eq q{}
&& !${ 'MF' . $user . $pmFile }{$id} =~ /$newMessageFlag/xsm )
)
&& -e "$memberdir/$user.$pmFile"
)
{
fopen( USERFILE, "<$memberdir/$user.$pmFile" );
my @userFile = ;
fclose( USERFILE );
my @newpmfile = ();
foreach my $userMessage (@userFile) {
my (
$uMessageId, $uFrom, $uToUser, $uTocc,
$uTobcc, $uSubject, $uDate, $uMessage,
$uPid, $uReply, $uip, $uStatus,
$uMessageFlags, $uStorefolder, $uAttach
) = split /\|/xsm, $userMessage;
if ( $uMessageId == $id ) {
if ( $newMessageFlag ne q{} ) {
$uMessageFlags =~ s/$newMessageFlag//gism;
}
if ( $uMessageFlags =~ s/$messageFlag/$newMessageFlag/ixsm ) {
$messageFoundFlag = 1;
}
else {
$uMessageFlags .= $newMessageFlag;
}
$userMessage =
"$uMessageId|$uFrom|$uToUser|$uTocc|$uTobcc|$uSubject|$uDate|$uMessage|$uPid|$uReply|$uip|$uStatus|$uMessageFlags|$uStorefolder|$uAttach";
}
${ 'MF' . $user . $pmFile }{$uMessageId} = $uMessageFlags;
push @newpmfile, $userMessage;
}
fopen( USERFILE, ">$memberdir/$user.$pmFile" );
print {USERFILE} @newpmfile or croak "$croak{'print'} USERFILE";
fclose(USERFILE);
}
return $messageFoundFlag;
}
sub updateIMS {
# update .ims file for user: &updateIMS(,,[target/action])
my ( $user, $id, $target ) = @_;
# load the user who is processed here, if not already loaded
if ( !exists ${$user}{'PMmnum'} ) { buildIMS( $user, 'load' ); }
# new msg received - add to the inbox lists and increment the counts
if ( $target eq 'messagein' ) {
# read the lines into temp variables
${$user}{'PMmnum'}++;
${$user}{'PMimnewcount'}++;
# message sent - add to the outbox list and increment count
}
elsif ( $target eq 'messageout' ) {
${$user}{'PMmoutnum'}++;
# reading msg in inbox - newcount -1, remove from unread list
}
elsif ( $target eq 'inread' ) {
if ( updateMessageFlag( $user, $id, 'msg', 'u', q{} ) ) {
${$user}{'PMimnewcount'}--;
}
else { return; }
# callback message - take off imnewcount, mnum
}
elsif ( $target eq 'callback' ) {
${$user}{'PMmnum'}--;
${$user}{'PMimnewcount'}--;
# draft added
}
elsif ( $target eq 'draftadd' ) {
${$user}{'PMdraftnum'}++;
# draft send
}
elsif ( $target eq 'draftsend' ) {
${$user}{'PMdraftnum'}--;
}
buildIMS( $user, 'update' ); # rebuild the .ims file it with the new values
return;
}
# delete|move IMs
sub Del_Some_IM {
LoadLanguage('InstantMessage');
if ($iamguest) { fatal_error('im_members_only'); }
my $fileToOpen = "$username.msg";
if ( $INFO{'caller'} == 2 ) { $fileToOpen = "$username.outbox"; }
elsif ( $INFO{'caller'} == 3 ) { $fileToOpen = "$username.imstore"; }
elsif ( $INFO{'caller'} == 4 ) { $fileToOpen = "$username.imdraft"; }
elsif ( $INFO{'caller'} == 5 ) { $fileToOpen = 'broadcast.messages'; }
fopen( USRFILE, "<$memberdir/$fileToOpen" );
my @messages = ;
fclose( USRFILE );
my @delpost = ();
# deleting
if ( $FORM{'imaction'} eq $inmes_txt{'remove'}
|| $INFO{'action'} eq $inmes_txt{'remove'}
|| $INFO{'deleteid'} )
{
my %CountStore;
if ( $INFO{'caller'} == 2 ) { ${$username}{'PMmoutnum'} = 0; }
elsif ( $INFO{'caller'} == 4 ) { ${$username}{'PMdraftnum'} = 0; }
elsif ( $INFO{'caller'} != 3 && $INFO{'caller'} != 5 ) {
${$username}{'PMmnum'} = 0;
${$username}{'PMimnewcount'} = 0;
}
if ( $INFO{'deleteid'} ) {
$FORM{ 'message' . $INFO{'deleteid'} } = 1;
} # single delete
@delpost = ();
foreach (@messages) {
my @m = split /\|/xsm, $_;
chomp @m;
if ( $INFO{'caller'} != 1 && $m[14] ne q{} ) {
foreach ( split /,/xsm, $m[14] ) {
my ( $pmAttachFile, $pmAttachUser ) = split /~/xsm, $_;
if ( $username eq $pmAttachUser ) {
unlink "$pmuploaddir/$pmAttachFile";
}
}
}
if ( !exists $FORM{ 'message' . $m[0] } ) {
push @delpost, $_;
if ( $INFO{'caller'} == 2 ) { ${$username}{'PMmoutnum'}++; }
elsif ( $INFO{'caller'} == 3 ) { $CountStore{ $m[13] }++; }
elsif ( $INFO{'caller'} == 4 ) { ${$username}{'PMdraftnum'}++; }
elsif ( $INFO{'caller'} != 5 ) {
${$username}{'PMmnum'}++;
if ( $m[12] =~ /u/sm ) { ${$username}{'PMimnewcount'}++; }
}
}
else {
if ( $INFO{'caller'} == 3 ) {
$INFO{'viewfolder'} = $m[13];
}
elsif ( $INFO{'caller'} == 5 ) {
if ( ${$username}{'PMbcRead'} !~ s/\b$m[0]$//gsm ) {
${$username}{'PMbcRead'} =~ s/$m[0]\b//gsm;
}
}
}
}
fopen( USRFILE, ">$memberdir/$fileToOpen" );
print {USRFILE} @delpost or croak "$croak{'print'} USRFILE";
fclose(USRFILE);
if ( $INFO{'caller'} == 3 ) {
${$username}{'PMfoldersCount'} = q{};
${$username}{'PMstorenum'} = 0;
foreach ( split /\|/xsm, ${$username}{'PMfolders'} ) {
$CountStore{$_} ||= 0;
${$username}{'PMfoldersCount'} .=
${$username}{'PMfoldersCount'} eq q{}
? $CountStore{$_}
: "|$CountStore{$_}";
${$username}{'PMstorenum'} += $CountStore{$_};
}
}
buildIMS( $username, 'update' );
# moving messages
}
elsif ($FORM{'imaction'} eq $inmes_imtxt{'store'}
|| $INFO{'imaction'} eq $inmes_imtxt{'store'} )
{
my ( @newmessages, %CountStore, $imstorefolder );
if ( $FORM{'tostorefolder'} ) {
$imstorefolder = $FORM{'tostorefolder'};
}
elsif ( $INFO{'caller'} == 1 ) { $imstorefolder = 'in'; }
else { $imstorefolder = 'out'; }
@delpost = ();
foreach (@messages) {
if ( !$FORM{ 'message' . ( split /\|/xsm, $_, 2 )[0] } ) {
if ( $INFO{'caller'} != 3 ) {
push @delpost, $_;
}
else {
my @m = split /\|/xsm, $_;
push @newmessages, [@m];
$CountStore{ $m[13] }++;
}
}
else {
my @m = split /\|/xsm, $_;
$m[13] = $imstorefolder;
push @newmessages, [@m];
$CountStore{$imstorefolder}++;
if ( $INFO{'caller'} != 3 ) {
${$username}{'PMstorenum'}++;
if ( $INFO{'caller'} == 1 ) { ${$username}{'PMmnum'}--; }
elsif ( $INFO{'caller'} == 2 ) {
${$username}{'PMmoutnum'}--;
}
if ( $m[12] =~ /u/sm ) { ${$username}{'PMimnewcount'}--; }
}
}
}
fopen( USRFILE, ">$memberdir/$fileToOpen" );
print {USRFILE} @delpost or croak "$croak{'print'} USRFILE";
fclose(USRFILE);
if (@newmessages) {
if ( $INFO{'caller'} != 3 ) {
fopen( IUSRFILE, "$memberdir/$username.imstore" );
while ( my $line = ) {
my @m = split /\|/xsm, $line;
push @newmessages, [@m];
$CountStore{ $m[13] }++;
}
fclose(IUSRFILE);
}
fopen( TRANSFER, ">$memberdir/$username.imstore" );
print {TRANSFER}
map( { join q{|}, @{$_} }
reverse sort { ${$a}[6] <=> ${$b}[6] } @newmessages )
or croak "$croak{'print'} TRANSFER";
fclose(TRANSFER);
${$username}{'PMfoldersCount'} = q{};
foreach ( split /\|/xsm, ${$username}{'PMfolders'} ) {
$CountStore{$_} ||= 0;
${$username}{'PMfoldersCount'} .=
${$username}{'PMfoldersCount'} eq q{}
? $CountStore{$_}
: "|$CountStore{$_}";
}
buildIMS( $username, 'update' );
}
}
my $redirect = 'im';
if ( $INFO{'caller'} == 2 ) { $redirect = 'imoutbox'; }
elsif ( $INFO{'caller'} == 3 ) {
$redirect = "imstorage;viewfolder=$INFO{'viewfolder'}";
}
elsif ( $INFO{'caller'} == 4 ) { $redirect = 'imdraft'; }
elsif ( $INFO{'caller'} == 5 ) { $redirectview = ';focus=bmess'; }
$yySetLocation = qq~$scripturl?action=$redirect~;
redirectexit();
return;
}
# if the user is valid.
sub LoadValidUserDisplay {
my ($muser) = @_;
if ( !$yyUDLoaded{$muser} && -e "$memberdir/$muser.vars" ) {
$sm = 1;
LoadUserDisplay($muser);
}
return;
}
# create either a full link or just a name for the IM display
sub CreateUserDisplayLine {
my ($usrname) = @_;
my $usernamelink;
$sendPM = q{};
$sendEmail = q{};
$membAdInfo = q{};
if ( $yyUDLoaded{$usrname} ) {
if (
$INFO{'caller'} != 2
|| ( $mstatus !~ /b/sm
&& $mtousers !~ /,/xsm
&& !$mccusers
&& !$mbccusers )
)
{
$signature = ${ $uid . $usrname }{'signature'};
if ( $INFO{'caller'} == 2 || $INFO{'caller'} == 3 ) {
$signature = q{};
}
if ( $INFO{'caller'} != 5
|| ( $mstatus ne 'g' && $mstatus ne 'ga' ) )
{
userOnLineStatus($usrname);
}
if ( !$iamguest ) {
# Allow instant message sending if current user is a member.
$sendPM =
qq~$menusep$img{'message_sm'}~;
}
if ( !${ $uid . $usrname }{'hidemail'}
|| $iamadmin
|| $iamgmod
|| $allow_hide_email != 1 )
{
$sendEmail =
qq~$menusep$img{'email_sm'}~;
}
if ( !$minlinkweb ) { $minlinkweb = 0; }
$membAdInfo .=
${ $uid . $usrname }{'weburl'}
? $menusep . ${ $uid . $usrname }{'weburl'}
: q{};
$membAdInfo .=
${ $uid . $usrname }{'gtalk'}
? $menusep . ${ $uid . $usrname }{'gtalk'}
: q{};
$membAdInfo .=
${ $uid . $usrname }{'skype'}
? $menusep . ${ $uid . $usrname }{'skype'}
: q{};
$membAdInfo .=
${ $uid . $usrname }{'myspace'}
? $menusep . ${ $uid . $usrname }{'myspace'}
: q{};
$membAdInfo .=
${ $uid . $usrname }{'facebook'}
? $menusep . ${ $uid . $usrname }{'facebook'}
: q{};
$membAdInfo .=
${ $uid . $usrname }{'twitter'}
? $menusep . ${ $uid . $usrname }{'twitter'}
: q{};
$membAdInfo .=
${ $uid . $usrname }{'youtube'}
? $menusep . ${ $uid . $usrname }{'youtube'}
: q{};
}
$usernamelink = $link{$usrname};
if ( $musername eq $username ) {
$imOpened = checkIMS( $usrname, $messageid, 'messageopened' );
LoadUser($usrname);
if (
!$imOpened
&& ( ${ $uid . $usrname }{'notify_me'} < 2
|| $enable_notifications < 2 )
)
{
$usernamelink .=
qq~ ($inmes_imtxt{'83'})~;
}
}
}
else {
$usernamelink = qq~$usrname~;
}
return $usernamelink;
}
# posting the IM
sub IMPost {
if ( ( $INFO{'bmess'} || $FORM{'isBMess'} ) eq 'yes' ) { $sendBMess = 1; }
## guests not allowed
if ($iamguest) { fatal_error('im_members_only'); }
## if user is not a FA/gmod and has a postcount below the threshold
if ( !$staff && ${ $uid . $username }{'postcount'} < $numposts ) {
fatal_error('im_low_postcount');
}
my ( $mdate, $mip, $mmessage );
## if the IM has a number assigned already, open the right IM file
if ( $INFO{'id'} ne q{} ) {
if ( $INFO{'caller'} < 5 ) {
updateIMS( $username, $INFO{'id'}, 'inread' );
}
my $pmFileType = "$username.msg";
if ( $INFO{'caller'} == 2 ) { $pmFileType = "$username.outbox"; }
elsif ( $INFO{'caller'} == 3 ) {
$pmFileType = "$username.imstore";
}
elsif ( $INFO{'caller'} == 4 ) {
$pmFileType = "$username.imdraft";
}
elsif ( $INFO{'caller'} == 5 ) {
$pmFileType = 'broadcast.messages';
}
if ( !$replyguest ) {
fopen( FILE, "$memberdir/$pmFileType" );
@messages = ;
fclose(FILE);
## split content of IM file up
foreach my $checkTheMessage (@messages) {
(
$qmessageid, $mfrom, $mto, $mtocc,
$mtobcc, $msubject, $mdate, $message,
$mparid, $mreplyno, $mip, $mstatus,
$mflags, $mstore, $mattach
) = split /\|/xsm, $checkTheMessage;
if ( $qmessageid == $INFO{'id'} ) { last; }
}
## remove 're:' from subject (why?)
$msubject =~ s/Re: //gsm;
$msubject =~ s/Fwd: //gsm;
## if replying/quoting, up the reply# by 1
if ( $INFO{'quote'} || $INFO{'reply'} ) {
$mreplyno++;
$INFO{'status'} = $mstatus;
}
## if quote
if ( $INFO{'reply'} ) { $message = q{}; }
if ( $INFO{'quote'} ) {
# swap out brs and spaces
$message =~ s//\n/igsm;
$message =~ s/ \ \ \ /\t/igsm;
if ( !$nestedquotes ) {
$message =~
s/\n{0,1}\[quote([^\]]*)\](.*?)\[\/quote([^\]]*)\]\n{0,1}/\n/isgm;
}
if ( $mfrom ne q{} && $do_scramble_id ) {
$cloakedAuthor = cloak($mfrom);
}
else { $cloakedAuthor = $mfrom; }
# next 2 lines for display names in Quotes in LivePreview
LoadUser($mfrom);
$usernames_life_quote{$cloakedAuthor} =
${ $uid . $mfrom }{'realname'};
$maxmessagedisplay ||= 10;
$quotestart =
int( $quotemsg / $maxmessagedisplay ) * $maxmessagedisplay;
if ( $INFO{'forward'} || $INFO{'quote'} ) {
$message =
qq~[quote author=$cloakedAuthor link=impost date=$mdate\]$message\[/quote\]\n~;
}
if ( $message =~ /\#nosmileys/isgm ) {
$message =~ s/\#nosmileys//isgm;
$nscheck = 'checked';
}
}
if ( $INFO{'reply'} || $INFO{'quote'} ) {
$msubject = "Re: $msubject";
}
if ( $INFO{'forward'} ) {
$msubject =~ s/Re: //gsm;
$msubject = "Fwd: $msubject";
}
}
elsif ($replyguest) {
fopen( FILE, "$memberdir/$pmFileType" );
@messages = ;
fclose(FILE);
## split content of IM file up
foreach my $checkTheMessage (@messages) {
(
$qmessageid, $mfrom, $mto, $mtocc,
$mtobcc, $msubject, $mdate, $message,
$mparid, $mreplyno, $mip, $mstatus,
$mflags, $mstore, $mattach
) = split /\|/xsm, $checkTheMessage;
if ( $qmessageid == $INFO{'id'} ) { last; }
}
( $guestName, $guestEmail ) = split /\ /sm, $mfrom;
$guestName =~ s/%20/ /gsm;
$message =~ s//\n/gism;
$message =~ s/ \ \ \ /\t/igsm;
$message =~ s/\[b\](.*?)\[\/b\]/*$1*/isgm;
$message =~ s/\[i\](.*?)\[\/i\]/\/$1\//isgm;
$message =~ s/\[u\](.*?)\[\/u\]/_$1_/isgm;
$message =~ s/\[.*?\]//gsm;
my $sendtouser = ${ $uid . $username }{'realname'};
$mdate = timeformat( $mdate, 1 );
require Sources::Mailer;
LoadLanguage('Email');
#sender email date subject message
$message = template_email(
$replyguestmail,
{
'sender' => $guestName,
'email' => $guestEmail,
'sendto' => $sendtouser,
'date' => $mdate,
'subject' => $msubject,
'message' => $message
}
);
$msubject = qq~Re: $msubject~;
}
}
if ( $INFO{'forward'} || $INFO{'quote'} ) { FromHTML($message); }
FromHTML($msubject);
$submittxt = $inmes_txt{'sendmess'};
if ( $INFO{'forward'} == 1 ) { $submittxt = $inmes_txt{'forward'}; }
$destination = 'imsend2';
$waction = 'imsend';
$post = 'imsend';
$icon = 'xx';
$draft = 'draft';
$mctitle = $inmes_txt{'sendmess'};
if ($sendBMess) { $mctitle = $inmes_txt{'sendbroadmess'}; }
return;
}
sub MarkAll {
if ($iamguest) { fatal_error('im_members_only'); }
fopen( FILE, "<$memberdir/$username.msg" );
my @messages = ;
fclose( FILE );
my @mymessages = ();
foreach (@messages) {
my (
$imessageid, $imusername, $imusernameto,
$imusernametocc, $imusernametobcc, $imsub,
$imdate, $mmessage, $imessagepid,
$imreply, $mip, $imstatus,
$imflags, $imstore, $imattach
) = split /\|/xsm, $_;
if ( $imflags =~ s/u//ism ) {
push @mymessages,
"$imessageid|$imusername|$imusernameto|$imusernametocc|$imusernametobcc|$imsub|$imdate|$mmessage|$imessagepid|$imreply|$mip|$imstatus|$imflags|$imstore|$imattach";
}
else { push @mymessages, $_; }
}
fopen( FILE, ">$memberdir/$username.msg" );
print {FILE} @mymessages or croak "$croak{'print'} FILE";
fclose(FILE);
${$username}{'PMimnewcount'} = 0;
buildIMS( $username, 'update' );
if ( $INFO{'oldmarkread'} ) {
$yySetLocation = qq~$scripturl?action=im~;
redirectexit();
}
$elenable = 0;
croak q{}; # This is here only to avoid server error log entries!
}
# change type of page index for PM
sub PmPageindex {
my ( $msindx, $trindx, $mbindx, undef ) =
split /\|/xsm, ${ $uid . $username }{'pageindex'};
if ( $INFO{'action'} eq 'pmpagedrop' ) {
${ $uid . $username }{'pageindex'} = qq~$msindx|$trindx|$mbindx|1~;
}
if ( $INFO{'action'} eq 'pmpagetext' ) {
${ $uid . $username }{'pageindex'} = qq~$msindx|$trindx|$mbindx|0~;
}
UserAccount( $username, 'update' );
if ( $INFO{'pmaction'} =~ /\//xsm ) {
my ( $act, $val ) = split /\//xsm, $INFO{'pmaction'};
$INFO{'pmaction'} = $act . ';start=' . $val;
}
if ( $INFO{'focus'} eq 'bmess' ) { $bmesslink = q~;focus=bmess~; }
$yySetLocation =
qq~$scripturl?action=$INFO{'pmaction'}$bmesslink;start=$INFO{'start'}~
. ( $INFO{'viewfolder'} ? ";viewfolder=$INFO{'viewfolder'}" : q{} );
redirectexit();
return;
}
# draw the whole block , with the menu, and the various PM views.
sub drawPMbox {
my ($PMfileToOpen) = @_;
LoadLanguage('InstantMessage');
if ( ( $PMfileToOpen || $INFO{'focus'} )
&& $view eq 'pm'
&& $pm_lev == 1 )
{
if ( !$INFO{'focus'} ) {
if ( $callerid < 5 ) {
fopen( NFILE, "$memberdir/$username.$PMfileToOpen" );
@dimmessages = ;
my ( $mID, $mFlag );
foreach ( reverse @dimmessages ) {
(
$mID, undef, undef, undef, undef, undef, undef,
undef, undef, undef, undef, undef, $mFlag, undef
) = split /\|/xsm, $_, 14;
${ $username . $PMfileToOpen }{$mID} = $mFlag;
if ( $INFO{'id'} == -1 && $mFlag eq 'u' ) {
$INFO{'id'} = $mID;
}
}
}
else {
fopen( NFILE, "$memberdir/broadcast.messages" );
@bmessages = ;
}
fclose(NFILE);
}
elsif ( $INFO{'focus'} eq 'bmess' && $PMenableBm_level > 0 ) {
fopen( BFILE, "$memberdir/broadcast.messages" );
@bmessages = ;
fclose(BFILE);
}
$stkmess = 0;
if ( @bmessages > 0 ) {
foreach my $checkbcm (@bmessages) {
my (
undef, $mfrom, $mto, undef, undef,
undef, undef, undef, undef, undef,
undef, $messStatus, undef,
) = split /\|/xsm, $checkbcm;
if ( $mfrom eq $username || BroadMessageView($mto) ) {
if ( $INFO{'sort'} ne 'gpdate'
&& ( $messStatus =~ m/g/sm || $messStatus =~ m/a/sm ) )
{
push @stkbmessages, $checkbcm;
$stkmess++;
}
else {
push @tmpbmessages, $checkbcm;
}
}
}
undef @bmessages;
}
@stkbmessages = reverse sort { $a <=> $b } @stkbmessages;
@tmpbmessages = reverse sort { $a <=> $b } @tmpbmessages;
push @dimmessages, @stkbmessages;
push @dimmessages, @tmpbmessages;
undef @stkbmessages;
undef @tmpbmessages;
}
$yyjavascript .= q~
function changeBox(cbox) {
box = eval(cbox);
box.checked = !box.checked;
}
~;
## new style box ####
## start with forum > my messages > inbox
$yymain .= qq~
~;
if ( $action =~ /^im/sm
&& ( !@dimmessages && $INFO{'focus'} ne 'bmess' )
&& $pm_lev == 1 )
{
if ( !@dimmessages ) {
if ( $action eq 'im' ) {
unlink "$memberdir/$username.msg";
}
elsif ( $action eq 'imoutbox' ) {
unlink "$memberdir/$username.outbox";
}
elsif ( $action eq 'imstorage' ) {
unlink "$memberdir/$username.imstore";
}
elsif ( $action eq 'imdraft' ) {
unlink "$memberdir/$username.imdraft";
}
}
}
LoadCensorList();
# Fix moderator showing in info
$sender = 'im';
$acount = 0;
## set browser title
$yytitle = $mycenter_txt{'welcometxt'};
## start new container - left side is menu, right side is content
my ( $display_prof, $display_posts, $display_pm, $tabPMHighlighted,
$tabProfHighlighted, $tabNotifyHighlighted );
if ( $mycenter_template =~ /{yabb mcmenu}/gsm ) {
mcMenu();
$newtemplate = 1;
}
if (
$view eq 'profile'
|| (
$view eq 'mycenter'
&& ( $PM_level == 0
|| ( $PM_level == 2 && !$staff )
|| ( $PM_level == 3 && !$iamadmin && !$iamgmod )
|| ( $PM_level == 4 && !$iamadmin && !$iamgmod && !$iamfmod ) )
)
)
{
$display_prof = 'inline';
$tabProfHighlighted = 'windowbg2';
}
else {
$display_prof = 'none';
$tabProfHighlighted = 'windowbg';
}
if ( $view eq 'notify' || $view eq 'favorites' || $view eq 'recentposts' ) {
$display_posts = 'inline';
$tabNotifyHighlighted = 'windowbg2';
}
else {
$display_posts = 'none';
$tabNotifyHighlighted = 'windowbg';
}
if (
$view eq 'pm'
|| ( $view eq 'mycenter'
&& $pm_lev == 1 )
)
{
$display_pm = 'inline';
$tabPMHighlighted = 'windowbg2';
}
else {
$display_pm = 'none';
$tabPMHighlighted = 'windowbg';
}
my $tabWidth = '33%';
if ( $PM_level == 0
|| ( $PM_level == 2 && !$staff )
|| ( $PM_level == 3 && !$iamadmin && !$iamgmod )
|| ( $PM_level == 4 && !$iamadmin && !$iamgmod && !$iamfmod ) )
{
$tabWidth = '50%';
}
$MCViewMenu = q{};
$MCPmMenu = q{};
$MCProfMenu = q{};
$MCPostsMenu = q{};
$MCExtraSmilies = q{};
$MCContent = q{};
if ($newtemplate) {
$MCView_tab = q~
~;
}
else {
$MCView_tab = q~
\n~;
if ( $PM_level == 0
|| ( $PM_level == 2 && !$staff )
|| ( $PM_level == 3 && !$iamadmin && !$iamgmod )
|| ( $PM_level == 4 && !$iamadmin && !$iamgmod && !$iamfmod ) )
{
$display_prof = 'inline';
$tabProfHighlighted = 'windowbg2';
}
if ( $pm_lev == 1 ) {
$MCViewMenu_mess = $my_MCViewMenu_mess;
$MCViewMenu_mess =~ s/{yabb tabPMHighlighted}/$tabPMHighlighted/sm;
$MCViewMenu_mess =~
s/{yabb mc_menus_messages}/$mc_menus{'messages'}/sm;
}
$MCViewMenu .= $my_MCViewMenu;
$MCViewMenu =~ s/{yabb MCView_tab}/$MCView_tab/sm;
$MCViewMenu =~ s/{yabb MCViewMenu_mess}/$MCViewMenu_mess/sm;
$MCViewMenu =~ s/{yabb tabWidth}/$tabWidth/gsm;
$MCViewMenu =~ s/{yabb tabProfHighlighted}/$tabProfHighlighted/sm;
$MCViewMenu =~ s/{yabb tabNotifyHighlighted}/$tabNotifyHighlighted/sm;
$MCViewMenu =~ s/{yabb mc_menus_profile}/$mc_menus{'profile'}/sm;
$MCViewMenu =~ s/{yabb mc_menus_posts}/$mc_menus{'posts'}/sm;
}
$MCViewMenu .= $MCView_tab;
## start Profile div
## links for profile pages. SID is now cloaked and controls whether or not
## the action goes to authenticate or straight to the page.
## The trick is to use $page to pass the intended page through and switch over on
## positive id.
if ( $page && $page ne $action ) { $action = $page; }
my $profileLink;
my $sid = $INFO{'sid'};
my $thisLink = q{};
my $sidLink = q{};
if ( !$sid ) { $sid = $FORM{'sid'}; }
if ($sid) { $sidLink = ";sid=$sid"; }
if ( !$sid ) { $profileLink = 'action=profileCheck;page='; }
else { $profileLink = 'action='; }
$thisLink_a = 'action=myviewprofile;username=' . $useraccount{$username};
$thisLink_b =
$profileLink . 'myprofile;username=' . $useraccount{$username} . $sidLink;
$thisLink_c =
$profileLink
. 'myprofileContacts;username='
. $useraccount{$username}
. $sidLink;
$thisLink_d =
$profileLink
. 'myprofileOptions;username='
. $useraccount{$username}
. $sidLink;
if ($buddyListEnabled) {
$thisLink_e =
$profileLink
. 'myprofileBuddy;username='
. $useraccount{$username}
. $sidLink;
$my_buddylink = $my_thislink_buddy;
$my_buddylink =~ s/{yabb thisLink_e}/$thisLink_e/sm;
}
if ( $pm_lev == 1 ) {
$thisLink_f =
$profileLink
. 'myprofileIM;username='
. $useraccount{$username}
. $sidLink;
$my_IMpref = $my_thislink_impref;
$my_IMpref =~ s/{yabb thisLink_f}/$thisLink_f/sm;
}
if (
$iamadmin
|| ( $iamgmod
&& $allow_gmod_profile
&& $gmod_access2{'profileAdmin'} eq 'on' )
)
{
$thisLink_g =
$profileLink
. 'myprofileAdmin;username='
. $useraccount{$username}
. $sidLink;
$my_adminlink = $my_thisLink_admin;
$my_adminlink =~ s/{yabb thisLink_g}/$thisLink_g/sm;
}
$MCProfMenu = $my_MCProfMenu;
$MCProfMenu =~ s/{yabb display_prof}/$display_prof/sm;
$MCProfMenu =~ s/{yabb thisLink_a}/$thisLink_a/sm;
$MCProfMenu =~ s/{yabb thisLink_b}/$thisLink_b/sm;
$MCProfMenu =~ s/{yabb thisLink_c}/$thisLink_c/sm;
$MCProfMenu =~ s/{yabb thisLink_d}/$thisLink_d/sm;
$MCProfMenu =~ s/{yabb my_buddylink}/$my_buddylink/sm;
$MCProfMenu =~ s/{yabb my_IMpref}/$my_IMpref/sm;
$MCProfMenu =~ s/{yabb my_adminlink}/$my_adminlink/sm;
## end Profile div
## start Posts div
if ( ${ $uid . $username }{'postcount'} > 0 && $maxrecentdisplay > 0 ) {
$MCPost_count = $my_MCPost_count;
$MCPost_count =~ s/{yabb username}/$useraccount{$username}/sm;
my ( $x, $y ) = ( int( $maxrecentdisplay / 5 ), 0 );
if ($x) {
foreach my $i ( 1 .. 5 ) {
$y = $i * $x;
$MCPost_recent .= qq~
~;
}
}
if ( $maxrecentdisplay > $y ) {
$MCPost_recent .= qq~
~;
}
$MCPost_recent .= qq~
$inmes_txt{'viewrecentposts2'}
~;
}
$MCPostsMenu = $my_MCPostsMenu;
$MCPostsMenu =~ s/{yabb display_posts}/$display_posts/sm;
$MCPostsMenu =~ s/{yabb MCPost_count}/$MCPost_count/sm;
$MCPostsMenu =~ s/{yabb MCPost_recent}/$MCPost_recent/sm;
## end Posts div
if ( !$replyguest ) {
if ( $view eq 'pm' && $action ne 'imsend' && $action ne 'imsend2' ) {
my $imstoreFolder;
if ( $action eq 'imstorage' ) {
$imstoreFolder = ";viewfolder=$INFO{'viewfolder'}";
}
$MCGlobalFormStart .= qq~