@@ -, +, @@ - modifies opac-showreviews.pl to display recent comments for all titles, sorted in descending order by date. - includes RSS feed - includes (thanks to Chris N.): --- C4/Dates.pm | 274 ++++++++++++-------- C4/Review.pm | 20 +- koha-tmpl/opac-tmpl/prog/en/css/opac.css | 28 ++- .../prog/en/modules/opac-showreviews-rss.tmpl | 36 +++ .../prog/en/modules/opac-showreviews.tmpl | 100 ++++++-- opac/opac-showreviews.pl | 128 +++++++++- t/Dates.t | 115 ++++---- 7 files changed, 494 insertions(+), 207 deletions(-) create mode 100644 koha-tmpl/opac-tmpl/prog/en/modules/opac-showreviews-rss.tmpl --- a/C4/Dates.pm +++ a/C4/Dates.pm @@ -1,4 +1,5 @@ package C4::Dates; + # This file is part of Koha. # # Koha is free software; you can redistribute it and/or modify it under the @@ -26,154 +27,198 @@ use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); use vars qw($debug $cgi_debug); BEGIN { - $VERSION = 0.04; - @ISA = qw(Exporter); - @EXPORT_OK = qw(format_date_in_iso format_date); + $VERSION = 0.04; + @ISA = qw(Exporter); + @EXPORT_OK = qw(format_date_in_iso format_date); } use vars qw($prefformat); + sub _prefformat { - unless (defined $prefformat) { + unless ( defined $prefformat ) { $prefformat = C4::Context->preference('dateformat'); } return $prefformat; } -our %format_map = ( - iso => 'yyyy-mm-dd', # plus " HH:MM:SS" - metric => 'dd/mm/yyyy', # plus " HH:MM:SS" - us => 'mm/dd/yyyy', # plus " HH:MM:SS" - sql => 'yyyymmdd HHMMSS', +our %format_map = ( + iso => 'yyyy-mm-dd', # plus " HH:MM:SS" + metric => 'dd/mm/yyyy', # plus " HH:MM:SS" + us => 'mm/dd/yyyy', # plus " HH:MM:SS" + sql => 'yyyymmdd HHMMSS', + rfc822 => 'a, dd b y HH:MM:SS z ', ); our %posix_map = ( - iso => '%Y-%m-%d', # or %F, "Full Date" - metric => '%d/%m/%Y', - us => '%m/%d/%Y', - sql => '%Y%m%d %H%M%S', + iso => '%Y-%m-%d', # or %F, "Full Date" + metric => '%d/%m/%Y', + us => '%m/%d/%Y', + sql => '%Y%m%d %H%M%S', + rfc822 => '%a, %d %b %Y %H:%M:%S %z', ); -our %dmy_subs = ( # strings to eval (after using regular expression returned by regexp below) - # make arrays for POSIX::strftime() - iso => '[(($6||0),($5||0),($4||0),$3, $2 - 1, $1 - 1900)]', - metric => '[(($6||0),($5||0),($4||0),$1, $2 - 1, $3 - 1900)]', - us => '[(($6||0),($5||0),($4||0),$2, $1 - 1, $3 - 1900)]', - sql => '[(($6||0),($5||0),($4||0),$3, $2 - 1, $1 - 1900)]', +our %dmy_subs = ( # strings to eval (after using regular expression returned by regexp below) + # make arrays for POSIX::strftime() + iso => '[(($6||0),($5||0),($4||0),$3, $2 - 1, $1 - 1900)]', + metric => '[(($6||0),($5||0),($4||0),$1, $2 - 1, $3 - 1900)]', + us => '[(($6||0),($5||0),($4||0),$2, $1 - 1, $3 - 1900)]', + sql => '[(($6||0),($5||0),($4||0),$3, $2 - 1, $1 - 1900)]', + rfc822 => '[($7, $6, $5, $2, $3, $4 - 1900, $8)]', ); +our @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); + +our @days = qw(Sun Mon Tue Wed Thu Fri Sat); + sub regexp ($;$) { - my $self = shift; - my $delim = qr/:?\:|\/|-/; # "non memory" cluster: no backreference - my $format = (@_) ? _recognize_format(shift) : ($self->{'dateformat'} || _prefformat()); + my $self = shift; + my $delim = qr/:?\:|\/|-/; # "non memory" cluster: no backreference + my $format = (@_) ? _recognize_format(shift) : ( $self->{'dateformat'} || _prefformat() ); # Extra layer of checking $self->{'dateformat'}. # Why? Because it is assumed you might want to check regexp against an *instantiated* Dates object as a # way of saying "does this string match *whatever* format that Dates object is?" - ($format eq 'sql') and - return qr/^(\d{4})(\d{1,2})(\d{1,2})(?:\s{4}(\d{2})(\d{2})(\d{2}))?/; - ($format eq 'iso') and - return qr/^(\d{4})$delim(\d{1,2})$delim(\d{1,2})(?:(?:\s{1}|T)(\d{2})\:?(\d{2})\:?(\d{2}))?Z?/; - return qr/^(\d{1,2})$delim(\d{1,2})$delim(\d{4})(?:\s{1}(\d{1,2})\:?(\d{1,2})\:?(\d{1,2}))?/; # everything else + ( $format eq 'sql' ) + and return qr/^(\d{4})(\d{1,2})(\d{1,2})(?:\s{4}(\d{2})(\d{2})(\d{2}))?/; + ( $format eq 'iso' ) + and return qr/^(\d{4})$delim(\d{1,2})$delim(\d{1,2})(?:(?:\s{1}|T)(\d{2})\:?(\d{2})\:?(\d{2}))?Z?/; + ( $format eq 'rfc822' ) + and return qr/^([a-zA-Z]{3}),\s{1}(\d{1,2})\s{1}([a-zA-Z]{3})\s{1}(\d{4})\s{1}(\d{1,2})\:(\d{1,2})\:(\d{1,2})\s{1}(([\-|\+]\d{4})|([A-Z]{3}))/; + return qr/^(\d{1,2})$delim(\d{1,2})$delim(\d{4})(?:\s{1}(\d{1,2})\:?(\d{1,2})\:?(\d{1,2}))?/; # everything else } sub dmy_map ($$) { - my $self = shift; - my $val = shift or return undef; - my $dformat = $self->{'dateformat'} or return undef; - my $re = $self->regexp(); - my $xsub = $dmy_subs{$dformat}; - $debug and print STDERR "xsub: $xsub \n"; - if ($val =~ /$re/) { - my $aref = eval $xsub; + my $self = shift; + my $val = shift or return undef; + my $dformat = $self->{'dateformat'} or return undef; + my $re = $self->regexp(); + my $xsub = $dmy_subs{$dformat}; + $debug and print STDERR "xsub: $xsub \n"; + if ( $val =~ /$re/ ) { + my $aref = eval $xsub; + if ($dformat eq 'rfc822') { + $aref = _abbr_to_numeric($aref, $dformat); + pop(@{$aref}); #pop off tz offset because we are not setup to handle tz conversions just yet + } _check_date_and_time($aref); - return @{$aref}; - } - # $debug and - carp "Illegal Date '$val' does not match '$dformat' format: " . $self->visual(); - return 0; + push @{$aref}, (-1,-1,1); # for some reason unknown to me, setting isdst to -1 or undef causes strftime to fail to return the tz offset which is required in RFC822 format -chris_n + return @{$aref}; + } + + # $debug and + carp "Illegal Date '$val' does not match '$dformat' format: " . $self->visual(); + return 0; +} + +sub _abbr_to_numeric { + my $aref = shift; + my $dformat = shift; + my ($month_abbr, $day_abbr) = ($aref->[4], $aref->[3]) if $dformat eq 'rfc822'; + + for( my $i = 0; $i < scalar(@months); $i++ ) { + if ( $months[$i] =~ /$month_abbr/ ) { + $aref->[4] = $i-1; + last; + } + }; + + for( my $i = 0; $i < scalar(@days); $i++ ) { + if ( $days[$i] =~ /$day_abbr/ ) { + $aref->[3] = $i; + last; + } + }; + return $aref; } sub _check_date_and_time { my $chron_ref = shift; - my ($year, $month, $day) = _chron_to_ymd($chron_ref); - unless (check_date($year, $month, $day)) { + my ( $year, $month, $day ) = _chron_to_ymd($chron_ref); + unless ( check_date( $year, $month, $day ) ) { carp "Illegal date specified (year = $year, month = $month, day = $day)"; } - my ($hour, $minute, $second) = _chron_to_hms($chron_ref); - unless (check_time($hour, $minute, $second)) { + my ( $hour, $minute, $second ) = _chron_to_hms($chron_ref); + unless ( check_time( $hour, $minute, $second ) ) { carp "Illegal time specified (hour = $hour, minute = $minute, second = $second)"; } } sub _chron_to_ymd { my $chron_ref = shift; - return ($chron_ref->[5] + 1900, $chron_ref->[4] + 1, $chron_ref->[3]); + return ( $chron_ref->[5] + 1900, $chron_ref->[4] + 1, $chron_ref->[3] ); } sub _chron_to_hms { my $chron_ref = shift; - return ($chron_ref->[2], $chron_ref->[1], $chron_ref->[0]); + return ( $chron_ref->[2], $chron_ref->[1], $chron_ref->[0] ); } sub new { - my $this = shift; - my $class = ref($this) || $this; - my $self = {}; - bless $self, $class; - return $self->init(@_); + my $this = shift; + my $class = ref($this) || $this; + my $self = {}; + bless $self, $class; + return $self->init(@_); } + sub init ($;$$) { - my $self = shift; - my $dformat; - $self->{'dateformat'} = $dformat = (scalar(@_) >= 2) ? $_[1] : _prefformat(); - ($format_map{$dformat}) or croak - "Invalid date format '$dformat' from " . ((scalar(@_) >= 2) ? 'argument' : 'system preferences'); - $self->{'dmy_arrayref'} = [((@_) ? $self->dmy_map(shift) : localtime )] ; - $debug and warn "(during init) \@\$self->{'dmy_arrayref'}: " . join(' ',@{$self->{'dmy_arrayref'}}) . "\n"; - return $self; + my $self = shift; + my $dformat; + $self->{'dateformat'} = $dformat = ( scalar(@_) >= 2 ) ? $_[1] : _prefformat(); + ( $format_map{$dformat} ) or croak "Invalid date format '$dformat' from " . ( ( scalar(@_) >= 2 ) ? 'argument' : 'system preferences' ); + $self->{'dmy_arrayref'} = [ ( (@_) ? $self->dmy_map(shift) : localtime ) ]; + $debug and warn "(during init) \@\$self->{'dmy_arrayref'}: " . join( ' ', @{ $self->{'dmy_arrayref'} } ) . "\n"; + return $self; } + sub output ($;$) { - my $self = shift; - my $newformat = (@_) ? _recognize_format(shift) : _prefformat(); - return (eval {POSIX::strftime($posix_map{$newformat}, @{$self->{'dmy_arrayref'}})} || undef); + my $self = shift; + my $newformat = (@_) ? _recognize_format(shift) : _prefformat(); + return ( eval { POSIX::strftime( $posix_map{$newformat}, @{ $self->{'dmy_arrayref'} } ) } || undef ); } -sub today ($;$) { # NOTE: sets date value to today (and returns it in the requested or current format) - my $class = shift; - $class = ref($class) || $class; - my $format = (@_) ? _recognize_format(shift) : _prefformat(); - return $class->new()->output($format); + +sub today ($;$) { # NOTE: sets date value to today (and returns it in the requested or current format) + my $class = shift; + $class = ref($class) || $class; + my $format = (@_) ? _recognize_format(shift) : _prefformat(); + return $class->new()->output($format); } + sub _recognize_format($) { - my $incoming = shift; - ($incoming eq 'syspref') and return _prefformat(); - (scalar grep (/^$incoming$/, keys %format_map) == 1) or croak "The format you asked for ('$incoming') is unrecognized."; - return $incoming; + my $incoming = shift; + ( $incoming eq 'syspref' ) and return _prefformat(); + ( scalar grep ( /^$incoming$/, keys %format_map ) == 1 ) or croak "The format you asked for ('$incoming') is unrecognized."; + return $incoming; } -sub DHTMLcalendar ($;$) { # interface to posix_map - my $class = shift; - my $format = (@_) ? shift : _prefformat(); - return $posix_map{$format}; + +sub DHTMLcalendar ($;$) { # interface to posix_map + my $class = shift; + my $format = (@_) ? shift : _prefformat(); + return $posix_map{$format}; } -sub format { # get or set dateformat: iso, metric, us, etc. - my $self = shift; - (@_) or return $self->{'dateformat'}; - $self->{'dateformat'} = _recognize_format(shift); + +sub format { # get or set dateformat: iso, metric, us, etc. + my $self = shift; + (@_) or return $self->{'dateformat'}; + $self->{'dateformat'} = _recognize_format(shift); } + sub visual { - my $self = shift; - if (@_) { - return $format_map{ _recognize_format(shift) }; - } - $self eq __PACKAGE__ and return $format_map{_prefformat()}; - return $format_map{ eval { $self->{'dateformat'} } || _prefformat()} ; + my $self = shift; + if (@_) { + return $format_map{ _recognize_format(shift) }; + } + $self eq __PACKAGE__ and return $format_map{ _prefformat() }; + return $format_map{ eval { $self->{'dateformat'} } || _prefformat() }; } # like the functions from the old C4::Date.pm sub format_date { - return __PACKAGE__ -> new(shift,'iso')->output((@_) ? shift : _prefformat()); + return __PACKAGE__->new( shift, 'iso' )->output( (@_) ? shift : _prefformat() ); } + sub format_date_in_iso { - return __PACKAGE__ -> new(shift,_prefformat())->output('iso'); + return __PACKAGE__->new( shift, _prefformat() )->output('iso'); } 1; @@ -192,6 +237,7 @@ The formats supported by Koha are: us - U.S. standard metric - European standard (slight misnomer, not really decimalized metric) sql - log format, not really for human consumption + rfc822 - Standard for using with RSS feeds, etc. =head2 ->new([string_date,][date_format]) @@ -200,19 +246,19 @@ used. If date_format is not supplied, the system preference from C4::Context is Examples: - my $now = C4::Dates->new(); - my $date1 = C4::Dates->new("09-21-1989","us"); - my $date2 = C4::Dates->new("19890921 143907","sql"); + my $now = C4::Dates->new(); + my $date1 = C4::Dates->new("09-21-1989","us"); + my $date2 = C4::Dates->new("19890921 143907","sql"); =head2 ->output([date_format]) The date value is stored independent of any specific format. Therefore any format can be invoked when displaying it. - my $date = C4::Dates->new(); # say today is July 12th, 2010 - print $date->output("iso"); # prints "2010-07-12" - print "\n"; - print $date->output("metric"); # prints "12-07-2010" + my $date = C4::Dates->new(); # say today is July 12th, 2010 + print $date->output("iso"); # prints "2010-07-12" + print "\n"; + print $date->output("metric"); # prints "12-07-2010" However, it is still necessary to know the format of any incoming date value (e.g., setting the value of an object with new()). Like new(), output() assumes the system preference @@ -228,32 +274,32 @@ method/function to tell you whether or not a Dates.pm object is of the 'iso' typ can see by this example that such a test is trivial to accomplish, and not necessary to include in the module: - sub is_iso { - my $self = shift; - return ($self->format() eq "iso"); - } + sub is_iso { + my $self = shift; + return ($self->format() eq "iso"); + } Note: A similar function would need to be included for each format. Instead a dependent script can retrieve the format of the object directly and decide what to do with it from there: - my $date = C4::Dates->new(); - my $format = $date->format(); - ($format eq "iso") or do_something($date); + my $date = C4::Dates->new(); + my $format = $date->format(); + ($format eq "iso") or do_something($date); Or if you just want to print a given value and format, no problem: - my $date = C4::Dates->new("1989-09-21", "iso"); - print $date->output; + my $date = C4::Dates->new("1989-09-21", "iso"); + print $date->output; Alternatively: - print C4::Dates->new("1989-09-21", "iso")->output; + print C4::Dates->new("1989-09-21", "iso")->output; Or even: - print C4::Dates->new("21-09-1989", "metric")->output("iso"); + print C4::Dates->new("21-09-1989", "metric")->output("iso"); =head2 "syspref" -- System Preference(s) @@ -263,24 +309,24 @@ psuedo-format argument "syspref". For example, to print an ISO date (from the database) in the format: - my $date = C4::Dates->new($date_from_database,"iso"); - my $datestring_for_display = $date->output("syspref"); - print $datestring_for_display; + my $date = C4::Dates->new($date_from_database,"iso"); + my $datestring_for_display = $date->output("syspref"); + print $datestring_for_display; Or even: - print C4::Dates->new($date_from_database,"iso")->output("syspref"); + print C4::Dates->new($date_from_database,"iso")->output("syspref"); If you just want to know what the is, a default Dates object can tell you: - C4::Dates->new()->format(); + C4::Dates->new()->format(); =head2 ->DHMTLcalendar([date_format]) Returns the format string for DHTML Calendar Display based on date_format. If date_format is not supplied, the return is based on system preference. - C4::Dates->DHTMLcalendar(); # e.g., returns "%m/%d/%Y" for 'us' system preference + C4::Dates->DHTMLcalendar(); # e.g., returns "%m/%d/%Y" for 'us' system preference =head3 Error Handling @@ -290,12 +336,12 @@ fatal error (because it is programmer error, not user error, typically). Scripts must still perform validation of user input. Attempting to set an invalid value will return 0 or undefined, so a script might check as follows: - my $date = C4::Dates->new($input) or deal_with_it("$input didn't work"); + my $date = C4::Dates->new($input) or deal_with_it("$input didn't work"); To validate before creating a new object, use the regexp method of the class: - $input =~ C4::Dates->regexp("iso") or deal_with_it("input ($input) invalid as iso format"); - my $date = C4::Dates->new($input,"iso"); + $input =~ C4::Dates->regexp("iso") or deal_with_it("input ($input) invalid as iso format"); + my $date = C4::Dates->new($input,"iso"); More verbose debugging messages are sent in the presence of non-zero $ENV{"DEBUG"}. --- a/C4/Review.pm +++ a/C4/Review.pm @@ -29,7 +29,7 @@ BEGIN { $VERSION = 3.00; require Exporter; @ISA = qw(Exporter); - @EXPORT = qw(getreview savereview updatereview numberofreviews + @EXPORT = qw(getreview savereview updatereview numberofreviews numberofreviewsbybiblionumber getreviews getallreviews approvereview deletereview); } @@ -91,6 +91,15 @@ sub updatereview { } sub numberofreviews { + my $dbh = C4::Context->dbh; + my $query = + "SELECT count(*) FROM reviews WHERE approved=?"; + my $sth = $dbh->prepare($query); + $sth->execute( 1 ); + return $sth->fetchrow; +} + +sub numberofreviewsbybiblionumber { my ($biblionumber) = @_; my $dbh = C4::Context->dbh; my $query = @@ -111,12 +120,13 @@ sub getreviews { } sub getallreviews { - my ($status) = @_; + my ($status, $offset, $row_count) = @_; + my @params = ($status,($offset ? $offset : 0),($row_count ? $row_count : 20)); my $dbh = C4::Context->dbh; my $query = - "SELECT * FROM reviews WHERE approved=? order by datereviewed desc"; - my $sth = $dbh->prepare($query); - $sth->execute($status); + "SELECT * FROM reviews WHERE approved=? order by datereviewed desc LIMIT ?, ?"; + my $sth = $dbh->prepare($query) || warn $dbh->err_str; + $sth->execute(@params); return $sth->fetchall_arrayref({}); } --- a/koha-tmpl/opac-tmpl/prog/en/css/opac.css +++ a/koha-tmpl/opac-tmpl/prog/en/css/opac.css @@ -1021,8 +1021,7 @@ a.cancel { .searchresults p { margin: 0; - padding: 0; - padding-top : .6em; + padding: 0 0 .6em 0; } td.resultscontrol img { @@ -1970,3 +1969,28 @@ div.ft { list-style:disc outside url("../../images/item-bullet.gif"); padding:0.2em 0; } + +#recentcomments { + margin:auto; + max-width:750px; +} + +.searchresults .commentline { + background-color : rgb(255, 255, 204); + background-color : rgba(255, 255, 204, 0.4); + border : 1px solid #CCC; + display: inline-block; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.2); + box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.2); + margin : .3em; + padding : .4em; +} + +.searchresults .commentline.yours { + background-color : rgb(239, 254, 213); + background-color : rgba(239, 254, 213, 0.4); +} --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-showreviews-rss.tmpl +++ a/koha-tmpl/opac-tmpl/prog/en/modules/opac-showreviews-rss.tmpl @@ -0,0 +1,36 @@ + + + + <![CDATA[<!-- TMPL_IF NAME="LibraryNameTitle" --><!-- TMPL_VAR NAME="LibraryNameTitle" --><!-- TMPL_ELSE -->Koha Online<!-- /TMPL_IF --> Catalog Recent Comments]]> + /cgi-bin/koha/opac-showreviews.pl&format=rss2 + Koha Online Catalog. Comments can be made by logged in users and are moderated by library staff.]]> + /cgi-bin/koha/opac-showreviews.pl&format=rss2" rel="self" type="application/rss+xml" /> + + + + New comment on <!-- TMPL_VAR NAME="title" ESCAPE="html" --> <!-- TMPL_LOOP NAME="subtitle" -->, <!-- TMPL_VAR ESCAPE="HTML" NAME="subfield" --><!-- /TMPL_LOOP --> + /cgi-bin/koha/opac-detail.pl?biblionumber=#comments + .01.TZZZZZZZ.jpg" alt="" /> + +/SC.GIF&client=&type=xw10&upc=&oclc=" alt="" /> + +/SC.GIF&client=&type=xw10&upc=&oclc=" alt="" /> + + +">See Baker & Taylor" /> +

