Bug 13642 - Adding new features for Dublin Core metadata
[koha.git] / C4 / Log.pm
blobc18794e8cc111f07a8556bb9da18d9ccc04901b7
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 C4::Context;
28 use Koha::DateUtils;
30 use vars qw($VERSION @ISA @EXPORT);
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);
40 =head1 NAME
42 C4::Log - Koha Log Facility functions
44 =head1 SYNOPSIS
46 use C4::Log;
48 =head1 DESCRIPTION
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.
52 =head1 FUNCTIONS
54 =over 2
56 =item logaction
58 &logaction($modulename, $actionname, $objectnumber, $infos);
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.
65 =cut
68 sub logaction {
69 my ($modulename, $actionname, $objectnumber, $infos)=@_;
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;
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;
84 =item cronlogaction
86 &cronlogaction($infos);
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.
91 =cut
94 sub cronlogaction {
95 my ($infos)=@_;
96 my $loginfo = (caller(0))[1];
97 $loginfo .= ' ' . $infos if $infos;
98 logaction( 'CRONJOBS', 'Run', undef, $loginfo ) if C4::Context->preference('CronjobLog');
102 =item GetLogStatus
104 $status = GetLogStatus;
106 C<$status> is a hasref like this example:
107 $hash = {
108 BorrowersLog => 1,
109 CataloguingLog => 0,
110 IssueLog => 0,
114 =cut
117 sub GetLogStatus {
118 my %hash;
119 $hash{BorrowersLog} = C4::Context->preference("BorrowersLog");
120 $hash{CataloguingLog} = C4::Context->preference("CataloguingLog");
121 $hash{IssueLog} = C4::Context->preference("IssueLog");
122 $hash{ReturnLog} = C4::Context->preference("ReturnLog");
123 $hash{SubscriptionLog} = C4::Context->preference("SubscriptionLog");
124 $hash{LetterLog} = C4::Context->preference("LetterLog");
125 $hash{FinesLog} = C4::Context->preference("FinesLog");
126 return \%hash;
129 =item displaylog
131 &displaylog($modulename, @filters);
132 $modulename is the name of the module on which the user wants to display logs
133 @filters is an optional table of hash containing :
134 - name : the name of the variable to filter
135 - value : the value of the filter.... May be with * joker
137 returns a table of hash containing who did what on which object at what time
139 =cut
142 sub displaylog {
143 my ($modulename, @filters) = @_;
144 my $dbh = C4::Context->dbh;
145 my $strsth=qq|
146 SELECT action_logs.timestamp, action_logs.action, action_logs.info,
147 borrowers.cardnumber, borrowers.surname, borrowers.firstname, borrowers.userid,
148 biblio.biblionumber, biblio.title, biblio.author
149 FROM action_logs
150 LEFT JOIN borrowers ON borrowers.borrowernumber=action_logs.user
151 LEFT JOIN biblio ON action_logs.object=biblio.biblionumber
152 WHERE action_logs.module = 'cataloguing'
154 my %filtermap = ();
155 if ($modulename eq "catalogue" or $modulename eq "acqui") {
156 %filtermap = (
157 user => 'borrowers.surname',
158 title => 'biblio.title',
159 author => 'biblio.author',
161 } elsif ($modulename eq "members") {
162 $strsth=qq|
163 SELECT action_logs.timestamp, action_logs.action, action_logs.info,
164 borrowers.cardnumber, borrowers.surname, borrowers.firstname, borrowers.userid,
165 bor2.cardnumber, bor2.surname, bor2.firstname, bor2.userid
166 FROM action_logs
167 LEFT JOIN borrowers ON borrowers.borrowernumber=action_logs.user
168 LEFT JOIN borrowers as bor2 ON action_logs.object=bor2.borrowernumber
169 WHERE action_logs.module = 'members'
171 %filtermap = (
172 user => 'borrowers.surname',
173 surname => 'bor2.surname',
174 firstname => 'bor2.firstname',
175 cardnumber => 'bor2.cardnumber',
177 } else {
178 return 0;
181 if (@filters) {
182 foreach my $filter (@filters) {
183 my $tempname = $filter->{name} or next;
184 (grep {/^$tempname$/} keys %filtermap) or next;
185 $filter->{value} =~ s/\*/%/g;
186 $strsth .= " AND " . $filtermap{$tempname} . " LIKE " . $filter->{value};
189 my $sth=$dbh->prepare($strsth);
190 $sth->execute;
191 my @results;
192 my $count;
193 my $hilighted=1;
194 while (my $data = $sth->fetchrow_hashref){
195 $data->{hilighted} = ($hilighted>0);
196 $data->{info} =~ s/\n/<br\/>/g;
197 $data->{day} = output_pref({ str => $data->{timestamp} });
198 push @results, $data;
199 $count++;
200 $hilighted = -$hilighted;
202 return ($count, \@results);
205 =item GetLogs
207 $logs = GetLogs($datefrom,$dateto,$user,\@modules,$action,$object,$info);
209 Return:
210 C<$logs> is a ref to a hash which containts all columns from action_logs
212 =cut
214 sub GetLogs {
215 my $datefrom = shift;
216 my $dateto = shift;
217 my $user = shift;
218 my $modules = shift;
219 my $action = shift;
220 my $object = shift;
221 my $info = shift;
223 my $iso_datefrom = output_pref({ dt => dt_from_string( $datefrom ), dateformat => 'iso', dateonly => 1 });
224 my $iso_dateto = output_pref({ dt => dt_from_string( $dateto ), dateformat => 'iso', dateonly => 1 });
226 my $dbh = C4::Context->dbh;
227 my $query = "
228 SELECT *
229 FROM action_logs
230 WHERE 1
233 my @parameters;
234 $query .= " AND DATE_FORMAT(timestamp, '%Y-%m-%d') >= \"".$iso_datefrom."\" " if $iso_datefrom; #fix me - mysql specific
235 $query .= " AND DATE_FORMAT(timestamp, '%Y-%m-%d') <= \"".$iso_dateto."\" " if $iso_dateto;
236 if($user ne "") {
237 $query .= " AND user = ? ";
238 push(@parameters,$user);
240 if($modules && scalar(@$modules)) {
241 $query .= " AND module IN (".join(",",map {"?"} @$modules).") ";
242 push(@parameters,@$modules);
244 if($action && scalar(@$action)) {
245 $query .= " AND action IN (".join(",",map {"?"} @$action).") ";
246 push(@parameters,@$action);
248 if($object) {
249 $query .= " AND object = ? ";
250 push(@parameters,$object);
252 if($info) {
253 $query .= " AND info LIKE ? ";
254 push(@parameters,"%".$info."%");
257 my $sth = $dbh->prepare($query);
258 $sth->execute(@parameters);
260 my @logs;
261 while( my $row = $sth->fetchrow_hashref ) {
262 push @logs , $row;
264 return \@logs;
268 __END__
270 =back
272 =head1 AUTHOR
274 Koha Development Team <http://koha-community.org/>
276 =cut