1############################################################################### 2# MoveSplitSplice.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############################################################################### 15use CGI::Carp qw(fatalsToBrowser); 16our $VERSION = '2.6.11'; 17 18$movesplitsplicepmver = 'YaBB 2.6.11 $Revision: 1611 $'; 19if ( $action eq 'detailedversion' ) { return 1; } 20 21LoadLanguage('MoveSplitSplice'); 22 23get_template('Display'); 24 25sub Split_Splice { 26 if ( !$staff ) { fatal_error('split_splice_not_allowed'); } 27 if ( $FORM{'ss_submit'} || $INFO{'ss_submit'} ) { Split_Splice_2(); } 28 29 my $curboard = $INFO{'board'}; 30 my $curthread = $INFO{'thread'}; 31 if ( !exists $FORM{'oldposts'} ) { $FORM{'oldposts'} = $INFO{'oldposts'}; } 32 if ( !exists $FORM{'leave'} ) { $FORM{'leave'} = $INFO{'leave'}; } 33 if ( exists $INFO{'newinfo'} ) { $FORM{'newinfo'} = $INFO{'newinfo'}; } 34 my $newcat = $FORM{'newcat'} || $INFO{'newcat'}; 35 my $newboard = $FORM{'newboard'} || $INFO{'newboard'}; 36 if ( !exists $FORM{'newthread'} ) { 37 $FORM{'newthread'} = $INFO{'newthread'}; 38 } 39 my $newthread = $FORM{'newthread'} || 'new'; 40 if ( !exists $FORM{'newthread_subject'} ) { 41 $FORM{'newthread_subject'} = $INFO{'newthread_subject'}; 42 } 43 if ( !exists $FORM{'position'} ) { $FORM{'position'} = $INFO{'position'}; } 44 45 require Sources::YaBBC; 46 LoadCensorList(); 47 48 # Get posts of current thread 49 if ( !ref $thread_arrayref{$curthread} ) { 50 fopen( FILE, "$datadir/$curthread.txt" ); 51 @{ $thread_arrayref{$curthread} } = <FILE>; 52 fclose(FILE); 53 } 54 my @messages = @{ $thread_arrayref{$curthread} }; 55 56 my ( $counter, $size1 ); 57 for my $counter ( 0 .. ( @messages - 1 ) ) { 58 $message = ( split /\|/xsm, $messages[$counter], 10 )[8]; 59 ( $message, undef ) = Split_Splice_Move( $message, 1 ); 60 DoUBBC(); 61 62 $convertstr = $message; 63 $convertstr =~ s/<(p|br|div).*?>/ /gxsm; 64 $convertstr =~ s/<.*?>//gxsm; # remove HTML-tags 65 $convertcut = 50; 66 CountChars(); 67 $message = $convertstr; 68 if ($cliped) { $message .= ' ...'; } 69 70 ToChars($message); 71 $message = Censor($message); 72 73 $messages[$counter] = qq~<option value="$counter" ~ 74 . ( 75 $FORM{'oldposts'} =~ /\b$counter\b/xsm 76 ? q~selected="selected"~ 77 : q{} 78 ) 79 . q~>~ 80 . ( $counter ? "$sstxt{'40'} $counter" : $sstxt{'41'} ) 81 . qq~: $message</option>\n~; 82 } 83 if ( ( $ttsureverse && ${ $uid . $username }{'reversetopic'} ) 84 || $ttsreverse ) 85 { 86 @messages = reverse @messages; 87 } 88 my $postlist = ( 89 $FORM{'oldposts'} eq 'all' 90 ? qq~<option value="all" selected="selected">$sstxt{'26'}</option>\n~ 91 : qq~<option value="all">$sstxt{'26'}</option>\n~ 92 ) . join q{}, @messages; 93 $size1 = @messages + 1; 94 $size1 = $size1 > 10 ? 10 : $size1; # maximum size of multiselect field 95 96 # List of options of what, if anything, to leave in place of the posts moved 97 my @leaveopts = ( $sstxt{'11'}, $sstxt{'12'}, $sstxt{'13'} ); 98 for my $counter ( 0 .. ( @leaveopts - 1 ) ) { 99 $leavelist .= 100 qq~<option value="$counter" ~ 101 . ( $FORM{'leave'} == $counter ? q~selected="selected"~ : q{} ) 102 . qq~>$leaveopts[$counter]</option>\n~; 103 } 104 105 # Get categories and make the current one the default selection 106 my $catlist = qq~<option value="cats" >$sstxt{'28'}</option>\n~; 107 foreach (@categoryorder) { 108 my ( $catname, $catperms ) = split /\|/xsm, $catinfo{$_}, 3; 109 next if !CatAccess($catperms); 110 $catlist .= 111 qq~<option value="$_" ~ 112 . ( $newcat eq $_ ? q~selected="selected"~ : q{} ) 113 . qq~>$catname</option>\n~; 114 } 115 116 # Get boards and make the current one the default selection 117 $boardlist = qq~<option value="boards">$sstxt{'29'}</option>\n~; 118 my $indent = -2; 119 120 *get_subboards = sub { 121 my @x = @_; 122 $indent += 2; 123 foreach my $childbd (@x) { 124 my $dash; 125 if ( $indent > 0 ) { $dash = q{-}; } 126 my ( $boardname, $boardperms ) = split /\|/xsm, $board{$childbd}, 3; 127 ToChars($boardname); 128 my $access = AccessCheck( $_, q{}, $boardperms ); 129 next if !$iamadmin && $access ne 'granted' && $boardview != 1; 130 131 my $bdnopost = 132 ( ${ $uid . $childbd }{'canpost'} || !$subboard{$childbd} ) 133 ? q{} 134 : q~ class="nopost"~; 135 $boardlist .= 136 qq~<option$bdnopost value="$childbd" ~ 137 . ( $newboard eq $childbd ? q~selected="selected"~ : q{} ) . q~>~ 138 . ( ' ' x $indent ) 139 . ( $dash x ( $indent / 2 ) ) 140 . qq~ $boardname</option>\n~; 141 142 if ( $subboard{$childbd} ) { 143 get_subboards( split /\|/xsm, $subboard{$childbd} ); 144 } 145 } 146 $indent -= 2; 147 return; 148 }; 149 get_subboards( split /,/xsm, $cat{$newcat} ); 150 151 # Get threads and make the current one the default selection 152 my ( $threadlist, $threadids, $positionlist ); 153 fopen( FILE, "$boardsdir/$newboard.txt" ); 154 my @threads = <FILE>; 155 fclose(FILE); 156 157 $threadlist = qq~<option value="new">$sstxt{'30'}</option>\n~; 158 my $threadid; 159 foreach (@threads) { 160 ( $threadid, $message, undef ) = split /\|/xsm, $_, 3; 161 next if $curthread eq $threadid; 162 $threadids .= "$threadid,"; 163 164 ( $message, undef ) = Split_Splice_Move( $message, $threadid ); 165 DoUBBC(); 166 167 $convertstr = $message; 168 $convertcut = 50; 169 CountChars(); 170 $message = $convertstr; 171 if ($cliped) { $message .= ' ...'; } 172 173 ToChars($message); 174 $message =~ s/<(p|br|div).*?>/ /gxsm; 175 $message =~ s/<.*?>//gxsm; # remove HTML-tags 176 $message = Censor($message); 177 178 $threadlist .= 179 qq~<option value="$threadid" ~ 180 . ( $newthread eq $threadid ? q~selected="selected"~ : q{} ) 181 . qq~>$message</option>\n~; 182 } 183 184 # Get new thread posts to select splice site 185 if ( $FORM{'newthread'} ne 'new' ) { 186 if ( !ref $thread_arrayref{$newthread} ) { 187 fopen( FILE, "$datadir/$newthread.txt" ); 188 @{ $thread_arrayref{$newthread} } = <FILE>; 189 fclose(FILE); 190 } 191 @messages = @{ $thread_arrayref{$newthread} }; 192 193 for my $counter ( 0 .. ( @messages - 1 ) ) { 194 $message = ( split /[\|]/xsm, $messages[$counter], 10 )[8]; 195 ( $message, undef ) = Split_Splice_Move( $message, 1 ); 196 DoUBBC(); 197 198 $convertstr = $message; 199 $convertcut = 50; 200 CountChars(); 201 $message = $convertstr; 202 if ($cliped) { $message .= ' ...'; } 203 204 ToChars($message); 205 $message =~ s/<(p|br|div).*?>/ /gxsm; 206 $message =~ s/<.*?>//gxsm; # remove HTML-tags 207 $message = Censor($message); 208 209 $messages[$counter] = 210 qq~<option value="$counter">~ 211 . ( $counter ? "$sstxt{'40'} $counter" : $sstxt{'41'} ) 212 . qq~: $message</option>\n~; 213 } 214 if ( ( $ttsureverse && ${ $uid . $username }{'reversetopic'} ) 215 || $ttsreverse ) 216 { 217 @messages = reverse @messages; 218 } 219 $positionlist = qq~<option value="end">$sstxt{'31'}</option>\n~; 220 $positionlist .= 221 qq~<option value="begin">$sstxt{'32'}</option>\n~; 222 $positionlist .= join q{}, @messages; 223 if ( $FORM{'position'} 224 && $newthread == $FORM{'old_position_thread'} ) 225 { 226 $positionlist =~ 227 s/(value="$FORM{'position'}")/$1 selected="selected"/xsm; 228 } 229 } 230 231 if ( $newthread eq 'new' 232 || !$threadlist 233 || $threadids !~ /\b$newthread\b/xsm ) 234 { 235 $my_output = $mymove_output_a; 236 $my_output =~ s/{yabb newthread_subject}/$FORM{'newthread_subject'}/sm; 237 $my_output =~ s/{yabb position}/$FORM{'position'}/sm; 238 $my_output =~ 239 s/{yabb old_position_thread}/$FORM{'old_position_thread'}/sm; 240 } 241 else { 242 $my_output = $mymove_output_b; 243 $my_output =~ s/{yabb positionlist}/$positionlist/sm; 244 $my_output =~ s/{yabb newthread_subject}/$FORM{'newthread_subject'}/sm; 245 $my_output =~ s/{yabb newthread}/$newthread/sm; 246 } 247 248 $my_checked = $FORM{'newinfo'} ? ' checked="checked"' : q{}; 249 250 $output = $mymove_top; 251 $output =~ s/{yabb formsession}/$formsession/sm; 252 $output =~ s/{yabb postlist}/$postlist/sm; 253 $output =~ s/{yabb leavelist}/$leavelist/sm; 254 $output =~ s/{yabb catlist}/$catlist/sm; 255 $output =~ s/{yabb boardlist}/$boardlist/sm; 256 $output =~ s/{yabb threadlist}/$threadlist/sm; 257 $output =~ s/{yabb my_output}/$my_output/sm; 258 $output =~ s/{yabb my_checked}/$my_checked/sm; 259 $output =~ s/{yabb size1}/$size1/sm; 260 261 print_output_header(); 262 print_HTML_output_and_finish(); 263 return; 264} 265 266sub Split_Splice_2 { 267 if ( !$staff && $INFO{'newboard'} ne $binboard ) { 268 fatal_error('split_splice_not_allowed'); 269 } 270 271 my $curboard = $INFO{'board'}; 272 my $curthreadid = $INFO{'thread'}; 273 my $movingposts = 274 exists $INFO{'oldposts'} ? $INFO{'oldposts'} : $FORM{'oldposts'}; 275 $FORM{'oldposts'} = $movingposts; 276 my $leavemess = exists $INFO{'leave'} ? $INFO{'leave'} : $FORM{'leave'}; 277 my $forcenewinfo = 278 exists $INFO{'newinfo'} ? $INFO{'newinfo'} : $FORM{'newinfo'}; 279 my $newcat = exists $INFO{'newcat'} ? $INFO{'newcat'} : $FORM{'newcat'}; 280 my $newboard = 281 exists $INFO{'newboard'} ? $INFO{'newboard'} : $FORM{'newboard'}; 282 my $newthreadid = 283 exists $INFO{'newthread'} ? $INFO{'newthread'} : $FORM{'newthread'}; 284 $FORM{'newthread'} = $newthreadid; 285 my $newthreadsub = 286 exists $INFO{'newthread_subject'} 287 ? $INFO{'newthread_subject'} 288 : $FORM{'newthread_subject'}; 289 my $newposition = 290 exists $INFO{'position'} ? $INFO{'position'} : $FORM{'position'}; 291 $FORM{'position'} = $newposition; 292 293 # Error messages if something is not filled out right 294 if ( $movingposts eq q{} ) { 295 fatal_error( q{}, "$sstxt{'22b'} $sstxt{'23'} $sstxt{'50'}" ); 296 } 297 if ( $newcat eq 'cats' ) { fatal_error( q{}, "$sstxt{'22'}" ); } 298 if ( $newboard eq 'boards' ) { fatal_error( q{}, "$sstxt{'22a'}" ); } 299 if ( -e "$datadir/$curthreadid.poll" && -e "$datadir/$newthreadid.poll" ) { 300 fatal_error( q{}, "$sstxt{'51'} $sstxt{'50'}" ); 301 } 302 303 my ( @postnum, @utdcurthread, @utdnewthread, $i ); 304 my $linkcount = 0; 305 306 # Get current thread posts 307 if ( !ref $thread_arrayref{$curthreadid} ) { 308 fopen( FILE, "$datadir/$curthreadid.txt" ); 309 @{ $thread_arrayref{$curthreadid} } = <FILE>; 310 fclose(FILE); 311 } 312 my @curthread = @{ $thread_arrayref{$curthreadid} }; 313 MessageTotals( 'load', $curthreadid ); 314 315 # Store post numbers to be moved in array 316 if ( ( split /\, /sm, $movingposts, 2 )[0] eq 'all' ) { 317 @postnum = ( 0 .. $#curthread ); 318 } 319 else { 320 @postnum = sort { $a <=> $b } split /\, /sm, $movingposts; 321 } # sort numerically ascending because may be reversed! 322 323# Check to see if current thread was the latest post for the board and if the last post was selected to change 324 BoardTotals( 'load', $curboard ); 325 if ( 326 ${$curthreadid}{'lastpostdate'} == ${ $uid . $curboard }{'lastposttime'} 327 && $leavemess == 2 328 && $postnum[-1] == $#curthread ) 329 { 330 $newest_post = 1; 331 } 332 333 # Move selected posts to a brand new thread 334 if ( $newthreadid eq 'new' ) { 335 336 # Find a valid random ID for new thread. 337 $newthreadid = ( split /\|/xsm, $curthread[ $postnum[0] ], 5 )[3] + 1; 338 while ( -e "$datadir/$newthreadid.txt" ) { $newthreadid++; } 339 340 foreach (@postnum) { 341 if ( $newthreadsub || $leavemess == 1 ) 342 { # insert new subject name || add 'no_postcount' into copies 343 my @x = split /\|/xsm, $curthread[$_]; 344 if ($newthreadsub) { 345 $x[0] = 346 $_ == $postnum[0] 347 ? $newthreadsub 348 : qq~$sstxt{'21'} $newthreadsub~; 349 } 350 if ( $leavemess == 1 ) { $x[5] = 'no_postcount'; } 351 push @utdnewthread, join q{|}, @x; 352 } 353 else { 354 push @utdnewthread, $curthread[$_]; 355 } 356 } 357 358 # Place selected posts in existing thread at selected position 359 } 360 else { 361 362 # Get existing thread posts 363 if ( !ref $thread_arrayref{$newthreadid} ) { 364 fopen( FILE, "$datadir/$newthreadid.txt" ); 365 @{ $thread_arrayref{$newthreadid} } = <FILE>; 366 fclose(FILE); 367 } 368 my @newthread = @{ $thread_arrayref{$newthreadid} }; 369 MessageTotals( 'load', $newthreadid ); 370 371 if ( $newposition eq 'end' ) { $newposition = $#newthread; } 372 elsif ( $newposition eq 'begin' ) { 373 foreach (@postnum) { 374 if ( $leavemess == 1 ) { # add 'no_postcount' into copies 375 my @x = split /\|/xsm, $curthread[$_]; 376 $x[5] = 'no_postcount'; 377 push @utdnewthread, join q{|}, @x; 378 } 379 else { 380 push @utdnewthread, $curthread[$_]; 381 } 382 } 383 $newposition = -1; 384 } 385 for my $i ( 0 .. ( @newthread - 1 ) ) { 386 push @utdnewthread, $newthread[$i]; 387 if ( $newposition == $i ) { 388 foreach (@postnum) { 389 if ( $leavemess == 1 ) { # add 'no_postcount' into copies 390 my @x = split /\|/xsm, $curthread[$_]; 391 $x[5] = 'no_postcount'; 392 push @utdnewthread, join q{|}, @x; 393 } 394 else { 395 push @utdnewthread, $curthread[$_]; 396 } 397 } 398 $linkcount = $i + 1; 399 } 400 } 401 } 402 403 # Remove or copy selected posts from current thread 404 if ( $#postnum == $#curthread && $leavemess != 1 ) { 405 if ( $newboard ne $binboard ) { 406 my ( $tmpsub, $tmpmessage ); 407 my $hidename = cloak($username); 408 ( $tmpsub, undef ) = split /\|/xsm, $curthread[0], 2; 409 if ( $curboard eq $newboard ) { 410 $tmpmessage = 411 qq~[m by=$hidename dest=$newthreadid/$linkcount#$linkcount]~; 412 $tmpsub = qq~[m by=$hidename dest=$newthreadid]: '$tmpsub'~; 413 } 414 else { 415 $tmpmessage = 416qq~[m by=$hidename destboard=$newboard dest=$newthreadid/$linkcount#$linkcount]~; 417 $tmpsub = 418qq~[m by=$hidename destboard=$newboard dest=$newthreadid]: '$tmpsub'~; 419 } 420 FromChars($tmpmessage); 421 $utdcurthread[0] = 422qq~$tmpsub|${$uid.$username}{'realname'}|${$uid.$username}{'email'}|$date|$username|no_postcount||$user_ip|$tmpmessage||||\n~; 423 424 if ( eval { require Variables::Movedthreads; 1 } ) { 425 $moved_file{$curthreadid} = $newthreadid; 426 delete $moved_file{$newthreadid}; 427 save_moved_file(); 428 $leavemess = 0; 429 } 430 } 431 else { 432 $leavemess = 2; 433 $forcenewinfo = 1; 434 } 435 } 436 elsif ( $leavemess != 1 ) { 437 if ( $newboard eq $binboard ) { $leavemess = 2; } 438 for my $i ( 0 .. ( @curthread - 1 ) ) { 439 if ( $movingposts =~ /\b$i\b/xsm ) { 440 if ( $leavemess == 0 && $i == $postnum[-1] ) { 441 my $tmpsub; 442 ( $tmpsub, undef ) = split /\|/xsm, $curthread[$i], 2; 443 push @utdcurthread, 444qq~$tmpsub|${$uid.$username}{'realname'}|${$uid.$username}{'email'}|$date|$username|no_postcount||$user_ip|[split] [link=$scripturl?num=$newthreadid/$linkcount#$linkcount][splithere][/link][splithere_end]||||\n~; 445 } 446 } 447 else { 448 push @utdcurthread, $curthread[$i]; 449 } 450 } 451 452 } 453 else { @utdcurthread = @curthread; } 454 455 if ($forcenewinfo) { 456 my ( $boardtitle, $tmpsub, $tmpmessage ); 457 ( $boardtitle, undef ) = split /\|/xsm, $board{$curboard}, 2; 458 $tmpmessage = ( 459 $#postnum == $#utdnewthread 460 ? '[b][movedhere]' 461 : '[b][postsmovedhere1] ' . @postnum . ' [postsmovedhere2]' 462 ) 463 . " [i]$boardtitle\[/i] [move by] [i]${$uid.$username}{'realname'}\[/i].[/b]"; 464 FromChars($tmpmessage); 465 ( $tmpsub, undef, undef, undef, undef, undef, undef ) = 466 split /\|/xsm, $utdnewthread[0], 7; 467 splice @utdnewthread, ( $linkcount + @postnum ), 0, 468qq~$sstxt{'21'} $tmpsub|${$uid.$username}{'realname'}|${$uid.$username}{'email'}|$date|$username|no_postcount||$user_ip|$tmpmessage||||\n~; 469 } 470 471 if (@utdcurthread) { 472 for my $i ( 0 .. ( @utdcurthread - 1 ) ) { # sort post numbers 473 my @x = split /\|/xsm, $utdcurthread[$i]; 474 $x[6] = $i; 475 $utdcurthread[$i] = join q{|}, @x; 476 } 477 478 # Update current thread 479 fopen( FILE, ">$datadir/$curthreadid.txt" ); 480 print {FILE} @utdcurthread or croak "$croak{'print'} FILE"; 481 fclose(FILE); 482 } 483 else { 484 require Sources::RemoveTopic; 485 my $moveit = $INFO{'moveit'}; 486 $INFO{'moveit'} = 1; 487 RemoveThread(); 488 $INFO{'moveit'} = $moveit; 489 } 490 491 for my $i ( 0 .. ( @utdnewthread - 1 ) ) { # sort post numbers 492 my @x = split /\|/xsm, $utdnewthread[$i]; 493 $x[6] = $i; 494 $utdnewthread[$i] = join q{|}, @x; 495 } 496 497 # Update new thread 498 fopen( FILE, ">$datadir/$newthreadid.txt" ); 499 print {FILE} @utdnewthread or croak "$croak{'print'} FILE"; 500 fclose(FILE); 501 502 # Update the .rlog files of the users 503 my ( 504 $reply, $ms, $mn, 505 $md, $mu, $mnp, 506 $mi, %mu, %curthreadusersdate, 507 %curthreaduserscount, %newthreadusersdate, %newthreaduserscount, 508 %BoardTotals 509 ); 510 $reply = 0; 511 foreach (@utdcurthread) 512 { # $subject|$name|$email|$date|$username|$icon|0|$user_ip|$message|$ns|||$fixfile 513 ( $ms, $mn, undef, $md, $mu, $mnp, undef, $mi, undef ) = 514 split /\|/xsm, $_, 9; 515 if ( ${ $BoardTotals{$curthreadid} }[0] <= $md ) { 516 $BoardTotals{$curthreadid} = [ $md, $mu, $reply, $ms, $mn, $mi ]; 517 } 518 $reply++; 519 next if $mnp eq 'no_postcount'; 520 if ( $curthreadusersdate{$mu} < $md ) { 521 $curthreadusersdate{$mu} = $md; 522 } 523 $curthreaduserscount{$mu}++; 524 $mu{$mu} = 1; 525 } 526 $reply = 0; 527 foreach (@utdnewthread) { 528 ( $ms, $mn, undef, $md, $mu, $mnp, undef, $mi, undef ) = 529 split /\|/xsm, $_, 9; 530 if ( ${ $BoardTotals{$newthreadid} }[0] <= $md ) { 531 $BoardTotals{$newthreadid} = [ $md, $mu, $reply, $ms, $mn, $mi ]; 532 } 533 $reply++; 534 next if $mnp eq 'no_postcount'; 535 if ( $newthreadusersdate{$mu} < $md ) { 536 $newthreadusersdate{$mu} = $md; 537 } 538 $newthreaduserscount{$mu}++; 539 $mu{$mu} = 1; 540 } 541 foreach my $mu ( keys %mu ) { 542 Recent_Load($mu); 543 delete $recent{$curthreadid}; 544 delete $recent{$newthreadid}; 545 if ( $curthreaduserscount{$mu} ) { 546 ${ $recent{$curthreadid} }[0] = $curthreaduserscount{$mu}; 547 ${ $recent{$curthreadid} }[1] = $curthreadusersdate{$mu}; 548 } 549 if ( $newthreaduserscount{$mu} ) { 550 ${ $recent{$newthreadid} }[0] = $newthreaduserscount{$mu}; 551 ${ $recent{$newthreadid} }[1] = $newthreadusersdate{$mu}; 552 } 553 Recent_Save($mu); 554 } 555 556 # For: Mark threads/boards as read 557 getlog(); 558 my $boardlog = 1; 559 560 # Mark new thread as read because you will be directed there at the end 561 delete $yyuserlog{"$newthreadid--unread"}; 562 $yyuserlog{$newthreadid} = $date; 563 564# Update .ctb, tags=>(board replies views lastposter lastpostdate threadstatus repliers) 565# curthread 566 ${$curthreadid}{'replies'} = $#utdcurthread; 567 ${$curthreadid}{'lastpostdate'} = ${ $BoardTotals{$curthreadid} }[0]; 568 ${$curthreadid}{'lastposter'} = 569 ${ $BoardTotals{$curthreadid} }[1] eq 'Guest' 570 ? "Guest-${$BoardTotals{$curthreadid}}[4]" 571 : ${ $BoardTotals{$curthreadid} }[1]; 572 573 # newthread 574 ${$newthreadid}{'replies'} = $#utdnewthread; 575 ${$newthreadid}{'lastpostdate'} = ${ $BoardTotals{$newthreadid} }[0]; 576 ${$newthreadid}{'lastposter'} = 577 ${ $BoardTotals{$newthreadid} }[1] eq 'Guest' 578 ? "Guest-${$BoardTotals{$newthreadid}}[4]" 579 : ${ $BoardTotals{$newthreadid} }[1]; 580 if ( $FORM{'newthread'} eq 'new' ) { 581 ${$newthreadid}{'board'} = $newboard; 582 ${$newthreadid}{'views'} = 583 $#postnum == $#curthread 584 ? ${$curthreadid}{'views'} 585 : ( $INFO{'ss_submit'} ? 1 : 0 ); 586 ${$newthreadid}{'threadstatus'} = ${$curthreadid}{'threadstatus'}; 587 ${$curthreadid}{'views'} = $#postnum == $#curthread 588 && $leavemess != 1 ? 0 : ${$curthreadid}{'views'}; 589 } 590 else { 591 ${$newthreadid}{'views'} += 592 int( ${$curthreadid}{'views'} / @curthread * @postnum ); 593 } 594 595 # Update current message index 596 fopen( BOARD, "<$boardsdir/$curboard.txt", 1 ); 597 my @curmessindex = <BOARD>; 598 fclose( BOARD ); 599 600 my $old_mstate; 601 for my $i ( 0 .. ( @curmessindex - 1 ) ) { 602 my ( 603 $mnum, $msub, $mname, $memail, $mdate, 604 $mreplies, $musername, $micon, $mstate 605 ) = split /\|/xsm, $curmessindex[$i]; 606 if ( $mdate > $yyuserlog{$curboard} ) { 607 $boardlog = 0; 608 } # For: Mark boards as read 609 if ( $mnum == $curthreadid ) { 610 chomp $mstate; 611 if ( $#postnum == $#curthread && $leavemess != 1 ) 612 { # thread was moved 613 my $hidename = cloak($username); 614 if ( $curboard eq $newboard ) { 615 $msub = qq~[m by=$hidename dest=$newthreadid]: '$msub'~; 616 } 617 else { 618 $msub = 619qq~[m by=$hidename destboard=$newboard dest=$newthreadid]: '$msub'~; 620 } 621 $mname = ${ $uid . $username }{'realname'}; 622 $memail = ${ $uid . $username }{'email'}; 623 $mreplies = 0; 624 $musername = $username; 625 626 # alter message icon to 'exclamation' to match status 'lm' 627 if ( $micon ne 'no_postcount' ) { $micon = 'exclamation'; } 628 629 # thread status - (a)nnoumcement, (h)idden, (l)ocked, (m)oved and (s)ticky 630 $old_mstate = $mstate; 631 if ( $curboard eq $annboard && $mstate !~ /a/ism ) { 632 $mstate .= 'a'; 633 } 634 if ( $mstate !~ /l/ism ) { $mstate .= 'l'; } 635 if ( $mstate !~ /m/ism ) { $mstate .= 'm'; } 636 ${$curthreadid}{'threadstatus'} = $mstate; 637 } 638 else { 639 ( $msub, $mname, $memail, undef, $musername, $micon, undef ) = 640 split /\|/xsm, $utdcurthread[0], 7; 641 $mreplies = ${$curthreadid}{'replies'}; 642 } 643 $curmessindex[$i] = 644qq~$mnum|$msub|$mname|$memail|${$curthreadid}{'lastpostdate'}|$mreplies|$musername|$micon|$mstate\n~; 645 ${ $BoardTotals{$mnum} }[6] = $mstate; 646 647 } 648 elsif ( $mnum == $newthreadid ) { 649 chomp $mstate; 650 if ( $FORM{'position'} eq 'begin' ) { 651 ( $msub, $mname, $memail, undef, $musername, $micon, undef ) = 652 split /\|/xsm, $utdnewthread[0], 7; 653 } 654 $yyThreadLine = $curmessindex[$i] = 655qq~$mnum|$msub|$mname|$memail|${$newthreadid}{'lastpostdate'}|${$newthreadid}{'replies'}|$musername|$micon|$mstate\n~; 656 ${ $BoardTotals{$mnum} }[6] = $mstate; 657 if ( 658 ( $enable_notifications == 1 || $enable_notifications == 3 ) 659 && ( -e "$boardsdir/$curboard.mail" 660 || -e "$datadir/$newthreadid.mail" ) 661 ) 662 { 663 require Sources::Post; 664 $currentboard = $curboard; 665 $msub = Censor($msub); 666 ReplyNotify( $newthreadid, $msub, ${$newthreadid}{'replies'} ); 667 } 668 } 669 } 670 if ( $curboard eq $newboard && $FORM{'newthread'} eq 'new' ) { 671 my ( $msub, $mname, $memail, $musername, $micon ); 672 ( $msub, $mname, $memail, undef, $musername, $micon, undef ) = 673 split /\|/xsm, $utdnewthread[0], 7; 674 if ( $old_mstate !~ /0/ism ) { $old_mstate .= '0'; } 675 $yyThreadLine = 676qq~$newthreadid|$msub|$mname|$memail|${$newthreadid}{'lastpostdate'}|${$newthreadid}{'replies'}|$musername|$micon|$old_mstate\n~; 677 unshift @curmessindex, $yyThreadLine; 678 ${ $BoardTotals{$newthreadid} }[6] = $old_mstate; 679 if ( ( $enable_notifications == 1 || $enable_notifications == 3 ) 680 && -e "$boardsdir/$newboard.mail" ) 681 { 682 require Sources::Post; 683 $currentboard = $curboard; 684 $msub = Censor($msub); 685 NewNotify( $newthreadid, $msub ); 686 } 687 } 688 fopen( BOARD, ">$boardsdir/$curboard.txt", 1 ); 689 print {BOARD} reverse 690 sort { ( split /\|/xsm, $a, 6 )[4] <=> ( split /\|/xsm, $b, 6 )[4] } 691 @curmessindex 692 or croak "$croak{'print'} BOARD"; 693 fclose( BOARD ); 694 695 if ($boardlog) { 696 $yyuserlog{$curboard} = $date; 697 } # For: Mark boards as read 698 699 # Update new message index if needed 700 if ( $curboard ne $newboard ) { 701 $boardlog = 1; # For: Mark boards as read 702 703 fopen( BOARD, "+<$boardsdir/$newboard.txt", 1 ); 704 seek BOARD, 0, 0; 705 my @newmessindex = <BOARD>; 706 truncate BOARD, 0; 707 seek BOARD, 0, 0; 708 709 if ( $FORM{'newthread'} eq 'new' ) { 710 711 # For: Mark boards as read 712 foreach (@newmessindex) { 713 if ( ( split /\|/xsm, $_, 6 )[4] > $yyuserlog{$newboard} ) { 714 $boardlog = 0; 715 } 716 last if !$boardlog; 717 } 718 719 my ( $msub, $mname, $memail, undef, $musername, $micon, undef ) = 720 split /\|/xsm, $utdnewthread[0], 7; 721 if ( $old_mstate =~ /a/ism ) { 722 if ( $newboard ne $annboard ) { $old_mstate =~ s/a//gism; } 723 } 724 elsif ( $newboard eq $annboard ) { 725 $old_mstate .= 'a'; 726 } 727 if ( $old_mstate !~ /0/ism ) { $old_mstate .= '0'; } 728 $yyThreadLine = 729qq~$newthreadid|$msub|$mname|$memail|${$newthreadid}{'lastpostdate'}|${$newthreadid}{'replies'}|$musername|$micon|$old_mstate\n~; 730 unshift @newmessindex, $yyThreadLine; 731 ${ $BoardTotals{$newthreadid} }[6] = $old_mstate; 732 if ( ( $enable_notifications == 1 || $enable_notifications == 3 ) 733 && -e "$boardsdir/$newboard.mail" ) 734 { 735 require Sources::Post; 736 $currentboard = $newboard; 737 $msub = Censor($msub); 738 NewNotify( $newthreadid, $msub ); 739 } 740 } 741 else { 742 for my $i ( 0 .. ( @newmessindex - 1 ) ) { 743 my ( 744 $mnum, $msub, $mname, $memail, $mdate, 745 $mreplies, $musername, $micon, $mstate 746 ) = split /\|/xsm, $newmessindex[$i]; 747 if ( $mdate > $yyuserlog{$newboard} ) { 748 $boardlog = 0; 749 } # For: Mark boards as read 750 if ( $mnum == $newthreadid ) { 751 chomp $mstate; 752 if ( $FORM{'position'} eq 'begin' ) { 753 ( 754 $msub, $mname, $memail, undef, $musername, $micon, 755 undef 756 ) = split /\|/xsm, $utdnewthread[0], 7; 757 } 758 $yyThreadLine = $newmessindex[$i] = 759qq~$mnum|$msub|$mname|$memail|${$newthreadid}{'lastpostdate'}|${$newthreadid}{'replies'}|$musername|$micon|$mstate\n~; 760 ${ $BoardTotals{$mnum} }[6] = $mstate; 761 } 762 } 763 if ( 764 ( $enable_notifications == 1 || $enable_notifications == 3 ) 765 && ( -e "$boardsdir/$newboard.mail" 766 || -e "$datadir/$newthreadid.mail" ) 767 ) 768 { 769 require Sources::Post; 770 $currentboard = $newboard; 771 $msub = Censor($msub); 772 ReplyNotify( $newthreadid, $msub, ${$newthreadid}{'replies'} ); 773 } 774 } 775 print {BOARD} reverse 776 sort { ( split /\|/xsm, $a, 6 )[4] <=> ( split /\|/xsm, $b, 6 )[4] } 777 @newmessindex 778 or croak "$croak{'print'} BOARD"; 779 fclose(BOARD); 780 781 if ($boardlog) { 782 $yyuserlog{$newboard} = $date; 783 } # For: Mark boards as read 784 } 785 786 if (@utdcurthread) { MessageTotals( 'update', $curthreadid ); } 787 MessageTotals( 'update', $newthreadid ); 788 789# update current board totals 790# BoardTotals- tags => (board threadcount messagecount lastposttime lastposter lastpostid lastreply lastsubject lasticon lasttopicstate) 791#&BoardTotals("load", $curboard); - Load this at top now to detect if newest board post is being moved - Unilat 792 if ( ${ $BoardTotals{$curthreadid} }[6] =~ /m/sm ) { # Moved-Info thread 793 if ( $curboard ne $newboard ) { 794 ${ $uid . $curboard }{'threadcount'}--; 795 ${ $uid . $curboard }{'messagecount'} -= @postnum; 796 } 797 BoardSetLastInfo( $curboard, \@curmessindex ); 798 } 799 else { 800 if ( $FORM{'newthread'} eq 'new' && $curboard eq $newboard ) { 801 ${ $uid . $curboard }{'threadcount'}++; 802 } 803 if ( $leavemess == 0 ) { 804 if ( $curboard ne $newboard ) { 805 ${ $uid . $curboard }{'messagecount'} -= $#postnum; 806 } 807 else { 808 ${ $uid . $curboard }{'messagecount'} += 809 ( $forcenewinfo ? 2 : 1 ); 810 } 811 } 812 elsif ( $leavemess == 1 && $curboard eq $newboard ) { 813 ${ $uid . $curboard }{'messagecount'} += 814 $#postnum + ( $forcenewinfo ? 1 : 0 ); 815 } 816 elsif ( $leavemess == 2 && $curboard ne $newboard && @utdcurthread ) { 817 ${ $uid . $curboard }{'messagecount'} -= @postnum; 818 } 819 if ( 820 $newest_post 821 || ( 822 ( 823 ( 824 ${ $uid . $curboard }{'threadcount'} == 1 825 && @utdcurthread 826 ) 827 || ${ $BoardTotals{$curthreadid} }[0] >= 828 ${ $uid . $curboard }{'lastposttime'} 829 ) 830 && ( $curboard ne $newboard 831 || ${ $BoardTotals{$curthreadid} }[0] >= 832 ${ $BoardTotals{$newthreadid} }[0] ) 833 ) 834 ) 835 { 836 ${ $uid . $curboard }{'lastposttime'} = 837 ${ $BoardTotals{$curthreadid} }[0]; 838 ${ $uid . $curboard }{'lastposter'} = 839 ${ $BoardTotals{$curthreadid} }[1] eq 'Guest' 840 ? "Guest-${$BoardTotals{$curthreadid}}[4]" 841 : ${ $BoardTotals{$curthreadid} }[1]; 842 ${ $uid . $curboard }{'lastpostid'} = $curthreadid; 843 ${ $uid . $curboard }{'lastreply'} = 844 ${ $BoardTotals{$curthreadid} }[2]--; 845 ${ $uid . $curboard }{'lastsubject'} = 846 ${ $BoardTotals{$curthreadid} }[3]; 847 ${ $uid . $curboard }{'lasticon'} = 848 ${ $BoardTotals{$curthreadid} }[5]; 849 ${ $uid . $curboard }{'lasttopicstate'} = 850 ${ $BoardTotals{$curthreadid} }[6]; 851 } 852 elsif ( ${ $BoardTotals{$newthreadid} }[0] >= 853 ${ $uid . $curboard }{'lastposttime'} 854 && $curboard eq $newboard ) 855 { 856 ${ $uid . $curboard }{'lastposttime'} = 857 ${ $BoardTotals{$newthreadid} }[0]; 858 ${ $uid . $curboard }{'lastposter'} = 859 ${ $BoardTotals{$newthreadid} }[1] eq 'Guest' 860 ? "Guest-${$BoardTotals{$newthreadid}}[4]" 861 : ${ $BoardTotals{$newthreadid} }[1]; 862 ${ $uid . $curboard }{'lastpostid'} = $newthreadid; 863 ${ $uid . $curboard }{'lastreply'} = 864 ${ $BoardTotals{$newthreadid} }[2]--; 865 ${ $uid . $curboard }{'lastsubject'} = 866 ${ $BoardTotals{$newthreadid} }[3]; 867 ${ $uid . $curboard }{'lasticon'} = 868 ${ $BoardTotals{$newthreadid} }[5]; 869 ${ $uid . $curboard }{'lasttopicstate'} = 870 ${ $BoardTotals{$newthreadid} }[6]; 871 } 872 BoardSetLastInfo( $curboard, \@curmessindex ); 873 } 874 875 # update new board totals if needed 876 if ( $curboard ne $newboard ) { 877 BoardTotals( 'load', $newboard ); 878 if ( $FORM{'newthread'} eq 'new' ) { 879 ${ $uid . $newboard }{'threadcount'}++; 880 } 881 ${ $uid . $newboard }{'messagecount'} += 882 @postnum + ( $forcenewinfo ? 1 : 0 ); 883 if ( ${ $uid . $newboard }{'threadcount'} == 1 884 || ${ $BoardTotals{$newthreadid} }[0] >= 885 ${ $uid . $newboard }{'lastposttime'} ) 886 { 887 ${ $uid . $newboard }{'lastposttime'} = 888 ${ $BoardTotals{$newthreadid} }[0]; 889 ${ $uid . $newboard }{'lastposter'} = 890 ${ $BoardTotals{$newthreadid} }[1] eq 'Guest' 891 ? "Guest-${$BoardTotals{$newthreadid}}[4]" 892 : ${ $BoardTotals{$newthreadid} }[1]; 893 ${ $uid . $newboard }{'lastpostid'} = $newthreadid; 894 ${ $uid . $newboard }{'lastreply'} = 895 ${ $BoardTotals{$newthreadid} }[2]--; 896 ${ $uid . $newboard }{'lastsubject'} = 897 ${ $BoardTotals{$newthreadid} }[3]; 898 ${ $uid . $newboard }{'lasticon'} = 899 ${ $BoardTotals{$newthreadid} }[5]; 900 ${ $uid . $newboard }{'lasttopicstate'} = 901 ${ $BoardTotals{$newthreadid} }[6]; 902 } 903 BoardTotals( 'update', $newboard ); 904 } 905 906 # now fix all attachments.txt info 907 my $attachments; 908 for my $i ( $postnum[0] .. ( @curthread - 1 ) ) 909 { # see if old thread had attachments 910 $attachments = ( split /\|/xsm, $curthread[$i] )[12]; 911 chomp $attachments; 912 if ($attachments) { 913 $attachments = 1; 914 last; 915 } 916 } 917 if ( !$attachments ) { # see if new thread has attachments 918 for my $i ( $linkcount .. ( @utdnewthread - 1 ) ) { 919 $attachments = ( split /\|/xsm, $utdnewthread[$i] )[12]; 920 chomp $attachments; 921 if ($attachments) { 922 $attachments = 2; 923 last; 924 } 925 } 926 } 927 if ($attachments) { 928 my ( @newattachments, %attachments ); 929 fopen( ATM, "<$vardir/attachments.txt", 1 ) 930 or fatal_error( 'cannot_open', "$vardir/attachments.txt", 1 ); 931 my @attach = <ATM>; 932 fclose(ATM); 933 for (@attach) { 934 my ( 935 $attid, undef, undef, undef, undef, undef, undef, 936 $attachmentname, $downloadscount 937 ) = split /\|/xsm, $_; 938 if ( ( $attid != $curthreadid && $attid != $newthreadid ) 939 || ( $attid == $curthreadid && $attachments != 1 ) ) 940 { 941 push @newattachments, $_; 942 } 943 chomp $downloadscount; 944 $attachments{$attachmentname} = $downloadscount; 945 } 946 947 my $mreplies = 0; 948 if ( $attachments == 1 ) { 949 foreach (@utdcurthread) { # fix new old thread attachments 950 my ( 951 $msub, $mname, undef, $mdate, undef, undef, undef, 952 undef, undef, undef, undef, undef, $mfn 953 ) = split /\|/xsm, $_; 954 chomp $mfn; 955 foreach ( split /,/xsm, $mfn ) { 956 if ( -e "$uploaddir/$_" ) { 957 my $asize = int( ( -s "$uploaddir/$_" ) / 1024 ) 958 || 1; 959 push @newattachments, 960qq~$curthreadid|$mreplies|$msub|$mname|$curboard|$asize|$mdate|$_|~ 961 . ( $attachments{$_} || 0 ) . qq~\n~; 962 } 963 } 964 $mreplies++; 965 } 966 } 967 968 $mreplies = 0; 969 foreach (@utdnewthread) { # fix new thread attachments 970 my ( 971 $msub, $mname, undef, $mdate, undef, undef, undef, 972 undef, undef, undef, undef, undef, $mfn 973 ) = split /\|/xsm, $_; 974 chomp $mfn; 975 foreach ( split /,/xsm, $mfn ) { 976 if ( -e "$uploaddir/$_" ) { 977 my $asize = int( ( -s "$uploaddir/$_" ) / 1024 ) || 1; 978 push @newattachments, 979qq~$newthreadid|$mreplies|$msub|$mname|$newboard|$asize|$mdate|$_|~ 980 . ( $attachments{$_} || 0 ) . qq~\n~; 981 } 982 } 983 $mreplies++; 984 } 985 fopen( FATM, ">$vardir/attachments.txt" ) 986 or fatal_error( 'cannot_open', "$vardir/attachments.txt" ); 987 print {FATM} 988 sort { ( split /\|/xsm, $a, 8 )[6] <=> ( split /\|/xsm, $b, 8 )[6] } 989 @newattachments or croak "$croak{'print'} ATM"; 990 fclose(FATM); 991 } 992 993 if ( $#postnum == $#curthread ) { 994 if ( -e "$datadir/$curthreadid.poll" ) { 995 rename 996 "$datadir/$curthreadid.poll", 997 "$datadir/$newthreadid.poll"; 998 } 999 if ( -e "$datadir/$curthreadid.polled" ) { 1000 rename 1001 "$datadir/$curthreadid.polled", 1002 "$datadir/$newthreadid.polled"; 1003 } 1004 if ( -e "$datadir/$curthreadid.mail" ) { 1005 rename 1006 "$datadir/$curthreadid.mail", 1007 "$datadir/$newthreadid.mail"; 1008 require Sources::Notify; 1009 ManageThreadNotify( 'load', $newthreadid ); 1010 my (%t); 1011 foreach my $u ( keys %thethread ) { 1012 LoadUser($u); 1013 foreach ( split /,/xsm, ${ $uid . $u }{'thread_notifications'} ) 1014 { 1015 $t{$_} = 1; 1016 } 1017 delete $t{$curthreadid}; 1018 $t{$newthreadid} = 1; 1019 ${ $uid . $u }{'thread_notifications'} = join q{,}, keys %t; 1020 UserAccount($u); 1021 undef %t; 1022 } 1023 } 1024 } 1025 1026 # Mark current thread as read 1027 delete $yyuserlog{"$curthreadid--unread"}; 1028 dumplog($curthreadid); # Save threads/boards as read 1029 1030 chomp $yyThreadLine; 1031 1032 if ( $INFO{'moveit'} == 1 ) { 1033 $currentboard = $curboard; 1034 return; 1035 } 1036 if ( $INFO{'ss_submit'} ) { 1037 $currentboard = $newboard; 1038 $INFO{'num'} = $INFO{'thread'} = $FORM{'threadid'} = $curnum = 1039 $newthreadid; 1040 redirectinternal(); 1041 } 1042 if ( $debug == 1 or ( $debug == 2 && $iamadmin ) ) { 1043 require Sources::Debug; 1044 Debug(); 1045 $yydebug = 1046qq~\n- $#utdnewthread<br />\n- @utdnewthread<br />\n- ${$newthreadid}{'lastpostdate'}<br />\n- ${$newthreadid}{'lastposter'}<br />\n- \$enable_notifications == $enable_notifications<br />\n- \$attachments = $attachments<br />\n<a href="javascript:load_thread($newthreadid,$linkcount);">continue</a>\n$yydebug~; 1047 } 1048 1049 print_output_header(); 1050 1051 $output = 1052qq~<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 1053<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="$abbr_lang" lang="$abbr_lang"> 1054<head> 1055<title>$sstxt{'1'}</title> 1056<meta http-equiv="Content-Type" content="text/html; charset=$yymycharset" /> 1057<script type="text/javascript"> 1058 function load_thread(threadid,replies) { 1059 try{ 1060 if (typeof(opener.document) == 'object') throw '1'; 1061 else throw '0'; 1062 } catch (e) { 1063 if (replies > 0 || ~ 1064 . ( 1065 ( 1066 ( $ttsureverse && ${ $uid . $username }{'reversetopic'} ) 1067 || $ttsreverse 1068 ) ? 1 : 0 1069 ) 1070 . qq~ == 1) replies = '/' + replies + '#' + replies; 1071 else replies = ''; 1072 if (e == 1) { 1073 opener.focus(); 1074 opener.location.href='$scripturl?num=' + threadid + replies; 1075 self.close(); 1076 } else { 1077 location.href='$scripturl?num=' + threadid + replies; 1078 } 1079 } 1080 } 1081</script> 1082</head> 1083<body onload="load_thread($newthreadid,$linkcount);"> 1084 $yydebug 1085</body> 1086</html>~; 1087 1088 print_HTML_output_and_finish(); 1089 return; 1090} 1091 10921; 1093