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

(-)a/C4/XSLT.pm (-2 / +2 lines)
Lines 270-276 sub XSLTParse4Display { Link Here
270
    # possibly insert component records into Detail views
270
    # possibly insert component records into Detail views
271
    if ($xslsyspref =~ m/Details/) {
271
    if ($xslsyspref =~ m/Details/) {
272
        my $biblio = Koha::Biblios->find( $biblionumber );
272
        my $biblio = Koha::Biblios->find( $biblionumber );
273
        my $components = $biblio->get_marc_components(300);
273
        my $components = $biblio->get_marc_analytics(300);
274
        $variables->{show_analytics_link} = ( scalar @{$components} == 0 ) ? 0 : 1;
274
        $variables->{show_analytics_link} = ( scalar @{$components} == 0 ) ? 0 : 1;
275
275
276
        my $showcomp = C4::Context->preference('ShowComponentRecords');
276
        my $showcomp = C4::Context->preference('ShowComponentRecords');
Lines 284-290 sub XSLTParse4Display { Link Here
284
284
285
             $variables->{show_analytics_link} = 0;
285
             $variables->{show_analytics_link} = 0;
286
286
287
             my $search_query = Koha::Util::Search::get_component_part_query($biblionumber);
287
             my $search_query = $biblio->get_analytics_query;
288
             $variables->{ComponentPartQuery} = $search_query;
288
             $variables->{ComponentPartQuery} = $search_query;
289
289
290
             my @componentPartRecordXML = ('<componentPartRecords>');
290
             my @componentPartRecordXML = ('<componentPartRecords>');
(-)a/Koha/Biblio.pm (-5 / +48 lines)
Lines 498-518 sub suggestions { Link Here
498
    return Koha::Suggestions->_new_from_dbic( $suggestions_rs );
498
    return Koha::Suggestions->_new_from_dbic( $suggestions_rs );
499
}
499
}
500
500
501
=head3 get_marc_components
501
=head3 get_marc_analytics
502
502
503
  my $components = $self->get_marc_components();
503
  my $analytics = $self->get_marc_analytics();
504
504
505
Returns an array of MARCXML data, which are component parts of
505
Returns an array of MARCXML data, which are analytic parts of
506
this object (MARC21 773$w points to this)
506
this object (MARC21 773$w points to this)
507
507
508
=cut
508
=cut
509
509
510
sub get_marc_components {
510
sub get_marc_analytics {
511
    my ($self, $max_results) = @_;
511
    my ($self, $max_results) = @_;
512
512
513
    return [] if (C4::Context->preference('marcflavour') ne 'MARC21');
513
    return [] if (C4::Context->preference('marcflavour') ne 'MARC21');
514
514
515
    my $searchstr = Koha::Util::Search::get_component_part_query($self->id);
515
    my $searchstr = $self->get_analytics_query;
516
516
517
    if (defined($searchstr)) {
517
    if (defined($searchstr)) {
518
        my $searcher = Koha::SearchEngine::Search->new({index => $Koha::SearchEngine::BIBLIOS_INDEX});
518
        my $searcher = Koha::SearchEngine::Search->new({index => $Koha::SearchEngine::BIBLIOS_INDEX});
Lines 523-528 sub get_marc_components { Link Here
523
    return $self->{_components} || [];
523
    return $self->{_components} || [];
524
}
524
}
525
525
526
=head2 get_analytics_query
527
528
Returns a query which can be used to search for all component parts of MARC21 biblios
529
530
=cut
531
532
sub get_analytics_query {
533
    my ($self) = @_;
534
535
    my $marc = $self->metadata->record;
536
537
    my $searchstr;
538
    if ( C4::Context->preference('UseControlNumber') ) {
539
        my $pf001 = $marc->field('001') || undef;
540
541
        if ( defined($pf001) ) {
542
            my $pf003 = $marc->field('003') || undef;
543
544
            if ( !defined($pf003) ) {
545
                # search for 773$w='Host001'
546
                $searchstr = "rcn:" . $pf001->data();
547
            }
548
            else {
549
                $searchstr  = "(";
550
                # search for (773$w='Host001' and 003='Host003') or 773$w='Host003 Host001')
551
                $searchstr .= "(rcn:" . $pf001->data() . " AND cni:" . $pf003->data() . ")";
552
                $searchstr .= " OR rcn:" . $pf003->data() . " " . $pf001->data();
553
                $searchstr .= ")";
554
            }
555
556
            # limit to monograph and serial component part records
557
            $searchstr .= " AND (bib-level:a OR bib-level:b)";
558
        }
559
    }
560
    else {
561
        my $cleaned_title = $marc->title;
562
        $cleaned_title =~ tr|/||;
563
        $searchstr = "Host-item:($cleaned_title)";
564
    }
565
566
    return $searchstr;
567
}
568
526
=head3 subscriptions
569
=head3 subscriptions
527
570
528
my $subscriptions = $self->subscriptions
571
my $subscriptions = $self->subscriptions
(-)a/Koha/Util/Search.pm (-73 lines)
Lines 1-73 Link Here
1
package Koha::Util::Search;
2
3
# Copyright 2020 University of Helsinki
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use C4::Biblio qw( GetMarcBiblio );
23
24
=head1 NAME
25
26
Koha::Util::Search - functions to build complex search queries
27
28
=head1 FUNCTIONS
29
30
=head2 get_component_part_query
31
32
Returns a query which can be used to search for all component parts of MARC21 biblios
33
34
=cut
35
36
sub get_component_part_query {
37
    my ($biblionumber) = @_;
38
39
    my $marc = GetMarcBiblio( { biblionumber => $biblionumber } );
40
41
    my $searchstr;
42
    if ( C4::Context->preference('UseControlNumber') ) {
43
        my $pf001 = $marc->field('001') || undef;
44
45
        if ( defined($pf001) ) {
46
            my $pf003 = $marc->field('003') || undef;
47
48
            if ( !defined($pf003) ) {
49
                # search for 773$w='Host001'
50
                $searchstr = "rcn:" . $pf001->data();
51
            }
52
            else {
53
                $searchstr  = "(";
54
                # search for (773$w='Host001' and 003='Host003') or 773$w='Host003 Host001')
55
                $searchstr .= "(rcn:" . $pf001->data() . " AND cni:" . $pf003->data() . ")";
56
                $searchstr .= " OR rcn:" . $pf003->data() . " " . $pf001->data();
57
                $searchstr .= ")";
58
            }
59
60
            # limit to monograph and serial component part records
61
            $searchstr .= " AND (bib-level:a OR bib-level:b)";
62
        }
63
    }
64
    else {
65
        my $cleaned_title = $marc->title;
66
        $cleaned_title =~ tr|/||;
67
        $searchstr = "Host-item:($cleaned_title)";
68
    }
69
70
    return $searchstr;
71
}
72
73
1;
(-)a/t/Koha/Util/Search.t (-54 lines)
Lines 1-54 Link Here
1
#!/usr/bin/perl
2
#
3
# Copyright 2020 University of Helsinki
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use Test::More tests => 1;
23
24
use t::lib::Mocks;
25
use t::lib::TestBuilder;
26
27
use C4::Biblio qw( GetMarcBiblio ModBiblioMarc );
28
use Koha::Util::Search;
29
use MARC::Field;
30
31
my $builder = t::lib::TestBuilder->new;
32
33
subtest 'get_component_part_query' => sub {
34
    plan tests => 3;
35
36
    my $biblio = $builder->build_sample_biblio();
37
    my $biblionumber = $biblio->biblionumber;
38
    my $record = GetMarcBiblio({ biblionumber => $biblionumber });
39
40
    t::lib::Mocks::mock_preference( 'UseControlNumber', '0' );
41
    is(Koha::Util::Search::get_component_part_query($biblionumber), "Host-item:(Some boring read)", "UseControlNumber disabled");
42
43
    t::lib::Mocks::mock_preference( 'UseControlNumber', '1' );
44
    my $marc_001_field = MARC::Field->new('001', $biblionumber);
45
    $record->append_fields($marc_001_field);
46
    ModBiblioMarc($record, $biblionumber);
47
48
    is(Koha::Util::Search::get_component_part_query($biblionumber), "rcn:$biblionumber AND (bib-level:a OR bib-level:b)", "UseControlNumber enabled without MarcOrgCode");
49
50
    my $marc_003_field = MARC::Field->new('003', 'OSt');
51
    $record->append_fields($marc_003_field);
52
    ModBiblioMarc($record, $biblionumber);
53
    is(Koha::Util::Search::get_component_part_query($biblionumber), "((rcn:$biblionumber AND cni:OSt) OR rcn:OSt $biblionumber) AND (bib-level:a OR bib-level:b)", "UseControlNumber enabled with MarcOrgCode");
54
};
(-)a/t/db_dependent/Koha/Biblio.t (-9 / +34 lines)
Lines 17-25 Link Here
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
20
use Test::More tests => 15;
20
use Test::More tests => 16;
21
21
22
use C4::Biblio qw( AddBiblio ModBiblio );
22
use C4::Biblio qw( AddBiblio ModBiblio ModBiblioMarc );
23
use Koha::Database;
23
use Koha::Database;
24
use Koha::Acquisition::Orders;
24
use Koha::Acquisition::Orders;
25
25
Lines 503-509 subtest 'suggestions() tests' => sub { Link Here
503
    $schema->storage->txn_rollback;
503
    $schema->storage->txn_rollback;
504
};
504
};
505
505
506
subtest 'get_marc_components() tests' => sub {
506
subtest 'get_marc_analytics() tests' => sub {
507
507
508
    plan tests => 3;
508
    plan tests => 3;
509
509
Lines 515-527 subtest 'get_marc_components() tests' => sub { Link Here
515
    my $search_mod = Test::MockModule->new( 'Koha::SearchEngine::Zebra::Search' );
515
    my $search_mod = Test::MockModule->new( 'Koha::SearchEngine::Zebra::Search' );
516
    $search_mod->mock( 'simple_search_compat', \&search_component_record2 );
516
    $search_mod->mock( 'simple_search_compat', \&search_component_record2 );
517
517
518
    my @components = $host_biblio->get_marc_components;
518
    my @components = $host_biblio->get_marc_analytics;
519
    is( ref(\@components), 'ARRAY', 'Return type is correct' );
519
    is( ref(\@components), 'ARRAY', 'Return type is correct' );
520
520
521
    is_deeply(
521
    is_deeply(
522
        [@components],
522
        [@components],
523
        [()],
523
        [[]],
524
        '->get_marc_components returns an empty ARRAY'
524
        '->get_marc_analytics returns an empty ARRAY'
525
    );
525
    );
526
526
527
    $search_mod->unmock( 'simple_search_compat');
527
    $search_mod->unmock( 'simple_search_compat');
Lines 529-543 subtest 'get_marc_components() tests' => sub { Link Here
529
    my $component_record = component_record1()->as_xml();
529
    my $component_record = component_record1()->as_xml();
530
530
531
    is_deeply(
531
    is_deeply(
532
        $host_biblio->get_marc_components,
532
        $host_biblio->get_marc_analytics,
533
        [($component_record)],
533
        [($component_record)],
534
        '->get_marc_components returns the related component part record'
534
        '->get_marc_analytics returns the related component part record'
535
    );
535
    );
536
    $search_mod->unmock( 'simple_search_compat');
536
    $search_mod->unmock( 'simple_search_compat');
537
537
538
    $schema->storage->txn_rollback;
538
    $schema->storage->txn_rollback;
539
};
539
};
540
540
541
subtest 'get_analytics_query' => sub {
542
    plan tests => 3;
543
544
    my $biblio = $builder->build_sample_biblio();
545
    my $biblionumber = $biblio->biblionumber;
546
    my $record = $biblio->metadata->record;
547
548
    t::lib::Mocks::mock_preference( 'UseControlNumber', '0' );
549
    is($biblio->get_analytics_query, "Host-item:(Some boring read)", "UseControlNumber disabled");
550
551
    t::lib::Mocks::mock_preference( 'UseControlNumber', '1' );
552
    my $marc_001_field = MARC::Field->new('001', $biblionumber);
553
    $record->append_fields($marc_001_field);
554
    C4::Biblio::ModBiblio( $record, $biblio->biblionumber );
555
    $biblio = Koha::Biblios->find( $biblio->biblionumber);
556
557
    is($biblio->get_analytics_query, "rcn:$biblionumber AND (bib-level:a OR bib-level:b)", "UseControlNumber enabled without MarcOrgCode");
558
559
    my $marc_003_field = MARC::Field->new('003', 'OSt');
560
    $record->append_fields($marc_003_field);
561
    C4::Biblio::ModBiblio( $record, $biblio->biblionumber );
562
    $biblio = Koha::Biblios->find( $biblio->biblionumber);
563
564
    is($biblio->get_analytics_query, "((rcn:$biblionumber AND cni:OSt) OR rcn:OSt $biblionumber) AND (bib-level:a OR bib-level:b)", "UseControlNumber enabled with MarcOrgCode");
565
};
566
541
subtest 'orders() and active_orders() tests' => sub {
567
subtest 'orders() and active_orders() tests' => sub {
542
568
543
    plan tests => 5;
569
    plan tests => 5;
544
- 

Return to bug 11175