Bug 16573: change created_on type - atomic update
[koha.git] / C4 / Log.pm
blobde5f1d0a150dcab960ee23840f19415dde6e060f
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(@ISA @EXPORT);
32 BEGIN {
33 require Exporter;
34 @ISA = qw(Exporter);
35 @EXPORT = qw(&logaction &cronlogaction &GetLogStatus &displaylog &GetLogs);
38 =head1 NAME
40 C4::Log - Koha Log Facility functions
42 =head1 SYNOPSIS
44 use C4::Log;
46 =head1 DESCRIPTION
48 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.
50 =head1 FUNCTIONS
52 =over 2
54 =item logaction
56 &logaction($modulename, $actionname, $objectnumber, $infos);
58 Adds a record into action_logs table to report the different changes upon the database.
59 Each log entry includes the number of the user currently logged in. For batch
60 jobs, which operate without authenticating a user and setting up a session, the user
61 number is set to 0, which is the same as the superlibrarian's number.
63 =cut
66 sub logaction {
67 my ($modulename, $actionname, $objectnumber, $infos)=@_;
69 # Get ID of logged in user. if called from a batch job,
70 # no user session exists and C4::Context->userenv() returns
71 # the scalar '0'.
72 my $userenv = C4::Context->userenv();
73 my $usernumber = (ref($userenv) eq 'HASH') ? $userenv->{'number'} : 0;
74 $usernumber ||= 0;
76 my $dbh = C4::Context->dbh;
77 my $sth=$dbh->prepare("Insert into action_logs (timestamp,user,module,action,object,info) values (now(),?,?,?,?,?)");
78 $sth->execute($usernumber,$modulename,$actionname,$objectnumber,$infos);
79 $sth->finish;
82 =item cronlogaction
84 &cronlogaction($infos);
86 Convenience routine to add a record into action_logs table from a cron job.
87 Logs the path and name of the calling script plus the information privided by param $infos.
89 =cut
92 sub cronlogaction {
93 my ($infos)=@_;
94 my $loginfo = (caller(0))[1];
95 $loginfo .= ' ' . $infos if $infos;
96 logaction( 'CRONJOBS', 'Run', undef, $loginfo ) if C4::Context->preference('CronjobLog');
100 =item GetLogStatus
102 $status = GetLogStatus;
104 C<$status> is a hasref like this example:
105 $hash = {
106 BorrowersLog => 1,
107 CataloguingLog => 0,
108 IssueLog => 0,
112 =cut
115 sub GetLogStatus {
116 my %hash;
117 $hash{BorrowersLog} = C4::Context->preference("BorrowersLog");
118 $hash{CataloguingLog} = C4::Context->preference("CataloguingLog");
119 $hash{IssueLog} = C4::Context->preference("IssueLog");
120 $hash{ReturnLog} = C4::Context->preference("ReturnLog");
121 $hash{SubscriptionLog} = C4::Context->preference("SubscriptionLog");
122 $hash{LetterLog} = C4::Context->preference("LetterLog");
123 $hash{FinesLog} = C4::Context->preference("FinesLog");
124 return \%hash;
127 =item displaylog
129 &displaylog($modulename, @filters);
130 $modulename is the name of the module on which the user wants to display logs
131 @filters is an optional table of hash containing :
132 - name : the name of the variable to filter
133 - value : the value of the filter.... May be with * joker
135 returns a table of hash containing who did what on which object at what time
137 =cut
140 sub displaylog {
141 my ($modulename, @filters) = @_;
142 my $dbh = C4::Context->dbh;
143 my $strsth=qq|
144 SELECT action_logs.timestamp, action_logs.action, action_logs.info,
145 borrowers.cardnumber, borrowers.surname, borrowers.firstname, borrowers.userid,
146 biblio.biblionumber, biblio.title, biblio.author
147 FROM action_logs
148 LEFT JOIN borrowers ON borrowers.borrowernumber=action_logs.user
149 LEFT JOIN biblio ON action_logs.object=biblio.biblionumber
150 WHERE action_logs.module = 'cataloguing'
152 my %filtermap = ();
153 if ($modulename eq "catalogue" or $modulename eq "acqui") {
154 %filtermap = (
155 user => 'borrowers.surname',
156 title => 'biblio.title',
157 author => 'biblio.author',
159 } elsif ($modulename eq "members") {
160 $strsth=qq|
161 SELECT action_logs.timestamp, action_logs.action, action_logs.info,
162 borrowers.cardnumber, borrowers.surname, borrowers.firstname, borrowers.userid,
163 bor2.cardnumber, bor2.surname, bor2.firstname, bor2.userid
164 FROM action_logs
165 LEFT JOIN borrowers ON borrowers.borrowernumber=action_logs.user
166 LEFT JOIN borrowers as bor2 ON action_logs.object=bor2.borrowernumber
167 WHERE action_logs.module = 'members'
169 %filtermap = (
170 user => 'borrowers.surname',
171 surname => 'bor2.surname',
172 firstname => 'bor2.firstname',
173 cardnumber => 'bor2.cardnumber',
175 } else {
176 return 0;
179 if (@filters) {
180 foreach my $filter (@filters) {
181 my $tempname = $filter->{name} or next;
182 (grep {/^$tempname$/} keys %filtermap) or next;
183 $filter->{value} =~ s/\*/%/g;
184 $strsth .= " AND " . $filtermap{$tempname} . " LIKE " . $filter->{value};
187 my $sth=$dbh->prepare($strsth);
188 $sth->execute;
189 my @results;
190 my $count;
191 my $hilighted=1;
192 while (my $data = $sth->fetchrow_hashref){
193 $data->{hilighted} = ($hilighted>0);
194 $data->{info} =~ s/\n/<br\/>/g;
195 $data->{day} = output_pref({ str => $data->{timestamp} });
196 push @results, $data;
197 $count++;
198 $hilighted = -$hilighted;
200 return ($count, \@results);
203 =item GetLogs
205 $logs = GetLogs($datefrom,$dateto,$user,\@modules,$action,$object,$info);
207 Return:
208 C<$logs> is a ref to a hash which containts all columns from action_logs
210 =cut
212 sub GetLogs {
213 my $datefrom = shift;
214 my $dateto = shift;
215 my $user = shift;
216 my $modules = shift;
217 my $action = shift;
218 my $object = shift;
219 my $info = shift;
221 my $iso_datefrom = $datefrom ? output_pref({ dt => dt_from_string( $datefrom ), dateformat => 'iso', dateonly => 1 }) : undef;
222 my $iso_dateto = $dateto ? output_pref({ dt => dt_from_string( $dateto ), dateformat => 'iso', dateonly => 1 }) : undef;
224 $user ||= q{};
226 my $dbh = C4::Context->dbh;
227 my $query = "
228 SELECT *
229 FROM action_logs
230 WHERE 1
233 my @parameters;
234 $query .=
235 " AND DATE_FORMAT(timestamp, '%Y-%m-%d') >= \"" . $iso_datefrom . "\" "
236 if $iso_datefrom; #fix me - mysql specific
237 $query .=
238 " AND DATE_FORMAT(timestamp, '%Y-%m-%d') <= \"" . $iso_dateto . "\" "
239 if $iso_dateto;
240 if ( $user ne q{} ) {
241 $query .= " AND user = ? ";
242 push( @parameters, $user );
244 if ( $modules && scalar(@$modules) ) {
245 $query .=
246 " AND module IN (" . join( ",", map { "?" } @$modules ) . ") ";
247 push( @parameters, @$modules );
249 if ( $action && scalar(@$action) ) {
250 $query .= " AND action IN (" . join( ",", map { "?" } @$action ) . ") ";
251 push( @parameters, @$action );
253 if ($object) {
254 $query .= " AND object = ? ";
255 push( @parameters, $object );
257 if ($info) {
258 $query .= " AND info LIKE ? ";
259 push( @parameters, "%" . $info . "%" );
262 my $sth = $dbh->prepare($query);
263 $sth->execute(@parameters);
265 my @logs;
266 while ( my $row = $sth->fetchrow_hashref ) {
267 push @logs, $row;
269 return \@logs;
273 __END__
275 =back
277 =head1 AUTHOR
279 Koha Development Team <http://koha-community.org/>
281 =cut