X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=C4%2FLog.pm;h=9f4430cbb64df4c3bbd6e4834179dd62e0dfe67e;hb=057fa1ac240e75e23e4f3cfc6486adb8272eb213;hp=7727528ad7f7c207eeb55df5336182947b4173b0;hpb=bec1be70907894576bad089c554e636390de7d7e;p=koha.git diff --git a/C4/Log.pm b/C4/Log.pm index 7727528ad7..9f4430cbb6 100644 --- a/C4/Log.pm +++ b/C4/Log.pm @@ -1,4 +1,4 @@ -package C4::Log; #assumes C4/Log +package C4::Log; #package to deal with Logging Actions in DB @@ -22,13 +22,17 @@ package C4::Log; #assumes C4/Log use strict; use C4::Context; - -require Exporter; +use C4::Dates qw(format_date); use vars qw($VERSION @ISA @EXPORT); -# set the version for version checking -$VERSION = 0.01; +BEGIN { + # set the version for version checking + $VERSION = 3.01; + require Exporter; + @ISA = qw(Exporter); + @EXPORT = qw(&logaction &GetLogStatus &displaylog &GetLogs); +} =head1 NAME @@ -46,46 +50,203 @@ The functions in this module perform various functions in order to log all the o =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 -@ISA = qw(Exporter); -@EXPORT = qw(&logaction &logstatus); +#' +sub logaction { + my ($modulename, $actionname, $objectnumber, $infos)=@_; -=item logaction + # Get ID of logged in user. if called from a batch job, + # no user session exists and C4::Context->userenv() returns + # the scalar '0'. + my $userenv = C4::Context->userenv(); + my $usernumber = (ref($userenv) eq 'HASH') ? $userenv->{'number'} : 0; + + my $dbh = C4::Context->dbh; + my $sth=$dbh->prepare("Insert into action_logs (timestamp,user,module,action,object,info) values (now(),?,?,?,?,?)"); + $sth->execute($usernumber,$modulename,$actionname,$objectnumber,$infos); + $sth->finish; +} + +=item GetLogStatus - &logaction($usernumber, $modulename, $actionname, $infos); + $status = GetLogStatus; -Adds a record into action_logs table to report the different changes upon the database +C<$status> is a hasref like this example: + $hash = { + BorrowersLog => 1, + CataloguingLog => 0, + IssueLog => 0, + ... + } =cut + #' -sub logaction{ - my ($usernumber,$modulename, $actionname, $infos)=@_; - my $dbh = C4::Context->dbh; - my $sth=$dbh->prepare("Insert into action_logs (timestamp,user,module,action,info) values (now(),?,?,?,?)"); - $sth->execute($usernumber,$modulename,$actionname,$infos); - $sth->finish; +sub GetLogStatus { + my %hash; + $hash{BorrowersLog} = C4::Context->preference("BorrowersLog"); + $hash{CataloguingLog} = C4::Context->preference("CataloguingLog"); + $hash{IssueLog} = C4::Context->preference("IssueLog"); + $hash{ReturnLog} = C4::Context->preference("ReturnLog"); + $hash{SubscriptionLog} = C4::Context->preference("SubscriptionLog"); + $hash{LetterLog} = C4::Context->preference("LetterLog"); + $hash{FinesLog} = C4::Context->preference("FinesLog"); + return \%hash; } -=item logstatus +=item displaylog - &logstatus; + &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 -returns True If Activate_Log variable is equal to On -Activate_Log is a system preference Variable =cut + #' -sub logstatus{ - my ($usernumber,$modulename, $actionname, $infos)=@_; - my $dbh = C4::Context->dbh; - my $sth=$dbh->prepare("select value from systempreferences where variable='Activate_Log'"); - $sth->execute; - my ($var)=$sth->fetchrow; - $sth->finish; - return ($var eq "On"?"True":"") +sub displaylog { + my ($modulename, @filters) = @_; + my $dbh = C4::Context->dbh; + my $strsth=qq| + SELECT action_logs.timestamp, action_logs.action, action_logs.info, + borrowers.cardnumber, borrowers.surname, borrowers.firstname, borrowers.userid, + biblio.biblionumber, biblio.title, biblio.author + FROM action_logs + LEFT JOIN borrowers ON borrowers.borrowernumber=action_logs.user + LEFT JOIN biblio ON action_logs.object=biblio.biblionumber + WHERE action_logs.module = 'cataloguing' + |; + my %filtermap = (); + if ($modulename eq "catalogue" or $modulename eq "acqui") { + %filtermap = ( + user => 'borrowers.surname', + title => 'biblio.title', + author => 'biblio.author', + ); + } elsif ($modulename eq "members") { + $strsth=qq| + SELECT action_logs.timestamp, action_logs.action, action_logs.info, + borrowers.cardnumber, borrowers.surname, borrowers.firstname, borrowers.userid, + bor2.cardnumber, bor2.surname, bor2.firstname, bor2.userid + FROM action_logs + LEFT JOIN borrowers ON borrowers.borrowernumber=action_logs.user + LEFT JOIN borrowers as bor2 ON action_logs.object=bor2.borrowernumber + WHERE action_logs.module = 'members' + |; + %filtermap = ( + user => 'borrowers.surname', + surname => 'bor2.surname', + firstname => 'bor2.firstname', + cardnumber => 'bor2.cardnumber', + ); + } else { + return 0; + } + + if (@filters) { + foreach my $filter (@filters) { + my $tempname = $filter->{name} or next; + (grep {/^$tempname$/} keys %filtermap) or next; + $filter->{value} =~ s/\*/%/g; + $strsth .= " AND " . $filtermap{$tempname} . " LIKE " . $filter->{value}; + } + } + my $sth=$dbh->prepare($strsth); + $sth->execute; + my @results; + my $count; + my $hilighted=1; + while (my $data = $sth->fetchrow_hashref){ + $data->{hilighted} = ($hilighted>0); + $data->{info} =~ s/\n//g; + $data->{day} = format_date($data->{timestamp}); + push @results, $data; + $count++; + $hilighted = -$hilighted; + } + return ($count, \@results); } -END { } # module clean-up code here (global destructor) +=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 + +sub GetLogs { + my $datefrom = shift; + my $dateto = shift; + my $user = shift; + my $modules = shift; + my $action = shift; + my $object = shift; + my $info = shift; + + my $iso_datefrom = C4::Dates->new($datefrom,C4::Context->preference("dateformat"))->output('iso'); + my $iso_dateto = C4::Dates->new($dateto,C4::Context->preference("dateformat"))->output('iso'); + + my $dbh = C4::Context->dbh; + my $query = " + SELECT * + FROM action_logs + WHERE 1 + "; + + my @parameters; + $query .= " AND DATE_FORMAT(timestamp, '%Y-%m-%d') >= \"".$iso_datefrom."\" " if $iso_datefrom; #fix me - mysql specific + $query .= " AND DATE_FORMAT(timestamp, '%Y-%m-%d') <= \"".$iso_dateto."\" " if $iso_dateto; + if($user) { + $query .= " AND user LIKE ? "; + push(@parameters,"%".$user."%"); + } + if(scalar @$modules > 1 or @$modules[0] ne "") { + $query .= " AND (1 = 2"; #always false but used to build the query + foreach my $module (@$modules) { + next if $module eq ""; + $query .= " or module = ?"; + push(@parameters,$module); + } + $query .= ")"; + } + if($action) { + $query .= " AND action LIKE ? "; + push(@parameters,"%".$action."%"); + } + if($object) { + $query .= " AND object LIKE ? "; + push(@parameters,"%".$object."%"); + } + if($info) { + $query .= " AND info LIKE ? "; + push(@parameters,"%".$info."%"); + } + + my $sth = $dbh->prepare($query); + $sth->execute(@parameters); + + my @logs; + while( my $row = $sth->fetchrow_hashref ) { + $row->{$row->{module}} = 1; + push @logs , $row; + } + return \@logs; +} 1; __END__