Browse Source

Bug 14321: Final cleanup, removing obsolete files

The new Upload.pm, unit test and file-upload.js obsolete a number of
files, including an older jQuery plugin.
The test files progressbar.pl and progressbarsubmit.pl are outdated and
do not serve any purpose in this form. (Actually, we could argue if they
should be here or just be part of a debugging phase.)

Test plan:
[1] Git grep on file-progress, file-upload.inc, UploadedFile,
    ajaxfileupload, ajaxFileUpload
    UploadedFile: Only a reference to DBIx file is found
    ajaxfileupload: Only release notes
[2] Upload a file with tools/upload and stage-marc-import.

Signed-off-by: Mirko Tietgen <mirko@abunchofthings.net>
Signed-off-by: Julian Maurice <julian.maurice@biblibre.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
3.22.x
Marcel de Rooy 9 years ago
committed by Tomas Cohen Arazi
parent
commit
f8a58d310e
  1. 309
      C4/UploadedFile.pm
  2. 323
      C4/UploadedFiles.pm
  3. 200
      koha-tmpl/intranet-tmpl/lib/jquery/plugins/ajaxfileupload.js
  4. 70
      koha-tmpl/intranet-tmpl/prog/en/includes/file-upload.inc
  5. 103
      koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/upload.tt
  6. 63
      koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/upload_delete_file.tt
  7. 43
      koha-tmpl/intranet-tmpl/prog/en/modules/test/progressbar.tt
  8. 16
      t/db_dependent/UploadedFile.t
  9. 61
      t/db_dependent/UploadedFiles.t
  10. 55
      test/progressbar.pl
  11. 104
      test/progressbarsubmit.pl
  12. 62
      tools/upload-file-progress.pl

309
C4/UploadedFile.pm

