Bug 16493: [QA Followup] Restore title and author match as an option, make it the...
[koha.git] / C4 / Log.pm
blob385f4dbfead4ec166c523fa7f9ec8aa8edf8c339
1 package C4::Log;
3 #package to deal with Logging Actions in DB
6 # Copyright 2000-2002 Katipo Communications
7 # Copyright 2011 MJ Ray and software.coop
9 # This file is part of Koha.
11 # Koha is free software; you can redistribute it and/or modify it
12 # under the terms of the GNU General Public License as published by
13 # the Free Software Foundation; either version 3 of the License, or
14 # (at your option) any later version.
16 # Koha is distributed in the hope that it will be useful, but
17 # WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 # GNU General Public License for more details.
21 # You should have received a copy of the GNU General Public License
22 # along with Koha; if not, see <http://www.gnu.org/licenses>.
24 use strict;
25 use warnings;
27 use JSON qw( to_json );
29 use C4::Context;
30 use Koha::DateUtils;
31 use Koha::Logger;
33 use vars qw(@ISA @EXPORT);
35 BEGIN {
36 require Exporter;
37 @ISA = qw(Exporter);
38 @EXPORT = qw(&logaction &cronlogaction &GetLogStatus &displaylog &GetLogs);
41 =head1 NAME
43 C4::Log - Koha Log Facility functions
45 =head1 SYNOPSIS
47 use C4::Log;
49 =head1 DESCRIPTION
51 The functions in this module perform various functions in order to log all the operations done on the Database, including deleting and undeleting books, adding/editing members, etc.
53 =head1 FUNCTIONS
55 =over 2
57 =item logaction
59 &logaction($modulename, $actionname, $objectnumber, $infos);
61 Adds a record into action_logs table to report the different changes upon the database.
62 Each log entry includes the number of the user currently logged in. For batch
63 jobs, which operate without authenticating a user and setting up a session, the user
64 number is set to 0, which is the same as the superlibrarian's number.
66 =cut
69 sub logaction {
70 my ($modulename, $actionname, $objectnumber, $infos)=@_;
72 # Get ID of logged in user. if called from a batch job,
73 # no user session exists and C4::Context->userenv() returns
74 # the scalar '0'.
75 my $userenv = C4::Context->userenv();
76 my $usernumber = (ref($userenv) eq 'HASH') ? $userenv->{'number'} : 0;
77 $usernumber ||= 0;
79 my $dbh = C4::Context->dbh;
80 my $sth=$dbh->prepare("Insert into action_logs (timestamp,user,module,action,object,info) values (now(),?,?,?,?,?)");
81 $sth->execute($usernumber,$modulename,$actionname,$objectnumber,$infos);
82 $sth->finish;
84 my $logger = Koha::Logger->get(
86 interface => 'intranet',
87 category => "ActionLogs.$modulename.$actionname"
90 $logger->debug(
91 sub {
92 "ACTION LOG: " . to_json(
94 user => $usernumber,
95 module => $modulename,
96 action => $actionname,
97 object => $objectnumber,
98 info => $infos
105 =item cronlogaction
107 &cronlogaction($infos);
109 Convenience routine to add a record into action_logs table from a cron job.
110 Logs the path and name of the calling script plus the information privided by param $infos.
112 =cut
115 sub cronlogaction {
116 my ($infos)=@_;
117 my $loginfo = (caller(0))[1];
118 $loginfo .= ' ' . $infos if $infos;
119 logaction( 'CRONJOBS', 'Run', undef, $loginfo ) if C4::Context->preference('CronjobLog');
123 =item GetLogStatus
125 $status = GetLogStatus;
127 C<$status> is a hasref like this example:
128 $hash = {
129 BorrowersLog => 1,
130 CataloguingLog => 0,
131 IssueLog => 0,
135 =cut
138 sub GetLogStatus {
139 my %hash;
140 $hash{BorrowersLog} = C4::Context->preference("BorrowersLog");
141 $hash{CataloguingLog} = C4::Context->preference("CataloguingLog");
142 $hash{IssueLog} = C4::Context->preference("IssueLog");
143 $hash{ReturnLog} = C4::Context->preference("ReturnLog");
144 $hash{SubscriptionLog} = C4::Context->preference("SubscriptionLog");
145 $hash{LetterLog} = C4::Context->preference("LetterLog");
146 $hash{FinesLog} = C4::Context->preference("FinesLog");
147 return \%hash;
150 =item displaylog
152 &displaylog($modulename, @filters);
153 $modulename is the name of the module on which the user wants to display logs
154 @filters is an optional table of hash containing :
155 - name : the name of the variable to filter
156 - value : the value of the filter.... May be with * joker
158 returns a table of hash containing who did what on which object at what time
160 =cut
163 sub displaylog {
164 my ($modulename, @filters) = @_;
165 my $dbh = C4::Context->dbh;
166 my $strsth=qq|
167 SELECT action_logs.timestamp, action_logs.action, action_logs.info,
168 borrowers.cardnumber, borrowers.surname, borrowers.firstname, borrowers.userid,
169 biblio.biblionumber, biblio.title, biblio.author
170 FROM action_logs
171 LEFT JOIN borrowers ON borrowers.borrowernumber=action_logs.user
172 LEFT JOIN biblio ON action_logs.object=biblio.biblionumber
173 WHERE action_logs.module = 'cataloguing'
175 my %filtermap = ();
176 if ($modulename eq "catalogue" or $modulename eq "acqui") {
177 %filtermap = (
178 user => 'borrowers.surname',
179 title => 'biblio.title',
180 author => 'biblio.author',
182 } elsif ($modulename eq "members") {
183 $strsth=qq|
184 SELECT action_logs.timestamp, action_logs.action, action_logs.info,
185 borrowers.cardnumber, borrowers.surname, borrowers.firstname, borrowers.userid,
186 bor2.cardnumber, bor2.surname, bor2.firstname, bor2.userid
187 FROM action_logs
188 LEFT JOIN borrowers ON borrowers.borrowernumber=action_logs.user
189 LEFT JOIN borrowers as bor2 ON action_logs.object=bor2.borrowernumber
190 WHERE action_logs.module = 'members'
192 %filtermap = (
193 user => 'borrowers.surname',
194 surname => 'bor2.surname',
195 firstname => 'bor2.firstname',
196 cardnumber => 'bor2.cardnumber',
198 } else {
199 return 0;
202 if (@filters) {
203 foreach my $filter (@filters) {
204 my $tempname = $filter->{name} or next;
205 (grep {/^$tempname$/} keys %filtermap) or next;
206 $filter->{value} =~ s/\*/%/g;
207 $strsth .= " AND " . $filtermap{$tempname} . " LIKE " . $filter->{value};
210 my $sth=$dbh->prepare($strsth);
211 $sth->execute;
212 my @results;
213 my $count;
214 my $hilighted=1;
215 while (my $data = $sth->fetchrow_hashref){
216 $data->{hilighted} = ($hilighted>0);
217 $data->{info} =~ s/\n/<br\/>/g;
218 $data->{day} = output_pref({ str => $data->{timestamp} });
219 push @results, $data;
220 $count++;
221 $hilighted = -$hilighted;
223 return ($count, \@results);
226 =item GetLogs
228 $logs = GetLogs($datefrom,$dateto,$user,\@modules,$action,$object,$info);
230 Return:
231 C<$logs> is a ref to a hash which containts all columns from action_logs
233 =cut
235 sub GetLogs {
236 my $datefrom = shift;
237 my $dateto = shift;
238 my $user = shift;
239 my $modules = shift;
240 my $action = shift;
241 my $object = shift;
242 my $info = shift;
244 my $iso_datefrom = $datefrom ? output_pref({ dt => dt_from_string( $datefrom ), dateformat => 'iso', dateonly => 1 }) : undef;
245 my $iso_dateto = $dateto ? output_pref({ dt => dt_from_string( $dateto ), dateformat => 'iso', dateonly => 1 }) : undef;
247 $user ||= q{};
249 my $dbh = C4::Context->dbh;
250 my $query = "
251 SELECT *
252 FROM action_logs
253 WHERE 1
256 my @parameters;
257 $query .=
258 " AND DATE_FORMAT(timestamp, '%Y-%m-%d') >= \"" . $iso_datefrom . "\" "
259 if $iso_datefrom; #fix me - mysql specific
260 $query .=
261 " AND DATE_FORMAT(timestamp, '%Y-%m-%d') <= \"" . $iso_dateto . "\" "
262 if $iso_dateto;
263 if ( $user ne q{} ) {
264 $query .= " AND user = ? ";
265 push( @parameters, $user );
267 if ( $modules && scalar(@$modules) ) {
268 $query .=
269 " AND module IN (" . join( ",", map { "?" } @$modules ) . ") ";
270 push( @parameters, @$modules );
272 if ( $action && scalar(@$action) ) {
273 $query .= " AND action IN (" . join( ",", map { "?" } @$action ) . ") ";
274 push( @parameters, @$action );
276 if ($object) {
277 $query .= " AND object = ? ";
278 push( @parameters, $object );
280 if ($info) {
281 $query .= " AND info LIKE ? ";
282 push( @parameters, "%" . $info . "%" );
285 my $sth = $dbh->prepare($query);
286 $sth->execute(@parameters);
288 my @logs;
289 while ( my $row = $sth->fetchrow_hashref ) {
290 push @logs, $row;
292 return \@logs;
296 __END__
298 =back
300 =head1 AUTHOR
302 Koha Development Team <http://koha-community.org/>
304 =cut