I have a simple web form in which I want the user to select a folder to upload (I only care about the contents of the folder). So my attempt to make this work is as followed:
#!/usr/bin/perl
use strict;
use warnings;
use CGI;
use Data::Dumper;
my $q = CGI->new();
print $q->header;
my $upload_folder = '/var/www/html/uploads';
my $name = $q->param('name');
my $email = $q->param('email');
my $comments = $q->param('comments');
my @files = $q->param('multi_files');
foreach my $upload(@files){
print "Upload this please -- $upload<br>";
my $upload_file = $q->upload($upload);
if ($upload_file){
open (OUTFILE,">$upload_folder/$upload") or die $!;;
binmode OUTFILE;
while (<$upload_file>) {
print OUTFILE;
}
}
else {
print "<b>Guess it's broken</b><br/>";
}
}
print "<p><b>Name</b> -- $name<br><b>Email</b> -- $email<br><b>Comments</b> -- $comments<br>";
print $q->end_html;
When I run the script all the parameters are correct, the files print out as expected but when I execute the upload query it returns blank. This is my first attempt at using CGI as I tend to use other languages to process forms.
Here is the code from the form just in case :
<html>
<head>
<title>Stupid Test Site</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js" ></script>
</head>
<body>
<h1>This is a test</h1>
<form action="/cgi-enabled/test.pl" method="POST">
Your Name: <input type="text" name="name"><br>
Email Address: <input type="text" name="email"><br>
Select PO folder: <input name="multi_files" type="file" webkitdirectory multiple /><br/>
Comments:<br>
<textarea name="comments" rows="5" cols="60"></textarea><br>
<input type="submit" value="Send">
</form>
</body>
</html>
I've also posted this question on perlmonks.com as well.
The main issue with my code was it was missing the
enctype="multipart/form-data"
from the form. I made some changes as well. Here is my working code.
#!/usr/bin/perl
use strict;
use warnings;
use CGI;
use Data::Dumper;
use CGI::Carp qw( fatalsToBrowser );
use HTML::Entities qw/encode_entities/;
use File::Copy qw' copy ';
use File::Basename;
my $q = new CGI;
print $q->header;
my $upload_folder = '/var/www/html/uploads';
my $name = $q->param('name');
my $email = $q->param('email');
my $comments = $q->param('comments');
my @files = $q->param('multi_files');
my @io_handles=$q->upload('multi_files');
my %file_hash;
foreach my $item(@files){
next unless $item =~ /.+\/(M.+\.pdf)/;
foreach my $sub_item(@io_handles){
if($item eq $sub_item){
$file_hash{$item} = $sub_item;
}
}
}
chdir $upload_folder or die "Cannot chdir to upload destination directory: $!\n";
print '<ul>';
foreach my $key(keys %file_hash){
my $base = basename($file_hash{$key});#
my $tmpfilename = $q->tmpFileName($file_hash{$key});
my $destFile = File::Spec->catfile($upload_folder,$base);
copy( $tmpfilename, $destFile ) or die "Copy to ($destFile) failed: $!\n";
print '<li>Sucessfully uploaded --- <b>', CGI->escapeHTML(basename($key)), '</b></li>';
}
print '</ul>';
print "<p><b>Name</b> -- $name<br><b>Email</b> -- $email<br><b>Comments</b> -- $comments<br>";
print $q->end_html;
Thanks for the help. (I posted this answer on perlmonks.com as well)