Bug 13889: Provide parameter $infos in cronlogaction()
[koha.git] / C4 / Log.pm
1 package C4::Log;
2
3 #package to deal with Logging Actions in DB
4
5
6 # Copyright 2000-2002 Katipo Communications
7 # Copyright 2011 MJ Ray and software.coop
8 #
9 # This file is part of Koha.
10 #
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.
15 #
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.
20 #
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>.
23
24 use strict;
25 use warnings;
26
27 use C4::Context;
28 use C4::Dates qw(format_date);
29
30 use vars qw($VERSION @ISA @EXPORT);
31
32 BEGIN {
33     # set the version for version checking
34     $VERSION = 3.07.00.049;
35         require Exporter;
36         @ISA = qw(Exporter);
37         @EXPORT = qw(&logaction &cronlogaction &GetLogStatus &displaylog &GetLogs);
38 }
39
40 =head1 NAME
41
42 C4::Log - Koha Log Facility functions
43
44 =head1 SYNOPSIS
45
46   use C4::Log;
47
48 =head1 DESCRIPTION
49
50 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.
51
52 =head1 FUNCTIONS
53
54 =over 2
55
56 =item logaction
57
58   &logaction($modulename, $actionname, $objectnumber, $infos);
59
60 Adds a record into action_logs table to report the different changes upon the database.
61 Each log entry includes the number of the user currently logged in.  For batch
62 jobs, which operate without authenticating a user and setting up a session, the user
63 number is set to 0, which is the same as the superlibrarian's number.
64
65 =cut
66
67 #'
68 sub logaction {
69     my ($modulename, $actionname, $objectnumber, $infos)=@_;
70
71     # Get ID of logged in user.  if called from a batch job,
72     # no user session exists and C4::Context->userenv() returns
73     # the scalar '0'.
74     my $userenv = C4::Context->userenv();
75     my $usernumber = (ref($userenv) eq 'HASH') ? $userenv->{'number'} : 0;
76     $usernumber ||= 0;
77
78     my $dbh = C4::Context->dbh;
79     my $sth=$dbh->prepare("Insert into action_logs (timestamp,user,module,action,object,info) values (now(),?,?,?,?,?)");
80     $sth->execute($usernumber,$modulename,$actionname,$objectnumber,$infos);
81     $sth->finish;
82 }
83
84 =item cronlogaction
85
86   &cronlogaction($infos);
87
88 Convenience routine to add a record into action_logs table from a cron job.
89 Logs the path and name of the calling script plus the information privided by param $infos.
90
91 =cut
92
93 #'
94 sub cronlogaction {
95     my ($infos)=@_;
96     my $loginfo = (caller(0))[1] . ' ' . $infos;
97     logaction( 'CRONJOBS', 'Run', 0, $loginfo ) if C4::Context->preference('CronjobLog');
98 }
99
100
101 =item GetLogStatus
102
103   $status = GetLogStatus;
104
105 C<$status> is a hasref like this example:
106     $hash = {
107         BorrowersLog   => 1,
108         CataloguingLog => 0,
109         IssueLog       => 0,
110         ...
111     }
112
113 =cut
114
115 #'
116 sub GetLogStatus {
117     my %hash;
118     $hash{BorrowersLog}    = C4::Context->preference("BorrowersLog");
119     $hash{CataloguingLog}  = C4::Context->preference("CataloguingLog");
120     $hash{IssueLog}        = C4::Context->preference("IssueLog");
121     $hash{ReturnLog}       = C4::Context->preference("ReturnLog");
122     $hash{SubscriptionLog} = C4::Context->preference("SubscriptionLog");
123     $hash{LetterLog}       = C4::Context->preference("LetterLog");
124     $hash{FinesLog}        = C4::Context->preference("FinesLog");
125     return \%hash;
126 }
127
128 =item displaylog
129
130   &displaylog($modulename, @filters);
131   $modulename is the name of the module on which the user wants to display logs
132   @filters is an optional table of hash containing :
133       - name : the name of the variable to filter
134     - value : the value of the filter.... May be with * joker
135
136 returns a table of hash containing who did what on which object at what time
137
138 =cut
139
140 #'
141 sub displaylog {
142   my ($modulename, @filters) = @_;
143     my $dbh = C4::Context->dbh;
144     my $strsth=qq|
145                 SELECT action_logs.timestamp, action_logs.action, action_logs.info,
146                                 borrowers.cardnumber, borrowers.surname, borrowers.firstname, borrowers.userid,
147                         biblio.biblionumber, biblio.title, biblio.author
148         FROM action_logs 
149                 LEFT JOIN borrowers ON borrowers.borrowernumber=action_logs.user 
150         LEFT JOIN  biblio   ON action_logs.object=biblio.biblionumber
151         WHERE action_logs.module = 'cataloguing' 
152         |;
153         my %filtermap = ();
154     if ($modulename eq "catalogue" or $modulename eq "acqui") {
155                 %filtermap = (
156                           user => 'borrowers.surname',
157                          title => 'biblio.title',
158                         author => 'biblio.author',
159                 );
160     } elsif ($modulename eq "members") {
161         $strsth=qq|
162                 SELECT action_logs.timestamp, action_logs.action, action_logs.info, 
163                         borrowers.cardnumber, borrowers.surname, borrowers.firstname, borrowers.userid,
164                         bor2.cardnumber, bor2.surname, bor2.firstname, bor2.userid
165         FROM action_logs 
166                 LEFT JOIN borrowers ON borrowers.borrowernumber=action_logs.user 
167                 LEFT JOIN borrowers as bor2 ON action_logs.object=bor2.borrowernumber
168         WHERE action_logs.module = 'members' 
169                 |;
170                 %filtermap = (
171                        user => 'borrowers.surname',
172                     surname => 'bor2.surname',
173                   firstname => 'bor2.firstname',
174                  cardnumber => 'bor2.cardnumber',
175                 );
176     } else {
177                 return 0;
178         }
179
180     if (@filters) {
181                 foreach my $filter (@filters) {
182                         my $tempname = $filter->{name}         or next;
183                         (grep {/^$tempname$/} keys %filtermap) or next;
184                         $filter->{value} =~ s/\*/%/g;
185                         $strsth .= " AND " . $filtermap{$tempname} . " LIKE " . $filter->{value};
186                 }
187         }
188     my $sth=$dbh->prepare($strsth);
189     $sth->execute;
190     my @results;
191     my $count;
192     my $hilighted=1;
193     while (my $data = $sth->fetchrow_hashref){
194         $data->{hilighted} = ($hilighted>0);
195         $data->{info} =~ s/\n/<br\/>/g;
196         $data->{day} = format_date($data->{timestamp});
197         push @results, $data;
198         $count++;
199         $hilighted = -$hilighted;
200     }
201     return ($count, \@results);
202 }
203
204 =item GetLogs
205
206 $logs = GetLogs($datefrom,$dateto,$user,\@modules,$action,$object,$info);
207
208 Return: 
209 C<$logs> is a ref to a hash which containts all columns from action_logs
210
211 =cut
212
213 sub GetLogs {
214     my $datefrom = shift;
215     my $dateto   = shift;
216     my $user     = shift;
217     my $modules   = shift;
218     my $action   = shift;
219     my $object   = shift;
220     my $info     = shift;
221    
222     my $iso_datefrom = C4::Dates->new($datefrom,C4::Context->preference("dateformat"))->output('iso');
223     my $iso_dateto = C4::Dates->new($dateto,C4::Context->preference("dateformat"))->output('iso');
224
225     my $dbh = C4::Context->dbh;
226     my $query = "
227         SELECT *
228         FROM   action_logs
229         WHERE 1
230     ";
231
232     my @parameters;
233     $query .= " AND DATE_FORMAT(timestamp, '%Y-%m-%d') >= \"".$iso_datefrom."\" " if $iso_datefrom;   #fix me - mysql specific
234     $query .= " AND DATE_FORMAT(timestamp, '%Y-%m-%d') <= \"".$iso_dateto."\" " if $iso_dateto;
235     if($user ne "") {
236         $query .= " AND user = ? ";
237         push(@parameters,$user);
238     }
239     if($modules && scalar(@$modules)) {
240         $query .= " AND module IN (".join(",",map {"?"} @$modules).") ";
241         push(@parameters,@$modules);
242     }
243     if($action && scalar(@$action)) {
244         $query .= " AND action IN (".join(",",map {"?"} @$action).") ";
245         push(@parameters,@$action);
246     }
247     if($object) {
248         $query .= " AND object = ? ";
249         push(@parameters,$object);
250     }
251     if($info) {
252         $query .= " AND info LIKE ? ";
253         push(@parameters,"%".$info."%");
254     }
255    
256     my $sth = $dbh->prepare($query);
257     $sth->execute(@parameters);
258     
259     my @logs;
260     while( my $row = $sth->fetchrow_hashref ) {
261         push @logs , $row;
262     }
263     return \@logs;
264 }
265
266 1;
267 __END__
268
269 =back
270
271 =head1 AUTHOR
272
273 Koha Development Team <http://koha-community.org/>
274
275 =cut