X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=C4%2FLog.pm;h=3a1e93e081b89bd6292fec0b826c93f9226023fb;hb=deb968ea45276e56826b592026617a96398b61da;hp=9e5f76cfba5d7de8e1b0557ab539d99ad802aab9;hpb=190d05b00eb3775b3405eb800421c53eb089daa9;p=koha.git diff --git a/C4/Log.pm b/C4/Log.pm index 9e5f76cfba..3a1e93e081 100644 --- a/C4/Log.pm +++ b/C4/Log.pm @@ -1,35 +1,42 @@ -package C4::Log; #assumes C4/Log +package C4::Log; #package to deal with Logging Actions in DB # Copyright 2000-2002 Katipo Communications +# Copyright 2011 MJ Ray and software.coop # # This file is part of Koha. # -# Koha is free software; you can redistribute it and/or modify it under the -# terms of the GNU General Public License as published by the Free Software -# Foundation; either version 2 of the License, or (at your option) any later -# version. +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. # -# Koha is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. # -# You should have received a copy of the GNU General Public License along with -# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place, -# Suite 330, Boston, MA 02111-1307 USA +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . use strict; -use C4::Context; -use C4::Date; +use warnings; + +use JSON qw( to_json ); -require Exporter; +use C4::Context; +use Koha::DateUtils; +use Koha::Logger; -use vars qw($VERSION @ISA @EXPORT); +use vars qw(@ISA @EXPORT); -# set the version for version checking -$VERSION = 0.01; +BEGIN { + require Exporter; + @ISA = qw(Exporter); + @EXPORT = qw(&logaction &cronlogaction &GetLogs); +} =head1 NAME @@ -47,143 +54,146 @@ The functions in this module perform various functions in order to log all the o =over 2 -=cut - -@ISA = qw(Exporter); -@EXPORT = qw(&logaction &logstatus &displaylog); - =item logaction - &logaction($usernumber, $modulename, $actionname, $infos); + &logaction($modulename, $actionname, $objectnumber, $infos); -Adds a record into action_logs table to report the different changes upon the database +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 + #' -sub logaction{ - my ($usernumber,$modulename, $actionname, $objectnumber, $infos)=@_; - 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; +sub logaction { + my ($modulename, $actionname, $objectnumber, $infos, $interface)=@_; + + # 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; + $usernumber ||= 0; + $interface //= C4::Context->interface; + + my $dbh = C4::Context->dbh; + my $sth=$dbh->prepare("Insert into action_logs (timestamp,user,module,action,object,info,interface) values (now(),?,?,?,?,?,?)"); + $sth->execute($usernumber,$modulename,$actionname,$objectnumber,$infos,$interface); + $sth->finish; + + my $logger = Koha::Logger->get( + { + interface => 'intranet', + category => "ActionLogs.$modulename.$actionname" + } + ); + $logger->debug( + sub { + "ACTION LOG: " . to_json( + { + user => $usernumber, + module => $modulename, + action => $actionname, + object => $objectnumber, + info => $infos + } + ); + } + ); } -=item logstatus +=item cronlogaction + + &cronlogaction($infos); - &logstatus; +Convenience routine to add a record into action_logs table from a cron job. +Logs the path and name of the calling script plus the information privided by param $infos. -returns True If Activate_Log variable is equal to On -Activate_Log is a system preference Variable =cut + #' -sub logstatus{ - return C4::Context->preference("Activate_Log"); +sub cronlogaction { + my ($infos)=@_; + my $loginfo = (caller(0))[1]; + $loginfo .= ' ' . $infos if $infos; + logaction( 'CRONJOBS', 'Run', undef, $loginfo ) if C4::Context->preference('CronjobLog'); } -=item displaylog +=item GetLogs - &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 +$logs = GetLogs($datefrom,$dateto,$user,\@modules,$action,$object,$info); -returns a table of hash containing who did what on which object at what time +Return: +C<$logs> is a ref to a hash which contains all columns from action_logs =cut -#' -sub displaylog{ - my ($modulename, @filters)=@_; - my $dbh = C4::Context->dbh; - my $strsth; - if ($modulename eq "catalogue"){ - $strsth="select action_logs.timestamp, action_logs.action, action_logs.info, borrowers.cardnumber, borrowers.surname, borrowers.firstname, borrowers.userid,"; - $strsth .= "biblio.biblionumber, biblio.title, biblio.author" ;#if ($modulename eq "acqui.simple"); - $strsth .= " FROM borrowers,action_logs "; - $strsth .= ",biblio " ;#if ($modulename eq "acqui.simple"); - - $strsth .=" WHERE borrowers.borrowernumber=action_logs.user"; - $strsth .=" AND action_logs.module = 'acqui.simple' AND action_logs.object=biblio.biblionumber ";# if ($modulename eq "acqui.simple"); - if (@filters){ - foreach my $filter (@filters){ - if ($filter->{name} =~ /user/){ - $filter->{value}=~s/\*/%/g; - $strsth .= " AND borrowers.surname like ".$filter->{value}; - }elsif ($filter->{name} =~ /title/){ - $filter->{value}=~s/\*/%/g; - $strsth .= " AND biblio.title like ".$filter->{value}; - }elsif ($filter->{name} =~ /author/){ - $filter->{value}=~s/\*/%/g; - $strsth .= " AND biblio.author like ".$filter->{value}; - } - } - } - } elsif ($modulename eq "acqui") { - $strsth="select action_logs.timestamp, action_logs.action, action_logs.info, borrowers.cardnumber, borrowers.surname, borrowers.firstname, borrowers.userid,"; - $strsth .= "biblio.biblionumber, biblio.title, biblio.author" ;#if ($modulename eq "acqui.simple"); - $strsth .= "FROM borrowers,action_logs "; - $strsth .= ",biblio " ;#if ($modulename eq "acqui.simple"); - - $strsth .=" WHERE borrowers.borrowernumber=action_logs.user"; - $strsth .= "AND action_logs.module = 'acqui.simple' AND action_logs.object=biblio.biblionumber ";# if ($modulename eq "acqui.simple"); - if (@filters){ - foreach my $filter (@filters){ - if ($filter->{name} =~ /user/){ - $filter->{value}=~s/\*/%/g; - $strsth .= " AND borrowers.surname like ".$filter->{value}; - }elsif ($filter->{name} =~ /title/){ - $filter->{value}=~s/\*/%/g; - $strsth .= " AND biblio.title like ".$filter->{value}; - }elsif ($filter->{name} =~ /author/){ - $filter->{value}=~s/\*/%/g; - $strsth .= " AND biblio.author like ".$filter->{value}; - } - } - } - } elsif ($modulename eq "members"){ - $strsth="select action_logs.timestamp, action_logs.action, action_logs.info, borrowers.cardnumber, borrowers.surname, borrowers.firstname, borrowers.userid,"; - $strsth .= "bor2.cardnumber, bor2.surname, bor2.firstname, bor2.userid,"; - $strsth .= "FROM borrowers,action_logs,borrowers as bor2 "; - - $strsth .=" WHERE borrowers.borrowernumber=action_logs.user"; - $strsth .= "AND action_logs.module = 'members' AND action_logs.object=bor2.borrowernumber ";# if ($modulename eq "acqui.simple"); - if (@filters){ - foreach my $filter (@filters){ - if ($filter->{name} =~ /user/){ - $filter->{value}=~s/\*/%/g; - $strsth .= " AND borrowers.surname like ".$filter->{value}; - }elsif ($filter->{name} =~ /surname/){ - $filter->{value}=~s/\*/%/g; - $strsth .= " AND bor2.surname like ".$filter->{value}; - }elsif ($filter->{name} =~ /firstname/){ - $filter->{value}=~s/\*/%/g; - $strsth .= " AND bor2.firsntame like ".$filter->{value}; - }elsif ($filter->{name} =~ /cardnumber/){ - $filter->{value}=~s/\*/%/g; - $strsth .= " AND bor2.cardnumber like ".$filter->{value}; - } - } - } - } -# warn "displaylog :".$strsth; - if ($strsth){ - 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); - } else {return 0;} + +sub GetLogs { + my $datefrom = shift; + my $dateto = shift; + my $user = shift; + my $modules = shift; + my $action = shift; + my $object = shift; + my $info = shift; + my $interfaces = shift; + + my $iso_datefrom = $datefrom ? output_pref({ dt => dt_from_string( $datefrom ), dateformat => 'iso', dateonly => 1 }) : undef; + my $iso_dateto = $dateto ? output_pref({ dt => dt_from_string( $dateto ), dateformat => 'iso', dateonly => 1 }) : undef; + + $user ||= q{}; + + 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 ne q{} ) { + $query .= " AND user = ? "; + push( @parameters, $user ); + } + if ( $modules && scalar(@$modules) ) { + $query .= + " AND module IN (" . join( ",", map { "?" } @$modules ) . ") "; + push( @parameters, @$modules ); + } + if ( $action && scalar(@$action) ) { + $query .= " AND action IN (" . join( ",", map { "?" } @$action ) . ") "; + push( @parameters, @$action ); + } + if ($object) { + $query .= " AND object = ? "; + push( @parameters, $object ); + } + if ($info) { + $query .= " AND info LIKE ? "; + push( @parameters, "%" . $info . "%" ); + } + if ( $interfaces && scalar(@$interfaces) ) { + $query .= + " AND interface IN (" . join( ",", map { "?" } @$interfaces ) . ") "; + push( @parameters, @$interfaces ); + } + + my $sth = $dbh->prepare($query); + $sth->execute(@parameters); + + my @logs; + while ( my $row = $sth->fetchrow_hashref ) { + push @logs, $row; + } + return \@logs; } -END { } # module clean-up code here (global destructor) 1; __END__ @@ -192,6 +202,6 @@ __END__ =head1 AUTHOR -Koha Developement team +Koha Development Team =cut