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

(-)a/Koha/Old/Biblio/Metadata.pm (-1 / +1 lines)
Lines 21-27 use MARC::File::XML; Link Here
21
use Scalar::Util qw( blessed );
21
use Scalar::Util qw( blessed );
22
22
23
use C4::Biblio qw( GetMarcFromKohaField );
23
use C4::Biblio qw( GetMarcFromKohaField );
24
use C4::Items  qw( GetMarcItem );
24
use C4::Items qw( GetMarcItem );
25
use Koha::Database;
25
use Koha::Database;
26
use Koha::Exceptions::Metadata;
26
use Koha::Exceptions::Metadata;
27
27
(-)a/Koha/Old/Biblios.pm (-1 / +1 lines)
Lines 54-60 sub api_query_fixer { Link Here
54
    } else {
54
    } else {
55
        $query =~
55
        $query =~
56
            s/${quotes}(age_restriction|cn_class|cn_item|cn_sort|cn_source|cn_suffix|collection_issn|collection_title|collection_volume|ean|edition_statement|illustrations|isbn|issn|item_type|lc_control_number|notes|number|pages|publication_place|publication_year|publisher|material_size|serial_total_issues|url|volume|volume_date|volume_description)${quotes}/${quotes}deletedbiblioitem\.$1${quotes}/g;
56
            s/${quotes}(age_restriction|cn_class|cn_item|cn_sort|cn_source|cn_suffix|collection_issn|collection_title|collection_volume|ean|edition_statement|illustrations|isbn|issn|item_type|lc_control_number|notes|number|pages|publication_place|publication_year|publisher|material_size|serial_total_issues|url|volume|volume_date|volume_description)${quotes}/${quotes}deletedbiblioitem\.$1${quotes}/g;
57
        $query =~ # handle ambiguous 'biblionumber'
57
        $query =~    # handle ambiguous 'biblionumber'
58
            s/${quotes}(biblio_id)${quotes}/${quotes}me\.$1${quotes}/g;
58
            s/${quotes}(biblio_id)${quotes}/${quotes}me\.$1${quotes}/g;
59
    }
59
    }
60
60
(-)a/Koha/REST/V1/DeletedBiblios.pm (-29 / +15 lines)
Lines 46-62 sub get { Link Here
46
    my $c = shift->openapi->valid_input or return;
46
    my $c = shift->openapi->valid_input or return;
47
47
48
    my $attributes;
48
    my $attributes;
49
    $attributes = { prefetch => [ 'metadata' ] } # don't prefetch metadata if not needed
49
    $attributes = { prefetch => ['metadata'] }    # don't prefetch metadata if not needed
50
        unless $c->req->headers->accept =~ m/application\/json/;
50
        unless $c->req->headers->accept =~ m/application\/json/;
51
51
52
    my $biblio = Koha::Old::Biblios->find( { biblionumber => $c->param('biblio_id') }, $attributes );
52
    my $biblio = Koha::Old::Biblios->find( { biblionumber => $c->param('biblio_id') }, $attributes );
53
53
54
    unless ( $biblio ) {
54
    unless ($biblio) {
55
        return $c->render(
55
        return $c->render(
56
            status  => 404,
56
            status  => 404,
57
            openapi => {
57
            openapi => { error => "Object not found." }
58
                error => "Object not found."
59
            }
60
        );
58
        );
61
    }
59
    }
62
60
Lines 67-74 sub get { Link Here
67
                status => 200,
65
                status => 200,
68
                json   => $biblio->to_api
66
                json   => $biblio->to_api
69
            );
67
            );
70
        }
68
        } else {
71
        else {
72
            my $metadata = $biblio->metadata;
69
            my $metadata = $biblio->metadata;
73
            my $record   = $metadata->record;
70
            my $record   = $metadata->record;
74
            my $schema   = $metadata->schema // C4::Context->preference("marcflavour");
71
            my $schema   = $metadata->schema // C4::Context->preference("marcflavour");
Lines 106-113 sub get { Link Here
106
                }
103
                }
107
            );
104
            );
108
        }
105
        }
109
    }
106
    } catch {
110
    catch {
111
        $c->unhandled_exception($_);
107
        $c->unhandled_exception($_);
112
    };
108
    };
