From b0da26f6624d75fa1bb2714afa9750573060c717 Mon Sep 17 00:00:00 2001
From: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Date: Mon, 26 Nov 2012 13:56:38 +0100
Subject: [PATCH] 6536: xslt on v38
Content-Type: text/plain; charset=utf-8

Voeg xslt optie toe aan z3950 search
Pas templates aan om errors altijd te laten zien ook als er results zijn
Bij het testen kwam er gemiddeld 0.005 second per record bij voor xslt slag
---
 C4/Breeding.pm                                     |   80 +++++++++++++++++---
 .../prog/en/modules/acqui/z3950_search.tt          |   17 +++--
 .../prog/en/modules/cataloguing/z3950_search.tt    |   14 ++--
 3 files changed, 86 insertions(+), 25 deletions(-)

diff --git a/C4/Breeding.pm b/C4/Breeding.pm
index b49c65f..fdeed75 100644
--- a/C4/Breeding.pm
+++ b/C4/Breeding.pm
@@ -23,11 +23,14 @@ use warnings;
 #use Encode;
 use MARC::File::USMARC;
 #use ZOOM; #has been loaded already in Context
+use XML::LibXML;
+use XML::LibXSLT;
 
 use C4::Biblio;
 use C4::Koha;
 use C4::Charset;
 use C4::ImportBatch;
+use C4::Templates;
 
 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
 
@@ -39,6 +42,8 @@ BEGIN {
     @EXPORT = qw(&ImportBreeding &BreedingSearch Z3950Search);
 }
 
+my %xslthash;
+
 =head1 NAME
 
 C4::Breeding : module to add biblios to import_records via
