Browse Source

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 <wizzyrea@gmail.com>
rebased for current master.

Signed-off-by: Ian Walls <koha.sekjal@gmail.com>
rebased again; some indentation issues in include menus.
3.10.x
Kyle Hall 12 years ago
committed by Paul Poulain
parent
commit
76b80ac33c
  1. 1
      C4/Auth.pm
  2. 155
      Koha/Borrower/Files.pm
  3. 1
      installer/data/mysql/sysprefs.sql
  4. 22
      installer/data/mysql/updatedatabase.pl
  5. 26
      koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc
  6. 27
      koha-tmpl/intranet-tmpl/prog/en/includes/members-menu.inc
  7. 6
      koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref
  8. 74
      koha-tmpl/intranet-tmpl/prog/en/modules/members/files.tt
  9. 115
      members/files.pl

1
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 {

155
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 <kyle.m.hall@gmail.com>
=cut

1
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 <a href="http://www.loc.gov/marc/languages/language_code.html">MARC Code List for Languages</a>)','','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');

22
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)

26
koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc

@ -63,18 +63,26 @@
<div id="menu">
<ul>
[% IF ( circview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/circ/circulation.pl?borrowernumber=[% borrowernumber %]">Check out</a></li>
[% IF ( CAN_user_borrowers ) %]
[% IF ( detailview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">Details</a></li>
[% END %]
[% IF ( CAN_user_updatecharges ) %]
[% IF ( finesview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=[% borrowernumber %]">Fines</a></li>
[% END %]
[% IF ( intranetreadinghistory ) %][% IF ( readingrecordview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/readingrec.pl?borrowernumber=[% borrowernumber %]">Circulation history</a></li>[% END %]
[% IF ( CAN_user_parameters ) %][% IF ( logview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/tools/viewlog.pl?do_it=1&amp;modules=MEMBERS&amp;modules=circulation&amp;object=[% borrowernumber %]&amp;src=circ">Modification log</a></li>[% END %]
[% IF ( CAN_user_borrowers ) %]
[% IF ( detailview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">Details</a></li>
[% END %]
[% IF ( CAN_user_updatecharges ) %]
[% IF ( finesview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=[% borrowernumber %]">Fines</a></li>
[% END %]
[% IF ( intranetreadinghistory ) %]
[% IF ( readingrecordview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/readingrec.pl?borrowernumber=[% borrowernumber %]">Circulation history</a></li>
[% END %]
[% IF ( CAN_user_parameters ) %]
[% IF ( logview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/tools/viewlog.pl?do_it=1&amp;modules=MEMBERS&amp;modules=circulation&amp;object=[% borrowernumber %]&amp;src=circ">Modification log</a></li>
[% END %]
[% IF ( EnhancedMessagingPreferences ) %]
[% END %]
[% IF ( sentnotices ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/notices.pl?borrowernumber=[% borrowernumber %]">Notices</a></li>
[% END %]
[% IF ( statisticsview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/statistics.pl?borrowernumber=[% borrowernumber %]">Statistics</a></li>
[% IF ( sentnotices ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/notices.pl?borrowernumber=[% borrowernumber %]">Notices</a></li>
[% IF EnableBorrowerFiles %]
[% IF ( borrower_files ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/files.pl?borrowernumber=[% borrowernumber %]">Files</a></li>
[% END %]
</ul></div>
[% END %]

27
koha-tmpl/intranet-tmpl/prog/en/includes/members-menu.inc

@ -1,15 +1,24 @@
[% IF ( borrowernumber ) %]
<div id="menu">
<ul> [% IF ( circview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/circ/circulation.pl?borrowernumber=[% borrowernumber %]">Check out</a></li>
[% IF ( detailview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">Details</a></li>
[% IF ( CAN_user_updatecharges ) %]
[% IF ( finesview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=[% borrowernumber %]">Fines</a></li>
[% END %]
[% IF ( intranetreadinghistory ) %][% IF ( readingrecordview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/readingrec.pl?borrowernumber=[% borrowernumber %]">Circulation history</a></li>[% END %]
[% IF ( CAN_user_parameters ) %][% IF ( logview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/tools/viewlog.pl?do_it=1&amp;modules=MEMBERS&amp;action=MODIFY&amp;object=[% borrowernumber %]">Modification log</a></li>[% END %]
[% IF ( EnhancedMessagingPreferences ) %]
<ul>
[% IF ( circview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/circ/circulation.pl?borrowernumber=[% borrowernumber %]">Check out</a></li>
[% IF ( detailview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">Details</a></li>
[% IF ( CAN_user_updatecharges ) %]
[% IF ( finesview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=[% borrowernumber %]">Fines</a></li>
[% END %]
[% IF ( intranetreadinghistory ) %]
[% IF ( readingrecordview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/readingrec.pl?borrowernumber=[% borrowernumber %]">Circulation history</a></li>
[% END %]
[% IF ( CAN_user_parameters ) %]
[% IF ( logview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/tools/viewlog.pl?do_it=1&amp;modules=MEMBERS&amp;action=MODIFY&amp;object=[% borrowernumber %]">Modification log</a></li>
[% END %]
[% IF ( EnhancedMessagingPreferences ) %]
[% IF ( sentnotices ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/notices.pl?borrowernumber=[% borrowernumber %]">Notices</a></li>
[% END %]
[% IF ( statisticsview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/statistics.pl?borrowernumber=[% borrowernumber %]">Statistics</a></li>
</ul></div>
[% IF EnableBorrowerFiles %]
[% IF ( borrower_files ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/files.pl?borrowernumber=[% borrowernumber %]">Files</a></li>
[% END %]
</ul>
</div>
[% END %]

6
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.

74
koha-tmpl/intranet-tmpl/prog/en/modules/members/files.tt

@ -0,0 +1,74 @@
[% USE KohaDates %]
[% INCLUDE 'doc-head-open.inc' %]
<title>Files for [% INCLUDE 'patron-title.inc' %]</title>
[% INCLUDE 'doc-head-close.inc' %]
</head>
<body>
[% INCLUDE 'header.inc' %]
[% INCLUDE 'patron-search.inc' %]
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/members/members-home.pl">Patrons</a> &rsaquo; Files for [% INCLUDE 'patron-title.inc' %]</div>
<div id="doc3" class="yui-t2">
<div id="bd">
<div id="yui-main">
<div class="yui-b">
[% INCLUDE 'circ-toolbar.inc' %]
<h1>Files</h1>
<table>
<thead>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Uploaded</th>
[% IF CAN_user_borrowers %]<th>&nbsp;</th>[% END %]
</thead>
<tbody>
[% IF errors %]
<div class="error warn">
[% 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 %]
</div>
[% END %]
[% FOREACH f IN files %]
<tr>
<td><a href="?borrowernumber=[% borrowernumber %]&op=download&file_id=[% f.file_id %]">[% f.file_name %]</a></td>
<td>[% f.file_type %]</td>
<td>[% f.file_description %]</td>
<td>[% f.date_uploaded | $KohaDates %]</td>
[% IF CAN_user_borrowers %]<td><a href="?borrowernumber=[% borrowernumber %]&op=delete&file_id=[% f.file_id %]">Delete</a></td>[% END %]
</tr>
[% END %]
</tbody>
</table>
<form method="post" enctype="multipart/form-data">
<fieldset>
<legend>Upload New File</legend>
<input type="hidden" name="op" value="upload" />
<input type="hidden" name="borrowernumber" value="[% borrowernumber %]" />
<input type="hidden" name="MAX_FILE_SIZE" value="2000000" />
<label for="description">Description:</label>
<input name="description" type="text" />
<input name="uploadfile" type="file" id="uploadfile" />
<input name="upload" type="submit" id="upload" value="Upload File" />
</fieldset>
</form>
</div>
</div>
<div class="yui-b">
[% INCLUDE 'circ-menu.inc' %]
</div>
</div>
</div>
[% INCLUDE 'intranet-bottom.inc' %]

115
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 <kyle@bywatersolutions.com>
=cut
Loading…
Cancel
Save