From srdjan at catalyst.net.nz Mon Mar 2 02:45:51 2015 From: srdjan at catalyst.net.nz (Srdjan) Date: Mon, 2 Mar 2015 14:45:51 +1300 Subject: [Koha-patches] [PATCH] bug_13413: Koha::Log - logging for Koha Message-ID: <1425260751-23906-1-git-send-email-srdjan@catalyst.net.nz> --- Koha/Log.pm | 405 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ debian/control | 2 + t/Koha_Log.t | 77 +++++++++++ 3 files changed, 484 insertions(+) create mode 100644 Koha/Log.pm create mode 100755 t/Koha_Log.t diff --git a/Koha/Log.pm b/Koha/Log.pm new file mode 100644 index 0000000..78b8183 --- /dev/null +++ b/Koha/Log.pm @@ -0,0 +1,405 @@ +package Koha::Log; + +# Copyright 2014 Catalyst IT +# +# This file is part of Koha. +# +# Koha 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. +# +# Koha 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 Koha; if not, see . + +use Modern::Perl; +use Log::Contextual qw(set_logger with_logger); +use Exporter::Declare; +use base 'Log::Contextual'; + +exports qw(with_debug with_logger create_logger set_default_logger); + +=head1 NAME + +Koha::Log - Logging for Koha + +=head1 SYNOPSIS + + # Main script + use Koha::Log; + # optionally + Koha::Log::set_default_logger('File', {filename => $LOG_FILE}); + + log_error { "Error" }; + log_warn { "Warn" }; + log_info { "Info" }; + + # Some module + use Koha::Log; + log_error { "Error" }; + +=head1 DESCRIPTION + + This is a combination of Log::Contextual and customised Log:Dispatcher + Why? + 1. Because it uses code blocks to log, so complex debugging can be left in + without any performance penalty + 2. Some useful things can be done + + Out of the box it logs to STDERR + +=head1 LOG LEVELS + + We support log levels of debug info warn error fatal + Not sure how useful is fatal; + trace level is TODO + + Log functions are log_I + +=head1 Log::Contextual FUNCTIONS + +By default, log_* functions are exported. For the full list see C + +=cut + +my $default_logger; + +sub arg_default_logger { + return $_[1] || ($default_logger ||= create_logger()); +} +sub arg_levels { [qw(debug trace info warn error fatal)] } +sub default_import { ':log' } + +=head1 FUNCTIONS + +=head2 create_logger( Sink1 => {params}, Sink2 => {params} ) + + If no sinks are given, Stderr is assumed + +=head3 Sinks + +Sinks are C module names, eg File, Syslog etc +We added two more: + C which is a shortcut for Screen stderr => 0 + C which is a shortcut for Screen stderr => 1 + + Default sink parameters: + C - if env KOHA_DEBUG is set to true valu then 'debug' else 'info' + C - lower case sink module name + + Filename rules for C) sink: + Filenames with absolute paths are honoured + otherwise files are placed in koha config logdir + + Default C parameter for C) sink is I + +=cut + +sub create_logger { + my %sink_defs = @_ ? @_ : (Stderr => {}); + my $logger = Koha::Log::Dispatch->new; + while (my ($sink, $params) = each %sink_defs) { + $logger->add_sink($sink, $params); + } + return $logger; +} + +=head1 DEFAULT LOGGER FUNCTIONS + +Following functions operate on the default logger. +Default logger should be used most of the time. + +=head2 set_default_logger( Sink1 => {params}, Sink2 => {params} ) + + Calls C and sets it as the default. + Should probably be used only in the main script. + +=cut + +sub set_default_logger { + $default_logger = create_logger(@_); + set_logger($default_logger); +} + +sub restore_default_logger { + set_logger($default_logger); +} + +=head2 add_sink( Sink, {params}, $force ) +=head2 remove_sink( sink_name ) +=head2 with_debug { code...} Sink1 [ => {params}], Sink2 ... + + C method proxies, called on the default logger + +=cut + +sub add_sink { + $default_logger->add_sink(@_); +} + +sub remove_sink { + my ($sink_name) = @_; + $default_logger->remove( lc $sink_name ); +} + +sub with_debug (&@) { + my $code = \&{shift @_}; + $default_logger->with_debug($code, @_); +} + +package Koha::Log::Dispatch; + +=head1 LOGGER CLASS + +C returns a loger class based on C + +=cut + +use Modern::Perl; +use Carp; +use Class::Load 'load_class'; + +use C4::Context; + +use base 'Log::Dispatch'; + +my %ALL_LOGGER_PARAMS = ( + newline => 1, + min_level => $ENV{KOHA_DEBUG} ? 'debug' : 'info', +); + +my %LOGGER_PARAMS = ( + Stdout => {stderr => 0}, + Stderr => {stderr => 1}, + Syslog => {facility => 'user'}, +); + +=head1 LOGGER METHODS + +=head2 outputs() + + Returns hashref {sink_name => sink_object...} + +=cut + +sub outputs { + my $self = shift; + return $self->{outputs}; +} + +=head2 set_level(log_level, @sink_names) + + Sets (minimum) log level for all named sinks (outputs) + If no named sinks are specified, all associated sinks are affected. + +=cut + +sub set_level { + my $self = shift; + my $level = shift or croak "No level specified"; + + my @outputs = @_ ? map ($self->output($_), @_) : values (%{ $self->outputs }); + $_->{min_level} = $_->_level_as_number($level) foreach @outputs; +} + +=head2 get_levels() + + Returns hashref {sink_name => log_level...} + +=cut + +sub get_levels { + my $self = shift; + + my @outputs = @_ ? map ($self->output($_), @_) : values (%{ $self->outputs }); + return { map { $_->name => $_->min_level } @outputs }; +} + +=head2 add_sink( Sink, {params}, $force ) + + Creates a C object, and calls C + If sink with the name altready exists it returns, unless $force is true, + in which case existing sink is replaced with a new one. + +=cut + +sub add_sink { + my $self = shift; + my ($sink, $params, $force) = @_; + + my $sink_params = $LOGGER_PARAMS{$sink} || {}; + my $sink_name = $params->{name} ||= lc $sink; + + if ( $self->output($sink_name) ) { + return unless $force; + $self->remove( $sink_name ); + } + + $params ||= {}; + if (my $filename = $params->{filename}) { + $params->{filename} = C4::Context->config("logdir") . "/$filename" + unless $filename =~ m!^[/.]!o; + } + + $sink = 'Screen' if $sink eq 'Stdout' || $sink eq 'Stderr'; + my $sink_class = "Log::Dispatch::$sink"; + load_class $sink_class; + $self->add( $sink_class->new( %ALL_LOGGER_PARAMS, %$sink_params, %$params ) ); + return $sink_name; +} + +=head2 with_debug( code_ref, Sink1 [ => {params}], Sink2 ... ) + + Executes code within a debug context + If Sink => params are given, those are used for debug logging in addition + to eny existing sinks with debug level. Otherwise all associated sinks + (outputs) are upgraded temporarily to debug level. + + See B below + +=cut + +sub with_debug { + my $self = shift; + my $code = shift; + + my $current_levels = $self->get_levels; + + my @sink; + my @extra_logger; + if (@_) { + while (my $sink = shift @_) { + # next if ref $sink; + my $params = {}; + $params = shift @_ if ref $_[0]; + my $sink_name = $params->{name} || lc $sink; + unless ($self->output($sink_name)) { + $params->{min_level} = 'debug'; + $self->add_sink($sink, $params); + push @extra_logger, $sink_name; + } + push @sink, $sink_name; + } + } + else { + @sink = keys %$current_levels; + } + $self->set_level('debug', @sink); + $code->(); + $self->remove($_) foreach @extra_logger; + while (my ($name, $level) = each %$current_levels) { + $self->set_level($level, $name); + } +} + + +=head1 USAGE + + The simplest example: + + use Koha::Log; + do things(); + log_info { "This will show in STDERR" }; + log_debug { "This will not show in STDERR" }; + + A less simple example: + + use Koha::Log qw(:log set_default_logger) + my %sinks = ( + 'File' => {filename => 'my.log'}, + ); + set_default_logger(%sinks); + + # In a module down below + use Koha::Log; + do things(); + log_info { "This will show in my.log" }; + log_debug { "This will not show in my.log" }; + + An example with multiple sinks: + + use Koha::Log qw(:log set_default_logger) + my %sinks = ( + 'Stderr' => {min_level => 'debug'}, + 'Syslog' => {}, + 'File' => {filename => 'my.log'}, + ); + set_default_logger(%sinks); + + # In a module down below + use Koha::Log; + do things(); + log_info { "This will show everywhere" }; + log_debug { "This will show in STDERR" }; + + Enable debug messages: + KOHA_DEBUG=1 some_koha_script.pl + + or in Apache: + SetEnv KOHA_DEBUG=1 + +=cut + +=head1 ADVANCED USAGE + + Enable debug messages just for a piece of code: + + use Koha::Log qw(:log set_default_logger) + my %sinks = ( + 'File' => {filename => 'my.log'}, + ); + set_default_logger(%sinks); + + # In a module down below + use Koha::Log qw(:log with_debug) + do things(); + log_debug { "This will not show" }; + ... + with_debug { + do other_things(); + log_debug {"This will show"}; + }; + + This will make the block surounded by with_debug {} output debug to my.log + Alternatively: + + with_debug { + do other_things(); + log_debug {"This will show"}; + } 'Stderr'; + + will leave my.log at 'info' level, and output debug (and other log levels) to STDERR. + + Special logging: + + use Koha::Log qw(:log set_default_logger) + my %sinks = ( + 'File' => {filename => 'my.log'}, + ); + set_default_logger(%sinks); + + # In a module down below + use Koha::Log qw(:log create_logger with_logger) + do things(); + log_warn { "This will show in my.log" }; + ... + my $special_logger = create_logger('File' => {filename => 'my_special.log}); + with_logger $special_logger => sub { + log_warn { "This will show in my_special.log" }; + }; + + This will make the block surounded by with_debug {} output debug to my.log + +=head1 TO DO + + * Add support for Email and possibly other sinks + * Integrate C4::Log + +=cut + +1; diff --git a/debian/control b/debian/control index 96a6650..f16bbab 100644 --- a/debian/control +++ b/debian/control @@ -65,6 +65,7 @@ Build-Depends: libalgorithm-checkdigits-perl, liblocale-currency-format-perl, liblocale-maketext-lexicon-perl, liblocale-po-perl, + liblog-contextual-perl, liblwp-protocol-https-perl|libwww-perl (<6.02), libio-socket-ssl-perl, libmail-sendmail-perl, libmarc-charset-perl, @@ -263,6 +264,7 @@ Depends: libalgorithm-checkdigits-perl, liblocale-currency-format-perl, liblocale-maketext-lexicon-perl, liblocale-po-perl, + liblog-contextual-perl, liblwp-protocol-https-perl|libwww-perl (<6.02), libio-socket-ssl-perl, libmail-sendmail-perl, libmarc-charset-perl, diff --git a/t/Koha_Log.t b/t/Koha_Log.t new file mode 100755 index 0000000..2446a78 --- /dev/null +++ b/t/Koha_Log.t @@ -0,0 +1,77 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use autodie; + +use Test::More tests => 6; +use Test::Output; + +my $LOG_FILE = '/tmp/koha_log_test.log'; +my $DEBUG_LOG_FILE = '/tmp/koha_log_debug.log'; +my $SPECIAL_LOG_FILE = '/tmp/koha_log_special.log'; + +BEGIN { + use_ok('Koha::Log', ":log", "with_logger", "with_debug", "create_logger", "set_default_logger"); +} + +my %sinks = ( + 'Stderr' => {}, + 'Stdout' => {min_level => 'debug'}, + 'Syslog' => {}, + 'File' => {filename => $LOG_FILE}, +); + +remove_log_files(); + +set_default_logger(%sinks); + +my $expect = join '', map "$_\n", "Error", "Warn", "Info", "Koha::Log::Test::test()"; +my $expect_debug = join '', map "$_\n", "Debug1", "Debug2", "Debug3"; + +stdout_is { stderr_is { + log_error { "Error" }; + log_warn { "Warn" }; + log_info { "Info" }; + + Koha::Log::Test::test(); + + log_debug {"Debug1"}; + with_debug { + log_debug {"Debug2"}; + } 'Stderr', 'File', {filename => $DEBUG_LOG_FILE, name => 'debug'}; + log_debug {"Debug3"}; + + my $special_logger = create_logger('File' => {filename => $SPECIAL_LOG_FILE}); + with_logger $special_logger => sub { + log_info { "Special" }; + }; + + log_info { "Last" }; +} $expect."Debug2\n"."Last\n", "logged to stderr" } $expect.$expect_debug."Last\n", "logged to stdout"; + +check_log($LOG_FILE, $expect."Last\n"); +check_log($DEBUG_LOG_FILE, "Debug2\n"); +check_log($SPECIAL_LOG_FILE, "Special\n"); + +remove_log_files(); + +sub check_log { + my ($file, $content) = @_; + + open (my $log, "<", $file); + my $logged = join '', <$log>; + is ($logged, $content, "logged to file $file"); +} + +sub remove_log_files { + -f $_ && unlink $_ foreach $LOG_FILE, $DEBUG_LOG_FILE, $SPECIAL_LOG_FILE; +} + +package Koha::Log::Test; + +use Koha::Log; + +sub test { + log_info { "Koha::Log::Test::test()" }; +} -- 1.9.1 From srdjan at catalyst.net.nz Mon Mar 2 02:46:01 2015 From: srdjan at catalyst.net.nz (Srdjan) Date: Mon, 2 Mar 2015 14:46:01 +1300 Subject: [Koha-patches] [PATCH] bug_13413: use Koha::Log with syslog sink instead of syslog directly in Sipserver.pm Message-ID: <1425260761-24002-1-git-send-email-srdjan@catalyst.net.nz> This way we can sift out debugs --- C4/SIP/SIPServer.pm | 56 +++++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/C4/SIP/SIPServer.pm b/C4/SIP/SIPServer.pm index 20a97c6..c5ec0cd 100755 --- a/C4/SIP/SIPServer.pm +++ b/C4/SIP/SIPServer.pm @@ -5,7 +5,6 @@ use strict; use warnings; use FindBin qw($Bin); use lib "$Bin"; -use Sys::Syslog qw(syslog); use Net::Server::PreFork; use IO::Socket::INET; use Socket qw(:DEFAULT :crlf); @@ -16,6 +15,7 @@ use C4::SIP::Sip::Configuration; use C4::SIP::Sip::Checksum qw(checksum verify_cksum); use C4::SIP::Sip::MsgType qw( handle login_core ); use C4::SIP::Sip qw( read_SIP_packet ); +use Koha::Log qw(:log set_default_logger); use base qw(Net::Server::PreFork); @@ -28,6 +28,11 @@ use constant LOG_SIP => "local6"; # Local alias for the logging facility # A script with no MAIN namespace? # A module that takes command line args? +set_default_logger( + Syslog => {min_level => 'warn', facility => LOG_SIP}, + Stdout => {min_level => 'fatal'}, +); + my %transports = ( RAW => \&raw_transport, telnet => \&telnet_transport, @@ -104,14 +109,13 @@ sub process_request { $self->{service} = $config->find_service($sockaddr, $port, $proto); if (!defined($self->{service})) { - syslog("LOG_ERR", "process_request: Unknown recognized server connection: %s:%s/%s", $sockaddr, $port, $proto); - die "process_request: Bad server connection"; + log_fatal { "process_request: Unknown recognized server connection: %s:%s/%s", $sockaddr, $port, $proto }; } $transport = $transports{$self->{service}->{transport}}; if (!defined($transport)) { - syslog("LOG_WARNING", "Unknown transport '%s', dropping", $service->{transport}); + log_warn { "Unknown transport '%s', dropping", $service->{transport} }; return; } else { &$transport($self); @@ -129,35 +133,35 @@ sub raw_transport { while (!$self->{account}) { local $SIG{ALRM} = sub { die "raw_transport Timed Out!\n"; }; - syslog("LOG_DEBUG", "raw_transport: timeout is %d", $service->{timeout}); + log_debug { "raw_transport: timeout is %d", $service->{timeout} }; $input = read_SIP_packet(*STDIN); if (!$input) { # EOF on the socket - syslog("LOG_INFO", "raw_transport: shutting down: EOF during login"); + log_info { "raw_transport: shutting down: EOF during login" }; return; } $input =~ s/[\r\n]+$//sm; # Strip off trailing line terminator(s) last if C4::SIP::Sip::MsgType::handle($input, $self, LOGIN); } - syslog("LOG_DEBUG", "raw_transport: uname/inst: '%s/%s'", + log_debug { "raw_transport: uname/inst: '%s/%s'", $self->{account}->{id}, - $self->{account}->{institution}); + $self->{account}->{institution} }; $self->sip_protocol_loop(); - syslog("LOG_INFO", "raw_transport: shutting down"); + log_info { "raw_transport: shutting down" }; } sub get_clean_string { my $string = shift; if (defined $string) { - syslog("LOG_DEBUG", "get_clean_string pre-clean(length %s): %s", length($string), $string); + log_debug { "get_clean_string pre-clean(length %s): %s", length($string), $string }; chomp($string); $string =~ s/^[^A-z0-9]+//; $string =~ s/[^A-z0-9]+$//; - syslog("LOG_DEBUG", "get_clean_string post-clean(length %s): %s", length($string), $string); + log_debug { "get_clean_string post-clean(length %s): %s", length($string), $string }; } else { - syslog("LOG_INFO", "get_clean_string called on undefined"); + log_info { "get_clean_string called on undefined" }; } return $string; } @@ -167,7 +171,7 @@ sub get_clean_input { my $in = ; $in = get_clean_string($in); while (my $extra = ){ - syslog("LOG_ERR", "get_clean_input got extra lines: %s", $extra); + log_error { "get_clean_input got extra lines: %s", $extra }; } return $in; } @@ -180,7 +184,7 @@ sub telnet_transport { my $input; my $config = $self->{config}; my $timeout = $self->{service}->{timeout} || $config->{timeout} || 30; - syslog("LOG_DEBUG", "telnet_transport: timeout is %s", $timeout); + log_debug { "telnet_transport: timeout is %s", $timeout }; eval { local $SIG{ALRM} = sub { die "telnet_transport: Timed Out ($timeout seconds)!\n"; }; @@ -199,10 +203,10 @@ sub telnet_transport { $pwd = ; alarm 0; - syslog("LOG_DEBUG", "telnet_transport 1: uid length %s, pwd length %s", length($uid), length($pwd)); + log_debug { "telnet_transport 1: uid length %s, pwd length %s", length($uid), length($pwd) }; $uid = get_clean_string ($uid); $pwd = get_clean_string ($pwd); - syslog("LOG_DEBUG", "telnet_transport 2: uid length %s, pwd length %s", length($uid), length($pwd)); + log_debug { "telnet_transport 2: uid length %s, pwd length %s", length($uid), length($pwd) }; if (exists ($config->{accounts}->{$uid}) && ($pwd eq $config->{accounts}->{$uid}->password())) { @@ -211,25 +215,23 @@ sub telnet_transport { last; } } - syslog("LOG_WARNING", "Invalid login attempt: '%s'", ($uid||'')); + log_warn { "Invalid login attempt: '%s'", ($uid||'') }; print("Invalid login$CRLF"); } }; # End of eval if ($@) { - syslog("LOG_ERR", "telnet_transport: Login timed out"); - die "Telnet Login Timed out"; + log_fatal { "telnet_transport: Login timed out" }; } elsif (!defined($account)) { - syslog("LOG_ERR", "telnet_transport: Login Failed"); - die "Login Failure"; + log_fatal { "telnet_transport: Login Failed" }; } else { - print "Login OK. Initiating SIP$CRLF"; + print "Login OK. Initiating SIP$CRLF"; } $self->{account} = $account; - syslog("LOG_DEBUG", "telnet_transport: uname/inst: '%s/%s'", $account->{id}, $account->{institution}); + log_debug { "telnet_transport: uname/inst: '%s/%s'", $account->{id}, $account->{institution} }; $self->sip_protocol_loop(); - syslog("LOG_INFO", "telnet_transport: shutting down"); + log_info { "telnet_transport: shutting down" }; } # @@ -271,19 +273,19 @@ sub sip_protocol_loop { $input =~ s/[^A-z0-9]+$//s; # Same on the end, should get DOSsy ^M line-endings too. while (chomp($input)) {warn "Extra line ending on input";} unless ($input) { - syslog("LOG_ERR", "sip_protocol_loop: empty input skipped"); + log_error { "sip_protocol_loop: empty input skipped" }; print("96$CR"); next; } # end cheap input hacks my $status = handle($input, $self, $expect); if (!$status) { - syslog("LOG_ERR", "sip_protocol_loop: failed to handle %s",substr($input,0,2)); + log_error { "sip_protocol_loop: failed to handle %s",substr($input,0,2) }; } next if $status eq REQUEST_ACS_RESEND; if ($expect && ($status ne $expect)) { # We received a non-"RESEND" that wasn't what we were expecting. - syslog("LOG_ERR", "sip_protocol_loop: expected %s, received %s, exiting", $expect, $input); + log_error { "sip_protocol_loop: expected %s, received %s, exiting", $expect, $input }; } # We successfully received and processed what we were expecting $expect = ''; -- 1.9.1 From srdjan at catalyst.net.nz Mon Mar 2 02:46:10 2015 From: srdjan at catalyst.net.nz (Srdjan) Date: Mon, 2 Mar 2015 14:46:10 +1300 Subject: [Koha-patches] [PATCH] bug_13413: Koha::Log in longoverdue.pl Message-ID: <1425260770-24085-1-git-send-email-srdjan@catalyst.net.nz> --- misc/cronjobs/longoverdue.pl | 53 +++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/misc/cronjobs/longoverdue.pl b/misc/cronjobs/longoverdue.pl index 193aaaf..342c6c4 100755 --- a/misc/cronjobs/longoverdue.pl +++ b/misc/cronjobs/longoverdue.pl @@ -37,6 +37,7 @@ use C4::Context; use C4::Items; use C4::Circulation qw/LostItem/; use Getopt::Long; +use Koha::Log qw(:log set_default_logger); my $lost; # key=lost value, value=num days. my ($charge, $verbose, $confirm, $quiet); @@ -53,6 +54,16 @@ GetOptions( 'mark-returned' => \$mark_returned, ); +my $log_level = $verbose ? 'debug' : 'info'; +my %loggers; +if ($quiet) { + $loggers{File} = {min_level => $log_level, filename => 'longoverdue.log'}; +} else { + $loggers{Stdout} = {min_level => $log_level, }; +} +set_default_logger( %loggers ); + + my $usage = << 'ENDUSAGE'; longoverdue.pl : This cron script set lost values on overdue items and optionally sets charges the patron's account for the item's replacement price. It is designed to be run as a nightly job. The command line options that globally @@ -126,7 +137,7 @@ if ( ! defined($charge) ) { } unless ($confirm) { $verbose = 1; # If you're not running it for real, then the whole point is the print output. - print "### TEST MODE -- NO ACTIONS TAKEN ###\n"; + log_info { "### TEST MODE -- NO ACTIONS TAKEN ###" }; } # In my opinion, this line is safe SQL to have outside the API. --atz @@ -168,14 +179,18 @@ foreach my $startrange (sort keys %$lost) { if( my $lostvalue = $lost->{$startrange} ) { my ($date1) = bounds($startrange); my ($date2) = bounds( $endrange); - # print "\nRange ", ++$i, "\nDue $startrange - $endrange days ago ($date2 to $date1), lost => $lostvalue\n" if($verbose); - $verbose and - printf "\nRange %s\nDue %3s - %3s days ago (%s to %s), lost => %s\n", ++$i, - $startrange, $endrange, $date2, $date1, $lostvalue; + #log_debug { "\nRange ", ++$i, "\nDue $startrange - $endrange days ago ($date2 to $date1), lost => $lostvalue" }; + log_debug { + sprintf "\nRange %s\nDue %3s - %3s days ago (%s to %s), lost => %s", + ++$i, $startrange, $endrange, $date2, $date1, $lostvalue; + }; $sth_items->execute($startrange, $endrange, $lostvalue); $count=0; while (my $row=$sth_items->fetchrow_hashref) { - printf ("Due %s: item %5s from borrower %5s to lost: %s\n", $row->{date_due}, $row->{itemnumber}, $row->{borrowernumber}, $lostvalue) if($verbose); + log_debug { + sprintf "Due %s: item %5s from borrower %5s to lost: %s", + $row->{date_due}, $row->{itemnumber}, $row->{borrowernumber}, $lostvalue; + }; if($confirm) { ModItem({ itemlost => $lostvalue }, $row->{'biblionumber'}, $row->{'itemnumber'}); LostItem($row->{'itemnumber'}, $mark_returned) if( $charge && $charge eq $lostvalue); @@ -196,20 +211,18 @@ foreach my $startrange (sort keys %$lost) { $endrange = $startrange; } -sub summarize ($$) { - my $arg = shift; # ref to array - my $got_items = shift || 0; # print "count" line for items - my @report = @$arg or return undef; +log_info { my $i = 0; - for my $range (@report) { - printf "\nRange %s\nDue %3s - %3s days ago (%s to %s), lost => %s\n", ++$i, - map {$range->{$_}} qw(startrange endrange date2 date1 lostvalue); - $got_items and printf " %4s items\n", $range->{count}; - } + join "", + "\n### LONGOVERDUE SUMMARY ###", + map ( + sprintf ( + "\nRange %s\nDue %3s - %3s days ago (%s to %s), lost => %s\n %4s items\n", + ++$i, @$_{qw(startrange endrange date2 date1 lostvalue count)} + ), + @report + ), + "\nTOTAL: $total items\n" + ; } -if (!$quiet){ - print "\n### LONGOVERDUE SUMMARY ###"; - summarize (\@report, 1); - print "\nTOTAL: $total items\n"; -} -- 1.9.1 From nengard at bywatersolutions.com Mon Mar 2 10:47:17 2015 From: nengard at bywatersolutions.com (Nicole C. Engard) Date: Mon, 2 Mar 2015 04:47:17 -0500 Subject: [Koha-patches] [PATCH] Bug 13771: Main Page Help fro 3.18 Message-ID: <1425289637-1905-1-git-send-email-nengard@bywatersolutions.com> This updates the main page help file for 3.18. To test: * Log in to staff cleint * Click help on the mian page * Review help file --- .../intranet-tmpl/prog/en/modules/help/mainpage.tt | 16 +++++++--------- 1 files changed, 7 insertions(+), 9 deletions(-) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/help/mainpage.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/help/mainpage.tt index 3d00f88..78c3cf3 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/help/mainpage.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/help/mainpage.tt @@ -1,11 +1,12 @@ [% INCLUDE 'help-top.inc' %] -

