1###############################################################################
2# Favorites.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);
19our $VERSION = '2.6.11';
20
21$favoritespmver = 'YaBB 2.6.11 $Revision: 1611 $';
22if ( $action eq 'detailedversion' ) { return 1; }
23
24sub Favorites {
25    LoadLanguage('MessageIndex');
26    get_micon();
27    get_template('MyPosts');
28
29    my $start = int( $INFO{'start'} ) || 0;
30    my (
31        @threads, $counter, $pages, $mnum,     $msub,
32        $mname,   $memail,  $mdate, $mreplies, $musername,
33        $micon,   $mstate,  $dlp
34    );
35    my $treplies = 0;
36
37# grab all relevant info on the favorite thread for this user and check access to them
38    if ( !$maxfavs ) { $maxfavs = 10; }
39    my @favboards;
40    eval { require Variables::Movedthreads };
41        foreach my $myfav ( split /,/xsm, ${ $uid . $username }{'favorites'} ) {
42
43            # see if thread exists and search for it if moved
44            if ( exists $moved_file{$myfav} ) {
45                my @moved = ($myfav);
46                while ( exists $moved_file{$myfav} ) {
47                    $myfav = $moved_file{$myfav};
48                    unshift @moved, $myfav;
49                }
50                foreach (@moved) {
51                    $myfav = $_;
52                    if ( $myfav ne $moved[-1] ) {
53                        if ( -e "$datadir/$myfav.ctb" ) {
54                            RemFav( $moved[-1], 'nonexist' );
55                            AddFav( $myfav, 0, 1 );
56                            last;
57                        }
58                    }
59                    elsif ( !-e "$datadir/$myfav.ctb" ) {
60                        RemFav( $myfav, 'nonexist' );
61                        $myfav = 0;
62                    }
63                }
64                next if !$myfav;
65            }
66            elsif ( !-e "$datadir/$myfav.ctb" ) {
67                RemFav( $myfav, 'nonexist' );
68                next;
69            }
70            MessageTotals( 'load', $myfav );
71            $favoboard = ${$myfav}{'board'};
72            push @favboards, "$favoboard|$myfav";
73        }
74
75    foreach ( sort @favboards ) {
76        ( $loadboard, $loadfav ) = split /\|/xsm, $_;
77        if ( !${ $uid . $loadboard }{'board'} ) {
78            BoardTotals( 'load', $loadboard );
79        }
80
81        next
82          if !$iamadmin
83              && AccessCheck( $loadboard, q{},
84                  ( split /\|/xsm, $board{$loadboard} )[1] ) ne 'granted';
85
86        next
87          if !$iamadmin
88              && !CatAccess(
89                  ( split /\|/xsm, $catinfo{"${$uid.$loadboard}{'cat'}"} )[1]
90              );
91
92        fopen( BRDTXT, "$boardsdir/$loadboard.txt" )
93          or fatal_error( 'cannot_open', "$boardsdir/$currentboard.txt", 1 );
94        while ( my $brd = <BRDTXT> ) {
95            if ( ( split /\|/xsm, $brd, 2 )[0] eq $loadfav ) {
96                push @threads, $brd;
97            }
98        }
99        fclose(BRDTXT);
100    }
101
102    my $curfav = @threads;
103
104    LoadCensorList();
105
106    my %attachments;
107    my $att_length = -s "$vardir/attachments.txt";
108    if ( ( -s "$vardir/attachments.txt" ) > 5 ) {
109        fopen( ATM, "$vardir/attachments.txt" );
110        while (<ATM>) {
111            $attachments{ ( split /\|/xsm, $_, 2 )[0] }++;
112        }
113        fclose(ATM);
114    }
115
116    # Print the header and board info.
117    my $colspan = 7;
118
119    # Begin printing the message index for current board.
120    $counter = $start;
121    getlog();
122    my $dmax = $date - ( $max_log_days_old * 86400 );
123    foreach (@threads) {
124        (
125            $mnum,     $msub,      $mname, $memail, $mdate,
126            $mreplies, $musername, $micon, $mstate
127        ) = split /\|/xsm, $_;
128
129        # Set thread class depending on locked status and number of replies.
130        if ( $mnum eq q{} ) { next; }
131
132        MessageTotals( 'load', $mnum );
133
134        $permlinkboard =
135          ${$mnum}{'board'} eq $annboard ? $annboard : $currentboard;
136        my $permdate = permtimer($mnum);
137        my $message_permalink =
138qq~<a href="http://$perm_domain/$symlink$permdate/$permlinkboard/$mnum">$messageindex_txt{'10'}</a>~;
139
140        $threadclass = 'thread';
141        if    ( $mstate =~ /h/ism ) { $threadclass = 'hide'; }
142        elsif ( $mstate =~ /l/ism ) { $threadclass = 'locked'; }
143        elsif ( $mreplies >= $VeryHotTopic ) { $threadclass = 'veryhotthread'; }
144        elsif ( $mreplies >= $HotTopic )     { $threadclass = 'hotthread'; }
145        elsif ( $mstate eq q{} ) { $threadclass = 'thread'; }
146        if ( $threadclass eq 'hide' && $mstate =~ /s/ism && $mstate !~ /l/ism )
147        {
148            $threadclass = 'hidesticky';
149        }
150        elsif ($threadclass eq 'hide'
151            && $mstate =~ /l/ism
152            && $mstate !~ /s/ism )
153        {
154            $threadclass = 'hidelock';
155        }
156        elsif ($threadclass eq 'hide'
157            && $mstate =~ /s/ism
158            && $mstate =~ /l/ism )
159        {
160            $threadclass = 'hidestickylock';
161        }
162        elsif ($threadclass eq 'locked'
163            && $mstate =~ /s/ism
164            && $mstate !~ /h/ism )
165        {
166            $threadclass = 'stickylock';
167        }
168        elsif ( $mstate =~ /s/ism && $mstate !~ /h/ism ) {
169            $threadclass = 'sticky';
170        }
171        elsif ( ${$mnum}{'board'} eq $annboard && $mstate !~ /h/ism ) {
172            $threadclass =
173              $threadclass eq 'locked' ? 'announcementlock' : 'announcement';
174        }
175
176        my $movedFlag;
177        ( undef, $movedFlag ) = Split_Splice_Move( $msub, $mnum );
178
179        if ( !$iamguest && $max_log_days_old ) {
180
181            # Decide if thread should have the "NEW" indicator next to it.
182            # Do this by reading the user's log for last read time on thread,
183            # and compare to the last post time on the thread.
184            $dlp =
185              int( $yyuserlog{$mnum} ) >
186              int( $yyuserlog{"$currentboard--mark"} )
187              ? int( $yyuserlog{$mnum} )
188              : int $yyuserlog{"$currentboard--mark"};
189            if (   $yyuserlog{"$mnum--unread"}
190                || ( !$dlp && $mdate > $dmax )
191                || ( $dlp > $dmax && $dlp < $mdate ) )
192            {
193                if ( ${$mnum}{'board'} eq $annboard ) {
194                    $new =
195qq~<a href="$scripturl?virboard=$currentboard;num=$mnum/new">$micon{'new'}</a>~;
196                }
197                else {
198                    $new =
199                      qq~<a href="$scripturl?num=$mnum/new">$micon{'new'}</a>~;
200                }
201            }
202            else {
203                $new = q{};
204            }
205        }
206        if ($movedFlag) { $new = q{}; }
207
208        $micon = $micon{$micon};
209        $mpoll = q{};
210        if ( -e "$datadir/$mnum.poll" ) {
211            $mpoll = qq~<b>$messageindex_txt{'15'}: </b>~;
212            fopen( POLL, "$datadir/$mnum.poll" );
213            my @poll = <POLL>;
214            fclose(POLL);
215            my (
216                $poll_question, $poll_locked, $poll_uname,   $poll_name,
217                $poll_email,    $poll_date,   $guest_vote,   $hide_results,
218                $multi_vote,    $poll_mod,    $poll_modname, $poll_comment,
219                $vote_limit,    $pie_radius,  $pie_legends,  $poll_end
220            ) = split /\|/xsm, $poll[0];
221            chomp $poll_end;
222            if ( $poll_end && !$poll_locked && $poll_end < $date ) {
223                $poll_locked = 1;
224                $poll_end    = q{};
225                $poll[0] =
226"$poll_question|$poll_locked|$poll_uname|$poll_name|$poll_email|$poll_date|$guest_vote|$hide_results|$multi_vote|$poll_mod|$poll_modname|$poll_comment|$vote_limit|$pie_radius|$pie_legends|$poll_end\n";
227                fopen( POLL, ">$datadir/$mnum.poll" );
228                print {POLL} @poll or croak "$croak{'print'} POLL";
229                fclose(POLL);
230            }
231            $micon = qq~$img{'pollicon'}~;
232            if ($poll_locked) { $micon = $img{'polliconclosed'}; }
233            elsif ( $max_log_days_old && $mdate > $dmax ) {
234                if ( $dlp < $createpoll_date ) {
235                    $micon = qq~$img{'polliconnew'}~;
236                }
237                else {
238                    fopen( POLLED, "$datadir/$mnum.polled" );
239                    my $polled = <POLLED>;
240                    fclose(POLLED);
241                    if ( $dlp < ( split /\|/xsm, $polled )[3] ) {
242                        $micon = qq~$img{'polliconnew'}~;
243                    }
244                }
245            }
246        }
247
248        # Load the current nickname of the account name of the thread starter.
249        if ( $musername ne 'Guest' ) {
250            LoadUser($musername);
251            if ( ${ $uid . $musername }{'realname'} ) {
252                $mname =
253qq~<a href="$scripturl?action=viewprofile;username=$useraccount{$musername}">$format_unbold{$musername}</a>~;
254            }
255            else {
256                $mname .= qq~ ($messageindex_txt{'470a'})~;
257            }
258        }
259
260        ( $msub, undef ) = Split_Splice_Move( $msub, 0 );
261
262        # Censor the subject of the thread.
263        $msub = Censor($msub);
264        ToChars($msub);
265
266        # Build the page links list.
267        $pages = q{};
268        $pagesall;
269        if ($showpageall) {
270            $pagesall =
271              qq~<a href="$scripturl?num=$mnum/all-0">$pidtxt{'01'}</a>~;
272        }
273        $maxmessagedisplay ||= 10;
274        if ( int( ( $mreplies + 1 ) / $maxmessagedisplay ) > 6 ) {
275            $pages =
276                qq~ <a href="$scripturl?num=$mnum/~
277              . ( !$ttsreverse ? '0#0' : "$mreplies#$mreplies" )
278              . q~">1</a>~;
279            $pages .= qq~ <a href="$scripturl?num=$mnum/~
280              . (
281                !$ttsreverse
282                ? "$maxmessagedisplay#$maxmessagedisplay"
283                : ( $mreplies - $maxmessagedisplay ) . q{#}
284                  . ( $mreplies - $maxmessagedisplay )
285              ) . q~">2</a>~;
286            $endpage = int( $mreplies / $maxmessagedisplay ) + 1;
287            $i       = ( $endpage - 1 ) * $maxmessagedisplay;
288            $j       = $i - $maxmessagedisplay;
289            $k       = $endpage - 1;
290            $tmpa    = $endpage - 2;
291            $tmpb    = $j - $maxmessagedisplay;
292            $pages .=
293qq~ <a href="javascript:void(0);" onclick="ListPages($mnum);">...</a>~;
294            $pages .= qq~ <a href="$scripturl?num=$mnum/~
295              . (
296                !$ttsreverse
297                ? "$tmpb#$tmpb"
298                : ( $mreplies - $tmpb ) . q{#} . ( $mreplies - $tmpb )
299              ) . qq~">$tmpa</a>~;
300            $pages .= qq~ <a href="$scripturl?num=$mnum/~
301              . (
302                !$ttsreverse
303                ? "$j#$j"
304                : ( $mreplies - $j ) . q{#} . ( $mreplies - $j )
305              ) . qq~">$k</a>~;
306            $pages .= qq~ <a href="$scripturl?num=$mnum/~
307              . (
308                !$ttsreverse
309                ? "$i#$i"
310                : ( $mreplies - $i ) . q{#} . ( $mreplies - $i )
311              ) . qq~">$endpage</a>~;
312            $pages =
313qq~<br /><span class="small">&#171; $messageindex_txt{'139'} $pages $pagesall &#187;</span>~;
314
315        }
316        elsif ( $mreplies + 1 > $maxmessagedisplay ) {
317            $tmpa = 1;
318            for my $tmpb ( 0 .. $mreplies ) {
319                if ( $tmpb % $maxmessagedisplay == 0 ) {
320                    $pages .=
321                        qq~<a href="$scripturl?num=$mnum/~
322                      . ( !$ttsreverse ? "$tmpb#$tmpb" : ( $mreplies - $tmpb ) )
323                      . qq~">$tmpa</a>\n~;
324                    ++$tmpa;
325                }
326            }
327            $pages =~ s/\n\Z//xsm;
328            $pages =
329qq~<br /><span class="small">&#171; $messageindex_txt{'139'} $pages &#187;</span>~;
330        }
331
332        $views      = ${$mnum}{'views'};
333        $lastposter = ${$mnum}{'lastposter'};
334        if ( $lastposter =~ m{\AGuest-(.*)}xsm ) {
335            $lastposter = $1;
336        }
337        elsif ( $lastposter !~ m{Guest}xsm
338            && !( -e "$memberdir/$lastposter.vars" ) )
339        {
340            $lastposter = $messageindex_txt{'470a'};
341        }
342        else {
343            if (
344                (
345                       $lastposter ne $messageindex_txt{'470'}
346                    && $lastposter ne $messageindex_txt{'470a'}
347                )
348                || !-e "$memberdir/$lastposter.vars"
349              )
350            {
351                LoadUser($lastposter);
352                if ( ${ $uid . $lastposter }{'realname'} ) {
353                    $lastposter =
354qq~<a href="$scripturl?action=viewprofile;username=$lastposter">$format_unbold{$lastposter}</a>~;
355                }
356            }
357        }
358        $lastpostername = $lastposter || $messageindex_txt{'470'};
359        $views = $views ? $views - 1 : 0;
360
361# Check if the thread contains attachments and create a paper-clip icon if it does
362        $temp_attachment =
363          $attachments{$mnum}
364          ? qq~<a href="javascript:void(window.open('$scripturl?action=viewdownloads;thread=$mnum','_blank','width=800,height=650,scrollbars=yes'))"><img src="$micon_bg{'paperclip'}" alt="$messageindex_txt{'3'} $attachments{$mnum} ~
365          . (
366              $attachments{$mnum} == 1
367            ? $messageindex_txt{'5'}
368            : $messageindex_txt{'4'}
369          )
370          . qq~" title="$messageindex_txt{'3'} $attachments{$mnum} ~
371          . (
372              $attachments{$mnum} == 1
373            ? $messageindex_txt{'5'}
374            : $messageindex_txt{'4'}
375          )
376          . q~" /></a>~
377          : q{};
378
379        $mydate = timeformat($mdate);
380
381        my $threadpic = $micon{$threadclass};
382        my $msublink  = qq~<a href="$scripturl?num=$mnum">$msub</a>~;
383        if ( !$movedFlag && ${$mnum}{'board'} eq $annboard ) {
384            $msublink =
385qq~<a href="$scripturl?virboard=$currentboard;num=$mnum">$msub</a>~;
386        }
387        my $lastpostlink =
388qq~<a href="$scripturl?num=$mnum/$mreplies#$mreplies">$img{'lastpost'}$mydate</a>~;
389        my $fmreplies = NumberFormat($mreplies);
390        $views = NumberFormat($views);
391        my $tempbar = $threadbar;
392        if ($movedFlag) { $tempbar = $threadbarMoved; }
393
394        $adminbar =
395qq~<input type="checkbox" name="admin$mcount" class="windowbg" value="$mnum" />~;
396        $admincol = $admincolumn;
397        $admincol =~ s/{yabb admin}/$adminbar/gsm;
398
399        $tempbar =~ s/{yabb admin column}/$admincol/gsm;
400        $tempbar =~ s/{yabb threadpic}/$threadpic/gsm;
401        $tempbar =~ s/{yabb icon}/$micon/gsm;
402        $tempbar =~ s/{yabb new}/$new/gsm;
403        $tempbar =~ s/{yabb poll}/$mpoll/gsm;
404        $tempbar =~ s/{yabb favorite}/$favicon{$mnum}/gsm;
405        $tempbar =~ s/{yabb subjectlink}/$msublink/gsm;
406        $tempbar =~ s/{yabb attachmenticon}/$temp_attachment/gsm;
407        $tempbar =~ s/{yabb pages}/$pages/gsm;
408        $tempbar =~ s/{yabb starter}/$mname/gsm;
409        $tempbar =~ s/{yabb replies}/$fmreplies/gsm;
410        $tempbar =~ s/{yabb views}/$views/gsm;
411        $tempbar =~ s/{yabb lastpostlink}/$lastpostlink/gsm;
412        $tempbar =~ s/{yabb lastposter}/$lastpostername/gsm;
413        if ( $accept_permalink == 1 ) {
414            $tempbar =~ s/{yabb permalink}/$message_permalink/gsm;
415        }
416        else {
417            $tempbar =~ s/{yabb permalink}//gsm;
418        }
419        $tmptempbar .= $tempbar;
420        $counter++;
421        $mcount++;
422        $treplies += $mreplies + 1;
423    }
424
425    # Put a "no messages" message if no threads exisit:
426    if ( !$tmptempbar ) {
427        $tmptempbar = $no_favs;
428    }
429
430    $yabbicons = qq~$micon{'thread'} $messageindex_txt{'457'}
431    <br />$micon{'sticky'} $messageindex_txt{'779'}
432    <br />$micon{'locked'} $messageindex_txt{'456'}
433    <br />$micon{'stickylock'}$messageindex_txt{'780'}<br />~;
434
435    if ( $staff && $sessionvalid == 1 ) {
436        $yabbadminicons = qq~$micon{'hide'} $messageindex_txt{'458'}
437        <br />$micon{'hidesticky'} $messageindex_txt{'459'}
438        <br />$micon{'hidelock'} $messageindex_txt{'460'}
439        <br />$micon{'hidestickylock'} $messageindex_txt{'461'}<br />~;
440    }
441
442    $yabbadminicons .= qq~$micon{'announcement'} $messageindex_txt{'779a'}
443    <br />$micon{'announcementlock'} $messageindex_txt{'779b'}
444    <br />$micon{'hotthread'} $messageindex_txt{'454'} $HotTopic $messageindex_txt{'454a'}
445    <br />$micon{'veryhotthread'} $messageindex_txt{'455'} $VeryHotTopic $messageindex_txt{'454a'}<br />
446    ~;
447
448    $formstart =
449qq~<form name="multiremfav" action="$scripturl?board=$currentboard;action=multiremfav" method="post" style="display: inline">~;
450    $formend =
451      qq~<input type="hidden" name="allpost" value="$INFO{'start'}" /></form>~;
452
453    LoadAccess();
454
455    $adminselector = qq~
456    <input type="submit" value="$messageindex_txt{'842'}" class="button small" />
457    ~;
458
459    $admincheckboxes = q~
460    <input type="checkbox" name="checkall" id="checkall" value="" class="titlebg" onclick="if (this.checked) checkAll(0); else uncheckAll(0);" />
461    ~;
462    $subfooterbar =~ s/{yabb admin selector}/$adminselector/gsm;
463    $subfooterbar =~ s/{yabb admin checkboxes}/$admincheckboxes/gsm;
464
465    # Template it
466    $adminheader =~ s/{yabb admin}/$messageindex_txt{'2'}/gsm;
467
468    $favorites_template =~ s/{yabb home}//gsm;
469    $favorites_template =~ s/{yabb category}//gsm;
470
471    $yynavigation =
472qq~&rsaquo; <a href="$scripturl?action=mycenter" class="nav">$img_txt{'mycenter'}</a> &rsaquo; $img_txt{'70'}~;
473
474    $favboard = qq~<span class="nav">$img_txt{'70'}</span>~;
475    $favorites_template =~ s/{yabb board}/$favboard/gsm;
476    $bdescrip =
477qq~$messageindex_txt{'75'}<br />$messageindex_txt{'76'} $curfav $messageindex_txt{'77'} $maxfavs $messageindex_txt{'78'}~;
478    $curfav   = NumberFormat($curfav);
479    $treplies = NumberFormat($treplies);
480    $bdpicExt ||= 'gif';
481
482    ToChars($bdescrip);
483    $boarddescription   =~ s/{yabb boarddescription}/$bdescrip/gsm;
484    $favorites_template =~ s/{yabb description}/$boarddescription/gsm;
485    $bdpic =
486qq~ <img src="$imagesdir/$my_favbrds" alt="$img_txt{'70'}" title="$img_txt{'70'}" /> ~;
487    $favorites_template =~ s/{yabb bdpicture}/$bdpic/gsm;
488    $favorites_template =~ s/{yabb threadcount}/$curfav/gsm;
489    $favorites_template =~ s/{yabb messagecount}/$treplies/gsm;
490
491    $favorites_template =~ s/{yabb colspan}/$colspan/gsm;
492
493    $favorites_template =~ s/{yabb admin column}/$adminheader/gsm;
494    $favorites_template =~ s/{yabb modupdate}/$formstart/gsm;
495    $favorites_template =~ s/{yabb modupdateend}/$formend/gsm;
496
497    $favorites_template =~ s/{yabb threadblock}/$tmptempbar/gsm;
498    $favorites_template =~ s/{yabb adminfooter}/$subfooterbar/gsm;
499    $favorites_template =~ s/{yabb icons}/$yabbicons/gsm;
500    $favorites_template =~ s/{yabb admin icons}/$yabbadminicons/gsm;
501    $showFavorites .= qq~$favorites_template~;
502
503    $showFavorites .= qq~
504<script type="text/javascript">
505        function checkAll(j) {
506            for (var i = 0; i < document.multiremfav.elements.length; i++) {
507                if (j == 0 ) {document.multiremfav.elements[i].checked = true;}
508            }
509        }
510        function uncheckAll(j) {
511            for (var i = 0; i < document.multiremfav.elements.length; i++) {
512                if (j == 0 ) {document.multiremfav.elements[i].checked = false;}
513            }
514        }
515        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'); }
516</script>
517    ~;
518
519    $yytitle = $img_txt{'70'};
520    return;
521}
522
523sub AddFav {
524    my @x      = @_;
525    my $favo   = $INFO{'fav'} || $x[0];
526    my $goto   = $INFO{'start'} || $x[1] || 0;
527    my $return = $x[2];
528
529    if ( $favo =~ /\D/xsm ) { fatal_error( 'error_occurred', q{}, 1 ); }
530
531    my @oldfav = split /,/xsm, ${ $uid . $username }{'favorites'};
532    if ( @oldfav < ( $maxfavs || 10 ) ) {
533        push @oldfav, $favo;
534        ${ $uid . $username }{'favorites'} = join q{,}, undupe(@oldfav);
535        UserAccount( $username, 'update' );
536    }
537    if ( !$return ) {
538        if ( $INFO{'oldaddfav'} ) {
539            $yySetLocation = qq~$scripturl?num=$favo/$goto~;
540            redirectexit();
541        }
542        $elenable = 0;
543        croak q{};    # This is here only to avoid server error log entries!
544    }
545    return;
546}
547
548sub MultiRemFav {
549    while ( $maxfavs >= $count ) {
550        RemFav( $FORM{"admin$count"} );
551        $count++;
552    }
553    $yySetLocation = qq~$scripturl?action=favorites~;
554    redirectexit();
555    return;
556}
557
558sub RemFav {
559    my @x    = @_;
560    my $favo = $INFO{'fav'} || $x[0];
561    my $goto = $INFO{'start'} || $x[1];
562    if ( !$goto ) { $goto = 0; }
563
564    my @newfav;
565    foreach ( split /,/xsm, ${ $uid . $username }{'favorites'} ) {
566        if ( $favo ne $_ ) { push @newfav, $_; }
567    }
568
569    ${ $uid . $username }{'favorites'} = join q{,}, undupe(@newfav);
570    UserAccount( $username, 'update' );
571
572    return if $x[1] eq 'nonexist';
573    if (   $INFO{'ref'} ne 'delete'
574        && $action ne 'multiremfav'
575        && $INFO{'oldaddfav'} )
576    {
577        $yySetLocation = qq~$scripturl?num=$favo/$goto~;
578        redirectexit();
579    }
580    if ( $action eq 'remfav' ) {
581        $elenable = 0;
582        croak q{};    # This is here only to avoid server error log entries!
583    }
584    return;
585}
586
587sub IsFav {
588    my @x         = @_;
589    my $favo      = $x[0];
590    my $goto      = $x[1] || 0;
591    my $postcheck = $x[2];
592
593    my $addfav = $img{'addfav'};
594    my $remfav = $img{'remfav'};
595    if ($useThreadtools) {
596        $addfav =~ s/\[tool=(.+?)\](.+?)\[\/tool\]/$2/gsm;
597        $remfav =~ s/\[tool=(.+?)\](.+?)\[\/tool\]/$2/gsm;
598    }
599    if ( !$postcheck ) {
600        $yyjavascript .= qq~\n
601        var addlink = '$addfav';
602        var remlink = '$remfav';\n~;
603    }
604
605    my @oldfav = split /,/xsm, ${ $uid . $username }{'favorites'};
606    my ( $button, $nofav );
607    if ( @oldfav < ( $maxfavs || 10 ) ) {
608        $button =
609qq~$menusep<a href="javascript:AddRemFav('$scripturl?action=addfav;fav=$favo;start=$goto','$imagesdir')" id="favlink">$img{'addfav'}</a>~;
610        $nofav = 1;
611    }
612    else { $nofav = 2; }
613
614    foreach (@oldfav) {
615        if ( $favo eq $_ ) {
616            $button =
617qq~$menusep<a href="javascript:AddRemFav('$scripturl?action=remfav;fav=$favo;start=$goto','$imagesdir')" id="favlink">$img{'remfav'}</a>~;
618            $nofav = 0;
619        }
620    }
621    return ( !$postcheck ? $button : $nofav );
622}
623
624sub IsFav1 {
625    my @x         = @_;
626    my $favo      = $x[0];
627    my $goto      = $x[1] || 0;
628    my $postcheck = $x[2];
629
630    my $addfav = $img{'addfav'};
631    my $remfav = $img{'remfav'};
632    if ($useThreadtools) {
633        $addfav =~ s/\[tool=(.+?)\](.+?)\[\/tool\]/$2/gsm;
634        $remfav =~ s/\[tool=(.+?)\](.+?)\[\/tool\]/$2/gsm;
635    }
636    if ( !$postcheck ) {
637        $yyjavascript .= qq~\n
638        addlink = '$addfav';
639        remlink = '$remfav';\n~;
640    }
641
642    my @oldfav = split /,/xsm, ${ $uid . $username }{'favorites'};
643    my ( $button, $nofav );
644    if ( @oldfav < ( $maxfavs || 10 ) ) {
645        $button =
646qq~$menusep<a href="javascript:AddRemFav('$scripturl?action=addfav;fav=$favo;start=$goto','$imagesdir')" id="favlink2">$img{'addfav'}</a>~;
647        $nofav = 1;
648    }
649    else { $nofav = 2; }
650
651    foreach (@oldfav) {
652        if ( $favo eq $_ ) {
653            $button =
654qq~$menusep<a href="javascript:AddRemFav('$scripturl?action=remfav;fav=$favo;start=$goto','$imagesdir')" id="favlink2">$img{'remfav'}</a>~;
655            $nofav = 0;
656        }
657    }
658    return ( !$postcheck ? $button : $nofav );
659}
660
6611;
662