Bug 7167: Followup: FIX conflicts with Bug 5347
[koha_gimpoz] / C4 / Search.pm
index fdb3479..04ce112 100644 (file)
@@ -31,8 +31,10 @@ use C4::Branch;
 use C4::Reserves;    # CheckReserves
 use C4::Debug;
 use C4::Items;
+use C4::Charset;
 use YAML;
 use URI::Escape;
+use Business::ISBN;
 
 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $DEBUG);
 
@@ -68,9 +70,8 @@ This module provides searching functions for Koha's bibliographic databases
   &NZgetRecords
   &AddSearchHistory
   &GetDistinctValues
-  &BiblioAddAuthorities
+  &enabled_staff_search_views
 );
-#FIXME: i had to add BiblioAddAuthorities here because in Biblios.pm it caused circular dependencies (C4::Search uses C4::Biblio, and BiblioAddAuthorities uses SimpleSearch from C4::Search)
 
 # make all your functions, whether exported or not;
 
@@ -1413,11 +1414,16 @@ 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 ( $search_context, $searchdesc, $hits, $results_per_page, $offset, $scan, @marcresults, $hidelostitems ) = @_;
+    my ( $search_context, $searchdesc, $hits, $results_per_page, $offset, $scan, $marcresults ) = @_;
     my $dbh = C4::Context->dbh;
     my @newresults;
 
-    $search_context = 'opac' unless $search_context eq 'opac' or $search_context eq 'intranet';
+    $search_context = 'opac' if !$search_context || $search_context ne 'intranet';
+    my ($is_opac, $hidelostitems);
+    if ($search_context eq 'opac') {
+        $hidelostitems = C4::Context->preference('hidelostitems');
+        $is_opac       = 1;
+    }
 
     #Build branchnames hash
     #find branchname