By .

+

+ + . + , + . +

+

commented on :

+ ]]>
+ /cgi-bin/koha/opac-detail.pl?biblionumber=&reviewid= + +
+ +
+
--- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-showreviews.tmpl +++ a/koha-tmpl/opac-tmpl/prog/en/modules/opac-showreviews.tmpl @@ -1,39 +1,97 @@ -Koha Online Catalog › +Koha Online Catalog › Recent Comments +Koha Online Catalog Recent Comments" href="/cgi-bin/koha/opac-showreviews.pl?format=rss" /> + - - - -
+
+ - + --- a/opac/opac-showreviews.pl +++ a/opac/opac-showreviews.pl @@ -1,5 +1,8 @@ #!/usr/bin/perl +# Copyright 2000-2002 Katipo Communications +# Parts copyright 2010 Nelsonville Public Library +# # This file is part of Koha. # # Koha is free software; you can redistribute it and/or modify it under the @@ -25,26 +28,135 @@ use C4::Output; use C4::Circulation; use C4::Review; use C4::Biblio; +use C4::Dates qw/format_date/; +use C4::Members qw/GetMemberDetails/; +use POSIX qw(ceil strftime); + +my $template_name; +my $query = new CGI; +my $format = $query->param("format") || ''; +my $count = C4::Context->preference('OPACnumSearchResults') || 20; +my $results_per_page = $query->param('count') || $count; +my $offset = $query->param('offset') || 0; +my $page = $query->param('page') || 1; +$offset = ($page-1)*$results_per_page if $page>1; -my $query = new CGI; -my $biblionumber = $query->param('biblionumber'); +if ($format eq "rss") { + $template_name = "opac-showreviews-rss.tmpl"; +} else { + $template_name = "opac-showreviews.tmpl", +} my ( $template, $borrowernumber, $cookie ) = &get_template_and_user( { - template_name => "opac-showreviews.tmpl", + template_name => $template_name, query => $query, type => "opac", authnotrequired => 1, } ); -my $biblio = GetBiblioData( $biblionumber ); -my $reviews = getreviews( $biblionumber, 1 ); +if($format eq "rss"){ + my $lastbuilddate = C4::Dates->new(); + my $lastbuilddate_output = $lastbuilddate->output("rfc822"); + $template->param( + rss => 1, + timestamp => $lastbuilddate_output + ); +} + +my $reviews = getallreviews(1,$offset,$results_per_page); +my $marcflavour = C4::Context->preference("marcflavour"); +my $hits = numberofreviews(); +my $i = 0; +my $latest_comment_date; +for my $result (@$reviews){ + my $biblionumber = $result->{biblionumber}; + my $bib = &GetBiblioData($biblionumber); + my $record = GetMarcBiblio($biblionumber); + my $frameworkcode = GetFrameworkCode($biblionumber); + my ( $borr ) = GetMemberDetails( $result->{borrowernumber} ); + $result->{normalized_upc} = GetNormalizedUPC($record,$marcflavour); + $result->{normalized_ean} = GetNormalizedEAN($record,$marcflavour); + $result->{normalized_oclc} = GetNormalizedOCLCNumber($record,$marcflavour); + $result->{normalized_isbn} = GetNormalizedISBN(undef,$record,$marcflavour); + $result->{title} = $bib->{'title'}; + $result->{subtitle} = GetRecordValue('subtitle', $record, $frameworkcode); + $result->{author} = $bib->{'author'}; + $result->{place} = $bib->{'place'}; + $result->{publishercode} = $bib->{'publishercode'}; + $result->{copyrightdate} = $bib->{'copyrightdate'}; + $result->{pages} = $bib->{'pages'}; + $result->{size} = $bib->{'size'}; + $result->{notes} = $bib->{'notes'}; + $result->{timestamp} = $bib->{'timestamp'}; + $result->{firstname} = $borr->{'firstname'}; + $result->{surname} = $borr->{'surname'}; + if ($result->{borrowernumber} eq $borrowernumber) { + $result->{your_comment} = 1; + } + + if($format eq "rss"){ + my $rsstimestamp = C4::Dates->new($result->{datereviewed},"iso"); + my $rsstimestamp_output = $rsstimestamp->output("rfc822"); + $result->{timestamp} = $rsstimestamp_output; + $result->{datereviewed} = format_date($result->{datereviewed}); + } else { + $result->{datereviewed} = format_date($result->{datereviewed}); + } +} +## Build the page numbers on the bottom of the page + my @page_numbers; + my $previous_page_first; + my $previous_page_offset; + # total number of pages there will be + my $pages = ceil($hits / $results_per_page); + # default page number + my $current_page_number = 1; + $current_page_number = ($offset / $results_per_page + 1) if $offset; + if($offset - $results_per_page == 0){ + $previous_page_first = 1; + } elsif ($offset - $results_per_page > 0){ + $previous_page_offset = $offset - $results_per_page; + } + my $next_page_offset = $offset + $results_per_page; + # If we're within the first 10 pages, keep it simple + if ($current_page_number < 10) { + # just show the first 10 pages + # Loop through the pages + my $pages_to_show = 10; + $pages_to_show = $pages if $pages<10; + for ($i=1; $i<=$pages_to_show;$i++) { + # the offset for this page + my $this_offset = (($i*$results_per_page)-$results_per_page); + # the page number for this page + my $this_page_number = $i; + # it should only be highlighted if it's the current page + my $highlight = 1 if ($this_page_number == $current_page_number); + # put it in the array + push @page_numbers, { offset => $this_offset, pg => $this_page_number, highlight => $highlight }; + + } + + } + # now, show twenty pages, with the current one smack in the middle + else { + for ($i=$current_page_number; $i<=($current_page_number + 20 );$i++) { + my $this_offset = ((($i-9)*$results_per_page)-$results_per_page); + my $this_page_number = $i-9; + my $highlight = 1 if ($this_page_number == $current_page_number); + if ($this_page_number <= $pages) { + push @page_numbers, { offset => $this_offset, pg => $this_page_number, highlight => $highlight }; + } + } + } +$template->param( PAGE_NUMBERS => \@page_numbers, + previous_page_first => $previous_page_first, + previous_page_offset => $previous_page_offset) unless $pages < 2; +$template->param(next_page_offset => $next_page_offset) unless $pages eq $current_page_number; $template->param( reviews => $reviews, - title => $biblio->{'title'}, ); -output_html_with_http_headers $query, $cookie, $template->output; - +output_html_with_http_headers $query, $cookie, $template->output; --- a/t/Dates.t +++ a/t/Dates.t @@ -3,44 +3,43 @@ use strict; use warnings; -use Test::More tests => 276; +use Test::More tests => 327; + BEGIN { - use FindBin; - use lib $FindBin::Bin; - use_ok('C4::Dates', qw(format_date format_date_in_iso)); + use FindBin; + use lib $FindBin::Bin; + use_ok( 'C4::Dates', qw(format_date format_date_in_iso) ); } sub describe ($$) { - my $front = sprintf("%-25s", shift); - my $tail = shift || 'FAILED'; - return "$front : $tail"; + my $front = sprintf( "%-25s", shift ); + my $tail = shift || 'FAILED'; + return "$front : $tail"; } -# Keep the number of test elements per [array] equal or the predicted number of tests +# Keep the number of test elements per [array] equal or the predicted number of tests # needs to be different for different (fake) sysprefs. my %thash = ( - iso => ['2001-1-1','1989-9-21','1952-1-0', '1989-9-21 13:46:02','2001-01-01','1989-09-21','1952-01-00', '1989-09-21 13:46:02'], - metric => ["1-1-2001",'21-9-1989','00-1-1952', '21-9-1989 13:46:02',"01-01-2001",'21-09-1989','00-01-1952', '21-09-1989 13:46:02'], - us => ["01-01-2001",'09-21-1989','01-00-1952', '09-21-1989 13:46:02'], - sql => ['20010101 010101', - '19890921 143907', - '19520100 000000', - '19890921 134602' ], + iso => [ '2001-1-1', '1989-9-21', '1952-1-0', '1989-9-21 13:46:02', '2001-01-01', '1989-09-21', '1952-01-00', '1989-09-21 13:46:02' ], + metric => [ "1-1-2001", '21-9-1989', '00-1-1952', '21-9-1989 13:46:02', "01-01-2001", '21-09-1989', '00-01-1952', '21-09-1989 13:46:02' ], + us => [ "01-01-2001", '09-21-1989', '01-00-1952', '09-21-1989 13:46:02' ], + sql => [ '20010101 010101', '19890921 143907', '19520100 000000', '19890921 134602' ], + rfc822 => [ 'Wed, 02 Oct 2002 15:00:00 +0200', 'Fri, 10 Sep 2010 08:00:00 +0500' ], ); -my ($date, $format, $today, $today0, $val, $re, $syspref); -my @formats = sort keys %thash; +my ( $date, $format, $today, $today0, $val, $re, $syspref ); +my @formats = sort keys %thash; my $fake_syspref_default = 'us'; -my $fake_syspref = (@ARGV) ? shift : $ENV{KOHA_TEST_DATE_FORMAT}; +my $fake_syspref = (@ARGV) ? shift : $ENV{KOHA_TEST_DATE_FORMAT}; if ($fake_syspref) { diag "You asked for date format '$fake_syspref'."; - unless (scalar grep {/^$fake_syspref$/} @formats) { + unless ( scalar grep { /^$fake_syspref$/ } @formats ) { diag "Warning: Unkown date format '$fake_syspref', reverting to default '$fake_syspref_default'."; $fake_syspref = $fake_syspref_default; } } $fake_syspref or $fake_syspref = $fake_syspref_default; -$C4::Dates::prefformat = $fake_syspref; # So Dates doesn't have to ask the DB anything. +$C4::Dates::prefformat = $fake_syspref; # So Dates doesn't have to ask the DB anything. diag <new->format(), "Your system preference is: $syspref"); +ok( $syspref = C4::Dates->new->format(), "Your system preference is: $syspref" ); print "\n"; -foreach (@{$thash{'iso'}}) { - ok($val = format_date($_), "format_date('$_'): $val" ); +foreach ( @{ $thash{'iso'} } ) { + ok( $val = format_date($_), "format_date('$_'): $val" ); } -foreach (@{$thash{$syspref}}) { - ok($val = format_date_in_iso($_), "format_date_in_iso('$_'): $val" ); +foreach ( @{ $thash{$syspref} } ) { + ok( $val = format_date_in_iso($_), "format_date_in_iso('$_'): $val" ); } -ok($today0 = C4::Dates->today(), "(default) CLASS ->today : $today0" ); +ok( $today0 = C4::Dates->today(), "(default) CLASS ->today : $today0" ); diag "\nTesting " . scalar(@formats) . " formats.\nTesting no input (defaults):\n"; print "\n"; foreach (@formats) { - my $pre = sprintf '(%-6s)', $_; - ok($date = C4::Dates->new(), "$pre Date Creation : new()"); - ok($_ eq ($format = $date->format($_)), "$pre format($_) : " . ($format|| 'FAILED') ); - ok($format = $date->visual(), "$pre visual() : " . ($format|| 'FAILED') ); - ok($today = $date->output(), "$pre output() : " . ($today || 'FAILED') ); - ok($today = $date->today(), "$pre object->today : " . ($today || 'FAILED') ); - print "\n"; + my $pre = sprintf '(%-6s)', $_; + ok( $date = C4::Dates->new(), "$pre Date Creation : new()" ); + ok( $_ eq ( $format = $date->format($_) ), "$pre format($_) : " . ( $format || 'FAILED' ) ); + ok( $format = $date->visual(), "$pre visual() : " . ( $format || 'FAILED' ) ); + ok( $today = $date->output(), "$pre output() : " . ( $today || 'FAILED' ) ); + ok( $today = $date->today(), "$pre object->today : " . ( $today || 'FAILED' ) ); + print "\n"; } diag "\nTesting with valid inputs:\n"; foreach $format (@formats) { - my $pre = sprintf '(%-6s)', $format; - foreach my $testval (@{$thash{ $format }}) { - ok($date = C4::Dates->new($testval,$format), "$pre Date Creation : new('$testval','$format')"); - ok($re = $date->regexp, "$pre has regexp()" ); - ok($testval =~ /^$re$/, "$pre has regexp() match $testval"); - ok($val = $date->output(), describe("$pre output()", $val) ); - SKIP: { - skip("special case with explicit regexp('syspref') because $format isn't $syspref", 1) unless ($format eq $syspref); - my $re_syspref = C4::Dates->regexp('syspref'); - ok($testval =~ /^$re_syspref$/, "$pre has regexp('syspref') match $testval"); + my $pre = sprintf '(%-6s)', $format; + foreach my $testval ( @{ $thash{$format} } ) { + ok( $date = C4::Dates->new( $testval, $format ), "$pre Date Creation : new('$testval','$format')" ); + ok( $re = $date->regexp, "$pre has regexp()" ); + ok( $testval =~ /^$re$/, "$pre has regexp() match $testval" ); + ok( $val = $date->output(), describe( "$pre output()", $val ) ); + SKIP: { + skip( "special case with explicit regexp('syspref') because $format isn't $syspref", 1 ) unless ( $format eq $syspref ); + my $re_syspref = C4::Dates->regexp('syspref'); + ok( $testval =~ /^$re_syspref$/, "$pre has regexp('syspref') match $testval" ); + } + foreach ( grep { !/$format/ } @formats ) { + ok( $today = $date->output($_), describe( sprintf( "$pre output(%8s)", "'$_'" ), $today ) ); + } + ok( $today = $date->today(), describe( "$pre object->today", $today ) ); + + # ok($today == ($today = C4::Dates->today()), "$pre CLASS ->today : $today" ); + ok( $val = $date->output(), describe( "$pre output()", $val ) ); + + # ok($format eq ($format = $date->format()), "$pre format() : $format" ); + print "\n"; } - foreach (grep {!/$format/} @formats) { - ok($today = $date->output($_), describe(sprintf("$pre output(%8s)","'$_'"), $today) ); - } - ok($today = $date->today(), describe("$pre object->today", $today) ); - # ok($today == ($today = C4::Dates->today()), "$pre CLASS ->today : $today" ); - ok($val = $date->output(), describe("$pre output()", $val) ); - # ok($format eq ($format = $date->format()), "$pre format() : $format" ); - print "\n"; - } } diag "\nTesting object independence from class\n"; -my $in1 = '12/25/1952'; # us -my $in2 = '13/01/2001'; # metric -my $d1 = C4::Dates->new($in1, 'us'); -my $d2 = C4::Dates->new($in2, 'metric'); +my $in1 = '12/25/1952'; # us +my $in2 = '13/01/2001'; # metric +my $d1 = C4::Dates->new( $in1, 'us' ); +my $d2 = C4::Dates->new( $in2, 'metric' ); my $out1 = $d1->output('iso'); my $out2 = $d2->output('iso'); -ok($out1 ne $out2, "subsequent constructors get different dataspace ($out1 != $out2)"); +ok( $out1 ne $out2, "subsequent constructors get different dataspace ($out1 != $out2)" ); diag "done.\n"; --