113
}
109
}
Lines 123-173 sub list { Link Here
123
119
124
    my @prefetch = qw(biblioitem);
120
    my @prefetch = qw(biblioitem);
125
    push @prefetch, 'metadata'    # don't prefetch metadata if not needed
121
    push @prefetch, 'metadata'    # don't prefetch metadata if not needed
126
      unless $c->req->headers->accept =~ m/application\/json/;
122
        unless $c->req->headers->accept =~ m/application\/json/;
127
123
128
    my $rs = Koha::Old::Biblios->search( undef, { prefetch => \@prefetch });
124
    my $rs      = Koha::Old::Biblios->search( undef, { prefetch => \@prefetch } );
129
    my $biblios = $c->objects->search_rs( $rs, [(sub{ $rs->api_query_fixer( $_[0], '', $_[1] ) })] );
125
    my $biblios = $c->objects->search_rs( $rs, [ ( sub { $rs->api_query_fixer( $_[0], '', $_[1] ) } ) ] );
130
126
131
    return try {
127
    return try {
132
128
133
        if ( $c->req->headers->accept =~ m/application\/json(;.*)?$/ ) {
129
        if ( $c->req->headers->accept =~ m/application\/json(;.*)?$/ ) {
134
            return $c->render(
130
            return $c->render(
135
                status => 200,
131
                status => 200,
136
                json   => $c->objects->to_api( $biblios ),
132
                json   => $c->objects->to_api($biblios),
137
            );
133
            );
138
        }
134
        } elsif ( $c->req->headers->accept =~ m/application\/marcxml\+xml(;.*)?$/ ) {
139
        elsif (
140
            $c->req->headers->accept =~ m/application\/marcxml\+xml(;.*)?$/ )
141
        {
142
            $c->res->headers->add( 'Content-Type', 'application/marcxml+xml' );
135
            $c->res->headers->add( 'Content-Type', 'application/marcxml+xml' );
143
            return $c->render(
136
            return $c->render(
144
                status => 200,
137
                status => 200,
145
                text   => $biblios->print_collection('marcxml')
138
                text   => $biblios->print_collection('marcxml')
146
            );
139
            );
147
        }
140
        } elsif ( $c->req->headers->accept =~ m/application\/marc-in-json(;.*)?$/ ) {
148
        elsif (
149
            $c->req->headers->accept =~ m/application\/marc-in-json(;.*)?$/ )
150
        {
151
            $c->res->headers->add( 'Content-Type', 'application/marc-in-json' );
141
            $c->res->headers->add( 'Content-Type', 'application/marc-in-json' );
152
            return $c->render(
142
            return $c->render(
153
                status => 200,
143
                status => 200,
154
                data   => $biblios->print_collection('mij')
144
                data   => $biblios->print_collection('mij')
155
            );
145
            );
156
        }
146
        } elsif ( $c->req->headers->accept =~ m/application\/marc(;.*)?$/ ) {
157
        elsif ( $c->req->headers->accept =~ m/application\/marc(;.*)?$/ ) {
158
            $c->res->headers->add( 'Content-Type', 'application/marc' );
147
            $c->res->headers->add( 'Content-Type', 'application/marc' );
159
            return $c->render(
148
            return $c->render(
160
                status => 200,
149
                status => 200,
161
                text   => $biblios->print_collection('marc')
150
                text   => $biblios->print_collection('marc')
162
            );
151
            );
163
        }
152
        } elsif ( $c->req->headers->accept =~ m/text\/plain(;.*)?$/ ) {
164
        elsif ( $c->req->headers->accept =~ m/text\/plain(;.*)?$/ ) {
165
            return $c->render(
153
            return $c->render(
166
                status => 200,
154
                status => 200,
167
                text   => $biblios->print_collection('txt')
155
                text   => $biblios->print_collection('txt')
168
            );
156
            );
169
        }
157
        } else {
170
        else {
171
            return $c->render(
158
            return $c->render(
172
                status  => 406,
159
                status  => 406,
173
                openapi => [
160
                openapi => [
Lines 177-184 sub list { Link Here
177
                ]
164
                ]
178
            );
165
            );
179
        }
166
        }
180
    }
167
    } catch {
181
    catch {
182
        $c->unhandled_exception($_);
168
        $c->unhandled_exception($_);
183
    };
169
    };
184
}
170
}
(-)a/Koha/Schema/Result/Deletedbiblio.pm (-8 / +9 lines)
Lines 215-236 __PACKAGE__->has_many( Link Here
215
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:KwlqhkWWX6CYWb3l2fCcSg
215
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:KwlqhkWWX6CYWb3l2fCcSg
216
216
217
__PACKAGE__->has_many(
217
__PACKAGE__->has_many(
218
  "biblioitem",
218
    "biblioitem",
219
  "Koha::Schema::Result::Deletedbiblioitem",
219
    "Koha::Schema::Result::Deletedbiblioitem",
220
  { "foreign.biblionumber" => "self.biblionumber" },
220
    { "foreign.biblionumber" => "self.biblionumber" },
221
  { cascade_copy => 0, cascade_delete => 0 },
221
    { cascade_copy           => 0, cascade_delete => 0 },
222
);
222
);
223
223
224
__PACKAGE__->has_one(
224
__PACKAGE__->has_one(
225
  "metadata",
225
    "metadata",
226
  "Koha::Schema::Result::DeletedbiblioMetadata",
226
    "Koha::Schema::Result::DeletedbiblioMetadata",
227
  { "foreign.biblionumber" => "self.biblionumber" },
227
    { "foreign.biblionumber" => "self.biblionumber" },
228
  { cascade_copy => 0, cascade_delete => 0 },
228
    { cascade_copy           => 0, cascade_delete => 0 },
229
);
229
);
230
230
231
sub koha_objects_class {
231
sub koha_objects_class {
232
    'Koha::Old::Biblios';
232
    'Koha::Old::Biblios';
233
}
233
}
234
234
sub koha_object_class {
235
sub koha_object_class {
235
    'Koha::Old::Biblio';
236
    'Koha::Old::Biblio';
236
}
237
}
(-)a/t/db_dependent/api/v1/deleted_biblios.t (-64 / +51 lines)
Lines 65-115 subtest 'get() tests' => sub { Link Here
65
    $patron->discard_changes;
65
    $patron->discard_changes;
66
    my $userid = $patron->userid;
66
    my $userid = $patron->userid;
67
67
68
    my $biblio = $builder->build_sample_biblio({
68
    my $biblio = $builder->build_sample_biblio(
69
        title  => 'The unbearable lightness of being',
69
        {
70
        author => 'Milan Kundera'
70
            title  => 'The unbearable lightness of being',
71
    });
71
            author => 'Milan Kundera'
72
        }
73
    );
72
74
73
    my $formatted = $biblio->metadata->record->as_formatted;
75
    my $formatted = $biblio->metadata->record->as_formatted;
74
    DelBiblio( $biblio->id );
76
    DelBiblio( $biblio->id );
75
77
76
    $t->get_ok("//$userid:$password@/api/v1/deleted/biblios/" . $biblio->biblionumber)
78
    $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios/" . $biblio->biblionumber )->status_is(403);
77
      ->status_is(403);
78
79
79
    $patron->flags(4)->store;
80
    $patron->flags(4)->store;
80
81
81
    $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios/" . $biblio->biblionumber
82
    $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios/"
82
                => { Accept => 'application/weird+format' } )
83
            . $biblio->biblionumber => { Accept => 'application/weird+format' } )->status_is(400);
