1###############################################################################
2# BoardIndex.pm                                                               #
3# $Date: 12.02.14 $                                                           #
4###############################################################################
5# YaBB: Yet another Bulletin Board                                            #
6# Open-Source Community Software for Webmasters                               #
7# Version:        YaBB 2.6.11                                                 #
8# Packaged:       December 2, 2014                                            #
9# Distributed by: http://www.yabbforum.com                                    #
10# =========================================================================== #
11# Copyright (c) 2000-2014 YaBB (www.yabbforum.com) - All Rights Reserved.     #
12# Software by:  The YaBB Development Team                                     #
13#               with assistance from the YaBB community.                      #
14###############################################################################
15# use strict;
16# use warnings;
17no warnings qw(uninitialized once redefine);
18use CGI::Carp qw(fatalsToBrowser);
19use English '-no_match_vars';
20our $VERSION = '2.6.11';
21
22$boardindexpmver = 'YaBB 2.6.11 $Revision: 1611 $';
23if ( $action eq 'detailedversion' ) { return 1; }
24
25LoadLanguage('BoardIndex');
26get_micon();
27
28sub BoardIndex {
29    my (
30        $users,   $lspostid,   $lspostbd,   $lssub,      $lsposter,
31        $lsreply, $lsdatetime, @goodboards, @loadboards, $guestlist
32    );
33    get_forum_master();
34    my @brd_img_id = sort ( keys %board);
35    my %brd_img_id = ();
36    my $brdimgcnt = 0;
37    for ( @brd_img_id ) {
38        $brd_img_id{$_} = $brdimgcnt;
39        $brdimgcnt++;
40    }
41
42    my ( $memcount, $latestmember ) = MembershipGet();
43    chomp $latestmember;
44    $totalm       = 0;
45    $totalt       = 0;
46    $lastposttime = 0;
47    my $lastthreadtime = 0;
48
49    if ( $INFO{'boardselect'} ) { $subboard_sel = $INFO{'boardselect'}; }
50
51    # if sub board is selected but none exists with that name, show everything
52    if ( $subboard_sel && !$subboard{$subboard_sel} ) {
53        $subboard_sel = 0;
54    }
55
56    get_template('BoardIndex');
57
58    my ( $numusers, $guests, $numbots, $user_in_log, $guest_in_log ) =
59      ( 0, 0, 0, 0, 0 );
60    my %bvusers = ();
61
62    # do not do this stuff when we're calling for sub board display
63    if ( !$subboard_sel ) {
64        GetBotlist();
65
66        my $lastonline = $date - ( $OnlineLogTime * 60 );
67        foreach (@logentries) {
68            ( $name, $date1, $last_ip, $last_host, undef, $boardv, undef ) =
69              split /\|/xsm, $_, 7;
70            if ( !$last_ip ) {
71                $last_ip =
72qq~</i></span><span class="error">$boardindex_txt{'no_ip'}</span><span class="small"><i>~;
73            }
74            my $lookupIP =
75              ( $ipLookup && $last_ip )
76              ? qq~<a href="$scripturl?action=iplookup;ip=$last_ip">$last_ip</a>~
77              : qq~$last_ip~;
78
79            my $is_a_bot = Is_Bot($last_host);
80            if ($is_a_bot) {
81                $numbots++;
82                $bot_count{$is_a_bot}++;
83            }
84            elsif ($name) {
85                if ( LoadUser($name) ) {
86                    if ( $name eq $username ) { $user_in_log = 1; }
87                    elsif ( ${ $uid . $name }{'lastonline'} < $lastonline ) {
88                        next;
89                    }
90                    if ( $iamadmin || $iamgmod || $iamfmod ) {
91                        $numusers++;
92                        $bvusers{$boardv}++;
93                        $users .= QuickLinks($name);
94                        $users .= ( ${ $uid . $name }{'stealth'} ? q{*} : q{} )
95                          . (
96                            (
97                                     ( $iamadmin && $show_online_ip_admin )
98                                  || ( $iamgmod && $show_online_ip_gmod )
99                                  || ( $iamfmod && $show_online_ip_fmod )
100                            ) ? qq~&nbsp;<i>($lookupIP)</i>, ~ : q{, }
101                          );
102
103                    }
104                    elsif ( !${ $uid . $name }{'stealth'} ) {
105                        $numusers++;
106                        $users .= QuickLinks($name) . q{, };
107                    }
108                }
109                else {
110                    if ( $name eq $user_ip ) { $guest_in_log = 1; }
111                    $guests++;
112                    $bvusers{$boardv}++;
113                    if (   ( $iamadmin && $show_online_ip_admin )
114                        || ( $iamgmod && $show_online_ip_gmod )
115                        || ( $iamfmod && $show_online_ip_fmod ) )
116                    {
117                        $guestlist .= qq~<i>$lookupIP</i>, ~;
118                    }
119                }
120            }
121        }
122        if ( !$iamguest && !$user_in_log ) {
123            if ($guests) { $guests--; }
124            $numusers++;
125            $bvusers{$boardv}++;
126            $users .= QuickLinks($username);
127            if ( $iamadmin || $iamgmod || $iamfmod ) {
128                $users .= ${ $uid . $username }{'stealth'} ? q{*} : q{};
129                if (   ( $iamadmin && $show_online_ip_admin )
130                    || ( $iamgmod && $show_online_ip_gmod )
131                    || ( $iamfmod && $show_online_ip_fmod ) )
132                {
133                    $users .= "&nbsp;<i>($user_ip)</i>";
134                    $guestlist =~ s/<i>$lookupIP<\/i>, //osm;
135                }
136            }
137        }
138        elsif ( $iamguest && !$iambot && !$guest_in_log ) {
139            $guests++;
140            $bvusers{$boardv}++;
141        }
142
143        if ($numusers) {
144            $users =~ s/, \Z//sm;
145            $users .= q~<br />~;
146        }
147        if ($guestlist) {    # build the guest list
148            $guestlist =~ s/, $//sm;
149            $guestlist = qq~<span class="small">$guestlist</span><br />~;
150        }
151        if ($numbots) {      # build the bot list
152            foreach ( sort keys %bot_count ) {
153                $botlist .= qq~$_&nbsp;($bot_count{$_}), ~;
154            }
155            $botlist =~ s/, $//sm;
156            $botlist = qq~<span class="small">$botlist</span>~;
157        }
158
159        if ( !$INFO{'catselect'} ) {
160            $yytitle = $boardindex_txt{'18'};
161        }
162        else {
163            ( $tmpcat, $tmpmod, $tmpcol ) =
164              split /\|/xsm, $catinfo{ $INFO{'catselect'} };
165            ToChars($tmpcat);
166            $yytitle      = qq~$tmpcat~;
167            $yynavigation = qq~&rsaquo; $tmpcat~;
168        }
169
170        if ( !$iamguest ) { Collapse_Load(); }
171    }
172
173    else {
174        foreach (@logentries) {
175            ( $name, $date1, $last_ip, $last_host, undef, $boardv, undef ) =
176              split /\|/xsm, $_, 7;
177            if ($name) {
178                if ( LoadUser($name) ) {
179                    if ( $iamadmin || $iamgmod || $iamfmod ) {
180                        $numusers++;
181                        $bvusers{$boardv}++;
182                    }
183                }
184                else {
185                    if ( $name eq $user_ip ) { $guest_in_log = 1; }
186                    $guests++;
187                    $bvusers{$boardv}++;
188                }
189            }
190        }
191    }
192
193    my @tmplist;
194    if ($subboard_sel) {
195        push @tmplist, $subboard_sel;
196    }
197    else {
198        push @tmplist, @categoryorder;
199    }
200
201# first get all the boards based on the categories found in forum.master or the provided sub board
202    foreach my $catid (@tmplist) {
203        if (   $INFO{'catselect'} ne $catid
204            && $INFO{'catselect'}
205            && !$subboard_sel )
206        {
207            next;
208        }
209
210        # get boards in category if we're not looking for subboards
211        if ( !$subboard_sel ) {
212            (@bdlist) = split /\,/xsm, $cat{$catid};
213            my ( $catname, $catperms, $catallowcol ) =
214              split /\|/xsm, $catinfo{$catid};
215
216            # Category Permissions Check
217            my $access = CatAccess($catperms);
218            if ( !$access ) { next; }
219            $cat_boardcnt{$catid} = 0;
220        }
221        else {
222            (@bdlist) = split /\|/xsm, $subboard{$catid};
223        }
224
225        foreach my $curboard (@bdlist) {
226            if ( !exists $board{$curboard} ) {
227                gostRemove( $catid, $curboard );
228                next;
229            }
230
231# hide the actual global announcement board for all normal users but admins and gmods
232            if (   $annboard eq $curboard
233                && !$iamadmin
234                && !$iamgmod
235                && !$iamfmod )
236            {
237                next;
238            }
239            my ( $boardname, $boardperms, $boardview ) =
240              split /\|/xsm, $board{$curboard};
241            my $access = AccessCheck( $curboard, q{}, $boardperms );
242            if ( !$iamadmin && $access ne 'granted' && $boardview != 1 ) {
243                next;
244            }
245
246     # Now check subboards that won't be displayed but we need their latest info
247            if ( $subboard{$curboard} ) {
248
249         # recursively check access to all sub boards then add them to load list
250                *recursive_boards = sub {
251                    foreach my $childbd (@_) {
252
253               # now fill all the necessary hashes to show all board index stuff
254                        if ( !exists $board{$childbd} ) {
255                            gostRemove( $catid, $childbd );
256                            next;
257                        }
258
259# hide the actual global announcement board for all normal users but admins and gmods
260                        if (   $annboard eq $childbd
261                            && !$iamadmin
262                            && !$iamgmod
263                            && !$iamfmod )
264                        {
265                            next;
266                        }
267                        ( $boardname, $boardperms, $boardview ) =
268                          split /\|/xsm, $board{$childbd};
269                        $access = AccessCheck( $childbd, q{}, $boardperms );
270                        if (  !$iamadmin
271                            && $access ne 'granted'
272                            && $boardview != 1 )
273                        {
274                            next;
275                        }
276
277                        # add it to list of boards to load data
278                        push @loadboards, $childbd;
279
280                        # make recursive call if this board has more children
281                        if ( $subboard{$childbd} ) {
282                            recursive_boards( split /\|/xsm,
283                                $subboard{$childbd} );
284                        }
285                    }
286                };
287                recursive_boards( split /\|/xsm, $subboard{$curboard} );
288            }
289
290            # if it's a sub board don't add to category count
291            if ( !${ $uid . $curboard }{'parent'} ) {
292                $cat_boardcnt{$catid}++;
293            }
294
295            push @goodboards, "$catid|$curboard";
296            push @loadboards, $curboard;
297        }
298    }
299
300    BoardTotals( 'load', @loadboards );
301    getlog();
302    my $dmax = $date - ( $max_log_days_old * 86400 );
303
304# if loading subboard list by ajax we don't need this (Ajax showcasepoll load does not work, assume this is mistake. DAR)
305
306    my $polltemp;
307    if ( -e "$datadir/showcase.poll" ) {
308        fopen( SCPOLLFILE, "$datadir/showcase.poll" );
309        my $scthreadnum = <SCPOLLFILE>;
310        fclose(SCPOLLFILE);
311
312        # Look for a valid poll file.
313        my $pollthread;
314        if ( -e "$datadir/$scthreadnum.poll" ) {
315            MessageTotals( 'load', $scthreadnum );
316            if ( $iamadmin || $iamgmod || $iamfmod ) {
317                $pollthread = 1;
318            }
319            else {
320                my $curcat = ${ $uid . ${$scthreadnum}{'board'} }{'cat'};
321                my $catperms = ( split /\|/xsm, $catinfo{$curcat} )[1];
322                if ( CatAccess($catperms) ) { $pollthread = 1; }
323                my $boardperms =
324                  ( split /\|/xsm, $board{ ${$scthreadnum}{'board'} } )[1];
325                $pollthread =
326                  AccessCheck( ${$scthreadnum}{'board'}, q{}, $boardperms ) eq
327                  'granted' ? $pollthread : 0;
328            }
329            if ( ${ $uid . $scboard }{'brdpasswr'} && !$iamadmin && !$iamgmod )
330            {
331                my $pswiammod = 0;
332                my $bdmods    = ${ $uid . $curboard }{'mods'};
333                $bdmods =~ s/\, /\,/gsm;
334                $bdmods =~ s/\ /\,/gsm;
335                foreach my $curuser ( split /\,/xsm, $bdmods ) {
336                    if ( $username eq $curuser ) { $pswiammod = 1; last; }
337                }
338                my $bdmodgroups = ${ $uid . $scboard }{'modgroups'};
339                $bdmodgroups =~ s/\, /\,/gsm;
340                foreach my $curgroup ( split /\,/xsm, $bdmodgroups ) {
341                    if ( ${ $uid . $username }{'position'} eq $curgroup ) {
342                        $pswiammod = 1;
343                        last;
344                    }
345                    foreach my $memberaddgroups ( split /\, /xsm,
346                        ${ $uid . $username }{'addgroups'} )
347                    {
348                        chomp $memberaddgroups;
349                        if ( $memberaddgroups eq $curgroup ) {
350                            $pswiammod = 1;
351                            last;
352                        }
353                    }
354                }
355                my $bpasscookie =
356                  "$cookiepassword$scboard$username$cookieother_name";
357                my $crypass = ${ $uid . $scboard }{'brdpassw'};
358                if ( !$pswiammod && $yyCookies{$bpasscookie} ne $crypass ) {
359                    $pollthread = 0;
360                }
361            }
362        }
363
364        if ($pollthread) {
365            my $tempcurrentboard = $currentboard;
366            $currentboard = ${$scthreadnum}{'board'};
367            my $tempstaff = $staff;
368            if ( !$iamadmin && !$iamgmod && !$iamfmod ) { $staff = 0; }
369            require Sources::Poll;
370            display_poll( $scthreadnum, 1 );
371            $staff        = $tempstaff;
372            $polltemp     = $pollmain . '<br />';
373            $currentboard = $tempcurrentboard;
374        }
375    }
376
377    # showcase poll end
378
379    foreach my $curboard (@loadboards) {
380        chomp $curboard;
381
382        my $iammodhere = q{};
383        foreach my $curuser ( split /, ?/sm, ${ $uid . $curboard }{'mods'} ) {
384            if ( $username eq $curuser ) { $iammodhere = 1; }
385        }
386        foreach
387          my $curgroup ( split /, /sm, ${ $uid . $curboard }{'modgroups'} )
388        {
389            if ( ${ $uid . $username }{'position'} eq $curgroup ) {
390                $iammodhere = 1;
391            }
392            foreach ( split /,/xsm, ${ $uid . $username }{'addgroups'} ) {
393                if ( $_ eq $curgroup ) { $iammodhere = 1; last; }
394            }
395        }
396
397# if this is a parent board and it can't be posted in, set lastposttime to 0 so subboards will show latest data
398        if ( $subboard{$curboard} && !${ $uid . $curboard }{'canpost'} ) {
399            ${ $uid . $curboard }{'lastposttime'} = 0;
400        }
401
402        $lastposttime = ${ $uid . $curboard }{'lastposttime'};
403
404      # hide hidden threads for ordinary members and guests in all loaded boards
405        if (   !$iammodhere
406            && !$iamadmin
407            && !$iamgmod
408            && !$iamfmod
409            && ${ $uid . $curboard }{'lasttopicstate'} =~ /h/ism )
410        {
411            ${ $uid . $curboard }{'lastpostid'}   = q{};
412            ${ $uid . $curboard }{'lastsubject'}  = q{};
413            ${ $uid . $curboard }{'lastreply'}    = q{};
414            ${ $uid . $curboard }{'lastposter'}   = $boardindex_txt{'470'};
415            ${ $uid . $curboard }{'lastposttime'} = q{};
416            $lastposttime{$curboard} = $boardindex_txt{'470'};
417            my ( $messageid, $messagestate );
418            fopen( MNUM, "$boardsdir/$curboard.txt" );
419            my @threadlist = <MNUM>;
420            fclose(MNUM);
421
422            foreach (@threadlist) {
423                (
424                    $messageid, undef, undef, undef, undef,
425                    undef,      undef, undef, $messagestate
426                ) = split /\|/xsm, $_;
427                if ( $messagestate !~ /h/ism ) {
428                    fopen( FILE, "$datadir/$messageid.txt" ) || next;
429                    my @lastthreadmessages = <FILE>;
430                    fclose(FILE);
431                    my @lastmessage = split /\|/xsm, $lastthreadmessages[-1], 6;
432                    ${ $uid . $curboard }{'lastpostid'}  = $messageid;
433                    ${ $uid . $curboard }{'lastsubject'} = $lastmessage[0];
434                    ${ $uid . $curboard }{'lastreply'}   = $#lastthreadmessages;
435                    ${ $uid . $curboard }{'lastposter'} =
436                      $lastmessage[4] eq 'Guest'
437                      ? qq~Guest-$lastmessage[1]~
438                      : $lastmessage[4];
439                    ${ $uid . $curboard }{'lastposttime'} = $lastmessage[3];
440                    $lastposttime{$curboard} = timeformat( $lastmessage[3] );
441                    $lastposttime{$curboard2} = timeformat( $lastmessage[3],0,0,0,1 );
442                    last;
443                }
444            }
445        }
446
447        ${ $uid . $curboard }{'lastposttime'} =
448          ( ${ $uid . $curboard }{'lastposttime'} eq 'N/A'
449              || !${ $uid . $curboard }{'lastposttime'} )
450          ? $boardindex_txt{'470'}
451          : ${ $uid . $curboard }{'lastposttime'};
452        if (   ${ $uid . $curboard }{'lastposttime'} ne 'N/A'
453            && ${ $uid . $curboard }{'lastposttime'} > 0 )
454        {
455            $lastposttime{$curboard} =
456              timeformat( ${ $uid . $curboard }{'lastposttime'} );
457            $lastposttime{$curboard2} =
458              timeformat( ${ $uid . $curboard }{'lastposttime'},0,0,0,1 );
459        }
460        else { $lastposttime{$curboard} = $boardindex_txt{'470'}; }
461
462        $lastpostrealtime{$curboard} =
463          ( ${ $uid . $curboard }{'lastposttime'} eq 'N/A'
464              || !${ $uid . $curboard }{'lastposttime'} )
465          ? 0
466          : ${ $uid . $curboard }{'lastposttime'};
467
468        $lsreply{$curboard} = ${ $uid . $curboard }{'lastreply'} + 1;
469        if ( ${ $uid . $curboard }{'lastposter'} =~ m{\AGuest-(.*)}xsm ) {
470            ${ $uid . $curboard }{'lastposter'} = $1 . " ($maintxt{'28'})";
471            $lastposterguest{$curboard} = 1;
472        }
473
474        ${ $uid . $curboard }{'lastposter'} =
475          ${ $uid . $curboard }{'lastposter'} eq 'N/A'
476          || !${ $uid . $curboard }{'lastposter'}
477          ? $boardindex_txt{'470'}
478          : ${ $uid . $curboard }{'lastposter'};
479
480        ${ $uid . $curboard }{'messagecount'} =
481          ${ $uid . $curboard }{'messagecount'} || 0;
482
483        ${ $uid . $curboard }{'threadcount'} =
484          ${ $uid . $curboard }{'threadcount'} || 0;
485
486        $totalm += ${ $uid . $curboard }{'messagecount'};
487        $totalt += ${ $uid . $curboard }{'threadcount'};
488
489        if (
490              !$iamguest
491            && $max_log_days_old
492            && $lastpostrealtime{$curboard}
493            && (
494                (
495                      !$yyuserlog{$curboard}
496                    && $lastpostrealtime{$curboard} > $dmax
497                )
498                || (   $yyuserlog{$curboard} > $dmax
499                    && $yyuserlog{$curboard} < $lastpostrealtime{$curboard} )
500            )
501          )
502        {
503            $new_boards{$curboard} = 1;
504        }
505
506        # determine the true last post on all the boards a user has access to
507        if ( ${ $uid . $curboard }{'lastposttime'} > $lastthreadtime
508            && $lastposttime{$curboard} ne $boardindex_txt{'470'} )
509        {
510            my $cookiename = "$cookiepassword$curboard$username";
511            my $crypass    = ${ $uid . $curboard }{'brdpassw'};
512            if ( !${ $uid . $curboard }{'brdpasswr'} ) {
513                $lsdatetime     = $lastposttime{$curboard2};
514                $lsposter       = ${ $uid . $curboard }{'lastposter'};
515                $lssub          = ${ $uid . $curboard }{'lastsubject'};
516                $lspostid       = ${ $uid . $curboard }{'lastpostid'};
517                $lsreply        = ${ $uid . $curboard }{'lastreply'};
518                $lastthreadtime = ${ $uid . $curboard }{'lastposttime'};
519                $lspostbd       = $curboard;
520            }
521            elsif ( $yyCookies{$cookiename} eq $crypass || $staff ) {
522                $lsdatetime     = $lastposttime{$curboard2};
523                $lsposter       = ${ $uid . $curboard }{'lastposter'};
524                $lssub          = ${ $uid . $curboard }{'lastsubject'};
525                $lspostid       = ${ $uid . $curboard }{'lastpostid'};
526                $lsreply        = ${ $uid . $curboard }{'lastreply'};
527                $lastthreadtime = ${ $uid . $curboard }{'lastposttime'};
528                $lspostbd       = $curboard;
529            }
530        }
531    }
532
533# make a copy of new boards has to update the tree if a sub board has a new post, but keep original so we know which individual boards are new
534    my %new_icon = %new_boards;
535
536    # count boards to see if we print anything when we're looking for subboards
537    my $brd_count;
538    LoadCensorList();
539    foreach my $catid (@tmplist) {
540        if (   $INFO{'catselect'} ne $catid
541            && $INFO{'catselect'}
542            && !$subboard_sel )
543        {
544            next;
545        }
546
547        my ( $catname, $catperms, $catallowcol, $catimage, $catrss );
548
549        # get boards in category if we're not looking for subboards
550        if ( !$subboard_sel ) {
551            (@bdlist) = split /\,/xsm, $cat{$catid};
552            ( $catname, $catperms, $catallowcol, $catimage, $catrss ) =
553              split /\|/xsm, $catinfo{$catid};
554            ToChars($catname);
555
556            # Category Permissions Check
557            $cataccess = CatAccess($catperms);
558            if ( !$cataccess ) { next; }
559        }
560        else {
561            (@bdlist) = split /\|/xsm, $subboard{$catid};
562            my ( $boardname, $boardperms, $boardview ) =
563              split /\|/xsm, $board{$catid};
564            ToChars($boardname);
565            ( $catname, $catperms, $catallowcol, $catimage ) =
566              ( qq~$boardindex_txt{'65'} '$boardname'~, 0, 0, q{} );
567        }
568
569        # Skip any empty categories.
570        if ( $cat_boardcnt{$catid} == 0 && !$subboard_sel ) { next; }
571
572        if ( !$iamguest ) {
573            my $newmsg = 0;
574            $newms{$catname}       = q{};
575            $newrowicon{$catname}  = q{};
576            $newrowstart{$catname} = q{};
577            $newrowend{$catname}   = q{};
578            $collapse_link         = q{};
579            $mnew                  = q{};
580
581            if ($catallowcol) {
582                $collapse_link =
583qq~<a href="javascript:SendRequest('$scripturl?action=collapse_cat;cat=$catid','$catid','$imagesdir','$boardindex_exptxt{'2'}','$boardindex_exptxt{'1'}')">~;
584            }
585
586# loop through any collapsed boards to find new posts in it and change the image to match
587# Now shows this whether minimized or not, for Javascript hiding/showing. (Unilat)
588            if ( $INFO{'catselect'} eq q{} ) {
589                foreach my $boardinfo (@goodboards) {
590                    my $testcat;
591                    ( $testcat, $curboard ) = split /\|/xsm, $boardinfo;
592                    if ( $testcat ne $catid ) { next; }
593
594# as we fill the vars based on all boards we need to skip any cat already shown before
595                    if ( $new_icon{$curboard} ) {
596                        my ( undef, $boardperms, $boardview ) =
597                          split /\|/xsm, $board{$curboard};
598                        if ( AccessCheck( $curboard, q{}, $boardperms ) eq
599                            'granted' )
600                        {
601                            $newmsg = 1;
602                        }
603                    }
604                }
605
606                if ($catallowcol) {
607                    $template_catnames .= qq~"$catid",~;
608                    $newrowend{$catname} = $brd_newrowend;
609                    if ( $catcol{$catid} ) {
610                        $my_brdrow = $brd_newrow;
611                        $my_brdrow =~ s/{yabb new_msg_bg}/$new_msg_bg/sm;
612                        $my_brdrow =~ s/{yabb new_msg_class}/$new_msg_class/sm;
613                        $newrowstart{$catname} = $my_brdrow;
614                        $template_boardtable = qq~id="$catid"~;
615                        $template_colboardtable =
616                          qq~id="col$catid" style="display:none"~;
617                    }
618                    else {
619                        $my_brdrow = $brd_newrow;
620                        $my_brdrow =~ s/{yabb new_msg_bg}/$new_msg_bg/sm;
621                        $my_brdrow =~ s/{yabb new_msg_class}/$new_msg_class/sm;
622                        $newrowstart{$catname} = $my_brdrow;
623                        $template_boardtable =
624                          qq~id="$catid" style="display:none;"~;
625                        $template_colboardtable = qq~id="col$catid"~;
626                    }
627                    if ($newmsg) {
628                        $mnew = q{new_} . $curboard;
629                        $newrowicon{$catname} =
630qq~<img src="$imagesdir/$newload{'brd_new'}" alt="$boardindex_txt{'333'}" title="$boardindex_txt{'333'}" class="ongif" id="$mnew" />~;
631                        $newms{$catname} = $boardindex_exptxt{'5'};
632                    }
633                    else {
634                        $newrowicon{$catname} =
635qq~<img src="$imagesdir/$newload{'brd_old'}" alt="$boardindex_txt{'334'}" title="$boardindex_txt{'334'}" class="ongif" />~;
636                        $newms{$catname} = $boardindex_exptxt{'6'};
637                    }
638                    if ( $catcol{$catid} ) {
639                        $hash{$catname} =
640qq~<img src="$imagesdir/$newload{'brd_col'}" id="img$catid" alt="$boardindex_exptxt{'2'}" title="$boardindex_exptxt{'2'}" /></a>~;
641                    }
642                    else {
643                        $hash{$catname} =
644qq~<img src="$imagesdir/$newload{'brd_exp'}" id="img$catid" alt="$boardindex_exptxt{'1'}" title="$boardindex_exptxt{'1'}" /></a>~;
645                    }
646                }
647                else {
648                    $template_boardtable = qq~id="$catid"~;
649                    $template_colboardtable =
650                      qq~id="col$catid" style="display:none;"~;
651                }
652            }
653            else {
654                $collapse_link       = q{};
655                $hash{$catname}      = q{};
656                $template_boardtable = qq~id="$catid"~;
657                $template_colboardtable =
658                  qq~id="col$catid" style="display:none;"~;
659            }
660
661            if ( $cat{$catid} && !$INFO{'board'} ) { $my_cat = 'catselect'; }
662            else                                   { $my_cat = 'boardselect'; }
663            $catlink =
664qq~$collapse_link $hash{$catname} <a href="$scripturl?$my_cat=$catid" title="$boardindex_txt{'797'} $catname">$catname</a>~;
665        }
666        else {
667            if ( $cat{$catid} && !$INFO{'board'} ) { $my_cat = 'catselect'; }
668            else                                   { $my_cat = 'boardselect'; }
669            $template_boardtable    = qq~id="$catid"~;
670            $template_colboardtable = qq~id="col$catid" style="display:none;"~;
671            $catlink = qq~<a href="$scripturl?$my_cat=$catid">$catname</a>~;
672        }
673
674        # Don't need the category headers if we're loading ajax subboards
675        if ( !$INFO{'a'} ) {
676            if ( !$rss_disabled && $catrss ) {
677                $rss_catlink =
678qq~<a href="$scripturl?action=RSSrecent;catselect=$catid" target="_blank"><img src="$micon_bg{'boardrss'}" alt="$maintxt{'rssfeed'} - $catname" title="$maintxt{'rssfeed'} - $catname" /></a>~;
679            }
680            else {
681                $rss_catlink = q{};
682            }
683            $templatecat = $catheader;
684            $tmpcatimg   = q{};
685            $imgid = $brd_img_id{$catid};
686            if ( $catimage ne q{} ) {
687                if ( $catimage =~ /\//ism ) {
688                    $catimage = qq~<img src="$catimage" alt="" id="brd_id_$imgid" onload="resize_brd_images(this);" />~;
689                }
690                elsif ($catimage) {
691                    $catimage = qq~<img src="$imagesdir/$catimage" alt="" id="brd_id_$imgid" onload="resize_brd_images(this);" />~;
692                }
693                $tmpcatimg = qq~$catimage~;
694            }
695            $templatecat =~ s/{yabb catimage}/$tmpcatimg/gsm;
696            $templatecat =~ s/{yabb catrss}/$rss_catlink/gsm;
697            $templatecat =~ s/{yabb catlink}/$catlink/gsm;
698            $templatecat =~ s/{yabb newmsg start}/$newrowstart{$catname}/gsm;
699            $templatecat =~ s/{yabb newmsg icon}/$newrowicon{$catname}/gsm;
700            $templatecat =~ s/{yabb newmsg}/$newms{$catname}/gsm;
701            $templatecat =~ s/{yabb newmsg end}/$newrowend{$catname}/gsm;
702            $templatecat =~ s/{yabb boardtable}/$template_boardtable/gsm;
703            $templatecat =~ s/{yabb colboardtable}/$template_colboardtable/gsm;
704            $tmptemplateblock .= $templatecat;
705        }
706
707        my $alternateboardcolor = 0;
708
709        # Moved this out of for loop. Gets the latest data for sub boards
710        *find_latest_data = sub {
711            my ( $parentbd, @children ) = @_;
712            $childcnt{$parentbd}    = 0;
713            $sub_new_cnt{$parentbd} = 0;
714            foreach my $childbd (@children) {
715
716# make recursive call first so we can get latest post data working from bottom up.
717                if ( $subboard{$childbd} ) {
718                    find_latest_data( $childbd, split /\|/xsm,
719                        $subboard{$childbd} );
720                }
721
722                # don't check sub board if its lastposttime is N/A
723                if ( ${ $uid . $childbd }{'lastposttime'} ne
724                    $boardindex_txt{'470'} )
725                {
726
727                  # update parent board last data if this child's is more recent
728                    if ( $lastpostrealtime{$childbd} >
729                        $lastpostrealtime{$parentbd} )
730                    {
731                        $lastposttime{$parentbd} = $lastposttime{$childbd};
732                        $lastpostrealtime{$parentbd} =
733                          $lastpostrealtime{$childbd};
734                        ${ $uid . $parentbd }{'lastposttime'} =
735                          ${ $uid . $childbd }{'lastposttime'};
736                        ${ $uid . $parentbd }{'lastposter'} =
737                          ${ $uid . $childbd }{'lastposter'};
738                        ${ $uid . $parentbd }{'lastpostid'} =
739                          ${ $uid . $childbd }{'lastpostid'};
740                        ${ $uid . $parentbd }{'lastreply'} =
741                          ${ $uid . $childbd }{'lastreply'};
742                        ${ $uid . $parentbd }{'lastsubject'} =
743                          ${ $uid . $childbd }{'lastsubject'};
744                        ${ $uid . $parentbd }{'lasticon'} =
745                          ${ $uid . $childbd }{'lasticon'};
746                        ${ $uid . $parentbd }{'lasttopicstate'} =
747                          ${ $uid . $childbd }{'lasttopicstate'};
748                    }
749                }
750
751                # Add to totals
752                ${ $uid . $parentbd }{'threadcount'} +=
753                  ${ $uid . $childbd }{'threadcount'};
754                ${ $uid . $parentbd }{'messagecount'} +=
755                  ${ $uid . $childbd }{'messagecount'};
756
757      # but if it's a parent board that can't be posted in, don't add to totals.
758                if ( $subboard{$childbd} && !${ $uid . $childbd }{'canpost'} ) {
759                    ${ $uid . $parentbd }{'threadcount'} -=
760                      ${ $uid . $childbd }{'threadcount'};
761                    ${ $uid . $parentbd }{'messagecount'} -=
762                      ${ $uid . $childbd }{'messagecount'};
763                }
764                if ( $new_icon{$childbd} ) {
765
766                    # parent board gets new status if child has something new
767                    $new_icon{$parentbd} = $new_icon{$childbd};
768
769                    # count sub boards with new posts
770                    $sub_new_cnt{$parentbd}++;
771                }
772
773                $childcnt{$parentbd}++;
774            }
775        };
776        if (  !$INFO{'oldcollapse'}
777            || $catcol{$catid}
778            || $INFO{'catselect'} ne q{}
779            || $iamguest )
780        {    # deti
781            foreach my $boardinfo (@goodboards) {
782                my $testcat;
783                ( $testcat, $curboard ) = split /\|/xsm, $boardinfo;
784                if ( $testcat ne $catid ) { next; }
785
786                $brd_count++;
787
788                # let's add this to javascript array of good boards.
789                $template_boardnames .= qq~"$curboard",~;
790
791# first off, lets find the most recent post data and total sub board posts/threads
792                if ( $subboard{$curboard} ) {
793
794# if its a parent board that cant be posted in, don't count its threads/posts towards total
795                    if ( !${ $uid . $curboard }{'canpost'} ) {
796                        ${ $uid . $curboard }{'threadcount'}  = 0;
797                        ${ $uid . $curboard }{'messagecount'} = 0;
798                    }
799
800                    find_latest_data( $curboard, split /\|/xsm,
801                        $subboard{$curboard} );
802                }
803
804                ( $boardname, $boardperms, $boardview ) =
805                  split /\|/xsm, $board{$curboard};
806                ToChars($boardname);
807                $INFO{'zeropost'} = 0;
808                $zero             = q{};
809                $bdpic = qq~$imagesdir/boards.$bdpicExt~;
810                fopen( BRDPIC, "<$boardsdir/brdpics.db" );
811                my @brdpics = <BRDPIC>;
812                fclose( BRDPIC);
813                chomp @brdpics;
814                for (@brdpics) {
815                    my ( $brdnm, $style, $brdpic ) = split /[|]/xsm, $_;
816                    if ( $brdnm eq $curboard && $usestyle eq $style ) {
817                        if ( $brdpic =~ /\//ism ) {
818                            $bdpic = $brdpic;
819                            last;
820                        }
821                        else {
822                            if ( -e "$htmldir/Templates/Forum/$useimages/Boards/$brdpic" ) {
823                                $bdpic = qq~$imagesdir/Boards/$brdpic~;
824                            }
825                            else { $bdpic = qq~$imagesdir/boards.$bdpicExt~; }
826                            last;
827                        }
828                    }
829                    else {
830                        if ( $boardname =~ m/[ht|f]tp[s]{0,1}:\/\//sm  ) {
831                            $bdpic = qq~$imagesdir/$extern~;
832                        }
833                        else {$bdpic = qq~$imagesdir/boards.$bdpicExt~; }
834                    }
835                }
836
837                if ( ${ $uid . $curboard }{'ann'} == 1 ) {
838                    $bdpic = qq~$imagesdir/ann.$bdpicExt~;
839                }
840                if ( ${ $uid . $curboard }{'rbin'} == 1 ) {
841                    $bdpic = qq~$imagesdir/recycle.$bdpicExt~;
842                }
843                $bddescr          = ${ $uid . $curboard }{'description'};
844                ToChars($bddescr);
845                $iammod     = q{};
846                %moderators = ();
847                my $curmods = ${ $uid . $curboard }{'mods'};
848
849                foreach my $curuser ( split /, ?/sm, $curmods ) {
850                    if ( $username eq $curuser ) { $iammod = 1; }
851                    LoadUser($curuser);
852                    $moderators{$curuser} = ${ $uid . $curuser }{'realname'};
853                }
854                $showmods = q{};
855                if ( keys %moderators == 1 ) {
856                    $showmods = qq~$boardindex_txt{'298'}: ~;
857                }
858                elsif ( keys %moderators != 0 ) {
859                    $showmods = qq~$boardindex_txt{'63'}: ~;
860                }
861                while ( $tmpa = each %moderators ) {
862                    FormatUserName($tmpa);
863                    $showmods .= QuickLinks( $tmpa, 1 ) . q{, };
864                }
865                $showmods =~ s/, \Z//sm;
866
867                LoadUser($username);
868                %moderatorgroups = ();
869                foreach my $curgroup ( split /, /sm,
870                    ${ $uid . $curboard }{'modgroups'} )
871                {
872                    if ( ${ $uid . $username }{'position'} eq $curgroup ) {
873                        $iammod = 1;
874                    }
875                    foreach ( split /,/xsm, ${ $uid . $username }{'addgroups'} )
876                    {
877                        if ( $_ eq $curgroup ) { $iammod = 1; last; }
878                    }
879                    ( $thismodgrp, undef ) =
880                      split /\|/xsm, $NoPost{$curgroup}, 2;
881                    $moderatorgroups{$curgroup} = $thismodgrp;
882                }
883
884                $showmodgroups = q{};
885                if ( scalar keys %moderatorgroups == 1 ) {
886                    $showmodgroups = qq~$boardindex_txt{'298a'}: ~;
887                }
888                elsif ( scalar keys %moderatorgroups != 0 ) {
889                    $showmodgroups = qq~$boardindex_txt{'63a'}: ~;
890                }
891                while ( $tmpa = each %moderatorgroups ) {
892                    $showmodgroups .= qq~$moderatorgroups{$tmpa}, ~;
893                }
894                $showmodgroups =~ s/, \Z//sm;
895                if ( $showmodgroups eq q{} && $showmods eq q{} ) {
896                    $showmodgroups = q~<br />~;
897                }
898                if ( $showmodgroups ne q{} && $showmods ne q{} ) {
899                    $showmods .= q~<br />~;
900                }
901
902                if ($iamguest) {
903                    $new  = q{};
904                    $new2 = q{};
905                }
906                elsif ( $new_icon{$curboard} ) {
907                    my ( undef, $boardperms, $boardview ) =
908                      split /\|/xsm, $board{"$curboard"};
909                    if ( AccessCheck( $curboard, q{}, $boardperms ) eq
910                        'granted' )
911                    {
912                        $mnew = q{new_} . $curboard;
913                        $new =
914qq~<img src="$imagesdir/$newload{'brd_new'}" alt="$boardindex_txt{'333'}" title="$boardindex_txt{'333'}" class="img_new" id="$mnew" />~;
915                        $new2 =
916qq~<img src="$imagesdir/$newload{'sub_brd_new'}" alt="$boardindex_txt{'333'}" title="$boardindex_txt{'333'}" class="img_new" id="$mnew" />~;
917
918                    }
919                    else {
920                        $new =
921qq~<img src="$imagesdir/$newload{'brd_old'}" alt="$boardindex_txt{'334'}" title="$boardindex_txt{'334'}" class="img_new" />~;
922                    }
923                }
924                else {
925                    $new =
926qq~<img src="$imagesdir/$newload{'brd_old'}" alt="$boardindex_txt{'334'}" title="$boardindex_txt{'334'}" />~;
927                }
928                $lastposter = ${ $uid . $curboard }{'lastposter'};
929                $lastposter =~ s/\AGuest-(.*)/$1 ($maintxt{'28'})/ism;
930
931                if ( !$lastposterguest{$curboard}
932                    && ${ $uid . $curboard }{'lastposter'} ne
933                    $boardindex_txt{'470'} )
934                {
935                    LoadUser($lastposter);
936                    if (
937                        (
938                               ${ $uid . $lastposter }{'regdate'}
939                            && ${ $uid . $curboard }{'lastposttime'} >
940                            ${ $uid . $lastposter }{'regtime'}
941                        )
942                        || ${ $uid . $lastposter }{'position'} eq
943                        'Administrator'
944                        || ${ $uid . $lastposter }{'position'} eq
945                        'Global Moderator'
946                      )
947                    {
948                        if ( $iamguest ) {
949                            $lastposter = qq~$format_unbold{$lastposter}~;
950                        }
951                        else {
952                            $lastposter =
953qq~<a href="$scripturl?action=viewprofile;username=$useraccount{$lastposter}" rel="nofollow">$format_unbold{$lastposter}</a>~;
954                        }
955                    }
956                    else {
957
958            # Need to load thread to see lastposters DISPLAYname if is Ex-Member
959                        fopen( EXMEMBERTHREAD,
960                            "$datadir/${$uid.$curboard}{'lastpostid'}.txt" )
961                          or fatal_error( 'cannot_open',
962                            "$datadir/${$uid.$curboard}{'lastpostid'}.txt", 1 );
963                        my @x = <EXMEMBERTHREAD>;
964                        fclose(EXMEMBERTHREAD);
965                        @lstp = split /\|/xsm, $x[-1];
966                        if ( $lstp[4] eq 'Guest') {
967                            $lastposter = qq~$lstp[1] ($maintxt{'28'})~;
968                        }
969                        else { $lastposter = qq~$lstp[1] - $boardindex_txt{'470a'}~; }
970                    }
971                }
972                ${ $uid . $curboard }{'lastposter'} = isempty( ${ $uid . $curboard }{'lastposter'}, $boardindex_txt{'470'} );
973                ${ $uid . $curboard }{'lastposttime'} = isempty( ${ $uid . $curboard }{'lastposttime'}, $boardindex_txt{'470'} );
974
975                my $templateblock = $boardblock;
976
977                # if we can't post in this parent board, change the layout
978                if ( $subboard{$curboard} && !${ $uid . $curboard }{'canpost'} )
979                {
980                    $templateblock = $nopost_boardblock;
981                }
982
983                my $lasttopictxt = ${ $uid . $curboard }{'lastsubject'};
984                ( $lasttopictxt, undef ) =
985                  Split_Splice_Move( $lasttopictxt, 0 );
986                my $fulltopictext = $lasttopictxt;
987
988                $convertstr = $lasttopictxt;
989                $convertcut = $topiccut ? $topiccut : 15;
990                CountChars();
991                $lasttopictxt = $convertstr;
992                if ($cliped) { $lasttopictxt .= q{...}; }
993
994                ToChars($lasttopictxt);
995                $lasttopictxt = Censor($lasttopictxt);
996
997                ToChars($fulltopictext);
998                $fulltopictext = Censor($fulltopictext);
999
1000                if ( ${ $uid . $curboard }{'lastreply'} ne q{} ) {
1001                    $lastpostlink =
1002qq~<a href="$scripturl?num=${$uid.$curboard}{'lastpostid'}/${$uid.$curboard}{'lastreply'}#${$uid.$curboard}{'lastreply'}" title="$boardindex_txt{'22'}">$img{'lastpost'}</a> $lastposttime{$curboard}~;
1003                }
1004                else {
1005                    $lastpostlink = qq~$img{'lastpost'} $boardindex_txt{'470'}~;
1006                }
1007
1008                if ( !$rss_disabled ) {
1009                    my ( undef, $boardperms, $boardview ) = split /\|/xsm,
1010                      $board{"$curboard"};
1011                    if ( AccessCheck( $curboard, q{}, $boardperms ) eq 'granted'
1012                        && ${ $uid . $curboard }{'brdrss'} == 1 )
1013                    {
1014                        $rss_boardlink =
1015qq~<a href="$scripturl?action=RSSboard;board=$curboard" target="_blank"><img src="$micon_bg{'boardrss'}" alt="$maintxt{'rssfeed'} - $boardname" title="$maintxt{'rssfeed'} - $boardname" /></a>~;
1016                    }
1017                    else {
1018                        $rss_boardlink = q{};
1019                    }
1020                }
1021
1022    # if we have subboards, check to see if there's something new and print name
1023                my $template_subboards;
1024                my $tmp_sublist = q{};
1025                my $sub_count;
1026                if ( $subboard{$curboard} ) {
1027                    my @childboards = split /\|/xsm, $subboard{$curboard};
1028                    $tmp_sublist = $subboard_list;
1029                    foreach my $childbd (@childboards) {
1030                        my $tmp_sublinks = $subboard_links_ext;
1031                        my ( $chldboardname, $chldboardperms, $chldboardview ) =
1032                          split /\|/xsm, $board{$childbd};
1033                        my $access =
1034                          AccessCheck( $childbd, q{}, $chldboardperms );
1035                        if (  !$iamadmin
1036                            && $access ne 'granted'
1037                            && $chldboardview != 1 )
1038                        {
1039                            next;
1040                        }
1041                        ToChars($chldboardname);
1042                        $sub_count++;
1043
1044                        $cookiename = "$cookiepassword$childbd$username";
1045                        $crypass    = ${ $uid . $childbd }{'brdpassw'};
1046                        $sub_lock   = q{};
1047                        if ($crypass) {
1048                            if ( $staff || $yyCookies{$cookiename} eq $crypass )
1049                            {
1050                                $sub_lock = qq~ $micon{'lockopen_sub'}~;
1051                            }
1052                            else {
1053                                $sub_lock = qq~ $micon{'lockimg_sub'}~;
1054                            }
1055                        }
1056
1057                        # get new icon
1058                        if ($iamguest) {
1059                            $sub_new = q{};
1060                        }
1061                        elsif ( $new_icon{$childbd} ) {
1062                            $mnew = q{new_} . $childbd . q{_sub};
1063                            $sub_new =
1064qq~<img src="$imagesdir/$newload{'sub_brd_new'}" alt="$boardindex_txt{'333'}" title="$boardindex_txt{'333'}" id="$mnew" />~;
1065                        }
1066                        else {
1067                            $sub_new =
1068qq~<img src="$imagesdir/$newload{'sub_brd_old'}" alt="$boardindex_txt{'334'}" title="$boardindex_txt{'334'}" />~;
1069                        }
1070
1071                        my $boardinfotxt =
1072                            $new_boards{$childbd}
1073                          ? $boardindex_txt{'67'}
1074                          : $boardindex_txt{'68'};
1075                        if ( $subboard{$childbd} ) {
1076                            if ( $childcnt{$childbd} > 1 ) {
1077                                $boardinfotxt .=
1078qq~ $sub_new_cnt{$childbd} $boardindex_txt{'69'} $childcnt{$childbd} $boardindex_txt{'70'}~;
1079                            }
1080                            else {
1081                                if ( $sub_new_cnt{$childbd} ) {
1082                                    $boardinfotxt .=
1083qq~ $childcnt{$childbd} $boardindex_txt{'71'}~;
1084                                }
1085                                else {
1086                                    $boardinfotxt .=
1087qq~ $childcnt{$childbd} $boardindex_txt{'72'}~;
1088                                }
1089                            }
1090                        }
1091
1092                        if ( $chldboardname =~ m/[ht|f]tp[s]{0,1}:\/\//sm ) {
1093                            $tmp_sublinks = $subboard_links_ext;
1094                            $bdd          = q{};
1095                            $my_bddescr   = ${ $uid . $childbd }{'description'};
1096                            my @bname = split /<br \/>/sm, $my_bddescr;
1097                            $boardname = qq~$scripturl\?action\=showexternal;exboard\=$childbd~;
1098                            $tmp_sublinks =~ s/{yabb boardurl}/$boardname/gsm;
1099                            $tmp_sublinks =~ s/{yabb new}/$new/gsm;
1100                            $tmp_sublinks =~ s/{yabb boardname}/$bname[0]/gsm;
1101                            $tmp_sublinks =~ s/{yabb sub_lock}/$sub_lock/gsm;
1102                        }
1103                        else {
1104                            $tmp_sublinks = $subboard_links;
1105                            $tmp_sublinks =~ s/{yabb boardname}/$chldboardname/gsm;
1106                            $tmp_sublinks =~ s/{yabb boardurl}/$scripturl\?board\=$childbd/gsm;
1107                            $tmp_sublinks =~ s/{yabb new}/$sub_new/gsm;
1108                            $tmp_sublinks =~ s/{yabb sub_lock}/$sub_lock/gsm;
1109                            $tmp_sublinks =~ s/{yabb boardinfo}/$boardinfotxt/gsm;
1110                        }
1111                        $template_subboards .= qq~$tmp_sublinks, ~;
1112                    }
1113                    $template_subboards =~ s/, $//gsm;
1114
1115                    my $sub_txt = $boardindex_txt{'64'};
1116
1117                    if ( $sub_count == 1 ) { $sub_txt = $boardindex_txt{'66'}; }
1118                    elsif ( $sub_count == 0 ) {
1119                        $sub_txt     = q{};
1120                        $tmp_sublist = q{};
1121                    }
1122
1123# drop down arrow for expanding sub boards
1124# only do this if 1 or more sub boards and if this is an ajax call we do not want infinite levels of subboards
1125                    my $subdropdown;
1126                    if ( $sub_count > 0 ) {
1127
1128                     # do not make an ajax dropdown if we are calling from ajax.
1129                        if ( $INFO{'a'} ) {
1130                            $subdropdown = qq~$sub_txt~;
1131                        }
1132                        else {
1133                            $subdropdown =
1134qq~<a href="javascript:void(0)" id="subdropa_$curboard" style="font-weight:bold" onclick="SubBoardList('$scripturl?board=$curboard','$curboard','$catid',$sub_count,$alternateboardcolor)"><img src="$imagesdir/$sub_arrow_dn" id="subdropbutton_$curboard" class="sub_drop" alt="" />&nbsp;$sub_txt</a>~;
1135                        }
1136                    }
1137                    $tmp_sublist =~
1138                      s/{yabb subboardlinks}/$template_subboards/gsm;
1139                    $tmp_sublist =~ s/{yabb subdropdown}/$subdropdown/gsm;
1140                }
1141
1142                my $altbrdcolor =
1143                  ( ( $alternateboardcolor % 2 ) == 1 )
1144                  ? 'windowbg'
1145                  : 'windowbg2';
1146                my $boardanchor = $curboard;
1147                if ( $boardanchor =~ m{\A[^az]}ism ) {
1148                    $boardanchor =~ s/(.*?)/b$1/xsm;
1149                }
1150                my $lasttopiclink =
1151qq~<a href="$scripturl?num=${$uid.$curboard}{'lastpostid'}/${$uid.$curboard}{'lastreply'}#${$uid.$curboard}{'lastreply'}" title="$fulltopictext">$lasttopictxt</a>~;
1152                my $boardpwpic = q{};
1153                my $crypass;
1154                if ( ${ $uid . $curboard }{'brdpasswr'} ) {
1155                    my $cookiename = "$cookiepassword$curboard$username";
1156                    $crypass = ${ $uid . $curboard }{'brdpassw'};
1157                    if (  !$staff
1158                        && $yyCookies{$cookiename} ne $crypass )
1159                    {
1160                        $boardpwpic    = qq~$micon{'lockimg'}~;
1161                        $lastpostlink  = qq~$maintxt{'900pr'}~;
1162                        $lasttopiclink = q~~;
1163                        $lastposter    = q~~;
1164                        $templateblock = $boardblockpw;
1165                    }
1166                    else {
1167                        $boardpwpic = qq~$micon{'lockopen'}~;
1168                    }
1169                }
1170                if ( ${ $uid . $curboard }{'threadcount'} < 0 ) {
1171                    ${ $uid . $curboard }{'threadcount'} = 0;
1172                }
1173                if ( ${ $uid . $curboard }{'messagecount'} < 0 ) {
1174                    ${ $uid . $curboard }{'messagecount'} = 0;
1175                }
1176                ${ $uid . $curboard }{'threadcount'} =
1177                  NumberFormat( ${ $uid . $curboard }{'threadcount'} );
1178                ${ $uid . $curboard }{'messagecount'} =
1179                  NumberFormat( ${ $uid . $curboard }{'messagecount'} );
1180
1181# if it's a parent board that cannot be posted in, just show sub board list when clicked vs. message index
1182                if ( $subboard{$curboard} && !${ $uid . $curboard }{'canpost'} )
1183                {
1184                    $templateblock =~ s/{yabb boardurl}/$scripturl\?boardselect\=$curboard/gsm;
1185                }
1186                else {
1187                    $templateblock =~ s/{yabb boardurl}/$scripturl\?board\=$curboard/gsm;
1188                }
1189
1190                # Make hidden table rows for drop down message list
1191                $expandmessages = $brd_expandmessages;
1192                $expandmessages =~ s/{yabb curboard}/$curboard/gsm;
1193                $messagedropdown;
1194                ( $boardname, $boardperms, $boardview ) =
1195                  split /\|/xsm, $board{$curboard};
1196                $access = AccessCheck( $curboard, q{}, $boardperms );
1197                if (   ( $boardperms eq q{} && !$crypass )
1198                    || ( !$iamguest && $access eq 'granted' ) )
1199                {
1200                    $messagedropdown =
1201qq~    <img src="$imagesdir/$brd_dropdown" onclick="MessageList('$scripturl\?board\=$curboard;messagelist=1','$yyhtml_root','$curboard', 0)" id="dropbutton_$curboard" class="cursor" alt="" />~;
1202                }
1203                else { $messagedropdown = q{}; }
1204
1205                $imgid = $brd_img_id{$curboard};
1206                $bdpic =
1207qq~ <img src="$bdpic" alt="$boardname" title="$boardname" id="brd_id_$imgid" onload="resize_brd_images(this);" /> ~;
1208
1209                if ( $boardname !~ m/[ht|f]tp[s]{0,1}:\/\//sm ) {
1210                    $templateblock =~ s/{yabb expandmessages}/$expandmessages/gsm;
1211                    $templateblock =~ s/{yabb messagedropdown}/$messagedropdown/gsm;
1212
1213                    $templateblock =~ s/{yabb boardanchor}/$boardanchor/gsm;
1214                    $templateblock =~ s/{yabb new}/$new/gsm;
1215                    $templateblock =~ s/{yabb boardrss}/$rss_boardlink/gsm;
1216                    $templateblock =~ s/{yabb newsm}/$new2/gsm;
1217                    $templateblock =~ s/{yabb boardpic}/$bdpic/gsm;
1218                    $templateblock =~ s/{yabb boardname}/$boardname $boardpwpic/gsm;
1219                    $templateblock =~ s/{yabb boarddesc}/$bddescr/gsm;
1220                    my $boardviewers;
1221
1222                    if ( $bvusers{$curboard} ) {
1223                        $tmpboardviewers = NumberFormat($bvusers{$curboard});
1224                        $boardviewers = qq~&nbsp;($tmpboardviewers&nbsp;$boardindex_txt{'bviews'})~;
1225                    }
1226                    $templateblock =~ s/{yabb boardviewers}/$boardviewers/gsm;
1227                    $templateblock =~ s/{yabb moderators}/$showmods$showmodgroups/gsm;
1228                    $templateblock =~ s/{yabb threadcount}/${$uid.$curboard}{'threadcount'}/gsm;
1229                    $templateblock =~ s/{yabb messagecount}/${$uid.$curboard}{'messagecount'}/gsm;
1230                    $templateblock =~ s/{yabb lastpostlink}/$lastpostlink/gsm;
1231                    $templateblock =~ s/{yabb lastposter}/$lastposter/gsm;
1232                    $templateblock =~ s/{yabb lasttopiclink}/$lasttopiclink/gsm;
1233                    $templateblock =~ s/{yabb altbrdcolor}/$altbrdcolor/gsm;
1234                    $templateblock =~ s/{yabb subboardlist}/$tmp_sublist/gsm;
1235                }
1236                else {
1237                    $templateblock = $boardblockext;
1238                    $bdd           = q{};
1239                    my @bname = split /<br \/>/sm, $bddescr;
1240                    my $dcnt = @bname;
1241                    for my $i ( 1 .. ( $dcnt - 1 ) ) {
1242                        $bdd .= $bname[$i] . '<br />';
1243                    }
1244                    $boardname =
1245                      qq~$scripturl\?action\=showexternal;exboard\=$curboard~;
1246                    $my_blankext = q{--};
1247                    $templateblock =~ s/{yabb boardurl}/$boardname/gsm;
1248                    $templateblock =~ s/{yabb boardpic}/$bdpic/gsm;
1249                    $templateblock =~ s/{yabb boardname}/$bname[0]/gsm;
1250                    $templateblock =~ s/{yabb boarddesc}/$bdd/gsm;
1251                    $templateblock =~ s/{yabb threadcount}/$my_blankext/gsm;
1252                    $templateblock =~ s/{yabb messagecount}/$my_blankext/gsm;
1253                    $lastpostlink = RedirectExternalShow() || 0;
1254                    $templateblock =~ s/{yabb lastpostlink}/$lastpostlink/gsm;
1255                    $templateblock =~ s/{yabb altbrdcolor}/$altbrdcolor/gsm;
1256                    $templateblock =~ s/{yabb subboardlist}/$tmp_sublist/gsm;
1257                    $templateblock =~ s/{yabb boardanchor}/$curboard/gsm;
1258                }
1259
1260                $tmptemplateblock .= $templateblock;
1261
1262                $alternateboardcolor++;
1263            }
1264        }
1265        $tmptemplateblock .= $INFO{'a'} ? q{} : $catfooter;
1266        ++$catcount;
1267    }
1268
1269    if ( !$iamguest && !$subboard_sel ) {
1270        if ( ${ $uid . $username }{'im_imspop'} ) {
1271            $yymain .= qq~\n\n<script type="text/javascript">
1272    function viewIM() { window.open("$scripturl?action=im"); }
1273    function viewIMOUT() { window.open("$scripturl?action=imoutbox"); }
1274    function viewIMSTORE() { window.open("$scripturl?action=imstorage"); }
1275</script>~;
1276        }
1277        else {
1278            $yymain .= qq~\n\n<script type="text/javascript">
1279    function viewIM() { location.href = ("$scripturl?action=im"); }
1280    function viewIMOUT() { location.href = ("$scripturl?action=imoutbox"); }
1281    function viewIMSTORE() { location.href = ("$scripturl?action=imstorage"); }
1282</script>~;
1283        }
1284        my $imsweredeleted = 0;
1285        if ( ${$username}{'PMmnum'} > $numibox && $numibox && $enable_imlimit )
1286        {
1287            Del_Max_IM( 'msg', $numibox );
1288            $imsweredeleted = ${$username}{'PMmnum'} - $numibox;
1289            $yymain .= qq~\n<script type="text/javascript">
1290    if (confirm('$boardindex_imtxt{'11'} ${$username}{'PMmnum'} $boardindex_imtxt{'12'} $boardindex_txt{'316'}, $boardindex_imtxt{'16'} $numibox $boardindex_imtxt{'18'}. $boardindex_imtxt{'19'} $imsweredeleted $boardindex_imtxt{'20'} $boardindex_txt{'316'} $boardindex_imtxt{'21'}')) viewIM();
1291</script>~;
1292            ${$username}{'PMmnum'} = $numibox;
1293        }
1294        if (   ${$username}{'PMmoutnum'} > $numobox
1295            && $numobox
1296            && $enable_imlimit )
1297        {
1298            Del_Max_IM( 'outbox', $numobox );
1299            $imsweredeleted = ${$username}{'PMmoutnum'} - $numobox;
1300            $yymain .= qq~\n<script type="text/javascript">
1301    if (confirm('$boardindex_imtxt{'11'} ${$username}{'PMmoutnum'} $boardindex_imtxt{'12'} $boardindex_txt{'320'}, $boardindex_imtxt{'16'} $numobox $boardindex_imtxt{'18'}. $boardindex_imtxt{'19'} $imsweredeleted $boardindex_imtxt{'20'} $boardindex_txt{'320'} $boardindex_imtxt{'21'}')) viewIMOUT();
1302</script>~;
1303            ${$username}{'PMmoutnum'} = $numobox;
1304        }
1305        if (   ${$username}{'PMstorenum'} > $numstore
1306            && $numstore
1307            && $enable_imlimit )
1308        {
1309            Del_Max_IM( 'imstore', $numstore );
1310            $imsweredeleted = ${$username}{'PMstorenum'} - $numstore;
1311            $yymain .= qq~\n<script type="text/javascript">
1312if (confirm('$boardindex_imtxt{'11'} ${$username}{'PMstorenum'} $boardindex_imtxt{'12'} $boardindex_imtxt{'46'}, $boardindex_imtxt{'16'} $numstore $boardindex_imtxt{'18'}. $boardindex_imtxt{'19'} $imsweredeleted $boardindex_imtxt{'20'} $boardindex_imtxt{'46'} $boardindex_imtxt{'21'}')) viewIMSTORE();
1313</script>~;
1314            ${$username}{'PMstorenum'} = $numstore;
1315        }
1316        if ($imsweredeleted) {
1317            buildIMS( $username, 'update' );
1318            LoadIMs();
1319        }
1320
1321        $ims    = q{};
1322        $pm_lev = PMlev();
1323        if ( $pm_lev == 1 ) {
1324            $ims =
1325qq~$boardindex_txt{'795'} <a href="$scripturl?action=im"><b>${$username}{'PMmnum'}</b></a> $boardindex_txt{'796'}~;
1326            if ( ${$username}{'PMmnum'} > 0 ) {
1327                if ( ${$username}{'PMimnewcount'} == 1 ) {
1328                    $ims .=
1329qq~ <span class="newPM">$boardindex_imtxt{'24'} <a href="$scripturl?action=im"><b>${$username}{'PMimnewcount'}</b></a> $boardindex_imtxt{'25'}.</span>~;
1330                }
1331                else {
1332                    $ims .=
1333qq~ <span class="newPM">$boardindex_imtxt{'24'} <a href="$scripturl?action=im"><b>${$username}{'PMimnewcount'}</b></a> $boardindex_imtxt{'26'}.</span>~;
1334                }
1335            }
1336            else {
1337                $ims .= q~.~;
1338            }
1339        }
1340
1341        if ( $INFO{'catselect'} eq q{} ) {
1342            if   ($colbutton) { $col_vis = q{}; }
1343            else              { $col_vis = q{ style="display:none;"}; }
1344            if ( ${ $uid . $username }{'cathide'} ) { $exp_vis = q{}; }
1345            else { $exp_vis = q{ style="display:none;"}; }
1346
1347            $expandlink =
1348qq~<span id="expandall" $exp_vis><a href="javascript:Collapse_All('$scripturl?action=collapse_all;status=1',1,'$imagesdir','$boardindex_exptxt{'2'}')">$img{'expand'}</a>$menusep</span>~;
1349            $collapselink =
1350qq~<span id="collapseall" $col_vis><a href="javascript:Collapse_All('$scripturl?action=collapse_all;status=0',0,'$imagesdir','$boardindex_exptxt{'1'}')">$img{'collapse'}</a>$menusep</span>~;
1351            $markalllink =
1352qq~<a href="javascript:MarkAllAsRead('$scripturl?action=markallasread','$imagesdir','0','1')">$img{'markallread'}</a>~;
1353        }
1354        else {
1355            $markalllink =
1356qq~<a href="javascript:MarkAllAsRead('$scripturl?action=markallasread;cat=$INFO{'catselect'}','$imagesdir')">$img{'markallread'}</a>~;
1357            $collapselink = q{};
1358            $expandlink   = q{};
1359        }
1360    }
1361
1362    if ( $totalt < 0 ) { $totalt = 0; }
1363    if ( $totalm < 0 ) { $totalm = 0; }
1364    $totalt = NumberFormat($totalt);
1365    $totalm = NumberFormat($totalm);
1366
1367    # Template some stuff for sub boards before the rest
1368    $boardindex_template =~ s/{yabb catsblock}/$tmptemplateblock/gsm;
1369
1370# no matter if this is ajax subboards, subboards at top of messageindex, or regular boardindex we need these vars now
1371    $brd_img_idw       = isempty( $max_brd_img_width, 50 );
1372    $brd_img_idh       = isempty( $max_brd_img_height, 50 );
1373    $fix_brd_img_size  = isempty( $fix_brd_img_size, 0 );
1374    $template_catnames =~ s/,\Z//xsm;
1375    $template_boardnames =~ s/,\Z//xsm;
1376    $yymain .= qq~
1377<script type="text/javascript">
1378    var catNames = [$template_catnames];
1379    var boardNames = [$template_boardnames];
1380    var boardOpen = "";
1381    var subboardOpen = "";
1382    var arrowup = '<img src="$imagesdir/$brd_arrowup" class="brd_arrow" alt="$boardindex_txt{'643'}" />';
1383    var openbutton = "$imagesdir/$brd_dropdown";
1384    var closebutton = "$imagesdir/$brd_dropup";
1385    var opensubbutton = "$imagesdir/$sub_arrow_dn";
1386    var closesubbutton = "$imagesdir/$sub_arrow_up";
1387    var loadimg = "$imagesdir/$brd_loadbar";
1388    var cachedBoards = new Object();
1389    var cachedSubBoards = new Object();
1390    var curboard = "";
1391    var insertindex;
1392    var insertcat;
1393    var prev_subcount;
1394    var markallreadlang = '$boardindex_txt{'500'}';
1395    var markfinishedlang = '$boardindex_txt{'500a'}';
1396    var markthreadslang = '$boardindex_txt{'500b'}';
1397    var brd_img_idw = $brd_img_idw;
1398    var brd_img_idh = $brd_img_idh;
1399    var fix_brd_size = $fix_brd_img_size;
1400</script>~;
1401
1402    # don't show info center, login, etc. if we're calling from sub boards
1403    if ( !$subboard_sel ) {
1404        $guestson =
1405          qq~<span class="small">$boardindex_txt{'141'}: <b>$guests</b></span>~;
1406        $userson =
1407qq~<span class="small">$boardindex_txt{'142'}: <b>$numusers</b></span>~;
1408        $botson =
1409qq~<span class="small">$boardindex_txt{'143'}: <b>$numbots</b></span>~;
1410
1411        $totalusers = $numusers + $guests;
1412
1413        if ( !-e ("$vardir/mostlog.txt") ) {
1414            fopen( MOSTUSERS, ">$vardir/mostlog.txt" );
1415            print {MOSTUSERS} "$numusers|$date\n"
1416              or croak "$croak{'print'} MOSTUSERS";
1417            print {MOSTUSERS} "$guests|$date\n"
1418              or croak "$croak{'print'} MOSTUSERS";
1419            print {MOSTUSERS} "$totalusers|$date\n"
1420              or croak "$croak{'print'} MOSTUSERS";
1421            print {MOSTUSERS} "$numbots|$date\n"
1422              or croak "$croak{'print'} MOSTUSERS";
1423            fclose(MOSTUSERS);
1424        }
1425        fopen( MOSTUSERS, "$vardir/mostlog.txt" );
1426        @mostentries = <MOSTUSERS>;
1427        fclose(MOSTUSERS);
1428        ( $mostmemb,  $datememb )  = split /\|/xsm, $mostentries[0];
1429        ( $mostguest, $dateguest ) = split /\|/xsm, $mostentries[1];
1430        ( $mostusers, $dateusers ) = split /\|/xsm, $mostentries[2];
1431        ( $mostbots,  $datebots )  = split /\|/xsm, $mostentries[3];
1432        $mostmemb  = ( $mostmemb  || 0 );
1433        $datememb  = ( $datememb  || 0 );
1434        $mostguest = ( $mostguest || 0 );
1435        $dateguest = ( $dateguest || 0 );
1436        $mostusers = ( $mostusers || 0 );
1437        $dateusers = ( $dateusers || 0 );
1438        $mostbots  = ( $mostbots  || 0 );
1439        $datebots  = ( $datebots  || 0 );
1440
1441        chomp $datememb;
1442        chomp $dateguest;
1443        chomp $dateusers;
1444        chomp $datebots;
1445
1446        if (   $numusers > $mostmemb
1447            || $guests > $mostguest
1448            || $numbots > $mostbots
1449            || $totalusers > $mostusers )
1450        {
1451            fopen( MOSTUSERS, ">$vardir/mostlog.txt" );
1452            if ( $numusers > $mostmemb ) {
1453                $mostmemb = $numusers;
1454                $datememb = $date;
1455            }
1456            if ( $guests > $mostguest ) {
1457                $mostguest = $guests;
1458                $dateguest = $date;
1459            }
1460            if ( $totalusers > $mostusers ) {
1461                $mostusers = $totalusers;
1462                $dateusers = $date;
1463            }
1464            if ( $numbots > $mostbots ) {
1465                $mostbots = $numbots;
1466                $datebots = $date;
1467            }
1468            print {MOSTUSERS} "$mostmemb|$datememb\n"
1469              or croak "$croak{'print'} MOSTUSERS";
1470            print {MOSTUSERS} "$mostguest|$dateguest\n"
1471              or croak "$croak{'print'} MOSTUSERS";
1472            print {MOSTUSERS} "$mostusers|$dateusers\n"
1473              or croak "$croak{'print'} MOSTUSERS";
1474            print {MOSTUSERS} "$mostbots|$datebots\n"
1475              or croak "$croak{'print'} MOSTUSERS";
1476            fclose(MOSTUSERS);
1477        }
1478        $themostmembdate  = timeformat($datememb,0,0,0,1);
1479        $themostguestdate = timeformat($dateguest,0,0,0,1);
1480        $themostuserdate  = timeformat($dateusers,0,0,0,1);
1481        $themostbotsdate  = timeformat($datebots,0,0,0,1);
1482        $mostmemb         = NumberFormat($mostmemb);
1483        $mostguest        = NumberFormat($mostguest);
1484        $mostusers        = NumberFormat($mostusers);
1485        $mostbots         = NumberFormat($mostbots);
1486
1487        my $shared_login;
1488        if ($iamguest) {
1489            require Sources::LogInOut;
1490            $sharedLogin_title = q{};
1491            $shared_login      = sharedLogin();
1492        }
1493
1494        my %tmpcolors;
1495        $tmpcnt    = 0;
1496        $grpcolors = q{};
1497
1498        foreach my $stafgrp ( sort keys %Group ) {
1499            ( $title, undef, undef, $color, $noshow, undef ) =
1500              split /\|/xsm, $Group{$stafgrp}, 6;
1501            if ( $color && $noshow != 1 ) {
1502                $tmpcnt++;
1503                $tmpcolors{$tmpcnt} =
1504qq~<div class="grpcolors"><span style="color: $color;"><b>lllll</b></span> $title</div>~;
1505            }
1506        }
1507        foreach (@nopostorder) {
1508            ( $title, undef, undef, $color, $noshow, undef ) =
1509              split /\|/xsm, $NoPost{$_}, 6;
1510            if ( $color && $noshow != 1 ) {
1511                $tmpcnt++;
1512                $tmpcolors{$tmpcnt} =
1513qq~<div class="grpcolors"><span style="color: $color;"><b>lllll</b></span> $title</div>~;
1514            }
1515        }
1516        foreach my $postamount ( reverse sort { $a <=> $b } keys %Post ) {
1517            ( $title, undef, undef, $color, $noshow, undef ) =
1518              split /\|/xsm, $Post{$postamount}, 6;
1519            if ( $color && $noshow != 1 ) {
1520                $tmpcnt++;
1521                $tmpcolors{$tmpcnt} =
1522qq~<div class="grpcolors"><span style="color: $color;"><b>lllll</b></span> $title</div>~;
1523            }
1524        }
1525        $rows = int( ( $tmpcnt / 2 ) + 0.5 );
1526        $col1 = 1;
1527        for ( 1 .. $rows ) {
1528            $col2 = $rows + $col1;
1529            if ( $tmpcolors{$col1} ) { $grpcolors .= qq~$tmpcolors{$col1}~; }
1530            if ( $tmpcolors{$col2} ) { $grpcolors .= qq~$tmpcolors{$col2}~; }
1531            $col1++;
1532        }
1533        undef %tmpcolors;
1534
1535        # Template it
1536        my ( $rss_link, $rss_text );
1537        if ( !$rss_disabled ) {
1538            $rss_link =
1539qq~<a href="$scripturl?action=RSSrecent" target="_blank"><img src="$micon_bg{'rss'}" alt="$maintxt{'rssfeed'}" title="$maintxt{'rssfeed'}" /></a>~;
1540            if ( $INFO{'catselect'} ) {
1541                $rss_link =
1542qq~<a href="$scripturl?action=RSSrecent;catselect=$INFO{'catselect'}" target="_blank"><img src="$micon_bg{'rss'}" alt="$maintxt{'rssfeed'}" title="$maintxt{'rssfeed'}" /></a>~;
1543            }
1544            $rss_text =
1545qq~<a href="$scripturl?action=RSSrecent" target="_blank">$boardindex_txt{'792'}</a>~;
1546            if ( $INFO{'catselect'} ) {
1547                $rss_text =
1548qq~<a href="$scripturl?action=RSSrecent;catselect=$INFO{'catselect'}" target="_blank">$boardindex_txt{'792'}</a>~;
1549            }
1550        }
1551        $yyrssfeed = $rss_text;
1552        $yyrss     = $rss_link;
1553        $boardindex_template =~ s/{yabb rssfeed}/$rss_text/gsm;
1554        $boardindex_template =~ s/{yabb rss}/$rss_link/gsm;
1555
1556        $boardindex_template =~ s/{yabb navigation}/&nbsp;/gsm;
1557        $boardindex_template =~ s/{yabb pollshowcase}/$polltemp/gsm;
1558        $boardindex_template =~ s/{yabb selecthtml}//gsm;
1559
1560        $boardhandellist =~ s/{yabb collapse}/$collapselink/gsm;
1561        $boardhandellist =~ s/{yabb expand}/$expandlink/gsm;
1562        $boardhandellist =~ s/{yabb markallread}/$markalllink/gsm;
1563
1564        $boardindex_template =~ s/{yabb boardhandellist}/$boardhandellist/gsm;
1565        $boardindex_template =~ s/{yabb totaltopics}/$totalt/gsm;
1566        $boardindex_template =~ s/{yabb totalmessages}/$totalm/gsm;
1567
1568### recent/recentopics?##
1569        if ($Show_RecentBar) {
1570            ( $lssub, undef ) = Split_Splice_Move( $lssub, 0 );
1571            ToChars($lssub);
1572            $lssub        = Censor($lssub);
1573            $tmlsdatetime = qq~($lsdatetime).<br />~;
1574            $lastpostlink =
1575qq~$boardindex_txt{'236'} <b><a href="$scripturl?num=$lspostid/$lsreply#$lsreply"><b>$lssub</b></a></b>~;
1576            if ( $Show_RecentBar == 1 || $Show_RecentBar == 3 ) {
1577                $recentl   = 'recent';
1578                $recenttxt = "$boardindex_txt{'792'}";
1579                if ( $maxrecentdisplay > 0 ) {
1580                    $recentpostslink =
1581qq~$boardindex_txt{'791'} <form method="post" action="$scripturl?action=$recentl" name="$recentl" style="display: inline"><select size="1" name="display" onchange="submit()"><option value="">&nbsp;</option>~;
1582                    my ( $x, $y ) = ( int( $maxrecentdisplay / 5 ), 0 );
1583                    if ($x) {
1584                        foreach my $i ( 1 .. 5 ) {
1585                            $y = $i * $x;
1586                            $recentpostslink .=
1587                              qq~<option value="$y">$y</option>~;
1588                        }
1589                    }
1590                    if ( $maxrecentdisplay > $y ) {
1591                        $recentpostslink .=
1592qq~<option value="$maxrecentdisplay">$maxrecentdisplay</option>~;
1593                    }
1594                    $recentpostslink .=
1595qq~</select> <input type="submit" style="display:none" /></form> $recenttxt $boardindex_txt{'793'}~;
1596                }
1597            }
1598            if ( $Show_RecentBar == 2 || $Show_RecentBar == 3 ) {
1599                $recentl_t   = 'recenttopics';
1600                $recenttxt_t = "$boardindex_txt{'792a'}";
1601                if ( $maxrecentdisplay_t > 0 ) {
1602                    $recenttopicslink =
1603qq~$boardindex_txt{'791'} <form method="post" action="$scripturl?action=$recentl_t" name="$recentl_t" style="display: inline"><select size="1" name="display" onchange="submit()"><option value="">&nbsp;</option>~;
1604                    my ( $x, $y ) = ( int( $maxrecentdisplay_t / 5 ), 0 );
1605                    if ($x) {
1606                        foreach my $i ( 1 .. 5 ) {
1607                            $y = $i * $x;
1608                            $recenttopicslink .=
1609                              qq~<option value="$y">$y</option>~;
1610                        }
1611                    }
1612                    if ( $maxrecentdisplay > $y ) {
1613qq~<option value="$maxrecentdisplay_t">$maxrecentdisplay_t</option>~;
1614                    }
1615                    $recenttopicslink .=
1616qq~</select> <input type="submit" style="display:none" /></form> $recenttxt_t $boardindex_txt{'793'}~;
1617                }
1618            }
1619            if ( $Show_RecentBar == 3 && $maxrecentdisplay_t > 0 ) {
1620                $spc = q~<br />~;
1621            }
1622            $boardindex_template =~ s/{yabb lastpostlink}/$lastpostlink/gsm;
1623            $boardindex_template =~ s/{yabb recentposts}/$recentpostslink/gsm;
1624            $boardindex_template =~ s/{yabb spc}/$spc/sm;
1625            $boardindex_template =~ s/{yabb recenttopics}/$recenttopicslink/gsm;
1626            $boardindex_template =~ s/{yabb lastpostdate}/$tmlsdatetime/gsm;
1627        }
1628        else {
1629            $boardindex_template =~ s/{yabb lastpostlink}//gsm;
1630            $boardindex_template =~ s/{yabb recentposts}//gsm;
1631            $boardindex_template =~ s/{yabb recenttopics}//gsm;
1632            $boardindex_template =~ s/{yabb lastpostdate}//gsm;
1633        }
1634        $memcount = NumberFormat($memcount);
1635        $membercountlink =
1636          qq~<a href="$scripturl?action=ml"><b>$memcount</b></a>~;
1637        if ( $iamguest && $ML_Allowed ) {
1638            $membercountlink = qq~<b>$memcount</b>~;
1639        }
1640        $boardindex_template =~ s/{yabb membercount}/$membercountlink/gsm;
1641        if ($showlatestmember) {
1642            LoadUser($latestmember);
1643            $latestmemberlink =
1644                qq~$boardindex_txt{'201'} ~
1645              . QuickLinks($latestmember)
1646              . q~.<br />~;
1647            $boardindex_template =~ s/{yabb latestmember}/$latestmemberlink/gsm;
1648        }
1649        else {
1650            $boardindex_template =~ s/{yabb latestmember}//gsm;
1651        }
1652        $boardindex_template =~ s/{yabb ims}/$ims/gsm;
1653        $boardindex_template =~ s/{yabb guests}/$guestson/gsm;
1654        $boardindex_template =~ s/{yabb users}/$userson/gsm;
1655        $boardindex_template =~ s/{yabb bots}/$botson/gsm;
1656        $boardindex_template =~ s/{yabb onlineusers}/$users/gsm;
1657        $boardindex_template =~ s/{yabb onlineguests}/$guestlist/gsm;
1658        $boardindex_template =~ s/{yabb onlinebots}/$botlist/gsm;
1659        $boardindex_template =~ s/{yabb mostmembers}/$mostmemb/gsm;
1660        $boardindex_template =~ s/{yabb mostguests}/$mostguest/gsm;
1661        $boardindex_template =~ s/{yabb mostbots}/$mostbots/gsm;
1662        $boardindex_template =~ s/{yabb mostusers}/$mostusers/gsm;
1663        $boardindex_template =~ s/{yabb mostmembersdate}/$themostmembdate/gsm;
1664        $boardindex_template =~ s/{yabb mostguestsdate}/$themostguestdate/gsm;
1665        $boardindex_template =~ s/{yabb mostbotsdate}/$themostbotsdate/gsm;
1666        $boardindex_template =~ s/{yabb mostusersdate}/$themostuserdate/gsm;
1667        $boardindex_template =~ s/{yabb groupcolors}/$grpcolors/gsm;
1668        $boardindex_template =~ s/{yabb sharedlogin}/$shared_login/gsm;
1669        $boardindex_template =~ s/{yabb new_load}/$newload/gsm;
1670
1671        # EventCal START
1672        my $cal_display;
1673        if ( $Show_EventCal == 2 || ( !$iamguest && $Show_EventCal == 1 ) ) {
1674            require Sources::EventCal;
1675            $cal_display = eventcal();
1676        }
1677        $boardindex_template =~ s/{yabb caldisplay}/$cal_display/gsm;
1678
1679        # EventCal END
1680
1681        chop $template_catnames;
1682        chop $template_boardnames;
1683        $yymain .= qq~$boardindex_template~;
1684
1685        $yymain .= qq~
1686<script type="text/javascript">
1687    function ListPages(tid) { window.open('$scripturl?action=pages;num='+tid, '', 'menubar=no,toolbar=no,top=50,left=50,scrollbars=yes,resizable=no,width=400,height=300'); }
1688    function ListPages2(bid,cid) { window.open('$scripturl?action=pages;board='+bid+';count='+cid, '', 'menubar=no,toolbar=no,top=50,left=50,scrollbars=yes,resizable=no,width=400,height=300'); }
1689            </script>
1690        ~;
1691
1692        if ( ${$username}{'PMimnewcount'} > 0 ) {
1693            if ( ${$username}{'PMimnewcount'} > 1 ) {
1694                $en  = 's';
1695                $en2 = $boardindex_imtxt{'47'};
1696            }
1697            else { $en = q{}; $en2 = $boardindex_imtxt{'48'}; }
1698
1699            if ( ${ $uid . $username }{'im_popup'} ) {
1700                if ( ${ $uid . $username }{'im_imspop'} ) {
1701                    $yymain .= qq~
1702<script type="text/javascript">
1703    if (confirm("$boardindex_imtxt{'14'} ${$username}{'PMimnewcount'}$boardindex_imtxt{'15'}?")) window.open("$scripturl?action=im","_blank");
1704</script>~;
1705                }
1706                else {
1707                    $yymain .= qq~
1708<script type="text/javascript">
1709    if (confirm("$boardindex_imtxt{'14'} ${$username}{'PMimnewcount'}$boardindex_imtxt{'15'}?")) location.href = ("$scripturl?action=im");
1710</script>~;
1711                }
1712            }
1713        }
1714
1715        LoadBroadcastMessages($username);
1716
1717        # look for new BM
1718        if ($BCnewMessage) {
1719            if ( ${ $uid . $username }{'im_imspop'} ) {
1720                $yymain .= qq~
1721<script type="text/javascript">
1722    if (confirm("$boardindex_imtxt{'50'}$boardindex_imtxt{'51'}?")) window.open("$scripturl?action=im;focus=bmess","_blank");
1723</script>~;
1724            }
1725            else {
1726                $yymain .= qq~
1727<script type="text/javascript">
1728    if (confirm("$boardindex_imtxt{'50'}$boardindex_imtxt{'51'}?")) location.href = ("$scripturl?action=im;focus=bmess");
1729</script>~;
1730            }
1731        }
1732
1733        # Make browsers aware of our RSS
1734        if ( !$rss_disabled ) {
1735            if ( $INFO{'catselect'} ) {    # Handle categories properly
1736                $yyinlinestyle .=
1737qq~    <link rel="alternate" type="application/rss+xml" title="$boardindex_txt{'792'}" href="$scripturl?action=RSSrecent;catselect=$INFO{'catselect'}" />~;
1738            }
1739            else {
1740                $yyinlinestyle .=
1741qq~    <link rel="alternate" type="application/rss+xml" title="$boardindex_txt{'792'}" href="$scripturl?action=RSSrecent" />~;
1742            }
1743        }
1744        template();
1745    }
1746
1747    # end info center, login, etc.
1748
1749    if ( !$INFO{'a'} ) {
1750        if ( $INFO{'boardselect'} ) {
1751            $yymain .= $boardindex_template;
1752
1753            my $boardtree = q{};
1754            $mycat = ${ $uid . $subboard_sel }{'cat'};
1755            ( $mynamecat, undef ) = split /\|/xsm, $catinfo{$mycat};
1756            ToChars($mynamecat);
1757            my $catlinkb =
1758              qq~<a href="$scripturl?catselect=$mycat">$mynamecat</a>~;
1759            my $parentboard = $subboard_sel;
1760
1761            while ($parentboard) {
1762                my ( $pboardname, undef, undef ) =
1763                  split /\|/xsm, $board{$parentboard};
1764                ToChars($pboardname);
1765                $yytitle = $pboardname;
1766                if ( ${ $uid . $parentboard }{'canpost'}
1767                    || !$subboard{$parentboard} )
1768                {
1769                    $pboardname =
1770qq~<a href="$scripturl?board=$parentboard" class="a"><b>$pboardname</b></a>~;
1771                }
1772                else {
1773                    $pboardname =
1774qq~<a href="$scripturl?boardselect=$parentboard;subboards=1" class="a"><b>$pboardname</b></a>~;
1775                }
1776                $boardtree =
1777                  qq~ &rsaquo; $catlinkb &rsaquo; $pboardname$boardtree~;
1778                $parentboard = ${ $uid . $parentboard }{'parent'};
1779            }
1780
1781            $yynavigation .= qq~$boardtree~;
1782            template();
1783        }
1784        elsif ($subboard_sel) {
1785            if ($brd_count) {
1786                $boardindex_template = qq~
1787                        <script type="text/javascript">
1788                        var catNames = [$template_catnames];
1789                        var boardNames = [$template_boardnames];
1790                        var boardOpen = "";
1791                        var subboardOpen = "";
1792                        var arrowup = '<img src="$imagesdir/$brd_arrowup" class="brd_arrow" alt="$boardindex_txt{'643'}" />';
1793                        var openbutton = "$imagesdir/$brd_dropdown";
1794                        var closebutton = "$imagesdir/$brd_dropup";
1795                        var loadimg = "$imagesdir/$brd_loadbar";
1796                        var cachedBoards = new Object();
1797                        var cachedSubBoards = new Object();
1798                        var curboard = "";
1799                        var insertindex;
1800                        var insertcat;
1801                        var prev_subcount;
1802                        </script>
1803                        $boardindex_template
1804~;
1805            }
1806        }
1807    }
1808    else {
1809        print "Content-type: text/html; charset=$yymycharset\n\n"
1810          or croak "$croak{'print'} charset";
1811        print qq~
1812            <table id="subloaded_$INFO{'board'}" style="display:none">
1813            $boardindex_template
1814            </table>
1815        ~ or croak "$croak{'print'} table";
1816        CORE::exit;    # This is here only to avoid server error log entries!
1817    }
1818
1819    # cannot have return here - breaks subboard display;
1820}
1821
1822sub GetBotlist {
1823    if ( -e "$vardir/bots.hosts" ) {
1824        fopen( BOTS, "$vardir/bots.hosts" )
1825          or fatal_error( 'cannot_open', "$vardir/bots.hosts", 1 );
1826        my @botlist = <BOTS>;
1827        fclose(BOTS);
1828        chomp @botlist;
1829        foreach (@botlist) {
1830            if ( $_ =~ /(.*?)\|(.*)/xsm ) {
1831                push @all_bots, $1;
1832                $bot_name{$1} = $2;
1833            }
1834        }
1835    }
1836    return;
1837}
1838
1839sub Is_Bot {
1840    my ($bothost) = @_;
1841    foreach (@all_bots) { return $bot_name{$_} if $bothost =~ /$_/ism; }
1842    return;
1843}
1844
1845sub Collapse_Write {
1846    my @userhide;
1847
1848    # rewrite the category hash for the user
1849    foreach my $key (@categoryorder) {
1850        my ( $catname, $catperms, $catallowcol ) =
1851          split /\|/xsm, $catinfo{$key};
1852        $access = CatAccess($catperms);
1853        if ( $catcol{$key} == 0 && $access ) { push @userhide, $key; }
1854    }
1855    ${ $uid . $username }{'cathide'} = join q{,}, @userhide;
1856    UserAccount( $username, 'update' );
1857    if ( -e "$memberdir/$username.cat" ) {
1858        unlink "$memberdir/$username.cat";
1859    }
1860    return;
1861}
1862
1863sub Collapse_Cat {
1864    if ($iamguest) { fatal_error('collapse_no_member'); }
1865    my $changecat = $INFO{'cat'};
1866    if ( !$colloaded ) { Collapse_Load(); }
1867
1868    if ( $catcol{$changecat} == 1 ) {
1869        $catcol{$changecat} = 0;
1870    }
1871    else {
1872        $catcol{$changecat} = 1;
1873    }
1874    Collapse_Write();
1875    if ( $INFO{'oldcollapse'} ) {
1876        $yySetLocation = $scripturl;
1877        redirectexit();
1878    }
1879    $elenable = 0;
1880    croak q{};    # This is here only to avoid server error log entries!
1881}
1882
1883sub Collapse_All {
1884    my $state = $INFO{'status'};
1885
1886    if ($iamguest) { fatal_error('collapse_no_member'); }
1887    if ( $state != 1 && $state != 0 ) {
1888        fatal_error('collapse_invalid_state');
1889    }
1890
1891    foreach my $key (@categoryorder) {
1892        my ( $catname, $catperms, $catallowcol ) =
1893          split /\|/xsm, $catinfo{$key};
1894        if ( $catallowcol eq '1' ) {
1895            $catcol{$key} = $state;
1896        }
1897        else {
1898            $catcol{$key} = 1;
1899        }
1900    }
1901    Collapse_Write();
1902    if ( $INFO{'oldcollapse'} ) {
1903        $yySetLocation = $scripturl;
1904        redirectexit();
1905    }
1906    $elenable = 0;
1907    croak q{};    # This is here only to avoid server error log entries!
1908}
1909
1910sub MarkAllRead {    # Mark all boards as read.
1911    get_forum_master();
1912
1913    my @cats = ();
1914    if ( $INFO{'cat'} ) {
1915        @cats = ( $INFO{'cat'} );
1916        $INFO{'catselect'} = $INFO{'cat'};
1917    }
1918    else { @cats = @categoryorder; }
1919
1920    # Load the whole log
1921    getlog();
1922
1923    *recursive_mark = sub {
1924        my @x = @_;
1925        foreach my $board (@x) {
1926
1927            # Security check
1928            if (
1929                AccessCheck(
1930                    $board, q{}, ( split /\|/xsm, $board{$board} )[1]
1931                ) ne 'granted'
1932              )
1933            {
1934                delete $yyuserlog{"$board--mark"};
1935                delete $yyuserlog{$board};
1936            }
1937            else {
1938
1939                # Mark it
1940                $yyuserlog{"$board--mark"} = $date;
1941                $yyuserlog{$board} = $date;
1942            }
1943
1944            # make recursive call if this board has more children
1945            if ( $subboard{$board} ) {
1946                recursive_mark( split /\|/xsm, $subboard{$board} );
1947            }
1948        }
1949    };
1950
1951    foreach my $catid (@cats) {
1952
1953        # Security check
1954        if ( !CatAccess( ( split /\|/xsm, $catinfo{$catid} )[1] ) ) {
1955            foreach my $board ( split /\,/xsm, $cat{$catid} ) {
1956                delete $yyuserlog{"$board--mark"};
1957                delete $yyuserlog{$board};
1958            }
1959            next;
1960        }
1961
1962        recursive_mark( split /\,/xsm, $cat{$catid} );
1963    }
1964
1965    # Write it out
1966    dumplog();
1967
1968    if ( $INFO{'oldmarkread'} ) {
1969        redirectinternal();
1970    }
1971    $elenable = 0;
1972    croak q{};    # This is here only to avoid server error log entries!
1973}
1974
1975sub gostRemove {
1976    my ( $thecat, $gostboard ) = @_;
1977    get_forum_master();
1978    (@gbdlist) = split /\,/xsm, $cat{$thecat};
1979    $tmp_master = q{};
1980    foreach my $item (@gbdlist) {
1981        if ( $item ne $gostboard ) {
1982            $tmp_master .= qq~$item,~;
1983        }
1984    }
1985    $tmp_master =~ s/,\Z//xsm;
1986    $cat{$thecat} = $tmp_master;
1987    Write_ForumMaster();
1988    return;
1989}
1990
1991sub Del_Max_IM {
1992    my ( $ext, $max ) = @_;
1993    fopen( DELMAXIM, "<$memberdir/$username.$ext" );
1994    my @IMmessages = <DELMAXIM>;
1995    fclose(DELMAXIM);
1996    splice @IMmessages, $max;
1997
1998    fopen( DELMAXIM, ">$memberdir/$username.$ext" );
1999    print {DELMAXIM} @IMmessages or croak "$croak{'print'} DELMAXIM";
2000    fclose(DELMAXIM);
2001    return;
2002}
2003
2004sub RedirectExternalShow {
2005    my $exboard = $INFO{'exboard'} || $curboard;
2006    fopen( COUNT, "$boardsdir/$exboard.exhits" );
2007    $excount = <COUNT>;
2008    chomp $excount;
2009    fclose(COUNT);
2010
2011    if ( $INFO{'action'} eq 'showexternal' ) {
2012        my $link = ( split /\|/xsm, $board{$exboard} )[0];
2013        if   ($excount) { $excount++; }
2014        else            { $excount = 1; }
2015        fopen( COUNT, ">$boardsdir/$exboard.exhits" );
2016        seek COUNT, 0, 0;
2017        print {COUNT} "$excount" or croak "$croak{'print'} COUNT";
2018        fclose(COUNT);
2019        print "Content-type: text/html\n" or croak "$croak{'print'} top";
2020        print "Location: $link\n\n"       or croak "$croak{'print'} link";
2021        exit;
2022    }
2023    else {
2024        return $excount;
2025    }
2026}
2027
20281;
2029