View | Details | Raw Unified | Return to bug 11909
Collapse All | Expand All

(-)a/C4/Items.pm (+84 lines)
Lines 75-80 BEGIN { Link Here
75
        GetItemnumberFromBarcode
75
        GetItemnumberFromBarcode
76
        GetBarcodeFromItemnumber
76
        GetBarcodeFromItemnumber
77
        GetHiddenItemnumbers
77
        GetHiddenItemnumbers
78
        GetHiddenItemnumbersByItemnumbers
79
        isHidingOverridden
78
        DelItemCheck
80
        DelItemCheck
79
    MoveItemFromBiblio
81
    MoveItemFromBiblio
80
    GetLatestAcquisitions
82
    GetLatestAcquisitions
Lines 1714-1719 sub GetHiddenItemnumbers { Link Here
1714
    return @resultitems;
1716
    return @resultitems;
1715
}
1717
}
1716
1718
1719
=head2 GetHiddenItemnumbersByItemnumbers
1720
1721
    my @hiddenitemnumbers = GetHiddenItemnumbersByItemnumbers(@itemnumbers);
1722
1723
Given a list of itemnumbers it checks which should be hidden from the OPAC given
1724
the current configuration. Returns a list of itemnumbers that should be hidden.
1725
1726
=cut
1727
1728
sub GetHiddenItemnumbersByItemnumbers {
1729
    my (@itemnumbers) = @_;
1730
    my @resultitems = ();
1731
    my $hidingrules = GetHidingRules();
1732
    if (! $hidingrules ) {
1733
        return ();
1734
    }
1735
    my $dbh = C4::Context->dbh;
1736
1737
    # For each item
1738
    foreach my $itemnumber (@itemnumbers) {
1739
1740
        # We check each rule
1741
        foreach my $field (keys %$hidingrules) {
1742
            my $query = "SELECT $field from items where itemnumber = ?";
1743
            my $val = $dbh->selectrow_array($query, undef, $itemnumber);
1744
            $val = '' unless defined $val;
1745
1746
            # If the results matches the values in the yaml file
1747
            if (any { $val eq $_ } @{$hidingrules->{$field}}) {
1748
1749
                # We add the itemnumber to the list
1750
                push @resultitems, $itemnumber;
1751
1752
                # If at least one rule matched for an item, no need to test the others
1753
                last;
1754
            }
1755
        }
1756
    }
1757
    return @resultitems;
1758
}
1759
1760
=head2 GetHiddingRules
1761
1762
    returns hiding rules keyed by rule name (i.e. homebranch)
1763
1764
=cut
1765
1766
sub GetHidingRules {
1767
    my $hidingrules;
1768
    my $yaml = C4::Context->preference('OpacHiddenItems');
1769
    return () if (! $yaml =~ /\S/ );
1770
    $yaml = "$yaml\n\n"; # YAML is anal on ending \n. Surplus does not hurt
1771
    eval {
1772
        $hidingrules = YAML::Load($yaml);
1773
    };  
1774
    if ($@) {
1775
        warn "Unable to parse OpacHiddenItems syspref : $@";
1776
        return ();
1777
    }
1778
    return $hidingrules;
1779
}
1780
1781
1782
=head2 isHidingOverridden
1783
1784
    returns 1 (true) if the OpacHiddenItems is overridden.
