Head & rel_2_2 merged
[koha.git] / search.marc / search.pl
index ab398d0..24a2015 100755 (executable)
@@ -24,23 +24,82 @@ use CGI;
 use C4::Auth;
 use HTML::Template;
 use C4::Context;
-use C4::Search;
+use C4::Search;
 use C4::Auth;
 use C4::Output;
 use C4::Interface::CGI::Output;
 use C4::Biblio;
 use C4::SearchMarc;
+use C4::Acquisition;
 use C4::Koha; # XXX subfield_is_koha_internal_p
 
+# Creates the list of active tags using the active MARC configuration
+sub create_marclist {
+       my $dbh = C4::Context->dbh;
+       my $tagslib = &MARCgettagslib($dbh,1);
+       my @marcarray;
+       push @marcarray,"";
+       my $widest_menu_item_width = 0;
+       for (my $pass = 1; $pass <= 2; $pass += 1)
+       {
+               for (my $tabloop = 0; $tabloop<=10;$tabloop++)
+               {
+                       my $separator_inserted_p = 0; # FIXME... should not use!!
+                       foreach my $tag (sort(keys (%{$tagslib})))
+                       {
+                               foreach my $subfield (sort(keys %{$tagslib->{$tag}}))
+                               {
+                                       next if subfield_is_koha_internal_p($subfield);
+                                       next unless ($tagslib->{$tag}->{$subfield}->{tab} eq $tabloop);
+                                       my $menu_item = "$tag$subfield - $tagslib->{$tag}->{$subfield}->{lib}";
+                                       if ($pass == 1)
+                                       {
+                                               $widest_menu_item_width = length $menu_item if($widest_menu_item_width < length $menu_item);
+                                       } else {
+                                               if (!$separator_inserted_p)
+                                               {
+                                                       my $w = int(($widest_menu_item_width - 3 + 0.5)/2);
+                                                       my $s = ('-' x ($w * 4/5));
+                                                       push @marcarray,  "$s $tabloop $s";
+                                                       $separator_inserted_p = 1;
+                                               }
+                                       push @marcarray, $menu_item;
+                                       }
+                               }
+                       }
+               }
+       }
+       return \@marcarray;
+}
+
+# Creates a scrolling list with the associated default value.
+# Using more than one scrolling list in a CGI assigns the same default value to all the
+# scrolling lists on the page !?!? That's why this function was written.
+sub create_scrolling_list {
+       my ($params) = @_;
+       my $scrollist = sprintf("<select name=\"%s\" size=\"%d\" onChange='%s'>\n", $params->{'name'}, $params->{'size'}, $params->{'onChange'});
+
+       foreach my $tag (@{$params->{'values'}})
+       {
+               my $selected = "selected " if($params->{'default'} eq $tag);
+               $scrollist .= sprintf("<option %svalue=\"%s\">%s</option>\n", $selected, $tag, $tag);
+       }
+
+       $scrollist .= "</select>\n";
+
+       return $scrollist;
+}
+
 my $query=new CGI;
 my $type=$query->param('type');
-my $op = $query->param('op');
-
+my $op = $query->param('op') || "";
 my $dbh = C4::Context->dbh;
 
 my $startfrom=$query->param('startfrom');
-($startfrom) || ($startfrom=0);
+$startfrom=0 if(!defined $startfrom);
 my ($template, $loggedinuser, $cookie);
