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

(-)a/Koha/REST/V1/Biblios.pm (+121 lines)
Lines 21-26 use Mojo::Base 'Mojolicious::Controller'; Link Here
21
21
22
use Koha::Biblios;
22
use Koha::Biblios;
23
use Koha::RecordProcessor;
23
use Koha::RecordProcessor;
24
use Koha::SearchEngine::Search;
24
use C4::Biblio qw( DelBiblio );
25
use C4::Biblio qw( DelBiblio );
25
26
26
use List::MoreUtils qw( any );
27
use List::MoreUtils qw( any );
Lines 142-147 sub delete { Link Here
142
    };
143
    };
143
}
144
}
144
145
146
=head3 get_biblios_public
147
148
Controller function that handles retrieving biblios by querying the database
149
via the searchengine that's currently in use. Use the q_ccl query paramater.
150
151
=cut
152
153
sub get_biblios_public {
154
155
    my $c = shift->openapi->valid_input or return;
156
157
    my $requested_content_type = $c->req->headers->header('Accept');
158
    my $searcher = Koha::SearchEngine::Search->new( { index => 'biblios' } );
159
    my $query    = $c->validation->param('q_ccl');
160
    my $record_processor = Koha::RecordProcessor->new(
161
        {
162
            filters => 'ViewPolicy',
163
            options => {
164
                interface => 'opac',
165
            }
166
        }
167
    );
168
169
    my ( $error, $results, $total_hits ) =
170
      $searcher->simple_search_compat( $query, 0, undef );
171
172
    if ( !$total_hits ) {
173
        return $c->render(
174
            status  => 404,
175
            openapi => {
176
                error => 'Nothing found.'
177
            }
178
        );
179
    }
180
181
    sub format_record_by_content_type {
182
        my ($args) = @_;
183
184
        if ( $args->{'content_type'} eq 'application/marc-in-json' ) {
185
            for my $record ( @{ $args->{'records'} } ) {
186
                $record = $record->to_mij;
187
            }
188
            return ( q{[} . ( join q{,}, @{ $args->{'records'} } ) . q{]} );
189
        }
190
191
        # Insert additional content types here or above, you know .. alphabetically
192
    }
193
194
    sub process_record {
195
        my ($args) = @_;
196
197
        my $biblionumber =
198
          $args->{'searcher'}->extract_biblionumber( $args->{'record'} );
199
        my $biblio = Koha::Biblios->find( { biblionumber => $biblionumber } );
200
201
        if (
202
            !(
203
                   $args->{'patron'}
204
                && $args->{'patron'}->category->override_hidden_items
205
            )
206
          )
207
        {
208
            if ( $biblio->hidden_in_opac( { rules => $args->{'rules'} } ) ) {
209
                next;
210
            }
211
        }
212
213
        $args->{'processor'}->process( $args->{'record'} );
214
215
        return $args->{'record'};
216
    }
217
218
    return try {
219
220
        my $marcflavour = C4::Context->preference('marcflavour');
221
222
        # Apply framework's filtering to MARC::Record object
223
224
        my $patron = $c->stash('koha.user');
225
        my $opachiddenitems_rules =
226
          C4::Context->yaml_preference('OpacHiddenItems');
227
228
        my @records;
229
        for my $result ( @{$results} ) {
230
231
            if ( ref($result) eq q{} ) { next; }
232
233
            push @records,
234
              process_record(
235
                {
236
                    searcher  => $searcher,
237
                    processor => $record_processor,
238
                    record    => $result,
239
                    patron    => $patron,
240
                    rules     => $opachiddenitems_rules
241
                }
242
              );
243
        }
244
245
        my $response =
246
          format_record_by_content_type(
247
            { content_type => $requested_content_type, records => \@records } );
248
249
        $c->respond_to(
250
            mij => {
251
                status => 200,
252
                format => 'mij',
253
                data   => $response
254
            },
255
            any => {
256
                status  => 406,
257
                openapi => [ 'application/marc-in-json', ]
258
            }
259
        );
260
    }
261
    catch {
262
        $c->unhandled_exception($_);
263
    };
264
}
265
145
=head3 get_public
266
=head3 get_public
146
267
147
Controller function that handles retrieving a single biblio object
268
Controller function that handles retrieving a single biblio object
(-)a/api/v1/swagger/paths/biblios.yaml (+46 lines)
Lines 279-284 Link Here
279
    x-koha-authorization:
279
    x-koha-authorization:
280
      permissions:
280
      permissions:
281
        reserveforothers: place_holds
281
        reserveforothers: place_holds
282
"/public/biblios":
283
  get:
284
    x-mojo-to: Biblios#get_biblios_public
285
    operationId: getBibliosPublic
286
    tags:
287
      - biblios
288
    summary: Get biblios (public)
289
    parameters:
290
      - $ref: "../swagger.yaml#/parameters/q_ccl"
291
    produces:
292
      - application/marc-in-json
293
    responses:
294
      "200":
295
        description: List of biblios
296
        schema:
297
          type: array
298
      "401":
299
        description: Authentication required
300
        schema:
301
          $ref: "../swagger.yaml#/definitions/error"
302
      "403":
303
        description: Access forbidden
304
        schema:
305
          $ref: "../swagger.yaml#/definitions/error"
306
      "404":
