View | Details | Raw Unified | Return to bug 20208
Collapse All | Expand All

(-)a/Koha/Schema/Result/UploadedFile.pm (-4 / +12 lines)
Lines 35-40 __PACKAGE__->table("uploaded_files"); Link Here
35
  is_nullable: 0
35
  is_nullable: 0
36
  size: 40
36
  size: 40
37
37
38
=head2 checksum
39
40
  data_type: 'tinyint'
41
  default_value: 1
42
  is_nullable: 1
43
38
=head2 filename
44
=head2 filename
39
45
40
  data_type: 'mediumtext'
46
  data_type: 'mediumtext'
Lines 43-49 __PACKAGE__->table("uploaded_files"); Link Here
43
=head2 dir
49
=head2 dir
44
50
45
  data_type: 'mediumtext'
51
  data_type: 'mediumtext'
46
  is_nullable: 0
52
  is_nullable: 1
47
53
48
=head2 filesize
54
=head2 filesize
49
55
Lines 84-93 __PACKAGE__->add_columns( Link Here
84
  { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
90
  { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
85
  "hashvalue",
91
  "hashvalue",
86
  { data_type => "char", is_nullable => 0, size => 40 },
92
  { data_type => "char", is_nullable => 0, size => 40 },
93
  "checksum",
94
  { data_type => "tinyint", default_value => 1, is_nullable => 1 },
87
  "filename",
95
  "filename",
88
  { data_type => "mediumtext", is_nullable => 0 },
96
  { data_type => "mediumtext", is_nullable => 0 },
89
  "dir",
97
  "dir",
90
  { data_type => "mediumtext", is_nullable => 0 },
98
  { data_type => "mediumtext", is_nullable => 1 },
91
  "filesize",
99
  "filesize",
92
  { data_type => "integer", is_nullable => 1 },
100
  { data_type => "integer", is_nullable => 1 },
93
  "dtcreated",
101
  "dtcreated",
Lines 120-127 __PACKAGE__->add_columns( Link Here
120
__PACKAGE__->set_primary_key("id");
128
__PACKAGE__->set_primary_key("id");
121
129
122
130
123
# Created by DBIx::Class::Schema::Loader v0.07042 @ 2018-02-16 17:54:54
131
# Created by DBIx::Class::Schema::Loader v0.07046 @ 2019-05-22 07:44:42
124
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:kJUbIULQMBo3t51HvWC8cg
132
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:M1e7DojIWOcQgijZey9/UQ
125
133
126
134
127
# You can replace this text with custom code or comments, and it will be preserved on regeneration
135
# You can replace this text with custom code or comments, and it will be preserved on regeneration
(-)a/Koha/UploadedFile.pm (-2 / +3 lines)
Lines 101-112 Returns the fully qualified path name for an uploaded file. Link Here
101
101
102
sub full_path {
102
sub full_path {
103
    my ( $self ) = @_;
103
    my ( $self ) = @_;
104
    my $filename = $self->checksum ? $self->hashvalue ."_". $self->filename : $self->filename;
104
    my $path = File::Spec->catfile(
105
    my $path = File::Spec->catfile(
105
        $self->permanent
106
        $self->permanent
106
            ? $self->permanent_directory
107
            ? $self->permanent_directory
107
            : C4::Context->temporary_directory,
108
            : C4::Context->temporary_directory,
108
        $self->dir,
109
        $self->dir ."/". $self->uploadcategorycode,
109
        $self->hashvalue. '_'. $self->filename,
110
        $filename,
110
    );
111
    );
111
    return $path;
112
    return $path;
112
}
113
}
(-)a/Koha/UploadedFiles.pm (+14 lines)
Lines 159-164 sub search_term { Link Here
159
    }
159
    }
160
    return $self->search(
160
    return $self->search(
161
        [ { filename => { like => '%'.$term.'%' }, %public },
161
        [ { filename => { like => '%'.$term.'%' }, %public },
162
          { dir => { like => '%'.$term.'%' }, %public },
163
          { uploadcategorycode => { like => '%'.$term.'%' }, %public },
162
          { hashvalue => { like => '%'.$params->{term}.'%' }, %public } ],
164
          { hashvalue => { like => '%'.$params->{term}.'%' }, %public } ],
163
        { order_by => { -asc => 'id' }},
165
        { order_by => { -asc => 'id' }},
164
    );
166
    );
Lines 178-183 sub getCategories { Link Here
178
    [ map {{ code => $_->{authorised_value}, name => $_->{lib} }} @$cats ];
180
    [ map {{ code => $_->{authorised_value}, name => $_->{lib} }} @$cats ];
179
}
181
}
180
182
183
=head3 getPaths
184
185
getPaths returns a list of upload path codes and names
186
187
=cut
188
189
sub getPaths {
190
    my ( $class ) = @_;
191
    my $paths = C4::Koha::GetAuthorisedValues('UPLOAD_PATH');
192
    [ map {{ code => $_->{authorised_value}, name => $_->{lib} }} @$paths ];
193
}
194
181
=head3 _type
195
=head3 _type
182
196
183
Returns name of corresponding DBIC resultset
197
Returns name of corresponding DBIC resultset
(-)a/Koha/Uploader.pm (-3 / +10 lines)
Lines 69-74 use Modern::Perl; Link Here
69
use CGI; # no utf8 flag, since it may interfere with binary uploads
69
use CGI; # no utf8 flag, since it may interfere with binary uploads
70
use Digest::MD5;
70
use Digest::MD5;
71
use Encode;
71
use Encode;
72
use File::Path;
72
use File::Spec;
73
use File::Spec;
73
use IO::File;
74
use IO::File;
74
use Time::HiRes;
75
use Time::HiRes;
Lines 197-202 sub _init { Link Here
197
198
198
    $params->{tmp} = $params->{temp} if !exists $params->{tmp};
199
    $params->{tmp} = $params->{temp} if !exists $params->{tmp};
199
    $self->{temporary} = $params->{tmp}? 1: 0; #default false
200
    $self->{temporary} = $params->{tmp}? 1: 0; #default false
201
    $params->{checksum} = 1 if !exists $params->{checksum};
202
    $self->{checksum} = $params->{checksum};
203
    $self->{dir} = $params->{dir} || "";
200
    if( $params->{tmp} ) {
204
    if( $params->{tmp} ) {
201
        my $db =  C4::Context->config('database');
205
        my $db =  C4::Context->config('database');
202
        $self->{category} = KOHA_UPLOAD;
206
        $self->{category} = KOHA_UPLOAD;
Lines 230-236 sub _create_file { Link Here
230
    } else {
234
    } else {
231
        my $dir = $self->_dir;
235
        my $dir = $self->_dir;
232
        my $hashval = $self->{files}->{$filename}->{hash};
236
        my $hashval = $self->{files}->{$filename}->{hash};
233
        my $fn = $hashval. '_'. $filename;
237
        my $fn = $self->{checksum} ? $hashval. '_'. $filename: $filename;
234
238
235
        # if the file exists and it is registered, then set error
239
        # if the file exists and it is registered, then set error
236
        # if it exists, but is not in the database, we will overwrite
240
        # if it exists, but is not in the database, we will overwrite
Lines 238-243 sub _create_file { Link Here
238
        Koha::UploadedFiles->search({
242
        Koha::UploadedFiles->search({
239
            hashvalue          => $hashval,
243
            hashvalue          => $hashval,
240
            uploadcategorycode => $self->{category},
244
            uploadcategorycode => $self->{category},
245
            dir                => $self->{dir},
241
        })->count ) {
246
        })->count ) {
242
            $self->{files}->{$filename}->{errcode} = ERR_EXISTS;
247
            $self->{files}->{$filename}->{errcode} = ERR_EXISTS;
243
            return;
248
            return;
Lines 257-264 sub _create_file { Link Here
257
sub _dir {
262
sub _dir {
258
    my ( $self ) = @_;
263
    my ( $self ) = @_;
259
    my $dir = $self->{temporary}? $self->{tmpdir}: $self->{rootdir};
264
    my $dir = $self->{temporary}? $self->{tmpdir}: $self->{rootdir};
265
    $dir.= '/'. $self->{dir} if( $self->{dir} );
260
    $dir.= '/'. $self->{category};
266
    $dir.= '/'. $self->{category};
261
    mkdir $dir if !-d $dir;
267
    mkpath $dir if !-d $dir;
262
    return $dir;
268
    return $dir;
263
}
269
}
264
270
Lines 285-292 sub _register { Link Here
285
    my ( $self, $filename, $size ) = @_;
291
    my ( $self, $filename, $size ) = @_;
286
    my $rec = Koha::UploadedFile->new({
292
    my $rec = Koha::UploadedFile->new({
287
        hashvalue => $self->{files}->{$filename}->{hash},
293
        hashvalue => $self->{files}->{$filename}->{hash},
294
        checksum  => $self->{checksum},
288
        filename  => $filename,
295
        filename  => $filename,
289
        dir       => $self->{category},
296
        dir       => $self->{dir},
290
        filesize  => $size,
297
        filesize  => $size,
291
        owner     => $self->{uid},
298
        owner     => $self->{uid},
292
        uploadcategorycode => $self->{category},
299
        uploadcategorycode => $self->{category},
(-)a/installer/data/mysql/atomicupdate/bug_20208.perl (+14 lines)
Line 0 Link Here
1
$DBversion = 'XXX'; # will be replaced by the RM
2
if( CheckVersion( $DBversion ) ) {
3
    unless ( column_exists('uploaded_files', 'checksum') ) {
4
        $dbh->do( q{ ALTER TABLE uploaded_files ADD checksum tinyint(1) DEFAULT 1 AFTER hashvalue });
5
        $dbh->do( q{ UPDATE uploaded_files SET checksum=1, dir=NULL });
6
        $dbh->do( q{ ALTER TABLE `uploaded_files` MODIFY COLUMN `dir` mediumtext DEFAULT NULL });
7
    }
8
9
    $dbh->do( q{ INSERT IGNORE INTO authorised_value_categories( category_name ) VALUES ('UPLOAD_PATH') });
10
11
    # Always end with this (adjust the bug info)
12
    SetVersion( $DBversion );
13
    print "Upgrade to $DBversion done (Bug 20208 - Custom file upload paths)\n";
14
}
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload.tt (-4 / +129 lines)
Lines 3-8 Link Here
3
[% USE Koha %]
3
[% USE Koha %]
4
[% SET footerjs = 1 %]
4
[% SET footerjs = 1 %]
5
[% INCLUDE 'doc-head-open.inc' %]
5
[% INCLUDE 'doc-head-open.inc' %]
6
[% Asset.css("lib/jquery/plugins/treetable/stylesheets/jquery.treetable.css") | $raw %]
6
[% IF plugin %]
7
[% IF plugin %]
7
    <title>Upload plugin</title>
8
    <title>Upload plugin</title>
8
[% ELSE %]
9
[% ELSE %]
Lines 47-52 Link Here
47
            <input type="file" id="fileToUpload" name="fileToUpload" multiple/>
48
            <input type="file" id="fileToUpload" name="fileToUpload" multiple/>
48
        </div>
49
        </div>
49
        </li>
50
        </li>
51
        <li>
52
            <label for="fileChecksum">Add file checksum to the uploaded filename: </label>
53
            <label class="radio">
54
                Yes <input type="radio" name="checksum" id="checksum" value="1" checked />
55
                No <input type="radio" name="checksum" id="checksum" value="0" />
56
            </label>
57
        </li>
58
        [% IF uploadpaths %]
59
            <li>
60
                <label for="uploadpath">Upload Path: </label>
61
                <select id="uploadpath" name="uploadpath">
62
                    [% IF !plugin %]
63
                        <option value=""></option>
64
                    [% END %]
65
                    [% FOREACH dir IN uploadpaths %]
66
                        <option value="[% dir.code | html %]">[% dir.name | html %]</option>
67
                    [% END %]
68
                </select>
69
            </li>
70
        [% END %]
50
        [% IF uploadcategories %]
71
        [% IF uploadcategories %]
51
            <li>
72
            <li>
52
                <label for="uploadcategory">Category: </label>
73
                <label for="uploadcategory">Category: </label>
Lines 149-161 Link Here
149
    [% END %]
170
    [% END %]
150
[% END %]
171
[% END %]
151
172
173
[% BLOCK upload_paths %]
174
        <fieldset class="rows">
175
        <legend>Search uploads by file tree</legend>
176
        <ol>
177
        <li>
178
    <table id="uploadpathtable">
179
        <caption>
180
            <span class="actions"><a href="#" id="expand_all">Expand all</a>
181
                | <a href="#" id="collapse_all">Collapse all</a>
182
            </span>
183
        </caption>
184
        <thead>
185
            <tr>
186
                <th>Path</th>
187
            </tr>
188
        </thead>
189
        <tbody>
190
            [% FOREACH up IN paths %]
191
                <tr data-pathname="[% up.pathname | $raw %]" data-tt-id="[% loop.count | html %]" data-tt-branch="true">
192
                    <td>[% up.name | html %]</td>
193
                </tr>
194
            [% END %]
195
        </tbody>
196
    </table>
197
        </li>
198
        </ol>
199
        </fieldset>
200
[% END %]
201
152
[% BLOCK table_results %]
202
[% BLOCK table_results %]
153
    <table id="uploadresults">
203
    <table id="uploadresults">
154
    <thead>
204
    <thead>
155
    <tr>
205
    <tr>
156
        <th>Filename</th>
206
        <th>Filename</th>
157
        <th>Size</th>
207
        <th>Size</th>
208
        <th>File checksum</th>
158
        <th>Hashvalue</th>
209
        <th>Hashvalue</th>
210
        <th>Upload path</th>
159
        <th>Category</th>
211
        <th>Category</th>
160
        [% IF !plugin %]<th>Public</th>[% END %]
212
        [% IF !plugin %]<th>Public</th>[% END %]
161
        [% IF !plugin %]<th>Temporary</th>[% END %]
213
        [% IF !plugin %]<th>Temporary</th>[% END %]
Lines 167-173 Link Here
167
    <tr>
219
    <tr>
168
        <td>[% record.filename | html %]</td>
220
        <td>[% record.filename | html %]</td>
169
        <td>[% record.filesize | html %]</td>
221
        <td>[% record.filesize | html %]</td>
222
        <td>[% IF record.checksum %] Yes [% ELSE %] No [% END %]</td>
170
        <td>[% record.hashvalue | html %]</td>
223
        <td>[% record.hashvalue | html %]</td>
224
        <td>[% record.dir | html %]</td>
171
        <td>[% record.uploadcategorycode | html %]</td>
225
        <td>[% record.uploadcategorycode | html %]</td>
172
        [% IF !plugin %]
226
        [% IF !plugin %]
173
            <td>[% IF record.public %]Yes[% ELSE %]No[% END %]</td>
227
            <td>[% IF record.public %]Yes[% ELSE %]No[% END %]</td>
Lines 222-227 Link Here
222
[% IF mode == 'new' || mode == 'deleted' %]
276
[% IF mode == 'new' || mode == 'deleted' %]
223
    [% PROCESS form_new %]
277
    [% PROCESS form_new %]
224
    [% PROCESS form_search %]
278
    [% PROCESS form_search %]
279
    [% PROCESS upload_paths %]
225
    [% PROCESS closer %]
280
    [% PROCESS closer %]
226
[% ELSIF mode == 'report' %]
281
[% ELSIF mode == 'report' %]
227
    [% IF uploads %]
282
    [% IF uploads %]
Lines 256-261 Link Here
256
    [% Asset.js("js/tools-menu.js") | $raw %]
311
    [% Asset.js("js/tools-menu.js") | $raw %]
257
    [% INCLUDE 'datatables.inc' %]
312
    [% INCLUDE 'datatables.inc' %]
258
    [% Asset.js("js/file-upload.js") | $raw %]
313
    [% Asset.js("js/file-upload.js") | $raw %]
314
    [% Asset.js("lib/jquery/plugins/treetable/jquery.treetable.js") | $raw %]
259
    <script>
315
    <script>
260
        function StartUpload() {
316
        function StartUpload() {
261
            if( $('#fileToUpload').prop('files').length == 0 ) return;
317
            if( $('#fileToUpload').prop('files').length == 0 ) return;
Lines 270-285 Link Here
270
            $("#searchfile").hide();
326
            $("#searchfile").hide();
271
            $("#lastbreadcrumb").text( _("Add a new upload") );
327
            $("#lastbreadcrumb").text( _("Add a new upload") );
272
328
273
            var cat, xtra='';
329
            var dir, cat, xtra='';
274
            if( $("#uploadcategory").val() )
330
            if( $("#uploadcategory").val() )
275
                cat = encodeURIComponent( $("#uploadcategory").val() );
331
                cat = encodeURIComponent( $("#uploadcategory").val() );
276
            if( cat ) xtra= 'category=' + cat + '&';
332
            if( cat ) xtra= 'category=' + cat + '&';
277
            [% IF plugin %]
333
            [% IF plugin %]
278
                xtra = xtra + 'public=1&temp=0';
334
                xtra = xtra + 'public=1&temp=0&';
279
            [% ELSE %]
335
            [% ELSE %]
280
                if( !cat ) xtra = 'temp=1&';
336
                if( !cat ) xtra = 'temp=1&';
281
                if( $('#public').prop('checked') ) xtra = xtra + 'public=1';
337
                if( $('#public').prop('checked') ) xtra = xtra + 'public=1&';
282
            [% END %]
338
            [% END %]
339
            if( $("#uploadpath").val() )
340
                dir = encodeURIComponent( $("#uploadpath").val() );
341
            if( dir ) xtra= xtra + 'dir=' + dir + '&';
342
            xtra = xtra + 'checksum=' + $('#checksum:checked').val();
283
            xhr= AjaxUpload( $('#fileToUpload'), $('#fileuploadprogress'), xtra, cbUpload );
343
            xhr= AjaxUpload( $('#fileToUpload'), $('#fileuploadprogress'), xtra, cbUpload );
284
        }
344
        }
285
        function CancelUpload() {
345
        function CancelUpload() {
Lines 381-387 Link Here
381
            [% END %]
441
            [% END %]
382
            window.close();
442
            window.close();
383
        }
443
        }
444
384
        $(document).ready(function() {
445
        $(document).ready(function() {
446
            var oTable = $("#uploadpathtable");
447
448
            $(oTable).treetable({
449
                expandable: true,
450
                onNodeCollapse: function() {
451
                    var node = this;
452
                    oTable.treetable("unloadBranch", node);
453
                },
454
                onNodeExpand: function() {
455
                    var node = this;
456
                    var id = node.id;
457
                    var pathname = node.row.data('pathname');
458
                    $.ajax({
459
                        type: 'POST',
460
                        url: "/cgi-bin/koha/svc/uploadpath",
461
                        data: {
462
                            pathname: pathname ,
463
                            [% IF plugin %] public: 1[% END %]
464
                        },
465
                        success: function(data) {
466
                            var childNodes = data.success;
467
                            if(childNodes) {
468
                                var parentNode = $("#uploadpathtable").treetable("node", id);
469
                                for (var i = 0; i < childNodes.length; i++) {
470
                                    var node = childNodes[i];
471
                                    var nodeToAdd = $("#uploadpathtable").treetable("node",id+"."+node['id']);
472
                                    // check if node already exists. If not add row to parent node
473
                                    if (!nodeToAdd) {
474
                                        var row ='<tr data-pathname="' + node['pathname'] + '" data-tt-id="' + id + '.' + ( i+1) + '" data-tt-parent-id="' + id + '" ';
475
                                        var search = '';
476
                                        if (node['type'] == 'branch' ) {
477
                                            row += ' data-tt-branch="true" ';
478
                                            search = "<a href='/cgi-bin/koha/tools/upload.pl?op=search&";
479
                                            [% IF plugin %]
480
                                                     search += "plugin=1&";
481
                                            [% END %]
482
                                            search += "term="+ node['path'] + "'>" + node['path'] + "</a>";
483
                                        }else {
484
                                            [% IF plugin %]
485
                                                     search += ' <button class="btn btn-default btn-xs" onclick="Choose(\'' + node['hashvalue'] + '\');"><i class="fa fa-plus"></i> Choose</button>';
486
                                            [% END %]
487
                                            search += ' <button class="btn btn-default btn-xs " onclick="SubmitMe( \'download\', ' + node['fileID'] + ');"><i class="fa fa-download"></i> Download</button>';
488
                                            search += " " + node['path'];
489
                                        }
490
                                        row += ' >';
491
                                        row += "<td>" + search + "</td>";
492
                                        row +="</tr>";
493
                                        $("#uploadpathtable").treetable("loadBranch", parentNode, row);
494
                                    }
495
                                }
496
                            }
497
                        },
498
                    });
499
                }
500
            });
501
            $("#expand_all").click(function(e){
502
                e.preventDefault();
503
                $(oTable).treetable('expandAll');
504
            });
505
            $("#collapse_all").click(function(e){
506
                e.preventDefault();
507
                $(oTable).treetable('collapseAll');
508
            });
509
385
            $("#uploadresults").dataTable($.extend(true, {}, dataTablesDefaults, {
510
            $("#uploadresults").dataTable($.extend(true, {}, dataTablesDefaults, {
386
                "aoColumnDefs": [
511
                "aoColumnDefs": [
387
                    { 'bSortable': false, 'aTargets': [ 'nosort' ] }
512
                    { 'bSortable': false, 'aTargets': [ 'nosort' ] }
Lines 389-395 Link Here
389
                "sPaginationType": "four_button"
514
                "sPaginationType": "four_button"
390
            }));
515
            }));
391
            [% IF msg %]
516
            [% IF msg %]
392
                ShowAlerts( [% msg | html %] );
517
                ShowAlerts( [% msg | $raw %] );
393
            [% END %]
518
            [% END %]
394
            $("#fileuploadcancel").hide();
519
            $("#fileuploadcancel").hide();
395
            $("#public_cb").click(function() {
520
            $("#public_cb").click(function() {
(-)a/svc/uploadpath (+108 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Copyright 2019 Devinim
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 3 of the License, or (at your option) any later
10
# version.
11
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License along
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
18
19
use Modern::Perl;
20
21
use CGI;
22
use JSON qw(to_json);
23
24
use C4::Context;
25
use C4::Auth qw(check_cookie_auth);
26
use Koha::UploadedFiles;
27
28
29
my $input = new CGI;
30
31
my ( $auth_status, $sessionID ) =
32
  check_cookie_auth( $input->cookie('CGISESSID'), { tools => 'upload_general_files' } );
33
34
if ( $auth_status ne "ok" ) {
35
    print $input->header(-type => 'text/plain', -status => '403 Forbidden');
36
    exit 0;
37
}
38
39
my $fullDir = $input->param('pathname');
40
my $public  = $input->param('public');
41
my $json;
42
43
exit if ! -e $fullDir;
44
45
opendir(BIN, $fullDir) or die "Can't open $fullDir: $!";
46
my @files;
47
my $total = 0;
48
my $temporary_directory = C4::Context::temporary_directory;
49
my $permanent_directory = Koha::UploadedFile->permanent_directory;
50
while( defined (my $file = readdir BIN) ) {
51
    next if $file eq '.' or $file eq '..' or $file eq "cgisess_koha_kohadev";
52
53
    $total++;
54
    my %hash = (
55
        id          => $total,
56
        pathname    => "$fullDir/$file",
57
        path        => $file,
58
    );
59
60
    if (-d "$fullDir/$file") {
61
        $hash{'type'} = "branch";
62
    }else{
63
        my ($category, $permanent) ;
64
        my $path = $fullDir;
65
        if ($path =~ m/^$temporary_directory/){
66
            $path =~ s/^$temporary_directory\///;
67
            $permanent = 0;
68
            $category = "koha_kohadev_upload";
69
        }else {
70
            $path =~ s/^$permanent_directory\///;
71
            $permanent = 1;
72
            $category = substr( $path, rindex($path, '/')+1);
73
        }
74
        $path =~ s/$category$//;
75
        $path =~ s/\/$//;
76
        my %dir = $path ? ( dir => $path ) : ();
77
        my %public = $public ? ( public => $public ) : ();
78
        my $uploads = Koha::UploadedFiles->search({
79
             uploadcategorycode => $category ,
80
             permanent          => $permanent ,
81
             %dir ,
82
             %public,
83
        })->unblessed;
84
        foreach my $up (@$uploads){
85
            my $filename = $up->{'checksum'} ? $up->{'hashvalue'} ."_". $up->{'filename'} : $up->{'filename'};
86
            if($filename eq $file){
87
                $hash{'fileID'} = $up->{'id'};
88
                $hash{'hashvalue'} = $up->{'hashvalue'};
89
            }
90
        }
91
        next unless($hash{'fileID'});
92
    }
93
    push (@files, \%hash);
94
}
95
closedir(BIN);
96
97
unless ( @files ) {
98
    $json = to_json( { success => 0, error => "ERROR" } );
99
}
100
101
$json = to_json( { success => \@files } );
102
binmode STDOUT, ":encoding(UTF-8)";
103
print $input->header(
104
    -type => 'application/json',
105
    -charset => 'UTF-8'
106
);
107
108
print $json;
(-)a/t/db_dependent/Upload.t (-1 / +118 lines)
Lines 2-8 Link Here
2
2
3
use Modern::Perl;
3
use Modern::Perl;
4
use File::Temp qw/ tempdir /;
4
use File::Temp qw/ tempdir /;
5
use Test::More tests => 13;
5
use Test::More tests => 18;
6
use Test::Warn;
6
use Test::Warn;
7
7
8
use Test::MockModule;
8
use Test::MockModule;
Lines 46-51 our $uploads = [ Link Here
46
        { name => 'file6', cat => undef, size => 6500 },
46
        { name => 'file6', cat => undef, size => 6500 },
47
        { name => 'file7', cat => undef, size => 6501 },
47
        { name => 'file7', cat => undef, size => 6501 },
48
    ],
48
    ],
49
    #cheksum tests
50
    [
51
        { name => 'file8', cat => 'A', checksum => 0, size => 2000 },
52
    ],
53
    [
54
        { name => 'file9', cat => undef, checksum => 0, size => 5000 }, # temp without checksum
55
    ],
56
    [
57
        { name => 'file3', cat => 'B', checksum => 0, size => 1000 }, #duplicate file without checksum
58
    ],
59
    #path tests
60
    [
61
        { name => 'file10', dir => 'A/B', cat => 'A', size => 2000 },
62
    ],
63
    [
64
        { name => 'file11', dir => 'A/B', cat => undef, size => 3000 },
65
    ],
49
];
66
];
50
67
51
# Redirect upload dir structure and mock C4::Context and CGI
68
# Redirect upload dir structure and mock C4::Context and CGI
Lines 327-332 subtest 'Testing download headers' => sub { Link Here
327
    is_deeply(\@pdf_head, \@pdf_expect,"Get inline pdf headers for pdf");
344
    is_deeply(\@pdf_head, \@pdf_expect,"Get inline pdf headers for pdf");
328
    is_deeply(\@not_head, \@not_expect,"Get download headers for non pdf");
345
    is_deeply(\@not_head, \@not_expect,"Get download headers for non pdf");
329
};
346
};
347
348
subtest 'Not add file checksum to the uploaded filename' => sub {
349
    plan tests => 7;
350
351
    my $upl = Koha::Uploader->new({
352
            category => $uploads->[$current_upload]->[0]->{cat},
353
            checksum => 0,
354
        }); #add file8
355
    my $cgi = $upl->cgi;
356
    my $res = $upl->result;
357
    is( $upl->err, undef, 'No errors reported' );
358
359
    my $rec = Koha::UploadedFiles->find( $res );
360
    is( $rec->filename, 'file8', 'Check file name' );
361
    is( $rec->checksum, 0, 'Checksum false' );
362
    my $path = $rec->full_path;
363
    is( -e $path, 1, 'File is found' );
364
    my $fh = $rec->file_handle;
365
    is( ref($fh) eq 'IO::File' && $fh->opened, 1, 'Get returns a file handle' );
366
    my $delete = $rec->delete;
367
    ok( $delete=~/^-?1$/, 'Delete successful' );
368
    isnt( -e $path, 1, 'File no longer found after delete' );
369
};
370
371
subtest 'Temporary upload without checksum' => sub {
372
    plan tests => 5;
373
374
    my $upl = Koha::Uploader->new({
375
            tmp => 1,
376
            checksum => 0,
377
        }); #add file9
378
    my $cgi = $upl->cgi;
379
    is( $upl->count, 1, 'Upload 9 includes one temporary file' );
380
    is( $upl->err, undef, 'No errors reported' );
381
382
    my $rec = Koha::UploadedFiles->find( $upl->result );
383
    is( $rec->checksum, 0, 'Checksum false' );
384
    is( $rec->uploadcategorycode =~ /_upload$/, 1, 'Check category temp file' );
385
    my $path = $rec->full_path;
386
    is( -e $path, 1, 'File is found' );
387
};
388
389
subtest 'Duplicate file without checksum' => sub {
390
    plan tests => 5;
391
392
    my $upl = Koha::Uploader->new({
393
            category => $uploads->[$current_upload]->[0]->{cat},
394
            checksum => 0,
395
        });
396
    my $cgi = $upl->cgi;
397
    is( $upl->count, 1, 'Upload 10 successful' );
398
    is( $upl->err, undef, 'No errors reported' );
399
400
    my $rec = Koha::UploadedFiles->find( $upl->result );
401
    is( $rec->filename, 'file3', 'Check file name' );
402
    is( $rec->checksum, 0, 'Checksum false' );
403
    my $e = $upl->err;
404
    isnt( $e->{file2}->{code}, Koha::Uploader::ERR_EXISTS, "Already exists error reported" );
405
};
406
407
subtest 'Add upload in dir' => sub {
408
    plan tests => 8;
409
410
    my $upl = Koha::Uploader->new({
411
            category => $uploads->[$current_upload]->[0]->{cat},
412
            dir => $uploads->[$current_upload]->[0]->{dir},
413
        });
414
    my $cgi = $upl->cgi;
415
    is( $upl->count, 1, 'Upload 10 successful' );
416
    isnt( $upl->result, undef, 'Result is undefined' );
417
    is( $upl->err, undef, 'No errors reported' );
418
419
    my $rec = Koha::UploadedFiles->find( $upl->result );
420
    is( $rec->dir, 'A/B', 'Check dir A/B' );
421
    my $path = $rec->full_path;
422
    is( -e $path, 1, 'File is found' );
423
    my $fh = $rec->file_handle;
424
    is( ref($fh) eq 'IO::File' && $fh->opened, 1, 'Get returns a file handle' );
425
    my $delete = $rec->delete;
426
    ok( $delete=~/^-?1$/, 'Delete successful' );
427
    isnt( -e $path, 1, 'File no longer found after delete' );
428
};
429
430
subtest 'Temporary upload in dir' => sub {
431
    plan tests => 4;
432
433
    my $upl = Koha::Uploader->new({
434
            tmp => 1,
435
            dir => $uploads->[$current_upload]->[0]->{dir},
436
        }); #add file9
437
    my $cgi = $upl->cgi;
438
    is( $upl->err, undef, 'No errors reported' );
439
440
    my $rec = Koha::UploadedFiles->find( $upl->result );
441
    is( $rec->dir, 'A/B', 'Check dir' );
442
    is( $rec->uploadcategorycode =~ /_upload$/, 1, 'Check category temp file' );
443
    my $path = $rec->full_path;
444
    is( -e $path, 1, 'File is found' );
445
};
446
330
# The end
447
# The end
331
$schema->storage->txn_rollback;
448
$schema->storage->txn_rollback;
332
449
(-)a/tools/upload-file.pl (-2 / +2 lines)
Lines 75-82 sub upload_pars { # this sub parses QUERY_STRING in order to build the Link Here
75
    $qstr = Encode::decode_utf8( uri_unescape( $qstr ) );
75
    $qstr = Encode::decode_utf8( uri_unescape( $qstr ) );
76
    # category could include a utf8 character
76
    # category could include a utf8 character
77
    my $rv = {};
77
    my $rv = {};
78
    foreach my $p ( qw[public category temp] ) {
78
    foreach my $p ( qw[public category temp checksum dir] ) {
79
        if( $qstr =~ /(^|&)$p=(\w+)(&|$)/ ) {
79
        if( $qstr =~ /(^|&)$p=([\w\/\_]*)(&|$)/ ) {
80
            $rv->{$p} = $2;
80
            $rv->{$p} = $2;
81
        }
81
        }
82
    }
82
    }
(-)a/tools/upload.pl (-2 / +11 lines)
Lines 46-56 my ( $template, $loggedinuser, $cookie ) = get_template_and_user( Link Here
46
    }
46
    }
47
);
47
);
48
48
49
my @paths;
50
push @paths, { pathname => Koha::UploadedFile->permanent_directory,
51
                name    => "Permanent Directory"
52
            };
53
54
push @paths, { pathname => C4::Context::temporary_directory,
55
                name    => "Temporary Directory"
56
            };
57
58
$template->param( paths => \@paths);
49
$template->param(
59
$template->param(
50
    index      => $index,
60
    index      => $index,
51
    owner      => $loggedinuser,
61
    owner      => $loggedinuser,
52
    plugin     => $plugin,
62
    plugin     => $plugin,
53
    uploadcategories => Koha::UploadedFiles->getCategories,
63
    uploadcategories => Koha::UploadedFiles->getCategories,
64
    uploadpaths => Koha::UploadedFiles->getPaths,
54
);
65
);
55
66
56
if ( $op eq 'new' ) {
67
if ( $op eq 'new' ) {
Lines 75-81 if ( $op eq 'new' ) { Link Here
75
            $plugin? (): ( include_private => 1 ),
86
            $plugin? (): ( include_private => 1 ),
76
        })->unblessed;
87
        })->unblessed;
77
    }
88
    }
78
79
    $template->param(
89
    $template->param(
80
        mode    => 'report',
90
        mode    => 'report',
81
        msg     => $msg,
91
        msg     => $msg,
82
- 

Return to bug 20208