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

(-)a/C4/XSLT.pm (-3 / +2 lines)
Lines 29-35 use C4::Koha qw( xml_escape ); Link Here
29
use C4::Biblio qw( GetAuthorisedValueDesc GetFrameworkCode GetMarcStructure );
29
use C4::Biblio qw( GetAuthorisedValueDesc GetFrameworkCode GetMarcStructure );
30
use Koha::AuthorisedValues;
30
use Koha::AuthorisedValues;
31
use Koha::ItemTypes;
31
use Koha::ItemTypes;
32
use Koha::Util::Search;
33
use Koha::XSLT::Base;
32
use Koha::XSLT::Base;
34
use Koha::Libraries;
33
use Koha::Libraries;
35
34
Lines 270-276 sub XSLTParse4Display { Link Here
270
    # possibly insert component records into Detail views
269
    # possibly insert component records into Detail views
271
    if ($xslsyspref =~ m/Details/) {
270
    if ($xslsyspref =~ m/Details/) {
272
        my $biblio = Koha::Biblios->find( $biblionumber );
271
        my $biblio = Koha::Biblios->find( $biblionumber );
273
        my $components = $biblio->get_marc_components(300);
272
        my $components = $biblio->get_marc_analytics(300);
274
        $variables->{show_analytics_link} = ( scalar @{$components} == 0 ) ? 0 : 1;
273
        $variables->{show_analytics_link} = ( scalar @{$components} == 0 ) ? 0 : 1;
275
274
276
        my $showcomp = C4::Context->preference('ShowComponentRecords');
275
        my $showcomp = C4::Context->preference('ShowComponentRecords');
Lines 284-290 sub XSLTParse4Display { Link Here
284
283
285
             $variables->{show_analytics_link} = 0;
284
             $variables->{show_analytics_link} = 0;
286
285
287
             my $search_query = Koha::Util::Search::get_component_part_query($biblionumber);
286
             my $search_query = $biblio->get_analytics_query;
288
             $variables->{ComponentPartQuery} = $search_query;
287
             $variables->{ComponentPartQuery} = $search_query;
289
288
290
             my @componentPartRecordXML = ('<componentPartRecords>');
289
             my @componentPartRecordXML = ('<componentPartRecords>');
(-)a/Koha/Biblio.pm (-6 / +48 lines)
Lines 43-49 use Koha::Suggestions; Link Here
43
use Koha::Subscriptions;
43
use Koha::Subscriptions;
44
use Koha::SearchEngine;
44
use Koha::SearchEngine;
45
use Koha::SearchEngine::Search;
45
use Koha::SearchEngine::Search;
46
use Koha::Util::Search;
47
46
48
=head1 NAME
47
=head1 NAME
49
48
Lines 498-518 sub suggestions { Link Here
498
    return Koha::Suggestions->_new_from_dbic( $suggestions_rs );
497
    return Koha::Suggestions->_new_from_dbic( $suggestions_rs );
499
}
498
}
500
499
501
=head3 get_marc_components
500
=head3 get_marc_analytics
502
501
503
  my $components = $self->get_marc_components();
502
  my $analytics = $self->get_marc_analytics();
504
503
505
Returns an array of MARCXML data, which are component parts of
504
Returns an array of MARCXML data, which are analytic parts of
506
this object (MARC21 773$w points to this)
505
this object (MARC21 773$w points to this)
507
506
508
=cut
507
=cut
509
508
510
sub get_marc_components {
509
sub get_marc_analytics {
511
    my ($self, $max_results) = @_;
510
    my ($self, $max_results) = @_;
512
511
513
    return [] if (C4::Context->preference('marcflavour') ne 'MARC21');
512
    return [] if (C4::Context->preference('marcflavour') ne 'MARC21');
514
513
515
    my $searchstr = Koha::Util::Search::get_component_part_query($self->id);
514
    my $searchstr = $self->get_analytics_query;
516
515
517
    if (defined($searchstr)) {
516
    if (defined($searchstr)) {
518
        my $searcher = Koha::SearchEngine::Search->new({index => $Koha::SearchEngine::BIBLIOS_INDEX});
517
        my $searcher = Koha::SearchEngine::Search->new({index => $Koha::SearchEngine::BIBLIOS_INDEX});
Lines 523-528 sub get_marc_components { Link Here
523
    return $self->{_components} || [];
522
    return $self->{_components} || [];
524
}
523
}
525
524
525
=head2 get_analytics_query
526
527
Returns a query which can be used to search for all component parts of MARC21 biblios
528
529
=cut
530
531
sub get_analytics_query {
532
    my ($self) = @_;
533
534
    my $marc = $self->metadata->record;
535
536
    my $searchstr;
537
    if ( C4::Context->preference('UseControlNumber') ) {
538
        my $pf001 = $marc->field('001') || undef;
539
540
        if ( defined($pf001) ) {
541
            my $pf003 = $marc->field('003') || undef;
542
543
            if ( !defined($pf003) ) {
544
                # search for 773$w='Host001'
545
                $searchstr = "rcn:" . $pf001->data();
546
            }
547
            else {
548
                $searchstr  = "(";
549
                # search for (773$w='Host001' and 003='Host003') or 773$w='Host003 Host001')
550
                $searchstr .= "(rcn:" . $pf001->data() . " AND cni:" . $pf003->data() . ")";
551
                $searchstr .= " OR rcn:" . $pf003->data() . " " . $pf001->data();
552
                $searchstr .= ")";
553
            }
554
555
            # limit to monograph and serial component part records
556
            $searchstr .= " AND (bib-level:a OR bib-level:b)";
557
        }
558
    }
559
    else {
560
        my $cleaned_title = $marc->title;
561
        $cleaned_title =~ tr|/||;
562
        $searchstr = "Host-item:($cleaned_title)";
563
    }
564
565
    return $searchstr;
566
}
567
526
=head3 subscriptions
568
=head3 subscriptions
527
569
528
my $subscriptions = $self->subscriptions
570
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