307
        description: Biblio not found
308
        schema:
309
          $ref: "../swagger.yaml#/definitions/error"
310
      "406":
311
        description: Not acceptable
312
        schema:
313
          type: array
314
          description: Accepted content-types
315
          items:
316
            type: string
317
      "500":
318
        description: |
319
          Internal server error. Possible `error_code` attribute values:
320
321
          * `internal_server_error`
322
        schema:
323
          $ref: "../swagger.yaml#/definitions/error"
324
      "503":
325
        description: Under maintenance
326
        schema:
327
          $ref: "../swagger.yaml#/definitions/error"
282
"/public/biblios/{biblio_id}":
328
"/public/biblios/{biblio_id}":
283
  get:
329
  get:
284
    x-mojo-to: Biblios#get_public
330
    x-mojo-to: Biblios#get_public
(-)a/api/v1/swagger/swagger.yaml (+8 lines)
Lines 201-206 paths: Link Here
201
    $ref: "./paths/patrons_password.yaml#/~1patrons~1{patron_id}~1password"
201
    $ref: "./paths/patrons_password.yaml#/~1patrons~1{patron_id}~1password"
202
  "/patrons/{patron_id}/password/expiration_date":
202
  "/patrons/{patron_id}/password/expiration_date":
203
    $ref: "./paths/patrons_password.yaml#/~1patrons~1{patron_id}~1password~1expiration_date"
203
    $ref: "./paths/patrons_password.yaml#/~1patrons~1{patron_id}~1password~1expiration_date"
204
  "/public/biblios":
205
    $ref: "./paths/biblios.yaml#/~1public~1biblios"
204
  "/public/biblios/{biblio_id}":
206
  "/public/biblios/{biblio_id}":
205
    $ref: "./paths/biblios.yaml#/~1public~1biblios~1{biblio_id}"
207
    $ref: "./paths/biblios.yaml#/~1public~1biblios~1{biblio_id}"
206
  "/public/biblios/{biblio_id}/items":
208
  "/public/biblios/{biblio_id}/items":
Lines 384-389 parameters: Link Here
384
    required: false
386
    required: false
385
    schema:
387
    schema:
386
      type: object
388
      type: object
389
  q_ccl:
390
    description: CCL query sent as a query parameter
391
    in: query
392
    name: q_ccl
393
    required: false
394
    type: string
387
  q_header:
395
  q_header:
388
    description: Query filter sent as a request header
396
    description: Query filter sent as a request header
389
    in: header
397
    in: header
(-)a/t/db_dependent/api/v1/biblios.t (-2 / +56 lines)
Lines 20-26 use Modern::Perl; Link Here
20
use utf8;
20
use utf8;
21
use Encode;
21
use Encode;
22
22
23
use Test::More tests => 7;
23
use Test::More tests => 8;
24
use Test::MockModule;
24
use Test::MockModule;
25
use Test::Mojo;
25
use Test::Mojo;
26
use Test::Warn;
26
use Test::Warn;
Lines 216-221 subtest 'delete() tests' => sub { Link Here
216
    $schema->storage->txn_rollback;
216
    $schema->storage->txn_rollback;
217
};
217
};
218
218
219
subtest 'get_biblios_public() tests' => sub {
220
221
    plan tests => 5;
222
223
    $schema->storage->txn_begin;
224
225
    my $category = $builder->build_object({ class => 'Koha::Patron::Categories' });
226
    my $patron = $builder->build_object(
227
        {
228
            class => 'Koha::Patrons',
229
            value => {
230
                flags        => undef, # opac user
231
                categorycode => $category->categorycode
232
            }
233
        }
234
    );
235
236
    my $password = 'thePassword123';
237
    $patron->set_password( { password => $password, skip_validation => 1 } );
238
    $patron->discard_changes;
239
    my $userid = $patron->userid;
240
241
    # Make sure author in shown in the OPAC
242
    my $subfields = Koha::MarcSubfieldStructures->search({ tagfield => '100' });
243
    while ( my $subfield = $subfields->next ) {
244
        $subfield->set({ hidden => -1 })->store;
245
    }
246
    Koha::Caches->get_instance()->flush_all;
247
248
    $t->get_ok( "//$userid:$password@/api/v1/public/biblios" . q{?q_ccl=test}
249
                => { Accept => 'application/weird+format' } )
250
      ->status_is(400);
251
252
    $t->get_ok( "//$userid:$password@/api/v1/public/biblios" . q{?q_ccl=test}
253
                 => { Accept => 'application/marc-in-json' } )
254
      ->status_is(200);
255
256
    subtest 'anonymous access' => sub {
257
258
        plan tests => 4;
259
260
        $t->get_ok( "/api/v1/public/biblios" . q{?q_ccl=test}
261
                    => { Accept => 'application/weird+format' } )
262
          ->status_is(400);
263
264
        $t->get_ok( "/api/v1/public/biblios" . q{?q_ccl=test}
265
                    => { Accept => 'application/marc-in-json' } )
266
          ->status_is(200);
267
268
    };
269
270
    $schema->storage->txn_rollback;
271
272
};
273
219
subtest 'get_public() tests' => sub {
274
subtest 'get_public() tests' => sub {
220
275
221
    plan tests => 25;
276
    plan tests => 25;
222
- 

Return to bug 25870