I can log in, what is next?

-

If this is your first time logging into Koha, you should now got to Koha Administration and setup all system parameters, especially patron categories.

+

Welcome to Koha

-

Once you have set up patron categories, you should create a new user in "Patrons" with super librarian privileges. Then use that user to log in rather than the root user set up as part of installation.

+

If this is your first time logging into Koha, you should now got to Koha Administration and setup all system preferences, patron categories, item types and libraries. You should also review the other settings found in administration.

-

Here are some other suggestions:

+

Once you have set up patron categories, you should create a new user in the Patrons module with superlibrarian permissions. Once that user is set you should use that user to log in rather than the root user set up as part of installation.

+ +

Here are some other places to look for more information about how to proceed:

-

Can I edit the online help?

+

Can I edit the online help?

You can edit the online help through the Koha Staff Client by clicking the "Edit Help" button. This feature has been designed so that library workflow and policies can be documented within Koha.

-

IMPORTANT NOTE: Online help is overwritten during a Koha upgrade.

- -

As part of the upgrade process your online help will be overwritten with the new Help as part of the install. If you want to keep a copy of your online help, you should instruct your System Administrator to upgrade the Online Help directory in the Koha file tree.

+

IMPORTANT: As part of the upgrade process your online help will be overwritten with the new Help as part of the install. If you want to keep a copy of your online help, you should instruct your System Administrator to upgrade the Online Help directory in the Koha file tree.

