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>.
27 use JSON qw( to_json );
33 use vars qw(@ISA @EXPORT);
38 @EXPORT = qw(&logaction &cronlogaction &GetLogStatus &displaylog &GetLogs);
43 C4::Log - Koha Log Facility functions
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.
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.
70 my ($modulename, $actionname, $objectnumber, $infos, $interface)=@_;
72 # Get ID of logged in user. if called from a batch job,
73 # no user session exists and C4::Context->userenv() returns
75 my $userenv = C4::Context->userenv();
76 my $usernumber = (ref($userenv) eq 'HASH') ? $userenv->{'number'} : 0;
78 $interface //= C4::Context->interface;
80 my $dbh = C4::Context->dbh;
81 my $sth=$dbh->prepare("Insert into action_logs (timestamp,user,module,action,object,info,interface) values (now(),?,?,?,?,?,?)");
82 $sth->execute($usernumber,$modulename,$actionname,$objectnumber,$infos,$interface);
85 my $logger = Koha::Logger->get(
87 interface => 'intranet',
88 category => "ActionLogs.$modulename.$actionname"
93 "ACTION LOG: " . to_json(
96 module => $modulename,
97 action => $actionname,
98 object => $objectnumber,
108 &cronlogaction($infos);
110 Convenience routine to add a record into action_logs table from a cron job.
111 Logs the path and name of the calling script plus the information privided by param $infos.
118 my $loginfo = (caller(0))[1];
119 $loginfo .= ' ' . $infos if $infos;
120 logaction( 'CRONJOBS', 'Run', undef, $loginfo ) if C4::Context->preference('CronjobLog');
126 $status = GetLogStatus;
128 C<$status> is a hasref like this example:
141 $hash{BorrowersLog} = C4::Context->preference("BorrowersLog");
142 $hash{CataloguingLog} = C4::Context->preference("CataloguingLog");
143 $hash{IssueLog} = C4::Context->preference("IssueLog");
144 $hash{ReturnLog} = C4::Context->preference("ReturnLog");
145 $hash{SubscriptionLog} = C4::Context->preference("SubscriptionLog");
146 $hash{LetterLog} = C4::Context->preference("LetterLog");
147 $hash{FinesLog} = C4::Context->preference("FinesLog");
153 &displaylog($modulename, @filters);
154 $modulename is the name of the module on which the user wants to display logs
155 @filters is an optional table of hash containing :
156 - name : the name of the variable to filter
157 - value : the value of the filter.... May be with * joker
159 returns a table of hash containing who did what on which object at what time
165 my ($modulename, @filters) = @_;
166 my $dbh = C4::Context->dbh;
168 SELECT action_logs.timestamp, action_logs.action, action_logs.info,
169 borrowers.cardnumber, borrowers.surname, borrowers.firstname, borrowers.userid,
170 biblio.biblionumber, biblio.title, biblio.author
172 LEFT JOIN borrowers ON borrowers.borrowernumber=action_logs.user
173 LEFT JOIN biblio ON action_logs.object=biblio.biblionumber
174 WHERE action_logs.module = 'cataloguing'
177 if ($modulename eq "catalogue" or $modulename eq "acqui") {
179 user => 'borrowers.surname',
180 title => 'biblio.title',
181 author => 'biblio.author',
183 } elsif ($modulename eq "members") {
185 SELECT action_logs.timestamp, action_logs.action, action_logs.info,
186 borrowers.cardnumber, borrowers.surname, borrowers.firstname, borrowers.userid,
187 bor2.cardnumber, bor2.surname, bor2.firstname, bor2.userid
189 LEFT JOIN borrowers ON borrowers.borrowernumber=action_logs.user
190 LEFT JOIN borrowers as bor2 ON action_logs.object=bor2.borrowernumber
191 WHERE action_logs.module = 'members'
194 user => 'borrowers.surname',
195 surname => 'bor2.surname',
196 firstname => 'bor2.firstname',
197 cardnumber => 'bor2.cardnumber',
204 foreach my $filter (@filters) {
205 my $tempname = $filter->{name} or next;
206 (grep {/^$tempname$/} keys %filtermap) or next;
207 $filter->{value} =~ s/\*/%/g;
208 $strsth .= " AND " . $filtermap{$tempname} . " LIKE " . $filter->{value};
211 my $sth=$dbh->prepare($strsth);
216 while (my $data = $sth->fetchrow_hashref){
217 $data->{hilighted} = ($hilighted>0);
218 $data->{info} =~ s/\n/<br\/>/g;
219 $data->{day} = output_pref({ str => $data->{timestamp} });
220 push @results, $data;
222 $hilighted = -$hilighted;
224 return ($count, \@results);
229 $logs = GetLogs($datefrom,$dateto,$user,\@modules,$action,$object,$info);
232 C<$logs> is a ref to a hash which containts all columns from action_logs
237 my $datefrom = shift;
244 my $interfaces = shift;
246 my $iso_datefrom = $datefrom ? output_pref({ dt => dt_from_string( $datefrom ), dateformat => 'iso', dateonly => 1 }) : undef;
247 my $iso_dateto = $dateto ? output_pref({ dt => dt_from_string( $dateto ), dateformat => 'iso', dateonly => 1 }) : undef;
251 my $dbh = C4::Context->dbh;
260 " AND DATE_FORMAT(timestamp, '%Y-%m-%d') >= \"" . $iso_datefrom . "\" "
261 if $iso_datefrom; #fix me - mysql specific
263 " AND DATE_FORMAT(timestamp, '%Y-%m-%d') <= \"" . $iso_dateto . "\" "
265 if ( $user ne q{} ) {
266 $query .= " AND user = ? ";
267 push( @parameters, $user );
269 if ( $modules && scalar(@$modules) ) {
271 " AND module IN (" . join( ",", map { "?" } @$modules ) . ") ";
272 push( @parameters, @$modules );
274 if ( $action && scalar(@$action) ) {
275 $query .= " AND action IN (" . join( ",", map { "?" } @$action ) . ") ";
276 push( @parameters, @$action );
279 $query .= " AND object = ? ";
280 push( @parameters, $object );
283 $query .= " AND info LIKE ? ";
284 push( @parameters, "%" . $info . "%" );
286 if ( $interfaces && scalar(@$interfaces) ) {
288 " AND interface IN (" . join( ",", map { "?" } @$interfaces ) . ") ";
289 push( @parameters, @$interfaces );
292 my $sth = $dbh->prepare($query);
293 $sth->execute(@parameters);
296 while ( my $row = $sth->fetchrow_hashref ) {
309 Koha Development Team <http://koha-community.org/>