83
      ->status_is(400);
84
84
85
    $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios/" . $biblio->biblionumber
85
    $t->get_ok(
86
                 => { Accept => 'application/json' } )
86
        "//$userid:$password@/api/v1/deleted/biblios/" . $biblio->biblionumber => { Accept => 'application/json' } )
87
      ->status_is(200)
87
        ->status_is(200)->json_is( '/title', 'The unbearable lightness of being' )
88
      ->json_is( '/title', 'The unbearable lightness of being' )
88
        ->json_is( '/author', 'Milan Kundera' );
89
      ->json_is( '/author', 'Milan Kundera' );
90
89
91
    $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios/" . $biblio->biblionumber
90
    $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios/"
92
                 => { Accept => 'application/marcxml+xml' } )
91
            . $biblio->biblionumber => { Accept => 'application/marcxml+xml' } )->status_is(200);
93
      ->status_is(200);
94
92
95
    $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios/" . $biblio->biblionumber
93
    $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios/"
96
                 => { Accept => 'application/marc-in-json' } )
94
            . $biblio->biblionumber => { Accept => 'application/marc-in-json' } )->status_is(200);
97
      ->status_is(200);
98
95
99
    $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios/" . $biblio->biblionumber
96
    $t->get_ok(
100
                 => { Accept => 'application/marc' } )
97
        "//$userid:$password@/api/v1/deleted/biblios/" . $biblio->biblionumber => { Accept => 'application/marc' } )
101
      ->status_is(200);
98
        ->status_is(200);
102
99
103
    $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios/" . $biblio->biblionumber
100
    $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios/" . $biblio->biblionumber => { Accept => 'text/plain' } )
104
                 => { Accept => 'text/plain' } )
101
        ->status_is(200)->content_is($formatted);
105
      ->status_is(200)
106
      ->content_is($formatted);
107
102
108
    my $biblio_exist = $builder->build_sample_biblio();
103
    my $biblio_exist = $builder->build_sample_biblio();
