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

(-)a/C4/UploadedFiles.pm (-6 / +70 lines)
Lines 355-369 sub httpheaders { Link Here
355
355
356
sub MaxUploadSize {
356
sub MaxUploadSize {
357
    my ( $user ) = @_;
357
    my ( $user ) = @_;
358
    my $s = _get_settings( $user, 'filesize', 1);
359
    return @$s? $s->[0]->{count1}: MAX_DEFAULT_UPLOAD;
360
}
361
362
=head2 CheckQuota
363
364
    Checks upload quota for a staff user.
365
    If we do not find quota, we allow uploading.
366
    We use this simple approach: if user exceeds a rule now, disallow.
367
    Returns 1 if we allow a new upload, undef if we do not.
368
369
=cut
370
371
sub CheckQuota {
372
    my ( $user ) = @_;
373
374
    # First: check number of uploaded items
375
    my $iq = _get_settings( $user, 'itemquota' );
376
    foreach my $qr ( @$iq ) {
377
        my $spent = _calc_uploaded( $user, $qr->{count2}, 'items' );
378
        return if $spent >= $qr->{count1};
379
    }
380
381
    # Second: check size of uploaded items
382
    my $sq = _get_settings( $user, 'spacequota' );
383
    foreach my $qr ( @$sq ) {
384
        my $spent = _calc_uploaded( $user, $qr->{count2}, 'bytes' );
385
        return if $spent >= $qr->{count1};
386
    }
387
388
    return 1;
389
}
390
391
# internal routines
392
393
sub _get_settings {
394
    my ( $user, $type, $limit ) = @_;
358
    my $dbh = C4::Context->dbh;
395
    my $dbh = C4::Context->dbh;
396
    my $count2= $type eq 'filesize'? '': ', count2, borrowernumber';
397
    $limit = $limit? "LIMIT $limit": '';
398
    my $query = qq|
399
SELECT count1$count2 FROM upload_settings
400
WHERE (borrowernumber=? OR borrowernumber IS NULL) AND type=?
401
ORDER BY IFNULL(borrowernumber, 0) DESC $limit
402
    |;
403
    my $attr = { Slice => {} };
404
    my $res = $dbh->selectall_arrayref( $query, $attr, ( $user, $type ) );
405
406
    # For itemquota and spacequota we delete general settings if we found
407
    # personal settings too. General settings have no borrowernumber.
408
    # Since we ordered the record, the first record tells us if we have
409
    # personal settings.
410
    if( $type =~ /(item|space)quota/ && @$res && $res->[0]->{borrowernumber} ) {
411
        $res = [ grep { $_->{borrowernumber} } @$res ];
412
    }
413
    return $res;
414
}
415
416
sub _calc_uploaded {
417
    my ( $user, $days, $type ) = @_;
418
        # type==items: count number; type==bytes: count size
419
420
    my $dbh = C4::Context->dbh;
421
    my $aggr = $type eq 'items'? 'COUNT(id)':
422
             ( $type eq 'bytes'? 'SUM(IFNULL(filesize,0))': '');
423
    return 0 if !$aggr; #unknown type
424
359
    my $query = qq|
425
    my $query = qq|
360
SELECT count1 FROM upload_settings
426
SELECT $aggr FROM uploaded_files
361
WHERE (borrowernumber=? OR borrowernumber IS NULL) AND
427
WHERE owner=? AND dtcreated + INTERVAL ? DAY > NOW()
362
    type='filesize'
363
ORDER BY IFNULL(borrowernumber, 0) DESC;
364
    |;
428
    |;
365
    my ( $max ) = $dbh->selectrow_array( $query, undef, ( $user ) );
429
    my @temp = $dbh->selectrow_array( $query, undef, ( $user, $days ) );
366
    return $max // MAX_DEFAULT_UPLOAD;
430
    return @temp? ($temp[0] // 0): 0;
367
}
431
}
368
432
369
1;
433
1;
(-)a/cataloguing/value_builder/upload.pl (-1 / +4 lines)
Lines 84-90 my $launcher = sub { Link Here
84
84
85
    # Dealing with the uploaded file
85
    # Dealing with the uploaded file
86
    my $dir = $input->param('dir');
86
    my $dir = $input->param('dir');
87
    if ($uploaded_file and $dir) {
87
    my $quota_ok = C4::UploadedFiles::CheckQuota( $loggedinuser );
88
    if( !$quota_ok ) {
89
        $template->param( quota_exceeded => 1 );
90
    } elsif( $uploaded_file && $dir) {
88
        my $fh = $input->upload('uploaded_file');
91
        my $fh = $input->upload('uploaded_file');
89
92
90
        $id = C4::UploadedFiles::UploadFile($uploaded_file, $dir, $fh->handle);
93
        $id = C4::UploadedFiles::UploadFile($uploaded_file, $dir, $fh->handle);
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/upload.tt (-1 / +4 lines)
Lines 57-63 return true; Link Here
57
57
58
[% ELSE %]
58
[% ELSE %]
59
59
60
    [% IF ( MissingURL ) %]
60
    [% IF ( quota_exceeded ) %]
61
        <p>Sorry, you exceed the upload quota at this moment. Please contact your system administrator for more information or adjusting your quota.</p>
62
        <p><input type="button" value="close" onclick="window.close();" /></p>
63
    [% ELSIF ( MissingURL ) %]
61
        <p>Error: The OPAC system preference OPACBaseURL is not configured.</p>
64
        <p>Error: The OPAC system preference OPACBaseURL is not configured.</p>
62
        <p><input type="button" value="close" onclick="window.close();" /></p>
65
        <p><input type="button" value="close" onclick="window.close();" /></p>
63
    [% ELSIF ( error ) %]
66
    [% ELSIF ( error ) %]
(-)a/t/db_dependent/UploadedFiles.t (-2 / +53 lines)
Lines 3-9 Link Here
3
use Modern::Perl;
3
use Modern::Perl;
4
use File::Temp qw/tempdir/;
4
use File::Temp qw/tempdir/;
5
use Test::CGI::Multipart;
5
use Test::CGI::Multipart;
6
use Test::More tests => 21;
6
use Test::More tests => 22;
7
use Test::Warn;
7
use Test::Warn;
8
8
9
use t::lib::Mocks;
9
use t::lib::Mocks;
Lines 79-84 is( @{$a->[0]->{dirs}} == 2, 1, 'Finddir returns subdirectories' ); Link Here
79
subtest 'Tests for MaxUploadSize' => sub {
79
subtest 'Tests for MaxUploadSize' => sub {
80
    test_max();
80
    test_max();
81
};
81
};
82
subtest 'Tests for CheckQuota' => sub {
83
    test_quota();
84
};
82
85
83
#end of game
86
#end of game
84
$dbh->rollback;
87
$dbh->rollback;
Lines 110-112 sub test_max { Link Here
110
    is( $max, 500, 'MaxUploadSize is still equal to default for user 2' );
113
    is( $max, 500, 'MaxUploadSize is still equal to default for user 2' );
111
    done_testing(4);
114
    done_testing(4);
112
}
115
}
113
- 
116
117
sub test_quota {
118
    $dbh->do("DELETE FROM upload_settings");
119
    $dbh->do("DELETE FROM uploaded_files");
120
    is( C4::UploadedFiles::CheckQuota(1), 1, 'Trivial quota check' );
121
122
    my @bor = $dbh->selectrow_array(
123
        'SELECT borrowernumber FROM borrowers LIMIT 1' );
124
    if( !@bor ) {
125
        done_testing(1);
126
        return;
127
    }
128
129
    # We now load some item rules: general 2 in 3 days and two rules
130
    # for specific borrower (2 per day, 3 in 2 days)
131
    $dbh->do("INSERT INTO upload_settings
132
        ( borrowernumber, type, count1, count2 )
133
        VALUES (?, ?, ?, ?)", undef, ( undef, 'itemquota', 2, 3 ));
134
    $dbh->do("INSERT INTO upload_settings
135
        ( borrowernumber, type, count1, count2 )
136
        VALUES (?, ?, ?, ?)", undef, ( $bor[0], 'itemquota', 2, 1 ));
137
    $dbh->do("INSERT INTO upload_settings
138
        ( borrowernumber, type, count1, count2 )
139
        VALUES (?, ?, ?, ?)", undef, ( $bor[0], 'itemquota', 3, 2 ));
140
141
    # check item quota
142
    is( C4::UploadedFiles::CheckQuota($bor[0]), 1, 'Nothing uploaded so far' );
143
    my $ins1= qq|INSERT INTO uploaded_files ( id, owner, filesize, dtcreated ) VALUES (?, ?, ?, NOW() + INTERVAL ? HOUR)|;
144
    $dbh->do( $ins1, undef, ( 'aa1', $bor[0], 1000, -25) );
145
    is( C4::UploadedFiles::CheckQuota($bor[0]), 1, 'One uploaded' );
146
    $dbh->do( $ins1, undef, ( 'aa2', $bor[0], 1000, -25) );
147
    is( C4::UploadedFiles::CheckQuota($bor[0]), 1, 'Two uploaded' );
148
    $dbh->do( $ins1, undef, ( 'aa3', $bor[0], 1000, 0) );
149
    is( C4::UploadedFiles::CheckQuota($bor[0]), undef, 'Max items reached' );
150
151
    # Now delete the last upload and add a size rule (5000 per 2 days)
152
    # Gradually update the size of the second uploaded file
153
    $dbh->do("DELETE FROM uploaded_files WHERE id=?", undef, ('aa3') );
154
    $dbh->do("INSERT INTO upload_settings
155
        ( borrowernumber, type, count1, count2 )
156
        VALUES (?, ?, ?, ?)", undef, ( $bor[0], 'spacequota', 5000, 2 ));
157
    is( C4::UploadedFiles::CheckQuota($bor[0]), 1, 'Size 2000' );
158
    $dbh->do("UPDATE uploaded_files SET filesize=? WHERE id=?", undef, (3000, 'aa2') );
159
    is( C4::UploadedFiles::CheckQuota($bor[0]), 1, 'Size 4000' );
160
    $dbh->do("UPDATE uploaded_files SET filesize=? WHERE id=?", undef, (4000, 'aa2') );
161
    is( C4::UploadedFiles::CheckQuota($bor[0]), undef, 'Size 5000 reached' );
162
163
    done_testing(8);
164
}

Return to bug 14296