Merge git://git.koha.org/pub/scm/koha
[koha.git] / C4 / Search.pm
index 3b52cae..ab6edc3 100644 (file)
@@ -429,8 +429,8 @@ sub getRecords {
                         my $tmprecord = MARC::Record->new();
                         $tmprecord->encoding('UTF-8');
                         my $tmptitle;
-
-                       # srote the minimal record in author/title (depending on MARC flavour)
+                                               my $tmpauthor;
+                       # the minimal record in author/title (depending on MARC flavour)
                         if ( C4::Context->preference("marcflavour") eq
                             "UNIMARC" )
                         {
@@ -441,15 +441,12 @@ sub getRecords {
                             );
                         }
                         else {
-                            $tmptitle = MARC::Field->new(
-                                '245', ' ', ' ',
-                                a => $term,
-                                b => $occ
-                            );
+                            $tmptitle = MARC::Field->new('245', ' ', ' ',a => $term,);
+                                                       $tmpauthor = MARC::Field->new('100', ' ', ' ',a => $occ,);
                         }
                         $tmprecord->append_fields($tmptitle);
-                        $results_hash->{'RECORDS'}[$j] =
-                          $tmprecord->as_usmarc();
+                                               $tmprecord->append_fields($tmpauthor);
+                        $results_hash->{'RECORDS'}[$j] = $tmprecord->as_usmarc();
                     }
                     else {
                         $record = $results[ $i - 1 ]->record($j)->raw();
@@ -660,8 +657,10 @@ sub _build_weighted_query {
         $weighted_query .= " or ti,phr,r3=\"$operand\"";            # phrase title
        #$weighted_query .= " or any,ext,r4=$operand";               # exact any
        #$weighted_query .=" or kw,wrdl,r5=\"$operand\"";            # word list any
-        $weighted_query .= " or wrd,fuzzy,r8=\"$operand\"" if $fuzzy_enabled; # add fuzzy, word list
-        $weighted_query .= " or wrd,right-Truncation,r9=\"$stemmed_operand\"" if ($stemming and $stemmed_operand); # add stemming, right truncation
+        $weighted_query .= " or wrdl,fuzzy,r8=\"$operand\"" if $fuzzy_enabled; # add fuzzy, word list
+        $weighted_query .= " or wrdl,right-Truncation,r9=\"$stemmed_operand\"" if ($stemming and $stemmed_operand); # add stemming, right truncation
+               $weighted_query .= " or wrdl,r9=\"$operand\"";
+
        # embedded sorting: 0 a-z; 1 z-a
        # $weighted_query .= ") or (sort1,aut=1";
     }
@@ -678,7 +677,7 @@ sub _build_weighted_query {
        $weighted_query .= " $index,ext,r1=\"$operand\"";            # exact index
        #$weighted_query .= " or (title-sort-az=0 or $index,startswithnt,st-word,r3=$operand #)";
        $weighted_query .= " or $index,phr,r3=\"$operand\"";         # phrase index
-       $weighted_query .= " or $index,rt,wrd,r3=\"$operand\"";      # word list index
+       $weighted_query .= " or $index,rt,wrdl,r3=\"$operand\"";      # word list index
     }
     $weighted_query .= "))";    # close rank specification
     return $weighted_query;
@@ -751,7 +750,8 @@ sub buildQuery {
 
                                # a flag to determine whether or not to add the index to the query
                                my $indexes_set;
-                               # if the user is sophisticated enough to specify an index, turn off some defaults
+
+                               # if the user is sophisticated enough to specify an index, turn off field weighting, stemming, and stopword handling
                                if ($operands[$i] =~ /(:|=)/ || $scan) {
                                        $weight_fields = 0;
                                        $stemming = 0;
@@ -760,9 +760,29 @@ sub buildQuery {
                 my $operand = $operands[$i];
                 my $index   = $indexes[$i];
 
+                               # add some attributes for certain index types
+                               # Date of Publication
+                               if ($index eq 'yr') {
+                                       $index .=",st-numeric";
+                                       $indexes_set++;
+                                       ($stemming,$auto_truncation,$weight_fields, $fuzzy_enabled, $remove_stopwords) = (0,0,0,0,0);
+                               }
+                               # Date of Acquisition
+                               elsif ($index eq 'acqdate') {
+                                       $index.=",st-date-normalized";
+                                       $indexes_set++;
+                                       ($stemming,$auto_truncation,$weight_fields, $fuzzy_enabled, $remove_stopwords) = (0,0,0,0,0);
+
+                               }
+
+                               # set default structure attribute (word list)
+                               my $struct_attr;
+                               unless (!$index || $index =~ /(st-|phr|ext|wrdl)/) {
+                                       $struct_attr = ",wrdl";
+                               }
                                # some helpful index modifs
-                my $index_plus = "$index:" if $index;
-                my $index_plus_comma="$index," if $index;
+                my $index_plus = $index.$struct_attr.":" if $index;
+                my $index_plus_comma=$index.$struct_attr."," if $index;
 
                 # Remove Stopwords
                                if ($remove_stopwords) {
@@ -876,15 +896,14 @@ sub buildQuery {
                        $limit_desc .=" or " if $group_OR_limits;
                        $group_OR_limits .= "$this_limit";
                        $limit_cgi .="&limit=$this_limit";
-                       $limit_desc .= "$this_limit";
+                       $limit_desc .= " $this_limit";
         }
-
                # regular old limits
                else {
                        $limit .= " and " if $limit || $query;
                        $limit .= "$this_limit";
                        $limit_cgi .="&limit=$this_limit";
-                       $limit_desc .=" and $this_limit";
+                       $limit_desc .=" $this_limit";
                }
     }
        if ($group_OR_limits) {
@@ -1033,19 +1052,28 @@ sub searchResults {
         }
         # add spans to search term in results for search term highlighting
         # save a native author, for the <a href=search.lq=<!--tmpl_var name="author"-->> link
+               my $searchhighlightblob;
+               for my $highlight_field ($marcrecord->fields) {
+                       next if $highlight_field->tag() =~ /(^00)/; # skip fixed fields
+                       my $match;
+                       my $field = $highlight_field->as_string();
+                       for my $term ( keys %$span_terms_hashref ) {
+                               if (($field =~ /$term/i) && (length($term) > 3)) {
+                                       $field =~ s/$term/<span class=\"term\">$&<\/span>/gi;
+                                       $match++;
+                               }
+                       }
+                       $searchhighlightblob .= $field." ... " if $match;
+               }
+               $oldbiblio->{'searchhighlightblob'} = $searchhighlightblob;
+
         $oldbiblio->{'author_nospan'} = $oldbiblio->{'author'};
-        foreach my $term ( keys %$span_terms_hashref ) {
+        for my $term ( keys %$span_terms_hashref ) {
             my $old_term = $term;
             if ( length($term) > 3 ) {
-                $term =~ s/(.*=|\)|\(|\+|\.|\?|\[|\])//g;
-                $term =~ s/\\//g;
-                $term =~ s/\*//g;
-
-                #FIXME: is there a better way to do this?
+                $term =~ s/(.*=|\)|\(|\+|\.|\?|\[|\]|\\|\*)//g;
                 $oldbiblio->{'title'} =~ s/$term/<span class=\"term\">$&<\/span>/gi;
-                $oldbiblio->{'subtitle'} =~
-                  s/$term/<span class=\"term\">$&<\/span>/gi;
-
+                $oldbiblio->{'subtitle'} =~ s/$term/<span class=\"term\">$&<\/span>/gi;
                 $oldbiblio->{'author'} =~ s/$term/<span class=\"term\">$&<\/span>/gi;
                 $oldbiblio->{'publishercode'} =~ s/$term/<span class=\"term\">$&<\/span>/gi;
                 $oldbiblio->{'place'} =~ s/$term/<span class=\"term\">$&<\/span>/gi;
@@ -1323,7 +1351,7 @@ sub NZanalyse {
         $left='subject' if $left =~ '^su$';
         $left='koha-Auth-Number' if $left =~ '^an$';
         $left='keyword' if $left =~ '^kw$';
-        if ($operator) {
+        if ($operator && $left  ne 'keyword' ) {
             #do a specific search
             my $dbh = C4::Context->dbh;
             $operator='LIKE' if $operator eq '=' and $right=~ /%/;
@@ -1364,7 +1392,7 @@ sub NZanalyse {
                 }
             }
         } else {
-            #do a complete search (all indexes)
+            #do a complete search (all indexes), if index='kw' do complete search too.
             my $dbh = C4::Context->dbh;
             my $sth = $dbh->prepare("SELECT biblionumbers FROM nozebra WHERE server=? AND value LIKE ?");
             # split each word, query the DB and build the biblionumbers result