# Copyright (C) 2008 Eric Hsu # 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 2 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. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the # Free Software Foundation, Inc. # 59 Temple Place, Suite 330 # Boston, MA 02111-1307 USA $ModulesDescription .= '

$Id: searchpaged-bfc.pl,v 0.2a 2008/07/16 23:20:09 Eric Hsu Exp $

'; use vars qw($ResultsPerPage); # ====================== # = searchresultspaged = # ====================== # SearchTitleAndBodyPage is like SearchTitleAndBody except that it outputs results in groups of $ResultsPerPage (5 default). We get the 'page' param to find the start point. We still expect to use &$func on each found $id to print the search result. # The navigation links are in the class "searchpagenav". Consider using CSS to center and enlarge it. $ResultsPerPage=5; *OldDoSearch = *DoSearch; *DoSearch = *DoSearchPaged; # DoSearchPaged, in addition to showing search results in pages, also allows you to send it # an array ref of results which will override the actual search algorithm to display the array of results. sub DoSearchPaged { my $string = shift; # return DoIndex() if $string eq ''; if ($string eq '') { SetParam('msg', T("Oops, you submitted an empty search!")); return; } my $replacement = GetParam('replace',undef); my $raw = GetParam('raw',''); my @results; if ($replacement or GetParam('delete', 0) or $raw) { OldDoSearch(); } else { unless (ref($string)) { print GetHeader('', Ts('Search for: %s', $string)), $q->start_div({-class=>'content search'}); } else { print GetHeader('', T('Your Current Cart')), $q->start_div({-class=>'content cart'}); } my ($start, $end, $total); unless (ref($string)) { ($start, $end, $total) = SearchTitleAndBodyPage($string, \&PrintSearchResult, HighlightRegex($string)); } else { ($start, $end, $total) = SearchTitleAndBodyPage($string, \&PrintSearchResult, undef); } my $jumpmenu; my $scriptlinks; my $thispageaction; unless (ref($string)) { $thispageaction = 'search=' . UrlEncode($string); } else { $thispageaction = 'action=cart'; } my $perpage = GetParam('perpage', $ResultsPerPage); my $page = GetParam('page', 1); my $lastpage = int($total/$perpage); if ( $lastpage < ($total/$perpage) ) { $lastpage++; } if ($total > $perpage) { my $prev= $page-1; my $next= $page+1; print Tss("Showing %1 to %2 out of %3 matches.", $start, $end, $total); $scriptlinks .= ScriptLink($thispageaction . ';page=' . $prev . ";perpage=" . $perpage, "<—" . T("Previous") . " " ) if ($page>1); # Make the little menu to jump from page to page. foreach $thispage (1..($lastpage)) { if ($thispage == $page) { $scriptlinks .= "" . $page . " "; } else { $scriptlinks .= ScriptLink($thispageaction . ';page=' . $thispage . ";perpage=" . $perpage, $thispage . " " ); } } $scriptlinks .= ScriptLink($thispageaction . ';page=' . $next . ";perpage=" . $perpage, T("Next") . "—>" ) if ($page<$lastpage); } if ($total == 0) { print T("Sorry, no items to show!"); } print $q->end_div(); print $q->p({-class=>'searchpagenav'}, $scriptlinks); PrintFooter(); } } sub SearchTitleAndBodyPage { my ($string, $func, @args) = @_; my @found; unless (ref($string)) { @found = SearchTitleAndBody($string, undef, undef); } else { @found = @$string; } return ShowResultsInPages(\@found, @_); } # @$found should be an array of names of items to display. sub ShowResultsInPages { my ($found, $string, $func, @args) = @_; my @found=@$found; my $total = scalar @found; my $page = GetParam('page', 1); my $perpage = GetParam('perpage', $ResultsPerPage); my $startpage = ($page - 1)*$perpage; my $endpage = ($page*$perpage)-1; if ($startpage+1 > $total) { my $diff = ( $startpage - $total ); my $diffpages = int($diff/$perpage); $diffpages += 1; $startpage -= ($perpage * $diffpages); $endpage = $startpage + $perpage - 1; } foreach $num ($startpage..$endpage){ my $id = $found[$num]; unless ($id) { last; } $endpage= $num; &$func($id, @args) if $func; # push @foundonpage, $id; } return ($startpage+1, $endpage+1, $total); } # OPTIMIZE. can we cache search results? maybe cache results of SearchTitleAndBody as a list of matched $id, with a timestamp and then only search more recent changes (beware minor edits). # Index it on recent changes? Just search changed pages? # Considered saving the last page searched, but doesn't quite work. # $CookieParameters{'page'}=1; # default first page $CookieParameters{'atatime'}=5; # default first page # $InvisibleCookieParameters{'page'}=1; $InvisibleCookieParameters{'atatime'}=1; __END__ = searchpaged.pl (0.2a) Fixed a display bug, so now pages past the end of results show the last page. Particularly helpful for carts where we delete something and move to the next page. (0.2) Rewrote innards to factor out the displaying in pages piece, to accommodate cart routines wanting to reuse the search display framework. (0.1a) Fixed the extra ghost results page bug. (0.1) First working version.