1785
1786
In the context of a particular search, a patron might be configured
1787
to SEEALL items.
1788
1789
=cut
1790
1791
sub isHidingOverridden {
1792
    my $override = 0;  # false
1793
1794
=pod
1795
#TODO: add patron SEEL and patron category override logic here
1796
    return @resultitems;
1797
=cut
1798
    return $override;
1799
}
1800
1717
=head3 get_item_authorised_values
1801
=head3 get_item_authorised_values
1718
1802
1719
find the types and values for all authorised values assigned to this item.
1803
find the types and values for all authorised values assigned to this item.
(-)a/C4/Search.pm (-18 / +68 lines)
Lines 31-36 use C4::Branch; Link Here
31
use C4::Reserves;    # GetReserveStatus
31
use C4::Reserves;    # GetReserveStatus
32
use C4::Debug;
32
use C4::Debug;
33
use C4::Charset;
33
use C4::Charset;
34
use List::MoreUtils qw/any/;
34
use YAML;
35
use YAML;
35
use URI::Escape;
36
use URI::Escape;
36
use Business::ISBN;
37
use Business::ISBN;
Lines 67-72 This module provides searching functions for Koha's bibliographic databases Link Here
67
  &SimpleSearch
68
  &SimpleSearch
68
  &searchResults
69
  &searchResults
69
  &getRecords
70
  &getRecords
71
  &getItemSubfieldsToSearch
70
  &buildQuery
72
  &buildQuery
71
  &AddSearchHistory
73
  &AddSearchHistory
72
  &GetDistinctValues
74
  &GetDistinctValues