@@ -1480,12 +1486,11 @@ sub searchResults {
        my $marcflavour = C4::Context->preference("marcflavour");
     # We get the biblionumber position in MARC
     my ($bibliotag,$bibliosubf)=GetMarcFromKohaField('biblio.biblionumber','');
-    my $fw;
 
     # 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] );
-        $fw = $scan
+        my $marcrecord = MARC::File::USMARC::decode( $marcresults->[$i] );
+        my $fw = $scan
              ? undef
              : $bibliotag < 10
                ? GetFrameworkCode($marcrecord->field($bibliotag)->data)
@@ -1603,18 +1608,18 @@ sub searchResults {
         my $other_count           = 0;
         my $wthdrawn_count        = 0;
         my $itemlost_count        = 0;
+        my $hideatopac_count      = 0;
         my $itembinding_count     = 0;
         my $itemdamaged_count     = 0;
         my $item_in_transit_count = 0;
         my $can_place_holds       = 0;
-       my $item_onhold_count     = 0;
+        my $item_onhold_count     = 0;
         my $items_count           = scalar(@fields);
-        my $maxitems =
-          ( C4::Context->preference('maxItemsinSearchResults') )
-          ? C4::Context->preference('maxItemsinSearchResults') - 1
-          : 1;
+        my $maxitems_pref = C4::Context->preference('maxItemsinSearchResults');
+        my $maxitems = $maxitems_pref ? $maxitems_pref - 1 : 1;
 
         # loop through every item
+             my @hiddenitems;
         foreach my $field (@fields) {
             my $item;
 
@@ -1624,9 +1629,11 @@ sub searchResults {
             }
 
                # Hidden items
-               my @items = ($item);
-               my (@hiddenitems) = GetHiddenItemnumbers(@items);
-           $item->{'hideatopac'} = 1 if (@hiddenitems); 
+            if ($is_opac) {
+                   my @hi = GetHiddenItemnumbers($item);
+               $item->{'hideatopac'} = @hi;
+              push @hiddenitems, @hi;
+            }
 
             my $hbranch     = C4::Context->preference('HomeOrHoldingBranch') eq 'homebranch' ? 'homebranch'    : 'holdingbranch';
             my $otherbranch = C4::Context->preference('HomeOrHoldingBranch') eq 'homebranch' ? 'holdingbranch' : 'homebranch';
@@ -1673,7 +1680,7 @@ sub searchResults {
                 my ($transfertfrom, $transfertto);
 
                 # is item on the reserve shelf?
-               my $reservestatus = 0;
+               my $reservestatus = '';
                my $reserveitem;
 
                 unless ($item->{wthdrawn}
@@ -1695,7 +1702,7 @@ sub searchResults {
                     #        should map transit status to record indexed in Zebra.
                     #
                     ($transfertwhen, $transfertfrom, $transfertto) = C4::Circulation::GetTransfers($item->{itemnumber});
-                   ($reservestatus, $reserveitem) = C4::Reserves::CheckReserves($item->{itemnumber});
+                   ($reservestatus, $reserveitem, undef) = C4::Reserves::CheckReserves($item->{itemnumber});
                 }
 
                 # item is withdrawn, lost, damaged, not for loan, reserved or in transit
@@ -1710,10 +1717,11 @@ sub searchResults {
                     $wthdrawn_count++        if $item->{wthdrawn};
                     $itemlost_count++        if $item->{itemlost};
                     $itemdamaged_count++     if $item->{damaged};
+                    $hideatopac_count++      if $item->{hideatopac};
                     $item_in_transit_count++ if $transfertwhen ne '';
                    $item_onhold_count++     if $reservestatus eq 'Waiting';
                     $item->{status} = $item->{wthdrawn} . "-" . $item->{itemlost} . "-" . $item->{damaged} . "-" . $item->{notforloan};
-                    
+
                     # can place hold on item ?
                     if ((!$item->{damaged} || C4::Context->preference('AllowHoldsOnDamagedItems'))
                       && !$item->{itemlost}
@@ -1748,11 +1756,11 @@ sub searchResults {
                 }
             }
         }    # notforloan, item level and biblioitem level
+       if ($items_count > 0) {
+        next if $is_opac       && $hideatopac_count >= $items_count;
+        next if $hidelostitems && $itemlost_count   >= $items_count;
+       }
         my ( $availableitemscount, $onloanitemscount, $otheritemscount );
-        $maxitems =
-          ( C4::Context->preference('maxItemsinSearchResults') )
-          ? C4::Context->preference('maxItemsinSearchResults') - 1
-          : 1;
         for my $key ( sort keys %$onloan_items ) {
             (++$onloanitemscount > $maxitems) and last;
             push @onloan_items_loop, $onloan_items->{$key};
@@ -1770,13 +1778,11 @@ sub searchResults {
        use C4::Charset;
        SetUTF8Flag($marcrecord);
        $debug && warn $marcrecord->as_formatted;
-        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
-
+       my $interface = $search_context eq 'opac' ? 'OPAC' : '';
+       if (!$scan && C4::Context->preference($interface . "XSLTResultsDisplay")) {
+            $oldbiblio->{XSLTResultsRecord} = XSLTParse4Display($oldbiblio->{biblionumber}, $marcrecord, 'Results',
+                                                                $search_context, 1, \@hiddenitems);
+           # the last parameter tells Koha to clean up the problematic ampersand entities that Zebra outputs
         }
 
         # if biblio level itypes are used and itemtype is notforloan, it can't be reserved either
@@ -1803,8 +1809,8 @@ sub searchResults {
         $oldbiblio->{intransitcount}       = $item_in_transit_count;
         $oldbiblio->{onholdcount}          = $item_onhold_count;
         $oldbiblio->{orderedcount}         = $ordered_count;
-        $oldbiblio->{isbn} =~
-          s/-//g;    # deleting - in isbn to enable amazon content
+        # deleting - in isbn to enable amazon content
+        $oldbiblio->{isbn} =~ s/-//g;
 
         if (C4::Context->preference("AlternateHoldingsField") && $items_count == 0) {
             my $fieldspec = C4::Context->preference("AlternateHoldingsField");
@@ -1834,10 +1840,7 @@ sub searchResults {
             $oldbiblio->{'alternateholdings_count'} = $alternateholdingscount;
         }
 
-        push( @newresults, $oldbiblio )
-            if(not $hidelostitems
-               or (($items_count > $itemlost_count )
-                    && $hidelostitems));
+        push( @newresults, $oldbiblio );
     }
 
     return @newresults;
@@ -2628,7 +2631,15 @@ $template->param ( MYLOOP => C4::Search::z3950_search_args($searchscalar) )
 
 sub z3950_search_args {
     my $bibrec = shift;
-    $bibrec = { title => $bibrec } if !ref $bibrec;
+    my $isbn = Business::ISBN->new($bibrec);
+
+    if (defined $isbn && $isbn->is_valid)
+    {
+        $bibrec = { isbn => $bibrec } if !ref $bibrec;
+    }
+    else {
+        $bibrec = { title => $bibrec } if !ref $bibrec;
+    }
     my $array = [];
     for my $field (qw/ lccn isbn issn title author dewey subject /)
     {
@@ -2638,105 +2649,6 @@ sub z3950_search_args {
     return $array;
 }
 
-=head2 BiblioAddAuthorities
-
-( $countlinked, $countcreated ) = BiblioAddAuthorities($record, $frameworkcode);
-
-this function finds the authorities linked to the biblio
-    * search in the authority DB for the same authid (in $9 of the biblio)
-    * search in the authority DB for the same 001 (in $3 of the biblio in UNIMARC)
-    * search in the authority DB for the same values (exactly) (in all subfields of the biblio)
-OR adds a new authority record
-
-=over 2
-
-=item C<input arg:>
-
-    * $record is the MARC record in question (marc blob)
-    * $frameworkcode is the bibliographic framework to use (if it is "" it uses the default framework)
-
-=item C<Output arg:>
-
-    * $countlinked is the number of authorities records that are linked to this authority
-    * $countcreated
-
-=item C<BUGS>
-    * I had to add this to Search.pm (instead of the logical Biblio.pm) because of a circular dependency (this sub uses SimpleSearch, and Search.pm uses Biblio.pm)
-
-=back
-
-=cut
-
-
-sub BiblioAddAuthorities{
-  my ( $record, $frameworkcode ) = @_;
-  my $dbh=C4::Context->dbh;
-  my $query=$dbh->prepare(qq|
-SELECT authtypecode,tagfield
-FROM marc_subfield_structure
-WHERE frameworkcode=?
-AND (authtypecode IS NOT NULL AND authtypecode<>\"\")|);
-# SELECT authtypecode,tagfield
-# FROM marc_subfield_structure
-# WHERE frameworkcode=?
-# AND (authtypecode IS NOT NULL OR authtypecode<>\"\")|);
-  $query->execute($frameworkcode);
-  my ($countcreated,$countlinked);
-  while (my $data=$query->fetchrow_hashref){
-    foreach my $field ($record->field($data->{tagfield})){
-      next if ($field->subfield('3')||$field->subfield('9'));
-      # No authorities id in the tag.
-      # Search if there is any authorities to link to.
-      my $query='at='.$data->{authtypecode}.' ';
-      map {$query.= ' and he,ext="'.$_->[1].'"' if ($_->[0]=~/[A-z]/)}  $field->subfields();
-      my ($error, $results, $total_hits)=SimpleSearch( $query, undef, undef, [ "authorityserver" ] );
-    # there is only 1 result
-          if ( $error ) {
-        warn "BIBLIOADDSAUTHORITIES: $error";
-            return (0,0) ;
-          }
-      if ( @{$results} == 1 ) {
-        my $marcrecord = MARC::File::USMARC::decode($results->[0]);
-        $field->add_subfields('9'=>$marcrecord->field('001')->data);
-        $countlinked++;
-      } elsif ( @{$results} > 1 ) {
-   #More than One result
-   #This can comes out of a lack of a subfield.
-#         my $marcrecord = MARC::File::USMARC::decode($results->[0]);
-#         $record->field($data->{tagfield})->add_subfields('9'=>$marcrecord->field('001')->data);
-  $countlinked++;
-      } else {
-  #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});
-         next unless $authtypedata;
-         my $marcrecordauth=MARC::Record->new();
-         my $authfield=MARC::Field->new($authtypedata->{auth_tag_to_report},'','',"a"=>"".$field->subfield('a'));
-         map { $authfield->add_subfields($_->[0]=>$_->[1]) if ($_->[0]=~/[A-z]/ && $_->[0] ne "a" )}  $field->subfields();
-         $marcrecordauth->insert_fields_ordered($authfield);
-
-         # bug 2317: ensure new authority knows it's using UTF-8; currently
-         # only need to do this for MARC21, as MARC::Record->as_xml_record() handles
-         # automatically for UNIMARC (by not transcoding)
-         # FIXME: AddAuthority() instead should simply explicitly require that the MARC::Record
-         # use UTF-8, but as of 2008-08-05, did not want to introduce that kind
-         # of change to a core API just before the 3.0 release.
-         if (C4::Context->preference('marcflavour') eq 'MARC21') {
-            SetMarcUnicodeFlag($marcrecordauth, 'MARC21');
-         }
-
-#          warn "AUTH RECORD ADDED : ".$marcrecordauth->as_formatted;
-
-         my $authid=AddAuthority($marcrecordauth,'',$data->{authtypecode});
-         $countcreated++;
-         $field->add_subfields('9'=>$authid);
-      }
-    }
-  }
-  return ($countlinked,$countcreated);
-}
-
 =head2 GetDistinctValues($field);
 
 C<$field> is a reference to the fields array