Bug 6536: Add XSLT transformation on Z3950 search results
authorMarcel de Rooy <m.de.rooy@rijksmuseum.nl>
Thu, 10 Jul 2014 15:21:21 +0000 (17:21 +0200)
committerTomas Cohen Arazi <tomascohen@gmail.com>
Mon, 1 Sep 2014 13:09:10 +0000 (10:09 -0300)
Use the stylesheets listed in field add_xslt of z3950servers to transform
search results of Z3950/SRU search.
Additionally, the template has been changed to make more error messages (or
warnings) visible when displaying results. Until now, error message were
shown in the results table and when connection errors occurred, no results
were displayed at all.

Test plan:
Create some stylesheets (or see the sample patch on bug 6536).
Add these stylesheets to some Z3950/SRU servers.
Do Z3950 search and verify the transformations.
Do a search with 2 targets; make one target fail (by manipulating its server
data). Do you see the connection error and the results for the other target?
Generate a XSLT error by modifying one stylesheet. Check search results. You
should see warnings.

Signed-off-by: Giuseppe Angilella <giuseppe.angilella@ct.infn.it>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@gmail.com>
C4/Breeding.pm
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/z3950_search.tt

index 2001fa5..7125cb2 100644 (file)
@@ -27,7 +27,9 @@ use C4::Charset;
 use MARC::File::USMARC;
 use C4::ImportBatch;
 use C4::AuthoritiesMarc; #GuessAuthTypeCode, FindDuplicateAuthority
+use C4::Languages;
 use Koha::Database;
+use Koha::XSLT_Handler;
 
 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
 
@@ -164,6 +166,7 @@ sub Z3950Search {
                     _translate_query( $server, $squery )));
         $s++;
     }
+    my $xslh = Koha::XSLT_Handler->new;
 
     my $nremaining = $s;
     while ( $nremaining-- ) {
@@ -185,17 +188,19 @@ sub Z3950Search {
             else {
                 my $numresults = $oResult[$k]->size();
                 my $i;
-                my $result = '';
+                my $res;
                 if ( $numresults > 0  and $numresults >= (($page-1)*20)) {
                     $show_next = 1 if $numresults >= ($page*20);
                     $total_pages = int($numresults/20)+1 if $total_pages < ($numresults/20);
                     for ($i = ($page-1)*20; $i < (($numresults < ($page*20)) ? $numresults : ($page*20)); $i++) {
-                        if($oResult[$k]->record($i)) {
-                            my $res=_handle_one_result($oResult[$k]->record($i), $servers[$k], ++$imported, $biblionumber); #ignores error in sequence numbering
+                        if ( $oResult[$k]->record($i) ) {
+                            undef $error;
+                            ( $res, $error ) = _handle_one_result( $oResult[$k]->record($i), $servers[$k], ++$imported, $biblionumber, $xslh ); #ignores error in sequence numbering
                             push @breeding_loop, $res if $res;
+                            push @errconn, { server => $servers[$k]->{servername}, error => $error, seq => $i+1 } if $error;
                         }
                         else {
-                            push(@breeding_loop,{'server'=>$servers[$k]->{servername},'title'=>join(': ',$oConnection[$k]->error_x()),'breedingid'=>-1,'biblionumber'=>-1});
+                            push @errconn, { 'server' => $servers[$k]->{servername}, error => ( ( $oConnection[$k]->error_x() )[0] ), seq => $i+1 };
                         }
                     }
                 }    #if $numresults
@@ -258,7 +263,7 @@ sub _build_query {
 }
 
 sub _handle_one_result {
-    my ($zoomrec, $servhref, $seq, $bib)= @_;
+    my ( $zoomrec, $servhref, $seq, $bib, $xslh )= @_;
 
     my $raw= $zoomrec->raw();
     my $marcrecord;
@@ -269,6 +274,8 @@ sub _handle_one_result {
         ($marcrecord) = MarcToUTF8Record($raw, C4::Context->preference('marcflavour'), $servhref->{encoding} // "iso-5426" ); #ignores charset return values
     }
     SetUTF8Flag($marcrecord);
+    my $error;
+    ( $marcrecord, $error ) = _do_xslt_proc($marcrecord, $servhref, $xslh);
 
     my $batch_id = GetZ3950BatchId($servhref->{servername});
     my $breedingid = AddBiblioToBatch($batch_id, $seq, $marcrecord, 'UTF-8', 0, 0);
@@ -279,12 +286,38 @@ sub _handle_one_result {
 
     #call to TransformMarcToKoha replaced by next call
     #we only need six fields from the marc record
-    return _add_rowdata(
+    my $row;
+    $row = _add_rowdata(
         {
             biblionumber => $bib,
             server       => $servhref->{servername},
             breedingid   => $breedingid,
         }, $marcrecord) if $breedingid;
+    return ( $row, $error );
+}
+
+sub _do_xslt_proc {
+    my ( $marc, $server, $xslh ) = @_;
+    return $marc if !$server->{add_xslt};
+
+    my $htdocs = C4::Context->config('intrahtdocs');
+    my $theme = C4::Context->preference("template"); #staff
+    my $lang = C4::Languages::getlanguage() || 'en';
+
+    my @files= split ',', $server->{add_xslt};
+    my $xml = $marc->as_xml;
+    foreach my $f ( @files ) {
+        $f =~ s/^\s+//; $f =~ s/\s+$//; next if !$f;
+        $f = C4::XSLT::_get_best_default_xslt_filename(
+            $htdocs, $theme, $lang, $f ) unless $f =~ /^\//;
+        $xml = $xslh->transform( $xml, $f );
+        last if $xslh->err; #skip other files
+    }
+    if( !$xslh->err ) {
+        return MARC::Record->new_from_xml($xml, 'UTF-8');
+    } else {
+        return ( $marc, 'xslt_err' ); #original record in case of errors
+    }
 }
 
 sub _add_rowdata {
index 587a9e3..3e79247 100644 (file)
@@ -161,6 +161,20 @@ tr.selected { background-color : #FFFFCC; } tr.selected td { background-color :
         [% IF ( stdid ) %]<em>Standard ID: </em><span class=term>[% stdid %]</span> [% END %]
     </p>
 
+    [% IF ( errconn ) %]
+            <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>
+                    [% ELSIF ( errcon.error == 'xslt_err' ) %]<li>[% errcon.server %]: Warning: XSLT error on search result [% errcon.seq %]</li>
+                    [% ELSE %]<li>[% errcon.server %] record [% errcon.seq %]: [% errcon.error %]</li>
+                    [% END %]
+                [% END %]
+                </ul>
+            </div>
+    [% END %]
+
     [% IF ( breeding_loop ) %]
     <table id="resultst">
 <thead>    <tr>
@@ -223,22 +237,10 @@ tr.selected { background-color : #FFFFCC; } tr.selected td { background-color :
         <br />Go to page : <input id="goto_page" name="goto_page" value="[% current_page %]" size="4" /><input type="submit" name="changepage_goto" onclick="return validate_goto_page();" value="Go" />
     </form>
 
-<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 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 %]
-                [% END %]
-                </ul>
-            </div>
-         [% END %]
-    <div class="dialog message"><h3>Nothing found</h3>
-    <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>
+        <div class="dialog message">Nothing found.</div>
     [% 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 %]