+my $searchdesc;
+my $resultsperpage;
 
 if ($op eq "do_search") {
        my @marclist = $query->param('marclist');
@@ -48,28 +107,130 @@ if ($op eq "do_search") {
        my @excluding = $query->param('excluding');
        my @operator = $query->param('operator');
        my @value = $query->param('value');
+
+               for (my $i=0;$i<=$#marclist;$i++) {
+               if ($searchdesc) { # don't put the and_or on the 1st search term
+                       $searchdesc .= $and_or[$i]." ".$excluding[$i]." ".($marclist[$i]?$marclist[$i]:"*")." ".$operator[$i]." ".$value[$i]." " if ($value[$i]);
+                       } else {
+                       $searchdesc = $excluding[$i]." ".($marclist[$i]?$marclist[$i]:"*")." ".$operator[$i]." ".$value[$i]." " if ($value[$i]);
+                       }
+               }
+       
+       $resultsperpage= $query->param('resultsperpage');
+       $resultsperpage = 19 if(!defined $resultsperpage);
+       my $orderby = $query->param('orderby');
+       my $desc_or_asc = $query->param('desc_or_asc');
+
        # builds tag and subfield arrays
        my @tags;
-       my @subfields;
+
        foreach my $marc (@marclist) {
-               push @tags, substr($marc,0,3);
-               push @subfields, substr($marc,3,1);
+               if ($marc) {
+                       my ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,$marc,'');
+                       if ($tag) {
+                               push @tags,$dbh->quote("$tag$subfield");
+                       } else {
+                               if ($marc =~ /^(\d){3}(. -)(.)*/)
+                               {
+                                       # The user is using the search catalogue part, more fields
+                                       push @tags, $dbh->quote(substr($marc,0,4));
+                               }
+                               else
+                               {
+                                       push @tags, $marc;
+                               }
+                       }
+               } else {
+                       push @tags, "";
+               }
+       }
+       findseealso($dbh,\@tags);
+       my ($results,$total) = catalogsearch($dbh, \@tags,\@and_or,
+                                                                               \@excluding, \@operator, \@value,
+                                                                               $startfrom*$resultsperpage, $resultsperpage,$orderby,$desc_or_asc);
+       if ($total == 1) {
+        # if only 1 answer, jump directly to the biblio
+       if (C4::Context->preference("IntranetBiblioDefaultView") eq "normal") {
+            print $query->redirect("/cgi-bin/koha/detail.pl?bib=".@$results[0]->{biblionumber});
+       } elsif (C4::Context->preference("IntranetBiblioDefaultView") eq "marc") {
+            print $query->redirect("/cgi-bin/koha/MARCdetail.pl?bib=".@$results[0]->{biblionumber});
+       } else {
+            print $query->redirect("/cgi-bin/koha/ISBDdetail.pl?bib=".@$results[0]->{biblionumber});
+       }
+        exit
        }
-       my @results = catalogsearch($dbh, \@tags, \@subfields, \@and_or,
-                                                                                       \@excluding, \@operator, \@value,
-                                                                                       $startfrom, 20);
        ($template, $loggedinuser, $cookie)
                = get_template_and_user({template_name => "search.marc/result.tmpl",
                                query => $query,
                                type => $type,
                                authnotrequired => 0,
                                flagsrequired => {borrowers => 1},
-#                              flagsrequired => {catalogue => 1},
+                               flagsrequired => {catalogue => 1},
                                debug => 1,
                                });
-       $template->param(result => \@results);
 
-} else {
+       # multi page display gestion
+       my $displaynext=0;
+       my $displayprev=$startfrom;
+       if(($total - (($startfrom+1)*($resultsperpage))) > 0 ) {
+               $displaynext = 1;
+       }
+
+       my @field_data = ();
+
+       for(my $i = 0 ; $i <= $#marclist ; $i++) {
+               push @field_data, { term => "marclist", val=>$marclist[$i] };
+               push @field_data, { term => "and_or", val=>$and_or[$i] };
+               push @field_data, { term => "excluding", val=>$excluding[$i] };
+               push @field_data, { term => "operator", val=>$operator[$i] };
+               push @field_data, { term => "value", val=>$value[$i] };
+       }
+
+       my @numbers = ();
+
+       if ($total>$resultsperpage) {
+               for (my $i=1; $i<$total/$resultsperpage+1; $i++) {
+                       if ($i<16) {
+                       my $highlight=0;
+                       ($startfrom==($i-1)) && ($highlight=1);
+                       push @numbers, { number => $i,
+                                       highlight => $highlight ,
+                                       searchdata=> \@field_data,
+                                       startfrom => ($i-1)};
+                       }
+       }
+       }
+
+       my $from = $startfrom*$resultsperpage+1;
+       my $to;
+
+       if($total < (($startfrom+1)*$resultsperpage))
+       {
+               $to = $total;
+       } else {
+               $to = (($startfrom+1)*$resultsperpage);
+       }
+       my $defaultview = 'BiblioDefaultView'.C4::Context->preference('IntranetBiblioDefaultView');
+       $template->param(result => $results,
+                                                       startfrom=> $startfrom,
+                                                       displaynext=> $displaynext,
+                                                       displayprev=> $displayprev,
+                                                       resultsperpage => $resultsperpage,
+                                                       startfromnext => $startfrom+1,
+                                                       startfromprev => $startfrom-1,
+                                                       searchdata=>\@field_data,
+                                                       total=>$total,
+                                                       from=>$from,
+                                                       to=>$to,
+                                                       numbers=>\@numbers,
+                                                       searchdesc=> $searchdesc,
+                                                       desc_asc=>$desc_or_asc,
+                                                       orderby=>$orderby,
+                                                       MARC_ON => C4::Context->preference("marc"),
+                                                       $defaultview => 1,
+                                                       );
+
+} elsif ($op eq "AddStatement") {
        ($template, $loggedinuser, $cookie)
                = get_template_and_user({template_name => "search.marc/search.tmpl",
                                query => $query,
@@ -78,52 +239,149 @@ if ($op eq "do_search") {
                                flagsrequired => {catalogue => 1},
                                debug => 1,
                                });
-       #$template->param(loggedinuser => $loggedinuser);
-       my $tagslib;
-       if ($type eq "opac") {
-               $tagslib = &MARCgettagslib($dbh,1);
-       } else {
-               $tagslib = &MARCgettagslib($dbh,1);
-       }
-       my @marcarray;
-       push @marcarray,"";
-       my $widest_menu_item_width = 0;
-       for (my $pass = 1; $pass <= 2; $pass += 1) {
-               for (my $tabloop = 0; $tabloop<=9;$tabloop++) {
-                       my $separator_inserted_p = 0; # FIXME... should not use!!
-                       foreach my $tag (sort(keys (%{$tagslib}))) {
-                               foreach my $subfield (sort(keys %{$tagslib->{$tag}})) {
-                                       next if subfield_is_koha_internal_p($subfield);
-                                       next unless ($tagslib->{$tag}->{$subfield}->{tab} eq $tabloop);
-                                       my $menu_item = "$tag$subfield - $tagslib->{$tag}->{$subfield}->{lib}";
-                                       if ($pass == 1) {
-                                               $widest_menu_item_width = length $menu_item
-                                                               if $widest_menu_item_width < length $menu_item;
-                                       } else {
-                                               if (!$separator_inserted_p) {
-                                                       my $w = int(($widest_menu_item_width - 3 + 0.5)/2);
-                                                       my $s = ('-' x ($w * 4/5));
-                                                       push @marcarray,  "$s $tabloop $s";
-                                                       $separator_inserted_p = 1;
-                                               }
-                                               push @marcarray, $menu_item;
-                                       }
-                               }
-                       }
-               }
+
+       # Gets the entered information
+       my @marcfields = $query->param('marclist');
+       my @and_or = $query->param('and_or');
+       my @excluding = $query->param('excluding');
+       my @operator = $query->param('operator');
+       my @value = $query->param('value');
+
+       my @statements = ();
+
+       # List of the marc tags to display
+       my $marcarray = create_marclist();
+
+       my $nbstatements = $query->param('nbstatements');
+       $nbstatements = 1 if(!defined $nbstatements);
+
+       for(my $i = 0 ; $i < $nbstatements ; $i++)
+       {
+               my %fields = ();
+
+               # Recreates the old scrolling lists with the previously selected values
+               my $marclist = create_scrolling_list({name=>"marclist",
+                                       values=> $marcarray,
+                                       size=> 1,
+                                       default=>$marcfields[$i],
+                                       onChange => "sql_update()"}
+                                       );
+
+               $fields{'marclist'} = $marclist;
+               $fields{'first'} = 1 if($i == 0);
+
+               # Restores the and/or parameters (no need to test the 'and' for activation because it's the default value)
+               $fields{'or'} = 1 if($and_or[$i] eq "or");
+
+               #Restores the "not" parameters
+               $fields{'not'} = 1 if($excluding[$i]);
+
+               #Restores the operators (most common operators first);
+               if($operator[$i] eq "=") { $fields{'eq'} = 1; }
+               elsif($operator[$i] eq "contains") { $fields{'contains'} = 1; }
+               elsif($operator[$i] eq "start") { $fields{'start'} = 1; }
+               elsif($operator[$i] eq ">") { $fields{'gt'} = 1; }      #greater than
+               elsif($operator[$i] eq ">=") { $fields{'ge'} = 1; } #greater or equal
+               elsif($operator[$i] eq "<") { $fields{'lt'} = 1; } #lower than
+               elsif($operator[$i] eq "<=") { $fields{'le'} = 1; } #lower or equal
+
+               #Restores the value
+               $fields{'value'} = $value[$i];
+
+               push @statements, \%fields;
        }
+       $nbstatements++;
+
+       # The new scrolling list
+       my $marclist = create_scrolling_list({name=>"marclist",
+                               values=> $marcarray,
+                               size=>1,
+                               onChange => "sql_update()"});
+       push @statements, {"marclist" => $marclist };
+
+       $template->param("statements" => \@statements,
+                                               "nbstatements" => $nbstatements);
+
+}
+else {
+       ($template, $loggedinuser, $cookie)
+               = get_template_and_user({template_name => "search.marc/search.tmpl",
+                               query => $query,
+                               type => $type,
+                               authnotrequired => 0,
+                               flagsrequired => {catalogue => 1},
+                               debug => 1,
+                               });
+       #$template->param(loggedinuser => $loggedinuser);
+
+       my $marcarray = create_marclist();
+
        my $marclist = CGI::scrolling_list(-name=>"marclist",
-                                       -values=> \@marcarray,
+                                       -values=> $marcarray,
                                        -size=>1,
+                                       -tabindex=>'',
                                        -multiple=>0,
                                        -onChange => "sql_update()",
                                        );
-       $template->param("marclist" => $marclist);
+
+       my @statements = ();
+
+       # Considering initial search with 3 criterias
+       push @statements, { "marclist" => $marclist, "first" => 1 };
+       push @statements, { "marclist" => $marclist, "first" => 0 };
+       push @statements, { "marclist" => $marclist, "first" => 0 };
+       my $sth=$dbh->prepare("Select itemtype,description from itemtypes order by description");
+       $sth->execute;
+       my  @itemtype;
+       my %itemtypes;
+       push @itemtype, "";
+       $itemtypes{''} = "";
+       while (my ($value,$lib) = $sth->fetchrow_array) {
+               push @itemtype, $value;
+               $itemtypes{$value}=$lib;
+       }
+
+       my $CGIitemtype=CGI::scrolling_list( -name     => 'value',
+                               -id => 'itemtype',
+                               -values   => \@itemtype,
+                               -labels   => \%itemtypes,
+                               -size     => 1,
+                               -tabindex=>'',
+                               -multiple => 0 );
+       $sth->finish;
+
+       my @branches;
+       my @select_branch;
+       my %select_branches;
+       my $branches=getbranches();
+       my @branchloop;
+       foreach my $thisbranch (sort keys %$branches) {
+#              my $selected = 1 if $thisbranch eq $branch;
+               my %row =(value => $thisbranch,
+#                                      selected => $selected,
+                                       branchname => $branches->{$thisbranch}->{'branchname'},
+                               );
+               push @branchloop, \%row;
+       }
+       $sth->finish;
+
+
+       $template->param('Disable_Dictionary'=>C4::Context->preference("Disable_Dictionary")) if (C4::Context->preference("Disable_Dictionary"));
+       $template->param("statements" => \@statements,
+                       "nbstatements" => 3,
+                       CGIitemtype => $CGIitemtype,
+                       branchloop => \@branchloop,
+                       );
 }
+
+
 # Print the page
+$template->param(intranetcolorstylesheet => C4::Context->preference("intranetcolorstylesheet"),
+               intranetstylesheet => C4::Context->preference("intranetstylesheet"),
+               IntranetNav => C4::Context->preference("IntranetNav"),
+               );
 output_html_with_http_headers $query, $cookie, $template->output;
 
-
 # Local Variables:
 # tab-width: 4
 # End: