#!/usr/bin/perl #------------------------------------------------------------------------------ # mwForum - Web-based discussion forum # Copyright (c) 1999-2015 Markus Wichitill # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. #------------------------------------------------------------------------------ use strict; use warnings; no warnings qw(uninitialized redefine); # Imports use MwfMain; #------------------------------------------------------------------------------ # Init my ($m, $cfg, $lng, $user, $userId) = MwfMain->new($_[0], autocomplete => 1); $m->cacheUserStatus() if $userId; # Check if access should be denied $cfg->{attachList} || $user->{admin} or $m->error('errNoAccess'); $cfg->{attachList} != 2 || $userId or $m->error('errNoAccess'); # Print header $m->printHeader(); # Get CGI parameters my $page = $m->paramInt('pg') || 1; my $words = $m->paramStr('words'); my $userName = $m->paramStr('user'); my $categBoardIdStr = $m->paramStrId('board') || "0"; # Sanitize later my $field = $m->paramStrId('field') || 'filename'; my $minAge = $m->paramInt('min'); my $maxAge = $m->paramInt('max'); my $order = $m->paramStr('order') || 'desc'; my $gallery = $m->paramBool('gallery'); # Enforce valid options $minAge = $m->min($minAge, 24855); $maxAge = $m->min($maxAge, 24855); $field = 'filename' if $field !~ /^(?:filename|caption)\z/; $order = 'desc' if $order !~ /^(?:asc|desc)\z/; $gallery = 0 if !$cfg->{attachGallery}; # Preserve parameters in links my @params = ( words => $words, user => $userName, board => $categBoardIdStr, field => $field, min => $minAge, max => $maxAge, order => $order, gallery => $gallery ); # Get visible boards with attachments enabled my $boards = $m->fetchAllHash(" SELECT boards.*, categories.title AS categTitle FROM boards AS boards INNER JOIN categories AS categories ON categories.id = boards.categoryId WHERE boards.attach > 0 ORDER BY categories.pos, boards.pos"); @$boards = grep($m->boardVisible($_), @$boards); # Search words my $fieldStr = "attachments.$field"; my $like = $m->{pgsql} ? 'ILIKE' : 'LIKE'; my $wordsLike = $m->dbEscLike($words); my @words = $wordsLike =~ /"[^"]+"|[^"\s]+/g; splice(@words, 10) if @words > 10; my @wordPreds = (); my @wordValues = (); for (my $i = 0; $i < @words; $i++) { $words[$i] =~ s/"//g; $words[$i] = $m->escHtml($words[$i]); push @wordPreds, "$fieldStr $like :word$i"; push @wordValues, "word$i" => "%$words[$i]%"; } my $wordStr = @wordPreds ? "AND (" . join(" AND ", @wordPreds) . ")" : ""; # Search username my $userNameLike = "%" . $m->dbEscLike($userName) . "%"; my $userNameStr = $userName ? "AND posts.userNameBak LIKE :userNameLike" : ""; # Limit to age my $minAgeStr = $minAge ? "AND posts.postTime < :now - :minAge * 86400" : ""; my $maxAgeStr = $maxAge ? "AND posts.postTime > :now - :maxAge * 86400" : ""; # Limit to category or board my $boardJoinStr = ""; my $boardStr = ""; my $boardId = 0; if ($categBoardIdStr =~ /^bid([0-9]+)\z/) { $boardStr = "AND posts.boardId = $1"; $boardId = $1; } elsif ($categBoardIdStr =~ /^cid([0-9]+)\z/) { $boardJoinStr = "INNER JOIN boards AS boards ON boards.id = posts.boardId"; $boardStr = "AND boards.categoryId = $1"; $boardId = 0; } # Get ids of attachments my $galleryStr = $gallery ? "AND attachments.webImage > 0" : ""; my @boardIds = map($_->{id}, @$boards); my $attachments = $m->fetchAllArray(" SELECT attachments.id FROM attachments AS attachments INNER JOIN posts AS posts ON posts.id = attachments.postId $boardJoinStr WHERE posts.boardId IN (:boardIds) $wordStr $userNameStr $minAgeStr $maxAgeStr $galleryStr $boardStr ORDER BY attachments.id $order", { @wordValues, userNameLike => $userNameLike, now => $m->{now}, minAge => $minAge, maxAge => $maxAge, boardIds => \@boardIds }); # Print page bar my $attachmentsPP = $gallery ? ($cfg->{attachGallPP} || 12) : ($cfg->{attachPP} || 25); my $pageNum = int(@$attachments / $attachmentsPP) + (@$attachments % $attachmentsPP != 0); my @pageLinks = $pageNum < 2 ? () : $m->pageLinks('attach_list', \@params, $page, $pageNum); my @navLinks = ({ url => $m->url('forum_show'), txt => 'comUp', ico => 'up' }); $m->printPageBar(mainTitle => $lng->{aliTitle}, navLinks => \@navLinks, pageLinks => \@pageLinks); # Get attachments on page my @pageAttachIds = @$attachments[($page - 1) * $attachmentsPP .. $m->min($page * $attachmentsPP, scalar @$attachments) - 1]; @pageAttachIds = map($_->[0], @pageAttachIds); $attachments = $m->fetchAllHash(" SELECT attachments.*, posts.userId, posts.userNameBak FROM attachments AS attachments INNER JOIN posts AS posts ON posts.id = attachments.postId WHERE attachments.id IN (:pageAttachIds) ORDER BY attachments.id $order", { pageAttachIds => \@pageAttachIds }); # Determine checkbox, radiobutton and listbox states my $galleryChk = $gallery ? 'checked' : ""; my %state = ( $categBoardIdStr => 'selected', $field => 'selected', $order => 'selected' ); # Display age 0 as empty string $minAge = $minAge ? $minAge : ""; $maxAge = $maxAge ? $maxAge : ""; # Escape submitted values my $wordsEsc = $m->escHtml($words); my $userNameEsc = $m->escHtml($userName); # Print attachment list form print "
\n", "
\n", "
$lng->{aliLfmTtl}
\n", "
\n", "
\n", "\n", "\n", "\n", "
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", $cfg->{attachGallery} ? "\n" : "", $m->submitButton('aliLfmListB', 'search'), "
\n", "
\n", "
\n", "
\n\n"; # Print normal attachment list if (!$gallery) { print "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n"; for my $attach (@$attachments) { my $fileName = $attach->{fileName}; my $postId = $attach->{postId}; my $postIdMod = $postId % 100; my $attShowUrl = $attach->{webImage} ? $m->url('attach_show', aid => $attach->{id}) : "$cfg->{attachUrlPath}/$postIdMod/$postId/$fileName"; my $postUrl = $m->url('topic_show', pid => $postId); my $size = -s $m->encFsPath("$cfg->{attachFsPath}/$postIdMod/$postId/$fileName"); my $sizeStr = $m->formatSize($size); my $userUrl = $m->url('user_info', uid => $attach->{userId}); my $userNameStr = $attach->{userNameBak} || " - "; $userNameStr = "$userNameStr" if $attach->{userId} > 0; print "\n", "\n", "\n", "\n", "\n", "\n", "\n"; } print "
$lng->{aliLstFile}$lng->{aliLstCapt}$lng->{aliLstSize}$lng->{aliLstPost}$lng->{aliLstUser}
$fileName$attach->{caption}$sizeStr$postId$userNameStr
\n\n"; } # Print attachment image gallery else { print "\n\n"; for (my $i = 0; $i < @$attachments; $i++) { print "\n" if $i && $i % 4 == 0; # Determine values my $attach = @$attachments[$i]; my $fileName = $attach->{fileName}; my $postId = $attach->{postId}; my $postIdMod = $postId % 100; my $imgFile = "$cfg->{attachFsPath}/$postIdMod/$postId/$fileName"; my $imgUrl = "$cfg->{attachUrlPath}/$postIdMod/$postId/$fileName"; my $imgShowUrl = $m->url('attach_show', aid => $attach->{id}); my $thbFile = $imgFile; my $thbUrl = $imgUrl; $thbFile =~ s!\.(?:jpg|png|gif)\z!.thb.jpg!i; $thbUrl =~ s!\.(?:jpg|png|gif)\z!.thb.jpg!i; my $size = -s $m->encFsPath($imgFile); my $sizeStr = $m->formatSize($size); my $useThb = -f $m->encFsPath($thbFile) || $m->addThumbnail($imgFile); my $postUrl = $m->url('topic_show', pid => $postId); my $src = $useThb ? $thbUrl : $imgUrl; my $thbStr = $useThb >= 0 ? "" : ($size ? "?" : "404"); # Print image and file size print "\n"; } # Print rest of table my $empty = 4 - @$attachments % 4; $empty = 0 if $empty == 4; print "\n" while $empty-- > 0; print "\n", "
\n", "
$thbStr
\n", "
$fileName
\n", "
$attach->{caption}
\n", "
\n\n"; } # Log action and finish $m->logAction(3, 'attach', 'list', $userId, $boardId); $m->printFooter(); $m->finish();