@ -1,309 +0,0 @@
package C4::UploadedFile;
# Copyright (C) 2007 LibLime
# Galen Charlton <galen.charlton@liblime.com>
#
# 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 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.
#
# You should have received a copy of the GNU General Public License
# along with Koha; if not, see <http://www.gnu.org/licenses>.
use strict;
#use warnings; FIXME - Bug 2505
use C4::Context;
use C4::Auth qw/get_session/;
use IO::File;
use vars qw($VERSION);
BEGIN {
# set the version for version checking
$VERSION = 3.07.00.049;
}
=head1 NAME
C4::UploadedFile - manage files uploaded by the user
for later processing.
=head1 SYNOPSIS
# create and store data
my $uploaded_file = C4::UploadedFile->new($sessionID);
my $fileID = $uploaded_file->id();
$uploaded_file->name('c:\temp\file.mrc');
$uploaded_file->max_size(1024);
while ($have_more_data) {
$uploaded_file->stash($data, $bytes_read);
}
$uploaded_file->done();
# check status of current file upload
my $progress = C4::UploadedFile->upload_progress($sessionID);
# get file handle for reading uploaded file
my $uploaded_file = C4::UploadedFile->fetch($fileID);
my $fh = $uploaded_file->fh();
Stores files uploaded by the user from their web browser. The
uploaded files are temporary and at present are not guaranteed
to survive beyond the life of the user's session.
This module allows for tracking the progress of the file
currently being uploaded.
TODO: implement secure persistent storage of uploaded files.
=cut
=head1 METHODS
=cut
=head2 new
my $uploaded_file = C4::UploadedFile->new($sessionID);
Creates a new object to represent the uploaded file. Requires
the current session ID.
=cut
sub new {
my $class = shift;
my $sessionID = shift;
my $self = {};
$self->{'sessionID'} = $sessionID;
$self->{'fileID'} = Digest::MD5::md5_hex(Digest::MD5::md5_hex(time().{}.rand().{}.$$));
# FIXME - make staging area configurable
my $TEMPROOT = "/tmp";
my $OUTPUTDIR = "$TEMPROOT/$sessionID";
mkdir $OUTPUTDIR;
my $tmp_file_name = "$OUTPUTDIR/$self->{'fileID'}";
my $fh = new IO::File $tmp_file_name, "w";
unless (defined $fh) {
return undef;
}
$fh->binmode(); # Windows compatibility
$self->{'fh'} = $fh;
$self->{'tmp_file_name'} = $tmp_file_name;
$self->{'max_size'} = 0;
$self->{'progress'} = 0;
$self->{'name'} = '';
bless $self, $class;
$self->_serialize();
my $session = get_session($sessionID);
$session->param('current_upload', $self->{'fileID'});
$session->flush();
return $self;
}
sub _serialize {
my $self = shift;
my $prefix = "upload_" . $self->{'fileID'};
my $session = get_session($self->{'sessionID'});
# temporarily take file handle out of structure
my $fh = $self->{'fh'};
delete $self->{'fh'};
$session->param($prefix, $self);
$session->flush();
$self->{'fh'} =$fh;
}
=head2 id
my $fileID = $uploaded_file->id();
=cut
sub id {
my $self = shift;
return $self->{'fileID'};
}
=head2 name
my $name = $uploaded_file->name();
$uploaded_file->name($name);
Accessor method for the name by which the file is to be known.
=cut
sub name {
my $self = shift;
if (@_) {
$self->{'name'} = shift;
$self->_serialize();
} else {
return $self->{'name'};
}
}
=head2 filename
my $filename = $uploaded_file->filename();
Accessor method for the name by which the file is to be known.
=cut
sub filename {
my $self = shift;
if (@_) {
$self->{'tmp_file_name'} = shift;
$self->_serialize();
} else {
return $self->{'tmp_file_name'};
}
}
=head2 max_size
my $max_size = $uploaded_file->max_size();
$uploaded_file->max_size($max_size);
Accessor method for the maximum size of the uploaded file.
=cut
sub max_size {
my $self = shift;
@_ ? $self->{'max_size'} = shift : $self->{'max_size'};
}
=head2 stash
$uploaded_file->stash($dataref, $bytes_read);
Write C<$dataref> to the temporary file. C<$bytes_read> represents
the number of bytes (out of C<$max_size>) transmitted so far.
=cut
sub stash {
my $self = shift;
my $dataref = shift;
my $bytes_read = shift;
my $fh = $self->{'fh'};
print $fh $$dataref;
my $percentage = int(($bytes_read / $self->{'max_size'}) * 100);
if ($percentage > $self->{'progress'}) {
$self->{'progress'} = $percentage;
$self->_serialize();
}
}
=head2 done
$uploaded_file->done();
Indicates that all of the bytes have been uploaded.
=cut
sub done {
my $self = shift;
$self->{'progress'} = 'done';
$self->{'fh'}->close();
$self->_serialize();
}
=head2 upload_progress
my $upload_progress = C4::UploadFile->upload_progress($sessionID);
Returns (as an integer from 0 to 100) the percentage
progress of the current file upload.
=cut
sub upload_progress {
my ($class, $sessionID) = shift;
my $session = get_session($sessionID);
my $fileID = $session->param('current_upload');
my $reported_progress = 0;
if (defined $fileID and $fileID ne "") {
my $file = C4::UploadedFile->fetch($sessionID, $fileID);
my $progress = $file->{'progress'};
if (defined $progress) {
if ($progress eq "done") {
$reported_progress = 100;
} else {
$reported_progress = $progress;
}
}
}
return $reported_progress;
}
=head2 fetch
my $uploaded_file = C4::UploadedFile->fetch($sessionID, $fileID);
Retrieves an uploaded file object from the current session.
=cut
sub fetch {
my $class = shift;
my $sessionID = shift;
my $fileID = shift;
my $session = get_session($sessionID);
my $prefix = "upload_$fileID";
my $self = $session->param($prefix);
my $fh = new IO::File $self->{'tmp_file_name'}, "r";
$self->{'fh'} = $fh;
bless $self, $class;
return $self;
}
=head2 fh
my $fh = $uploaded_file->fh();
Returns an IO::File handle to read the uploaded file.
=cut
sub fh {
my $self = shift;
return $self->{'fh'};
}
1;
__END__
=head1 AUTHOR
Koha Development Team <http://koha-community.org/>
Galen Charlton <galen.charlton@liblime.com>
=cut

323
C4/UploadedFiles.pm

