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

(-)a/C4/XSLT.pm (-135 / +163 lines)
Lines 37-55 use XML::LibXML; Link Here
37
use Encode;
37
use Encode;
38
use vars qw(@ISA @EXPORT);
38
use vars qw(@ISA @EXPORT);
39
39
40
my $engine;    #XSLT Handler object
40
41
41
my $engine; #XSLT Handler object
42
our ( @ISA, @EXPORT_OK );
42
43
43
our (@ISA, @EXPORT_OK);
44
BEGIN {
44
BEGIN {
45
    require Exporter;
45
    require Exporter;
46
    @ISA = qw(Exporter);
46
    @ISA       = qw(Exporter);
47
    @EXPORT_OK = qw(
47
    @EXPORT_OK = qw(
48
        buildKohaItemsNamespace
48
        buildKohaItemsNamespace
49
        XSLTParse4Display
49
        XSLTParse4Display
50
        &CustomXSLTExportList
50
        &CustomXSLTExportList
51
    );
51
    );
52
    $engine=Koha::XSLT::Base->new( { do_not_return_source => 1 } );
52
    $engine = Koha::XSLT::Base->new( { do_not_return_source => 1 } );
53
}
53
}
54
54
55
=head1 NAME
55
=head1 NAME
Lines 71-90 The helper function _get_best_default_xslt_filename is used in a unit test. Link Here
71
=cut
71
=cut
72
72
73
sub _get_best_default_xslt_filename {
73
sub _get_best_default_xslt_filename {
74
    my ($htdocs, $theme, $lang, $base_xslfile) = @_;
74
    my ( $htdocs, $theme, $lang, $base_xslfile ) = @_;
75
75
76
    my @candidates = (
76
    my @candidates = (
77
        "$htdocs/$theme/$lang/xslt/${base_xslfile}", # exact match
77
        "$htdocs/$theme/$lang/xslt/${base_xslfile}",    # exact match
78
        "$htdocs/$theme/en/xslt/${base_xslfile}",    # if not, preferred theme in English
78
        "$htdocs/$theme/en/xslt/${base_xslfile}",       # if not, preferred theme in English
79
        "$htdocs/prog/$lang/xslt/${base_xslfile}",   # if not, 'prog' theme in preferred language
79
        "$htdocs/prog/$lang/xslt/${base_xslfile}",      # if not, 'prog' theme in preferred language
80
        "$htdocs/prog/en/xslt/${base_xslfile}",      # otherwise, prog theme in English; should always
80
        "$htdocs/prog/en/xslt/${base_xslfile}",         # otherwise, prog theme in English; should always
81
                                                     # exist
81
                                                        # exist
82
    );
82
    );
83
    my $xslfilename;
83
    my $xslfilename;
84
    foreach my $filename (@candidates) {
84
    foreach my $filename (@candidates) {
85
        $xslfilename = $filename;
85
        $xslfilename = $filename;
86
        if (-f $filename) {
86
        if ( -f $filename ) {
87
            last; # we have a winner!
87
            last;                                       # we have a winner!
88
        }
88
        }
89
    }
89
    }
90
    return $xslfilename;
90
    return $xslfilename;
Lines 129-193 sub get_xslt_sysprefs { Link Here
129
    return $sysxml;
129
    return $sysxml;
130
}
130
}
131
131
132
=head2 get_xsl_filename
133
134
    return xsl filenames in CustomXSLTExportPath or in /koha-tmpl/intranet-tmpl/prog/en/xslt/biblioexport/
135
136
=cut
137
132
sub get_xsl_filename {
138
sub get_xsl_filename {
133
    my ( $xslsyspref, $xslfilename ) = @_;
139
    my ( $xslsyspref, $xslfilename ) = @_;
134
140
135
    my $lang   = C4::Languages::getlanguage();
141
    my $lang = C4::Languages::getlanguage();
136
142
137
    $xslfilename ||= C4::Context->preference($xslsyspref) || "default";
143
    $xslfilename ||= C4::Context->preference($xslsyspref) || "default";
144
    my $customXSLTExportPath = C4::Context->preference('CustomXSLTExportPath');
138
145
139
    if ($xslsyspref eq "XSLTCustomExport") {
146
    if ( $xslsyspref eq "XSLTCustomExport" ) {
140
        my $dir;
147
        my $dir;
141
        $dir = C4::Context->config('intrahtdocs') .
148
        $dir =
142
            '/' . C4::Context->preference("template") .
149
            $customXSLTExportPath ?
143
            '/' . $lang .
150
            $customXSLTExportPath :
144
            '/xslt/biblioexport';
151
              C4::Context->config('intrahtdocs') . '/'
152
            . C4::Context->preference("template") . '/'
153
            . $lang
154
            . '/xslt/biblioexport';
145
        $xslfilename = $dir . "/" . $xslfilename;
155
        $xslfilename = $dir . "/" . $xslfilename;
146
    } elsif ($xslsyspref eq "OPACXSLTCustomExport") {
156
    } elsif ( $xslsyspref eq "OPACXSLTCustomExport" ) {
147
        my $dir;
157
        my $dir;
148
        $dir = C4::Context->config('opachtdocs') .
158
        $dir =
149
            '/' . C4::Context->preference("opacthemes") .
159
            $customXSLTExportPath ?
150
            '/' . $lang .
160
            $customXSLTExportPath :
151
            '/xslt/biblioexport';
161
              C4::Context->config('opachtdocs') . '/'
162
            . C4::Context->preference("opacthemes") . '/'
163
            . $lang
164
            . '/xslt/biblioexport';
152
        $xslfilename = $dir . "/" . $xslfilename;
165
        $xslfilename = $dir . "/" . $xslfilename;
153
    } elsif ( $xslfilename =~ /^\s*"?default"?\s*$/i ) {
166
    } elsif ( $xslfilename =~ /^\s*"?default"?\s*$/i ) {
154
167
155
        my ( $htdocs, $theme, $xslfile );
168
        my ( $htdocs, $theme, $xslfile );
156
169
157
        if ($xslsyspref eq "XSLTDetailsDisplay") {
170
        if ( $xslsyspref eq "XSLTDetailsDisplay" ) {
158
            $htdocs  = C4::Context->config('intrahtdocs');
171
            $htdocs  = C4::Context->config('intrahtdocs');
159
            $theme   = C4::Context->preference("template");
172
            $theme   = C4::Context->preference("template");
160
            $xslfile = C4::Context->preference('marcflavour') .
173
            $xslfile = C4::Context->preference('marcflavour') . "slim2intranetDetail.xsl";
161
                       "slim2intranetDetail.xsl";
174
        } elsif ( $xslsyspref eq "XSLTResultsDisplay" ) {
162
        } elsif ($xslsyspref eq "XSLTResultsDisplay") {
163
            $htdocs  = C4::Context->config('intrahtdocs');
175
            $htdocs  = C4::Context->config('intrahtdocs');
164
            $theme   = C4::Context->preference("template");
176
            $theme   = C4::Context->preference("template");
165
            $xslfile = C4::Context->preference('marcflavour') .
177
            $xslfile = C4::Context->preference('marcflavour') . "slim2intranetResults.xsl";
166
                        "slim2intranetResults.xsl";
178
        } elsif ( $xslsyspref eq "OPACXSLTDetailsDisplay" ) {
167
        } elsif ($xslsyspref eq "OPACXSLTDetailsDisplay") {
168
            $htdocs  = C4::Context->config('opachtdocs');
179
            $htdocs  = C4::Context->config('opachtdocs');
169
            $theme   = C4::Context->preference("opacthemes");
180
            $theme   = C4::Context->preference("opacthemes");
170
            $xslfile = C4::Context->preference('marcflavour') .
181
            $xslfile = C4::Context->preference('marcflavour') . "slim2OPACDetail.xsl";
171
                       "slim2OPACDetail.xsl";
182
        } elsif ( $xslsyspref eq "OPACXSLTResultsDisplay" ) {
172
        } elsif ($xslsyspref eq "OPACXSLTResultsDisplay") {
173
            $htdocs  = C4::Context->config('opachtdocs');
183
            $htdocs  = C4::Context->config('opachtdocs');
174
            $theme   = C4::Context->preference("opacthemes");
184
            $theme   = C4::Context->preference("opacthemes");
175
            $xslfile = C4::Context->preference('marcflavour') .
185
            $xslfile = C4::Context->preference('marcflavour') . "slim2OPACResults.xsl";
176
                       "slim2OPACResults.xsl";
186
        } elsif ( $xslsyspref eq 'XSLTListsDisplay' ) {
177
        } elsif ($xslsyspref eq 'XSLTListsDisplay') {
187
178
            # Lists default to *Results.xslt
188
            # Lists default to *Results.xslt
179
            $htdocs  = C4::Context->config('intrahtdocs');
189
            $htdocs  = C4::Context->config('intrahtdocs');
180
            $theme   = C4::Context->preference("template");
190
            $theme   = C4::Context->preference("template");
181
            $xslfile = C4::Context->preference('marcflavour') .
191
            $xslfile = C4::Context->preference('marcflavour') . "slim2intranetResults.xsl";
182
                        "slim2intranetResults.xsl";
192
        } elsif ( $xslsyspref eq 'OPACXSLTListsDisplay' ) {
183
        } elsif ($xslsyspref eq 'OPACXSLTListsDisplay') {
193
184
            # Lists default to *Results.xslt
194
            # Lists default to *Results.xslt
185
            $htdocs  = C4::Context->config('opachtdocs');
195
            $htdocs  = C4::Context->config('opachtdocs');
186
            $theme   = C4::Context->preference("opacthemes");
196
            $theme   = C4::Context->preference("opacthemes");
187
            $xslfile = C4::Context->preference('marcflavour') .
197
            $xslfile = C4::Context->preference('marcflavour') . "slim2OPACResults.xsl";
188
                       "slim2OPACResults.xsl";
189
        }
198
        }
190
        $xslfilename = _get_best_default_xslt_filename($htdocs, $theme, $lang, $xslfile);
199
        $xslfilename = _get_best_default_xslt_filename( $htdocs, $theme, $lang, $xslfile );
191
    }
200
    }
192
201
193
    if ( $xslfilename =~ m/\{langcode\}/ ) {
202
    if ( $xslfilename =~ m/\{langcode\}/ ) {
Lines 198-204 sub get_xsl_filename { Link Here
198
}
207
}
199
208
200
sub XSLTParse4Display {
209
sub XSLTParse4Display {
201
    my ( $params ) = @_;
210
    my ($params) = @_;
202
211
203
    my $biblionumber = $params->{biblionumber};
212
    my $biblionumber = $params->{biblionumber};
204
    my $record       = $params->{record};
213
    my $record       = $params->{record};
Lines 213-224 sub XSLTParse4Display { Link Here
213
    die "Mandatory \$params->{xsl_syspref} was not provided, called with biblionumber $params->{biblionumber}"
222
    die "Mandatory \$params->{xsl_syspref} was not provided, called with biblionumber $params->{biblionumber}"
214
        if not defined $params->{xsl_syspref};
223
        if not defined $params->{xsl_syspref};
215
224
216
    $xslfilename = get_xsl_filename( $xslsyspref, $xslfilename);
225
    $xslfilename = get_xsl_filename( $xslsyspref, $xslfilename );
217
226
218
    my $frameworkcode = GetFrameworkCode($biblionumber) || '';
227
    my $frameworkcode    = GetFrameworkCode($biblionumber) || '';
219
    my $record_processor = Koha::RecordProcessor->new(
228
    my $record_processor = Koha::RecordProcessor->new(
220
        {
229
        {
221
            filters => [ 'ExpandCodedFields' ],
230
            filters => ['ExpandCodedFields'],
222
            options => {
231
            options => {
223
                interface     => $interface,
232
                interface     => $interface,
224
                frameworkcode => $frameworkcode
233
                frameworkcode => $frameworkcode
Lines 229-252 sub XSLTParse4Display { Link Here
229
238
230
    # grab the XML, run it through our stylesheet, push it out to the browser
239
    # grab the XML, run it through our stylesheet, push it out to the browser
231
    my $itemsxml;
240
    my $itemsxml;
232
    if ( $xslsyspref eq "OPACXSLTDetailsDisplay" || $xslsyspref eq "XSLTDetailsDisplay" || $xslsyspref eq "XSLTResultsDisplay" ) {
241
    if (   $xslsyspref eq "OPACXSLTDetailsDisplay"
233
        $itemsxml = ""; #We don't use XSLT for items display on these pages
242
        || $xslsyspref eq "XSLTDetailsDisplay"
243
        || $xslsyspref eq "XSLTResultsDisplay" )
244
    {
245
        $itemsxml = "";    #We don't use XSLT for items display on these pages
234
    } else {
246
    } else {
235
        $itemsxml = buildKohaItemsNamespace($biblionumber, $hidden_items, $items_rs);
247
        $itemsxml = buildKohaItemsNamespace( $biblionumber, $hidden_items, $items_rs );
236
    }
248
    }
237
    my $xmlrecord = $record->as_xml(C4::Context->preference('marcflavour'));
249
    my $xmlrecord = $record->as_xml( C4::Context->preference('marcflavour') );
238
250
239
    $variables ||= {};
251
    $variables ||= {};
240
    my $biblio;
252
    my $biblio;
241
    if ( $interface eq 'opac' && C4::Context->preference('OPACShowOpenURL')) {
253
    if ( $interface eq 'opac' && C4::Context->preference('OPACShowOpenURL') ) {
242
        my @biblio_itemtypes;
254
        my @biblio_itemtypes;
243
        $biblio //= Koha::Biblios->find($biblionumber);
255
        $biblio //= Koha::Biblios->find($biblionumber);
244
        if (C4::Context->preference('item-level_itypes')) {
256
        if ( C4::Context->preference('item-level_itypes') ) {
245
            @biblio_itemtypes = $biblio->items->get_column("itype");
257
            @biblio_itemtypes = $biblio->items->get_column("itype");
246
        } else {
258
        } else {
247
            push @biblio_itemtypes, $biblio->itemtype;
259
            push @biblio_itemtypes, $biblio->itemtype;
248
        }
260
        }
249
        my @itypes = split( /\s/, C4::Context->preference('OPACOpenURLItemTypes') );
261
        my @itypes   = split( /\s/, C4::Context->preference('OPACOpenURLItemTypes') );
250
        my %original = ();
262
        my %original = ();
251
        map { $original{$_} = 1 } @biblio_itemtypes;
263
        map { $original{$_} = 1 } @biblio_itemtypes;
252
        if ( grep { $original{$_} } @itypes ) {
264
        if ( grep { $original{$_} } @itypes ) {
Lines 256-262 sub XSLTParse4Display { Link Here
256
268
257
    # embed variables
269
    # embed variables
258
    my $varxml = "<variables>\n";
270
    my $varxml = "<variables>\n";
259
    while (my ($key, $value) = each %$variables) {
271
    while ( my ( $key, $value ) = each %$variables ) {
260
        $value //= q{};
272
        $value //= q{};
261
        $varxml .= "<variable name=\"$key\">$value</variable>\n";
273
        $varxml .= "<variable name=\"$key\">$value</variable>\n";
262
    }
274
    }
Lines 264-270 sub XSLTParse4Display { Link Here
264
276
265
    my $sysxml = get_xslt_sysprefs();
277
    my $sysxml = get_xslt_sysprefs();
266
    $xmlrecord =~ s/\<\/record\>/$itemsxml$sysxml$varxml\<\/record\>/;
278
    $xmlrecord =~ s/\<\/record\>/$itemsxml$sysxml$varxml\<\/record\>/;
267
    if ($fixamps) { # We need to correct the ampersand entities that Zebra outputs
279
    if ($fixamps) {    # We need to correct the ampersand entities that Zebra outputs
268
        $xmlrecord =~ s/\&amp;amp;/\&amp;/g;
280
        $xmlrecord =~ s/\&amp;amp;/\&amp;/g;
269
        $xmlrecord =~ s/\&amp\;lt\;/\&lt\;/g;
281
        $xmlrecord =~ s/\&amp\;lt\;/\&lt\;/g;
270
        $xmlrecord =~ s/\&amp\;gt\;/\&gt\;/g;
282
        $xmlrecord =~ s/\&amp\;gt\;/\&gt\;/g;
Lines 275-281 sub XSLTParse4Display { Link Here
275
    #If the xslt should fail, we will return undef (old behavior was
287
    #If the xslt should fail, we will return undef (old behavior was
276
    #raw MARC)
288
    #raw MARC)
277
    #Note that we did set do_not_return_source at object construction
289
    #Note that we did set do_not_return_source at object construction
278
    return $engine->transform($xmlrecord, $xslfilename ); #file or URL
290
    return $engine->transform( $xmlrecord, $xslfilename );    #file or URL
279
}
291
}
280
292
281
=head2 buildKohaItemsNamespace
293
=head2 buildKohaItemsNamespace
Lines 294-306 Is only used in this module currently. Link Here
294
=cut
306
=cut
295
307
296
sub buildKohaItemsNamespace {
308
sub buildKohaItemsNamespace {
297
    my ($biblionumber, $hidden_items, $items_rs) = @_;
309
    my ( $biblionumber, $hidden_items, $items_rs ) = @_;
298
310
299
    $hidden_items ||= [];
311
    $hidden_items ||= [];
300
312
301
    my $query = {};
313
    my $query = {};
302
    $query = { 'me.itemnumber' => { not_in => $hidden_items } }
314
    $query = { 'me.itemnumber' => { not_in => $hidden_items } }
303
      if $hidden_items;
315
        if $hidden_items;
304
316
305
    unless ( $items_rs && ref($items_rs) eq 'Koha::Items' ) {
317
    unless ( $items_rs && ref($items_rs) eq 'Koha::Items' ) {
306
        $query->{'me.biblionumber'} = $biblionumber;
318
        $query->{'me.biblionumber'} = $biblionumber;
Lines 309-325 sub buildKohaItemsNamespace { Link Here
309
321
310
    my $items = $items_rs->search( $query, { prefetch => [ 'branchtransfers', 'reserves' ] } );
322
    my $items = $items_rs->search( $query, { prefetch => [ 'branchtransfers', 'reserves' ] } );
311
323
312
    my $shelflocations =
324
    my $shelflocations = {
313
      { map { $_->{authorised_value} => $_->{opac_description} } Koha::AuthorisedValues->get_descriptions_by_koha_field( { frameworkcode => "", kohafield => 'items.location' } ) };
325
        map { $_->{authorised_value} => $_->{opac_description} }
314
    my $ccodes =
326
            Koha::AuthorisedValues->get_descriptions_by_koha_field(
315
      { map { $_->{authorised_value} => $_->{opac_description} } Koha::AuthorisedValues->get_descriptions_by_koha_field( { frameworkcode => "", kohafield => 'items.ccode' } ) };
327
            { frameworkcode => "", kohafield => 'items.location' }
316
328
            )
317
    my %branches = map { $_->branchcode => $_->branchname } Koha::Libraries->search({}, { order_by => 'branchname' })->as_list;
329
    };
330
    my $ccodes = {
331
        map { $_->{authorised_value} => $_->{opac_description} }
332
            Koha::AuthorisedValues->get_descriptions_by_koha_field(
333
            { frameworkcode => "", kohafield => 'items.ccode' }
334
            )
335
    };
336
337
    my %branches =
338
        map { $_->branchcode => $_->branchname } Koha::Libraries->search( {}, { order_by => 'branchname' } )->as_list;
318
339
319
    my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search->unblessed } };
340
    my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search->unblessed } };
320
    my $xml = '';
341
    my $xml       = '';
321
    my %descs = map { $_->{authorised_value} => $_ } Koha::AuthorisedValues->get_descriptions_by_koha_field( { kohafield => 'items.notforloan' } );
342
    my %descs     = map { $_->{authorised_value} => $_ }
322
    my $ref_status = C4::Context->preference('Reference_NFL_Statuses') // q{}; # fallback to 1|2 removed
343
        Koha::AuthorisedValues->get_descriptions_by_koha_field( { kohafield => 'items.notforloan' } );
344
    my $ref_status = C4::Context->preference('Reference_NFL_Statuses') // q{};    # fallback to 1|2 removed
323
345
324
    while ( my $item = $items->next ) {
346
    while ( my $item = $items->next ) {
325
        my $status;
347
        my $status;
Lines 327-407 sub buildKohaItemsNamespace { Link Here
327
        my $recalls_count;
349
        my $recalls_count;
328
350
329
        if ( C4::Context->preference('UseRecalls') ) {
351
        if ( C4::Context->preference('UseRecalls') ) {
330
            $recalls_count = Koha::Recalls->search({ item_id => $item->itemnumber, status => 'waiting' })->count;
352
            $recalls_count = Koha::Recalls->search( { item_id => $item->itemnumber, status => 'waiting' } )->count;
331
        }
353
        }
332
354
333
        if ($recalls_count) {
355
        if ($recalls_count) {
356
334
            # recalls take priority over holds
357
            # recalls take priority over holds
335
            $status = 'other';
358
            $status    = 'other';
336
            $substatus = 'Recall waiting';
359
            $substatus = 'Recall waiting';
337
        }
360
        } elsif ( $item->has_pending_hold ) {
338
        elsif ( $item->has_pending_hold ) {
361
            $status    = 'other';
339
            $status = 'other';
340
            $substatus = 'Pending hold';
362
            $substatus = 'Pending hold';
341
        }
363
        } elsif ( $item->holds->waiting->count ) {
342
        elsif ( $item->holds->waiting->count ) {
364
            $status    = 'other';
343
            $status = 'other';
344
            $substatus = 'Hold waiting';
365
            $substatus = 'Hold waiting';
345
        }
366
        } elsif ( $item->get_transfer ) {
346
        elsif ($item->get_transfer) {
367
            $status    = 'other';
347
            $status = 'other';
348
            $substatus = 'In transit';
368
            $substatus = 'In transit';
349
        }
369
        } elsif ( $item->damaged ) {
350
        elsif ($item->damaged) {
370
            $status    = 'other';
351
            $status = 'other';
352
            $substatus = "Damaged";
371
            $substatus = "Damaged";
353
        }
372
        } elsif ( $item->itemlost ) {
354
        elsif ($item->itemlost) {
373
            $status    = 'other';
355
            $status = 'other';
356
            $substatus = "Lost";
374
            $substatus = "Lost";
357
        }
375
        } elsif ( $item->withdrawn ) {
358
        elsif ( $item->withdrawn) {
376
            $status    = 'other';
359
            $status = 'other';
360
            $substatus = "Withdrawn";
377
            $substatus = "Withdrawn";
361
        }
378
        } elsif ( $item->onloan ) {
362
        elsif ($item->onloan) {
379
            $status    = 'other';
363
            $status = 'other';
364
            $substatus = "Checked out";
380
            $substatus = "Checked out";
365
        }
381
        } elsif ( $item->notforloan ) {
366
        elsif ( $item->notforloan ) {
382
            $status =
367
            $status = $item->notforloan =~ /^($ref_status)$/
383
                $item->notforloan =~ /^($ref_status)$/
368
                ? "reference"
384
                ? "reference"
369
                : "reallynotforloan";
385
                : "reallynotforloan";
370
            $substatus = exists $descs{$item->notforloan} ? $descs{$item->notforloan}->{opac_description} : "Not for loan";
386
            $substatus =
371
        }
387
                exists $descs{ $item->notforloan } ? $descs{ $item->notforloan }->{opac_description} : "Not for loan";
372
        elsif ( exists $itemtypes->{ $item->effective_itemtype }
388
        } elsif ( exists $itemtypes->{ $item->effective_itemtype }
373
            && $itemtypes->{ $item->effective_itemtype }->{notforloan}
389
            && $itemtypes->{ $item->effective_itemtype }->{notforloan}
374
            && $itemtypes->{ $item->effective_itemtype }->{notforloan} == 1 )
390
            && $itemtypes->{ $item->effective_itemtype }->{notforloan} == 1 )
375
        {
391
        {
376
            $status = "1" =~ /^($ref_status)$/
392
            $status =
393
                  "1" =~ /^($ref_status)$/
377
                ? "reference"
394
                ? "reference"
378
                : "reallynotforloan";
395
                : "reallynotforloan";
379
            $substatus = "Not for loan";
396
            $substatus = "Not for loan";
380
        }
397
        } else {
381
        else {
382
            $status = "available";
398
            $status = "available";
383
        }
399
        }
384
        my $homebranch     = C4::Koha::xml_escape($branches{$item->homebranch});
400
        my $homebranch    = C4::Koha::xml_escape( $branches{ $item->homebranch } );
385
        my $holdingbranch  = C4::Koha::xml_escape($branches{$item->holdingbranch});
401
        my $holdingbranch = C4::Koha::xml_escape( $branches{ $item->holdingbranch } );
386
        my $resultbranch   = C4::Context->preference('OPACResultsLibrary') eq 'homebranch' ? $homebranch : $holdingbranch;
402
        my $resultbranch = C4::Context->preference('OPACResultsLibrary') eq 'homebranch' ? $homebranch : $holdingbranch;
387
        my $location       = C4::Koha::xml_escape($item->location && exists $shelflocations->{$item->location} ? $shelflocations->{$item->location} : $item->location);
403
        my $location     = C4::Koha::xml_escape(
388
        my $ccode          = C4::Koha::xml_escape($item->ccode    && exists $ccodes->{$item->ccode}            ? $ccodes->{$item->ccode}            : $item->ccode);
404
              $item->location && exists $shelflocations->{ $item->location }
389
        my $itemcallnumber = C4::Koha::xml_escape($item->itemcallnumber);
405
            ? $shelflocations->{ $item->location }
390
        my $stocknumber    = C4::Koha::xml_escape($item->stocknumber);
406
            : $item->location
407
        );
408
        my $ccode = C4::Koha::xml_escape( $item->ccode
409
                && exists $ccodes->{ $item->ccode } ? $ccodes->{ $item->ccode } : $item->ccode );
410
        my $itemcallnumber = C4::Koha::xml_escape( $item->itemcallnumber );
411
        my $stocknumber    = C4::Koha::xml_escape( $item->stocknumber );
391
        $xml .=
412
        $xml .=
392
            "<item>"
413
              "<item>"
393
          . "<homebranch>$homebranch</homebranch>"
414
            . "<homebranch>$homebranch</homebranch>"
394
          . "<holdingbranch>$holdingbranch</holdingbranch>"
415
            . "<holdingbranch>$holdingbranch</holdingbranch>"
395
          . "<resultbranch>$resultbranch</resultbranch>"
416
            . "<resultbranch>$resultbranch</resultbranch>"
396
          . "<location>$location</location>"
417
            . "<location>$location</location>"
397
          . "<ccode>$ccode</ccode>"
418
            . "<ccode>$ccode</ccode>"
398
          . "<status>".( $status // q{} )."</status>"
419
            . "<status>"
399
          . "<substatus>$substatus</substatus>"
420
            . ( $status // q{} )
400
          . "<itemcallnumber>$itemcallnumber</itemcallnumber>"
421
            . "</status>"
401
          . "<stocknumber>$stocknumber</stocknumber>"
422
            . "<substatus>$substatus</substatus>"
402
          . "</item>";
423
            . "<itemcallnumber>$itemcallnumber</itemcallnumber>"
424
            . "<stocknumber>$stocknumber</stocknumber>"
425
            . "</item>";
403
    }
426
    }
404
    $xml = "<items xmlns=\"http://www.koha-community.org/items\">".$xml."</items>";
427
    $xml = "<items xmlns=\"http://www.koha-community.org/items\">" . $xml . "</items>";
405
    return $xml;
428
    return $xml;
406
}
429
}
407
430
Lines 422-473 sub engine { Link Here
422
=cut
445
=cut
423
446
424
sub CustomXSLTExportList {
447
sub CustomXSLTExportList {
425
    my $opac = shift; # opac (1) vs intranet (0)
448
    my $opac = shift;    # opac (1) vs intranet (0)
426
    return [] if $opac && C4::Context->preference('OpacExportOptions') !~ /custom/;
449
    return [] if $opac && C4::Context->preference('OpacExportOptions') !~ /custom/;
427
450
451
    my $customXSLTExportPath = C4::Context->preference('CustomXSLTExportPath');
452
428
    # Check the cache first
453
    # Check the cache first
429
    my $cache = Koha::Caches->get_instance;
454
    my $cache      = Koha::Caches->get_instance;
430
    my $key = $opac ? 'CustomXSLTExportListOPAC' : 'CustomXSLTExportListIntra';
455
    my $key        = $opac ? 'CustomXSLTExportListOPAC' : 'CustomXSLTExportListIntra';
431
    my $cached_val = $cache->get_from_cache($key);
456
    my $cached_val = $cache->get_from_cache($key);
432
    return $cached_val if $cached_val;
457
    return $cached_val if $cached_val;
433
458
434
    my @tabFiles;
459
    my @tabFiles;
435
460
436
    my $dir = C4::Context->config( $opac ? 'opachtdocs' : 'intrahtdocs') .
461
    my $dir =
437
                      '/' . C4::Context->preference( $opac ? "opacthemes" : "template") .
462
        $customXSLTExportPath ?
438
                      '/' . C4::Languages::getlanguage() .
463
        $customXSLTExportPath :
439
                      '/xslt/biblioexport';
464
          C4::Context->config( $opac     ? 'opachtdocs' : 'intrahtdocs' ) . '/'
465
        . C4::Context->preference( $opac ? "opacthemes" : "template" ) . '/'
466
        . C4::Languages::getlanguage()
467
        . '/xslt/biblioexport';
440
    my @files = glob qq("$dir/*.xsl");
468
    my @files = glob qq("$dir/*.xsl");
441
    foreach my $file (@files) {
469
    foreach my $file (@files) {
442
        if ( -f "$file" ) {
470
        if ( -f "$file" ) {
443
            (my $text = $file) =~ s/.*\///g;
471
            ( my $text = $file ) =~ s/.*\///g;
444
472
445
            ## Get title of the option
473
            ## Get title of the option
446
            my $dom;
474
            my $dom;
447
            eval { $dom = XML::LibXML->load_xml( location => $file ); };
475
            eval { $dom = XML::LibXML->load_xml( location => $file ); };
448
            next unless $dom;
476
            next unless $dom;
449
477
450
            my $node = $dom->documentElement();
478
            my $node  = $dom->documentElement();
451
            my $title = $node->{"title"};
479
            my $title = $node->{"title"};
452
            ($title = $text) =~ s/\.xsl// unless defined $title;
480
            ( $title = $text ) =~ s/\.xsl// unless defined $title;
453
481
454
            # Get output format
482
            # Get output format
455
            # There should only be one xsl:output node, so taking the first one only is OK
483
            # There should only be one xsl:output node, so taking the first one only is OK
456
            $node = @{$node->findnodes("xsl:output")}[0];
484
            $node = @{ $node->findnodes("xsl:output") }[0];
457
            my $outputformat= "";
485
            my $outputformat = "";
458
            $outputformat = $node->{"method"} if $node;
486
            $outputformat = $node->{"method"} if $node;
459
            $outputformat = "txt" if ($outputformat eq "" || $outputformat eq "text");
487
            $outputformat = "txt"             if ( $outputformat eq "" || $outputformat eq "text" );
460
488
461
            my %row = (
489
            my %row = (
462
                value       => $text,
490
                value    => $text,
463
                filename    => $title,
491
                filename => $title,
464
                format      => $outputformat,
492
                format   => $outputformat,
465
            );
493
            );
466
494
467
            push @tabFiles, \%row;
495
            push @tabFiles, \%row;
468
        }
496
        }
469
    }
497
    }
470
    $cache->set_in_cache( $key, [ @tabFiles ] );
498
    $cache->set_in_cache( $key, [@tabFiles] );
471
    return \@tabFiles;
499
    return \@tabFiles;
472
}
500
}
473
1;
501
1;
(-)a/basket/basket.pl (-3 / +3 lines)
Lines 112-120 my $resultsarray = \@results; Link Here
112
112
113
$template->param(
113
$template->param(
114
    BIBLIO_RESULTS => $resultsarray,
114
    BIBLIO_RESULTS => $resultsarray,
115
    csv_profiles => Koha::CsvProfiles->search({ type => 'marc', used_for => 'export_records' }),
115
    csv_profiles   => Koha::CsvProfiles->search({ type => 'marc', used_for => 'export_records' }),
116
    xsl_exports => CustomXSLTExportList(),
116
    xsl_exports    => CustomXSLTExportList(),
117
    bib_list => $bib_list,
117
    bib_list       => $bib_list,
118
);
118
);
119
119
120
output_html_with_http_headers $query, $cookie, $template->output;
120
output_html_with_http_headers $query, $cookie, $template->output;
(-)a/basket/downloadcart.pl (-42 / +43 lines)
Lines 34-111 use Koha::Biblios; Link Here
34
use utf8;
34
use utf8;
35
my $query = CGI->new;
35
my $query = CGI->new;
36
36
37
my ( $template, $borrowernumber, $cookie ) = get_template_and_user (
37
my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
38
    {
38
    {
39
        template_name   => "basket/downloadcart.tt",
39
        template_name => "basket/downloadcart.tt",
40
        query           => $query,
40
        query         => $query,
41
        type            => "intranet",
41
        type          => "intranet",
42
        flagsrequired   => { catalogue => 1 },
42
        flagsrequired => { catalogue => 1 },
43
    }
43
    }
44
);
44
);
45
45
46
my $bib_list = $query->param('bib_list');
46
my $bib_list = $query->param('bib_list');
47
my $format  = $query->param('format');
47
my $format   = $query->param('format');
48
my $dbh     = C4::Context->dbh;
48
my $dbh      = C4::Context->dbh;
49
49
50
if ($bib_list && $format) {
50
if ( $bib_list && $format ) {
51
51
52
    my @bibs = split( /\//, $bib_list );
52
    my @bibs = split( /\//, $bib_list );
53
53
54
    my $marcflavour         = C4::Context->preference('marcflavour');
54
    my $marcflavour = C4::Context->preference('marcflavour');
55
    my $output;
55
    my $output;
56
56
57
    # CSV   
57
    # CSV
58
    if ($format =~ /^\d+$/) {
58
    if ( $format =~ /^\d+$/ ) {
59
59
60
        $output = marc2csv(\@bibs, $format);
60
        $output = marc2csv( \@bibs, $format );
61
    
61
62
    # Other formats
62
        # Other formats
63
    } else {
63
    } else {
64
64
65
        foreach my $biblionumber (@bibs) {
65
        foreach my $biblionumber (@bibs) {
66
66
67
            my $biblio = Koha::Biblios->find($biblionumber);
67
            my $biblio  = Koha::Biblios->find($biblionumber);
68
            my $record = $biblio->metadata->record({ embed_items => 1 });
68
            my $record  = $biblio->metadata->record( { embed_items => 1 } );
69
            my $xslFile = $query->param("file");
69
            my $xslFile = $query->param("file");
70
            next unless $record;
70
            next unless $record;
71
71
72
            if ($format eq 'iso2709') {
72
            if ( $format eq 'iso2709' ) {
73
73
                #NOTE: If we don't explicitly UTF-8 encode the output,
74
                #NOTE: If we don't explicitly UTF-8 encode the output,
74
                #the browser will guess the encoding, and it won't always choose UTF-8.
75
                #the browser will guess the encoding, and it won't always choose UTF-8.
75
                $output .= encode("UTF-8", $record->as_usmarc()) // q{};
76
                $output .= encode( "UTF-8", $record->as_usmarc() ) // q{};
76
            }
77
            } elsif ( $format eq 'ris' ) {
77
            elsif ($format eq 'ris') {
78
                $output .= marc2ris($record);
78
                $output .= marc2ris($record);
79
            }
79
            } elsif ( $format eq 'bibtex' ) {
80
            elsif ($format eq 'bibtex') {
80
                $output .= marc2bibtex( $record, $biblionumber );
81
                $output .= marc2bibtex($record, $biblionumber);
81
            } elsif ( $format =~ /^xsl\.(.*)$/ ) {
82
            }
82
                $output .= XSLTParse4Display(
83
            elsif ($format =~ /^xsl\.(.*)$/) {
83
                    {
84
                $output .= XSLTParse4Display({
84
                        biblionumber => $biblio,
85
                    biblionumber => $biblio,
85
                        record       => $record,
86
                    record       => $record,
86
                        xsl_syspref  => "XSLTCustomExport",
87
                    xsl_syspref  => "XSLTCustomExport",
87
                        fix_amps     => 1,
88
                    fix_amps     => 1,
88
                        hidden_items => undef,
89
                    hidden_items => undef,
89
                        xslfilename  => $xslFile,
90
                    xslfilename  => $xslFile,
90
                    }
91
                });
91
                );
92
            }
92
            }
93
        }
93
        }
94
    }
94
    }
95
95
96
    # If it was a CSV export we change the format after the export so the file extension is fine
96
    # If it was a CSV export we change the format after the export so the file extension is fine
97
    $format = "csv" if ($format =~ m/^\d+$/);
97
    $format = "csv"  if ( $format =~ m/^\d+$/ );
98
    $format = "html" if ($format =~ /^xsl\./);
98
    $format = "html" if ( $format =~ /^xsl\./ );
99
99
100
    print $query->header(
100
    print $query->header(
101
	-type => 'application/octet-stream',
101
        -type                        => 'application/octet-stream',
102
	-'Content-Transfer-Encoding' => 'binary',
102
        -'Content-Transfer-Encoding' => 'binary',
103
	-attachment=>"cart.$format");
103
        -attachment                  => "cart.$format"
104
    );
104
    print $output;
105
    print $output;
105
106
106
} else { 
107
} else {
107
    $template->param(csv_profiles => Koha::CsvProfiles->search({ type => 'marc', used_for => 'export_records' }));
108
    $template->param( csv_profiles => Koha::CsvProfiles->search( { type => 'marc', used_for => 'export_records' } ) );
108
    $template->param(xsl_exports => CustomXSLTExportList());
109
    $template->param( xsl_exports  => CustomXSLTExportList() );
109
    $template->param(bib_list => $bib_list); 
110
    $template->param( bib_list     => $bib_list );
110
    output_html_with_http_headers $query, $cookie, $template->output;
111
    output_html_with_http_headers $query, $cookie, $template->output;
111
}
112
}
(-)a/catalogue/detail.pl (-2 / +2 lines)
Lines 85-92 if ( C4::Context->config('enable_plugins') ) { Link Here
85
    );
85
    );
86
}
86
}
87
87
88
##### ADD CUSTOM XSLT
88
# Add custom XSLT
89
$template->param(filesOptions => CustomXSLTExportList(0));
89
$template->param( filesOptions => CustomXSLTExportList(0) );
90
90
91
my $biblionumber = $query->param('biblionumber');
91
my $biblionumber = $query->param('biblionumber');
92
$biblionumber = HTML::Entities::encode($biblionumber);
92
$biblionumber = HTML::Entities::encode($biblionumber);
(-)a/catalogue/export.pl (-83 / +78 lines)
Lines 10-115 use C4::Ris qw( marc2ris ); Link Here
10
use C4::XSLT qw( XSLTParse4Display );
10
use C4::XSLT qw( XSLTParse4Display );
11
use Koha::Biblios;
11
use Koha::Biblios;
12
12
13
14
15
my $query = CGI->new;
13
my $query = CGI->new;
16
my ( $template, $loggedinuser, $cookie ) = get_template_and_user({
14
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
17
    template_name   => "tools/export.tt",
15
    {
18
    query           => $query,
16
        template_name => "tools/export.tt",
19
    type            => "intranet",
17
        query         => $query,
20
    flagsrequired   => { catalogue => 1 },
18
        type          => "intranet",
21
    });
19
        flagsrequired => { catalogue => 1 },
20
    }
21
);
22
22
23
my $op=$query->param("op");
23
my $op     = $query->param("op");
24
my $format=$query->param("format");
24
my $format = $query->param("format");
25
my $error = '';
25
my $error  = '';
26
if ($op eq "export") {
26
if ( $op eq "export" ) {
27
    my $biblionumber = $query->param("bib");
27
    my $biblionumber = $query->param("bib");
28
        if ($biblionumber){
28
    if ($biblionumber) {
29
            my $file_id = $biblionumber;
29
        my $file_id  = $biblionumber;
30
            my $file_pre = "bib-";
30
        my $file_pre = "bib-";
31
31
32
            my $biblio = Koha::Biblios->find($biblionumber);
32
        my $biblio = Koha::Biblios->find($biblionumber);
33
            my $marc   = $biblio->metadata->record({ embed_items => 1 });
33
        my $marc   = $biblio->metadata->record( { embed_items => 1 } );
34
34
35
            if( C4::Context->preference('DefaultSaveRecordFileID') eq 'controlnumber' ){
35
        if ( C4::Context->preference('DefaultSaveRecordFileID') eq 'controlnumber' ) {
36
                my $marcflavour = C4::Context->preference('marcflavour'); #FIXME This option is required but does not change control num behaviour
36
            my $marcflavour = C4::Context->preference('marcflavour')
37
                my $control_num = GetMarcControlnumber( $marc, $marcflavour );
37
                ;    #FIXME This option is required but does not change control num behaviour
38
                if( $control_num ){
38
            my $control_num = GetMarcControlnumber( $marc, $marcflavour );
39
                    $file_id = $control_num;
39
            if ($control_num) {
40
                    $file_pre = "record-";
40
                $file_id  = $control_num;
41
                }
41
                $file_pre = "record-";
42
            }
42
            }
43
        }
43
44
44
            if ($format =~ /endnote/) {
45
        if ( $format =~ /endnote/ ) {
45
                $marc = marc2endnote($marc);
46
            $marc   = marc2endnote($marc);
46
                $format = 'endnote';
47
            $format = 'endnote';
47
            }
48
        } elsif ( $format =~ /marcxml/ ) {
48
            elsif ($format =~ /marcxml/) {
49
            $marc   = marc2marcxml($marc);
49
                $marc = marc2marcxml($marc);
50
            $format = "marcxml";
50
                $format = "marcxml";
51
        } elsif ( $format =~ /mods/ ) {
51
            }
52
            $marc   = marc2modsxml($marc);
52
            elsif ($format=~ /mods/) {
53
            $format = "mods";
53
                $marc = marc2modsxml($marc);
54
        } elsif ( $format =~ /ris/ ) {
54
                $format = "mods";
55
            $marc   = marc2ris($marc);
55
            }
56
            $format = "ris";
56
            elsif ($format =~ /ris/) {
57
        } elsif ( $format =~ /bibtex/ ) {
57
                $marc = marc2ris($marc);
58
            $marc   = marc2bibtex($marc);
58
                $format = "ris";
59
            $format = "bibtex";
59
            }
60
        } elsif ( $format =~ /dc$/ ) {
60
            elsif ($format =~ /bibtex/) {
61
            $marc   = marc2dcxml( undef, undef, $biblionumber, $format );
61
                $marc = marc2bibtex($marc);
62
            $format = "dublin-core.xml";
62
                $format = "bibtex";
63
        } elsif ( $format =~ /marc8/ ) {
63
            }
64
            $marc   = changeEncoding( $marc, "MARC", "MARC21", "MARC-8" );
64
            elsif ($format =~ /dc$/) {
65
            $marc   = $marc->as_usmarc();
65
                $marc = marc2dcxml(undef, undef, $biblionumber, $format);
66
            $format = "marc8";
66
                $format = "dublin-core.xml";
67
        } elsif ( $format =~ /utf8/ ) {
67
            }
68
            C4::Charset::SetUTF8Flag( $marc, 1 );
68
            elsif ($format =~ /marc8/) {
69
            $marc   = $marc->as_usmarc();
69
                $marc = changeEncoding($marc,"MARC","MARC21","MARC-8");
70
            $format = "utf8";
70
                $marc = $marc->as_usmarc();
71
        } elsif ( $format =~ /marcstd/ ) {
71
                $format = "marc8";
72
            C4::Charset::SetUTF8Flag( $marc, 1 );
72
            }
73
            ( $error, $marc ) = marc2marc( $marc, 'marcstd', C4::Context->preference('marcflavour') );
73
            elsif ($format =~ /utf8/) {
74
            $format = "marcstd";
74
                C4::Charset::SetUTF8Flag($marc, 1);
75
        }
75
                $marc = $marc->as_usmarc();
76
        if ( $format =~ /utf8/ or $format =~ /marcstd/ ) {
76
                $format = "utf8";
77
            binmode STDOUT, ':encoding(UTF-8)';
77
            }
78
            elsif ($format =~ /marcstd/) {
79
                C4::Charset::SetUTF8Flag($marc,1);
80
                ($error, $marc) = marc2marc($marc, 'marcstd', C4::Context->preference('marcflavour'));
81
                $format = "marcstd";
82
            }
83
            if ( $format =~ /utf8/ or $format =~ /marcstd/ ) {
84
                binmode STDOUT, ':encoding(UTF-8)';
85
            }
86
            print $query->header(
87
                -type => 'application/octet-stream',
88
                -attachment=>"$file_pre$file_id.$format");
89
            print $marc;
90
        }
78
        }
91
}elsif ($op eq "exportxsl"){
79
        print $query->header(
80
            -type       => 'application/octet-stream',
81
            -attachment => "$file_pre$file_id.$format"
82
        );
83
        print $marc;
84
    }
85
} elsif ( $op eq "exportxsl" ) {
92
    my $biblionumber = $query->param("bib");
86
    my $biblionumber = $query->param("bib");
93
    if ($biblionumber){
87
    if ($biblionumber) {
94
        my $xslFile = $query->param("file");
88
        my $xslFile = $query->param("file");
95
        my $biblio = Koha::Biblios->find($biblionumber);
89
        my $biblio  = Koha::Biblios->find($biblionumber);
96
        my $marc = $biblio->metadata->record( { embed_items => 1 } );
90
        my $marc    = $biblio->metadata->record( { embed_items => 1 } );
97
        my $format=$query->param("format")||'txt';
91
        my $format  = $query->param("format") || 'txt';
98
        my @hiddenitems;
92
        my @hiddenitems;
99
93
100
        $marc = XSLTParse4Display(
94
        $marc = XSLTParse4Display(
101
            {
95
            {
102
                biblionumber   => $biblionumber,
96
                biblionumber => $biblionumber,
103
                record         => $marc,
97
                record       => $marc,
104
                xsl_syspref    => "XSLTCustomExport",
98
                xsl_syspref  => "XSLTCustomExport",
105
                fix_amps       => 1,
99
                fix_amps     => 1,
106
                hidden_items   => \@hiddenitems,
100
                hidden_items => \@hiddenitems,
107
                xslfilename    => $xslFile,
101
                xslfilename  => $xslFile,
108
            }
102
            }
109
        );
103
        );
110
        print $query->header(
104
        print $query->header(
111
            -type => 'application/octet-stream',
105
            -type       => 'application/octet-stream',
112
            -attachment=>"bib-$biblionumber.$format");
106
            -attachment => "bib-$biblionumber.$format"
107
        );
113
        print $marc;
108
        print $marc;
114
    }
109
    }
115
}
110
}
(-)a/installer/data/mysql/atomicupdate/bug_17385-CustomOptionForOpacExportOptions_syspref.pl (+29 lines)
Line 0 Link Here
1
use Modern::Perl;
2
3
return {
4
    bug_number  => "17385",
5
    description => "Add a custom option for OpacExportOptions system preference",
6
    up          => sub {
7
        my ($args) = @_;
8
        my ( $dbh, $out ) = @$args{qw(dbh out)};
9
10
        $dbh->do(
11
            q{
12
                UPDATE systempreferences
13
                SET value = 'bibtex,dc,marcxml,marc8,utf8,marcstd,mods,ris,isbd,custom'
14
                WHERE variable = 'OpacExportOptions';
15
            }
16
        );
17
18
        $dbh->do(
19
            q{
20
                INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type)
21
                VALUES ('CustomXSLTExportPath','','','The path to the folder containing the customized XSL files for export','');
22
            }
23
        );
24
25
        # sysprefs
26
        say $out "Updated system preference 'OpacExportOptions'";
27
        say $out "Added new system preference 'OpacCustomExportFilePath'";
28
    },
29
};
(-)a/installer/data/mysql/mandatory/sysprefs.sql (-1 / +2 lines)
Lines 176-181 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
176
('CurrencyFormat','US','US|FR|CH','Determines the display format of currencies. eg: \'36000\' is displayed as \'360 000,00\'  in \'FR\' or \'360,000.00\'  in \'US\'.','Choice'),
176
('CurrencyFormat','US','US|FR|CH','Determines the display format of currencies. eg: \'36000\' is displayed as \'360 000,00\'  in \'FR\' or \'360,000.00\'  in \'US\'.','Choice'),
177
('CustomCoverImages','0',NULL,'If enabled, the custom cover images will be displayed in the staff interface. CustomCoverImagesURL must be defined.','YesNo'),
177
('CustomCoverImages','0',NULL,'If enabled, the custom cover images will be displayed in the staff interface. CustomCoverImagesURL must be defined.','YesNo'),
178
('CustomCoverImagesURL','',NULL,'Define an URL serving book cover images, using the following patterns: %issn%, %isbn%, FIXME ADD MORE (use it with CustomCoverImages and/or OPACCustomCoverImages)','free'),
178
('CustomCoverImagesURL','',NULL,'Define an URL serving book cover images, using the following patterns: %issn%, %isbn%, FIXME ADD MORE (use it with CustomCoverImages and/or OPACCustomCoverImages)','free'),
179
('CustomXSLTExportPath','','','The path to the folder containing the customized XSL files for export',''),
179
('dateformat','us','metric|us|iso|dmydot','Define global date format (us mm/dd/yyyy, metric dd/mm/yyy, ISO yyyy-mm-dd, dmydot dd.mm.yyyy)','Choice'),
180
('dateformat','us','metric|us|iso|dmydot','Define global date format (us mm/dd/yyyy, metric dd/mm/yyy, ISO yyyy-mm-dd, dmydot dd.mm.yyyy)','Choice'),
180
('DebugLevel','2','0|1|2','Define the level of debugging information sent to the browser when errors are encountered (set to 0 in production). 0=none, 1=some, 2=most','Choice'),
181
('DebugLevel','2','0|1|2','Define the level of debugging information sent to the browser when errors are encountered (set to 0 in production). 0=none, 1=some, 2=most','Choice'),
181
('decreaseLoanHighHolds','0','','Decreases the loan period for items with number of holds above the threshold specified in decreaseLoanHighHoldsValue','YesNo'),
182
('decreaseLoanHighHolds','0','','Decreases the loan period for items with number of holds above the threshold specified in decreaseLoanHighHoldsValue','YesNo'),
Lines 463-469 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
463
('OPACdefaultSortOrder','dsc','asc|dsc|za|az','Specify the default sort order','Choice'),
464
('OPACdefaultSortOrder','dsc','asc|dsc|za|az','Specify the default sort order','Choice'),
464
('OPACdidyoumean','',NULL,'Did you mean? configuration for the OPAC. Do not change, as this is controlled by /cgi-bin/koha/admin/didyoumean.pl.','Free'),
465
('OPACdidyoumean','',NULL,'Did you mean? configuration for the OPAC. Do not change, as this is controlled by /cgi-bin/koha/admin/didyoumean.pl.','Free'),
465
('OPACDisplay856uAsImage','OFF','OFF|Details|Results|Both','Display the URI in the 856u field as an image, the corresponding OPACXSLT option must be on','Choice'),
466
('OPACDisplay856uAsImage','OFF','OFF|Details|Results|Both','Display the URI in the 856u field as an image, the corresponding OPACXSLT option must be on','Choice'),
466
('OpacExportOptions','bibtex,dc,marcxml,marc8,utf8,marcstd,mods,ris,isbd','','Define export options available on OPAC detail page.','multiple'),
467
('OpacExportOptions','bibtex,dc,marcxml,marc8,utf8,marcstd,mods,ris,isbd,custom','','Define export options available on OPAC detail page.','multiple'),
467
('OPACFallback', 'prog', 'bootstrap|prog', 'Define the fallback theme for the OPAC interface.', 'Themes'),
468
('OPACFallback', 'prog', 'bootstrap|prog', 'Define the fallback theme for the OPAC interface.', 'Themes'),
468
('OpacFavicon','','','Enter a complete URL to an image to replace the default Koha favicon on the OPAC','free'),
469
('OpacFavicon','','','Enter a complete URL to an image to replace the default Koha favicon on the OPAC','free'),
469
('OPACFineNoRenewals','100','','Fine limit above which user cannot renew books via OPAC','Integer'),
470
('OPACFineNoRenewals','100','','Fine limit above which user cannot renew books via OPAC','Integer'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc (-1 / +1 lines)
Lines 107-113 Link Here
107
        <li><a href="/cgi-bin/koha/catalogue/export.pl?format=mods&amp;op=export&amp;bib=[% biblionumber | uri %]">MODS (XML)</a></li>
107
        <li><a href="/cgi-bin/koha/catalogue/export.pl?format=mods&amp;op=export&amp;bib=[% biblionumber | uri %]">MODS (XML)</a></li>
108
        <li><a href="/cgi-bin/koha/catalogue/export.pl?format=ris&amp;op=export&amp;bib=[% biblionumber | uri %]">RIS</a></li>
108
        <li><a href="/cgi-bin/koha/catalogue/export.pl?format=ris&amp;op=export&amp;bib=[% biblionumber | uri %]">RIS</a></li>
109
        [% FOREACH filesOption IN filesOptions %]
109
        [% FOREACH filesOption IN filesOptions %]
110
            <li><a href="/cgi-bin/koha/catalogue/export.pl?format=[% filesOption.format | uri %]&amp;op=exportxsl&amp;file=[% filesOption.value | uri %]&amp;bib=[% biblionumber | uri %]">XSL - [% filesOption.filename | html %]</a></li>
110
            <li><a href="/cgi-bin/koha/catalogue/export.pl?format=[% filesOption.format | uri %]&amp;op=exportxsl&amp;file=[% filesOption.value | uri %]&amp;bib=[% biblionumber | uri %]">[% filesOption.filename | html %]</a></li>
111
        [% END %]
111
        [% END %]
112
    </ul>
112
    </ul>
113
    </div>
113
    </div>
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/virtualshelves-toolbar.inc (-1 / +1 lines)
Lines 39-45 Link Here
39
                        <li><a href="/cgi-bin/koha/virtualshelves/downloadshelf.pl?format=[% csv_profile.export_format_id | uri %]&amp;shelfid=[% shelf.shelfnumber | uri %]">CSV - [% csv_profile.profile | html %]</a></li>
39
                        <li><a href="/cgi-bin/koha/virtualshelves/downloadshelf.pl?format=[% csv_profile.export_format_id | uri %]&amp;shelfid=[% shelf.shelfnumber | uri %]">CSV - [% csv_profile.profile | html %]</a></li>
40
                    [% END %]
40
                    [% END %]
41
                    [% FOREACH xsl_export IN xsl_exports %]
41
                    [% FOREACH xsl_export IN xsl_exports %]
42
                        <li><a href="/cgi-bin/koha/virtualshelves/downloadshelf.pl?format=xsl.[% xsl_export.value | uri %]&amp;file=[% xsl_export.value | uri %]&amp;shelfid=[% shelf.shelfnumber | uri %]">XSL - [% xsl_export.filename | html %]</a></li>
42
                        <li><a href="/cgi-bin/koha/virtualshelves/downloadshelf.pl?format=xsl.[% xsl_export.value | uri %]&amp;file=[% xsl_export.value | uri %]&amp;shelfid=[% shelf.shelfnumber | uri %]">[% xsl_export.filename | html %]</a></li>
43
                    [% END %]
43
                    [% END %]
44
                </ul>
44
                </ul>
45
        </div>
45
        </div>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref (+5 lines)
Lines 384-389 Cataloging: Link Here
384
            - "All values of repeating tags and subfields will be printed with the given BibTeX tag."
384
            - "All values of repeating tags and subfields will be printed with the given BibTeX tag."
385
            - "<br/>"
385
            - "<br/>"
386
            - "Use '@' ( with quotes ) as the BT_TAG to replace the bibtex record type with a field value of your choosing."
386
            - "Use '@' ( with quotes ) as the BT_TAG to replace the bibtex record type with a field value of your choosing."
387
        -
388
            - "Use this"
389
            - pref: CustomXSLTExportPath
390
              class: long
391
            - "as the path containing the customized XSL files for export (write the complete path)."
387
        -
392
        -
388
            - "Include the following fields when exporting RIS:"
393
            - "Include the following fields when exporting RIS:"
389
            - pref: RisExportAdditionalFields
394
            - pref: RisExportAdditionalFields
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref (-1 / +1 lines)
Lines 280-286 OPAC: Link Here
280
                mods: MODS
280
                mods: MODS
281
                ris: RIS
281
                ris: RIS
282
                isbd: ISBD
282
                isbd: ISBD
283
                custom: XSL - Simple Export
283
                custom: Simple HTML formats
284
        -
284
        -
285
            - pref: OpacSeparateHoldings
285
            - pref: OpacSeparateHoldings
286
              choices:
286
              choices:
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/basket/basket.tt (-1 / +1 lines)
Lines 64-70 Link Here
64
                                <li><a href="/cgi-bin/koha/basket/downloadcart.pl?format=[% csv_profile.export_format_id | uri %]&amp;bib_list=[% bib_list | uri %]">CSV - [% csv_profile.profile | html %]</a></li>
64
                                <li><a href="/cgi-bin/koha/basket/downloadcart.pl?format=[% csv_profile.export_format_id | uri %]&amp;bib_list=[% bib_list | uri %]">CSV - [% csv_profile.profile | html %]</a></li>
65
                            [% END %]
65
                            [% END %]
66
                            [% FOREACH xsl_export IN xsl_exports %]
66
                            [% FOREACH xsl_export IN xsl_exports %]
67
                                <li><a href="/cgi-bin/koha/basket/downloadcart.pl?format=xsl.[% xsl_export.value | uri %]&amp;file=[% xsl_export.value | uri %]&amp;bib_list=[% bib_list | uri %]">XSL - [% xsl_export.filename | html %]</a></li>
67
                                <li><a href="/cgi-bin/koha/basket/downloadcart.pl?format=xsl.[% xsl_export.value | uri %]&amp;file=[% xsl_export.value | uri %]&amp;bib_list=[% bib_list | uri %]">[% xsl_export.filename | html %]</a></li>
68
                            [% END %]
68
                            [% END %]
69
                            </ul>
69
                            </ul>
70
                        </div>
70
                        </div>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt (-1 / +1 lines)
Lines 1099-1105 Link Here
1099
        <option value="marc8">MARC (non-Unicode/MARC-8)</option>
1099
        <option value="marc8">MARC (non-Unicode/MARC-8)</option>
1100
        <option value="utf8">MARC (Unicode/UTF-8)</option>
1100
        <option value="utf8">MARC (Unicode/UTF-8)</option>
1101
        [% FOREACH filesOption IN filesOptions %]
1101
        [% FOREACH filesOption IN filesOptions %]
1102
            <option value="[% filesOption.value | html %]">XSL -[% filesOption.filename | html %]</option>
1102
            <option value="[% filesOption.value | html %]">[% filesOption.filename | html %]</option>
1103
        [% END %]</select>
1103
        [% END %]</select>
1104
        <input type="submit" name="save" class="btn btn-primary" value="Download record" /></td>
1104
        <input type="submit" name="save" class="btn btn-primary" value="Download record" /></td>
1105
  </tr>
1105
  </tr>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/virtualshelves/downloadshelf.tt (-1 / +1 lines)
Lines 43-49 Link Here
43
	    <option value="[% csv_profile.export_format_id | html %]">CSV - [% csv_profile.profile | html %]</option>
43
	    <option value="[% csv_profile.export_format_id | html %]">CSV - [% csv_profile.profile | html %]</option>
44
	    [% END %]
44
	    [% END %]
45
        [% FOREACH xsl_export IN xsl_exports %]
45
        [% FOREACH xsl_export IN xsl_exports %]
46
            <option value="xsl.[% xsl_export.value | html %]">XSL - [% xsl_export.filename | html %]</option>
46
            <option value="xsl.[% xsl_export.value | html %]">[% xsl_export.filename | html %]</option>
47
        [% END %]
47
        [% END %]
48
	</select>
48
	</select>
49
	</li></ol>
49
	</li></ol>
(-)a/koha-tmpl/intranet-tmpl/prog/en/xslt/biblioexport/MARC21_simple_export.xsl (-52 / +79 lines)
Lines 1-62 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
1
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
3
<!DOCTYPE stylesheet>
4
2
<xsl:stylesheet version="1.0"
5
<xsl:stylesheet version="1.0"
3
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
6
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
4
   xmlns:marc="http://www.loc.gov/MARC21/slim"
7
    xmlns:marc="http://www.loc.gov/MARC21/slim"
5
   title="Simple Export">
8
    exclude-result-prefixes="marc"
6
<xsl:output method="html" encoding="UTF-8"/>
9
    title="Simple Export">
10
11
    <xsl:output
12
        method="html"
13
        indent="yes"
14
        encoding="UTF-8"/>
7
15
8
    <xsl:template match="/">
16
    <xsl:template match="/">
9
      <xsl:apply-templates/>
17
        <xsl:text disable-output-escaping='yes'>&lt;!DOCTYPE html&gt;</xsl:text>
18
19
        <html lang="en">
20
            <head>
21
                <meta http-equiv="Content-Type" content="text/html"/>
22
                <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
23
                <title>Simple Export</title>
24
            </head>
25
26
            <body>
27
                <xsl:apply-templates/>
28
            </body>
29
        </html>
10
    </xsl:template>
30
    </xsl:template>
11
31
12
    <xsl:template match="marc:record">
32
    <xsl:template match="marc:record">
13
      <p>
33
        <p>
14
        <xsl:if test="marc:datafield[@tag=245]">
34
            <xsl:if test="marc:datafield[@tag=245]">
15
        <xsl:for-each select="marc:datafield[@tag=245]">
35
                <xsl:for-each select="marc:datafield[@tag=245]">
16
            <xsl:value-of select="marc:subfield[@code='a']"/>
36
                    <xsl:value-of select="marc:subfield[@code='a']"/>
17
            <xsl:if test="marc:subfield[@code='b']">
37
18
                 <xsl:text> </xsl:text>
38
                    <xsl:if test="marc:subfield[@code='b']">
19
                 <xsl:value-of select="marc:subfield[@code='b']"></xsl:value-of>
39
                        <xsl:text> </xsl:text>
20
            </xsl:if>
40
                        <xsl:value-of select="marc:subfield[@code='b']"></xsl:value-of>
21
            <xsl:if test="marc:subfield[@code='c']">
41
                    </xsl:if>
22
                  <xsl:text> </xsl:text>
42
23
                  <xsl:value-of select="marc:subfield[@code='c']"></xsl:value-of>
43
                    <xsl:if test="marc:subfield[@code='c']">
24
            </xsl:if>
44
                        <xsl:text> </xsl:text>
25
        </xsl:for-each>
45
                        <xsl:value-of select="marc:subfield[@code='c']"></xsl:value-of>
26
        </xsl:if>
46
                    </xsl:if>
27
        <xsl:if test="marc:datafield[@tag=260]">
47
                </xsl:for-each>
28
        <br/>
29
        <xsl:for-each select="marc:datafield[@tag=260]">
30
            <xsl:if test="marc:subfield[@code='a']">
31
                 <xsl:value-of select="marc:subfield[@code='a']"/>
32
            </xsl:if>
33
            <xsl:if test="marc:subfield[@code='b']">
34
                 <xsl:text> </xsl:text>
35
                 <xsl:value-of select="marc:subfield[@code='b']"></xsl:value-of>
36
            </xsl:if>
37
            <xsl:if test="marc:subfield[@code='c']">
38
                  <xsl:text> </xsl:text>
39
                  <xsl:value-of select="marc:subfield[@code='c']"></xsl:value-of>
40
            </xsl:if>
41
        </xsl:for-each>
42
        </xsl:if>
43
        <xsl:if test="marc:datafield[@tag=264]">
44
        <br/>
45
        <xsl:for-each select="marc:datafield[@tag=264]">
46
            <xsl:if test="marc:subfield[@code='a']">
47
                 <xsl:value-of select="marc:subfield[@code='a']"/>
48
            </xsl:if>
48
            </xsl:if>
49
            <xsl:if test="marc:subfield[@code='b']">
49
50
                 <xsl:text> </xsl:text>
50
            <xsl:if test="marc:datafield[@tag=260]">
51
                 <xsl:value-of select="marc:subfield[@code='b']"></xsl:value-of>
51
                <br/>
52
                <xsl:for-each select="marc:datafield[@tag=260]">
53
                    <xsl:if test="marc:subfield[@code='a']">
54
                        <xsl:value-of select="marc:subfield[@code='a']"/>
55
                    </xsl:if>
56
57
                    <xsl:if test="marc:subfield[@code='b']">
58
                        <xsl:text> </xsl:text>
59
                        <xsl:value-of select="marc:subfield[@code='b']"></xsl:value-of>
60
                    </xsl:if>
61
62
                    <xsl:if test="marc:subfield[@code='c']">
63
                        <xsl:text> </xsl:text>
64
                        <xsl:value-of select="marc:subfield[@code='c']"></xsl:value-of>
65
                    </xsl:if>
66
                </xsl:for-each>
52
            </xsl:if>
67
            </xsl:if>
53
            <xsl:if test="marc:subfield[@code='c']">
68
54
                  <xsl:text> </xsl:text>
69
            <xsl:if test="marc:datafield[@tag=264]">
55
                  <xsl:value-of select="marc:subfield[@code='c']"></xsl:value-of>
70
                <br/>
71
                <xsl:for-each select="marc:datafield[@tag=264]">
72
                    <xsl:if test="marc:subfield[@code='a']">
73
                        <xsl:value-of select="marc:subfield[@code='a']"/>
74
                    </xsl:if>
75
76
                    <xsl:if test="marc:subfield[@code='b']">
77
                        <xsl:text> </xsl:text>
78
                        <xsl:value-of select="marc:subfield[@code='b']"></xsl:value-of>
79
                    </xsl:if>
80
81
                    <xsl:if test="marc:subfield[@code='c']">
82
                        <xsl:text> </xsl:text>
83
                        <xsl:value-of select="marc:subfield[@code='c']"></xsl:value-of>
84
                    </xsl:if>
85
                </xsl:for-each>
56
            </xsl:if>
86
            </xsl:if>
57
        </xsl:for-each>
87
        </p>
58
        </xsl:if>
59
      </p>
60
    </xsl:template>
88
    </xsl:template>
61
89
</xsl:stylesheet>
62
</xsl:stylesheet>
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-detail-sidebar.inc (-1 / +1 lines)
Lines 87-93 Link Here
87
                                </a>
87
                                </a>
88
                            [% ELSE %]
88
                            [% ELSE %]
89
                                [% FOREACH filesOption IN filesOptions %]
89
                                [% FOREACH filesOption IN filesOptions %]
90
                                    <a href="/cgi-bin/koha/opac-export.pl?format=[% filesOption.format | html %]&amp;op=exportxsl&amp;file=[% filesOption.value | html %]&amp;bib=[% biblionumber | html %]" >XSL - [% filesOption.filename | html %]</a>
90
                                    <a href="/cgi-bin/koha/opac-export.pl?format=[% filesOption.format | url %]&amp;op=exportxsl&amp;file=[% filesOption.value | url %]&amp;bib=[% biblionumber | url %]" >[% filesOption.filename | html %]</a>
91
                                [% END %]
91
                                [% END %]
92
                            [% END %]
92
                            [% END %]
93
                        [% END %]
93
                        [% END %]
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-basket.tt (-1 / +1 lines)
Lines 44-50 Link Here
44
                                        [% FOREACH option IN export_options %]
44
                                        [% FOREACH option IN export_options %]
45
                                            [% IF option == 'custom' %]
45
                                            [% IF option == 'custom' %]
46
                                                [% FOREACH xsl_export IN xsl_exports %]
46
                                                [% FOREACH xsl_export IN xsl_exports %]
47
                                                    <a role="menuitem" class="dropdown-item" href="/cgi-bin/koha/opac-downloadcart.pl?format=xsl.[% xsl_export.value | uri %]&amp;file=[% xsl_export.value | uri %]&amp;bib_list=[% bib_list | uri %]">XSL - [% xsl_export.filename | html %]</a></li>
47
                                                    <a role="menuitem" class="dropdown-item" href="/cgi-bin/koha/opac-downloadcart.pl?format=xsl.[% xsl_export.value | uri %]&amp;file=[% xsl_export.value | uri %]&amp;bib_list=[% bib_list | uri %]">[% xsl_export.filename | html %]</a></li>
48
                                                [% END %]
48
                                                [% END %]
49
                                            [% END %]
49
                                            [% END %]
50
                                        [% END %]
50
                                        [% END %]
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-downloadcart.tt (-1 / +1 lines)
Lines 21-27 Link Here
21
                                    <option value="[% csv_profile.export_format_id | html %]">CSV - [% csv_profile.profile | html %]</option>
21
                                    <option value="[% csv_profile.export_format_id | html %]">CSV - [% csv_profile.profile | html %]</option>
22
                                [% END %]
22
                                [% END %]
23
                                [% FOREACH xsl_export IN xsl_exports %]
23
                                [% FOREACH xsl_export IN xsl_exports %]
24
                                    <option value="xsl.[% xsl_export.value | html %]">XSL - [% xsl_export.filename | html %]</option>
24
                                    <option value="xsl.[% xsl_export.value | html %]">[% xsl_export.filename | html %]</option>
25
                                [% END %]
25
                                [% END %]
26
                            </select>
26
                            </select>
27
                            <fieldset class="action">
27
                            <fieldset class="action">
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-downloadshelf.tt (-1 / +1 lines)
Lines 69-75 Link Here
69
                                            <option value="[% csv_profile.export_format_id | html %]">CSV - [% csv_profile.profile | html %]</option>
69
                                            <option value="[% csv_profile.export_format_id | html %]">CSV - [% csv_profile.profile | html %]</option>
70
                                            [% END %]
70
                                            [% END %]
71
                                            [% FOREACH xsl_export IN xsl_exports %]
71
                                            [% FOREACH xsl_export IN xsl_exports %]
72
                                                <option value="xsl.[% xsl_export.value | html %]">XSL - [% xsl_export.filename | html %]</option>
72
                                                <option value="xsl.[% xsl_export.value | html %]">[% xsl_export.filename | html %]</option>
73
                                            [% END %]
73
                                            [% END %]
74
                                        </select>
74
                                        </select>
75
                                        <span class="required">Required</span>
75
                                        <span class="required">Required</span>
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-shelves.tt (-1 / +1 lines)
Lines 237-243 Link Here
237
                                                [% FOREACH option IN export_options %]
237
                                                [% FOREACH option IN export_options %]
238
                                                    [% IF option == 'custom' %]
238
                                                    [% IF option == 'custom' %]
239
                                                        [% FOREACH xsl_export IN xsl_exports %]
239
                                                        [% FOREACH xsl_export IN xsl_exports %]
240
                                                            <a role="menuitem" class="dropdown-item" href="/cgi-bin/koha/opac-downloadshelf.pl?format=xsl.[% xsl_export.value | uri %]&amp;file=[% xsl_export.value | uri %]&amp;shelfnumber=[% shelf.shelfnumber | uri %]">XSL - [% xsl_export.filename | html %]</a></li>
240
                                                            <a role="menuitem" class="dropdown-item" href="/cgi-bin/koha/opac-downloadshelf.pl?format=xsl.[% xsl_export.value | uri %]&amp;file=[% xsl_export.value | uri %]&amp;shelfnumber=[% shelf.shelfnumber | uri %]">[% xsl_export.filename | html %]</a></li>
241
                                                        [% END %]
241
                                                        [% END %]
242
                                                    [% END %]
242
                                                    [% END %]
243
                                                [% END %]
243
                                                [% END %]
(-)a/opac/opac-basket.pl (-45 / +46 lines)
Lines 37-43 use Koha::Items; Link Here
37
37
38
my $query = CGI->new;
38
my $query = CGI->new;
39
39
40
my ( $template, $borrowernumber, $cookie ) = get_template_and_user (
40
my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
41
    {
41
    {
42
        template_name   => "opac-basket.tt",
42
        template_name   => "opac-basket.tt",
43
        query           => $query,
43
        query           => $query,
Lines 46-109 my ( $template, $borrowernumber, $cookie ) = get_template_and_user ( Link Here
46
    }
46
    }
47
);
47
);
48
48
49
my $bib_list     = $query->param('bib_list');
49
my $bib_list = $query->param('bib_list');
50
my $verbose      = $query->param('verbose');
50
my $verbose  = $query->param('verbose');
51
51
52
if ($verbose)      { $template->param( verbose      => 1 ); }
52
if ($verbose) { $template->param( verbose => 1 ); }
53
53
54
my @bibs = split( /\//, $bib_list );
54
my @bibs = split( /\//, $bib_list );
55
my @results;
55
my @results;
56
56
57
my $num = 1;
57
my $num         = 1;
58
my $marcflavour = C4::Context->preference('marcflavour');
58
my $marcflavour = C4::Context->preference('marcflavour');
59
if (C4::Context->preference('TagsEnabled')) {
59
if ( C4::Context->preference('TagsEnabled') ) {
60
	$template->param(TagsEnabled => 1);
60
    $template->param( TagsEnabled => 1 );
61
	foreach (qw(TagsShowOnList TagsInputOnList)) {
61
    foreach (qw(TagsShowOnList TagsInputOnList)) {
62
		C4::Context->preference($_) and $template->param($_ => 1);
62
        C4::Context->preference($_) and $template->param( $_ => 1 );
63
	}
63
    }
64
}
64
}
65
65
66
my $logged_in_user = Koha::Patrons->find($borrowernumber);
66
my $logged_in_user = Koha::Patrons->find($borrowernumber);
67
67
68
my $record_processor = Koha::RecordProcessor->new({ filters => 'ViewPolicy' });
68
my $record_processor = Koha::RecordProcessor->new( { filters => 'ViewPolicy' } );
69
my $rules = C4::Context->yaml_preference('OpacHiddenItems');
69
my $rules            = C4::Context->yaml_preference('OpacHiddenItems');
70
70
71
foreach my $biblionumber ( @bibs ) {
71
foreach my $biblionumber (@bibs) {
72
    $template->param( biblionumber => $biblionumber );
72
    $template->param( biblionumber => $biblionumber );
73
73
74
    my $biblio           = Koha::Biblios->find( $biblionumber ) or next;
74
    my $biblio = Koha::Biblios->find($biblionumber) or next;
75
    my $dat = { %{$biblio->unblessed}, %{$biblio->biblioitem->unblessed} };
75
    my $dat    = { %{ $biblio->unblessed }, %{ $biblio->biblioitem->unblessed } };
76
76
77
    # No filtering on the item records needed for the record itself
77
    # No filtering on the item records needed for the record itself
78
    # since the only reason item information is grabbed is because of branchcodes.
78
    # since the only reason item information is grabbed is because of branchcodes.
79
    my $record = $biblio->metadata->record;
79
    my $record    = $biblio->metadata->record;
80
    my $framework = &GetFrameworkCode( $biblionumber );
80
    my $framework = &GetFrameworkCode($biblionumber);
81
    $record_processor->options({
81
    $record_processor->options(
82
        interface => 'opac',
82
        {
83
        frameworkcode => $framework
83
            interface     => 'opac',
84
    });
84
            frameworkcode => $framework
85
        }
86
    );
85
    $record_processor->process($record);
87
    $record_processor->process($record);
86
    next unless $record;
88
    next unless $record;
87
    my $marcnotesarray   = $biblio->get_marc_notes({ opac => 1 });
89
    my $marcnotesarray   = $biblio->get_marc_notes( { opac => 1 } );
88
    my $marcauthorsarray = $biblio->get_marc_contributors;
90
    my $marcauthorsarray = $biblio->get_marc_contributors;
89
    my $marcsubjctsarray = GetMarcSubjects( $record, $marcflavour );
91
    my $marcsubjctsarray = GetMarcSubjects( $record, $marcflavour );
90
    my $marcseriesarray  = GetMarcSeries  ($record,$marcflavour);
92
    my $marcseriesarray  = GetMarcSeries( $record, $marcflavour );
91
    my $marcurlsarray    = GetMarcUrls    ($record,$marcflavour);
93
    my $marcurlsarray    = GetMarcUrls( $record, $marcflavour );
92
94
93
    # If every item is hidden, then the biblio should be hidden too.
95
    # If every item is hidden, then the biblio should be hidden too.
94
    next
96
    next
95
      if $biblio->hidden_in_opac({ rules => $rules });
97
        if $biblio->hidden_in_opac( { rules => $rules } );
96
98
97
    my $hasauthors = 0;
99
    my $hasauthors = 0;
98
    if($dat->{'author'} || @$marcauthorsarray) {
100
    if ( $dat->{'author'} || @$marcauthorsarray ) {
99
      $hasauthors = 1;
101
        $hasauthors = 1;
100
    }
102
    }
101
103
102
	# COinS format FIXME: for books Only
104
    # COinS format FIXME: for books Only
103
        my $fmt = substr $record->leader(), 6,2;
105
    my $fmt = substr $record->leader(), 6, 2;
104
        my $fmts;
106
    my $fmts;
105
        $fmts->{'am'} = 'book';
107
    $fmts->{'am'}         = 'book';
106
        $dat->{ocoins_format} = $fmts->{$fmt};
108
    $dat->{ocoins_format} = $fmts->{$fmt};
107
109
108
    if ( $num % 2 == 1 ) {
110
    if ( $num % 2 == 1 ) {
109
        $dat->{'even'} = 1;
111
        $dat->{'even'} = 1;
Lines 111-127 foreach my $biblionumber ( @bibs ) { Link Here
111
113
112
    $num++;
114
    $num++;
113
    $dat->{biblionumber} = $biblionumber;
115
    $dat->{biblionumber} = $biblionumber;
114
    $dat->{ITEM_RESULTS}   = $biblio->items->filter_by_visible_in_opac({ patron => $logged_in_user });
116
    $dat->{ITEM_RESULTS} = $biblio->items->filter_by_visible_in_opac( { patron => $logged_in_user } );
115
    $dat->{MARCNOTES}      = $marcnotesarray;
117
    $dat->{MARCNOTES}    = $marcnotesarray;
116
    $dat->{MARCSUBJCTS}    = $marcsubjctsarray;
118
    $dat->{MARCSUBJCTS}  = $marcsubjctsarray;
117
    $dat->{MARCAUTHORS}    = $marcauthorsarray;
119
    $dat->{MARCAUTHORS}  = $marcauthorsarray;
118
    $dat->{MARCSERIES}  = $marcseriesarray;
120
    $dat->{MARCSERIES}   = $marcseriesarray;
119
    $dat->{MARCURLS}    = $marcurlsarray;
121
    $dat->{MARCURLS}     = $marcurlsarray;
120
    $dat->{HASAUTHORS}  = $hasauthors;
122
    $dat->{HASAUTHORS}   = $hasauthors;
121
    my ( $host, $relatedparts, $hostinfo ) = $biblio->get_marc_host;
123
    my ( $host, $relatedparts, $hostinfo ) = $biblio->get_marc_host;
122
    $dat->{HOSTITEMENTRIES} = $host;
124
    $dat->{HOSTITEMENTRIES} = $host;
123
    $dat->{RELATEDPARTS} = $relatedparts;
125
    $dat->{RELATEDPARTS}    = $relatedparts;
124
    $dat->{HOSTINFO} = $hostinfo;
126
    $dat->{HOSTINFO}        = $hostinfo;
125
127
126
    push( @results, $dat );
128
    push( @results, $dat );
127
}
129
}
Lines 131-141 my $resultsarray = \@results; Link Here
131
# my $itemsarray=\@items;
133
# my $itemsarray=\@items;
132
134
133
$template->param(
135
$template->param(
134
    csv_profiles => Koha::CsvProfiles->search(
136
    csv_profiles   => Koha::CsvProfiles->search( { type => 'marc', used_for => 'export_records', staff_only => 0 } ),
135
        { type => 'marc', used_for => 'export_records', staff_only => 0 } ),
137
    bib_list       => $bib_list,
136
    bib_list => $bib_list,
137
    BIBLIO_RESULTS => $resultsarray,
138
    BIBLIO_RESULTS => $resultsarray,
138
    xsl_exports => CustomXSLTExportList(),
139
    xsl_exports    => CustomXSLTExportList(),
139
);
140
);
140
141
141
output_html_with_http_headers $query, $cookie, $template->output, undef, { force_no_caching => 1 };
142
output_html_with_http_headers $query, $cookie, $template->output, undef, { force_no_caching => 1 };
(-)a/opac/opac-detail.pl (-1 / +1 lines)
Lines 103-109 my ( $template, $borrowernumber, $cookie ) = get_template_and_user( Link Here
103
    }
103
    }
104
);
104
);
105
105
106
$template->param(filesOptions => CustomXSLTExportList(1));
106
$template->param( filesOptions => CustomXSLTExportList(1) );
107
107
108
my $patron = Koha::Patrons->find( $borrowernumber );
108
my $patron = Koha::Patrons->find( $borrowernumber );
109
109
(-)a/opac/opac-downloadcart.pl (-48 / +49 lines)
Lines 36-42 use Koha::RecordProcessor; Link Here
36
use utf8;
36
use utf8;
37
my $query = CGI->new();
37
my $query = CGI->new();
38
38
39
my ( $template, $borrowernumber, $cookie ) = get_template_and_user (
39
my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
40
    {
40
    {
41
        template_name   => "opac-downloadcart.tt",
41
        template_name   => "opac-downloadcart.tt",
42
        query           => $query,
42
        query           => $query,
Lines 46-55 my ( $template, $borrowernumber, $cookie ) = get_template_and_user ( Link Here
46
);
46
);
47
47
48
my $bib_list = $query->param('bib_list');
48
my $bib_list = $query->param('bib_list');
49
my $format  = $query->param('format');
49
my $format   = $query->param('format');
50
my $dbh     = C4::Context->dbh;
50
my $dbh      = C4::Context->dbh;
51
51
52
if ($bib_list && $format) {
52
if ( $bib_list && $format ) {
53
53
54
    my $patron = Koha::Patrons->find($borrowernumber);
54
    my $patron = Koha::Patrons->find($borrowernumber);
55
55
Lines 60-67 if ($bib_list && $format) { Link Here
60
    my $extension;
60
    my $extension;
61
    my $type;
61
    my $type;
62
62
63
    # CSV   
63
    # CSV
64
    if ($format =~ /^\d+$/) {
64
    if ( $format =~ /^\d+$/ ) {
65
65
66
        my $csv_profile = Koha::CsvProfiles->find($format);
66
        my $csv_profile = Koha::CsvProfiles->find($format);
67
        if ( not $csv_profile or $csv_profile->staff_only ) {
67
        if ( not $csv_profile or $csv_profile->staff_only ) {
Lines 69-81 if ($bib_list && $format) { Link Here
69
            exit;
69
            exit;
70
        }
70
        }
71
71
72
        $output = marc2csv(\@bibs, $format);
72
        $output = marc2csv( \@bibs, $format );
73
73
74
        # Other formats
74
        # Other formats
75
    } else {
75
    } else {
76
        my $record_processor = Koha::RecordProcessor->new({
76
        my $record_processor = Koha::RecordProcessor->new( { filters => 'ViewPolicy' } );
77
            filters => 'ViewPolicy'
78
        });
79
        foreach my $biblionumber (@bibs) {
77
        foreach my $biblionumber (@bibs) {
80
78
81
            my $biblio = Koha::Biblios->find($biblionumber);
79
            my $biblio = Koha::Biblios->find($biblionumber);
Lines 86-147 if ($bib_list && $format) { Link Here
86
                    patron      => $patron,
84
                    patron      => $patron,
87
                }
85
                }
88
            );
86
            );
89
            my $xslFile = $query->param("file");
87
            my $xslFile   = $query->param("file");
90
            my $framework = &GetFrameworkCode( $biblio );
88
            my $framework = &GetFrameworkCode($biblio);
91
            $record_processor->options({
89
            $record_processor->options(
92
                interface => 'opac',
90
                {
93
                frameworkcode => $framework
91
                    interface     => 'opac',
94
            });
92
                    frameworkcode => $framework
93
                }
94
            );
95
            $record_processor->process($record);
95
            $record_processor->process($record);
96
96
97
            next unless $record;
97
            next unless $record;
98
98
99
            if ($format eq 'iso2709') {
99
            if ( $format eq 'iso2709' ) {
100
100
                #NOTE: If we don't explicitly UTF-8 encode the output,
101
                #NOTE: If we don't explicitly UTF-8 encode the output,
101
                #the browser will guess the encoding, and it won't always choose UTF-8.
102
                #the browser will guess the encoding, and it won't always choose UTF-8.
102
                $output .= encode("UTF-8", $record->as_usmarc()) // q{};
103
                $output .= encode( "UTF-8", $record->as_usmarc() ) // q{};
103
            }
104
            } elsif ( $format eq 'ris' ) {
104
            elsif ($format eq 'ris') {
105
                $output .= marc2ris($record);
105
                $output .= marc2ris($record);
106
            }
106
            } elsif ( $format eq 'bibtex' ) {
107
            elsif ($format eq 'bibtex') {
107
                $output .= marc2bibtex( $record, $biblio );
108
                $output .= marc2bibtex($record, $biblio);
108
            } elsif ( $format eq 'isbd' ) {
109
            }
109
                my $framework = GetFrameworkCode($biblio);
110
            elsif ( $format eq 'isbd' ) {
110
                $output .= GetISBDView(
111
                my $framework = GetFrameworkCode( $biblio );
111
                    {
112
                $output   .= GetISBDView({
112
                        'record'    => $record,
113
                    'record'    => $record,
113
                        'template'  => 'opac',
114
                    'template'  => 'opac',
114
                        'framework' => $framework,
115
                    'framework' => $framework,
115
                    }
116
                });
116
                );
117
                $extension = "txt";
117
                $extension = "txt";
118
                $type      = "text/plain";
118
                $type      = "text/plain";
119
            }
119
            } elsif ( $format =~ /^xsl\.(.*)$/ ) {
120
            elsif ($format =~ /^xsl\.(.*)$/) {
120
                $output .= XSLTParse4Display(
121
                $output .= XSLTParse4Display({
121
                    {
122
                    biblionumber   => $biblio,
122
                        biblionumber => $biblio,
123
                    record         => $record,
123
                        record       => $record,
124
                    xsl_syspref    => "OPACXSLTCustomExport",
124
                        xsl_syspref  => "OPACXSLTCustomExport",
125
                    fix_amps       => 1,
125
                        fix_amps     => 1,
126
                    hidden_items => undef,
126
                        hidden_items => undef,
127
                    xslfilename  => $xslFile,
127
                        xslfilename  => $xslFile,
128
                });
128
                    }
129
                );
129
            }
130
            }
130
        }
131
        }
131
    }
132
    }
132
133
133
    # If it was a CSV export we change the format after the export so the file extension is fine
134
    # If it was a CSV export we change the format after the export so the file extension is fine
134
    $format = "csv" if ($format =~ m/^\d+$/);
135
    $format = "csv"  if ( $format =~ m/^\d+$/ );
135
    $format = "html" if ($format =~ /^xsl\./);
136
    $format = "html" if ( $format =~ /^xsl\./ );
136
137
137
    print $query->header(
138
    print $query->header(
138
                               -type => ($type) ? $type : 'application/octet-stream',
139
        -type                        => ($type) ? $type : 'application/octet-stream',
139
        -'Content-Transfer-Encoding' => 'binary',
140
        -'Content-Transfer-Encoding' => 'binary',
140
                         -attachment => ($extension) ? "cart.$format.$extension" : "cart.$format"
141
        -attachment                  => ($extension) ? "cart.$format.$extension" : "cart.$format"
141
    );
142
    );
142
    print $output;
143
    print $output;
143
144
144
} else { 
145
} else {
145
    $template->param(
146
    $template->param(
146
        csv_profiles => Koha::CsvProfiles->search(
147
        csv_profiles => Koha::CsvProfiles->search(
147
            {
148
            {
Lines 152-158 if ($bib_list && $format) { Link Here
152
        ),
153
        ),
153
        bib_list => $bib_list,
154
        bib_list => $bib_list,
154
    );
155
    );
155
    $template->param(bib_list => $bib_list);
156
    $template->param( bib_list    => $bib_list );
156
    $template->param(xsl_exports => CustomXSLTExportList());
157
    $template->param( xsl_exports => CustomXSLTExportList() );
157
    output_html_with_http_headers $query, $cookie, $template->output;
158
    output_html_with_http_headers $query, $cookie, $template->output;
158
}
159
}
(-)a/opac/opac-downloadshelf.pl (-48 / +47 lines)
Lines 37-48 use utf8; Link Here
37
my $query = CGI->new;
37
my $query = CGI->new;
38
38
39
# if virtualshelves is disabled, leave immediately
39
# if virtualshelves is disabled, leave immediately
40
if ( ! C4::Context->preference('virtualshelves') ) {
40
if ( !C4::Context->preference('virtualshelves') ) {
41
    print $query->redirect("/cgi-bin/koha/errors/404.pl");
41
    print $query->redirect("/cgi-bin/koha/errors/404.pl");
42
    exit;
42
    exit;
43
}
43
}
44
44
45
my ( $template, $borrowernumber, $cookie ) = get_template_and_user (
45
my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
46
    {
46
    {
47
        template_name   => "opac-downloadshelf.tt",
47
        template_name   => "opac-downloadshelf.tt",
48
        query           => $query,
48
        query           => $query,
Lines 51-76 my ( $template, $borrowernumber, $cookie ) = get_template_and_user ( Link Here
51
    }
51
    }
52
);
52
);
53
53
54
my $patron = Koha::Patrons->find( $borrowernumber );
54
my $patron = Koha::Patrons->find($borrowernumber);
55
55
56
my $shelfnumber = $query->param('shelfnumber');
56
my $shelfnumber = $query->param('shelfnumber');
57
my $format  = $query->param('format');
57
my $format      = $query->param('format');
58
my $context = $query->param('context');
58
my $context     = $query->param('context');
59
59
60
my $shelf = Koha::Virtualshelves->find( $shelfnumber );
60
my $shelf = Koha::Virtualshelves->find($shelfnumber);
61
if ( $shelf and $shelf->can_be_viewed( $borrowernumber ) ) {
61
if ( $shelf and $shelf->can_be_viewed($borrowernumber) ) {
62
62
63
    if ($shelfnumber && $format) {
63
    if ( $shelfnumber && $format ) {
64
64
65
65
        my $contents    = $shelf->get_contents;
66
        my $contents = $shelf->get_contents;
67
        my $marcflavour = C4::Context->preference('marcflavour');
66
        my $marcflavour = C4::Context->preference('marcflavour');
68
        my $output;
67
        my $output;
69
        my $extension;
68
        my $extension;
70
        my $type;
69
        my $type;
71
70
72
       # CSV
71
        # CSV
73
        if ($format =~ /^\d+$/) {
72
        if ( $format =~ /^\d+$/ ) {
74
73
75
            my $csv_profile = Koha::CsvProfiles->find($format);
74
            my $csv_profile = Koha::CsvProfiles->find($format);
76
            if ( not $csv_profile or $csv_profile->staff_only ) {
75
            if ( not $csv_profile or $csv_profile->staff_only ) {
Lines 82-93 if ( $shelf and $shelf->can_be_viewed( $borrowernumber ) ) { Link Here
82
            while ( my $content = $contents->next ) {
81
            while ( my $content = $contents->next ) {
83
                push @biblios, $content->biblionumber;
82
                push @biblios, $content->biblionumber;
84
            }
83
            }
85
            $output = marc2csv(\@biblios, $format);
84
            $output = marc2csv( \@biblios, $format );
86
        # Other formats
85
86
            # Other formats
87
        } else {
87
        } else {
88
            my $record_processor = Koha::RecordProcessor->new({
88
            my $record_processor = Koha::RecordProcessor->new( { filters => 'ViewPolicy' } );
89
                filters => 'ViewPolicy'
90
            });
91
            while ( my $content = $contents->next ) {
89
            while ( my $content = $contents->next ) {
92
                my $biblionumber = $content->biblionumber;
90
                my $biblionumber = $content->biblionumber;
93
91
Lines 99-137 if ( $shelf and $shelf->can_be_viewed( $borrowernumber ) ) { Link Here
99
                        patron      => $patron,
97
                        patron      => $patron,
100
                    }
98
                    }
101
                );
99
                );
102
                my $xslFile = $query->param("file");
100
                my $xslFile   = $query->param("file");
103
                my $framework = $biblio->frameworkcode;
101
                my $framework = $biblio->frameworkcode;
104
                $record_processor->options({
102
                $record_processor->options(
105
                    interface => 'opac',
103
                    {
106
                    frameworkcode => $framework
104
                        interface     => 'opac',
107
                });
105
                        frameworkcode => $framework
106
                    }
107
                );
108
                $record_processor->process($record);
108
                $record_processor->process($record);
109
                next unless $record;
109
                next unless $record;
110
110
111
                if ($format eq 'iso2709') {
111
                if ( $format eq 'iso2709' ) {
112
                    $output .= $record->as_usmarc();
112
                    $output .= $record->as_usmarc();
113
                }
113
                } elsif ( $format eq 'ris' ) {
114
                elsif ($format eq 'ris' ) {
115
                    $output .= marc2ris($record);
114
                    $output .= marc2ris($record);
116
                }
115
                } elsif ( $format eq 'bibtex' ) {
117
                elsif ($format eq 'bibtex') {
116
                    $output .= marc2bibtex( $record, $biblionumber );
118
                    $output .= marc2bibtex($record, $biblionumber);
117
                } elsif ( $format eq 'isbd' ) {
119
                }
118
                    $output .= GetISBDView(
120
                elsif ( $format eq 'isbd' ) {
119
                        {
121
                    $output   .= GetISBDView({
120
                            'record'    => $record,
122
                        'record'    => $record,
121
                            'template'  => 'opac',
123
                        'template'  => 'opac',
122
                            'framework' => $framework,
124
                        'framework' => $framework,
123
                        }
125
                    });
124
                    );
126
                    $extension = "txt";
125
                    $extension = "txt";
127
                    $type      = "text/plain";
126
                    $type      = "text/plain";
128
                }elsif ($format =~ /^xsl\.(.*)$/){
127
                } elsif ( $format =~ /^xsl\.(.*)$/ ) {
129
                    $output .= XSLTParse4Display(
128
                    $output .= XSLTParse4Display(
130
                        {
129
                        {
131
                            biblionumber => $biblionumber,
130
                            biblionumber => $biblionumber,
132
                            record => $record,
131
                            record       => $record,
133
                            xsl_syspref  => "XSLTCustomExport",
132
                            xsl_syspref  => "XSLTCustomExport",
134
                            fix_amps  => 1,
133
                            fix_amps     => 1,
135
                            hidden_items => undef,
134
                            hidden_items => undef,
136
                            xslfilename  => $xslFile,
135
                            xslfilename  => $xslFile,
137
                        }
136
                        }
Lines 141-162 if ( $shelf and $shelf->can_be_viewed( $borrowernumber ) ) { Link Here
141
        }
140
        }
142
141
143
        # If it was a CSV export we change the format after the export so the file extension is fine
142
        # If it was a CSV export we change the format after the export so the file extension is fine
144
        $format = "csv" if ($format =~ m/^\d+$/);
143
        $format = "csv"  if ( $format =~ m/^\d+$/ );
145
        $format = "html" if ($format =~ /^xsl\./);
144
        $format = "html" if ( $format =~ /^xsl\./ );
146
        print $query->header(
145
        print $query->header(
147
                                   -type => ($type) ? $type : 'application/octet-stream',
146
            -type                        => ($type) ? $type : 'application/octet-stream',
148
            -'Content-Transfer-Encoding' => 'binary',
147
            -'Content-Transfer-Encoding' => 'binary',
149
                             -attachment => ($extension) ? "shelf.$format.$extension" : "shelf.$format"
148
            -attachment                  => ($extension) ? "shelf.$format.$extension" : "shelf.$format"
150
        );
149
        );
151
        print $output;
150
        print $output;
152
151
153
    } else {
152
    } else {
154
153
155
        # if modal context is passed set a variable so that page markup can be different
154
        # if modal context is passed set a variable so that page markup can be different
156
        if($context eq "modal"){
155
        if ( $context eq "modal" ) {
157
            $template->param(modal => 1);
156
            $template->param( modal => 1 );
158
        } else {
157
        } else {
159
            $template->param(fullpage => 1);
158
            $template->param( fullpage => 1 );
160
        }
159
        }
161
        $template->param(
160
        $template->param(
162
            csv_profiles => Koha::CsvProfiles->search(
161
            csv_profiles => Koha::CsvProfiles->search(
Lines 168-179 if ( $shelf and $shelf->can_be_viewed( $borrowernumber ) ) { Link Here
168
            ),
167
            ),
169
            shelf => $shelf,
168
            shelf => $shelf,
170
        );
169
        );
171
        $template->param(xsl_exports => CustomXSLTExportList());
170
        $template->param( xsl_exports => CustomXSLTExportList() );
172
        $template->param( shelf => $shelf );
171
        $template->param( shelf       => $shelf );
173
        output_html_with_http_headers $query, $cookie, $template->output;
172
        output_html_with_http_headers $query, $cookie, $template->output;
174
    }
173
    }
175
174
176
} else {
175
} else {
177
    $template->param(invalidlist => 1); 
176
    $template->param( invalidlist => 1 );
178
    output_html_with_http_headers $query, $cookie, $template->output;
177
    output_html_with_http_headers $query, $cookie, $template->output;
179
}
178
}
(-)a/opac/opac-export.pl (-86 / +79 lines)
Lines 34-43 use Koha::Biblios; Link Here
34
use C4::XSLT qw( XSLTParse4Display );
34
use C4::XSLT qw( XSLTParse4Display );
35
use Koha::RecordProcessor;
35
use Koha::RecordProcessor;
36
36
37
my $query = CGI->new;
37
my $query        = CGI->new;
38
my $op=$query->param("op")||''; #op=export is currently the only use
38
my $op           = $query->param("op") || '';           #op=export is currently the only use
39
my $format=$query->param("format")||'utf8';
39
my $format       = $query->param("format") || 'utf8';
40
my $biblionumber = $query->param("bib")||0;
40
my $biblionumber = $query->param("bib") || 0;
41
$biblionumber = int($biblionumber);
41
$biblionumber = int($biblionumber);
42
my $error = q{};
42
my $error = q{};
43
43
Lines 48-198 my $patron; Link Here
48
if ($userenv) {
48
if ($userenv) {
49
    my $borrowernumber = $userenv->{'number'};
49
    my $borrowernumber = $userenv->{'number'};
50
    if ($borrowernumber) {
50
    if ($borrowernumber) {
51
        $patron = Koha::Patrons->find( $borrowernumber );
51
        $patron = Koha::Patrons->find($borrowernumber);
52
    }
52
    }
53
}
53
}
54
54
55
my $include_items = ($format =~ /bibtex/) ? 0 : 1;
55
my $include_items = ( $format =~ /bibtex/ ) ? 0 : 1;
56
my $biblio = Koha::Biblios->find($biblionumber);
56
my $biblio        = Koha::Biblios->find($biblionumber);
57
my $marc = $biblio
57
my $marc          = $biblio
58
  ? $biblio->metadata->record(
58
    ? $biblio->metadata->record(
59
    {
59
    {
60
        embed_items => 1,
60
        embed_items => 1,
61
        opac        => 1,
61
        opac        => 1,
62
        patron      => $patron,
62
        patron      => $patron,
63
    }
63
    }
64
  )
64
    )
65
  : undef;
65
    : undef;
66
66
67
if(!$marc) {
67
if ( !$marc ) {
68
    print $query->redirect("/cgi-bin/koha/errors/404.pl");
68
    print $query->redirect("/cgi-bin/koha/errors/404.pl");
69
    exit;
69
    exit;
70
}
70
}
71
71
72
my $file_id = $biblionumber;
72
my $file_id  = $biblionumber;
73
my $file_pre = "bib-";
73
my $file_pre = "bib-";
74
if( C4::Context->preference('DefaultSaveRecordFileID') eq 'controlnumber' ){
74
if ( C4::Context->preference('DefaultSaveRecordFileID') eq 'controlnumber' ) {
75
    my $marcflavour = C4::Context->preference('marcflavour'); #FIXME This option is required but does not change control num behaviour
75
    my $marcflavour =
76
        C4::Context->preference('marcflavour'); #FIXME This option is required but does not change control num behaviour
76
    my $control_num = GetMarcControlnumber( $marc, $marcflavour );
77
    my $control_num = GetMarcControlnumber( $marc, $marcflavour );
77
    if( $control_num ){
78
    if ($control_num) {
78
        $file_id = $control_num;
79
        $file_id  = $control_num;
79
        $file_pre = "record-";
80
        $file_pre = "record-";
80
    }
81
    }
81
}
82
}
82
83
83
my $framework = $biblio->frameworkcode;
84
my $framework        = $biblio->frameworkcode;
84
my $record_processor = Koha::RecordProcessor->new({
85
my $record_processor = Koha::RecordProcessor->new(
85
    filters => 'ViewPolicy',
86
    {
86
    options => {
87
        filters => 'ViewPolicy',
87
        interface => 'opac',
88
        options => {
88
        frameworkcode => $framework
89
            interface     => 'opac',
90
            frameworkcode => $framework
91
        }
89
    }
92
    }
90
});
93
);
91
$record_processor->process($marc);
94
$record_processor->process($marc);
92
95
93
if ($format =~ /endnote/) {
96
if ( $format =~ /endnote/ ) {
94
    $marc = marc2endnote($marc);
97
    $marc   = marc2endnote($marc);
95
    $format = 'endnote';
98
    $format = 'endnote';
96
}
99
} elsif ( $format =~ /marcxml/ ) {
97
elsif ($format =~ /marcxml/) {
100
    $marc   = marc2marcxml($marc);
98
    $marc = marc2marcxml($marc);
99
    $format = 'marcxml';
101
    $format = 'marcxml';
100
}
102
} elsif ( $format =~ /mods/ ) {
101
elsif ($format=~ /mods/) {
103
    $marc   = marc2modsxml($marc);
102
    $marc = marc2modsxml($marc);
103
    $format = 'mods';
104
    $format = 'mods';
104
}
105
} elsif ( $format =~ /ris/ ) {
105
elsif ($format =~ /ris/) {
106
    $marc   = marc2ris($marc);
106
    $marc = marc2ris($marc);
107
    $format = 'ris';
107
    $format = 'ris';
108
}
108
} elsif ( $format =~ /bibtex/ ) {
109
elsif ($format =~ /bibtex/) {
109
    $marc   = marc2bibtex( $marc, $biblionumber );
110
    $marc = marc2bibtex($marc,$biblionumber);
111
    $format = 'bibtex';
110
    $format = 'bibtex';
112
}
111
} elsif ( $format =~ /^(dc|oaidc|srwdc|rdfdc)$/i ) {
113
elsif ($format =~ /^(dc|oaidc|srwdc|rdfdc)$/i ) {
112
114
    # TODO: Dublin Core leaks fields marked hidden by framework.
113
    # TODO: Dublin Core leaks fields marked hidden by framework.
115
    $marc = marc2dcxml($marc, undef, $biblionumber, $format);
114
    $marc   = marc2dcxml( $marc, undef, $biblionumber, $format );
116
    $format = "dublin-core.xml";
115
    $format = "dublin-core.xml";
117
}
116
} elsif ( $format =~ /marc8/ ) {
118
elsif ($format =~ /marc8/) {
117
    ( $error, $marc ) = changeEncoding( $marc, "MARC", "MARC21", "MARC-8" );
119
    ($error,$marc) = changeEncoding($marc,"MARC","MARC21","MARC-8");
118
    $marc   = $marc->as_usmarc() unless $error;
120
    $marc = $marc->as_usmarc() unless $error;
121
    $format = 'marc8';
119
    $format = 'marc8';
122
}
120
} elsif ( $format =~ /utf8/ ) {
123
elsif ($format =~ /utf8/) {
121
    C4::Charset::SetUTF8Flag( $marc, 1 );
124
    C4::Charset::SetUTF8Flag($marc,1);
122
    $marc   = $marc->as_usmarc();
125
    $marc = $marc->as_usmarc();
126
    $format = 'utf8';
123
    $format = 'utf8';
127
}
124
} elsif ( $format =~ /marcstd/ ) {
128
elsif ($format =~ /marcstd/) {
125
    C4::Charset::SetUTF8Flag( $marc, 1 );
129
    C4::Charset::SetUTF8Flag($marc,1);
126
    ( $error, $marc ) = marc2marc( $marc, 'marcstd', C4::Context->preference('marcflavour') );
130
    ($error,$marc) = marc2marc($marc, 'marcstd', C4::Context->preference('marcflavour'));
131
    $format = 'marcstd';
127
    $format = 'marcstd';
132
}
128
} elsif ( $format =~ /isbd/ ) {
133
elsif ( $format =~ /isbd/ ) {
129
    $marc = GetISBDView(
134
    $marc   = GetISBDView({
130
        {
135
        'record'    => $marc,
131
            'record'    => $marc,
136
        'template'  => 'opac',
132
            'template'  => 'opac',
137
        'framework' => $framework,
133
            'framework' => $framework,
138
    });
134
        }
135
    );
139
    $format = 'isbd';
136
    $format = 'isbd';
140
}
137
} elsif ( $format =~ /html/ ) {
141
elsif ($format =~ /html/ ) {
138
    if ($biblionumber) {
142
    if ($biblionumber){
143
        my $xslFile = $query->param("file");
139
        my $xslFile = $query->param("file");
144
        my $biblio = Koha::Biblios->find($biblionumber);
140
        my $biblio  = Koha::Biblios->find($biblionumber);
145
        $marc = $biblio->metadata->record;
141
        $marc = $biblio->metadata->record;
146
        my @hiddenitems;
142
        my @hiddenitems;
147
143
148
        $marc = XSLTParse4Display(
144
        $marc = XSLTParse4Display(
149
            {
145
            {
150
                biblionumber => $biblionumber,
146
                biblionumber => $biblionumber,
151
                record => $marc,
147
                record       => $marc,
152
                xsl_syspref  => "OPACXSLTCustomExport",
148
                xsl_syspref  => "OPACXSLTCustomExport",
153
                fix_amps  => 1,
149
                fix_amps     => 1,
154
                hidden_items => \@hiddenitems,
150
                hidden_items => \@hiddenitems,
155
                xslfilename    => $xslFile,
151
                xslfilename  => $xslFile,
156
            }
152
            }
157
        );
153
        );
158
    }
154
    }
159
}
155
} else {
160
else {
156
    $error = "Format $format is not supported.";
161
    $error= "Format $format is not supported.";
162
}
157
}
163
158
164
if ($error){
159
if ($error) {
165
    print $query->header();
160
    print $query->header();
166
    print $query->start_html();
161
    print $query->start_html();
167
    print "<h1>An error occurred </h1>";
162
    print "<h1>An error occurred </h1>";
168
    print $query->escapeHTML("$error");
163
    print $query->escapeHTML("$error");
169
    print $query->end_html();
164
    print $query->end_html();
170
}
165
} else {
171
else {
166
    if ( $format eq 'marc8' ) {
172
    if ($format eq 'marc8'){
173
        print $query->header(
167
        print $query->header(
174
            -type => 'application/marc',
168
            -type       => 'application/marc',
175
            -charset=>'ISO-2022',
169
            -charset    => 'ISO-2022',
176
            -attachment=>"$file_pre$file_id.$format");
170
            -attachment => "$file_pre$file_id.$format"
177
    }
171
        );
178
    elsif ( $format eq 'isbd' ) {
172
    } elsif ( $format eq 'isbd' ) {
179
        print $query->header(
173
        print $query->header(
180
            -type       => 'text/plain',
174
            -type       => 'text/plain',
181
            -charset    => 'utf-8',
175
            -charset    => 'utf-8',
182
            -attachment =>  "$file_pre$file_id.txt"
176
            -attachment => "$file_pre$file_id.txt"
183
        );
177
        );
184
    }
178
    } elsif ( $format eq 'ris' ) {
185
    elsif ( $format eq 'ris' ) {
186
        print $query->header(
179
        print $query->header(
187
            -type => 'text/plain',
180
            -type       => 'text/plain',
188
            -charset => 'utf-8',
181
            -charset    => 'utf-8',
189
            -attachment => "$file_pre$file_id.$format"
182
            -attachment => "$file_pre$file_id.$format"
190
        );
183
        );
191
    } else {
184
    } else {
192
        binmode STDOUT, ':encoding(UTF-8)';
185
        binmode STDOUT, ':encoding(UTF-8)';
193
        print $query->header(
186
        print $query->header(
194
            -type => 'application/octet-stream',
187
            -type       => 'application/octet-stream',
195
            -charset => 'utf-8',
188
            -charset    => 'utf-8',
196
            -attachment => "$file_pre$file_id.$format"
189
            -attachment => "$file_pre$file_id.$format"
197
        );
190
        );
198
    }
191
    }
(-)a/opac/opac-shelves.pl (-110 / +130 lines)
Lines 46-53 use Koha::Virtualshelfshares; Link Here
46
use Koha::Virtualshelves;
46
use Koha::Virtualshelves;
47
use Koha::RecordProcessor;
47
use Koha::RecordProcessor;
48
48
49
use constant ANYONE => 2;
49
use constant ANYONE    => 2;
50
use constant STAFF => 3;
50
use constant STAFF     => 3;
51
use constant PERMITTED => 4;
51
use constant PERMITTED => 4;
52
52
53
my $query = CGI->new;
53
my $query = CGI->new;
Lines 55-61 my $query = CGI->new; Link Here
55
my $template_name = $query->param('rss') ? "opac-shelves-rss.tt" : "opac-shelves.tt";
55
my $template_name = $query->param('rss') ? "opac-shelves-rss.tt" : "opac-shelves.tt";
56
56
57
# if virtualshelves is disabled, leave immediately
57
# if virtualshelves is disabled, leave immediately
58
if ( ! C4::Context->preference('virtualshelves') ) {
58
if ( !C4::Context->preference('virtualshelves') ) {
59
    print $query->redirect("/cgi-bin/koha/errors/404.pl");
59
    print $query->redirect("/cgi-bin/koha/errors/404.pl");
60
    exit;
60
    exit;
61
}
61
}
Lines 63-110 if ( ! C4::Context->preference('virtualshelves') ) { Link Here
63
my $op = $query->param('op') || 'list';
63
my $op = $query->param('op') || 'list';
64
my ( $template, $loggedinuser, $cookie );
64
my ( $template, $loggedinuser, $cookie );
65
65
66
if( $op eq 'view' || $op eq 'list' ){
66
if ( $op eq 'view' || $op eq 'list' ) {
67
    ( $template, $loggedinuser, $cookie ) = get_template_and_user({
67
    ( $template, $loggedinuser, $cookie ) = get_template_and_user(
68
        {
68
            template_name   => $template_name,
69
            template_name   => $template_name,
69
            query           => $query,
70
            query           => $query,
70
            type            => "opac",
71
            type            => "opac",
71
            authnotrequired => ( C4::Context->preference("OpacPublic") ? 1 : 0 ),
72
            authnotrequired => ( C4::Context->preference("OpacPublic") ? 1 : 0 ),
72
        });
73
        }
74
    );
73
} else {
75
} else {
74
    ( $template, $loggedinuser, $cookie ) = get_template_and_user({
76
    ( $template, $loggedinuser, $cookie ) = get_template_and_user(
77
        {
75
            template_name   => $template_name,
78
            template_name   => $template_name,
76
            query           => $query,
79
            query           => $query,
77
            type            => "opac",
80
            type            => "opac",
78
            authnotrequired => 0,
81
            authnotrequired => 0,
79
        });
82
        }
83
    );
80
}
84
}
81
85
82
if (C4::Context->preference("BakerTaylorEnabled")) {
86
if ( C4::Context->preference("BakerTaylorEnabled") ) {
83
    $template->param(
87
    $template->param(
84
        BakerTaylorImageURL => &image_url(),
88
        BakerTaylorImageURL => &image_url(),
85
        BakerTaylorLinkURL  => &link_url(),
89
        BakerTaylorLinkURL  => &link_url(),
86
    );
90
    );
87
}
91
}
88
92
89
my $referer  = $query->param('referer')  || $op;
93
my $referer = $query->param('referer') || $op;
90
my $public = 0;
94
my $public  = 0;
91
$public = 1 if $query->param('public') && $query->param('public') == 1;
95
$public = 1 if $query->param('public') && $query->param('public') == 1;
92
96
93
my ( $shelf, $shelfnumber, @messages );
97
my ( $shelf, $shelfnumber, @messages );
94
98
95
# PART 1: Perform a few actions
99
# PART 1: Perform a few actions
96
if ( $op eq 'add_form' ) {
100
if ( $op eq 'add_form' ) {
101
97
    # Only pass default
102
    # Only pass default
98
    $shelf = { allow_change_from_owner => 1 };
103
    $shelf = { allow_change_from_owner => 1 };
99
} elsif ( $op eq 'edit_form' ) {
104
} elsif ( $op eq 'edit_form' ) {
100
    $shelfnumber = $query->param('shelfnumber');
105
    $shelfnumber = $query->param('shelfnumber');
101
    $shelf       = Koha::Virtualshelves->find($shelfnumber);
106
    $shelf       = Koha::Virtualshelves->find($shelfnumber);
102
107
103
    if ( $shelf ) {
108
    if ($shelf) {
104
        $public = $shelf->public;
109
        $public = $shelf->public;
105
        my $patron = Koha::Patrons->find( $shelf->owner );
110
        my $patron = Koha::Patrons->find( $shelf->owner );
106
        $template->param( owner => $patron, );
111
        $template->param( owner => $patron, );
107
        unless ( $shelf->can_be_managed( $loggedinuser ) ) {
112
        unless ( $shelf->can_be_managed($loggedinuser) ) {
108
            push @messages, { type => 'error', code => 'unauthorized_on_update' };
113
            push @messages, { type => 'error', code => 'unauthorized_on_update' };
109
            $op = 'list';
114
            $op = 'list';
110
        }
115
        }
Lines 112-129 if ( $op eq 'add_form' ) { Link Here
112
        push @messages, { type => 'error', code => 'does_not_exist' };
117
        push @messages, { type => 'error', code => 'does_not_exist' };
113
    }
118
    }
114
} elsif ( $op eq 'add' ) {
119
} elsif ( $op eq 'add' ) {
115
    if ( $loggedinuser ) {
120
    if ($loggedinuser) {
116
        my $allow_changes_from = $query->param('allow_changes_from');
121
        my $allow_changes_from = $query->param('allow_changes_from');
117
        eval {
122
        eval {
118
            $shelf = Koha::Virtualshelf->new(
123
            $shelf = Koha::Virtualshelf->new(
119
                {   shelfname          => scalar $query->param('shelfname'),
124
                {
120
                    sortfield          => scalar $query->param('sortfield'),
125
                    shelfname                         => scalar $query->param('shelfname'),
121
                    public             => $public,
126
                    sortfield                         => scalar $query->param('sortfield'),
122
                    allow_change_from_owner            => $allow_changes_from > 0,
127
                    public                            => $public,
123
                    allow_change_from_others           => $allow_changes_from == ANYONE,
128
                    allow_change_from_owner           => $allow_changes_from > 0,
124
                    allow_change_from_staff            => $allow_changes_from == STAFF,
129
                    allow_change_from_others          => $allow_changes_from == ANYONE,
130
                    allow_change_from_staff           => $allow_changes_from == STAFF,
125
                    allow_change_from_permitted_staff => $allow_changes_from == PERMITTED,
131
                    allow_change_from_permitted_staff => $allow_changes_from == PERMITTED,
126
                    owner              => scalar $loggedinuser,
132
                    owner                             => scalar $loggedinuser,
127
                }
133
                }
128
            );
134
            );
129
            $shelf->store;
135
            $shelf->store;
Lines 144-162 if ( $op eq 'add_form' ) { Link Here
144
} elsif ( $op eq 'edit' ) {
150
} elsif ( $op eq 'edit' ) {
145
    $shelfnumber = $query->param('shelfnumber');
151
    $shelfnumber = $query->param('shelfnumber');
146
    $shelf       = Koha::Virtualshelves->find($shelfnumber);
152
    $shelf       = Koha::Virtualshelves->find($shelfnumber);
147
    if ( $shelf ) {
153
    if ($shelf) {
148
        $op = $referer;
154
        $op = $referer;
149
        my $sortfield = $query->param('sortfield');
155
        my $sortfield = $query->param('sortfield');
150
        $sortfield = 'title' unless grep { $_ eq $sortfield } qw( title author copyrightdate itemcallnumber dateadded );
156
        $sortfield = 'title' unless grep { $_ eq $sortfield } qw( title author copyrightdate itemcallnumber dateadded );
151
        if ( $shelf->can_be_managed( $loggedinuser ) ) {
157
        if ( $shelf->can_be_managed($loggedinuser) ) {
152
            $shelf->shelfname( scalar $query->param('shelfname') );
158
            $shelf->shelfname( scalar $query->param('shelfname') );
153
            $shelf->sortfield( $sortfield );
159
            $shelf->sortfield($sortfield);
154
            my $allow_changes_from = $query->param('allow_changes_from');
160
            my $allow_changes_from = $query->param('allow_changes_from');
155
            $shelf->allow_change_from_owner( $allow_changes_from > 0 );
161
            $shelf->allow_change_from_owner( $allow_changes_from > 0 );
156
            $shelf->allow_change_from_others( $allow_changes_from == ANYONE );
162
            $shelf->allow_change_from_others( $allow_changes_from == ANYONE );
157
            $shelf->allow_change_from_staff( $allow_changes_from == STAFF );
163
            $shelf->allow_change_from_staff( $allow_changes_from == STAFF );
158
            $shelf->allow_change_from_permitted_staff( $allow_changes_from == PERMITTED );
164
            $shelf->allow_change_from_permitted_staff( $allow_changes_from == PERMITTED );
159
            $shelf->public( $public );
165
            $shelf->public($public);
160
            eval { $shelf->store };
166
            eval { $shelf->store };
161
167
162
            if ($@) {
168
            if ($@) {
Lines 175-181 if ( $op eq 'add_form' ) { Link Here
175
    $shelfnumber = $query->param('shelfnumber');
181
    $shelfnumber = $query->param('shelfnumber');
176
    $shelf       = Koha::Virtualshelves->find($shelfnumber);
182
    $shelf       = Koha::Virtualshelves->find($shelfnumber);
177
    if ($shelf) {
183
    if ($shelf) {
178
        if ( $shelf->can_be_deleted( $loggedinuser ) ) {
184
        if ( $shelf->can_be_deleted($loggedinuser) ) {
179
            eval { $shelf->delete; };
185
            eval { $shelf->delete; };
180
            if ($@) {
186
            if ($@) {
181
                push @messages, { type => 'error', code => ref($@), msg => $@ };
187
                push @messages, { type => 'error', code => ref($@), msg => $@ };
Lines 191-202 if ( $op eq 'add_form' ) { Link Here
191
    $op = $referer;
197
    $op = $referer;
192
} elsif ( $op eq 'remove_share' ) {
198
} elsif ( $op eq 'remove_share' ) {
193
    $shelfnumber = $query->param('shelfnumber');
199
    $shelfnumber = $query->param('shelfnumber');
194
    $shelf = Koha::Virtualshelves->find($shelfnumber);
200
    $shelf       = Koha::Virtualshelves->find($shelfnumber);
195
    if ($shelf) {
201
    if ($shelf) {
196
        my $removed = eval { $shelf->remove_share( $loggedinuser ); };
202
        my $removed = eval { $shelf->remove_share($loggedinuser); };
197
        if ($@) {
203
        if ($@) {
198
            push @messages, { type => 'error', code => ref($@), msg => $@ };
204
            push @messages, { type => 'error', code => ref($@), msg => $@ };
199
        } elsif ( $removed ) {
205
        } elsif ($removed) {
200
            push @messages, { type => 'message', code => 'success_on_remove_share' };
206
            push @messages, { type => 'message', code => 'success_on_remove_share' };
201
        } else {
207
        } else {
202
            push @messages, { type => 'error', code => 'error_on_remove_share' };
208
            push @messages, { type => 'error', code => 'error_on_remove_share' };
Lines 208-223 if ( $op eq 'add_form' ) { Link Here
208
214
209
} elsif ( $op eq 'add_biblio' ) {
215
} elsif ( $op eq 'add_biblio' ) {
210
    $shelfnumber = $query->param('shelfnumber');
216
    $shelfnumber = $query->param('shelfnumber');
211
    $shelf = Koha::Virtualshelves->find($shelfnumber);
217
    $shelf       = Koha::Virtualshelves->find($shelfnumber);
212
    if ($shelf) {
218
    if ($shelf) {
213
        if( my $barcode = $query->param('barcode') ) {
219
        if ( my $barcode = $query->param('barcode') ) {
214
            my $item = Koha::Items->find({ barcode => $barcode });
220
            my $item = Koha::Items->find( { barcode => $barcode } );
215
            if ( $item ) {
221
            if ($item) {
216
                if ( $shelf->can_biblios_be_added( $loggedinuser ) ) {
222
                if ( $shelf->can_biblios_be_added($loggedinuser) ) {
217
                    my $added = eval { $shelf->add_biblio( $item->biblionumber, $loggedinuser ); };
223
                    my $added = eval { $shelf->add_biblio( $item->biblionumber, $loggedinuser ); };
218
                    if ($@) {
224
                    if ($@) {
219
                        push @messages, { type => 'error', code => ref($@), msg => $@ };
225
                        push @messages, { type => 'error', code => ref($@), msg => $@ };
220
                    } elsif ( $added ) {
226
                    } elsif ($added) {
221
                        push @messages, { type => 'message', code => 'success_on_add_biblio' };
227
                        push @messages, { type => 'message', code => 'success_on_add_biblio' };
222
                    } else {
228
                    } else {
223
                        push @messages, { type => 'message', code => 'error_on_add_biblio' };
229
                        push @messages, { type => 'message', code => 'error_on_add_biblio' };
Lines 235-255 if ( $op eq 'add_form' ) { Link Here
235
    $op = $referer;
241
    $op = $referer;
236
} elsif ( $op eq 'remove_biblios' ) {
242
} elsif ( $op eq 'remove_biblios' ) {
237
    $shelfnumber = $query->param('shelfnumber');
243
    $shelfnumber = $query->param('shelfnumber');
238
    $shelf = Koha::Virtualshelves->find($shelfnumber);
244
    $shelf       = Koha::Virtualshelves->find($shelfnumber);
239
    my @biblionumber = $query->multi_param('biblionumber');
245
    my @biblionumber = $query->multi_param('biblionumber');
240
    if ($shelf) {
246
    if ($shelf) {
241
        if ( $shelf->can_biblios_be_removed( $loggedinuser ) ) {
247
        if ( $shelf->can_biblios_be_removed($loggedinuser) ) {
242
            my $number_of_biblios_removed = eval {
248
            my $number_of_biblios_removed = eval {
243
                $shelf->remove_biblios(
249
                $shelf->remove_biblios(
244
                    {
250
                    {
245
                        biblionumbers => \@biblionumber,
251
                        biblionumbers  => \@biblionumber,
246
                        borrowernumber => $loggedinuser,
252
                        borrowernumber => $loggedinuser,
247
                    }
253
                    }
248
                );
254
                );
249
            };
255
            };
250
            if ($@) {
256
            if ($@) {
251
                push @messages, { type => 'error', code => ref($@), msg => $@ };
257
                push @messages, { type => 'error', code => ref($@), msg => $@ };
252
            } elsif ( $number_of_biblios_removed ) {
258
            } elsif ($number_of_biblios_removed) {
253
                push @messages, { type => 'message', code => 'success_on_remove_biblios' };
259
                push @messages, { type => 'message', code => 'success_on_remove_biblios' };
254
            } else {
260
            } else {
255
                push @messages, { type => 'error', code => 'no_biblio_removed' };
261
                push @messages, { type => 'error', code => 'no_biblio_removed' };
Lines 261-296 if ( $op eq 'add_form' ) { Link Here
261
        push @messages, { type => 'error', code => 'does_not_exist' };
267
        push @messages, { type => 'error', code => 'does_not_exist' };
262
    }
268
    }
263
    $op = 'view';
269
    $op = 'view';
264
} elsif( $op eq 'transfer' ) {
270
} elsif ( $op eq 'transfer' ) {
265
    $shelfnumber = $query->param('shelfnumber');
271
    $shelfnumber = $query->param('shelfnumber');
266
    $shelf = Koha::Virtualshelves->find($shelfnumber) if $shelfnumber;
272
    $shelf       = Koha::Virtualshelves->find($shelfnumber) if $shelfnumber;
267
    my $new_owner = $query->param('new_owner'); # borrowernumber or undef
273
    my $new_owner = $query->param('new_owner');    # borrowernumber or undef
268
    my $error_code = $shelf
274
    my $error_code =
269
        ? $shelf->cannot_be_transferred({ by => $loggedinuser, to => $new_owner, interface => 'opac' })
275
          $shelf
276
        ? $shelf->cannot_be_transferred( { by => $loggedinuser, to => $new_owner, interface => 'opac' } )
270
        : 'does_not_exist';
277
        : 'does_not_exist';
271
278
272
    if( !$new_owner && $error_code eq 'missing_to_parameter' ) { # show transfer form
279
    if ( !$new_owner && $error_code eq 'missing_to_parameter' ) {    # show transfer form
273
        my $patrons = [];
280
        my $patrons = [];
274
        my $shares = $shelf->get_shares->search({ borrowernumber => { '!=' => undef } });
281
        my $shares  = $shelf->get_shares->search( { borrowernumber => { '!=' => undef } } );
275
        while( my $share = $shares->next ) {
282
        while ( my $share = $shares->next ) {
276
            my $email = $share->sharee->notice_email_address;
283
            my $email = $share->sharee->notice_email_address;
277
            push @$patrons, { email => $email, borrowernumber => $share->get_column('borrowernumber') } if $email;
284
            push @$patrons, { email => $email, borrowernumber => $share->get_column('borrowernumber') } if $email;
278
        }
285
        }
279
        if( @$patrons ) {
286
        if (@$patrons) {
280
            $template->param( shared_users => $patrons );
287
            $template->param( shared_users => $patrons );
281
            $op = 'transfer';
288
            $op = 'transfer';
282
        } else {
289
        } else {
283
            push @messages, { type => 'error', code => 'no_email_found' };
290
            push @messages, { type => 'error', code => 'no_email_found' };
284
        }
291
        }
285
    } elsif( $error_code ) {
292
    } elsif ($error_code) {
286
        push @messages, { type => 'error', code => $error_code };
293
        push @messages, { type => 'error', code => $error_code };
287
        $op = 'list';
294
        $op = 'list';
288
    } else { # transfer; remove new_owner from virtualshelfshares, add loggedinuser
295
    } else {    # transfer; remove new_owner from virtualshelfshares, add loggedinuser
289
        $shelf->_result->result_source->schema->txn_do( sub {
296
        $shelf->_result->result_source->schema->txn_do(
290
            $shelf->get_shares->search({ borrowernumber => $new_owner })->delete;
297
            sub {
291
            Koha::Virtualshelfshare->new({ shelfnumber => $shelfnumber, borrowernumber => $loggedinuser, sharedate => dt_from_string })->store;
298
                $shelf->get_shares->search( { borrowernumber => $new_owner } )->delete;
292
            $shelf->owner($new_owner)->store;
299
                Koha::Virtualshelfshare->new(
293
        });
300
                    { shelfnumber => $shelfnumber, borrowernumber => $loggedinuser, sharedate => dt_from_string } )
301
                    ->store;
302
                $shelf->owner($new_owner)->store;
303
            }
304
        );
294
        $op = 'list';
305
        $op = 'list';
295
    }
306
    }
296
}
307
}
Lines 299-319 if ( $op eq 'add_form' ) { Link Here
299
if ( $op eq 'view' ) {
310
if ( $op eq 'view' ) {
300
    $shelfnumber ||= $query->param('shelfnumber');
311
    $shelfnumber ||= $query->param('shelfnumber');
301
    $shelf = Koha::Virtualshelves->find($shelfnumber);
312
    $shelf = Koha::Virtualshelves->find($shelfnumber);
302
    if ( $shelf ) {
313
    if ($shelf) {
303
        if ( $shelf->can_be_viewed( $loggedinuser ) ) {
314
        if ( $shelf->can_be_viewed($loggedinuser) ) {
304
            $public = $shelf->public;
315
            $public = $shelf->public;
305
316
306
            # Sortfield param may still include sort order with :asc or :desc, but direction overrides it
317
            # Sortfield param may still include sort order with :asc or :desc, but direction overrides it
307
            my( $sortfield, $direction );
318
            my ( $sortfield, $direction );
308
            if( $query->param('sortfield') ){
319
            if ( $query->param('sortfield') ) {
309
                ( $sortfield, $direction ) = split /:/, $query->param('sortfield');
320
                ( $sortfield, $direction ) = split /:/, $query->param('sortfield');
310
            } else {
321
            } else {
311
                $sortfield = $shelf->sortfield;
322
                $sortfield = $shelf->sortfield;
312
                $direction = 'asc';
323
                $direction = 'asc';
313
            }
324
            }
314
            $direction = $query->param('direction') if $query->param('direction');
325
            $direction = $query->param('direction') if $query->param('direction');
315
            $direction = 'asc' if !$direction or ( $direction ne 'asc' and $direction ne 'desc' );
326
            $direction = 'asc'                      if !$direction or ( $direction ne 'asc' and $direction ne 'desc' );
316
            $sortfield = 'title' if !$sortfield or !grep { $_ eq $sortfield } qw( title author copyrightdate itemcallnumber dateadded );
327
            $sortfield = 'title'
328
                if !$sortfield
329
                or !grep { $_ eq $sortfield } qw( title author copyrightdate itemcallnumber dateadded );
317
330
318
            my ( $page, $rows );
331
            my ( $page, $rows );
319
            unless ( $query->param('print') or $query->param('rss') ) {
332
            unless ( $query->param('print') or $query->param('rss') ) {
Lines 334-355 if ( $op eq 'view' ) { Link Here
334
347
335
            # get biblionumbers stored in the cart
348
            # get biblionumbers stored in the cart
336
            my @cart_list;
349
            my @cart_list;
337
            if(my $cart_list = $query->cookie('bib_list')){
350
            if ( my $cart_list = $query->cookie('bib_list') ) {
338
                @cart_list = split(/\//, $cart_list);
351
                @cart_list = split( /\//, $cart_list );
339
            }
352
            }
340
353
341
            my $patron = Koha::Patrons->find( $loggedinuser );
354
            my $patron = Koha::Patrons->find($loggedinuser);
342
355
343
            my $categorycode; # needed for may_article_request
356
            my $categorycode;    # needed for may_article_request
344
            if( C4::Context->preference('ArticleRequests') ) {
357
            if ( C4::Context->preference('ArticleRequests') ) {
345
                $categorycode = $patron ? $patron->categorycode : undef;
358
                $categorycode = $patron ? $patron->categorycode : undef;
346
            }
359
            }
347
360
348
            my $record_processor = Koha::RecordProcessor->new({ filters => 'ViewPolicy' });
361
            my $record_processor = Koha::RecordProcessor->new( { filters => 'ViewPolicy' } );
349
362
350
            my $art_req_itypes;
363
            my $art_req_itypes;
351
            if( C4::Context->preference('ArticleRequests') ) {
364
            if ( C4::Context->preference('ArticleRequests') ) {
352
                $art_req_itypes = Koha::CirculationRules->guess_article_requestable_itemtypes({ $patron ? ( categorycode => $patron->categorycode ) : () });
365
                $art_req_itypes = Koha::CirculationRules->guess_article_requestable_itemtypes(
366
                    { $patron ? ( categorycode => $patron->categorycode ) : () } );
353
            }
367
            }
354
368
355
            my @items_info;
369
            my @items_info;
Lines 361-386 if ( $op eq 'view' ) { Link Here
361
                my $framework    = GetFrameworkCode($biblionumber);
375
                my $framework    = GetFrameworkCode($biblionumber);
362
                $record_processor->options(
376
                $record_processor->options(
363
                    {
377
                    {
364
                    interface => 'opac',
378
                        interface     => 'opac',
365
                    frameworkcode => $framework
379
                        frameworkcode => $framework
366
                });
380
                    }
381
                );
367
                $record_processor->process($record);
382
                $record_processor->process($record);
368
383
369
                my $marcflavour = C4::Context->preference("marcflavour");
384
                my $marcflavour = C4::Context->preference("marcflavour");
370
                my $itemtype = Koha::Biblioitems->search({ biblionumber => $content->biblionumber })->next->itemtype;
385
                my $itemtype = Koha::Biblioitems->search( { biblionumber => $content->biblionumber } )->next->itemtype;
371
                $itemtype = Koha::ItemTypes->find( $itemtype );
386
                $itemtype = Koha::ItemTypes->find($itemtype);
372
                if( $itemtype ) {
387
                if ($itemtype) {
373
                    $this_item->{imageurl}          = C4::Koha::getitemtypeimagelocation( 'opac', $itemtype->imageurl );
388
                    $this_item->{imageurl} = C4::Koha::getitemtypeimagelocation( 'opac', $itemtype->imageurl );
374
                    $this_item->{description}       = $itemtype->description; #FIXME Should not it be translated_description?
389
                    $this_item->{description} = $itemtype->description;  #FIXME Should not it be translated_description?
375
                    $this_item->{notforloan}        = $itemtype->notforloan;
390
                    $this_item->{notforloan}  = $itemtype->notforloan;
376
                }
391
                }
377
                $this_item->{'coins'}           = $biblio->get_coins;
392
                $this_item->{'coins'}           = $biblio->get_coins;
378
                $this_item->{'normalized_upc'}  = GetNormalizedUPC( $record, $marcflavour );
393
                $this_item->{'normalized_upc'}  = GetNormalizedUPC( $record, $marcflavour );
379
                $this_item->{'normalized_ean'}  = GetNormalizedEAN( $record, $marcflavour );
394
                $this_item->{'normalized_ean'}  = GetNormalizedEAN( $record, $marcflavour );
380
                $this_item->{'normalized_oclc'} = GetNormalizedOCLCNumber( $record, $marcflavour );
395
                $this_item->{'normalized_oclc'} = GetNormalizedOCLCNumber( $record, $marcflavour );
381
                $this_item->{'normalized_isbn'} = GetNormalizedISBN( undef, $record, $marcflavour );
396
                $this_item->{'normalized_isbn'} = GetNormalizedISBN( undef, $record, $marcflavour );
397
382
                # BZ17530: 'Intelligent' guess if result can be article requested
398
                # BZ17530: 'Intelligent' guess if result can be article requested
383
                $this_item->{artreqpossible} = ( $art_req_itypes->{ $this_item->{itemtype} // q{} } || $art_req_itypes->{ '*' } ) ? 1 : q{};
399
                $this_item->{artreqpossible} =
400
                    ( $art_req_itypes->{ $this_item->{itemtype} // q{} } || $art_req_itypes->{'*'} ) ? 1 : q{};
384
401
385
                unless ( defined $this_item->{size} ) {
402
                unless ( defined $this_item->{size} ) {
386
403
Lines 388-416 if ( $op eq 'view' ) { Link Here
388
                    $this_item->{size} = q||;
405
                    $this_item->{size} = q||;
389
                }
406
                }
390
407
391
                if (C4::Context->preference('TagsEnabled') and C4::Context->preference('TagsShowOnList')) {
408
                if ( C4::Context->preference('TagsEnabled') and C4::Context->preference('TagsShowOnList') ) {
392
                    $this_item->{TagLoop} = get_tags({
409
                    $this_item->{TagLoop} = get_tags(
393
                        biblionumber => $biblionumber, approved=>1, 'sort'=>'-weight',
410
                        {
394
                        limit => C4::Context->preference('TagsShowOnList'),
411
                            biblionumber => $biblionumber, approved => 1, 'sort' => '-weight',
395
                    });
412
                            limit        => C4::Context->preference('TagsShowOnList'),
413
                        }
414
                    );
396
                }
415
                }
397
416
398
                my $items = $biblio->items->filter_by_visible_in_opac({ patron => $patron });
417
                my $items = $biblio->items->filter_by_visible_in_opac( { patron => $patron } );
399
                my $allow_onshelf_holds;
418
                my $allow_onshelf_holds;
400
                while ( my $item = $items->next ) {
419
                while ( my $item = $items->next ) {
401
420
402
                    # This method must take a Koha::Items rs
421
                    # This method must take a Koha::Items rs
403
                    $allow_onshelf_holds ||= Koha::CirculationRules->get_onshelfholds_policy(
422
                    $allow_onshelf_holds ||=
404
                        { item => $item, patron => $patron } );
423
                        Koha::CirculationRules->get_onshelfholds_policy( { item => $item, patron => $patron } );
405
424
406
                }
425
                }
407
426
408
                $this_item->{allow_onshelf_holds} = $allow_onshelf_holds;
427
                $this_item->{allow_onshelf_holds} = $allow_onshelf_holds;
409
                $this_item->{'ITEM_RESULTS'} = $items;
428
                $this_item->{'ITEM_RESULTS'}      = $items;
410
429
411
                my $variables = {
430
                my $variables = { anonymous_session => ($loggedinuser) ? 0 : 1 };
412
                    anonymous_session => ($loggedinuser) ? 0 : 1
413
                };
414
                $this_item->{XSLTBloc} = XSLTParse4Display(
431
                $this_item->{XSLTBloc} = XSLTParse4Display(
415
                    {
432
                    {
416
                        biblionumber   => $biblionumber,
433
                        biblionumber   => $biblionumber,
Lines 422-441 if ( $op eq 'view' ) { Link Here
422
                    }
439
                    }
423
                );
440
                );
424
441
425
442
                if ( grep { $_ eq $biblionumber } @cart_list ) {
426
                if ( grep {$_ eq $biblionumber} @cart_list) {
427
                    $this_item->{incart} = 1;
443
                    $this_item->{incart} = 1;
428
                }
444
                }
429
445
430
                $this_item->{biblio_object} = $biblio;
446
                $this_item->{biblio_object} = $biblio;
431
                $this_item->{biblionumber}  = $biblionumber;
447
                $this_item->{biblionumber}  = $biblionumber;
432
                $this_item->{shelves} =
448
                $this_item->{shelves}       = Koha::Virtualshelves->get_shelves_containing_record(
433
                  Koha::Virtualshelves->get_shelves_containing_record(
434
                    {
449
                    {
435
                        biblionumber   => $biblionumber,
450
                        biblionumber   => $biblionumber,
436
                        borrowernumber => $loggedinuser,
451
                        borrowernumber => $loggedinuser,
437
                    }
452
                    }
438
                  );
453
                );
439
                push @items_info, $this_item;
454
                push @items_info, $this_item;
440
            }
455
            }
441
456
Lines 447-466 if ( $op eq 'view' ) { Link Here
447
                itemsloop          => \@items_info,
462
                itemsloop          => \@items_info,
448
                sortfield          => $sortfield,
463
                sortfield          => $sortfield,
449
                direction          => $direction,
464
                direction          => $direction,
450
                csv_profiles => Koha::CsvProfiles->search(
465
                csv_profiles       => Koha::CsvProfiles->search(
451
                    {
466
                    {
452
                        type       => 'marc',
467
                        type       => 'marc',
453
                        used_for   => 'export_records',
468
                        used_for   => 'export_records',
454
                        staff_only => 0
469
                        staff_only => 0
455
                    }
470
                    }
456
                  ),
471
                ),
457
            );
472
            );
458
            if ( $page ) {
473
            if ($page) {
459
                my $pager = $contents->pager;
474
                my $pager = $contents->pager;
460
                $template->param(
475
                $template->param(
461
                    pagination_bar => pagination_bar(
476
                    pagination_bar => pagination_bar(
462
                        q||, $pager->last_page - $pager->first_page + 1,
477
                        q||,   $pager->last_page - $pager->first_page + 1,
463
                        $page, "page", { op => 'view', shelfnumber => $shelf->shelfnumber, sortfield => $sortfield, direction => $direction, }
478
                        $page, "page",
479
                        {
480
                            op        => 'view', shelfnumber => $shelf->shelfnumber, sortfield => $sortfield,
481
                            direction => $direction,
482
                        }
464
                    ),
483
                    ),
465
                );
484
                );
466
            }
485
            }
Lines 475-498 if ( $op eq 'view' ) { Link Here
475
    my $shelves;
494
    my $shelves;
476
    my ( $page, $rows ) = ( $query->param('page') || 1, 20 );
495
    my ( $page, $rows ) = ( $query->param('page') || 1, 20 );
477
    if ( !$public ) {
496
    if ( !$public ) {
478
        $shelves = Koha::Virtualshelves->get_private_shelves({ page => $page, rows => $rows, borrowernumber => $loggedinuser, });
497
        $shelves = Koha::Virtualshelves->get_private_shelves(
498
            { page => $page, rows => $rows, borrowernumber => $loggedinuser, } );
479
    } else {
499
    } else {
480
        $shelves = Koha::Virtualshelves->get_public_shelves({ page => $page, rows => $rows, });
500
        $shelves = Koha::Virtualshelves->get_public_shelves( { page => $page, rows => $rows, } );
481
    }
501
    }
482
502
483
    my $pager = $shelves->pager;
503
    my $pager = $shelves->pager;
484
    $template->param(
504
    $template->param(
485
        shelves => $shelves,
505
        shelves        => $shelves,
486
        pagination_bar => pagination_bar(
506
        pagination_bar => pagination_bar(
487
            q||, $pager->last_page - $pager->first_page + 1,
507
            q||,   $pager->last_page - $pager->first_page + 1,
488
            $page, "page", { op => 'list', public => $public, }
508
            $page, "page", { op => 'list', public => $public, }
489
        ),
509
        ),
490
    );
510
    );
491
}
511
}
492
512
493
my ($staffuser, $permitteduser);
513
my ( $staffuser, $permitteduser );
494
$staffuser = Koha::Patrons->find( $loggedinuser )->can_patron_change_staff_only_lists if $loggedinuser;
514
$staffuser     = Koha::Patrons->find($loggedinuser)->can_patron_change_staff_only_lists      if $loggedinuser;
495
$permitteduser = Koha::Patrons->find( $loggedinuser )->can_patron_change_permitted_staff_lists if $loggedinuser;
515
$permitteduser = Koha::Patrons->find($loggedinuser)->can_patron_change_permitted_staff_lists if $loggedinuser;
496
516
497
$template->param(
517
$template->param(
498
    op            => $op,
518
    op            => $op,
Lines 504-511 $template->param( Link Here
504
    listsview     => 1,
524
    listsview     => 1,
505
    staffuser     => $staffuser,
525
    staffuser     => $staffuser,
506
    permitteduser => $permitteduser,
526
    permitteduser => $permitteduser,
507
    xsl_exports => CustomXSLTExportList()
527
    xsl_exports   => CustomXSLTExportList()
508
);
528
);
509
529
510
my $content_type = $query->param('rss')? 'rss' : 'html';
530
my $content_type = $query->param('rss') ? 'rss' : 'html';
511
output_with_http_headers $query, $cookie, $template->output, $content_type;
531
output_with_http_headers $query, $cookie, $template->output, $content_type;
(-)a/t/db_dependent/XSLT.t (-139 / +174 lines)
Lines 30-36 use Koha::Libraries; Link Here
30
use Koha::ItemTypes;
30
use Koha::ItemTypes;
31
31
32
BEGIN {
32
BEGIN {
33
    use_ok('C4::XSLT', qw( buildKohaItemsNamespace ));
33
    use_ok( 'C4::XSLT', qw( buildKohaItemsNamespace ) );
34
}
34
}
35
35
36
my $schema  = Koha::Database->new->schema;
36
my $schema  = Koha::Database->new->schema;
Lines 38-49 my $builder = t::lib::TestBuilder->new; Link Here
38
our $cache = Koha::Caches->get_instance;
38
our $cache = Koha::Caches->get_instance;
39
39
40
subtest 'Tests moved from t' => sub {
40
subtest 'Tests moved from t' => sub {
41
    plan tests => 11;
41
    plan tests => 14;
42
    $schema->storage->txn_begin;
42
    $schema->storage->txn_begin;
43
43
44
    my $dir = File::Temp->newdir();
44
    my $dir    = File::Temp->newdir();
45
    my @themes = ('prog', 'test');
45
    my @themes = ( 'prog', 'test' );
46
    my @langs = ('en', 'es-ES');
46
    my @langs  = ( 'en', 'es-ES' );
47
47
48
    # create temporary files to be tested later
48
    # create temporary files to be tested later
49
    foreach my $theme (@themes) {
49
    foreach my $theme (@themes) {
Lines 56-64 subtest 'Tests moved from t' => sub { Link Here
56
    }
56
    }
57
57
58
    sub find_and_slurp {
58
    sub find_and_slurp {
59
        my ($dir, $theme, $lang) = @_;
59
        my ( $dir, $theme, $lang ) = @_;
60
60
61
        my $filename = C4::XSLT::_get_best_default_xslt_filename($dir, $theme, $lang, 'my_file.xslt');
61
        my $filename = C4::XSLT::_get_best_default_xslt_filename( $dir, $theme, $lang, 'my_file.xslt' );
62
        open my $fh, '<', $filename;
62
        open my $fh, '<', $filename;
63
        my $str = <$fh>;
63
        my $str = <$fh>;
64
        close $fh;
64
        close $fh;
Lines 67-115 subtest 'Tests moved from t' => sub { Link Here
67
67
68
    # These tests verify that we're finding the right XSLT file when present,
68
    # These tests verify that we're finding the right XSLT file when present,
69
    # and falling back to the right XSLT file when an exact match is not present.
69
    # and falling back to the right XSLT file when an exact match is not present.
70
    is(find_and_slurp($dir, 'test', 'en'   ), 'Theme test, language en',    'Found test/en');
70
    is( find_and_slurp( $dir, 'test', 'en' ),    'Theme test, language en',    'Found test/en' );
71
    is(find_and_slurp($dir, 'test', 'es-ES'), 'Theme test, language es-ES', 'Found test/es-ES');
71
    is( find_and_slurp( $dir, 'test', 'es-ES' ), 'Theme test, language es-ES', 'Found test/es-ES' );
72
    is(find_and_slurp($dir, 'prog', 'en',  ), 'Theme prog, language en',    'Found test/en');
72
    is( find_and_slurp( $dir, 'prog', 'en', ),   'Theme prog, language en',    'Found test/en' );
73
    is(find_and_slurp($dir, 'prog', 'es-ES'), 'Theme prog, language es-ES', 'Found test/es-ES');
73
    is( find_and_slurp( $dir, 'prog', 'es-ES' ), 'Theme prog, language es-ES', 'Found test/es-ES' );
74
    is(find_and_slurp($dir, 'test', 'fr-FR'), 'Theme test, language en',    'Fell back to test/en for test/fr-FR');
74
    is( find_and_slurp( $dir, 'test', 'fr-FR' ), 'Theme test, language en',    'Fell back to test/en for test/fr-FR' );
75
    is(find_and_slurp($dir, 'nope', 'es-ES'), 'Theme prog, language es-ES', 'Fell back to prog/es-ES for nope/es-ES');
75
    is(
76
    is(find_and_slurp($dir, 'nope', 'fr-FR'), 'Theme prog, language en',    'Fell back to prog/en for nope/fr-FR');
76
        find_and_slurp( $dir, 'nope', 'es-ES' ), 'Theme prog, language es-ES',
77
        'Fell back to prog/es-ES for nope/es-ES'
78
    );
79
    is( find_and_slurp( $dir, 'nope', 'fr-FR' ), 'Theme prog, language en', 'Fell back to prog/en for nope/fr-FR' );
77
80
78
    my $matching_string = q{<syspref name="singleBranchMode">[0|1]</syspref>};
81
    my $matching_string = q{<syspref name="singleBranchMode">[0|1]</syspref>};
79
    my $sysprefs_xml = C4::XSLT::get_xslt_sysprefs();
82
    my $sysprefs_xml    = C4::XSLT::get_xslt_sysprefs();
80
    ok( $sysprefs_xml =~ m/$matching_string/, 'singleBranchMode has no value');
83
    ok( $sysprefs_xml =~ m/$matching_string/, 'singleBranchMode has no value' );
84
85
    sub createXSLTFiles {
86
        my ( $path ) = @_;
87
88
        open my $fh, '>', "$path/export_01.xsl";
89
        print $fh qq|<?xml version="1.0" encoding="UTF-8"?>
90
        <xsl:stylesheet version="1.0"
91
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
92
        xmlns:marc="http://www.loc.gov/MARC21/slim"
93
        title="Export 01">
94
        </xsl:stylesheet>|;
95
        close $fh;
96
97
        # Make XSL without title
98
        open $fh, '>', "$path/export_02.xsl";
99
        print $fh qq|<?xml version="1.0" encoding="UTF-8"?>
100
        <xsl:stylesheet version="1.0"
101
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
102
        xmlns:marc="http://www.loc.gov/MARC21/slim">
103
        </xsl:stylesheet>|;
104
        close $fh;
105
106
        open $fh, '>', "$path/export_03.xsl";
107
        print $fh qq|<?xml version="1.0" encoding="UTF-8"?>|;
108
        close $fh;
109
    }
110
111
    t::lib::Mocks::mock_preference( 'CustomXSLTExportPath', '' );
112
    t::lib::Mocks::mock_config( 'opachtdocs', "$dir" );
81
113
82
    t::lib::Mocks::mock_config('opachtdocs', "$dir");
83
    make_path("$dir/bootstrap/en/xslt/biblioexport");
114
    make_path("$dir/bootstrap/en/xslt/biblioexport");
115
    createXSLTFiles("$dir/bootstrap/en/xslt/biblioexport");
84
116
85
    # Make XSL with title
117
    t::lib::Mocks::mock_preference( 'OpacExportOptions', 'custom' );
86
    open my $fh, '>', "$dir/bootstrap/en/xslt/biblioexport/export_01.xsl";
118
    my @custom_xslts = @{ C4::XSLT::CustomXSLTExportList(1) };
87
    print $fh qq|<?xml version="1.0" encoding="UTF-8"?>
119
88
    <xsl:stylesheet version="1.0"
120
    ok( ( scalar @custom_xslts ) == 2,               "CustomXSLTExportList finds custom XSLTs" );
89
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
121
    ok( $custom_xslts[0]->{filename} eq "Export 01", "Title is specified in root node" );
90
       xmlns:marc="http://www.loc.gov/MARC21/slim"
122
    ok( $custom_xslts[1]->{filename} eq "export_02", "Title is filename if not specified" );
91
       title="Export 01">
123
92
    </xsl:stylesheet>|;
124
    # CustomXSLTExportPath
93
    close $fh;
125
    t::lib::Mocks::mock_preference( 'CustomXSLTExportPath', "/$dir/XSLTExportFiles" );
94
126
    make_path("$dir/XSLTExportFiles");
95
    # Make XSL without title
127
    createXSLTFiles("$dir/XSLTExportFiles");
96
    open $fh, '>', "$dir/bootstrap/en/xslt/biblioexport/export_02.xsl";
128
    @custom_xslts = @{ C4::XSLT::CustomXSLTExportList(1) };
97
    print $fh qq|<?xml version="1.0" encoding="UTF-8"?>
129
98
    <xsl:stylesheet version="1.0"
130
    ok( ( scalar @custom_xslts ) == 2,               "CustomXSLTExportList finds custom XSLTs with CustomXSLTExportPath" );
99
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
131
    ok( $custom_xslts[0]->{filename} eq "Export 01", "Title is specified in root node with CustomXSLTExportPath" );
100
       xmlns:marc="http://www.loc.gov/MARC21/slim">
132
    ok( $custom_xslts[1]->{filename} eq "export_02", "Title is filename if not specified with CustomXSLTExportPath" );
101
    </xsl:stylesheet>|;
102
    close $fh;
103
104
    open $fh, '>', "$dir/bootstrap/en/xslt/biblioexport/export_03.xsl";
105
    print $fh qq|<?xml version="1.0" encoding="UTF-8"?>|;
106
    close $fh;
107
108
    t::lib::Mocks::mock_preference( 'OpacExportOptions', 'custom');
109
    my @custom_xslts = @{C4::XSLT::CustomXSLTExportList(1)};
110
    ok((scalar @custom_xslts) == 2, "CustomXSLTExportList finds custom XSLTs");
111
    ok($custom_xslts[0]->{filename} eq "Export 01", "Title is specified in root node");
112
    ok($custom_xslts[1]->{filename} eq "export_02", "Title is filename if not specified");
113
133
114
    $schema->storage->txn_rollback;
134
    $schema->storage->txn_rollback;
115
};
135
};
Lines 118-220 subtest 'buildKohaItemsNamespace status tests' => sub { Link Here
118
    plan tests => 18;
138
    plan tests => 18;
119
    $schema->storage->txn_begin;
139
    $schema->storage->txn_begin;
120
140
121
    t::lib::Mocks::mock_preference('Reference_NFL_Statuses', '1|2');
141
    t::lib::Mocks::mock_preference( 'Reference_NFL_Statuses', '1|2' );
122
    t::lib::Mocks::mock_preference( 'OPACResultsLibrary', 'holdingbranch' );
142
    t::lib::Mocks::mock_preference( 'OPACResultsLibrary',     'holdingbranch' );
123
    t::lib::Mocks::mock_preference( 'OPACResultsMaxItems', '2' );
143
    t::lib::Mocks::mock_preference( 'OPACResultsMaxItems',    '2' );
124
144
125
    my $itype = $builder->build_object({ class => 'Koha::ItemTypes' });
145
    my $itype          = $builder->build_object( { class => 'Koha::ItemTypes' } );
126
    my $itemtype = $builder->build_object({ class => 'Koha::ItemTypes' });
146
    my $itemtype       = $builder->build_object( { class => 'Koha::ItemTypes' } );
127
    my $holdinglibrary = $builder->build_object({ class => 'Koha::Libraries' });
147
    my $holdinglibrary = $builder->build_object( { class => 'Koha::Libraries' } );
128
    my $item = $builder->build_sample_item({ itype => $itype->itemtype });
148
    my $item = $builder->build_sample_item( { itype => $itype->itemtype } );
129
    $item->holdingbranch( $holdinglibrary->branchcode )->store;
149
    $item->holdingbranch( $holdinglibrary->branchcode )->store;
130
    $item->biblioitem->itemtype($itemtype->itemtype)->store;
150
    $item->biblioitem->itemtype( $itemtype->itemtype )->store;
131
151
132
    my $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
152
    my $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber, [] );
133
    like($xml,qr{<status>available</status>},"Item is available when no other status applied");
153
    like( $xml, qr{<status>available</status>}, "Item is available when no other status applied" );
134
154
135
    # notforloan
155
    # notforloan
136
    {
156
    {
137
        t::lib::Mocks::mock_preference('item-level_itypes', 0);
157
        t::lib::Mocks::mock_preference( 'item-level_itypes', 0 );
138
        $item->notforloan(0)->store;
158
        $item->notforloan(0)->store;
139
        Koha::ItemTypes->find($item->itype)->notforloan(0)->store;
159
        Koha::ItemTypes->find( $item->itype )->notforloan(0)->store;
140
        Koha::ItemTypes->find($item->biblioitem->itemtype)->notforloan(1)->store;
160
        Koha::ItemTypes->find( $item->biblioitem->itemtype )->notforloan(1)->store;
141
        $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
161
        $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber, [] );
142
        like($xml,qr{<status>reference</status>},"reference if positive itype notforloan value");
162
        like( $xml, qr{<status>reference</status>}, "reference if positive itype notforloan value" );
143
163
144
        t::lib::Mocks::mock_preference('item-level_itypes', 1);
164
        t::lib::Mocks::mock_preference( 'item-level_itypes', 1 );
145
        Koha::ItemTypes->find($item->itype)->notforloan(1)->store;
165
        Koha::ItemTypes->find( $item->itype )->notforloan(1)->store;
146
        Koha::ItemTypes->find($item->biblioitem->itemtype)->notforloan(0)->store;
166
        Koha::ItemTypes->find( $item->biblioitem->itemtype )->notforloan(0)->store;
147
        $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
167
        $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber, [] );
148
        like($xml,qr{<status>reference</status>},"reference if positive itemtype notforloan value");
168
        like( $xml, qr{<status>reference</status>}, "reference if positive itemtype notforloan value" );
149
        Koha::ItemTypes->find($item->itype)->notforloan(0)->store;
169
        Koha::ItemTypes->find( $item->itype )->notforloan(0)->store;
150
170
151
        my $substatus = Koha::AuthorisedValues->search({ category => 'NOT_LOAN', authorised_value => -1 })->next->lib;
171
        my $substatus = Koha::AuthorisedValues->search( { category => 'NOT_LOAN', authorised_value => -1 } )->next->lib;
152
        $item->notforloan(-1)->store;
172
        $item->notforloan(-1)->store;
153
        $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
173
        $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber, [] );
154
        like($xml,qr{<status>reallynotforloan</status>},"reallynotforloan if negative notforloan value");
174
        like( $xml, qr{<status>reallynotforloan</status>}, "reallynotforloan if negative notforloan value" );
155
        like($xml,qr{<substatus>$substatus</substatus>},"substatus set if negative notforloan value");
175
        like( $xml, qr{<substatus>$substatus</substatus>}, "substatus set if negative notforloan value" );
156
176
157
        $item->notforloan(1)->store;
177
        $item->notforloan(1)->store;
158
        $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
178
        $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber, [] );
159
        like($xml,qr{<status>reference</status>},"reference if positive notforloan value");
179
        like( $xml, qr{<status>reference</status>}, "reference if positive notforloan value" );
160
180
161
        # But now make status notforloan==1 count under Not available
181
        # But now make status notforloan==1 count under Not available
162
        t::lib::Mocks::mock_preference('Reference_NFL_Statuses', '2');
182
        t::lib::Mocks::mock_preference( 'Reference_NFL_Statuses', '2' );
163
        $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
183
        $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber, [] );
164
        like($xml,qr{<status>reallynotforloan</status>},"reallynotforloan when we change Reference_NFL_Statuses");
184
        like( $xml, qr{<status>reallynotforloan</status>}, "reallynotforloan when we change Reference_NFL_Statuses" );
165
        t::lib::Mocks::mock_preference('Reference_NFL_Statuses', q{}); # empty, same effect
185
        t::lib::Mocks::mock_preference( 'Reference_NFL_Statuses', q{} );    # empty, same effect
166
        $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
186
        $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber, [] );
167
        like($xml,qr{<status>reallynotforloan</status>},"reallynotforloan when we empty Reference_NFL_Statuses");
187
        like( $xml, qr{<status>reallynotforloan</status>}, "reallynotforloan when we empty Reference_NFL_Statuses" );
168
        t::lib::Mocks::mock_preference('Reference_NFL_Statuses', '1|2');
188
        t::lib::Mocks::mock_preference( 'Reference_NFL_Statuses', '1|2' );
169
    }
189
    }
170
190
171
    $item->onloan('2001-01-01')->store;
191
    $item->onloan('2001-01-01')->store;
172
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
192
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber, [] );
173
    like( $xml, qr/<status>other<\/status>/, "Checked out is part of other statuses" );
193
    like( $xml, qr/<status>other<\/status>/,            "Checked out is part of other statuses" );
174
    like($xml,qr{<substatus>Checked out</substatus>},"Checked out status takes precedence over Not for loan");
194
    like( $xml, qr{<substatus>Checked out</substatus>}, "Checked out status takes precedence over Not for loan" );
175
195
176
    $item->withdrawn(1)->store;
196
    $item->withdrawn(1)->store;
177
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
197
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber, [] );
178
    like($xml,qr{<substatus>Withdrawn</substatus>},"Withdrawn status takes precedence over Checked out");
198
    like( $xml, qr{<substatus>Withdrawn</substatus>}, "Withdrawn status takes precedence over Checked out" );
179
199
180
    $item->itemlost(1)->store;
200
    $item->itemlost(1)->store;
181
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
201
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber, [] );
182
    like($xml,qr{<substatus>Lost</substatus>},"Lost status takes precedence over Withdrawn");
202
    like( $xml, qr{<substatus>Lost</substatus>}, "Lost status takes precedence over Withdrawn" );
183
203
184
    $item->damaged(1)->store;
204
    $item->damaged(1)->store;
185
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
205
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber, [] );
186
    like($xml,qr{<substatus>Damaged</substatus>},"Damaged status takes precedence over Lost");
206
    like( $xml, qr{<substatus>Damaged</substatus>}, "Damaged status takes precedence over Lost" );
187
207
188
    $builder->build({ source => "Branchtransfer", value => {
208
    $builder->build(
189
        itemnumber  => $item->itemnumber,
209
        {
190
        datearrived => undef,
210
            source => "Branchtransfer",
191
        datecancelled => undef,
211
            value  => {
212
                itemnumber    => $item->itemnumber,
213
                datearrived   => undef,
214
                datecancelled => undef,
215
            }
192
        }
216
        }
193
    });
217
    );
194
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
218
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber, [] );
195
    like($xml,qr{<substatus>In transit</substatus>},"In-transit status takes precedence over Damaged");
219
    like( $xml, qr{<substatus>In transit</substatus>}, "In-transit status takes precedence over Damaged" );
196
220
197
    my $hold = $builder->build_object({ class => 'Koha::Holds', value => {
221
    my $hold = $builder->build_object(
198
        biblionumber => $item->biblionumber,
222
        {
199
        itemnumber   => $item->itemnumber,
223
            class => 'Koha::Holds',
200
        found        => 'W',
224
            value => {
201
        priority     => 0,
225
                biblionumber => $item->biblionumber,
226
                itemnumber   => $item->itemnumber,
227
                found        => 'W',
228
                priority     => 0,
229
            }
202
        }
230
        }
203
    });
231
    );
204
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
232
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber, [] );
205
    like($xml,qr{<substatus>Hold waiting</substatus>},"Waiting status takes precedence over In transit (holds)");
233
    like( $xml, qr{<substatus>Hold waiting</substatus>}, "Waiting status takes precedence over In transit (holds)" );
206
    $hold->cancel;
234
    $hold->cancel;
207
235
208
    $builder->build({ source => "TmpHoldsqueue", value => {
236
    $builder->build( { source => "TmpHoldsqueue", value => { itemnumber => $item->itemnumber } } );
209
        itemnumber => $item->itemnumber
237
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber, [] );
210
        }
238
    like( $xml, qr{<substatus>Pending hold</substatus>}, "Pending status takes precedence over all" );
211
    });
212
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
213
    like($xml,qr{<substatus>Pending hold</substatus>},"Pending status takes precedence over all");
214
    my $library_name = $holdinglibrary->branchname;
239
    my $library_name = $holdinglibrary->branchname;
215
    like($xml,qr{<resultbranch>${library_name}</resultbranch>}, "Found resultbranch / holding branch" );
240
    like( $xml, qr{<resultbranch>${library_name}</resultbranch>}, "Found resultbranch / holding branch" );
216
241
217
    t::lib::Mocks::mock_preference('UseRecalls', 1);
242
    t::lib::Mocks::mock_preference( 'UseRecalls', 1 );
218
    my $recall = $builder->build_object(
243
    my $recall = $builder->build_object(
219
        {
244
        {
220
            class => 'Koha::Recalls',
245
            class => 'Koha::Recalls',
Lines 227-246 subtest 'buildKohaItemsNamespace status tests' => sub { Link Here
227
        }
252
        }
228
    );
253
    );
229
    $recall->set_waiting;
254
    $recall->set_waiting;
230
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
255
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber, [] );
231
    like($xml,qr{<substatus>Recall waiting</substatus>},"Waiting status takes precedence over In transit (recalls)");
256
    like(
232
    t::lib::Mocks::mock_preference('UseRecalls', 0);
257
        $xml, qr{<substatus>Recall waiting</substatus>},
258
        "Waiting status takes precedence over In transit (recalls)"
259
    );
260
    t::lib::Mocks::mock_preference( 'UseRecalls', 0 );
233
261
234
    $schema->storage->txn_rollback;
262
    $schema->storage->txn_rollback;
235
};
263
};
236
264
237
subtest 'CustomXSLTExportList: Check export options' => sub {
265
subtest 'CustomXSLTExportList: Check export options' => sub {
238
    plan tests => 2;
266
    plan tests => 2;
239
    t::lib::Mocks::mock_preference('OpacExportOptions', 'custom');
267
    t::lib::Mocks::mock_preference( 'OpacExportOptions', 'custom' );
240
    my $list = C4::XSLT::CustomXSLTExportList(1);
268
    my $list = C4::XSLT::CustomXSLTExportList(1);
241
    is( $list>0, 1, 'We expect at least one result: simple export' );
269
    is( $list > 0, 1, 'We expect at least one result: simple export' );
242
    $cache->clear_from_cache('CustomXSLTExportListOPAC');
270
    $cache->clear_from_cache('CustomXSLTExportListOPAC');
243
    t::lib::Mocks::mock_preference('OpacExportOptions', 'dc');
271
    t::lib::Mocks::mock_preference( 'OpacExportOptions', 'dc' );
244
    $list = C4::XSLT::CustomXSLTExportList(1);
272
    $list = C4::XSLT::CustomXSLTExportList(1);
245
    is( @$list, 0, 'We expect an empty list now' );
273
    is( @$list, 0, 'We expect an empty list now' );
246
};
274
};
Lines 250-268 subtest 'buildKohaItemsNamespace() including/omitting items tests' => sub { Link Here
250
278
251
    $schema->storage->txn_begin;
279
    $schema->storage->txn_begin;
252
280
253
    my $biblio = $builder->build_sample_biblio;
281
    my $biblio  = $builder->build_sample_biblio;
254
    my $biblio2 = $builder->build_sample_biblio;
282
    my $biblio2 = $builder->build_sample_biblio;
255
283
256
    # Have two known libraries for testing purposes
284
    # Have two known libraries for testing purposes
257
    my $library_1 = $builder->build_object({ class => 'Koha::Libraries' });
285
    my $library_1 = $builder->build_object( { class => 'Koha::Libraries' } );
258
    my $library_2 = $builder->build_object({ class => 'Koha::Libraries' });
286
    my $library_2 = $builder->build_object( { class => 'Koha::Libraries' } );
259
    my $library_3 = $builder->build_object({ class => 'Koha::Libraries' });
287
    my $library_3 = $builder->build_object( { class => 'Koha::Libraries' } );
260
288
261
    my $item_1 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber, library => $library_1->id });
289
    my $item_1 = $builder->build_sample_item( { biblionumber => $biblio->biblionumber, library => $library_1->id } );
262
    my $item_2 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber, library => $library_2->id });
290
    my $item_2 = $builder->build_sample_item( { biblionumber => $biblio->biblionumber, library => $library_2->id } );
263
    my $item_3 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber, library => $library_3->id });
291
    my $item_3 = $builder->build_sample_item( { biblionumber => $biblio->biblionumber, library => $library_3->id } );
264
292
265
    my $items_rs = $biblio->items->search({ "me.itemnumber" => { '!=' => $item_3->itemnumber } });
293
    my $items_rs = $biblio->items->search( { "me.itemnumber" => { '!=' => $item_3->itemnumber } } );
266
294
267
    ## Test passing items_rs only
295
    ## Test passing items_rs only
268
    my $xml = C4::XSLT::buildKohaItemsNamespace( $biblio->biblionumber, undef, $items_rs );
296
    my $xml = C4::XSLT::buildKohaItemsNamespace( $biblio->biblionumber, undef, $items_rs );
Lines 271-296 subtest 'buildKohaItemsNamespace() including/omitting items tests' => sub { Link Here
271
    my $library_2_name = $library_2->branchname;
299
    my $library_2_name = $library_2->branchname;
272
    my $library_3_name = $library_3->branchname;
300
    my $library_3_name = $library_3->branchname;
273
301
274
    like(   $xml, qr{<homebranch>$library_1_name</homebranch>}, '$item_1 present in the XML' );
302
    like( $xml, qr{<homebranch>$library_1_name</homebranch>}, '$item_1 present in the XML' );
275
    like(   $xml, qr{<homebranch>$library_2_name</homebranch>}, '$item_2 present in the XML' );
303
    like( $xml, qr{<homebranch>$library_2_name</homebranch>}, '$item_2 present in the XML' );
276
    unlike( $xml, qr{<homebranch>$library_3_name</homebranch>}, '$item_3 not present in the XML' );
304
    unlike( $xml, qr{<homebranch>$library_3_name</homebranch>}, '$item_3 not present in the XML' );
277
305
278
    t::lib::Mocks::mock_preference('OpacHiddenItems', 'biblionumber: ['.$biblio2->biblionumber.']');
306
    t::lib::Mocks::mock_preference( 'OpacHiddenItems', 'biblionumber: [' . $biblio2->biblionumber . ']' );
279
    my $hid_rs = $biblio->items->search({ "me.itemnumber" => { '!=' => $item_3->itemnumber } })->filter_by_visible_in_opac();
307
    my $hid_rs =
308
        $biblio->items->search( { "me.itemnumber" => { '!=' => $item_3->itemnumber } } )->filter_by_visible_in_opac();
280
    $xml = C4::XSLT::buildKohaItemsNamespace( $biblio->biblionumber, undef, $hid_rs );
309
    $xml = C4::XSLT::buildKohaItemsNamespace( $biblio->biblionumber, undef, $hid_rs );
281
    like(   $xml, qr{<homebranch>$library_1_name</homebranch>}, '$item_1 present in the XML' );
310
    like( $xml, qr{<homebranch>$library_1_name</homebranch>}, '$item_1 present in the XML' );
282
    like(   $xml, qr{<homebranch>$library_2_name</homebranch>}, '$item_2 present in the XML' );
311
    like( $xml, qr{<homebranch>$library_2_name</homebranch>}, '$item_2 present in the XML' );
283
    unlike( $xml, qr{<homebranch>$library_3_name</homebranch>}, '$item_3 not present in the XML' );
312
    unlike( $xml, qr{<homebranch>$library_3_name</homebranch>}, '$item_3 not present in the XML' );
284
313
285
    ## Test passing one item in hidden_items and items_rs
314
    ## Test passing one item in hidden_items and items_rs
286
    $xml = C4::XSLT::buildKohaItemsNamespace( $biblio->biblionumber, [ $item_1->itemnumber ], $items_rs->reset );
315
    $xml = C4::XSLT::buildKohaItemsNamespace( $biblio->biblionumber, [ $item_1->itemnumber ], $items_rs->reset );
287
316
288
    unlike( $xml, qr{<homebranch>$library_1_name</homebranch>}, '$item_1 not present in the XML' );
317
    unlike( $xml, qr{<homebranch>$library_1_name</homebranch>}, '$item_1 not present in the XML' );
289
    like(   $xml, qr{<homebranch>$library_2_name</homebranch>}, '$item_2 present in the XML' );
318
    like( $xml, qr{<homebranch>$library_2_name</homebranch>}, '$item_2 present in the XML' );
290
    unlike( $xml, qr{<homebranch>$library_3_name</homebranch>}, '$item_3 not present in the XML' );
319
    unlike( $xml, qr{<homebranch>$library_3_name</homebranch>}, '$item_3 not present in the XML' );
291
320
292
    ## Test passing both items in hidden_items and items_rs
321
    ## Test passing both items in hidden_items and items_rs
293
    $xml = C4::XSLT::buildKohaItemsNamespace( $biblio->biblionumber, [ $item_1->itemnumber, $item_2->itemnumber ], $items_rs->reset );
322
    $xml = C4::XSLT::buildKohaItemsNamespace(
323
        $biblio->biblionumber, [ $item_1->itemnumber, $item_2->itemnumber ],
324
        $items_rs->reset
325
    );
294
326
295
    unlike( $xml, qr{<homebranch>$library_1_name</homebranch>}, '$item_1 not present in the XML' );
327
    unlike( $xml, qr{<homebranch>$library_1_name</homebranch>}, '$item_1 not present in the XML' );
296
    unlike( $xml, qr{<homebranch>$library_2_name</homebranch>}, '$item_2 not present in the XML' );
328
    unlike( $xml, qr{<homebranch>$library_2_name</homebranch>}, '$item_2 not present in the XML' );
Lines 298-304 subtest 'buildKohaItemsNamespace() including/omitting items tests' => sub { Link Here
298
    is( $xml, '<items xmlns="http://www.koha-community.org/items"></items>', 'Empty XML' );
330
    is( $xml, '<items xmlns="http://www.koha-community.org/items"></items>', 'Empty XML' );
299
331
300
    ## Test passing both items in hidden_items and no items_rs
332
    ## Test passing both items in hidden_items and no items_rs
301
    $xml = C4::XSLT::buildKohaItemsNamespace( $biblio->biblionumber, [ $item_1->itemnumber, $item_2->itemnumber, $item_3->itemnumber ] );
333
    $xml = C4::XSLT::buildKohaItemsNamespace(
334
        $biblio->biblionumber,
335
        [ $item_1->itemnumber, $item_2->itemnumber, $item_3->itemnumber ]
336
    );
302
337
303
    unlike( $xml, qr{<homebranch>$library_1_name</homebranch>}, '$item_1 not present in the XML' );
338
    unlike( $xml, qr{<homebranch>$library_1_name</homebranch>}, '$item_1 not present in the XML' );
304
    unlike( $xml, qr{<homebranch>$library_2_name</homebranch>}, '$item_2 not present in the XML' );
339
    unlike( $xml, qr{<homebranch>$library_2_name</homebranch>}, '$item_2 not present in the XML' );
Lines 309-316 subtest 'buildKohaItemsNamespace() including/omitting items tests' => sub { Link Here
309
    $xml = C4::XSLT::buildKohaItemsNamespace( $biblio->biblionumber, [ $item_1->itemnumber ] );
344
    $xml = C4::XSLT::buildKohaItemsNamespace( $biblio->biblionumber, [ $item_1->itemnumber ] );
310
345
311
    unlike( $xml, qr{<homebranch>$library_1_name</homebranch>}, '$item_1 not present in the XML' );
346
    unlike( $xml, qr{<homebranch>$library_1_name</homebranch>}, '$item_1 not present in the XML' );
312
    like(   $xml, qr{<homebranch>$library_2_name</homebranch>}, '$item_2 present in the XML' );
347
    like( $xml, qr{<homebranch>$library_2_name</homebranch>}, '$item_2 present in the XML' );
313
    like(   $xml, qr{<homebranch>$library_3_name</homebranch>}, '$item_3 present in the XML' );
348
    like( $xml, qr{<homebranch>$library_3_name</homebranch>}, '$item_3 present in the XML' );
314
349
315
    ## Test not passing any param
350
    ## Test not passing any param
316
    $xml = C4::XSLT::buildKohaItemsNamespace( $biblio->biblionumber );
351
    $xml = C4::XSLT::buildKohaItemsNamespace( $biblio->biblionumber );
(-)a/virtualshelves/downloadshelf.pl (-36 / +33 lines)
Lines 27-33 use C4::Record; Link Here
27
use C4::Ris qw( marc2ris );
27
use C4::Ris qw( marc2ris );
28
use C4::XSLT qw( XSLTParse4Display );
28
use C4::XSLT qw( XSLTParse4Display );
29
29
30
31
use Koha::Biblios;
30
use Koha::Biblios;
32
use Koha::CsvProfiles;
31
use Koha::CsvProfiles;
33
use Koha::Virtualshelves;
32
use Koha::Virtualshelves;
Lines 35-46 use Koha::Virtualshelves; Link Here
35
use utf8;
34
use utf8;
36
my $query = CGI->new;
35
my $query = CGI->new;
37
36
38
my ( $template, $loggedinuser, $cookie ) = get_template_and_user (
37
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
39
    {
38
    {
40
        template_name   => "virtualshelves/downloadshelf.tt",
39
        template_name => "virtualshelves/downloadshelf.tt",
41
        query           => $query,
40
        query         => $query,
42
        type            => "intranet",
41
        type          => "intranet",
43
        flagsrequired   => { catalogue => 1 },
42
        flagsrequired => { catalogue => 1 },
44
    }
43
    }
45
);
44
);
46
45
Lines 49-92 my $format = $query->param('format'); Link Here
49
my $dbh     = C4::Context->dbh;
48
my $dbh     = C4::Context->dbh;
50
my @messages;
49
my @messages;
51
50
52
if ($shelfid && $format) {
51
if ( $shelfid && $format ) {
53
52
54
    my $marcflavour         = C4::Context->preference('marcflavour');
53
    my $marcflavour = C4::Context->preference('marcflavour');
55
    my $output='';
54
    my $output      = '';
56
55
57
    my $shelf = Koha::Virtualshelves->find($shelfid);
56
    my $shelf = Koha::Virtualshelves->find($shelfid);
58
    if ( $shelf ) {
57
    if ($shelf) {
59
        if ( $shelf->can_be_viewed( $loggedinuser ) ) {
58
        if ( $shelf->can_be_viewed($loggedinuser) ) {
60
59
61
            my $contents = $shelf->get_contents;
60
            my $contents = $shelf->get_contents;
61
62
            # CSV
62
            # CSV
63
            if ($format =~ /^\d+$/) {
63
            if ( $format =~ /^\d+$/ ) {
64
                my @biblios;
64
                my @biblios;
65
                while ( my $content = $contents->next ) {
65
                while ( my $content = $contents->next ) {
66
                    push @biblios, $content->biblionumber;
66
                    push @biblios, $content->biblionumber;
67
                }
67
                }
68
                $output = marc2csv(\@biblios, $format);
68
                $output = marc2csv( \@biblios, $format );
69
            }
69
            } else {    #Other formats
70
            else { #Other formats
71
                while ( my $content = $contents->next ) {
70
                while ( my $content = $contents->next ) {
72
                    my $biblionumber = $content->biblionumber;
71
                    my $biblionumber = $content->biblionumber;
73
                    my $biblio = Koha::Biblios->find($biblionumber);
72
                    my $biblio       = Koha::Biblios->find($biblionumber);
74
                    my $record = $biblio->metadata->record({ embed_items => 1 });
73
                    my $record       = $biblio->metadata->record( { embed_items => 1 } );
75
                    my $xslFile = $query->param("file");
74
                    my $xslFile      = $query->param("file");
76
                    if ($format eq 'iso2709') {
75
                    if ( $format eq 'iso2709' ) {
77
                        $output .= $record->as_usmarc();
76
                        $output .= $record->as_usmarc();
78
                    }
77
                    } elsif ( $format eq 'ris' ) {
79
                    elsif ($format eq 'ris') {
80
                        $output .= marc2ris($record);
78
                        $output .= marc2ris($record);
81
                    }
79
                    } elsif ( $format eq 'bibtex' ) {
82
                    elsif ($format eq 'bibtex') {
80
                        $output .= marc2bibtex( $record, $biblionumber );
83
                        $output .= marc2bibtex($record, $biblionumber);
81
                    } elsif ( $format =~ /^xsl\.(.*)$/ ) {
84
                    }
85
                    elsif ($format =~ /^xsl\.(.*)$/){
86
                        $output .= XSLTParse4Display(
82
                        $output .= XSLTParse4Display(
87
                            {
83
                            {
88
                                biblionumber => $biblionumber,
84
                                biblionumber => $biblionumber,
89
                                record => $record,
85
                                record       => $record,
90
                                xsl_syspref  => 'XSLTCustomExport',
86
                                xsl_syspref  => 'XSLTCustomExport',
91
                                fix_amps     => 1,
87
                                fix_amps     => 1,
92
                                hidden_items => undef,
88
                                hidden_items => undef,
Lines 98-109 if ($shelfid && $format) { Link Here
98
            }
94
            }
99
95
100
            # If it was a CSV export we change the format after the export so the file extension is fine
96
            # If it was a CSV export we change the format after the export so the file extension is fine
101
            $format = "csv" if ($format =~ m/^\d+$/);
97
            $format = "csv"  if ( $format =~ m/^\d+$/ );
102
            $format = "html" if ($format =~ /^xsl\./);
98
            $format = "html" if ( $format =~ /^xsl\./ );
103
            print $query->header(
99
            print $query->header(
104
            -type => 'application/octet-stream',
100
                -type                        => 'application/octet-stream',
105
            -'Content-Transfer-Encoding' => 'binary',
101
                -'Content-Transfer-Encoding' => 'binary',
106
            -attachment=>"shelf.$format");
102
                -attachment                  => "shelf.$format"
103
            );
107
            print $output;
104
            print $output;
108
            exit;
105
            exit;
109
        } else {
106
        } else {
Lines 112-121 if ($shelfid && $format) { Link Here
112
    } else {
109
    } else {
113
        push @messages, { type => 'error', code => 'does_not_exist' };
110
        push @messages, { type => 'error', code => 'does_not_exist' };
114
    }
111
    }
115
}
112
} else {
116
else {
113
    $template->param(
117
    $template->param(csv_profiles => [ Koha::CsvProfiles->search({ type => 'marc', used_for => 'export_records' })->as_list ]);
114
        csv_profiles => [ Koha::CsvProfiles->search( { type => 'marc', used_for => 'export_records' } )->as_list ] );
118
    $template->param(shelfid => $shelfid); 
115
    $template->param( shelfid => $shelfid );
119
}
116
}
120
$template->param( messages => \@messages );
117
$template->param( messages => \@messages );
121
output_html_with_http_headers $query, $cookie, $template->output;
118
output_html_with_http_headers $query, $cookie, $template->output;
(-)a/virtualshelves/shelves.pl (-9 / +8 lines)
Lines 385-399 if ( $op eq 'view' ) { Link Here
385
}
385
}
386
386
387
$template->param(
387
$template->param(
388
    op       => $op,
388
    op             => $op,
389
    referer  => $referer,
389
    referer        => $referer,
390
    shelf    => $shelf,
390
    shelf          => $shelf,
391
    messages => \@messages,
391
    messages       => \@messages,
392
    public   => $public,
392
    public         => $public,
393
    print    => scalar $query->param('print') || 0,
393
    print          => scalar $query->param('print') || 0,
394
    csv_profiles => [ Koha::CsvProfiles->search({ type => 'marc', used_for => 'export_records' })->as_list ],
394
    csv_profiles   => [ Koha::CsvProfiles->search({ type => 'marc', used_for => 'export_records' })->as_list ],
395
    allow_transfer => $allow_transfer,
395
    allow_transfer => $allow_transfer,
396
    xsl_exports => CustomXSLTExportList()
396
    xsl_exports    => CustomXSLTExportList()
397
);
397
);
398
398
399
output_html_with_http_headers $query, $cookie, $template->output;
399
output_html_with_http_headers $query, $cookie, $template->output;
400
- 

Return to bug 17385