From 76b80ac33ce5ad2048f4de8a9d132610f89d3fc1 Mon Sep 17 00:00:00 2001 From: Kyle M Hall Date: Mon, 21 May 2012 16:42:53 -0400 Subject: [PATCH] Bug 8130 - attach PDF files to a patron record Adds the ability to attach unlimited arbitrary files to a borrower record. Test Plan: 1) Enable system preference EnableBorrowerFiles 2) Look up borrower record, click 'Files' tab on left 3) Upload a file, download the file, delete the file. Signed-off-by: Liz Rea rebased for current master. Signed-off-by: Ian Walls rebased again; some indentation issues in include menus. --- C4/Auth.pm | 1 + Koha/Borrower/Files.pm | 155 ++++++++++++++++++ installer/data/mysql/sysprefs.sql | 1 + installer/data/mysql/updatedatabase.pl | 22 +++ .../prog/en/includes/circ-menu.inc | 26 ++- .../prog/en/includes/members-menu.inc | 27 ++- .../en/modules/admin/preferences/patrons.pref | 6 + .../prog/en/modules/members/files.tt | 74 +++++++++ members/files.pl | 115 +++++++++++++ 9 files changed, 409 insertions(+), 18 deletions(-) create mode 100644 Koha/Borrower/Files.pm create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/members/files.tt create mode 100755 members/files.pl diff --git a/C4/Auth.pm b/C4/Auth.pm index 143fe3ff23..f796d118d5 100644 --- a/C4/Auth.pm +++ b/C4/Auth.pm @@ -365,6 +365,7 @@ sub get_template_and_user { LocalCoverImages => C4::Context->preference('LocalCoverImages'), OPACLocalCoverImages => C4::Context->preference('OPACLocalCoverImages'), AllowMultipleCovers => C4::Context->preference('AllowMultipleCovers'), + EnableBorrowerFiles => C4::Context->preference('EnableBorrowerFiles'), ); } else { diff --git a/Koha/Borrower/Files.pm b/Koha/Borrower/Files.pm new file mode 100644 index 0000000000..91a5463801 --- /dev/null +++ b/Koha/Borrower/Files.pm @@ -0,0 +1,155 @@ +package Koha::Borrower::Files; + +# Copyright 2012 Kyle M Hall +# +# 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); + +use C4::Context; +use C4::Output; +use C4::Dates; +use C4::Debug; + +BEGIN { + + # set the version for version checking + $VERSION = 0.01; + require Exporter; + @ISA = qw(Exporter); + @EXPORT = qw( + + ); + + my $debug = C4::Context->preference("DebugLevel"); +} + +=head1 NAME + +Koha::Borrower::Files - Module for managing borrower files + +=cut + +sub new { + my ( $class, %args ) = @_; + my $self = bless( {}, $class ); + + $self->{'borrowernumber'} = $args{'borrowernumber'}; + + return $self; +} + +=item GetFilesInfo() + + my $bf = Koha::Borrower::Files->new( borrowernumber => $borrowernumber ); + my $files_hashref = $bf->GetFilesInfo + +=cut + +sub GetFilesInfo { + my $self = shift; + + my $dbh = C4::Context->dbh; + my $query = " + SELECT + file_id, + file_name, + file_type, + file_description, + date_uploaded + FROM borrower_files + WHERE borrowernumber = ? + ORDER BY file_name, date_uploaded + "; + my $sth = $dbh->prepare($query); + $sth->execute( $self->{'borrowernumber'} ); + return $sth->fetchall_arrayref( {} ); +} + +=item AddFile() + my $bf = Koha::Borrower::Files->new( borrowernumber => $borrowernumber ); + $bh->AddFile( name => $filename, type => $mimetype, description => $description, content => $content ); +=cut + +sub AddFile { + my ( $self, %args ) = @_; + + my $name = $args{'name'}; + my $type = $args{'type'}; + my $description = $args{'description'}; + my $content = $args{'content'}; + + return unless ( $name && $content ); + + my $dbh = C4::Context->dbh; + my $query = " + INSERT INTO borrower_files ( borrowernumber, file_name, file_type, file_description, file_content ) + VALUES ( ?,?,?,?,? ) + "; + my $sth = $dbh->prepare($query); + $sth->execute( $self->{'borrowernumber'}, + $name, $type, $description, $content ); +} + +=item GetFile() + my $bf = Koha::Borrower::Files->new( borrowernumber => $borrowernumber ); + my $file = $bh->GetFile( file_id => $file_id ); +=cut + +sub GetFile { + my ( $self, %args ) = @_; + + my $file_id = $args{'id'}; + + my $dbh = C4::Context->dbh; + my $query = " + SELECT * FROM borrower_files WHERE file_id = ? AND borrowernumber = ? + "; + my $sth = $dbh->prepare($query); + $sth->execute( $file_id, $self->{'borrowernumber'} ); + return $sth->fetchrow_hashref(); +} + +=item DelFile() + my $bf = Koha::Borrower::Files->new( borrowernumber => $borrowernumber ); + $bh->DelFile( file_id => $file_id ); +=cut + +sub DelFile { + my ( $self, %args ) = @_; + + my $file_id = $args{'id'}; + + my $dbh = C4::Context->dbh; + my $query = " + DELETE FROM borrower_files WHERE file_id = ? AND borrowernumber = ? + "; + my $sth = $dbh->prepare($query); + $sth->execute( $file_id, $self->{'borrowernumber'} ); +} + +1; +__END__ + +=back + +=head1 AUTHOR + +Kyle M Hall + +=cut diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index 8e3066d675..947433631d 100644 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -372,3 +372,4 @@ INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES(' INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('DefaultLanguageField008','','Fill in the default language for field 008 Range 35-37 (e.g. eng, nor, ger, see MARC Code List for Languages)','','Free'); INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OPACShowBarcode','0','Show items barcode in holding tab','','YesNo'); INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('OPACShowUnusedAuthorities','1','','Show authorities that are not being used in the OPAC.','YesNo'); +INSERT INTO systempreferences (variable,value,explanation,type) VALUES('EnableBorrowerFiles','0','If enabled, allows librarians to upload and attach arbitrary files to a borrower record.','YesNo'); diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index 4d1f37b250..f3acaad9ec 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -5423,6 +5423,28 @@ if (C4::Context->preference("Version") < TransformToNum($DBversion)) { SetVersion ($DBversion); } +$DBversion = "3.09.00.020"; +if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { + $dbh->do("INSERT INTO systempreferences (variable,value,explanation,type) VALUES('EnableBorrowerFiles','0','If enabled, allows librarians to upload and attach arbitrary files to a borrower record.','YesNo')"); + $dbh->do(" +CREATE TABLE IF NOT EXISTS borrower_files ( + file_id int(11) NOT NULL AUTO_INCREMENT, + borrowernumber int(11) NOT NULL, + file_name varchar(255) NOT NULL, + file_type varchar(255) NOT NULL, + file_description varchar(255) DEFAULT NULL, + file_content longblob NOT NULL, + date_uploaded timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (file_id), + KEY borrowernumber (borrowernumber) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + "); + $dbh->do("ALTER TABLE borrower_files ADD CONSTRAINT borrower_files_ibfk_1 FOREIGN KEY (borrowernumber) REFERENCES borrowers (borrowernumber) ON DELETE CASCADE ON UPDATE CASCADE"); + + print "Upgrade to $DBversion done (Added borrow_files table, EnableBorrowerFiles syspref)\n"; + SetVersion($DBversion); +} + =head1 FUNCTIONS =head2 TableExists($table) diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc index 7014c39ee1..3c8c1bf0cb 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc @@ -63,18 +63,26 @@ [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/members-menu.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/members-menu.inc index 4b771d853b..9bd528516b 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/members-menu.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/members-menu.inc @@ -1,15 +1,24 @@ [% IF ( borrowernumber ) %] + [% IF EnableBorrowerFiles %] + [% IF ( borrower_files ) %]
  • [% ELSE %]
  • [% END %]Files
  • + [% END %] + + [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref index 030f376af9..70af7623fe 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref @@ -131,3 +131,9 @@ Patrons: - pref: StatisticsFields class: multi - Define Fields (from the items table) used for statistics members (separate fields with |, for example:"location|itype|ccode"). + - + - pref: EnableBorrowerFiles + choices: + yes: Do + no: "Don't" + - enable the ability to upload and attach arbitrary files to a borrower record. diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/files.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/files.tt new file mode 100644 index 0000000000..1655823661 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/files.tt @@ -0,0 +1,74 @@ +[% USE KohaDates %] +[% INCLUDE 'doc-head-open.inc' %] +Files for [% INCLUDE 'patron-title.inc' %] +[% INCLUDE 'doc-head-close.inc' %] + + +[% INCLUDE 'header.inc' %] +[% INCLUDE 'patron-search.inc' %] + + + +
    +
    +
    +
    + [% INCLUDE 'circ-toolbar.inc' %] + +

    Files

    + + + + + + + + [% IF CAN_user_borrowers %][% END %] + + + + [% IF errors %] +
    + [% IF errors.empty_upload %]The file you are attempting to upload has no contents.[% END %] + [% IF errors.no_file %]You did not select a file to upload.[% END %] +
    + [% END %] + + [% FOREACH f IN files %] + + + + + + [% IF CAN_user_borrowers %][% END %] + + [% END %] + +
    NameTypeDescriptionUploaded 
    [% f.file_name %][% f.file_type %][% f.file_description %][% f.date_uploaded | $KohaDates %]Delete
    + +
    +
    + Upload New File + + + + + + + + + + + +
    +
    + +
    +
    + +
    + [% INCLUDE 'circ-menu.inc' %] +
    +
    +
    +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/members/files.pl b/members/files.pl new file mode 100755 index 0000000000..ccd11bc28b --- /dev/null +++ b/members/files.pl @@ -0,0 +1,115 @@ +#!/usr/bin/perl + +# Copyright 2012 ByWater Solutions +# +# 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use strict; +use warnings; + +use CGI; + +use C4::Auth; +use C4::Output; +use C4::Members; +use C4::Debug; + +use Koha::DateUtils; +use Koha::Borrower::Files; + +my $cgi = CGI->new; + +my ( $template, $loggedinuser, $cookie ) = get_template_and_user( + { + template_name => "members/files.tmpl", + query => $cgi, + type => "intranet", + authnotrequired => 0, + flagsrequired => { borrowers => 1 }, + debug => 1, + } +); +$template->param( 'borrower_files' => 1 ); + +my $borrowernumber = $cgi->param('borrowernumber'); +my $bf = Koha::Borrower::Files->new( borrowernumber => $borrowernumber ); + +my $op = $cgi->param('op') || ''; + +if ( $op eq 'download' ) { + my $file_id = $cgi->param('file_id'); + my $file = $bf->GetFile( id => $file_id ); + + print $cgi->header( + -type => $file->{'file_type'}, + -charset => 'utf-8', + -attachment => $file->{'file_name'} + ); + print $file->{'file_content'}; +} +else { + my $data = GetMember( borrowernumber => $borrowernumber ); + $template->param(%$data); + + my %errors; + + if ( $op eq 'upload' ) { + my $uploaded_file = $cgi->upload('uploadfile'); + + if ($uploaded_file) { + my $filename = $cgi->param('uploadfile'); + my $mimetype = $cgi->uploadInfo($filename)->{'Content-Type'}; + + $errors{'empty_upload'} = 1 unless ( length($uploaded_file) > 0 ); + + if (%errors) { + $template->param( errors => %errors ); + } + else { + my $file_content; + while (<$uploaded_file>) { + $file_content .= $_; + } + + $bf->AddFile( + name => $filename, + type => $mimetype, + content => $file_content, + description => $cgi->param('description'), + ); + } + } + else { + $errors{'no_file'} = 1; + } + } elsif ( $op eq 'delete' ) { + $bf->DelFile( id => $cgi->param('file_id') ); + } + + $template->param( + files => Koha::Borrower::Files->new( borrowernumber => $borrowernumber ) + ->GetFilesInfo(), + + errors => %errors + ); + output_html_with_http_headers $cgi, $cookie, $template->output; +} + +=head1 AUTHOR + +Kyle M Hall + +=cut -- 2.39.5