The online help directory is:

[% themelang %]/modules/help

See the full documentation for Koha in the manual (online).

- [% INCLUDE 'help-bottom.inc' %] -- 1.7.2.5 From nengard at bywatersolutions.com Mon Mar 2 11:32:47 2015 From: nengard at bywatersolutions.com (Nicole C. Engard) Date: Mon, 2 Mar 2015 05:32:47 -0500 Subject: [Koha-patches] [PATCH] BUG 13771: Update Tools Help Files for 3.18 Message-ID: <1425292367-2279-1-git-send-email-nengard@bywatersolutions.com> This patch creates a helpf ile for the batch record delete tool and updates the help files for notices and marc export. To test: * Visit tools > batch record deletion * confirm help is right * Visit tools > Notices & Slips * confirm help is right * Visit tools > export marc * cofirm the help is right --- .../en/modules/help/tools/batch_delete_records.tt | 15 +++++++++++++++ .../prog/en/modules/help/tools/export.tt | 2 ++ .../prog/en/modules/help/tools/letter.tt | 1 - 3 files changed, 17 insertions(+), 1 deletions(-) create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/help/tools/batch_delete_records.tt diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/help/tools/batch_delete_records.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/help/tools/batch_delete_records.tt new file mode 100644 index 0000000..0df79f6 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/help/tools/batch_delete_records.tt @@ -0,0 +1,15 @@ +[% INCLUDE 'help-top.inc' %] + +