109
    $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios/" . $biblio_exist->biblionumber
104
    $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios/"
110
                 => { Accept => 'application/marc' } )
105
            . $biblio_exist->biblionumber => { Accept => 'application/marc' } )->status_is(404)
111
      ->status_is(404)
106
        ->json_is( '/error', 'Object not found.' );
112
      ->json_is( '/error', 'Object not found.' );
113
107
114
    subtest 'marc-in-json encoding tests' => sub {
108
    subtest 'marc-in-json encoding tests' => sub {
115
109
Lines 126-136 subtest 'get() tests' => sub { Link Here
126
120
127
        DelBiblio( $biblio->id );
121
        DelBiblio( $biblio->id );
128
122
129
        my $result = $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios/" . $biblio->biblionumber
123
        my $result = $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios/"
130
                    => { Accept => 'application/marc-in-json' } )
124
                . $biblio->biblionumber => { Accept => 'application/marc-in-json' } )->status_is(200)->tx->res->body;
131
          ->status_is(200)->tx->res->body;
132
125
133
        my $encoded_title  = Encode::encode( "UTF-8", $title_with_diacritics );
126
        my $encoded_title = Encode::encode( "UTF-8", $title_with_diacritics );
134
127
135
        like( $result, qr/\Q$encoded_title/, "The title is not double encoded" );
128
        like( $result, qr/\Q$encoded_title/, "The title is not double encoded" );
136
    };
129
    };
Lines 139-146 subtest 'get() tests' => sub { Link Here
139
        plan tests => 3;
132
        plan tests => 3;
140
133
141
        my $marcflavour = C4::Context->preference('marcflavour');
134
        my $marcflavour = C4::Context->preference('marcflavour');
142
        t::lib::Mocks::mock_preference('marcflavour', 'UNIMARC');
135
        t::lib::Mocks::mock_preference( 'marcflavour', 'UNIMARC' );
143
144
136
145
        my $title_with_diacritics = "L'insoutenable légèreté de l'être";
137
        my $title_with_diacritics = "L'insoutenable légèreté de l'être";
146
138
Lines 153-171 subtest 'get() tests' => sub { Link Here
153
145
154
        my $record = $biblio->metadata->record;
146
        my $record = $biblio->metadata->record;
155
        $record->leader('     nam         3  4500');
147
        $record->leader('     nam         3  4500');
156
        $biblio->metadata->metadata($record->as_xml_record('UNIMARC'));
148
        $biblio->metadata->metadata( $record->as_xml_record('UNIMARC') );
157
        $biblio->metadata->store;
149
        $biblio->metadata->store;
158
150
159
        DelBiblio( $biblio->id );
151
        DelBiblio( $biblio->id );
160
152
161
        my $result = $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios/" . $biblio->biblionumber
153
        my $result = $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios/"
162
                    => { Accept => 'application/marcxml+xml' } )
154
                . $biblio->biblionumber => { Accept => 'application/marcxml+xml' } )->status_is(200)->tx->res->body;
163
          ->status_is(200)->tx->res->body;
164
155
165
        my $encoded_title  = Encode::encode( "UTF-8", $title_with_diacritics );
156
        my $encoded_title = Encode::encode( "UTF-8", $title_with_diacritics );
166
157
167
        like( $result, qr/\Q$encoded_title/, "The title is not double encoded" );
158
        like( $result, qr/\Q$encoded_title/, "The title is not double encoded" );
168
        t::lib::Mocks::mock_preference('marcflavour', $marcflavour);
159
        t::lib::Mocks::mock_preference( 'marcflavour', $marcflavour );
169
    };
160
    };
170
161
171
    $schema->storage->txn_rollback;
162
    $schema->storage->txn_rollback;
