From 25ec2b0bf49ac110cda3c6dec6c485391cc18f34 Mon Sep 17 00:00:00 2001 From: hdl Date: Wed, 24 Aug 2005 10:44:53 +0000 Subject: [PATCH] Adding Log Facility for Biblio management. Note that a javascript will soon be written for action type management and that viewlog.pl is fully functionnal (tested) only for Catalogue. --- C4/Log.pm | 207 ++++++++++++++++ acqui.simple/addbiblio.pl | 3 + admin/viewlog.pl | 149 ++++++++++++ .../default/en/parameters/viewlog.tmpl | 230 ++++++++++++++++++ 4 files changed, 589 insertions(+) create mode 100644 C4/Log.pm create mode 100755 admin/viewlog.pl create mode 100644 koha-tmpl/intranet-tmpl/default/en/parameters/viewlog.tmpl diff --git a/C4/Log.pm b/C4/Log.pm new file mode 100644 index 0000000000..103b788bce --- /dev/null +++ b/C4/Log.pm @@ -0,0 +1,207 @@ +package C4::Log; #assumes C4/Log + +#package to deal with Logging Actions in DB + + +# Copyright 2000-2002 Katipo Communications +# +# 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 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 + +use strict; +use C4::Context; +use C4::Date; + +require Exporter; + +use vars qw($VERSION @ISA @EXPORT); + +# set the version for version checking +$VERSION = 0.01; + +=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 + +=cut + +@ISA = qw(Exporter); +@EXPORT = qw(&logaction &logstatus &displaylog); + +=item logaction + + &logaction($usernumber, $modulename, $actionname, $infos); + +Adds a record into action_logs table to report the different changes upon the database + +=cut +#' +sub logaction{ + my ($usernumber,$modulename, $actionname, $objectnumber, $infos)=@_; + my $dbh = C4::Context->dbh; + warn "logactions :$usernumber,$modulename, $actionname, $objectnumber, $infos"; + 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 logstatus + + &logstatus; + +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"); +} + +=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 +#' +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 action_logs LEFT JOIN borrowers ON borrowers.borrowernumber=action_logs.user"; + $strsth .= ",biblio " ;#if ($modulename eq "acqui.simple"); + + $strsth .=" WHERE 1"; + $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}."') OR (borrowers.cardnumber like '".$filter->{value}."') OR (borrowers.firstname like '".$filter->{value}."')) "; + }elsif ($filter->{name} =~ /action/){ + $filter->{value}=~s/\*/%/g; + $strsth .= " AND action_logs.action like ".$dbh->quote($filter->{value}); + }elsif ($filter->{name} =~ /from/){ + $filter->{value}=~s/\*/%/g; + $strsth .= " AND action_logs.timestamp>".$dbh->quote($filter->{value}); + }elsif ($filter->{name} =~ /to/){ + $filter->{value}=~s/\*/%/g; + $strsth .= " AND action_logs.timestamp<".$dbh->quote($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;} +} +END { } # module clean-up code here (global destructor) + +1; +__END__ + +=back + +=head1 AUTHOR + +Koha Developement team + +=cut diff --git a/acqui.simple/addbiblio.pl b/acqui.simple/addbiblio.pl index c4e0ebf88b..b121ed0b48 100755 --- a/acqui.simple/addbiblio.pl +++ b/acqui.simple/addbiblio.pl @@ -21,6 +21,7 @@ use strict; use CGI; +use C4::Log; use C4::Auth; use C4::Output; use C4::Interface::CGI::Output; @@ -441,8 +442,10 @@ if ($op eq "addbiblio") { if ($is_a_modif) { NEWmodbiblioframework($dbh,$bibid,$frameworkcode); NEWmodbiblio($dbh,$record,$bibid,$frameworkcode); + logaction($loggedinuser,"acqui.simple","modify",$bibid,"record : ".$record->as_formatted) if (logstatus()); } else { ($bibid,$oldbibnum,$oldbibitemnum) = NEWnewbiblio($dbh,$record,$frameworkcode); + logaction($loggedinuser,"acqui.simple","add",$bibid,"record : ".$record->as_formatted) if (logstatus()); } # now, redirect to additem page print $input->redirect("additem.pl?bibid=$bibid&frameworkcode=$frameworkcode"); diff --git a/admin/viewlog.pl b/admin/viewlog.pl new file mode 100755 index 0000000000..e3c4992a31 --- /dev/null +++ b/admin/viewlog.pl @@ -0,0 +1,149 @@ +#!/usr/bin/perl + +# $Id$ + +# Copyright 2000-2002 Katipo Communications +# +# 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 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 + +use strict; +use C4::Auth; +use CGI; +use C4::Context; +use HTML::Template; +use C4::Koha; +use C4::Interface::CGI::Output; +use C4::Log; +use Date::Manip; + +=head1 NAME + +plugin that shows a stats on borrowers + +=head1 DESCRIPTION + + +=over2 + +=cut + +my $input = new CGI; +my $do_it=$input->param('do_it'); +my $fullreportname = "parameters/viewlog.tmpl"; +my $modulename = $input->param("module"); +my $userfilter = $input->param("user"); +my $actionfilter = $input->param("action"); +my $fromfilter = $input->param("from"); +my $tofilter = $input->param("to"); +my $basename = $input->param("basename"); +my $mime = $input->param("MIME"); +my $del = $input->param("sep"); +my $output = $input->param("output"); + +#warn "module : ".$modulename; +my ($template, $borrowernumber, $cookie) + = get_template_and_user({template_name => $fullreportname, + query => $input, + type => "intranet", + authnotrequired => 0, + flagsrequired => {editcatalogue => 1}, + debug => 1, + }); +$template->param(do_it => $do_it); +if ($do_it) { +# Displaying results + #building filters + my @filters; + push @filters, {name=> 'user', value=> $userfilter} if ($userfilter); + push @filters, {name=> 'action', value=> $actionfilter} if ($actionfilter); + push @filters, {name=> 'from', value=> $fromfilter} if ($fromfilter); + push @filters, {name=> 'to', value=> $tofilter} if ($tofilter); + if ($modulename eq "catalogue"){ + my $titlefilter = $input->param("title"); + my $authorfilter = $input->param("author"); + my $publisherfilter = $input->param("publisher"); + my $callnumberfilter = $input->param("itemcallnumber"); + + push @filters, {name=> 'title', value=> $titlefilter} if ($titlefilter); + push @filters, {name=> 'author', value=> $authorfilter} if ($authorfilter); + push @filters, {name=> 'publisher', value=> $publisherfilter} if ($publisherfilter); + push @filters, {name=> 'callnumber', value=> $callnumberfilter} if ($callnumberfilter); + } + + my ($count, $results) = displaylog( $modulename, @filters); + if ($output eq "screen"){ +# Printing results to screen + $template->param(modulename =>$modulename, $modulename => 1, looprow => $results); + output_html_with_http_headers $input, $cookie, $template->output; + exit(1); + } else { +# Printing to a csv file + print $input->header(-type => 'application/vnd.sun.xml.calc', + -attachment=>"$basename.csv", + -filename=>"$basename.csv" ); + my $sep; + $sep =C4::Context->preference("delimiter"); +# header top-right +# Other header +# Table + foreach my $line ( @$results ) { + if ($modulename eq "catalogue"){ + print $line->{timestamp}.$sep; + print $line->{firstname}.$sep; + print $line->{surname}.$sep; + print $line->{action}.$sep; + print $line->{info}.$sep; + print $line->{title}.$sep; + print $line->{author}.$sep; + } + print "\n"; + } +# footer + exit(1); + } +} else { + my $dbh = C4::Context->dbh; + my @values; + my %labels; + my %select; + my $req; + + my @mime = ( C4::Context->preference("MIME") ); +# foreach my $mime (@mime){ +# warn "".$mime; +# } + + my $CGIextChoice=CGI::scrolling_list( + -name => 'MIME', + -id => 'MIME', + -values => \@mime, + -size => 1, + -multiple => 0 ); + + my @dels = ( C4::Context->preference("delimiter") ); + my $CGIsepChoice=CGI::scrolling_list( + -name => 'sep', + -id => 'sep', + -values => \@dels, + -size => 1, + -multiple => 0 ); + + $template->param( + CGIextChoice => $CGIextChoice, + CGIsepChoice => $CGIsepChoice + ); +output_html_with_http_headers $input, $cookie, $template->output; +} diff --git a/koha-tmpl/intranet-tmpl/default/en/parameters/viewlog.tmpl b/koha-tmpl/intranet-tmpl/default/en/parameters/viewlog.tmpl new file mode 100644 index 0000000000..d6b9714eac --- /dev/null +++ b/koha-tmpl/intranet-tmpl/default/en/parameters/viewlog.tmpl @@ -0,0 +1,230 @@ + +
+ + + +

Koha : Hisory view for

+ +

Filtered on

+ +

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Modified on + Title + Librarian + Action + Info +

() +
, + + + +
Timestamp + Firstname + Surname + Action + Info + Title + Author +
+ + ')" > + + + + +
Timestamp + Firstname + Surname + Action + Info + Title + Author +
+ + + + + + + +
+ +

Koha : Display Logs

+
+ + + + + + + + + + + + + + +
On ModuleUser/Action FiltersObject Filter
+ + +

+ Koha User : +

+

Action type : +

+

From + /includes/calendar/cal.gif" border="0" hspace="0" vspace="0" id="openCalendarFrom" style="cursor: pointer;" valign="top"> + + To + /includes/calendar/cal.gif" id="openCalendarTo" style="cursor: pointer;" valign="top" border="0" hspace="0" vspace="0"> + +

+ +
+

Output

+ To screen into the browser +
+ To file into an application + + +

+
+

+ + "> + +

+ +
+ -- 2.39.5