Batch record deletion

+ +

This tool will take a batch of record numbers for either bibliographic records or authority records and allow you to delete all those records and any items attached to them in a batch.

+ +

First you need to tell the tool if you're deleting bibliographic or authority records. Next you can load a file with biblionumbers or authids or enter a list of those numbers in the box provided. Once you submit the form you will be presented with a summary of the records you are trying to delete.

+ +

If a record you want to delete can't be deleted it will be highlighted.

+ +

Check the records you want to delete and click the 'Delete selected records' button to finish the process.

+ +

See the full documentation for Batch Delete Records in the manual (online).

+ +[% INCLUDE 'help-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/help/tools/export.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/help/tools/export.tt index e0fd1fb..9dd5cde 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/help/tools/export.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/help/tools/export.tt @@ -20,6 +20,7 @@
  • Limit to an acquisition date range
  • +
  • If you'd like you can load a file of biblionumbers for the records you would like to export
  • Next choose what to skip when exporting
    • By default items will be exported, if you would like to only export bibliographic data, check the 'Don't export items' box
    • @@ -44,6 +45,7 @@
      • Fill in the form in order to limit your export to a specific range or type of authority record (all fields are optional)
      • +
      • If you'd like you can load a file of authority id numbers for the records you would like to export
      • Next choose fields that you would like to exclude from the export separated by a space (no commas)
        • If you'd like to exclude all subfields of the 200 for example just enter 200
        • diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/help/tools/letter.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/help/tools/letter.tt index 568c4f3..09692d3 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/help/tools/letter.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/help/tools/letter.tt @@ -29,7 +29,6 @@
        • Next you can customize the notice for every possible delivery method
          • Every notice should have an Email template set for it
          • -
          • Next, you can set up a Feed template
          • If you're using the TalkingTechItivaPhoneNotification service you can set up a Phone notification
          • If you plan on printing this notice you can set the Print template next
          • If you have enabled SMS notices with the SMSSendDriver preference you can set the text for your SMS notices next
          • -- 1.7.2.5 From dpavlin at rot13.org Mon Mar 2 12:24:39 2015 From: dpavlin at rot13.org (Dobrica Pavlinusic) Date: Mon, 2 Mar 2015 12:24:39 +0100 Subject: [Koha-patches] [PATCH] Bug 13773 - add stock number to details and items display Message-ID: <1425295479-17391-1-git-send-email-dpavlin@rot13.org> This patch adds stocknumber to details table and items display if it exists. Test scenario: 1. find item(s) which have stock number assigned 2. verify that you don't see stock number in items display 3. apply this patch 4. verify that stock number is now available --- catalogue/detail.pl | 3 ++- .../prog/en/modules/catalogue/detail.tt | 5 +++++ 2 files changed, 7 insertions(+), 1 deletions(-) diff --git a/catalogue/detail.pl b/catalogue/detail.pl index adf6823..95513b7 100755 --- a/catalogue/detail.pl +++ b/catalogue/detail.pl @@ -224,7 +224,7 @@ foreach my $item (@items) { $item->{'ccode'} = $collections->{$ccode} if ( defined( $ccode ) && defined($collections) && exists( $collections->{$ccode} ) ); my $copynumber = $item->{'copynumber'}; $item->{'copynumber'} = $copynumbers->{$copynumber} if ( defined($copynumber) && defined($copynumbers) && exists( $copynumbers->{$copynumber} ) ); - foreach (qw(ccode enumchron copynumber itemnotes uri)) { + foreach (qw(ccode enumchron copynumber stocknumber itemnotes uri)) { $itemfields{$_} = 1 if ( $item->{$_} ); } @@ -313,6 +313,7 @@ $template->param( itemdata_enumchron => $itemfields{enumchron}, itemdata_uri => $itemfields{uri}, itemdata_copynumber => $itemfields{copynumber}, + itemdata_stocknumber => $itemfields{stocknumber}, volinfo => $itemfields{enumchron}, itemdata_itemnotes => $itemfields{itemnotes}, z3950_search_params => C4::Search::z3950_search_args($dat), diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt index ee5915e..02730b3 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt @@ -561,6 +561,7 @@ function verify_images() { [% IF ( volinfo ) %]Publication details[% END %] [% IF ( itemdata_uri ) %]url[% END %] [% IF ( itemdata_copynumber ) %]Copy number[% END %] + [% IF ( itemdata_stocknumber ) %]Stock number[% END %] [% IF materials %]Materials specified[% END %] [% IF ( itemdata_itemnotes ) %]Public notes[% END %] [% IF ( SpineLabelShowPrintOnBibDetails ) %]Spine label[% END %] @@ -725,6 +726,9 @@ function verify_images() { [% IF ( itemdata_copynumber ) %] [% item.copynumber %] [% END %] + [% IF ( itemdata_stocknumber ) %] + [% item.stocknumber %] + [% END %] [% IF materials %] [% item.materials %] [% END %] @@ -788,6 +792,7 @@ function verify_images() { +
            itemdata_enumchron[% itemdata_enumchron %]
            itemdata_copynumber[% itemdata_copynumber %]
            itemdata_stocknumber[% itemdata_stocknumber %]
            serial[% serial %]
            [% END %] -- 1.7.2.5 From dpavlin at rot13.org Wed Mar 4 14:32:04 2015 From: dpavlin at rot13.org (Dobrica Pavlinusic) Date: Wed, 4 Mar 2015 14:32:04 +0100 Subject: [Koha-patches] [PATCH] Bug 13789 - facets with accented utf-8 characters generate double encoded links Message-ID: <1425475924-28235-1-git-send-email-dpavlin@rot13.org> Bug 13425 tried to fix XSS in OPAC, by using url filter in template toolkit on whole generated url. This doesn't work and create double encoded strings in facets because we are creating url variable by concatenating query_cgi (which did pass through uri_escape_utf8 on perl side) and other parameters which have to be escaped in template. Also, code like [% SET limit_cgi_f = limit_cgi | url %] doesn't do anything (at least doesn't apply url filter) so it's not needed. Test scenario: 1. find results in your opac which contain accented characters 2. click on them and verify that results are missing 3. apply this patch 4. re-run search and click on facets link verifying that there are now results 5. verify that facets are still safe from injection by constructing url like /cgi-bin/koha/opac-search.pl?q=123&sort_by='">&limit=123 and verifying that you DON'T see prompt window in your browser --- .../bootstrap/en/includes/opac-facets.inc | 11 +++++------ 1 files changed, 5 insertions(+), 6 deletions(-) diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-facets.inc b/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-facets.inc index 6e846f0..44fd40c 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-facets.inc +++ b/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-facets.inc @@ -32,20 +32,19 @@
              [% FOREACH facet IN facets_loo.facets %]
            • - [% SET query_cgi_f = query_cgi %] - [% SET limit_cgi_f = limit_cgi | url %] - [% SET url = "/cgi-bin/koha/opac-search.pl?" _ query_cgi_f _ limit_cgi_f %] + [% SET url = "/cgi-bin/koha/opac-search.pl?" _ query_cgi %] + [% url = BLOCK %][% url %][% limit_cgi |url %][% END %] [% IF ( sort_by ) %] - [% SET url = url _ "&sort_by=" _ sort_by |url %] + [% url = BLOCK %][% url %][% "&sort_by=" _ sort_by |url %][% END %] [% END %] [% facet.facet_link_value = BLOCK %][% facet.facet_link_value | uri %][% END %] [% IF facet.active %] [% SET url = url _ "&nolimit=" _ facet.type_link_value _ ":" _ facet.facet_link_value %] [% facet.facet_label_value %] - [x] + [x] [% ELSE %] [% SET url = url _ "&limit=" _ facet.type_link_value _ ":" _ facet.facet_link_value %] - [% facet.facet_label_value %] + [% facet.facet_label_value %] [% IF ( displayFacetCount ) %] ([% facet.facet_count %]) [% END %] -- 1.7.2.5 From dpavlin at rot13.org Thu Mar 5 09:37:41 2015 From: dpavlin at rot13.org (Dobrica Pavlinusic) Date: Thu, 5 Mar 2015 09:37:41 +0100 Subject: [Koha-patches] [PATCH] Bug 13773 - add stock number to details and items display Message-ID: <1425544661-20029-1-git-send-email-dpavlin@rot13.org> This patch adds stocknumber (named Inventory number in interface) to details table and items display if it exists. Test scenario: 1. find item(s) which have inventory number assigned 2. verify that you don't see inventory number in items display 3. apply this patch 4. verify that inventory number is now available --- catalogue/detail.pl | 3 ++- .../prog/en/modules/catalogue/detail.tt | 4 ++++ 2 files changed, 6 insertions(+), 1 deletions(-) diff --git a/catalogue/detail.pl b/catalogue/detail.pl index adf6823..95513b7 100755 --- a/catalogue/detail.pl +++ b/catalogue/detail.pl @@ -224,7 +224,7 @@ foreach my $item (@items) { $item->{'ccode'} = $collections->{$ccode} if ( defined( $ccode ) && defined($collections) && exists( $collections->{$ccode} ) ); my $copynumber = $item->{'copynumber'}; $item->{'copynumber'} = $copynumbers->{$copynumber} if ( defined($copynumber) && defined($copynumbers) && exists( $copynumbers->{$copynumber} ) ); - foreach (qw(ccode enumchron copynumber itemnotes uri)) { + foreach (qw(ccode enumchron copynumber stocknumber itemnotes uri)) { $itemfields{$_} = 1 if ( $item->{$_} ); } @@ -313,6 +313,7 @@ $template->param( itemdata_enumchron => $itemfields{enumchron}, itemdata_uri => $itemfields{uri}, itemdata_copynumber => $itemfields{copynumber}, + itemdata_stocknumber => $itemfields{stocknumber}, volinfo => $itemfields{enumchron}, itemdata_itemnotes => $itemfields{itemnotes}, z3950_search_params => C4::Search::z3950_search_args($dat), diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt index ee5915e..1aa765e 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt @@ -561,6 +561,7 @@ function verify_images() { [% IF ( volinfo ) %]Publication details[% END %] [% IF ( itemdata_uri ) %]url[% END %] [% IF ( itemdata_copynumber ) %]Copy number[% END %] + [% IF ( itemdata_stocknumber ) %]Inventory number[% END %] [% IF materials %]Materials specified[% END %] [% IF ( itemdata_itemnotes ) %]Public notes[% END %] [% IF ( SpineLabelShowPrintOnBibDetails ) %]Spine label[% END %] @@ -725,6 +726,9 @@ function verify_images() { [% IF ( itemdata_copynumber ) %] [% item.copynumber %] [% END %] + [% IF ( itemdata_stocknumber ) %] + [% item.stocknumber %] + [% END %] [% IF materials %] [% item.materials %] [% END %] -- 1.7.2.5 From christophe.croullebois at biblibre.com Tue Mar 10 14:04:46 2015 From: christophe.croullebois at biblibre.com (Christophe Croullebois) Date: Tue, 10 Mar 2015 14:04:46 +0100 Subject: [Koha-patches] [PATCH 1/1] Bug 13768: Correction of double quotes escaped into double quotes Message-ID: <1425992686-3677-1-git-send-email-christophe.croullebois@biblibre.com> Without the patch the translated pages for quotes.tt may have the problematic line broken. So the js is broken too. The line with bad usage of double quotes escaped : var sEmptyTable = _("No quotes available. Please use the \"Add quote\" button to add a quote."); --- .../intranet-tmpl/prog/en/modules/tools/quotes.tt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/quotes.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/quotes.tt index 25aceaa..8ae34ec 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/quotes.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/quotes.tt @@ -11,7 +11,7 @@ var MSG_ID_HELP = _("Click on the quote's id to select or deselect the quote. Multiple quotes may be selected."); var oTable; /* oTable needs to be global */ - var sEmptyTable = _("No quotes available. Please use the \"Add quote\" button to add a quote."); /* override the default message in datatables-strings.inc */ + var sEmptyTable = _("No quotes available. Please use the 'Add quote' button to add a quote."); /* override the default message in datatables-strings.inc */ $(document).ready(function() { /* NOTE: This is an ajax-source datatable and *not* a server-side sourced datatable. */ /* See the datatable docs if you don't understand this difference. */ -- 1.7.9.5 From dpavlin at rot13.org Tue Mar 17 12:15:48 2015 From: dpavlin at rot13.org (Dobrica Pavlinusic) Date: Tue, 17 Mar 2015 12:15:48 +0100 Subject: [Koha-patches] [PATCH] Bug 13815 - plack loose CGI qw(-utf8) flag creating incorrect utf-8 encoding everywhere Message-ID: <1426590948-22654-1-git-send-email-dpavlin@rot13.org> This is major problem for plack installations with utf-8 encoding. In this case, we are overriding CGI->new to setup utf-8 flag and get correctly decoded $cgi->params, and reset syspref cache using C4::Context->clear_syspref_cache Test scenario: 1. under plack try to search with utf-8 charactes 2. try to find patron with utf-8 characters --- misc/plack/koha.psgi | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/misc/plack/koha.psgi b/misc/plack/koha.psgi index 7acb567..a35eb77 100644 --- a/misc/plack/koha.psgi +++ b/misc/plack/koha.psgi @@ -5,6 +5,18 @@ use lib qw( ./lib ); use Plack::Middleware::Debug; use Plack::App::Directory; +use CGI qw(-utf8 ); # we will loose -utf8 under plack +{ + no warnings 'redefine'; + my $old_new = \&CGI::new; + *CGI::new = sub { + my $q = $old_new->( @_ ); + $CGI::PARAM_UTF8 = 1; + C4::Context->clear_syspref_cache(); + return $q; + }; +} + BEGIN { # override configuration from startup script below: -- 1.7.2.5 From hector.hecaxmmx at gmail.com Fri Mar 20 05:36:46 2015 From: hector.hecaxmmx at gmail.com (Hector Eduardo Castro Avalos) Date: Thu, 19 Mar 2015 22:36:46 -0600 Subject: [Koha-patches] [PATCH] Bug 13878 - Typo in help file (aqbudgets.tt) Message-ID: <1426826206-6078-1-git-send-email-hector.hecaxmmx@gmail.com> Test plan: 1) Go to url 'koha-tmpl/intranet-tmpl/prog/en/modules/help/admin/aqbudgets.tt:15' and check the typo "wan" or go to Administration > Acquisition parameters > Funds > Help 2) Apply the patch 3) Repeat step 1 and check if the typo is fixed. Sponsored-by: Universidad de El Salvador Signed-off-by: Hector Eduardo Castro Avalos --- koha-tmpl/intranet-tmpl/prog/en/modules/help/admin/aqbudgets.tt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/help/admin/aqbudgets.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/help/admin/aqbudgets.tt index 2eed8d6..e48a45a 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/help/admin/aqbudgets.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/help/admin/aqbudgets.tt @@ -12,7 +12,7 @@

              To add a new fund click the New button and then choose which Budget you would like to add the fund to.

              -

              In the form that appears you wan to enter the basics about your fund.

              +

              In the form that appears you want to enter the basics about your fund.

              The three first fields are required, the rest are optional

              -- 1.7.10.4 From hector.hecaxmmx at gmail.com Fri Mar 20 05:28:39 2015 From: hector.hecaxmmx at gmail.com (Hector Eduardo Castro Avalos) Date: Thu, 19 Mar 2015 22:28:39 -0600 Subject: [Koha-patches] [PATCH] Bug 13878 - Typo in help file (aqbudgets.tt) Message-ID: <1426825720-5953-1-git-send-email-hector.hecaxmmx@gmail.com> Test plan: 1) Go to url 'koha-tmpl/intranet-tmpl/prog/en/modules/help/admin/aqbudgets.tt:15' and check the typo "wan" or go to Administration > Acquisition parameters > Funds > Help 2) Apply the patch 3) Repeat step 1 and check if the typo is fixed. Sponsored-by: Universidad de El Salvador Signed-off-by: Hector Eduardo Castro Avalos --- koha-tmpl/intranet-tmpl/prog/en/modules/help/admin/aqbudgets.tt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/help/admin/aqbudgets.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/help/admin/aqbudgets.tt index 2eed8d6..e48a45a 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/help/admin/aqbudgets.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/help/admin/aqbudgets.tt @@ -12,7 +12,7 @@

              To add a new fund click the New button and then choose which Budget you would like to add the fund to.

              -

              In the form that appears you wan to enter the basics about your fund.

              +

              In the form that appears you want to enter the basics about your fund.

              The three first fields are required, the rest are optional

              -- 1.7.10.4 From srdjan at catalyst.net.nz Thu Mar 26 07:36:05 2015 From: srdjan at catalyst.net.nz (Srdjan) Date: Thu, 26 Mar 2015 19:36:05 +1300 Subject: [Koha-patches] [PATCH] Bug 5786: Correction: Moved holdability check from opac-search.pl to searchResults() Message-ID: <1427351765-27206-1-git-send-email-srdjan@catalyst.net.nz> Additional param $borrowernumber for searchResults() when searching in OPAC --- C4/Search.pm | 24 ++++++++++++++++------ .../opac-tmpl/bootstrap/en/modules/opac-results.tt | 2 +- opac/opac-detail.pl | 2 +- opac/opac-search.pl | 21 ++----------------- 4 files changed, 22 insertions(+), 27 deletions(-) diff --git a/C4/Search.pm b/C4/Search.pm index f93dd15..2ddc238 100644 --- a/C4/Search.pm +++ b/C4/Search.pm @@ -25,7 +25,7 @@ use Lingua::Stem; use C4::Search::PazPar2; use XML::Simple; use C4::Dates qw(format_date); -use C4::Members qw(GetHideLostItemsPreference); +use C4::Members qw(GetHideLostItemsPreference GetMember); use C4::XSLT; use C4::Branch; use C4::Reserves; # GetReserveStatus @@ -1833,7 +1833,7 @@ Format results in a form suitable for passing to the template # IMO this subroutine is pretty messy still -- it's responsible for # building the HTML output for the template sub searchResults { - my ( $search_context, $searchdesc, $hits, $results_per_page, $offset, $scan, $marcresults ) = @_; + my ( $search_context, $searchdesc, $hits, $results_per_page, $offset, $scan, $marcresults, $borrowernumber ) = @_; my $dbh = C4::Context->dbh; my @newresults; @@ -1863,6 +1863,12 @@ sub searchResults { # get notforloan authorised value list (see $shelflocations FIXME) my $notforloan_authorised_value = GetAuthValCode('items.notforloan',''); + my $userenv = C4::Context->userenv; + my $hide_lost_items = GetHideLostItemsPreference($userenv->{'number'}); + + # $borrowernumber is passed for opac search + my $borrower = $borrowernumber ? GetMember( borrowernumber => $borrowernumber ) : undef; + #Build itemtype hash #find itemtype & itemtype image my %itemtypes; @@ -2038,13 +2044,15 @@ sub searchResults { my $onloan_count = 0; my $longoverdue_count = 0; my $other_count = 0; - my $withdrawn_count = 0; + my $withdrawn_count = 0; my $itemlost_count = 0; my $hideatopac_count = 0; my $itembinding_count = 0; my $itemdamaged_count = 0; my $item_in_transit_count = 0; my $can_place_holds = 0; + # If no borrower no point checking issuing_rules + my $can_place_item_holds = $borrower ? 0 : 1; my $item_onhold_count = 0; my $notforloan_count = 0; my $items_count = scalar(@fields); @@ -2091,8 +2099,7 @@ sub searchResults { my $prefix = $item->{$hbranch} . '--' . $item->{location} . $item->{itype} . $item->{itemcallnumber}; # For each grouping of items (onloan, available, unavailable), we build a key to store relevant info about that item - my $userenv = C4::Context->userenv; - if ( $item->{onloan} && !(C4::Members::GetHideLostItemsPreference($userenv->{'number'}) && $item->{itemlost}) ) { + if ( $item->{onloan} && !($hide_lost_items && $item->{itemlost}) ) { $onloan_count++; my $key = $prefix . $item->{onloan} . $item->{barcode}; $onloan_items->{$key}->{due_date} = format_date($item->{onloan}); @@ -2203,6 +2210,11 @@ sub searchResults { $available_items->{$prefix}->{imageurl} = getitemtypeimagelocation( $search_context, $itemtypes{ $item->{itype} }->{imageurl} ); } } + # ||= because we only need one + $can_place_item_holds + ||= IsAvailableForItemLevelRequest($item, $borrower) && + OPACItemHoldsAllowed($item, $borrower) + if $can_place_holds && $borrower; } # notforloan, item level and biblioitem level # if all items are hidden, do not show the record @@ -2237,7 +2249,7 @@ sub searchResults { $can_place_holds = 0; } } - $oldbiblio->{norequests} = 1 unless $can_place_holds; + $oldbiblio->{norequests} = !($can_place_holds && $can_place_item_holds); $oldbiblio->{itemsplural} = 1 if $items_count > 1; $oldbiblio->{items_count} = $items_count; $oldbiblio->{available_items_loop} = \@available_items_loop; diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt index fd2cb9f..2622b59 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt @@ -471,7 +471,7 @@
              [% IF Koha.Preference( 'RequestOnOpac' ) == 1 %] [% UNLESS ( SEARCH_RESULT.norequests ) %] - [% IF ( Koha.Preference( 'opacuserlogin' ) == 1 ) && SEARCH_RESULT.holdable %] + [% IF ( Koha.Preference( 'opacuserlogin' ) == 1 ) %] Place hold [% END # / IF opacuserlogin && holdable %] [% END # UNLESS SEARCH_RESULT.norequests %] diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl index c5f9a6f..0ff60b1 100755 --- a/opac/opac-detail.pl +++ b/opac/opac-detail.pl @@ -207,7 +207,7 @@ if ($session->param('busc')) { for (my $i=0;$i<@servers;$i++) { my $server = $servers[$i]; $hits = $results_hashref->{$server}->{"hits"}; - @newresults = searchResults('opac', '', $hits, $results_per_page, $offset, $arrParamsBusc->{'scan'}, $results_hashref->{$server}->{"RECORDS"}); + @newresults = searchResults('opac', '', $hits, $results_per_page, $offset, $arrParamsBusc->{'scan'}, $results_hashref->{$server}->{"RECORDS"}, $borrowernumber); } return \@newresults; }#searchAgain diff --git a/opac/opac-search.pl b/opac/opac-search.pl index cdf0fbb..0327cd9 100755 --- a/opac/opac-search.pl +++ b/opac/opac-search.pl @@ -42,8 +42,6 @@ use C4::Branch; # GetBranches use C4::SocialData; use C4::Ratings; use C4::External::OverDrive; -use C4::Members; -use C4::Reserves; use POSIX qw(ceil floor strftime); use URI::Escape; @@ -569,11 +567,8 @@ if ($@ || $error) { exit; } -my $borrower = $borrowernumber ? GetMember( borrowernumber => $borrowernumber ) : undef; - # At this point, each server has given us a result set # now we build that set for template display -my %allow_onshelf_holds; my @sup_results_array; for (my $i=0;$i<@servers;$i++) { my $server = $servers[$i]; @@ -587,24 +582,12 @@ for (my $i=0;$i<@servers;$i++) { # we want as specified by $offset and $results_per_page, # we need to set the offset parameter of searchResults to 0 my @group_results = searchResults( 'opac', $query_desc, $group->{'group_count'},$results_per_page, 0, $scan, - $group->{"RECORDS"}); - if ($borrower) { - $_->{holdable} = - IsAvailableForItemLevelRequest($_, $borrower) && - OPACItemHoldsAllowed($_, $borrower) - foreach @group_results; - } + $group->{"RECORDS"}, $borrowernumber); push @newresults, { group_label => $group->{'group_label'}, GROUP_RESULTS => \@group_results }; } } else { @newresults = searchResults('opac', $query_desc, $hits, $results_per_page, $offset, $scan, - $results_hashref->{$server}->{"RECORDS"}); - if ($borrower) { - $_->{holdable} = - IsAvailableForItemLevelRequest($_, $borrower) && - OPACItemHoldsAllowed($_, $borrower) - foreach @newresults; - } + $results_hashref->{$server}->{"RECORDS"}, $borrowernumber); } $hits = 0 unless @newresults; -- 1.9.1 From srdjan at catalyst.net.nz Fri Mar 27 01:21:26 2015 From: srdjan at catalyst.net.nz (Srdjan) Date: Fri, 27 Mar 2015 13:21:26 +1300 Subject: [Koha-patches] [PATCH] Bug 5786: Correction: Removed erroneous holdability check from opac-search.pl Message-ID: <1427415686-5121-1-git-send-email-srdjan@catalyst.net.nz> --- .../opac-tmpl/bootstrap/en/modules/opac-results.tt | 2 +- opac/opac-search.pl | 17 ----------------- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt index fd2cb9f..2622b59 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt @@ -471,7 +471,7 @@
              [% IF Koha.Preference( 'RequestOnOpac' ) == 1 %] [% UNLESS ( SEARCH_RESULT.norequests ) %] - [% IF ( Koha.Preference( 'opacuserlogin' ) == 1 ) && SEARCH_RESULT.holdable %] + [% IF ( Koha.Preference( 'opacuserlogin' ) == 1 ) %] Place hold [% END # / IF opacuserlogin && holdable %] [% END # UNLESS SEARCH_RESULT.norequests %] diff --git a/opac/opac-search.pl b/opac/opac-search.pl index cdf0fbb..f634f12 100755 --- a/opac/opac-search.pl +++ b/opac/opac-search.pl @@ -42,8 +42,6 @@ use C4::Branch; # GetBranches use C4::SocialData; use C4::Ratings; use C4::External::OverDrive; -use C4::Members; -use C4::Reserves; use POSIX qw(ceil floor strftime); use URI::Escape; @@ -569,11 +567,8 @@ if ($@ || $error) { exit; } -my $borrower = $borrowernumber ? GetMember( borrowernumber => $borrowernumber ) : undef; - # At this point, each server has given us a result set # now we build that set for template display -my %allow_onshelf_holds; my @sup_results_array; for (my $i=0;$i<@servers;$i++) { my $server = $servers[$i]; @@ -588,23 +583,11 @@ for (my $i=0;$i<@servers;$i++) { # we need to set the offset parameter of searchResults to 0 my @group_results = searchResults( 'opac', $query_desc, $group->{'group_count'},$results_per_page, 0, $scan, $group->{"RECORDS"}); - if ($borrower) { - $_->{holdable} = - IsAvailableForItemLevelRequest($_, $borrower) && - OPACItemHoldsAllowed($_, $borrower) - foreach @group_results; - } push @newresults, { group_label => $group->{'group_label'}, GROUP_RESULTS => \@group_results }; } } else { @newresults = searchResults('opac', $query_desc, $hits, $results_per_page, $offset, $scan, $results_hashref->{$server}->{"RECORDS"}); - if ($borrower) { - $_->{holdable} = - IsAvailableForItemLevelRequest($_, $borrower) && - OPACItemHoldsAllowed($_, $borrower) - foreach @newresults; - } } $hits = 0 unless @newresults; -- 1.9.1