@ -1,323 +0,0 @@
package C4::UploadedFiles;
# This file is part of Koha.
#
# Copyright (C) 2011-2012 BibLibre
#
# 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.
#
# You should have received a copy of the GNU General Public License
# along with Koha; if not, see <http://www.gnu.org/licenses>.
=head1 NAME
C4::UploadedFiles - Functions to deal with files uploaded with cataloging plugin upload.pl
=head1 SYNOPSIS
use C4::UploadedFiles;
my $filename = $cgi->param('uploaded_file');
my $file = $cgi->upload('uploaded_file');
my $dir = $input->param('dir');
# upload file
my $id = C4::UploadedFiles::UploadFile($filename, $dir, $file->handle);
# retrieve file infos
my $uploaded_file = C4::UploadedFiles::GetUploadedFile($id);
# delete file
C4::UploadedFiles::DelUploadedFile($id);
=head1 DESCRIPTION
This module provides basic functions for adding, retrieving and deleting files related to
cataloging plugin upload.pl.
It uses uploaded_files table.
It is not related to C4::UploadedFile
=head1 FUNCTIONS
=cut
use Modern::Perl;
use Digest::SHA;
use Fcntl;
use Encode;
use C4::Context;
use C4::Koha;
sub _get_file_path {
my ($hash, $dirname, $filename) = @_;
my $upload_path = C4::Context->config('upload_path');
if( !-d "$upload_path/$dirname" ) {
mkdir "$upload_path/$dirname";
}
my $filepath = "$upload_path/$dirname/${hash}_$filename";
$filepath =~ s|/+|/|g;
return $filepath;
}
=head2 GetUploadedFile
my $file = C4::UploadedFiles::GetUploadedFile($id);
Returns a hashref containing infos on uploaded files.
Hash keys are:
=over 2
=item * id: id of the file (same as given in argument)
=item * filename: name of the file
=item * dir: directory where file is stored (relative to config variable 'upload_path')
=back
It returns undef if file is not found
=cut
sub GetUploadedFile {
my ( $hashvalue ) = @_;
return unless $hashvalue;
my $dbh = C4::Context->dbh;
my $query = qq{
SELECT hashvalue, filename, dir
FROM uploaded_files
WHERE hashvalue = ?
};
my $sth = $dbh->prepare($query);
$sth->execute( $hashvalue );
my $file = $sth->fetchrow_hashref;
if ($file) {
$file->{filepath} = _get_file_path($file->{hashvalue}, $file->{dir},
$file->{filename});
}
return $file;
}
=head2 UploadFile
my $id = C4::UploadedFiles::UploadFile($filename, $dir, $io_handle);
Upload a new file and returns its id (its SHA-1 sum, actually).
Parameters:
=over 2
=item * $filename: name of the file
=item * $dir: directory where to store the file (path relative to config variable 'upload_path'
=item * $io_handle: valid IO::Handle object, can be retrieved with
$cgi->upload('uploaded_file')->handle;
=back
=cut
sub UploadFile {
my ($filename, $dir, $handle) = @_;
$filename = decode_utf8($filename);
if($filename =~ m#(^|/)\.\.(/|$)# or $dir =~ m#(^|/)\.\.(/|$)#) {
warn "Filename or dirname contains '..'. Aborting upload";
return;
}
my $buffer;
my $data = '';
while($handle->read($buffer, 1024)) {
$data .= $buffer;
}
$handle->close;
my $sha = new Digest::SHA;
$sha->add($data);
$sha->add($filename);
$sha->add($dir);
my $hash = $sha->hexdigest;
# Test if this id already exist
my $file = GetUploadedFile($hash);
if ($file) {
return $file->{hashvalue};
}
my $file_path = _get_file_path($hash, $dir, $filename);
my $out_fh;
# Create the file only if it doesn't exist
unless( sysopen($out_fh, $file_path, O_WRONLY|O_CREAT|O_EXCL) ) {
warn "Failed to open file '$file_path': $!";
return;
}
print $out_fh $data;
my $size= tell($out_fh);
close $out_fh;
my $dbh = C4::Context->dbh;
my $query = qq{
INSERT INTO uploaded_files (hashvalue, filename, filesize, dir, categorycode, owner) VALUES (?,?,?,?,?,?);
};
my $sth = $dbh->prepare($query);
my $uid= C4::Context->userenv? C4::Context->userenv->{number}: undef;
# uid is null in unit test
if($sth->execute($hash, $filename, $size, $dir, $dir, $uid)) {
return $hash;
}
return;
}
=head2 DanglingEntry
C4::UploadedFiles::DanglingEntry($id,$isfileuploadurl);
Determine if a entry is dangling.
Returns: 2 == no db entry
1 == no plain file
0 == both a file and db entry.
-1 == N/A (undef id / non-file-upload URL)
=cut
sub DanglingEntry {
my ($id,$isfileuploadurl) = @_;
my $retval;
if (defined($id)) {
my $file = GetUploadedFile($id);
if($file) {
my $file_path = $file->{filepath};
my $file_deleted = 0;
unless( -f $file_path ) {
$retval = 1;
} else {
$retval = 0;
}
}
else {
if ( $isfileuploadurl ) {
$retval = 2;
}
else {
$retval = -1;
}
}
}
else {
$retval = -1;
}
return $retval;
}
=head2 DelUploadedFile
C4::UploadedFiles::DelUploadedFile( $hash );
Remove a previously uploaded file, given its hash value.
Returns: 1 == file deleted
0 == file not deleted
-1== no file to delete / no meaninful id passed
=cut
sub DelUploadedFile {
my ( $hashval ) = @_;
my $retval;
if ( $hashval ) {
my $file = GetUploadedFile( $hashval );
if($file) {
my $file_path = $file->{filepath};
my $file_deleted = 0;
unless( -f $file_path ) {
warn "Id $file->{hashvalue} is in database but no plain file found, removing id from database";
$file_deleted = 1;
} else {
if(unlink $file_path) {
$file_deleted = 1;
}
}
unless($file_deleted) {
warn "File $file_path cannot be deleted: $!";
}
my $dbh = C4::Context->dbh;
my $query = qq{
DELETE FROM uploaded_files
WHERE hashvalue = ?
};
my $sth = $dbh->prepare($query);
my $numrows = $sth->execute( $hashval );
# if either a DB entry or file was deleted,
# then clearly we have a deletion.
if ($numrows>0 || $file_deleted==1) {
$retval = 1;
}
else {
$retval = 0;
}
}
else {
warn "There was no file for hash $hashval.";
$retval = -1;
}
}
else {
warn "DelUploadFile called without hash value.";
$retval = -1;
}
return $retval;
}
=head2 getCategories
getCategories returns a list of upload category codes and names
=cut
sub getCategories {
my $cats = C4::Koha::GetAuthorisedValues('UPLOAD');
[ map {{ code => $_->{authorised_value}, name => $_->{lib} }} @$cats ];
}
=head2 httpheaders
httpheaders returns http headers for a retrievable upload
Will be extended by report 14282
=cut
sub httpheaders {
my $file= shift;
return
( '-type' => 'application/octet-stream',
'-attachment' => $file, );
}
1;

200
koha-tmpl/intranet-tmpl/lib/jquery/plugins/ajaxfileupload.js

@ -1,200 +0,0 @@
jQuery.extend({
createUploadIframe: function(id, uri)
{
//create frame
var frameId = 'jUploadFrame' + id;
try {
var io = document.createElement('<iframe id="' + frameId + '" name="' + frameId + '" />');
if(typeof uri== 'boolean'){
io.src = 'javascript:false';
}
else if(typeof uri== 'string'){
io.src = uri;
}
}
catch(e) {
var io = document.createElement('iframe');
io.id = frameId;
io.name = frameId;
}
io.style.position = 'absolute';
io.style.top = '-1000px';
io.style.left = '-1000px';
document.body.appendChild(io);
return io
},
createUploadForm: function(id, fileElementId)
{
//create form
var formId = 'jUploadForm' + id;
var fileId = 'jUploadFile' + id;
var form = $('<form action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
var oldElement = $('#' + fileElementId);
var newElement = $(oldElement).clone();
$(oldElement).attr('id', fileId);
$(oldElement).before(newElement);
$(oldElement).appendTo(form);
//set attributes
$(form).css('position', 'absolute');
$(form).css('top', '-1200px');
$(form).css('left', '-1200px');
$(form).appendTo('body');
return form;
},
ajaxFileUpload: function(s) {
// TODO introduce global settings, allowing the client to modify them for all requests, not only timeout
s = jQuery.extend({}, jQuery.ajaxSettings, s);
var id = new Date().getTime()
var form = jQuery.createUploadForm(id, s.fileElementId);
var io = jQuery.createUploadIframe(id, s.secureuri);
var frameId = 'jUploadFrame' + id;
var formId = 'jUploadForm' + id;
// Watch for a new set of requests
if ( s.global && ! jQuery.active++ )
{
jQuery.event.trigger( "ajaxStart" );
}
var requestDone = false;
// Create the request object
var xml = {}
if ( s.global )
jQuery.event.trigger("ajaxSend", [xml, s]);
// Wait for a response to come back
var uploadCallback = function(isTimeout)
{
var io = document.getElementById(frameId);
try
{
if(io.contentWindow)
{
xml.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null;
xml.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;
}else if(io.contentDocument)
{
xml.responseText = io.contentDocument.document.body?io.contentDocument.document.body.innerHTML:null;
xml.responseXML = io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocument:io.contentDocument.document;
}
}catch(e)
{
jQuery.handleError(s, xml, null, e);
}
if ( xml || isTimeout == "timeout")
{
requestDone = true;
var status;
try {
status = isTimeout != "timeout" ? "success" : "error";
// Make sure that the request was successful or notmodified
if ( status != "error" )
{
// process the data (runs the xml through httpData regardless of callback)
var data = jQuery.uploadHttpData( xml, s.dataType );
// If a local callback was specified, fire it and pass it the data
if ( s.success )
s.success( data, status );
// Fire the global callback
if( s.global )
jQuery.event.trigger( "ajaxSuccess", [xml, s] );
} else
jQuery.handleError(s, xml, status);
} catch(e)
{
status = "error";
jQuery.handleError(s, xml, status, e);
}
// The request was completed
if( s.global )
jQuery.event.trigger( "ajaxComplete", [xml, s] );
// Handle the global AJAX counter
if ( s.global && ! --jQuery.active )
jQuery.event.trigger( "ajaxStop" );
// Process result
if ( s.complete )
s.complete(xml, status);
jQuery(io).unbind()
setTimeout(function()
{ try
{
$(io).remove();
$(form).remove();
} catch(e)
{
jQuery.handleError(s, xml, null, e);
}
}, 100)
xml = null
}
}
// Timeout checker
if ( s.timeout > 0 )
{
setTimeout(function(){
// Check to see if the request is still happening
if( !requestDone ) uploadCallback( "timeout" );
}, s.timeout);
}
try
{
// var io = $('#' + frameId);
var form = $('#' + formId);
$(form).attr('action', s.url);
$(form).attr('method', 'POST');
$(form).attr('target', frameId);
if(form.encoding)
{
form.encoding = 'multipart/form-data';
}
else
{
form.enctype = 'multipart/form-data';
}
$(form).submit();
} catch(e)
{
jQuery.handleError(s, xml, null, e);
}
if(window.attachEvent){
document.getElementById(frameId).attachEvent('onload', uploadCallback);
}
else{
document.getElementById(frameId).addEventListener('load', uploadCallback, false);
}
return {abort: function () {}};
},
uploadHttpData: function( r, type ) {
var data = !type;
data = type == "xml" || data ? r.responseXML : r.responseText;
// If the type is "script", eval it in global context
if ( type == "script" )
jQuery.globalEval( data );
// Get the JavaScript object, if JSON is used.
if ( type == "json" )
eval( "data = " + data );
// evaluate scripts within html
if ( type == "html" )
jQuery("<div>").html(data).evalScripts();
//alert($('param', data).each(function(){alert($(this).attr('value'));}));
return data;
}
})

70
koha-tmpl/intranet-tmpl/prog/en/includes/file-upload.inc

@ -1,70 +0,0 @@
<!-- AJAX file upload stuff -->
<script type="text/javascript" src="[% interface %]/lib/jquery/plugins/ajaxfileupload.js"></script>
<script type="text/javascript">
//<![CDATA[
var fileUploadProgressTimer = 0;
var inFileUploadProgressTimer = false;
var fileUploadProgressTimerCanceled = false;
function updateProgress() {
if (inFileUploadProgressTimer) {
// since $.getJSON is asynchronous, wait
// until the last one is finished
return;
}
inFileUploadProgressTimer = true;
$.getJSON("/cgi-bin/koha/tools/upload-file-progress.pl", function(json) {
if (!fileUploadProgressTimerCanceled) {
var bgproperty = (parseInt(json.progress)*2-300)+"px 0px";
$("#fileuploadprogress").css("background-position",bgproperty);
$("#fileuploadpercent").text(json.progress);
}
inFileUploadProgressTimer = false;
});
}
function ajaxFileUpload()
{
fileUploadProgressTimerCanceled = false;
$("#uploadpanel").show();
$("#fileuploadstatus").show();
fileUploadProgressTimer = setInterval("updateProgress()",500);
$.ajaxFileUpload (
{
url:'/cgi-bin/koha/tools/upload-file.pl',
secureuri:false,
global:false,
fileElementId:'fileToUpload',
dataType: 'json',
success: function (data, status) {
if (data.status == 'denied') {
$("#fileuploadstatus").hide();
$("#fileuploadfailed").show();
$("#fileuploadfailed").text("Upload failed -- no permission to upload files");
} else if (data.status == 'failed') {
$("#fileuploadstatus").hide();
$("#fileuploadfailed").show();
$("#fileuploadfailed").text("Upload failed -- unable to store file on server");
} else if (data.status == 'maintenance') {
$("#fileuploadstatus").hide();
$("#fileuploadfailed").show();
$("#fileuploadfailed").text("Upload failed -- database in maintenance state");
} else {
$("#uploadedfileid").val(data.fileid);
$("#fileuploadprogress").css("background-position","0px 0px");
$("#processfile").show();
$("#fileuploadpercent").text("100");
}
fileUploadProgressTimerCanceled = true;
clearInterval(fileUploadProgressTimer);
},
error: function (data, status, e) {
fileUploadProgressTimerCanceled = true;
alert(e);
clearInterval(fileUploadProgressTimer);
}
}
)
return false;
}
//]]>
</script>

103
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/upload.tt

@ -1,103 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Upload plugin</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="[% interface %]/lib/jquery/jquery.js"></script>
<link rel="stylesheet" type="text/css" href="[% themelang %]/css/staff-global.css" />
<script type="text/javascript">
function ValidateForm() {
var filename = document.forms["UploadForm"]["uploaded_file"].value;
if (!filename) {
alert("Please select a file to upload.");
return false;
}
return true;
}
</script>
</head>
<body id="cat_upload" class="cat">
<div id="doc3" class="yui-t2"><div id="bd"><div id="yui-main">
[% IF ( success ) %]
<script type="text/javascript">
function report() {
var doc = opener.document;
var field = doc.getElementById("[% index %]");
field.value = "[% return %]";
}
$(document).ready(function() {
report();
});
</script>
The file [% uploaded_file | html %] has been successfully uploaded.
<p><input type="button" value="close" onclick="window.close();" /></p>
[% ELSE %]
[% IF ( MissingURL ) %]
<p>Error: The OPAC system preference OPACBaseURL is not configured.</p>
<p><input type="button" value="close" onclick="window.close();" /></p>
[% ELSIF ( error ) %]
<p>Error: Failed to upload file. See logs for details.</p>
<p><input type="button" value="close" onclick="window.close();" /></p>
[% ELSE %]
[% IF (error_upload_path_not_configured) %]
<h2>Configuration error</h2>
<p>Configuration variable 'upload_path' is not configured.</p>
<p>Please configure it in your koha-conf.xml</p>
[% ELSE %]
[% IF (error_nothing_selected) %]
<p class="error">Error: You have to choose the file to upload and select where to upload the file.</p>
[% END %]
[% IF (error_no_file_selected) %]
<p class="error">Error: You have to choose the file to upload.</p>
[% END %]
[% IF (error_no_dir_selected) %]
<p class="error">Error: You have to select where to upload the file.</p>
[% END %]
[% IF (dangling) %]
<p class="error">Error: The URL has no file to retrieve.</p>
[% END %]
<h2>Please select the file to upload:</h2>
<form name="UploadForm" method="post" enctype="multipart/form-data" action="/cgi-bin/koha/cataloguing/plugin_launcher.pl" onsubmit="return ValidateForm()">
<input type="hidden" name="from_popup" value="1" />
<input type="hidden" name="plugin_name" value="upload.pl" />
<input type="hidden" name="index" value="[% index %]" />
<div>[% filefield %]</div>
<p/>
<div>
<label for="uploadcategory">Category: </label>
[% IF uploadcategories %]
<select id="uploadcategory" name="uploadcategory">
[% FOREACH cat IN uploadcategories %]
<option value="[% cat.code %]">[% cat.name %]</option>
[% END %]
</select>
[% ELSE %]
<input type="hidden" name="uploadcategory" value="CATALOGUING" />
[% END %]
</div>
<p/>
<fieldset class="action">
<input type="submit" value="Upload">
<input type="button" value="Cancel" onclick="window.close();" />
</fieldset>
</form>
[% END %]
[% END %]
[% END %]
</div></div></div>
</body>
</html>

63
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/upload_delete_file.tt

@ -1,63 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Upload plugin</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="[% interface %]/lib/jquery/jquery.js"></script>
<link rel="stylesheet" type="text/css" href="[% themelang %]/css/staff-global.css" />
<script type="text/javascript">
//<![CDATA[
function goToUploadPage() {
var url = "/cgi-bin/koha/cataloguing/plugin_launcher.pl?"
+ "plugin_name=upload.pl&index=[% index %]";
window.location.href = url;
}
//]]>
</script>
</head>
<body id="cat_upload_delete" class="cat">
[% IF ( success ) %]
<script type="text/javascript">
function report() {
var doc = opener.document;
var field = doc.getElementById("[% index %]");
field.value = "";
}
$(document).ready(function() {
report();
});
</script>
<p>The file has been successfully deleted.</p>
<input type="button" value="Upload a new file" onclick="goToUploadPage();" />
<input type="button" value="Close" onclick="window.close();" />
[% ELSE %]
[% IF ( MissingURL ) %]
<p>Error: The OPAC system preference OPACBaseURL is not configured.</p>
<p><input type="button" value="close" onclick="window.close();" /></p>
[% ELSIF ( error ) %]
<p>Error: Unable to delete the file.</p>
<p><input type="button" value="close" onclick="window.close();" /></p>
[% ELSE %]
<h2>File deletion</h2>
<p>A file has already been uploaded for this field. Do you want to delete it?</p>
<form method="post" action="/cgi-bin/koha/cataloguing/plugin_launcher.pl">
<input type="hidden" name="plugin_name" value="upload.pl" />
<input type="hidden" name="delete" value="delete" />
<input type="hidden" name="id" value="[% id %]" />
<input type="hidden" name="index" value="[% index %]" />
<input type="button" value="Cancel" onclick="javascript:window.close();" />
<input type="submit" value="Delete" />
</form>
[% END %]
[% END %]
</body>
</html>

43
koha-tmpl/intranet-tmpl/prog/en/modules/test/progressbar.tt

@ -1,43 +0,0 @@
[% INCLUDE 'doc-head-open.inc' %]
<title>Koha &rsaquo; Tools &rsaquo; Stage MARC records for import</title>
[% INCLUDE 'doc-head-close.inc' %]
[% INCLUDE 'file-upload.inc' %]
<script type="text/javascript" src="[% themelang %]/js/background-job-progressbar.js"></script>
<style type="text/css">
#uploadpanel,#fileuploadstatus,#fileuploadfailed,#jobpanel,#jobstatus,#jobfailed { display : none; }
#fileuploadstatus,#jobstatus { margin:.4em; }
#fileuploadprogress,#jobprogress{ width:150px;height:10px;border:1px solid #666;background:url('[% interface %]/[% theme %]/img/progress.png') -300px 0px no-repeat; }</style>
<script type="text/javascript">
//<![CDATA[
$(document).ready(function(){
});
function CheckForm(f) {
submitBackgroundJob(f);
return false;
}
//]]>
</script>
</head>
<body id="test_progressbar" class="test">
<div id="doc3" class="yui-t2">
<form method="post" action="progressbarsubmit.pl">
<input type="hidden" name="submitted" id="submitted" value="1" />
<input type="hidden" name="runinbackground" id="runinbackground" value="" />
<input type="hidden" name="completedJobID" id="completedJobID" value="" />
<input type="button" id="mainformsubmit" onclick="return CheckForm(this.form);" value="Start" />
<div id="jobpanel">
<div id="jobstatus">Job progress: <div id="jobprogress"></div> <span id="jobprogresspercent">0</span>%</div>
<div id="jobfailed"></div>
</div>
</form>
</div>
<div>
Completed: <span id="completed">[% completedJobID %] </span>
</div>
</body>

16
t/db_dependent/UploadedFile.t

@ -1,16 +0,0 @@
#!/usr/bin/perl
#
# A simple test for UploadedFile
# only ->new is covered
use strict;
use warnings;
use Test::More tests => 2;
BEGIN {
use_ok('C4::UploadedFile');
}
ok(my $file = C4::UploadedFile->new());

61
t/db_dependent/UploadedFiles.t

@ -1,61 +0,0 @@
#!/usr/bin/perl
use Modern::Perl;
use File::Temp qw/ tempdir /;
use Test::CGI::Multipart;
use Test::More tests => 18;
use Test::Warn;
use t::lib::Mocks;
use C4::Context;
use C4::UploadedFiles;
# This simulates a multipart POST request with a file upload.
my $tcm = new Test::CGI::Multipart;
$tcm->upload_file(
name => 'testfile',
file => 'testfilename.txt',
value => "This is the content of testfilename.txt",
);
my $cgi = $tcm->create_cgi;
my $tempdir = tempdir(CLEANUP => 1);
t::lib::Mocks::mock_config('upload_path', $tempdir);
my $testfilename = $cgi->param('testfile');
my $testfile_fh = $cgi->upload('testfile');
my $id = C4::UploadedFiles::UploadFile($testfilename, '', $testfile_fh->handle);
ok($id, "File uploaded, id is $id");
my $file = C4::UploadedFiles::GetUploadedFile($id);
isa_ok($file, 'HASH', "GetUploadedFiles($id)");
foreach my $key (qw(hashvalue filename filepath dir)) {
ok(exists $file->{$key}, "GetUploadedFile($id)->{$key} exists");
}
ok(-e $file->{filepath}, "File $file->{filepath} exists");
ok(C4::UploadedFiles::DanglingEntry()==-1, "DanglingEntry() returned -1 as expected.");
ok(C4::UploadedFiles::DanglingEntry($id)==0, "DanglingEntry($id) returned 0 as expected.");
unlink ($file->{filepath});
ok(C4::UploadedFiles::DanglingEntry($id)==1, "DanglingEntry($id) returned 1 as expected.");
open my $fh,">",($file->{filepath});
print $fh "";
close $fh;
my $DelResult;
is(C4::UploadedFiles::DelUploadedFile($id),1, "DelUploadedFile($id) returned 1 as expected.");
warning_like { $DelResult=C4::UploadedFiles::DelUploadedFile($id); } qr/file for hash/, "Expected warning for deleting Dangling Entry.";
is($DelResult,-1, "DelUploadedFile($id) returned -1 as expected.");
ok(! -e $file->{filepath}, "File $file->{filepath} does not exist anymore");
my $UploadResult;
warning_like { $UploadResult=C4::UploadedFiles::UploadFile($testfilename,'../',$testfile_fh->handle); } qr/^Filename or dirname contains '..'. Aborting upload/, "Expected warning for bad file upload.";
is($UploadResult, undef, "UploadFile with dir containing \"..\" return undef");
is(C4::UploadedFiles::GetUploadedFile(), undef, 'GetUploadedFile without parameters returns undef');
#trivial test for httpheaders
my @hdrs = C4::UploadedFiles::httpheaders('does_not_matter_yet');
is( @hdrs == 4 && $hdrs[1] =~ /application\/octet-stream/, 1, 'Simple test for httpheaders'); #TODO Will be extended on report 14282

55
test/progressbar.pl

@ -1,55 +0,0 @@
#!/usr/bin/perl
# Script for testing progressbar, part 1 - initial screem
# it is split into two scripts so we can use firebug to debug it
# Koha library project www.koha-community.org
# Licensed under the GPL
# Copyright 2010 Catalyst IT, Ltd
#
# 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 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.
#
# You should have received a copy of the GNU General Public License
# along with Koha; if not, see <http://www.gnu.org/licenses>.
use strict;
use warnings;
# standard or CPAN modules used
use CGI qw ( -utf8 );
use CGI::Cookie;
# Koha modules used
use C4::Context;
use C4::Auth;
use C4::Output;
use C4::BackgroundJob;
my $input = new CGI;
my $dbh = C4::Context->dbh;
$dbh->{AutoCommit} = 0;
my ($template, $loggedinuser, $cookie)
= get_template_and_user({template_name => "test/progressbar.tt",
query => $input,
type => "intranet",
debug => 1,
});
output_html_with_http_headers $input, $cookie, $template->output;
exit 0;

104
test/progressbarsubmit.pl

@ -1,104 +0,0 @@
#!/usr/bin/perl
# Script for testing progressbar, part 2 - json submit handler
# and Z39.50 lookups
# Koha library project www.koha-community.org
# Licensed under the GPL
# Copyright 2010 Catalyst IT, Ltd
#
# 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 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.
#
# You should have received a copy of the GNU General Public License
# along with Koha; if not, see <http://www.gnu.org/licenses>.
use strict;
use warnings;
# standard or CPAN modules used
use CGI qw ( -utf8 );
use CGI::Cookie;
# Koha modules used
use C4::Context;
use C4::Auth;
use C4::Output;
use C4::BackgroundJob;
my $input = new CGI;
my $submitted=$input->param('submitted');
my $runinbackground = $input->param('runinbackground');
my $jobID = $input->param('jobID');
my $completedJobID = $input->param('completedJobID');
my ($template, $loggedinuser, $cookie)
= get_template_and_user({template_name => "test/progressbar.tt",
query => $input,
type => "intranet",
debug => 1,
});
my %cookies = parse CGI::Cookie($cookie);
my $sessionID = $cookies{'CGISESSID'}->value;
if ($completedJobID) {
} elsif ($submitted) {
my $job = undef;
if ($runinbackground) {
my $job_size = 100;
$job = C4::BackgroundJob->new($sessionID, undef, $ENV{'SCRIPT_NAME'}, $job_size);
$jobID = $job->id();
# fork off
if (my $pid = fork) {
# parent
# return job ID as JSON
# prevent parent exiting from
# destroying the kid's database handle
# FIXME: according to DBI doc, this may not work for Oracle
my $reply = CGI->new("");
print $reply->header(-type => 'text/html');
print '{"jobID":"' . $jobID . '"}';
exit 0;
} elsif (defined $pid) {
# if we get here, we're a child that has detached
# itself from Apache
# close STDOUT to signal to Apache that
# we're now running in the background
close STDOUT;
close STDERR;
foreach (1..100) {
$job->progress( $_ );
sleep 1;
}
$job->finish();
} else {
# fork failed, so exit immediately
die "fork failed while attempting to run $ENV{'SCRIPT_NAME'} as a background job";
}
}
} else {
# initial form
die "We should not be here";
}
exit 0;

62
tools/upload-file-progress.pl

@ -1,62 +0,0 @@
#!/usr/bin/perl
# Copyright (C) 2007 LibLime
#
# 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 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.
#
# You should have received a copy of the GNU General Public License
# along with Koha; if not, see <http://www.gnu.org/licenses>.
use strict;
#use warnings; FIXME - Bug 2505
# standard or CPAN modules used
use IO::File;
use CGI qw ( -utf8 );
use CGI::Session;
use C4::Context;
use C4::Auth qw/check_cookie_auth haspermission/;
use C4::UploadedFile;
use CGI::Cookie; # need to check cookies before
# having CGI parse the POST request
my $flags_required = [
{circulate => 'circulate_remaining_permissions'},
{tools => 'stage_marc_import'},
{tools => 'upload_local_cover_images'},
];
my %cookies = fetch CGI::Cookie;
my ($auth_status, $sessionID) = check_cookie_auth($cookies{'CGISESSID'}->value);
my $auth_failure = 1;
foreach my $flag_required ( @{$flags_required} ) {
if ( my $flags = haspermission( C4::Context->config('user'), $flag_required ) ) {
$auth_failure = 0 if $auth_status eq 'ok';
}
}
if ($auth_failure) {
my $reply = CGI->new("");
print $reply->header(-type => 'text/html');
print '{"progress":"0"}';
exit 0;
}
my $reported_progress = C4::UploadedFile->upload_progress($sessionID);
my $reply = CGI->new("");
print $reply->header(-type => 'text/html');
# response will be sent back as JSON
print '{"progress":"' . $reported_progress . '"}';
Loading…
Cancel
Save