| File: | C4/Log.pm |
| Coverage: | 17.2% |
| line | stmt | bran | cond | sub | time | code |
|---|---|---|---|---|---|---|
| 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 under the | |||||
| 12 | # terms of the GNU General Public License as published by the Free Software | |||||
| 13 | # Foundation; either version 2 of the License, or (at your option) any later | |||||
| 14 | # version. | |||||
| 15 | # | |||||
| 16 | # Koha is distributed in the hope that it will be useful, but WITHOUT ANY | |||||
| 17 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||||
| 18 | # A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||||
| 19 | # | |||||
| 20 | # You should have received a copy of the GNU General Public License along | |||||
| 21 | # with Koha; if not, write to the Free Software Foundation, Inc., | |||||
| 22 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |||||
| 23 | ||||||
| 24 | 22 22 22 | 21318 169 766 | use strict; | |||
| 25 | 22 22 22 | 374 150 1092 | use warnings; | |||
| 26 | ||||||
| 27 | 22 22 22 | 458 118 384 | use C4::Context; | |||
| 28 | 22 22 22 | 662 124 1719 | use C4::Dates qw(format_date); | |||
| 29 | ||||||
| 30 | 22 22 22 | 212 142 3128 | use vars qw($VERSION @ISA @EXPORT); | |||
| 31 | ||||||
| 32 | BEGIN { | |||||
| 33 | # set the version for version checking | |||||
| 34 | 22 | 157 | $VERSION = 3.01; | |||
| 35 | 22 | 252 | require Exporter; | |||
| 36 | 22 | 486 | @ISA = qw(Exporter); | |||
| 37 | 22 | 26079 | @EXPORT = qw(&logaction &GetLogStatus &displaylog &GetLogs); | |||
| 38 | } | |||||
| 39 | ||||||
| 40 - 65 | =head1 NAME C4::Log - Koha Log Facility functions =head1 SYNOPSIS use C4::Log; =head1 DESCRIPTION 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. =head1 FUNCTIONS =over 2 =item logaction &logaction($modulename, $actionname, $objectnumber, $infos); Adds a record into action_logs table to report the different changes upon the database. Each log entry includes the number of the user currently logged in. For batch jobs, which operate without authenticating a user and setting up a session, the user number is set to 0, which is the same as the superlibrarian's number. =cut | |||||
| 66 | ||||||
| 67 | #' | |||||
| 68 | sub logaction { | |||||
| 69 | 0 | 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 | 0 | my $userenv = C4::Context->userenv(); | ||||
| 75 | 0 | my $usernumber = (ref($userenv) eq 'HASH') ? $userenv->{'number'} : 0; | ||||
| 76 | ||||||
| 77 | 0 | my $dbh = C4::Context->dbh; | ||||
| 78 | 0 | my $sth=$dbh->prepare("Insert into action_logs (timestamp,user,module,action,object,info) values (now(),?,?,?,?,?)"); | ||||
| 79 | 0 | $sth->execute($usernumber,$modulename,$actionname,$objectnumber,$infos); | ||||
| 80 | 0 | $sth->finish; | ||||
| 81 | } | |||||
| 82 | ||||||
| 83 - 95 | =item GetLogStatus
$status = GetLogStatus;
C<$status> is a hasref like this example:
$hash = {
BorrowersLog => 1,
CataloguingLog => 0,
IssueLog => 0,
...
}
=cut | |||||
| 96 | ||||||
| 97 | #' | |||||
| 98 | sub GetLogStatus { | |||||
| 99 | 0 | my %hash; | ||||
| 100 | 0 | $hash{BorrowersLog} = C4::Context->preference("BorrowersLog"); | ||||
| 101 | 0 | $hash{CataloguingLog} = C4::Context->preference("CataloguingLog"); | ||||
| 102 | 0 | $hash{IssueLog} = C4::Context->preference("IssueLog"); | ||||
| 103 | 0 | $hash{ReturnLog} = C4::Context->preference("ReturnLog"); | ||||
| 104 | 0 | $hash{SubscriptionLog} = C4::Context->preference("SubscriptionLog"); | ||||
| 105 | 0 | $hash{LetterLog} = C4::Context->preference("LetterLog"); | ||||
| 106 | 0 | $hash{FinesLog} = C4::Context->preference("FinesLog"); | ||||
| 107 | 0 | return \%hash; | ||||
| 108 | } | |||||
| 109 | ||||||
| 110 - 120 | =item displaylog
&displaylog($modulename, @filters);
$modulename is the name of the module on which the user wants to display logs
@filters is an optional table of hash containing :
- name : the name of the variable to filter
- value : the value of the filter.... May be with * joker
returns a table of hash containing who did what on which object at what time
=cut | |||||
| 121 | ||||||
| 122 | #' | |||||
| 123 | sub displaylog { | |||||
| 124 | 0 | my ($modulename, @filters) = @_; | ||||
| 125 | 0 | my $dbh = C4::Context->dbh; | ||||
| 126 | 0 | my $strsth=qq| | ||||
| 127 | SELECT action_logs.timestamp, action_logs.action, action_logs.info, | |||||
| 128 | borrowers.cardnumber, borrowers.surname, borrowers.firstname, borrowers.userid, | |||||
| 129 | biblio.biblionumber, biblio.title, biblio.author | |||||
| 130 | FROM action_logs | |||||
| 131 | LEFT JOIN borrowers ON borrowers.borrowernumber=action_logs.user | |||||
| 132 | LEFT JOIN biblio ON action_logs.object=biblio.biblionumber | |||||
| 133 | WHERE action_logs.module = 'cataloguing' | |||||
| 134 | |; | |||||
| 135 | 0 | my %filtermap = (); | ||||
| 136 | 0 | if ($modulename eq "catalogue" or $modulename eq "acqui") { | ||||
| 137 | 0 | %filtermap = ( | ||||
| 138 | user => 'borrowers.surname', | |||||
| 139 | title => 'biblio.title', | |||||
| 140 | author => 'biblio.author', | |||||
| 141 | ); | |||||
| 142 | } elsif ($modulename eq "members") { | |||||
| 143 | 0 | $strsth=qq| | ||||
| 144 | SELECT action_logs.timestamp, action_logs.action, action_logs.info, | |||||
| 145 | borrowers.cardnumber, borrowers.surname, borrowers.firstname, borrowers.userid, | |||||
| 146 | bor2.cardnumber, bor2.surname, bor2.firstname, bor2.userid | |||||
| 147 | FROM action_logs | |||||
| 148 | LEFT JOIN borrowers ON borrowers.borrowernumber=action_logs.user | |||||
| 149 | LEFT JOIN borrowers as bor2 ON action_logs.object=bor2.borrowernumber | |||||
| 150 | WHERE action_logs.module = 'members' | |||||
| 151 | |; | |||||
| 152 | 0 | %filtermap = ( | ||||
| 153 | user => 'borrowers.surname', | |||||
| 154 | surname => 'bor2.surname', | |||||
| 155 | firstname => 'bor2.firstname', | |||||
| 156 | cardnumber => 'bor2.cardnumber', | |||||
| 157 | ); | |||||
| 158 | } else { | |||||
| 159 | 0 | return 0; | ||||
| 160 | } | |||||
| 161 | ||||||
| 162 | 0 | if (@filters) { | ||||
| 163 | 0 | foreach my $filter (@filters) { | ||||
| 164 | 0 | my $tempname = $filter->{name} or next; | ||||
| 165 | 0 0 | (grep {/^$tempname$/} keys %filtermap) or next; | ||||
| 166 | 0 | $filter->{value} =~ s/\*/%/g; | ||||
| 167 | 0 | $strsth .= " AND " . $filtermap{$tempname} . " LIKE " . $filter->{value}; | ||||
| 168 | } | |||||
| 169 | } | |||||
| 170 | 0 | my $sth=$dbh->prepare($strsth); | ||||
| 171 | 0 | $sth->execute; | ||||
| 172 | 0 | my @results; | ||||
| 173 | 0 | my $count; | ||||
| 174 | 0 | my $hilighted=1; | ||||
| 175 | 0 | while (my $data = $sth->fetchrow_hashref){ | ||||
| 176 | 0 | $data->{hilighted} = ($hilighted>0); | ||||
| 177 | 0 | $data->{info} =~ s/\n/<br\/>/g; | ||||
| 178 | 0 | $data->{day} = format_date($data->{timestamp}); | ||||
| 179 | 0 | push @results, $data; | ||||
| 180 | 0 | $count++; | ||||
| 181 | 0 | $hilighted = -$hilighted; | ||||
| 182 | } | |||||
| 183 | 0 | return ($count, \@results); | ||||
| 184 | } | |||||
| 185 | ||||||
| 186 - 193 | =item GetLogs $logs = GetLogs($datefrom,$dateto,$user,\@modules,$action,$object,$info); Return: C<$logs> is a ref to a hash which containts all columns from action_logs =cut | |||||
| 194 | ||||||
| 195 | sub GetLogs { | |||||
| 196 | 0 | my $datefrom = shift; | ||||
| 197 | 0 | my $dateto = shift; | ||||
| 198 | 0 | my $user = shift; | ||||
| 199 | 0 | my $modules = shift; | ||||
| 200 | 0 | my $action = shift; | ||||
| 201 | 0 | my $object = shift; | ||||
| 202 | 0 | my $info = shift; | ||||
| 203 | ||||||
| 204 | 0 | my $iso_datefrom = C4::Dates->new($datefrom,C4::Context->preference("dateformat"))->output('iso'); | ||||
| 205 | 0 | my $iso_dateto = C4::Dates->new($dateto,C4::Context->preference("dateformat"))->output('iso'); | ||||
| 206 | ||||||
| 207 | 0 | my $dbh = C4::Context->dbh; | ||||
| 208 | 0 | my $query = " | ||||
| 209 | SELECT * | |||||
| 210 | FROM action_logs | |||||
| 211 | WHERE 1 | |||||
| 212 | "; | |||||
| 213 | ||||||
| 214 | 0 | my @parameters; | ||||
| 215 | 0 | $query .= " AND DATE_FORMAT(timestamp, '%Y-%m-%d') >= \"".$iso_datefrom."\" " if $iso_datefrom; #fix me - mysql specific | ||||
| 216 | 0 | $query .= " AND DATE_FORMAT(timestamp, '%Y-%m-%d') <= \"".$iso_dateto."\" " if $iso_dateto; | ||||
| 217 | 0 | if($user ne "") { | ||||
| 218 | 0 | $query .= " AND user = ? "; | ||||
| 219 | 0 | push(@parameters,$user); | ||||
| 220 | } | |||||
| 221 | 0 | if($modules && scalar(@$modules)) { | ||||
| 222 | 0 0 | $query .= " AND module IN (".join(",",map {"?"} @$modules).") "; | ||||
| 223 | 0 | push(@parameters,@$modules); | ||||
| 224 | } | |||||
| 225 | 0 | if($action && scalar(@$action)) { | ||||
| 226 | 0 0 | $query .= " AND action IN (".join(",",map {"?"} @$action).") "; | ||||
| 227 | 0 | push(@parameters,@$action); | ||||
| 228 | } | |||||
| 229 | 0 | if($object) { | ||||
| 230 | 0 | $query .= " AND object = ? "; | ||||
| 231 | 0 | push(@parameters,$object); | ||||
| 232 | } | |||||
| 233 | 0 | if($info) { | ||||
| 234 | 0 | $query .= " AND info LIKE ? "; | ||||
| 235 | 0 | push(@parameters,"%".$info."%"); | ||||
| 236 | } | |||||
| 237 | ||||||
| 238 | 0 | my $sth = $dbh->prepare($query); | ||||
| 239 | 0 | $sth->execute(@parameters); | ||||
| 240 | ||||||
| 241 | 0 | my @logs; | ||||
| 242 | 0 | while( my $row = $sth->fetchrow_hashref ) { | ||||
| 243 | 0 | $row->{$row->{module}} = 1; | ||||
| 244 | 0 | push @logs , $row; | ||||
| 245 | } | |||||
| 246 | 0 | return \@logs; | ||||
| 247 | } | |||||
| 248 | ||||||
| 249 | 1; | |||||