Bug 11533: (regression test) QP breaks authority search
[koha.git] / C4 / UploadedFile.pm
blobb7bcd37386863c532eeb8d09ff467a807cdbec7d
1 package C4::UploadedFile;
3 # Copyright (C) 2007 LibLime
4 # Galen Charlton <galen.charlton@liblime.com>
6 # This file is part of Koha.
8 # Koha is free software; you can redistribute it and/or modify it under the
9 # terms of the GNU General Public License as published by the Free Software
10 # Foundation; either version 2 of the License, or (at your option) any later
11 # version.
13 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
14 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License along
18 # with Koha; if not, write to the Free Software Foundation, Inc.,
19 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 use strict;
22 #use warnings; FIXME - Bug 2505
23 use C4::Context;
24 use C4::Auth qw/get_session/;
25 use IO::File;
27 use vars qw($VERSION);
29 BEGIN {
30 # set the version for version checking
31 $VERSION = 3.07.00.049;
34 =head1 NAME
36 C4::UploadedFile - manage files uploaded by the user
37 for later processing.
39 =head1 SYNOPSIS
41 # create and store data
42 my $uploaded_file = C4::UploadedFile->new($sessionID);
43 my $fileID = $uploaded_file->id();
44 $uploaded_file->name('c:\temp\file.mrc');
45 $uploaded_file->max_size(1024);
46 while ($have_more_data) {
47 $uploaded_file->stash($data, $bytes_read);
49 $uploaded_file->done();
51 # check status of current file upload
52 my $progress = C4::UploadedFile->upload_progress($sessionID);
54 # get file handle for reading uploaded file
55 my $uploaded_file = C4::UploadedFile->fetch($fileID);
56 my $fh = $uploaded_file->fh();
59 Stores files uploaded by the user from their web browser. The
60 uploaded files are temporary and at present are not guaranteed
61 to survive beyond the life of the user's session.
63 This module allows for tracking the progress of the file
64 currently being uploaded.
66 TODO: implement secure persistant storage of uploaded files.
68 =cut
70 =head1 METHODS
72 =cut
74 =head2 new
76 my $uploaded_file = C4::UploadedFile->new($sessionID);
78 Creates a new object to represent the uploaded file. Requires
79 the current session ID.
81 =cut
83 sub new {
84 my $class = shift;
85 my $sessionID = shift;
87 my $self = {};
89 $self->{'sessionID'} = $sessionID;
90 $self->{'fileID'} = Digest::MD5::md5_hex(Digest::MD5::md5_hex(time().{}.rand().{}.$$));
91 # FIXME - make staging area configurable
92 my $TEMPROOT = "/tmp";
93 my $OUTPUTDIR = "$TEMPROOT/$sessionID";
94 mkdir $OUTPUTDIR;
95 my $tmp_file_name = "$OUTPUTDIR/$self->{'fileID'}";
96 my $fh = new IO::File $tmp_file_name, "w";
97 unless (defined $fh) {
98 return undef;
100 $fh->binmode(); # Windows compatibility
101 $self->{'fh'} = $fh;
102 $self->{'tmp_file_name'} = $tmp_file_name;
103 $self->{'max_size'} = 0;
104 $self->{'progress'} = 0;
105 $self->{'name'} = '';
107 bless $self, $class;
108 $self->_serialize();
110 my $session = get_session($sessionID);
111 $session->param('current_upload', $self->{'fileID'});
112 $session->flush();
114 return $self;
118 sub _serialize {
119 my $self = shift;
121 my $prefix = "upload_" . $self->{'fileID'};
122 my $session = get_session($self->{'sessionID'});
124 # temporarily take file handle out of structure
125 my $fh = $self->{'fh'};
126 delete $self->{'fh'};
127 $session->param($prefix, $self);
128 $session->flush();
129 $self->{'fh'} =$fh;
132 =head2 id
134 my $fileID = $uploaded_file->id();
136 =cut
138 sub id {
139 my $self = shift;
140 return $self->{'fileID'};
143 =head2 name
145 my $name = $uploaded_file->name();
146 $uploaded_file->name($name);
148 Accessor method for the name by which the file is to be known.
150 =cut
152 sub name {
153 my $self = shift;
154 if (@_) {
155 $self->{'name'} = shift;
156 $self->_serialize();
157 } else {
158 return $self->{'name'};
162 =head2 filename
164 my $filename = $uploaded_file->filename();
166 Accessor method for the name by which the file is to be known.
168 =cut
170 sub filename {
171 my $self = shift;
172 if (@_) {
173 $self->{'tmp_file_name'} = shift;
174 $self->_serialize();
175 } else {
176 return $self->{'tmp_file_name'};
180 =head2 max_size
182 my $max_size = $uploaded_file->max_size();
183 $uploaded_file->max_size($max_size);
185 Accessor method for the maximum size of the uploaded file.
187 =cut
189 sub max_size {
190 my $self = shift;
191 @_ ? $self->{'max_size'} = shift : $self->{'max_size'};
194 =head2 stash
196 $uploaded_file->stash($dataref, $bytes_read);
198 Write C<$dataref> to the temporary file. C<$bytes_read> represents
199 the number of bytes (out of C<$max_size>) transmitted so far.
201 =cut
203 sub stash {
204 my $self = shift;
205 my $dataref = shift;
206 my $bytes_read = shift;
208 my $fh = $self->{'fh'};
209 print $fh $$dataref;
211 my $percentage = int(($bytes_read / $self->{'max_size'}) * 100);
212 if ($percentage > $self->{'progress'}) {
213 $self->{'progress'} = $percentage;
214 $self->_serialize();
218 =head2 done
220 $uploaded_file->done();
222 Indicates that all of the bytes have been uploaded.
224 =cut
226 sub done {
227 my $self = shift;
228 $self->{'progress'} = 'done';
229 $self->{'fh'}->close();
230 $self->_serialize();
233 =head2 upload_progress
235 my $upload_progress = C4::UploadFile->upload_progress($sessionID);
237 Returns (as an integer from 0 to 100) the percentage
238 progress of the current file upload.
240 =cut
242 sub upload_progress {
243 my ($class, $sessionID) = shift;
245 my $session = get_session($sessionID);
247 my $fileID = $session->param('current_upload');
249 my $reported_progress = 0;
250 if (defined $fileID and $fileID ne "") {
251 my $file = C4::UploadedFile->fetch($sessionID, $fileID);
252 my $progress = $file->{'progress'};
253 if (defined $progress) {
254 if ($progress eq "done") {
255 $reported_progress = 100;
256 } else {
257 $reported_progress = $progress;
261 return $reported_progress;
264 =head2 fetch
266 my $uploaded_file = C4::UploadedFile->fetch($sessionID, $fileID);
268 Retrieves an uploaded file object from the current session.
270 =cut
272 sub fetch {
273 my $class = shift;
274 my $sessionID = shift;
275 my $fileID = shift;
277 my $session = get_session($sessionID);
278 my $prefix = "upload_$fileID";
279 my $self = $session->param($prefix);
280 my $fh = new IO::File $self->{'tmp_file_name'}, "r";
281 $self->{'fh'} = $fh;
283 bless $self, $class;
284 return $self;
287 =head2 fh
289 my $fh = $uploaded_file->fh();
291 Returns an IO::File handle to read the uploaded file.
293 =cut
295 sub fh {
296 my $self = shift;
297 return $self->{'fh'};
301 __END__
303 =head1 AUTHOR
305 Koha Development Team <http://koha-community.org/>
307 Galen Charlton <galen.charlton@liblime.com>
309 =cut