Bug 3326: Work around Zebra's handling of & entities
[srvgit] / C4 / Search.pm
index 229ee40..c486df9 100644 (file)
@@ -29,7 +29,6 @@ use C4::XSLT;
 use C4::Branch;
 use C4::Reserves;    # CheckReserves
 use C4::Debug;
-use YAML;
 use URI::Escape;
 
 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $DEBUG);
@@ -651,7 +650,6 @@ sub _remove_stopwords {
 #
                foreach ( keys %{ C4::Context->stopwords } ) {
                        next if ( $_ =~ /(and|or|not)/ );    # don't remove operators
-                       $debug && warn "$_ Dump($operand)";
                        if ( my ($matched) = ($operand =~
                                /([^\X\p{isAlnum}]\Q$_\E[^\X\p{isAlnum}]|[^\X\p{isAlnum}]\Q$_\E$|^\Q$_\E[^\X\p{isAlnum}])/gi))
                        {
@@ -895,6 +893,8 @@ sub getIndexes{
                     'popularity',
                     'pubdate',
                     'Publisher',
+                    'Record-control-number',
+                    'rcn',
                     'Record-type',
                     'rtype',
                     'se',
@@ -1043,7 +1043,13 @@ sub buildQuery {
 # for handling ccl, cql, pqf queries in diagnostic mode, skip the rest of the steps
 # DIAGNOSTIC ONLY!!
     if ( $query =~ /^ccl=/ ) {
-        return ( undef, $', $', "q=ccl=$'", $', '', '', '', '', 'ccl' );
+        my $q=$';
+        # This is needed otherwise ccl= and &limit won't work together, and
+        # this happens when selecting a subject on the opac-detail page
+        if (@limits) {
+            $q .= ' and '.join(' and ', @limits);
+        }
+        return ( undef, $q, $q, "q=ccl=$q", $q, '', '', '', '', 'ccl' );
     }
     if ( $query =~ /^cql=/ ) {
         return ( undef, $', $', "q=cql=$'", $', '', '', '', '', 'cql' );
@@ -1256,21 +1262,28 @@ sub buildQuery {
     my $group_OR_limits;
     my $availability_limit;
     foreach my $this_limit (@limits) {
-#        if ( $this_limit =~ /available/ ) {
+        if ( $this_limit =~ /available/ ) {
 #
 ## 'available' is defined as (items.onloan is NULL) and (items.itemlost = 0)
 ## In English:
 ## all records not indexed in the onloan register (zebra) and all records with a value of lost equal to 0
-#            $availability_limit .=
-#"( ( allrecords,AlwaysMatches='' not onloan,AlwaysMatches='') and (lost,st-numeric=0) )"; #or ( allrecords,AlwaysMatches='' not lost,AlwaysMatches='')) )";
-#            $limit_cgi  .= "&limit=available";
-#            $limit_desc .= "";
-#        }
-#
+            $availability_limit .=
+"( ( allrecords,AlwaysMatches='' not onloan,AlwaysMatches='') and (lost,st-numeric=0) )"; #or ( allrecords,AlwaysMatches='' not lost,AlwaysMatches='')) )";
+            $limit_cgi  .= "&limit=available";
+            $limit_desc .= "";
+        }
+
         # group_OR_limits, prefixed by mc-
         # OR every member of the group
-#        elsif ( $this_limit =~ /mc/ ) {
-        if ( $this_limit =~ /mc/ ) {
+        elsif ( $this_limit =~ /mc/ ) {
+        
+            if ( $this_limit =~ /mc-ccode:/ ) {
+                # in case the mc-ccode value has complicating chars like ()'s inside it we wrap in quotes
+                $this_limit =~ tr/"//d;
+                my ($k,$v) = split(/:/, $this_limit,2);
+                $this_limit = $k.":\"".$v."\"";
+            }
+
             $group_OR_limits .= " or " if $group_OR_limits;
             $limit_desc      .= " or " if $group_OR_limits;
             $group_OR_limits .= "$this_limit";
@@ -1310,10 +1323,11 @@ sub buildQuery {
     # if user wants to do ccl or cql, start the query with that
 #    $query =~ s/:/=/g;
     $query =~ s/(?<=(ti|au|pb|su|an|kw|mc)):/=/g;
-    $query =~ s/(?<=rtrn):/=/g;
+    $query =~ s/(?<=(wrdl)):/=/g;
+    $query =~ s/(?<=(trn|phr)):/=/g;
     $limit =~ s/:/=/g;
     for ( $query, $query_desc, $limit, $limit_desc ) {
-        s/  / /g;    # remove extra spaces
+        s/  +/ /g;    # remove extra spaces
         s/^ //g;     # remove any beginning spaces
         s/ $//g;     # remove any ending spaces
         s/==/=/g;    # remove double == from query
@@ -1345,6 +1359,10 @@ sub buildQuery {
 
 =head2 searchResults
 
+  my @search_results = searchResults($search_context, $searchdesc, $hits, 
+                                     $results_per_page, $offset, $scan, 
+                                     @marcresults, $hidelostitems);
+
 Format results in a form suitable for passing to the template
 
 =cut
@@ -1352,10 +1370,12 @@ Format results in a form suitable for passing to the template
 # IMO this subroutine is pretty messy still -- it's responsible for
 # building the HTML output for the template
 sub searchResults {
-    my ( $searchdesc, $hits, $results_per_page, $offset, $scan, @marcresults, $hidelostitems ) = @_;
+    my ( $search_context, $searchdesc, $hits, $results_per_page, $offset, $scan, @marcresults, $hidelostitems ) = @_;
     my $dbh = C4::Context->dbh;
     my @newresults;
 
+    $search_context = 'opac' unless $search_context eq 'opac' or $search_context eq 'intranet';
+
     #Build branchnames hash
     #find branchname
     #get branch information.....
@@ -1422,12 +1442,11 @@ sub searchResults {
     # loop through all of the records we've retrieved
     for ( my $i = $offset ; $i <= $times - 1 ; $i++ ) {
         my $marcrecord = MARC::File::USMARC::decode( $marcresults[$i] );
-        if ($bibliotag<10){
-            $fw = GetFrameworkCode($marcrecord->field($bibliotag)->data);
-        }else{
-            $fw = GetFrameworkCode($marcrecord->subfield($bibliotag,$bibliosubf));
-        }
-
+        $fw = $scan
+             ? undef
+             : $bibliotag < 10
+               ? GetFrameworkCode($marcrecord->field($bibliotag)->data)
+               : GetFrameworkCode($marcrecord->subfield($bibliotag,$bibliosubf));
         my $oldbiblio = TransformMarcToKoha( $dbh, $marcrecord, $fw );
         $oldbiblio->{subtitle} = GetRecordValue('subtitle', $marcrecord, $fw);
         $oldbiblio->{result_number} = $i + 1;
@@ -1606,7 +1625,7 @@ sub searchResults {
                 if (   $item->{wthdrawn}
                     || $item->{itemlost}
                     || $item->{damaged}
-                    || $item->{notforloan}
+                    || $item->{notforloan} > 0
                    || $reservestatus eq 'Waiting'
                     || ($transfertwhen ne ''))
                 {
@@ -1664,9 +1683,13 @@ sub searchResults {
        use C4::Charset;
        SetUTF8Flag($marcrecord);
        $debug && warn $marcrecord->as_formatted;
-        if (C4::Context->preference("XSLTResultsDisplay") && !$scan) {
-            $oldbiblio->{XSLTResultsRecord} = XSLTParse4Display(
-                $oldbiblio->{biblionumber}, $marcrecord, 'Results' );
+        if (!$scan && $search_context eq 'opac' && C4::Context->preference("OPACXSLTResultsDisplay")) {
+            # FIXME note that XSLTResultsDisplay (use of XSLT to format staff interface bib search results)
+            # is not implemented yet
+            $oldbiblio->{XSLTResultsRecord} = XSLTParse4Display($oldbiblio->{biblionumber}, $marcrecord, 'Results', 
+                                                                $search_context, 1);
+                # the last parameter tells Koha to clean up the problematic ampersand entities that Zebra outputs
+
         }
 
         # last check for norequest : if itemtype is notforloan, it can't be reserved either, whatever the items
@@ -1907,7 +1930,6 @@ sub NZanalyse {
         # depending of operand, intersect, union or exclude both lists
         # to get a result list
         if ( $operator eq ' and ' ) {
-            warn "NZAND";
             return NZoperatorAND($leftresult,$rightresult);
         }
         elsif ( $operator eq ' or ' ) {
@@ -2568,7 +2590,7 @@ AND (authtypecode IS NOT NULL AND authtypecode<>\"\")|);
   #There are no results, build authority record, add it to Authorities, get authid and add it to 9
   ###NOTICE : This is only valid if a subfield is linked to one and only one authtypecode
   ###NOTICE : This can be a problem. We should also look into other types and rejected forms.
-         my $authtypedata=C4::AuthoritiesMarc->GetAuthType($data->{authtypecode});
+         my $authtypedata=C4::AuthoritiesMarc::GetAuthType($data->{authtypecode});
          next unless $authtypedata;
          my $marcrecordauth=MARC::Record->new();
          my $authfield=MARC::Field->new($authtypedata->{auth_tag_to_report},'','',"a"=>"".$field->subfield('a'));
@@ -2653,6 +2675,6 @@ __END__
 
 =head1 AUTHOR
 
-Koha Developement team <info@koha.org>
+Koha Development Team <http://koha-community.org/>
 
 =cut