Lines 188-197 subtest 'list() tests' => sub { Link Here
188
    $patron->discard_changes;
179
    $patron->discard_changes;
189
    my $userid = $patron->userid;
180
    my $userid = $patron->userid;
190
181
191
    t::lib::Mocks::mock_preference('marcflavour', 'UNIMARC');
182
    t::lib::Mocks::mock_preference( 'marcflavour', 'UNIMARC' );
192
183
193
    my $title_with_diacritics = "L'insoutenable légèreté de l'être";
184
    my $title_with_diacritics = "L'insoutenable légèreté de l'être";
194
    my $biblio = $builder->build_sample_biblio(
185
    my $biblio                = $builder->build_sample_biblio(
195
        {
186
        {
196
            title  => $title_with_diacritics,
187
            title  => $title_with_diacritics,
197
            author => "Milan Kundera",
188
            author => "Milan Kundera",
Lines 200-214 subtest 'list() tests' => sub { Link Here
200
191
201
    my $record = $biblio->metadata->record;
192
    my $record = $biblio->metadata->record;
202
    $record->leader('     nam         3  4500');
193
    $record->leader('     nam         3  4500');
203
    $biblio->metadata->metadata($record->as_xml_record('UNIMARC'))->store;
194
    $biblio->metadata->metadata( $record->as_xml_record('UNIMARC') )->store;
204
195
205
    my $biblio_id_1 = $biblio->id;
196
    my $biblio_id_1 = $biblio->id;
206
197
207
    t::lib::Mocks::mock_preference('marcflavour', 'MARC21');
198
    t::lib::Mocks::mock_preference( 'marcflavour', 'MARC21' );
208
    my $biblio_id_2 = $builder->build_sample_biblio->id;
199
    my $biblio_id_2 = $builder->build_sample_biblio->id;
209
    
200
210
    DelBiblio( $biblio_id_1 );
201
    DelBiblio($biblio_id_1);
211
    DelBiblio( $biblio_id_2 );
202
    DelBiblio($biblio_id_2);
212
203
213
    my $query = encode_json( [ { biblio_id => $biblio_id_1 }, { biblio_id => $biblio_id_2 } ] );
204
    my $query = encode_json( [ { biblio_id => $biblio_id_1 }, { biblio_id => $biblio_id_2 } ] );
214
205
Lines 219-227 subtest 'list() tests' => sub { Link Here
219
    $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios?q=$query" => { Accept => 'application/weird+format' } )
210
    $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios?q=$query" => { Accept => 'application/weird+format' } )
220
        ->status_is(400);
211
        ->status_is(400);
221
212
222
    $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios?q=$query" => { Accept => 'application/json' } )->status_is(200);
213
    $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios?q=$query" => { Accept => 'application/json' } )
214
        ->status_is(200);
223
215
224
    my $result = $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios?q=$query" => { Accept => 'application/marcxml+xml' } )
216
    my $result =
217
        $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios?q=$query" => { Accept => 'application/marcxml+xml' } )
225
        ->status_is(200)->tx->res->body;
218
        ->status_is(200)->tx->res->body;
226
219
227
    my $encoded_title = Encode::encode( "UTF-8", $title_with_diacritics );
220
    my $encoded_title = Encode::encode( "UTF-8", $title_with_diacritics );
Lines 230-252 subtest 'list() tests' => sub { Link Here
230
    $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios?q=$query" => { Accept => 'application/marc-in-json' } )
223
    $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios?q=$query" => { Accept => 'application/marc-in-json' } )
231
        ->status_is(200);
224
        ->status_is(200);
232
225
233
    $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios?q=$query" => { Accept => 'application/marc' } )->status_is(200);
226
    $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios?q=$query" => { Accept => 'application/marc' } )
227
        ->status_is(200);
234
228
235
    $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios?q=$query" => { Accept => 'text/plain' } )->status_is(200);
229
    $t->get_ok( "//$userid:$password@/api/v1/deleted/biblios?q=$query" => { Accept => 'text/plain' } )->status_is(200);
236
230
237
    # DELETE any biblio with ISBN = TOMAS
231
    # DELETE any biblio with ISBN = TOMAS
238
    Koha::Biblios->search({ 'biblioitem.isbn' => 'TOMAS' }, { join => [ 'biblioitem' ] })
232
    Koha::Biblios->search( { 'biblioitem.isbn' => 'TOMAS' }, { join => ['biblioitem'] } )->delete;
239
                 ->delete;
240
241
233
242
    my $isbn_query = encode_json({ isbn => 'TOMAS' });
234
    my $isbn_query   = encode_json( { isbn => 'TOMAS' } );
243
    my $tomas_biblio = $builder->build_sample_biblio({
235
    my $tomas_biblio = $builder->build_sample_biblio( { isbn => 'TOMAS' } );
244
        isbn => 'TOMAS'
245
    });
246
    DelBiblio( $tomas_biblio->id );
236
    DelBiblio( $tomas_biblio->id );
247
    $t->get_ok( "//$userid:$password@/api/v1/biblios?q=$isbn_query" =>
237
    $t->get_ok( "//$userid:$password@/api/v1/biblios?q=$isbn_query" => { Accept => 'text/plain' } )->status_is(200);
248
          { Accept => 'text/plain' } )
249
      ->status_is(200);
250
238
251
    $schema->storage->txn_rollback;
239
    $schema->storage->txn_rollback;
252
};
240
};
253
- 

Return to bug 33960