Lines 340-345 sub getRecords { Link Here
340
    my @results;
342
    my @results;
341
    my $results_hashref = ();
343
    my $results_hashref = ();
342
344
345
    my $opachiddenitems = C4::Context->preference('OpacHiddenItems');
346
    my $hidingrules = C4::Items::GetHidingRules(); 
347
    my $ishidingoverridden = C4::Items::isHidingOverridden();
348
343
    # Initialize variables for the faceted results objects
349
    # Initialize variables for the faceted results objects
344
    my $facets_counter = ();
350
    my $facets_counter = ();
345
    my $facets_info    = ();
351
    my $facets_info    = ();
Lines 506-511 sub getRecords { Link Here
506
                    my $jmax =
512
                    my $jmax =
507
                      $size > $facets_maxrecs ? $facets_maxrecs : $size;
513
                      $size > $facets_maxrecs ? $facets_maxrecs : $size;
508
                    for my $facet (@$facets) {
514
                    for my $facet (@$facets) {
515
#warn "XXXfacet: ".$facet->{idx}."  ".$facet->{label};;
509
                        for ( my $j = 0 ; $j < $jmax ; $j++ ) {
516
                        for ( my $j = 0 ; $j < $jmax ; $j++ ) {
510
517
511
                            my $marc_record = new_record_from_zebra (
518
                            my $marc_record = new_record_from_zebra (
Lines 519-528 sub getRecords { Link Here
519
                                next;
526
                                next;
520
                            }
527
                            }
521
528
529
                            if ($opac) {
530
                                if ($opachiddenitems && !$ishidingoverridden) { 
531
# TODO: get hidden tag mapping
532
                #my ($bibliotag,$bibliosubf)=GetMarcFromKohaField('biblio.hidden','');
533
                my ($bibliotag,$bibliosubf)=('999','h');
534
                                        my $bibliohidden = $marc_record->field($bibliotag)->subfield($bibliosubf);
535
#warn "$i $j bibliohidden:$bibliohidden";
536
                                        if ( $bibliohidden && $bibliohidden == 1 ) {
537
                                            next; # this biblio is not part of facets
538
                                        }
539
540
                                }
541
                            }
542
522
                            my @used_datas = ();
543
                            my @used_datas = ();
523
544
524
                            foreach my $tag ( @{ $facet->{tags} } ) {
545
                            foreach my $tag ( @{ $facet->{tags} } ) {
525
526
                                # avoid first line
546
                                # avoid first line
527
                                my $tag_num = substr( $tag, 0, 3 );
547
                                my $tag_num = substr( $tag, 0, 3 );
528
                                my $subfield_letters = substr( $tag, 3 );
548
                                my $subfield_letters = substr( $tag, 3 );
Lines 532-537 sub getRecords { Link Here
532
                                my @fields = $marc_record->field($tag_num);
552
                                my @fields = $marc_record->field($tag_num);
533
                                foreach my $field (@fields) {
553
                                foreach my $field (@fields) {
534
                                    my $data = $field->as_string( $subfield_letters, $facet->{sep} );
554
                                    my $data = $field->as_string( $subfield_letters, $facet->{sep} );
555
#warn "tagnum:$tag_num tag: $tag data: $data";
556
# ITEMLEVEL handling:
557
#NEED TO LOOK AT ITEM IN DB and don't count YAML MATCHING fields   tag subfield -> mapping  holdingbranch
558
# these fields are from marc_record.  might need raw as in rebuild_zebra.
559
560
#IDEA:
561
#TOD GET RID OF hidden library facets  do these: (if not patron SEEALL, and patronCategory, and OpacHiddenItems)
562
                                    # hide the facet if it's OpacHiddenItems rule hides its items.
563
                                    # (because we don't hide biblios if any non-hidden items exists)
564
                                    # Could be done for other facets such as authors, locations, itemtypes, series, topics
565
                                    # TODO: possibly discern which to hide based on DisplayLibraryFacets syspref from bug 11334 if it gets pushed
566
                                    # handle homebranch as well if needed
567
                                    if ($opachiddenitems && !$ishidingoverridden) { 
568
                                        if (any { $data eq $_ } @{$hidingrules->{'holdingbranch'}}) { # see getFacets branch tag995b or 952b
569
                                        next; # skip hidden
570
                                        }
571
                                    }
535
572
536
                                    unless ( $data ~~ @used_datas ) {
573
                                    unless ( $data ~~ @used_datas ) {
537
                                        push @used_datas, $data;
574
                                        push @used_datas, $data;
Lines 591-597 sub getRecords { Link Here
591
                                      $facet_max_length;
628
                                      $facet_max_length;
592
629
593
                            # if it's a branch, label by the name, not the code,
630
                            # if it's a branch, label by the name, not the code,
594
                                if ( $link_value =~ /branch/ ) {
631
                                if ( $link_value =~ /branch/ ) { # see getFacets tag for branch (holdingbranch)
595
                                    if (   defined $branches
632
                                    if (   defined $branches
596
                                        && ref($branches) eq "HASH"
633
                                        && ref($branches) eq "HASH"
597
                                        && defined $branches->{$one_facet}
634
                                        && defined $branches->{$one_facet}
Lines 606-611 sub getRecords { Link Here
606
                                        $facet_label_value = "*";
643
                                        $facet_label_value = "*";
607
                                    }
644
                                    }
608
                                }
645
                                }
646
#warn "onefacet: $link_value $number_of_facets $one_facet ^ $facet_link_value ? $facet_label_value =$expanded_facet:$facets_info->{$link_value}->{'expanded'}";
609
647
610
                          # if it's a itemtype, label by the name, not the code,
648
                          # if it's a itemtype, label by the name, not the code,
611
                                if ( $link_value =~ /itype/ ) {
649
                                if ( $link_value =~ /itype/ ) {
Lines 1682-1697 sub searchResults { Link Here
1682
    my ($itemtag, undef) = &GetMarcFromKohaField( "items.itemnumber", "" );
1720
    my ($itemtag, undef) = &GetMarcFromKohaField( "items.itemnumber", "" );
1683
1721
1684
    ## find column names of items related to MARC
1722
    ## find column names of items related to MARC
1685
    my $sth2 = $dbh->prepare("SHOW COLUMNS FROM items");
1723
    my $subfieldstosearch_hashref = getItemSubfieldsToSearch();
1686
    $sth2->execute;
1724
    my %subfieldstosearch = %$subfieldstosearch_hashref;
1687
    my %subfieldstosearch;
1688
    while ( ( my $column ) = $sth2->fetchrow ) {
1689
        my ( $tagfield, $tagsubfield ) =
1690
          &GetMarcFromKohaField( "items." . $column, "" );
1691
        if ( defined $tagsubfield ) {
1692
            $subfieldstosearch{$column} = $tagsubfield;
1693
        }
1694
    }
1695
1725
1696
    # handle which records to actually retrieve
1726
    # handle which records to actually retrieve
1697
    my $times;
1727
    my $times;
Lines 1844-1850 sub searchResults { Link Here
1844
        my $other_count           = 0;
1874
        my $other_count           = 0;
1845
        my $withdrawn_count        = 0;
1875
        my $withdrawn_count        = 0;
1846
        my $itemlost_count        = 0;
1876
        my $itemlost_count        = 0;
1847
        my $hideatopac_count      = 0;
1848
        my $itembinding_count     = 0;
1877
        my $itembinding_count     = 0;
1849
        my $itemdamaged_count     = 0;
1878
        my $itemdamaged_count     = 0;
1850
        my $item_in_transit_count = 0;
1879
        my $item_in_transit_count = 0;
Lines 1854-1859 sub searchResults { Link Here
1854
        my $maxitems_pref = C4::Context->preference('maxItemsinSearchResults');
1883
        my $maxitems_pref = C4::Context->preference('maxItemsinSearchResults');
1855
        my $maxitems = $maxitems_pref ? $maxitems_pref - 1 : 1;
1884
        my $maxitems = $maxitems_pref ? $maxitems_pref - 1 : 1;
1856
        my @hiddenitems; # hidden itemnumbers based on OpacHiddenItems syspref
1885
        my @hiddenitems; # hidden itemnumbers based on OpacHiddenItems syspref
1886
        my @itemnumbers; # itemnumbers for this biblio
1857
1887
1858
        # loop through every item
1888
        # loop through every item
1859
        foreach my $field (@fields) {
1889
        foreach my $field (@fields) {
Lines 1864-1882 sub searchResults { Link Here
1864
                $item->{$code} = $field->subfield( $subfieldstosearch{$code} );
1894
                $item->{$code} = $field->subfield( $subfieldstosearch{$code} );
1865
            }
1895
            }
1866
            $item->{description} = $itemtypes{ $item->{itype} }{description};
1896
            $item->{description} = $itemtypes{ $item->{itype} }{description};
1897
            push @itemnumbers, $item->{itemnumber};
1867
1898
1868
	        # OPAC hidden items
1899
	    # OPAC hidden items
1869
            if ($is_opac) {
1900
            if ($is_opac) {
1870
                # hidden because lost
1901
                # hidden because lost
1871
                if ($hidelostitems && $item->{itemlost}) {
1902
                if ($hidelostitems && $item->{itemlost}) {
1872
                    $hideatopac_count++;
1873
                    next;
1903
                    next;
1874
                }
1904
                }
1875
                # hidden based on OpacHiddenItems syspref
1905
                # hidden based on OpacHiddenItems syspref
1876
                my @hi = C4::Items::GetHiddenItemnumbers($item);
1906
                my @itemnum = ($item->{itemnumber});
1907
                my @hi = C4::Items::GetHiddenItemnumbersByItemnumbers(@itemnum);
1877
                if (scalar @hi) {
1908
                if (scalar @hi) {
1878
                    push @hiddenitems, @hi;
1909
                    push @hiddenitems, @hi;
1879
                    $hideatopac_count++;
1880
                    next;
1910
                    next;
1881
                }
1911
                }
1882
            }
1912
            }
Lines 2007-2013 sub searchResults { Link Here
2007
        }    # notforloan, item level and biblioitem level
2037
        }    # notforloan, item level and biblioitem level
2008
2038
2009
        # if all items are hidden, do not show the record
2039
        # if all items are hidden, do not show the record
2010
        if ($items_count > 0 && $hideatopac_count == $items_count) {
2040
        if ( scalar(@itemnumbers) > 0 && scalar(@hiddenitems) == scalar(@itemnumbers) ) {
2041
            # TODO: patron category override
2011
            next;
2042
            next;
2012
        }
2043
        }
2013
2044
Lines 2094-2099 sub searchResults { Link Here
2094
    return @newresults;
2125
    return @newresults;
2095
}
2126
}
2096
2127
2128
=head2 getItemSubfieldsToSearch
2129
    Search for the item table related subfield tags
2130
=cut
2131
sub getItemSubfieldsToSearch {
2132
    my $dbh = C4::Context->dbh;
2133
    ## find column names of items related to MARC
2134
    my $sth2 = $dbh->prepare("SHOW COLUMNS FROM items");
2135
    $sth2->execute;
2136
    my %subfieldstosearch;
2137
    while ( ( my $column ) = $sth2->fetchrow ) {
2138
        my ( $tagfield, $tagsubfield ) =
2139
          &GetMarcFromKohaField( "items." . $column, "" );
2140
        if ( defined $tagsubfield ) {
2141
            $subfieldstosearch{$column} = $tagsubfield;
2142
        }
2143
    }
2144
    return \%subfieldstosearch;
2145
}
2146
2097
=head2 SearchAcquisitions
2147
=head2 SearchAcquisitions
2098
    Search for acquisitions
2148
    Search for acquisitions
2099
=cut
2149
=cut
(-)a/misc/migration_tools/rebuild_zebra.pl (-3 / +86 lines)
Lines 638-646 sub get_corrected_marc_record { Link Here
638
        fix_leader($marc);
638
        fix_leader($marc);
639
        if ($record_type eq 'authority') {
639
        if ($record_type eq 'authority') {
640
            fix_authority_id($marc, $record_number);
640
            fix_authority_id($marc, $record_number);
641
        } elsif ($record_type eq 'biblio' && C4::Context->preference('IncludeSeeFromInSearches')) {
641
        } elsif ($record_type eq 'biblio') {
642
            my $normalizer = Koha::RecordProcessor->new( { filters => 'EmbedSeeFromHeadings' } );
642
            if (C4::Context->preference('IncludeSeeFromInSearches')) { 
643
            $marc = $normalizer->process($marc);
643
                my $normalizer = Koha::RecordProcessor->new( { filters => 'EmbedSeeFromHeadings' } );
644
                $marc = $normalizer->process($marc);
645
            }
646
            my $enriched_marc = enrich_marc($marc);
647
            if (defined $enriched_marc) {
648
                $marc = $enriched_marc;
649
            }
644
        }
650
        }
645
        if (C4::Context->preference("marcflavour") eq "UNIMARC") {
651
        if (C4::Context->preference("marcflavour") eq "UNIMARC") {
646
            fix_unimarc_100($marc);
652
            fix_unimarc_100($marc);
Lines 773-778 sub fix_unimarc_100 { Link Here
773
    }
779
    }
774
}
780
}
775
781
782
783
=pod
784
785
Enriches marc record to facilitate adding local tags.
786
787
Used to enable upfront processing when generating indexes (zebra, etc)
788
as tags can be added on the fly without affecting the original marc records
789
in the database.  Aggregated results based on items are done once during index
790
build time, which don't need to be done on each and every search.
791
792
Currently supports:
793
- updating biblio's $biblionumbertagfield (i.e. 999h=1) when all associated
794
  items are "hidden" as specified by the OpacHiddenItems syspref rules.
795
- updating biblio's $biblionumbertagfield (i.e. 999s=1) when all associated
796
  items are "suppressed" as specified by the items.suppressed mapping.
797
  
798
$marc = marc record
799
800
=cut
801
sub enrich_marc {
802
    my $marc = $_[0];
803
    my $frameworkcode = '';
804
    my $results_marc = $marc;
805
806
    my $biblionumber = $marc->field($biblionumbertagfield)->subfield($biblionumbertagsubfield);
807
    die qq{No biblionumber tag for framework "$frameworkcode"} unless $biblionumber;
808
    if ($biblionumber &&
809
        (C4::Context->preference('OpacHiddenItems') ||
810
         C4::Context->preference('OpacSuppression') ) ) {
811
812
        my $old_biblio_field = $marc->field($biblionumbertagfield);
813
        my $current_biblio_field = $old_biblio_field->clone;
814
        my $new_biblio_field;
815
        my @itemnumbers = @{ GetItemnumbersForBiblio($biblionumber) };
816
817
        if (C4::Context->preference('OpacHiddenItems')) {
818
            my ($bibliohiddentagfield,$bibliohiddentagsubfield) = &GetMarcFromKohaField("biblio.hidden",$frameworkcode);
819
            if ( !defined $bibliohiddentagfield) { $bibliohiddentagfield = '999'; }      # default
820
            if ( !defined $bibliohiddentagsubfield) { $bibliohiddentagsubfield = 'h'; }  # default
821
822
823
            my @hiddenitems = GetHiddenItemnumbersByItemnumbers(@itemnumbers);
824
#warn "itemcount:".@itemnumbers."  hiddenitemcount:".@hiddenitems;
825
            if ( @itemnumbers > 0 && (scalar(@itemnumbers) == scalar(@hiddenitems)) ) {
826
                # all items are hidden, so set the marc record biblionumber subfield h to 1
827
                $current_biblio_field->update( $bibliohiddentagsubfield => 1); # hidden
828
                $new_biblio_field = $current_biblio_field;
829
            }
830
        }
831
=pod
832
        if (C4::Context->preference('OpacSuppression')) {
833
            my ($bibliosuppresstagfield,$bibliosuppresstagsubfield) = &GetMarcFromKohaField("biblio.suppress",$frameworkcode);
834
            if ( !defined $bibliosuppresstagfield) { $bibliosuppresstagfield = '942'; }      # default
835
            if ( !defined $bibliosuppresstagsubfield) { $bibliodsuppresstagsubfield = 'n'; }  # default
836
837
            my @suppresseditems = GetSuppressedItemnumbers(@itemnumbers);
838
#warn "itemcount:".@itemnumbers."  suppresseditemcount:".@suppresseditems;
839
            if ( @itemnumbers > 0 && (scalar(@itemnumbers) == scalar(@suppresseditems)) ) {
840
                # all items are suppressed, so set the marc record biblionumber subfield s to 1
841
#TODO:  SuppressMarcTags syspref with list of marc tags  942n=1|... so folks with other/multiple suppress scenarios can work
842
                $current_biblio_field->update( $bibliosuppresstagsubfield => 1); # suppressed
843
                $new_biblio_field = $current_biblio_field;
844
            }
845
        }
846
=cut
847
848
        if (defined $new_biblio_field && defined $old_biblio_field) {
849
            # drop old field and replace with new one...
850
            $marc->delete_field($old_biblio_field);
851
            $marc->insert_fields_ordered($new_biblio_field);
852
        }
853
    }
854
855
    return $results_marc;
856
}
857
858
776
sub do_indexing {
859
sub do_indexing {
777
    my ($record_type, $op, $record_dir, $reset_index, $noshadow, $record_format, $zebraidx_log_opt) = @_;
860
    my ($record_type, $op, $record_dir, $reset_index, $noshadow, $record_format, $zebraidx_log_opt) = @_;
778
861
(-)a/opac/opac-search.pl (-2 / +1 lines)
Lines 610-616 for (my $i=0;$i<@servers;$i++) { Link Here
610
        }
610
        }
611
611
612
        if ($results_hashref->{$server}->{"hits"}){
612
        if ($results_hashref->{$server}->{"hits"}){
613
            $total = $total + $results_hashref->{$server}->{"hits"};
613
            $total = $total + @newresults;
614
        }
614
        }
615
615
616
        # Opac search history
616
        # Opac search history
617
- 

Return to bug 11909