1###############################################################################
2# Recent.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;
17# no warnings qw(uninitialized once);
18use CGI::Carp qw(fatalsToBrowser);
19our $VERSION = '2.6.11';
20
21# from YaBB3.0 build 100 #
22$recentpmver = 'YaBB 2.6.11 $Revision: 1611 $';
23if ( $action eq 'detailedversion' ) { return 1; }
24
25# Sub RecentTopics shows all the most recently posted topics
26# Meaning each thread will show up ONCE in the list.
27
28# Sub RecentPosts will show the X last POSTS
29# Even if they are all from the same thread
30get_template('Display');
31
32sub RecentPosts {
33    spam_protection();
34
35    my $display = isempty( $FORM{'display'}, 10 );
36    if ( $display < 0 ) { $display = 5; }
37    elsif ( $display > $maxrecentdisplay ) { $display = $maxrecentdisplay; }
38
39    $numfound = 0;
40
41    get_forum_master();
42
43    *recursive_check2 = sub {
44        foreach my $curboard (@_) {
45            ( $boardname{$curboard}, $boardperms, $boardview ) =
46              split /\|/xsm, $board{$curboard};
47
48            my $access = AccessCheck( $curboard, q{}, $boardperms );
49            if ( !$iamadmin && $access ne 'granted' ) { next; }
50
51            if ( ${ $uid . $curboard }{'brdpasswr'} ) {
52                my $bdmods = ${ $uid . $curboard }{'mods'};
53                $bdmods =~ s/\, /\,/gsm;
54                $bdmods =~ s/\ /\,/gsm;
55                my %moderators = ();
56                my $pswiammod  = 0;
57                foreach my $curuser ( split /\,/xsm, $bdmods ) {
58                    if ( $username eq $curuser ) { $pswiammod = 1; }
59                }
60                my $bdmodgroups = ${ $uid . $curboard }{'modgroups'};
61                $bdmodgroups =~ s/\, /\,/gsm;
62                my %moderatorgroups = ();
63                foreach my $curgroup ( split /\,/xsm, $bdmodgroups ) {
64                    if ( ${ $uid . $username }{'position'} eq $curgroup ) {
65                        $pswiammod = 1;
66                    }
67                    foreach my $memberaddgroups ( split /\, /sm,
68                        ${ $uid . $username }{'addgroups'} )
69                    {
70                        chomp $memberaddgroups;
71                        if ( $memberaddgroups eq $curgroup ) {
72                            $pswiammod = 1;
73                            last;
74                        }
75                    }
76                }
77                my $cookiename = "$cookiepassword$curboard$username";
78                my $crypass    = ${ $uid . $curboard }{'brdpassw'};
79                if (   !$iamadmin
80                    && !$iamgmod
81                    && !$pswiammod
82                    && $yyCookies{$cookiename} ne $crypass )
83                {
84                    next;
85                }
86            }
87
88            $catid{$curboard}   = $catid;
89            $catname{$curboard} = $catname;
90
91            fopen( REC_BDTXT, "$boardsdir/$curboard.txt" );
92            @buffer = <REC_BDTXT>;
93            for my $i ( 0 .. ( $display - 1 ) ) {
94                if ( $buffer[$i] ) {
95                    (
96                        $tnum,      $tsub,  $tname,
97                        $temail,    $tdate, $treplies,
98                        $tusername, $ticon, $tstate
99                    ) = split /\|/xsm, $buffer[$i];
100                    chomp $tstate;
101                    if ( $tstate !~ /h/sm || $iamadmin || $iamgmod ) {
102                        $mtime = $tdate;
103                        $data[$numfound] =
104"$mtime|$curboard|$tnum|$treplies|$tusername|$tname|$tstate";
105                        $numfound++;
106                    }
107                }
108            }
109            fclose(REC_BDTXT);
110
111            if ( $subboard{$curboard} ) {
112                recursive_check2( split /\|/xsm, $subboard{$curboard} );
113            }
114        }
115    };
116
117    foreach my $catid (@categoryorder) {
118
119        (@bdlist) = split /\,/xsm, $cat{$catid};
120
121        ( $catname, $catperms ) = split /\|/xsm, $catinfo{$catid};
122        $cataccess = CatAccess($catperms);
123        if ( !$cataccess ) { next; }
124
125        recursive_check2(@bdlist);
126    }
127    @data = reverse sort { $a cmp $b } @data;
128
129    $numfound = 0;
130    $threadfound = @data > $display ? $display : @data;
131
132    for my $i ( 0 .. ( $threadfound - 1 ) ) {
133        ( $mtime, $curboard, $tnum, $treplies, $tusername, $tname, $tstate ) =
134          split /\|/xsm, $data[$i];
135
136        # No need to check for hidden topics here, it was done above
137        $tstart = $mtime;
138        fopen( REC_THRETXT, "$datadir/$tnum.txt" ) || next;
139        @mess = <REC_THRETXT>;
140        fclose(REC_THRETXT);
141
142        $threadfrom = @mess > $display ? @mess - $display : 0;
143        for my $c ( $threadfrom .. @mess ) {
144            if ( $mess[$c] ) {
145                (
146                    $msub,  $mname,   $memail, $mdate,   $musername,
147                    $micon, $mattach, $mip,    $message, $mns
148                ) = split /\|/xsm, $mess[$c];
149                $mtime = $mdate;
150                $messages[$numfound] =
151"$mtime|$curboard|$tnum|$c|$tusername|$tname|$msub|$mname|$memail|$mdate|$musername|$micon|$mattach|$mip|$message|$mns|$tstate|$tstart";
152                $numfound++;
153            }
154        }
155    }
156
157    @messages = reverse sort { $a cmp $b } @messages;
158
159    if ( $numfound > 0 ) {
160        if ( $numfound > $display ) { $numfound = $display; }
161        LoadCensorList();
162    }
163    else {
164        $yymain .= qq~<hr class="hr"><b>$maintxt{'170'}</b><hr />~;
165    }
166
167    for my $i ( 0 .. ( $numfound - 1 ) ) {
168        (
169            $dummy,   $board, $tnum,    $c,     $tusername, $tname,
170            $msub,    $mname, $memail,  $mdate, $musername, $micon,
171            $mattach, $mip,   $message, $mns,   $tstate,    $trstart
172        ) = split /\|/xsm, $messages[$i];
173        $displayname = $mname;
174
175        if ( $tusername ne 'Guest' && -e ("$memberdir/$tusername.vars") ) {
176            LoadUser($tusername);
177        }
178        if ( ${ $uid . $tusername }{'regtime'} ) {
179            $registrationdate = ${ $uid . $tusername }{'regtime'};
180        }
181        else {
182            $registrationdate = $date;
183        }
184
185        if ( ${ $uid . $tusername }{'regdate'} && $trstart > $registrationdate )
186        {
187            if ( $iamguest ) {
188                $tname = qq~$format_unbold{$tusername}~;
189            }
190            else {
191                $tname =
192qq~<a href="$scripturl?action=viewprofile;username=$useraccount{$tusername}" rel="nofollow">$format_unbold{$tusername}</a>~;
193            }
194        }
195        elsif ( $tusername !~ m{Guest}sm && $trstart < $registrationdate ) {
196            $tname = qq~$tname - $maintxt{'470a'}~;
197        }
198        else {
199            $tname = "$tname ($maintxt{'28'})";
200        }
201
202        if ( $musername ne 'Guest' && -e ("$memberdir/$musername.vars") ) {
203            LoadUser($musername);
204        }
205        if ( ${ $uid . $musername }{'regtime'} ) {
206            $registrationdate = ${ $uid . $musername }{'regtime'};
207        }
208        else {
209            $registrationdate = $date;
210        }
211
212        if ( ${ $uid . $musername }{'regdate'} && $mdate > $registrationdate ) {
213            if ( $iamguest ) {
214                $mname = qq~$format_unbold{$musername}~;
215            }
216            else {
217                $mname =
218qq~<a href="$scripturl?action=viewprofile;username=$useraccount{$musername}" rel="nofollow">$format_unbold{$musername}</a>~;
219            }
220        }
221        elsif ( $musername !~ m{Guest}sm && $mdate < $registrationdate ) {
222            $mname = qq~$mname - $maintxt{'470a'}~;
223        }
224        else {
225            $mname = "$mname ($maintxt{'28'})";
226        }
227
228        wrap();
229        $movedflag = q{};
230        ( $message, $movedflag ) = Split_Splice_Move( $message, $tnum );
231        if ($enable_ubbc) {
232            $ns = $mns;
233            enable_yabbc();
234            DoUBBC();
235        }
236        wrap2();
237        ToChars($message);
238        $message = Censor($message);
239
240        ( $msub, undef ) = Split_Splice_Move( $msub, 0 );
241        ToChars($msub);
242        $msub = Censor($msub);
243
244        if ($iamguest) {
245            $notify = q{};
246        }
247        else {
248            if ( ${ $uid . $username }{'thread_notifications'} =~
249                /\b$tnum\b/xsm )
250            {
251                $notify =
252qq~$menusep<a href="$scripturl?action=notify3;num=$tnum/$c;oldnotify=1">$img{'del_notify'}</a>~;
253            }
254            else {
255                $notify =
256qq~$menusep<a href="$scripturl?action=notify2;num=$tnum/$c;oldnotify=1">$img{'add_notify'}</a>~;
257            }
258        }
259        $mdate = timeformat($mdate);
260
261        # generate a sub board tree
262        my $boardtree   = q{};
263        my $parentboard = $board;
264        while ($parentboard) {
265            my ( $pboardname, undef, undef ) =
266              split /\|/xsm, $board{$parentboard};
267            if ( ${ $uid . $parentboard }{'canpost'}
268                || !$subboard{$parentboard} )
269            {
270                $pboardname =
271qq~<a href="$scripturl?board=$parentboard"><span class="under">$pboardname</span></a>~;
272            }
273            else {
274                $pboardname =
275qq~<a href="$scripturl?boardselect=$parentboard;subboards=1"><span class="under">$pboardname</span></a>~;
276            }
277            $boardtree   = qq~ / $pboardname$boardtree~;
278            $my_cat      = ${ $uid . $parentboard }{'cat'};
279            $parentboard = ${ $uid . $parentboard }{'parent'};
280        }
281        $counter = $i + 1;
282
283        if ( $tstate != 1 && ( !$iamguest || $enable_guestposting ) ) {
284            $my_tstate = $myrecent_mess;
285            $my_tstate =~ s/{yabb tnum}/$tnum/gsm;
286            $my_tstate =~ s/{yabb c}/$c/gsm;
287        }
288
289        $yymain .= $myrecent;
290        $yymain =~ s/{yabb counter}/$counter/sm;
291        $yymain =~ s/{yabb catbrd}/$my_cat/sm;
292        $yymain =~ s/{yabb catname}/$catname{$board}/sm;
293        $yymain =~ s/{yabb boardtree}/$boardtree/sm;
294        $yymain =~ s/{yabb tnum}/$tnum\/$c#$c/sm;
295        $yymain =~ s/{yabb msub}/$msub/sm;
296        $yymain =~ s/{yabb mdate}/$mdate/sm;
297        $yymain =~ s/{yabb tname}/$tname/sm;
298        $yymain =~ s/{yabb mname}/$mname/sm;
299        $yymain =~ s/{yabb my_tstate}/$my_tstate/sm;
300        $yymain =~ s/{yabb message}/$message/sm;
301    }
302
303    $yynavigation = qq~&rsaquo; $maintxt{'214'}~;
304    $yytitle      = $maintxt{'214'};
305    template();
306    return;
307}
308
309sub RecentTopics {
310    spam_protection();
311
312    $recent_topics = $action eq 'recenttopics' ? 1 : 0;
313
314    $display = $FORM{'display'} || $INFO{'display'} || 10;
315    if ( $display < 0 ) { $display = 5; }
316    elsif ( $display > $maxrecentdisplay ) { $display = $maxrecentdisplay; }
317
318    $numfound = 0;
319    get_forum_master();
320    foreach my $catid (@categoryorder) {
321        my ( $catname, $catperms ) = split /\|/xsm, $catinfo{$catid};
322        if ( !CatAccess($catperms) ) { next; }
323        (@bdlist) = split /\,/xsm, $cat{$catid};
324        recursive_check(@bdlist);
325    }
326
327    @data = reverse sort { $a cmp $b } @data;
328
329    $numfound = 0;
330    $notify =
331      $recent_topics
332      ? scalar @data
333      : ( @data > $display ? $display : scalar @data );
334    for my $i ( 0 .. ( $notify - 1 ) ) {
335        ( $mtime, $curboard, $tnum, $treplies, $tusername, $tname, $tstate ) =
336          split /\|/xsm, $data[$i];
337
338        fopen( REC_THRETXT, "$datadir/$tnum.txt" ) || next;
339        @mess = <REC_THRETXT>;
340        fclose(REC_THRETXT);
341
342        for my $c ( $#mess .. @mess ) {
343            chomp $mess[$c];
344            if ( $mess[$c] ) {
345                (
346                    $msub,  $mname,    $memail, $mdate,   $musername,
347                    $micon, $mreplyno, $mip,    $message, $mns
348                ) = split /\|/xsm, $mess[$c];
349                $messages[$numfound] =
350"$mdate|$curboard|$tnum|$c|$tusername|$tname|$msub|$mname|$memail|$mdate|$musername|$micon|$mreplyno|$mip|$message|$mns|$tstate|$mtime";
351                $numfound++;
352            }
353        }
354        if ( $recent_topics && $numfound == $display ) { last; }
355    }
356
357    @messages = reverse sort { $a cmp $b } @messages;
358
359    if ( $numfound > 0 ) {
360        if ( $numfound > $display ) { $numfound = $display; }
361        LoadCensorList();
362        $icanbypass = checkUserLockBypass();
363    }
364    else {
365        $yymain .= qq~<hr class="hr" /><b>$maintxt{'170'}</b><hr />~;
366    }
367
368    for my $i ( 0 .. ( $numfound - 1 ) ) {
369        (
370            $dummy,   $board, $tnum,    $c,     $tusername, $tname,
371            $msub,    $mname, $memail,  $mdate, $musername, $micon,
372            $mattach, $mip,   $message, $mns,   $tstate,    $trstart
373        ) = split /\|/xsm, $messages[$i];
374        $displayname = $mname;
375
376        if ( $tusername ne 'Guest' && -e ("$memberdir/$tusername.vars") ) {
377            LoadUser($tusername);
378        }
379        if ( ${ $uid . $tusername }{'regtime'} ) {
380            $registrationdate = ${ $uid . $tusername }{'regtime'};
381        }
382        else {
383            $registrationdate = $date;
384        }
385
386        if ( ${ $uid . $tusername }{'regdate'} && $trstart > $registrationdate )
387        {
388            if ( $iamguest ) {
389                $tname = qq~$format_unbold{$tusername}~;
390            }
391            else {
392                $tname =
393qq~<a href="$scripturl?action=viewprofile;username=$useraccount{$tusername}" rel="nofollow">$format_unbold{$tusername}</a>~;
394            }
395        }
396        elsif ( $tusername !~ m{Guest}sm && $trstart < $registrationdate ) {
397            $tname = qq~$tname - $maintxt{'470a'}~;
398        }
399        else {
400            $tname = "$tname ($maintxt{'28'})";
401        }
402
403        if ( $musername ne 'Guest' && -e ("$memberdir/$musername.vars") ) {
404            LoadUser($musername);
405        }
406        if ( ${ $uid . $musername }{'regtime'} ) {
407            $registrationdate = ${ $uid . $musername }{'regtime'};
408        }
409        else {
410            $registrationdate = $date;
411        }
412
413        if ( ${ $uid . $musername }{'regdate'} && $mdate > $registrationdate ) {
414            if ( $iamguest ) {
415                $mname = qq~$format_unbold{$tusername}~;
416            }
417            else {
418                $mname =
419qq~<a href="$scripturl?action=viewprofile;username=$useraccount{$musername}" rel="nofollow">$format_unbold{$musername}</a>~;
420            }
421        }
422        elsif ( $musername !~ m{Guest}sm && $mdate < $registrationdate ) {
423            $mname = qq~$mname - $maintxt{'470a'}~;
424        }
425        else {
426            $mname = "$mname ($maintxt{'28'})";
427        }
428
429        wrap();
430        $movedflag = q{};
431        ( $message, $movedflag ) = Split_Splice_Move( $message, $tnum );
432        if ($enable_ubbc) {
433            $ns = $mns;
434            enable_yabbc();
435            DoUBBC();
436        }
437        wrap2();
438        ToChars($message);
439        $message = Censor($message);
440
441        ( $msub, undef ) = Split_Splice_Move( $msub, 0 );
442        ToChars($msub);
443        $msub = Censor($msub);
444
445        if ($iamguest) {
446            $notify = q{};
447        }
448        else {
449            if ( ${ $uid . $username }{'thread_notifications'} =~
450                /\b$tnum\b/xsm )
451            {
452                $notify =
453qq~$menusep<a href="$scripturl?action=notify3;num=$tnum/$c;oldnotify=1">$img{'del_notify'}</a>~;
454            }
455            else {
456                $notify =
457qq~$menusep<a href="$scripturl?action=notify2;num=$tnum/$c;oldnotify=1">$img{'add_notify'}</a>~;
458            }
459        }
460        $mdate = timeformat($mdate);
461
462        # generate a sub board tree
463        my $boardtree   = q{};
464        my $parentboard = $board;
465        while ($parentboard) {
466            my ( $pboardname, undef, undef ) =
467              split /\|/xsm, $board{"$parentboard"};
468            if ( ${ $uid . $parentboard }{'canpost'}
469                || !$subboard{$parentboard} )
470            {
471                $pboardname =
472qq~<a href="$scripturl?board=$parentboard"><span class="under">$pboardname</span></a>~;
473            }
474            else {
475                $pboardname =
476qq~<a href="$scripturl?boardselect=$parentboard&subboards=1"><span class="under">$pboardname</span></a>~;
477            }
478            $boardtree = qq~ / $pboardname$boardtree~;
479            $my_cat    = ${ $uid . $parentboard }{'cat'};
480            ( $my_catname, undef ) = split /\|/xsm, $catinfo{$my_cat};
481            $parentboard = ${ $uid . $parentboard }{'parent'};
482        }
483        $counter = $i + 1;
484
485        if ( $tstate != 1 && ( !$iamguest || $enable_guestposting ) ) {
486            $my_tstate = $myrecent_mess;
487            $my_tstate =~ s/{yabb tnum}/$tnum/gsm;
488            $my_tstate =~ s/{yabb c}/$c/gsm;
489        }
490
491        $yymain .= $myrecent;
492        $yymain =~ s/{yabb counter}/$counter/sm;
493        $yymain =~ s/{yabb catbrd}/$my_cat/sm;
494        $yymain =~ s/{yabb catname}/$my_catname/sm;
495        $yymain =~ s/{yabb boardtree}/$boardtree/sm;
496        $yymain =~ s/{yabb tnum}/$tnum\/$c#$c/sm;
497        $yymain =~ s/{yabb msub}/$msub/sm;
498        $yymain =~ s/{yabb mdate}/$mdate/sm;
499        $yymain =~ s/{yabb tname}/$tname/sm;
500        $yymain =~ s/{yabb mname}/$mname/sm;
501        $yymain =~ s/{yabb my_tstate}/$my_tstate/sm;
502        $yymain =~ s/{yabb message}/$message/sm;
503    }
504
505    $yynavigation = qq~&rsaquo; $maintxt{'214b'}~;
506    $yytitle      = $maintxt{'214b'};
507    template();
508    return;
509}
510
511sub recursive_check {
512    my @x = @_;
513    foreach my $curboard (@x) {
514        ( $boardname{$curboard}, $boardperms, undef ) = split /\|/xsm,
515          $board{$curboard};
516
517        my $access = AccessCheck( $curboard, q{}, $boardperms );
518        if ( !$iamadmin && $access ne 'granted' ) { next; }
519
520        if ( ${ $uid . $curboard }{'brdpasswr'} ) {
521            my $bdmods = ${ $uid . $curboard }{'mods'};
522            $bdmods =~ s/\, /\,/gsm;
523            $bdmods =~ s/\ /\,/gsm;
524            my %moderators = ();
525            my $pswiammod  = 0;
526            foreach my $curuser ( split /\,/xsm, $bdmods ) {
527                if ( $username eq $curuser ) { $pswiammod = 1; }
528            }
529            my $bdmodgroups = ${ $uid . $curboard }{'modgroups'};
530            $bdmodgroups =~ s/\, /\,/gsm;
531            my %moderatorgroups = ();
532            foreach my $curgroup ( split /\,/xsm, $bdmodgroups ) {
533                if ( ${ $uid . $username }{'position'} eq $curgroup ) {
534                    $pswiammod = 1;
535                }
536                foreach my $memberaddgroups ( split /\, /sm,
537                    ${ $uid . $username }{'addgroups'} )
538                {
539                    chomp $memberaddgroups;
540                    if ( $memberaddgroups eq $curgroup ) {
541                        $pswiammod = 1;
542                        last;
543                    }
544                }
545            }
546            my $cookiename = "$cookiepassword$curboard$username";
547            my $crypass    = ${ $uid . $curboard }{'brdpassw'};
548            if (   !$iamadmin
549                && !$iamgmod
550                && !$pswiammod
551                && $yyCookies{$cookiename} ne $crypass )
552            {
553                next;
554            }
555        }
556
557        $catid{$curboard}   = $catid;
558        $catname{$curboard} = $catname;
559
560        fopen( REC_BDTXT, "$boardsdir/$curboard.txt" );
561        @buffer = <REC_BDTXT>;
562        if ( !$display ) {
563            $display = scalar @buffer;
564        }
565        for my $i ( 0 .. ( $display - 1 ) ) {
566            if ( $buffer[$i] ) {
567                (
568                    $tnum,     $tsub,      $tname, $temail, $tdate,
569                    $treplies, $tusername, $ticon, $tstate
570                ) = split /\|/xsm, $buffer[$i];
571                chomp $tstate;
572                if ( $tstate !~ /h/sm || $iamadmin || $iamgmod ) {
573                    $mtime = $tdate;
574                    $data[$numfound] =
575"$mtime|$curboard|$tnum|$treplies|$tusername|$tname|$tstate";
576                    $numfound++;
577                }
578            }
579        }
580        fclose(REC_BDTXT);
581        if ( $subboard{$curboard} ) {
582            recursive_check( split /\|/xsm, $subboard{$curboard} );
583        }
584    }
585    return;
586}
587
5881;
589