X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=blobdiff_plain;f=C4%2FXSLT.pm;h=1d09010ff08d5063f19cbe37ea7fd07300ab4c9f;hb=51d881069e5ef79e23c17368dc83e2f49c4eafa1;hp=7557efe5a2bac6d555a993877ef3d3aa6a14e7e1;hpb=20fd03724aca67beb98b09dbf2275a81a1f8a3a7;p=koha_fer diff --git a/C4/XSLT.pm b/C4/XSLT.pm index 7557efe5a2..1d09010ff0 100644 --- a/C4/XSLT.pm +++ b/C4/XSLT.pm @@ -1,14 +1,16 @@ package C4::XSLT; + # Copyright (C) 2006 LibLime # # Parts Copyright Katrin Fischer 2011 # Parts Copyright ByWater Solutions 2011 +# Parts Copyright Biblibre 2012 # # This file is part of Koha. # # Koha is free software; you can redistribute it and/or modify it under the # terms of the GNU General Public License as published by the Free Software -# Foundation; either version 2 of the License, or (at your option) any later +# Foundation; either version 3 of the License, or (at your option) any later # version. # # Koha is distributed in the hope that it will be useful, but WITHOUT ANY @@ -29,19 +31,25 @@ use C4::Koha; use C4::Biblio; use C4::Circulation; use C4::Reserves; +use Koha::XSLT_Handler; + use Encode; -use XML::LibXML; -use XML::LibXSLT; use vars qw($VERSION @ISA @EXPORT); +my $engine; #XSLT Handler object +my %authval_per_framework; + # Cache for tagfield-tagsubfield to decode per framework. + # Should be preferably be placed in Koha-core... + BEGIN { require Exporter; - $VERSION = 0.03; + $VERSION = 3.07.00.049; @ISA = qw(Exporter); @EXPORT = qw( &XSLTParse4Display ); + $engine=Koha::XSLT_Handler->new( { do_not_return_source => 1 } ); } =head1 NAME @@ -53,6 +61,7 @@ C4::XSLT - Functions for displaying XSLT-generated content =head2 transformMARCXML4XSLT Replaces codes with authorized values in a MARC::Record object +Is only used in this module currently. =cut @@ -92,13 +101,10 @@ sub transformMARCXML4XSLT { =head2 getAuthorisedValues4MARCSubfields Returns a ref of hash of ref of hash for tag -> letter controled by authorised values +Is only used in this module currently. =cut -# Cache for tagfield-tagsubfield to decode per framework. -# Should be preferably be placed in Koha-core... -my %authval_per_framework; - sub getAuthorisedValues4MARCSubfields { my ($frameworkcode) = @_; unless ( $authval_per_framework{ $frameworkcode } ) { @@ -118,14 +124,77 @@ sub getAuthorisedValues4MARCSubfields { return $authval_per_framework{ $frameworkcode }; } -my $stylesheet; +=head2 XSLTParse4Display + +Returns xml for biblionumber and requested XSLT transformation. +Returns undef if the transform fails. + +Used in OPAC results and detail, intranet results and detail, list display. +(Depending on the settings of your XSLT preferences.) + +The helper function _get_best_default_xslt_filename is used in a unit test. + +=cut + +sub _get_best_default_xslt_filename { + my ($htdocs, $theme, $lang, $base_xslfile) = @_; + + my @candidates = ( + "$htdocs/$theme/$lang/xslt/${base_xslfile}", # exact match + "$htdocs/$theme/en/xslt/${base_xslfile}", # if not, preferred theme in English + "$htdocs/prog/$lang/xslt/${base_xslfile}", # if not, 'prog' theme in preferred language + "$htdocs/prog/en/xslt/${base_xslfile}", # otherwise, prog theme in English; should always + # exist + ); + my $xslfilename; + foreach my $filename (@candidates) { + $xslfilename = $filename; + if (-f $filename) { + last; # we have a winner! + } + } + return $xslfilename; +} sub XSLTParse4Display { - my ( $biblionumber, $orig_record, $xsl_suffix, $interface, $fixamps, $hidden_items ) = @_; - $interface = 'opac' unless $interface; + my ( $biblionumber, $orig_record, $xslsyspref, $fixamps, $hidden_items ) = @_; + my $xslfilename = C4::Context->preference($xslsyspref); + if ( $xslfilename =~ /^\s*"?default"?\s*$/i ) { + my $htdocs; + my $theme; + my $lang = C4::Templates::_current_language(); + my $xslfile; + if ($xslsyspref eq "XSLTDetailsDisplay") { + $htdocs = C4::Context->config('intrahtdocs'); + $theme = C4::Context->preference("template"); + $xslfile = C4::Context->preference('marcflavour') . + "slim2intranetDetail.xsl"; + } elsif ($xslsyspref eq "XSLTResultsDisplay") { + $htdocs = C4::Context->config('intrahtdocs'); + $theme = C4::Context->preference("template"); + $xslfile = C4::Context->preference('marcflavour') . + "slim2intranetResults.xsl"; + } elsif ($xslsyspref eq "OPACXSLTDetailsDisplay") { + $htdocs = C4::Context->config('opachtdocs'); + $theme = C4::Context->preference("opacthemes"); + $xslfile = C4::Context->preference('marcflavour') . + "slim2OPACDetail.xsl"; + } elsif ($xslsyspref eq "OPACXSLTResultsDisplay") { + $htdocs = C4::Context->config('opachtdocs'); + $theme = C4::Context->preference("opacthemes"); + $xslfile = C4::Context->preference('marcflavour') . + "slim2OPACResults.xsl"; + } + $xslfilename = _get_best_default_xslt_filename($htdocs, $theme, $lang, $xslfile); + } + + if ( $xslfilename =~ m/\{langcode\}/ ) { + my $lang = C4::Templates::_current_language(); + $xslfilename =~ s/\{langcode\}/$lang/; + } + # grab the XML, run it through our stylesheet, push it out to the browser my $record = transformMARCXML4XSLT($biblionumber, $orig_record); - #return $record->as_formatted(); my $itemsxml = buildKohaItemsNamespace($biblionumber, $hidden_items); my $xmlrecord = $record->as_xml(C4::Context->preference('marcflavour')); my $sysxml = "\n"; @@ -134,8 +203,10 @@ sub XSLTParse4Display { OPACBaseURL TraceCompleteSubfields UseICU UseAuthoritiesForTracings TraceSubjectSubdivisions Display856uAsImage OPACDisplay856uAsImage - UseControlNumber - AlternateHoldingsField AlternateHoldingsSeparator / ) + UseControlNumber IntranetBiblioDefaultView BiblioDefaultView + singleBranchMode OPACItemLocation DisplayIconsXSLT + AlternateHoldingsField AlternateHoldingsSeparator + TrackClicks / ) { my $sp = C4::Context->preference( $syspref ); next unless defined($sp); @@ -143,42 +214,27 @@ sub XSLTParse4Display { } $sysxml .= "\n"; $xmlrecord =~ s/\<\/record\>/$itemsxml$sysxml\<\/record\>/; - if ($fixamps) { # We need to correct the ampersand entities that Zebra outputs + if ($fixamps) { # We need to correct the HTML entities that Zebra outputs $xmlrecord =~ s/\&amp;/\&/g; + $xmlrecord =~ s/\&\;lt\;/\<\;/g; + $xmlrecord =~ s/\&\;gt\;/\>\;/g; } $xmlrecord =~ s/\& /\&\; /; $xmlrecord =~ s/\&\;amp\; /\&\; /; - my $parser = XML::LibXML->new(); - # don't die when you find &, >, etc - $parser->recover_silently(0); - my $source = $parser->parse_string($xmlrecord); - unless ( $stylesheet ) { - my $xslt = XML::LibXSLT->new(); - my $xslfile; - if ($interface eq 'intranet') { - $xslfile = C4::Context->config('intrahtdocs') . - '/' . C4::Context->preference("template") . - '/' . C4::Templates::_current_language() . - '/xslt/' . - C4::Context->preference('marcflavour') . - "slim2intranet$xsl_suffix.xsl"; - } else { - $xslfile = C4::Context->config('opachtdocs') . - '/' . C4::Context->preference("opacthemes") . - '/' . C4::Templates::_current_language() . - '/xslt/' . - C4::Context->preference('marcflavour') . - "slim2OPAC$xsl_suffix.xsl"; - } - my $style_doc = $parser->parse_file($xslfile); - $stylesheet = $xslt->parse_stylesheet($style_doc); - } - my $results = $stylesheet->transform($source); - my $newxmlrecord = $stylesheet->output_string($results); - return $newxmlrecord; + #If the xslt should fail, we will return undef (old behavior was + #raw MARC) + #Note that we did set do_not_return_source at object construction + return $engine->transform($xmlrecord, $xslfilename ); #file or URL } +=head2 buildKohaItemsNamespace + +Returns XML for items. +Is only used in this module currently. + +=cut + sub buildKohaItemsNamespace { my ($biblionumber, $hidden_items) = @_; @@ -187,17 +243,23 @@ sub buildKohaItemsNamespace { my %hi = map {$_ => 1} @$hidden_items; @items = grep { !$hi{$_->{itemnumber}} } @items; } + + my $shelflocations = GetKohaAuthorisedValues('items.location',GetFrameworkCode($biblionumber), 'opac'); + my $ccodes = GetKohaAuthorisedValues('items.ccode',GetFrameworkCode($biblionumber), 'opac'); + my $branches = GetBranches(); my $itemtypes = GetItemTypes(); + my $location = ""; + my $ccode = ""; my $xml = ''; for my $item (@items) { my $status; my ( $transfertwhen, $transfertfrom, $transfertto ) = C4::Circulation::GetTransfers($item->{itemnumber}); - my ( $reservestatus, $reserveitem, undef ) = C4::Reserves::CheckReserves($item->{itemnumber}); + my $reservestatus = C4::Reserves::GetReserveStatus( $item->{itemnumber} ); - if ( $itemtypes->{ $item->{itype} }->{notforloan} || $item->{notforloan} || $item->{onloan} || $item->{wthdrawn} || $item->{itemlost} || $item->{damaged} || + if ( $itemtypes->{ $item->{itype} }->{notforloan} || $item->{notforloan} || $item->{onloan} || $item->{withdrawn} || $item->{itemlost} || $item->{damaged} || (defined $transfertwhen && $transfertwhen ne '') || $item->{itemnotforloan} || (defined $reservestatus && $reservestatus eq "Waiting") ){ if ( $item->{notforloan} < 0) { $status = "On order"; @@ -208,7 +270,7 @@ sub buildKohaItemsNamespace { if ($item->{onloan}) { $status = "Checked out"; } - if ( $item->{wthdrawn}) { + if ( $item->{withdrawn}) { $status = "Withdrawn"; } if ($item->{itemlost}) { @@ -227,28 +289,40 @@ sub buildKohaItemsNamespace { $status = "available"; } my $homebranch = $item->{homebranch}? xml_escape($branches->{$item->{homebranch}}->{'branchname'}):''; - my $itemcallnumber = xml_escape($item->{itemcallnumber}); + my $holdingbranch = $item->{holdingbranch}? xml_escape($branches->{$item->{holdingbranch}}->{'branchname'}):''; + $location = $item->{location}? xml_escape($shelflocations->{$item->{location}}||$item->{location}):''; + $ccode = $item->{ccode}? xml_escape($ccodes->{$item->{ccode}}||$item->{ccode}):''; + my $itemcallnumber = xml_escape($item->{itemcallnumber}); $xml.= "$homebranch". - "$status". - "".$itemcallnumber."" - . ""; - + "$holdingbranch". + "$location". + "$ccode". + "$status". + "".$itemcallnumber."". + ""; } $xml = "".$xml.""; return $xml; } +=head2 engine +Returns reference to XSLT handler object. -1; -__END__ +=cut + +sub engine { + return $engine; +} -=head1 NOTES +1; -=cut +__END__ =head1 AUTHOR Joshua Ferraro +Koha Development Team + =cut