From 0556192e295a66020cb7644c7172b8157d0efc29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nazl=C4=B1=20=C3=87etin?= Date: Wed, 22 May 2019 08:20:36 +0000 Subject: [PATCH] Bug 20208: Custom file upload paths --- Koha/Schema/Result/UploadedFile.pm | 16 ++- Koha/UploadedFile.pm | 5 +- Koha/UploadedFiles.pm | 14 +++ Koha/Uploader.pm | 13 +- installer/data/mysql/atomicupdate/bug_20208.perl | 14 +++ .../intranet-tmpl/prog/en/modules/tools/upload.tt | 133 ++++++++++++++++++++- svc/uploadpath | 108 +++++++++++++++++ t/db_dependent/Upload.t | 119 +++++++++++++++++- tools/upload-file.pl | 4 +- tools/upload.pl | 12 +- 10 files changed, 421 insertions(+), 17 deletions(-) create mode 100644 installer/data/mysql/atomicupdate/bug_20208.perl create mode 100755 svc/uploadpath diff --git a/Koha/Schema/Result/UploadedFile.pm b/Koha/Schema/Result/UploadedFile.pm index 5a4397db69..e7852e4f82 100644 --- a/Koha/Schema/Result/UploadedFile.pm +++ b/Koha/Schema/Result/UploadedFile.pm @@ -35,6 +35,12 @@ __PACKAGE__->table("uploaded_files"); is_nullable: 0 size: 40 +=head2 checksum + + data_type: 'tinyint' + default_value: 1 + is_nullable: 1 + =head2 filename data_type: 'mediumtext' @@ -43,7 +49,7 @@ __PACKAGE__->table("uploaded_files"); =head2 dir data_type: 'mediumtext' - is_nullable: 0 + is_nullable: 1 =head2 filesize @@ -84,10 +90,12 @@ __PACKAGE__->add_columns( { data_type => "integer", is_auto_increment => 1, is_nullable => 0 }, "hashvalue", { data_type => "char", is_nullable => 0, size => 40 }, + "checksum", + { data_type => "tinyint", default_value => 1, is_nullable => 1 }, "filename", { data_type => "mediumtext", is_nullable => 0 }, "dir", - { data_type => "mediumtext", is_nullable => 0 }, + { data_type => "mediumtext", is_nullable => 1 }, "filesize", { data_type => "integer", is_nullable => 1 }, "dtcreated", @@ -120,8 +128,8 @@ __PACKAGE__->add_columns( __PACKAGE__->set_primary_key("id"); -# Created by DBIx::Class::Schema::Loader v0.07042 @ 2018-02-16 17:54:54 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:kJUbIULQMBo3t51HvWC8cg +# Created by DBIx::Class::Schema::Loader v0.07046 @ 2019-05-22 07:44:42 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:M1e7DojIWOcQgijZey9/UQ # You can replace this text with custom code or comments, and it will be preserved on regeneration diff --git a/Koha/UploadedFile.pm b/Koha/UploadedFile.pm index 20fc608c68..ba4e87a131 100644 --- a/Koha/UploadedFile.pm +++ b/Koha/UploadedFile.pm @@ -101,12 +101,13 @@ Returns the fully qualified path name for an uploaded file. sub full_path { my ( $self ) = @_; + my $filename = $self->checksum ? $self->hashvalue ."_". $self->filename : $self->filename; my $path = File::Spec->catfile( $self->permanent ? $self->permanent_directory : C4::Context->temporary_directory, - $self->dir, - $self->hashvalue. '_'. $self->filename, + $self->dir ."/". $self->uploadcategorycode, + $filename, ); return $path; } diff --git a/Koha/UploadedFiles.pm b/Koha/UploadedFiles.pm index b6804f299b..0b0f4767de 100644 --- a/Koha/UploadedFiles.pm +++ b/Koha/UploadedFiles.pm @@ -159,6 +159,8 @@ sub search_term { } return $self->search( [ { filename => { like => '%'.$term.'%' }, %public }, + { dir => { like => '%'.$term.'%' }, %public }, + { uploadcategorycode => { like => '%'.$term.'%' }, %public }, { hashvalue => { like => '%'.$params->{term}.'%' }, %public } ], { order_by => { -asc => 'id' }}, ); @@ -178,6 +180,18 @@ sub getCategories { [ map {{ code => $_->{authorised_value}, name => $_->{lib} }} @$cats ]; } +=head3 getPaths + +getPaths returns a list of upload path codes and names + +=cut + +sub getPaths { + my ( $class ) = @_; + my $paths = C4::Koha::GetAuthorisedValues('UPLOAD_PATH'); + [ map {{ code => $_->{authorised_value}, name => $_->{lib} }} @$paths ]; +} + =head3 _type Returns name of corresponding DBIC resultset diff --git a/Koha/Uploader.pm b/Koha/Uploader.pm index a4baa6a30b..c72729a334 100644 --- a/Koha/Uploader.pm +++ b/Koha/Uploader.pm @@ -69,6 +69,7 @@ use Modern::Perl; use CGI; # no utf8 flag, since it may interfere with binary uploads use Digest::MD5; use Encode; +use File::Path; use File::Spec; use IO::File; use Time::HiRes; @@ -197,6 +198,9 @@ sub _init { $params->{tmp} = $params->{temp} if !exists $params->{tmp}; $self->{temporary} = $params->{tmp}? 1: 0; #default false + $params->{checksum} = 1 if !exists $params->{checksum}; + $self->{checksum} = $params->{checksum}; + $self->{dir} = $params->{dir} || ""; if( $params->{tmp} ) { my $db = C4::Context->config('database'); $self->{category} = KOHA_UPLOAD; @@ -230,7 +234,7 @@ sub _create_file { } else { my $dir = $self->_dir; my $hashval = $self->{files}->{$filename}->{hash}; - my $fn = $hashval. '_'. $filename; + my $fn = $self->{checksum} ? $hashval. '_'. $filename: $filename; # if the file exists and it is registered, then set error # if it exists, but is not in the database, we will overwrite @@ -238,6 +242,7 @@ sub _create_file { Koha::UploadedFiles->search({ hashvalue => $hashval, uploadcategorycode => $self->{category}, + dir => $self->{dir}, })->count ) { $self->{files}->{$filename}->{errcode} = ERR_EXISTS; return; @@ -257,8 +262,9 @@ sub _create_file { sub _dir { my ( $self ) = @_; my $dir = $self->{temporary}? $self->{tmpdir}: $self->{rootdir}; + $dir.= '/'. $self->{dir} if( $self->{dir} ); $dir.= '/'. $self->{category}; - mkdir $dir if !-d $dir; + mkpath $dir if !-d $dir; return $dir; } @@ -285,8 +291,9 @@ sub _register { my ( $self, $filename, $size ) = @_; my $rec = Koha::UploadedFile->new({ hashvalue => $self->{files}->{$filename}->{hash}, + checksum => $self->{checksum}, filename => $filename, - dir => $self->{category}, + dir => $self->{dir}, filesize => $size, owner => $self->{uid}, uploadcategorycode => $self->{category}, diff --git a/installer/data/mysql/atomicupdate/bug_20208.perl b/installer/data/mysql/atomicupdate/bug_20208.perl new file mode 100644 index 0000000000..42237913c8 --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug_20208.perl @@ -0,0 +1,14 @@ +$DBversion = 'XXX'; # will be replaced by the RM +if( CheckVersion( $DBversion ) ) { + unless ( column_exists('uploaded_files', 'checksum') ) { + $dbh->do( q{ ALTER TABLE uploaded_files ADD checksum tinyint(1) DEFAULT 1 AFTER hashvalue }); + $dbh->do( q{ UPDATE uploaded_files SET checksum=1, dir=NULL }); + $dbh->do( q{ ALTER TABLE `uploaded_files` MODIFY COLUMN `dir` mediumtext DEFAULT NULL }); + } + + $dbh->do( q{ INSERT IGNORE INTO authorised_value_categories( category_name ) VALUES ('UPLOAD_PATH') }); + + # Always end with this (adjust the bug info) + SetVersion( $DBversion ); + print "Upgrade to $DBversion done (Bug 20208 - Custom file upload paths)\n"; +} diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload.tt index 6bd010ad6f..839dd5053e 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload.tt @@ -3,6 +3,7 @@ [% USE Koha %] [% SET footerjs = 1 %] [% INCLUDE 'doc-head-open.inc' %] +[% Asset.css("lib/jquery/plugins/treetable/stylesheets/jquery.treetable.css") | $raw %] [% IF plugin %] Upload plugin [% ELSE %] @@ -47,6 +48,26 @@ +
  • + + +
  • + [% IF uploadpaths %] +
  • + + +
  • + [% END %] [% IF uploadcategories %]
  • @@ -149,13 +170,44 @@ [% END %] [% END %] +[% BLOCK upload_paths %] +
    + Search uploads by file tree +
      +
    1. + + + + + + + + + [% FOREACH up IN paths %] + + + + [% END %] + +
      + Expand all + | Collapse all + +
      Path
      [% up.name | html %]
      +
    2. +
    +
    +[% END %] + [% BLOCK table_results %] + + [% IF !plugin %][% END %] [% IF !plugin %][% END %] @@ -167,7 +219,9 @@ + + [% IF !plugin %] @@ -222,6 +276,7 @@ [% IF mode == 'new' || mode == 'deleted' %] [% PROCESS form_new %] [% PROCESS form_search %] + [% PROCESS upload_paths %] [% PROCESS closer %] [% ELSIF mode == 'report' %] [% IF uploads %] @@ -256,6 +311,7 @@ [% Asset.js("js/tools-menu.js") | $raw %] [% INCLUDE 'datatables.inc' %] [% Asset.js("js/file-upload.js") | $raw %] + [% Asset.js("lib/jquery/plugins/treetable/jquery.treetable.js") | $raw %]
    Filename SizeFile checksum HashvalueUpload path CategoryPublicTemporary
    [% record.filename | html %] [% record.filesize | html %][% IF record.checksum %] Yes [% ELSE %] No [% END %] [% record.hashvalue | html %][% record.dir | html %] [% record.uploadcategorycode | html %][% IF record.public %]Yes[% ELSE %]No[% END %]