Assigning bug 1835 : change password would never log password change.
[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 #
8 # This file is part of Koha.
9 #
10 # Koha is free software; you can redistribute it and/or modify it under the
11 # terms of the GNU General Public License as published by the Free Software
12 # Foundation; either version 2 of the License, or (at your option) any later
13 # version.
14 #
15 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
16 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
17 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License along with
20 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
21 # Suite 330, Boston, MA  02111-1307 USA
22
23 use strict;
24 use C4::Context;
25 use C4::Dates qw(format_date);
26
27 use vars qw($VERSION @ISA @EXPORT);
28
29 BEGIN {
30         # set the version for version checking
31         $VERSION = 3.01;
32         require Exporter;
33         @ISA = qw(Exporter);
34         @EXPORT = qw(&logaction &GetLogStatus &displaylog &GetLogs);
35 }
36
37 =head1 NAME
38
39 C4::Log - Koha Log Facility functions
40
41 =head1 SYNOPSIS
42
43   use C4::Log;
44
45 =head1 DESCRIPTION
46
47 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.
48
49 =head1 FUNCTIONS
50
51 =over 2
52
53 =item logaction
54
55   &logaction($modulename, $actionname, $objectnumber, $infos);
56
57 Adds a record into action_logs table to report the different changes upon the database.
58 Each log entry includes the number of the user currently logged in.  For batch
59 jobs, which operate without authenticating a user and setting up a session, the user
60 number is set to 0, which is the same as the superlibrarian's number.
61
62 =cut
63
64 #'
65 sub logaction {
66     my ($modulename, $actionname, $objectnumber, $infos)=@_;
67
68     # Get ID of logged in user.  if called from a batch job,
69     # no user session exists and C4::Context->userenv() returns
70     # the scalar '0'.
71     my $userenv = C4::Context->userenv();
72     my $usernumber = (ref($userenv) eq 'HASH') ? $userenv->{'number'} : 0;
73
74     my $dbh = C4::Context->dbh;
75     my $sth=$dbh->prepare("Insert into action_logs (timestamp,user,module,action,object,info) values (now(),?,?,?,?,?)");
76     $sth->execute($usernumber,$modulename,$actionname,$objectnumber,$infos);
77     $sth->finish;
78 }
79
80 =item GetLogStatus
81
82   $status = GetLogStatus;
83
84 C<$status> is a hasref like this example:
85     $hash = {
86         BorrowersLog   => 1,
87         CataloguingLog => 0,
88         IssueLog       => 0,
89         ...
90     }
91
92 =cut
93
94 #'
95 sub GetLogStatus {
96     my %hash;
97     $hash{BorrowersLog}    = C4::Context->preference("BorrowersLog");
98     $hash{CataloguingLog}  = C4::Context->preference("CataloguingLog");
99     $hash{IssueLog}        = C4::Context->preference("IssueLog");
100     $hash{ReturnLog}       = C4::Context->preference("ReturnLog");
101     $hash{SubscriptionLog} = C4::Context->preference("SubscriptionLog");
102     $hash{LetterLog}       = C4::Context->preference("LetterLog");
103     $hash{FinesLog}        = C4::Context->preference("FinesLog");
104     return \%hash;
105 }
106
107 =item displaylog
108
109   &displaylog($modulename, @filters);
110   $modulename is the name of the module on which the user wants to display logs
111   @filters is an optional table of hash containing :
112       - name : the name of the variable to filter
113     - value : the value of the filter.... May be with * joker
114
115 returns a table of hash containing who did what on which object at what time
116
117 =cut
118
119 #'
120 sub displaylog {
121   my ($modulename, @filters) = @_;
122     my $dbh = C4::Context->dbh;
123     my $strsth=qq|
124                 SELECT action_logs.timestamp, action_logs.action, action_logs.info,
125                                 borrowers.cardnumber, borrowers.surname, borrowers.firstname, borrowers.userid,
126                         biblio.biblionumber, biblio.title, biblio.author
127         FROM action_logs 
128                 LEFT JOIN borrowers ON borrowers.borrowernumber=action_logs.user 
129         LEFT JOIN  biblio   ON action_logs.object=biblio.biblionumber
130         WHERE action_logs.module = 'cataloguing' 
131         |;
132         my %filtermap = ();
133     if ($modulename eq "catalogue" or $modulename eq "acqui") {
134                 %filtermap = (
135                           user => 'borrowers.surname',
136                          title => 'biblio.title',
137                         author => 'biblio.author',
138                 );
139     } elsif ($modulename eq "members") {
140         $strsth=qq|
141                 SELECT action_logs.timestamp, action_logs.action, action_logs.info, 
142                         borrowers.cardnumber, borrowers.surname, borrowers.firstname, borrowers.userid,
143                         bor2.cardnumber, bor2.surname, bor2.firstname, bor2.userid
144         FROM action_logs 
145                 LEFT JOIN borrowers ON borrowers.borrowernumber=action_logs.user 
146                 LEFT JOIN borrowers as bor2 ON action_logs.object=bor2.borrowernumber
147         WHERE action_logs.module = 'members' 
148                 |;
149                 %filtermap = (
150                        user => 'borrowers.surname',
151                     surname => 'bor2.surname',
152                   firstname => 'bor2.firstname',
153                  cardnumber => 'bor2.cardnumber',
154                 );
155     } else {
156                 return 0;
157         }
158
159     if (@filters) {
160                 foreach my $filter (@filters) {
161                         my $tempname = $filter->{name}         or next;
162                         (grep {/^$tempname$/} keys %filtermap) or next;
163                         $filter->{value} =~ s/\*/%/g;
164                         $strsth .= " AND " . $filtermap{$tempname} . " LIKE " . $filter->{value};
165                 }
166         }
167     my $sth=$dbh->prepare($strsth);
168     $sth->execute;
169     my @results;
170     my $count;
171     my $hilighted=1;
172     while (my $data = $sth->fetchrow_hashref){
173         $data->{hilighted} = ($hilighted>0);
174         $data->{info} =~ s/\n/<br\/>/g;
175         $data->{day} = format_date($data->{timestamp});
176         push @results, $data;
177         $count++;
178         $hilighted = -$hilighted;
179     }
180     return ($count, \@results);
181 }
182
183 =head2 GetLogs
184
185 $logs = GetLogs($datefrom,$dateto,$user,$module,$action,$object,$info);
186
187 Return: 
188 C<$logs> is a ref to a hash which containts all columns from action_logs
189
190 =cut
191
192 sub GetLogs {
193     my $datefrom = shift;
194     my $dateto   = shift;
195     my $user     = shift;
196     my $module   = shift;
197     my $action   = shift;
198     my $object   = shift;
199     my $info     = shift;
200    
201     my $iso_datefrom = C4::Dates->new($datefrom,C4::Context->preference("dateformat"))->output('iso');
202     my $iso_dateto = C4::Dates->new($dateto,C4::Context->preference("dateformat"))->output('iso');
203
204     my $dbh = C4::Context->dbh;
205     my $query = "
206         SELECT *
207         FROM   action_logs
208         WHERE 1
209     ";
210     $query .= " AND DATE_FORMAT(timestamp, '%Y-%m-%d') >= \"".$iso_datefrom."\" " if $iso_datefrom;
211     $query .= " AND DATE_FORMAT(timestamp, '%Y-%m-%d') <= \"".$iso_dateto."\" " if $iso_dateto;
212     $query .= " AND user LIKE \"%".$user."%\" "     if $user;
213     $query .= " AND module LIKE \"%".$module."%\" " if $module;
214     $query .= " AND action LIKE \"%".$action."%\" " if $action;
215     $query .= " AND object LIKE \"%".$object."%\" " if $object;
216     $query .= " AND info LIKE \"%".$info."%\" "     if $info;
217    
218     my $sth = $dbh->prepare($query);
219     $sth->execute;
220     
221     my @logs;
222     while( my $row = $sth->fetchrow_hashref ) {
223         $row->{$row->{module}} = 1;
224         push @logs , $row;
225     }
226     return \@logs;
227 }
228
229 1;
230 __END__
231
232 =back
233
234 =head1 AUTHOR
235
236 Koha Developement team <info@koha.org>
237
238 =cut