@@ -230,10 +235,8 @@ sub Z3950Search {
     my ($pars, $template)= @_;
 
     my $server;
+    my @servers;
     my $marcdata;
-    my @encoding;
-    my @serverhost;
-    my @servername;
     my @sru;
     my @breeding_loop = ();
     my $numberpending;
@@ -315,6 +318,8 @@ sub Z3950Search {
         my $sth = $dbh->prepare("SELECT * FROM z3950servers WHERE id=? ORDER BY rank, name");
         $sth->execute($servid);
         while ( $server = $sth->fetchrow_hashref ) {
+            $servers[$s]= $server;
+            $servers[$s]->{encoding}= "iso-5426" if !$servers[$s]->{encoding};
             if($server->{host}=~/^sru=/) {
                 $sru[$s]= {
                     srufields=>$server->{srufields},
@@ -339,9 +344,6 @@ sub Z3950Search {
             else {
                 $oConnection[$s]->connect( $server->{host}, $server->{port} );
             }
-            $serverhost[$s] = $server->{host};
-            $servername[$s] = $server->{name};
-            $encoding[$s]   = ($server->{encoding}?$server->{encoding}:"iso-5426");
             $s++;
         }    ## while fetch
     }    # foreach
@@ -371,7 +373,7 @@ sub Z3950Search {
           $oConnection[$k]->error_x();
         if ($error) {
             if ($error =~ m/^(10000|10007)$/ ) {
-                push(@errconn, {'server' => $serverhost[$k], 'error' => $error});
+                push(@errconn, {'server' => $servers[$k]->{host}, 'error' => $error});
             }
         }
         else {
@@ -389,9 +391,14 @@ sub Z3950Search {
                             $marcrecord= MARC::Record->new_from_xml($marcdata,'UTF-8',$sru[$k]->{syntax});
                         }
                         else { #z3950
-                            ($marcrecord)= MarcToUTF8Record($marcdata, C4::Context->preference('marcflavour'), $encoding[$k]);
+                            ($marcrecord)= MarcToUTF8Record($marcdata, C4::Context->preference('marcflavour'), $servers[$k]->{encoding});
                         }
                         SetUTF8Flag($marcrecord);
+                        $marcrecord= do_xslt_proc($marcrecord, $servers[$k]->{add_xslt});
+                        if(!$marcrecord) {
+                            push @errconn, {'server' => $servers[$k]->{name}, 'error' => 'Additional XSLT failure on record '.$i}; #not a real connection error..
+                            next;
+                        }
 
                         my $oldbiblio = TransformMarcToKoha( $dbh, $marcrecord, "" );
                         $oldbiblio->{isbn}   =~ s/ |-|\.//g if $oldbiblio->{isbn};
@@ -405,11 +412,11 @@ sub Z3950Search {
                         $oldbiblio->{issn} =~ s/\(/ \(/g if $oldbiblio->{issn};
 
                         #call to ImportBreeding replaced by next two calls for optimization
-                        my $batch_id = GetZ3950BatchId($servername[$k]);
+                        my $batch_id = GetZ3950BatchId($servers[$k]->{name});
                         my $breedingid = AddBiblioToBatch($batch_id, 0, $marcrecord, 'UTF-8', $pars->{random});
 
                         my %row_data;
-                        $row_data{server}       = $servername[$k];
+                        $row_data{server}       = $servers[$k]->{name};
                         $row_data{isbn}         = $oldbiblio->{isbn};
                         $row_data{lccn}         = $oldbiblio->{lccn};
                         $row_data{title}        = $oldbiblio->{title};
@@ -421,7 +428,7 @@ sub Z3950Search {
                         push( @breeding_loop, \%row_data );
 
                     } else {
-                        push(@breeding_loop,{'server'=>$servername[$k],'title'=>join(': ',$oConnection[$k]->error_x()),'breedingid'=>-1,'biblionumber'=>-1});
+                        push(@breeding_loop,{'server'=>$servers[$k]->{name},'title'=>join(': ',$oConnection[$k]->error_x()),'breedingid'=>-1,'biblionumber'=>-1});
                     } # $rec
                 }
             }    #$numresults
@@ -430,7 +437,7 @@ sub Z3950Search {
     $numberpending = $nremaining - 1;
     $template->param(
         breeding_loop => \@breeding_loop,
-        server        => $servername[$k],
+        server        => $servers[$k]->{name},
         numberpending => $numberpending,
         biblionumber  => $pars->{biblionumber},
         errconn       => \@errconn,
@@ -493,5 +500,54 @@ sub tran_query { #translate to specific sru fields per server
   return $q;
 }
 
+sub do_xslt_proc {
+    my ($marcrec, $xsltfile)= @_;
+    return $marcrec if !$xsltfile;
+
+    my $stylesheet= _load_xslt_stylesheet($xsltfile);
+    return $marcrec if !$stylesheet;
+
+    my $parser = XML::LibXML->new();
+    my $doc= $parser->parse_string($marcrec->as_xml());
+    return if !$doc; #undef: trouble
+
+    my $result= $stylesheet->transform($doc);
+    my $xml= $stylesheet->output_as_chars($result);
+    return $xml? MARC::Record->new_from_xml($xml, 'UTF-8'): undef;
+}
+
+sub _load_xslt_stylesheet {
+    my ($name)= @_;
+    if(exists $xslthash{$name}) {
+        return $xslthash{$name}{stylesheet};
+    }
+    my $f=_full_xslt_path($name);
+    if($f && -e $f) {
+        my $parser = XML::LibXML->new();
+        #my $style_doc = $parser->parse_file($f);
+        my $style_doc = $parser->load_xml(location=>$f);
+        my $xslt = XML::LibXSLT->new();
+        $xslthash{$name}{stylesheet}= $xslt->parse_stylesheet($style_doc);
+        return $xslthash{$name}{stylesheet};
+    }
+}
+
+sub _full_xslt_path {
+  my $name=shift;
+  #absolute path?
+  if(substr($name,0,1) eq '/') {
+    return $name;
+  }
+  #a relative path: look in xslt subfolder of staff templates
+  my $dir= C4::Context->config('intrahtdocs').'/'.
+    C4::Context->preference('template');
+  #try language folder first, otherwise english
+  my $lang=C4::Templates::_current_language() || 'en'; #null->english
+  my $ff= $dir.'/'.$lang.'/xslt/'.$name;
+  return $ff if -e $ff;
+  $ff=$dir.'/en/xslt/'.$name;
+  return $ff;
+}
+
 1;
 __END__
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/z3950_search.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/z3950_search.tt
index 0d4ef2e..acdf74c 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/z3950_search.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/z3950_search.tt
@@ -156,23 +156,26 @@ tr.selected { background-color : #FFFFCC; } tr.selected td { background-color :
     [% END %]</tbody>
 </table>
     [% ELSE %]
-        [% IF ( emptyserverlist ) %]
+        <div class="dialog message">Nothing found. <a href="javascript: history.back()">Try another search</a>.</div>
+    [% END %]
+    [% IF ( emptyserverlist ) %]
             <div class="dialog alert">You didn't select any Z39.50 target.</div>
-        [% ELSE %]
-            [% IF ( errconn ) %]
+    [% ELSE %]
+        [% IF ( errconn ) %]
+            <h2>Problems</h2>
                 <div class="dialog alert">
                     <ul>
                     [% FOREACH errcon IN errconn %]
-                        <li>Connection failed to [% errcon.server %]</li>
+                        [% IF ( errcon.error == '10000' ) %]<li>Connection failed to [% errcon.server %]</li>
+                        [% ELSIF ( errcon.error == '10007' ) %]<li>Connection timeout to [% errcon.server %]</li>
+                        [% ELSE %]<li>[% errcon.server %]: [% errcon.error %]</li>
+                        [% END %]
                     [% END %]
                     </ul>
                 </div>
-            [% END %]
         [% END %]
-        <div class="dialog message">Nothing found. <a href="javascript: history.back()">Try another search</a>.</div>
     [% END %]
 
-
 [% END %]
 
 	</div>
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/z3950_search.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/z3950_search.tt
index ffd29d2..0877f1b 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/z3950_search.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/z3950_search.tt
@@ -160,21 +160,23 @@ tr.selected { background-color : #FFFFCC; } tr.selected td { background-color :
         [% END %]
     [% END %]</tbody>
 </table>
-<p><form method="get" action="/cgi-bin/koha/cataloguing/z3950_search.pl"><input type="hidden" name="biblionumber" value="[% biblionumber %]"/><input type="hidden" name="frameworkcode" value="[% frameworkcode %]"/><input type="submit" value="Try Another Search"/></form></p>
     [% ELSE %]
-        [% IF ( errconn ) %]
+        <div class="dialog message">Nothing found.</div>
+    [% END %]
+    [% IF ( errconn ) %]
+        <h2>Problems</h2>
             <div class="dialog alert">
                 <ul>
                 [% FOREACH errcon IN errconn %]
                     [% IF ( errcon.error == '10000' ) %]<li>Connection failed to [% errcon.server %]</li>
-                    [% ELSIF ( errcon.error == '10007' ) %]<li>Connection timeout to [% errcon.server %]</li>[% END %]
+                    [% ELSIF ( errcon.error == '10007' ) %]<li>Connection timeout to [% errcon.server %]</li>
+                    [% ELSE %]<li>[% errcon.server %]: [% errcon.error %]</li>
+                    [% END %]
                 [% END %]
                 </ul>
             </div>
-         [% END %]
-   <div class="dialog message">Nothing found.</div>
-	<p><form method="get" action="/cgi-bin/koha/cataloguing/z3950_search.pl"><input type="hidden" name="biblionumber" value="[% biblionumber %]"/><input type="hidden" name="frameworkcode" value="[% frameworkcode %]"/><input type="submit" value="Try Another Search"/></form></p>
     [% END %]
+    <p><form method="get" action="/cgi-bin/koha/cataloguing/z3950_search.pl"><input type="hidden" name="biblionumber" value="[% biblionumber %]"/><input type="hidden" name="frameworkcode" value="[% frameworkcode %]"/><input type="submit" value="Try Another Search"/></form></p>
 
 
 [% END %]
-- 
1.7.7.6