Bug Fixing : NZsearch
[koha.git] / C4 / Search.pm
index d408dcb..e19e3dc 100644 (file)
@@ -1181,8 +1181,55 @@ sub NZanalyse {
     # split the query string in 3 parts : X AND Y means : $left="X", $operand="AND" and $right="Y"
     # then, call again NZanalyse with $left and $right
     # (recursive until we find a leaf (=> something without and/or/not)
-    $string =~ /(.*)( and | or | not | AND | OR | NOT )(.*)/;
-    my $left = $1;
+    #process parenthesis before.   
+    if ($string =~ /^\s*\((.*)\)(( and | or | not | AND | OR | NOT )(.*))?/){
+      my $left = $1;
+      warn "left :".$left;   
+      my $right = $4;
+      my $operator = lc($3); # FIXME: and/or/not are operators, not operands
+      my $leftresult = NZanalyse($left,$server);
+      if ($operator) {
+        my $rightresult = NZanalyse($right,$server);
+        # OK, we have the results for right and left part of the query
+        # depending of operand, intersect, union or exclude both lists
+        # to get a result list
+        if ($operator eq ' and ') {
+            my @leftresult = split /;/, $leftresult;
+#             my @rightresult = split /;/,$leftresult;
+            my $finalresult;
+            # parse the left results, and if the biblionumber exist in the right result, save it in finalresult
+            # the result is stored twice, to have the same weight for AND than OR.
+            # example : TWO : 61,61,64,121 (two is twice in the biblio #61) / TOWER : 61,64,130
+            # result : 61,61,61,61,64,64 for two AND tower : 61 has more weight than 64
+            foreach (@leftresult) {
+                if ($rightresult =~ "$_;") {
+                    $finalresult .= "$_;$_;";
+                }
+            }
+            return $finalresult;
+        } elsif ($operator eq ' or ') {
+            # just merge the 2 strings
+            return $leftresult.$rightresult;
+        } elsif ($operator eq ' not ') {
+            my @leftresult = split /;/, $leftresult;
+#             my @rightresult = split /;/,$leftresult;
+            my $finalresult;
+            foreach (@leftresult) {
+                unless ($rightresult =~ "$_;") {
+                    $finalresult .= "$_;";
+                }
+            }
+            return $finalresult;
+        } else {
+            # this error is impossible, because of the regexp that isolate the operand, but just in case...
+            return $leftresult;
+            exit;        
+        }
+      }   
+    }  
+    warn "string :".$string;
+    $string =~ /(.*?)( and | or | not | AND | OR | NOT )(.*)/;
+    my $left = $1;   
     my $right = $3;
     my $operand = lc($2); # FIXME: and/or/not are operators, not operands
     # it's not a leaf, we have a and/or/not
@@ -1231,7 +1278,7 @@ sub NZanalyse {
     } else {
         $string =~  s/__X__/"$commacontent"/ if $commacontent;
         $string =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|&|\+|\*|\// /g;
-         warn "leaf : $string\n" if $DEBUG;
+        warn "leaf : $string\n" if $DEBUG;
         # parse the string in in operator/operand/value again
         $string =~ /(.*)(>=|<=)(.*)/;
         my $left = $1;
@@ -1258,8 +1305,10 @@ sub NZanalyse {
             my $sth = $dbh->prepare("SELECT biblionumbers,value FROM nozebra WHERE server=? AND indexname=? AND value $operator ?");
             warn "$left / $operator / $right\n";
             # split each word, query the DB and build the biblionumbers result
+            #sanitizing leftpart      
+            $left=~s/^\s+|\s+$//;
+            my ($biblionumbers,$value);
             foreach (split / /,$right) {
-                my ($biblionumbers,$value);
                 next unless $_;
                 warn "EXECUTE : $server, $left, $_";
                 $sth->execute($server, $left, $_) or warn "execute failed: $!";
@@ -1267,7 +1316,7 @@ sub NZanalyse {
                     # if we are dealing with a numeric value, use only numeric results (in case of >=, <=, > or <)
                     # otherwise, fill the result
                     $biblionumbers .= $line unless ($right =~ /\d/ && $value =~ /\D/);
-                    warn "result : $value ". ($right =~ /\d/) . "==".(!$value =~ /\d/) ;#= $line";
+                    warn "result : $value ". ($right =~ /\d/) . "==".(!$value =~ /\d/) ;#= $line";
                 }
                 # do a AND with existing list if there is one, otherwise, use the biblionumbers list as 1st result list
                 if ($results) {
@@ -1326,7 +1375,7 @@ sub NZanalyse {
                 }
             }
         }
-         warn "return : $results for LEAF : $string" if $DEBUG;
+#         warn "return : $results for LEAF : $string" if $DEBUG;
         return $results;
     }
 }