diff --git a/share/html/Ticket/AttachmentZip/dhandler b/share/html/Ticket/AttachmentZip/dhandler
new file mode 100644
index 0000000..4a1975b
--- /dev/null
+++ b/share/html/Ticket/AttachmentZip/dhandler
@@ -0,0 +1,67 @@
+<%init>
+# grab ticket number from URL
+my ($ticket_no) = ($m->dhandler_arg =~ m/^(\d+)\// );
+
+# create ticket object
+my $Ticket = LoadTicket($ticket_no);
+
+# collect individual attached files in a hash of arrays
+my $AttachObj = $m->comp('/Ticket/Elements/FindAttachments',
+ Ticket => $Ticket);
+my %attached_files;
+while (my $attached_name = $AttachObj->Next() ) {
+ next unless ($attached_name->Filename());
+ push( @{ $attached_files{ $attached_name->Filename } }, $attached_name );
+}
+
+my $tempdir = File::Temp->newdir( CLEANUP => 1 );
+my $zip = Archive::Zip->new();
+my ($zip_fh,$zip_name) = Archive::Zip::tempFile($tempdir);
+
+%init>
+<%perl>
+foreach my $name (keys %attached_files) {
+ foreach my $revision (@{$attached_files{$name}}) {
+ # temporary on-disk storage of files for zip
+ my $tempfile_fh = File::Temp->new(DIR => $tempdir, SUFFIX => ".tmp");
+
+ # these objects go out of scope before the zipfile is written to disk,
+ # which would cause them to be deleted too early. Let the tempdir
+ # CLEANUP take care of them instead.
+ $tempfile_fh->unlink_on_destroy(0);
+ my $tempfile_name = $tempfile_fh->filename;
+ print $tempfile_fh $revision->Content;
+
+ # need to close the FH so that perl flushes output
+ close $tempfile_fh;
+
+ # add tempfile to zip as the original name from the attachment, with revision ID
+ my $member = $zip->addFile($tempfile_name,sprintf('ticket_%d/%d_%s',$Ticket->Id,$revision->Id,$revision->Filename));
+ $member->desiredCompressionMethod( COMPRESSION_DEFLATED );
+ }
+}
+
+if ( $zip->writeToFileHandle($zip_fh) == AZ_OK) {
+ # need to close the FH so that perl flushes output
+ close $zip_fh;
+ $r->content_type( "application/zip" );
+ $m->clear_buffer();
+ $m->out($m->file($zip_name));
+ $m->abort;
+} else {
+ close $zip_fh;
+ $RT::Logger->error("write error writing zip to $zip_name");
+ $r->content_type( "text/plain" );
+ $m->clear_buffer();
+ $m->out("Sorry, error creating zip. Please contact your system administrator.");
+ $m->abort;
+}
+undef $tempdir;
+%perl>
+<%attr>
+AutoFlush => 0
+%attr>
+<%once>
+use Archive::Zip qw( :ERROR_CODES :CONSTANTS);
+use File::Temp qw( tempfile tempdir);
+%once>
diff --git a/share/html/Ticket/Elements/ShowAttachments b/share/html/Ticket/Elements/ShowAttachments
index 1f476be..083f3a8 100755
--- a/share/html/Ticket/Elements/ShowAttachments
+++ b/share/html/Ticket/Elements/ShowAttachments
@@ -51,6 +51,7 @@
class => 'ticket-info-attachments',
color => "#336699" &>
+Download all as zip
% foreach my $key (keys %documents) {
<%$key%>